require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _ = require("@antv/util"); var constant_1 = require("../constant"); var Adjust = /** @class */ (function () { function Adjust(cfg) { var xField = cfg.xField, yField = cfg.yField, _a = cfg.adjustNames, adjustNames = _a === void 0 ? ['x', 'y'] : _a; this.adjustNames = adjustNames; this.xField = xField; this.yField = yField; } /** * 查看维度是否是 adjust 字段 * @param dim */ Adjust.prototype.isAdjust = function (dim) { return this.adjustNames.indexOf(dim) >= 0; }; Adjust.prototype.getAdjustRange = function (dim, dimValue, values) { var yField = this.yField; var index = values.indexOf(dimValue); var length = values.length; var pre; var next; // 没有 y 字段,但是需要根据 y 调整 if (!yField && this.isAdjust('y')) { pre = 0; next = 1; } else if (length > 1) { // 如果以其开头,则取之,否则取他前面一个 pre = values[index === 0 ? 0 : index - 1]; // 如果以其结尾,则取之,否则取他后面一个 next = values[index === length - 1 ? length - 1 : index + 1]; if (index !== 0) { pre += (dimValue - pre) / 2; } else { pre -= (next - dimValue) / 2; } if (index !== length - 1) { next -= (next - dimValue) / 2; } else { next += (dimValue - values[length - 2]) / 2; } } else { pre = dimValue === 0 ? 0 : dimValue - 0.5; next = dimValue === 0 ? 1 : dimValue + 0.5; } return { pre: pre, next: next, }; }; Adjust.prototype.adjustData = function (groupedDataArray, mergedData) { var _this = this; // 所有调整维度的值数组 var dimValuesMap = this.getDimValues(mergedData); // 按照每一个分组来进行调整 _.each(groupedDataArray, function (dataArray, index) { // 遍历所有数据集合 // 每个分组中,分别按照不同的 dim 进行调整 _.each(dimValuesMap, function (values, dim) { // 根据不同的度量分别调整位置 _this.adjustDim(dim, values, dataArray, index); }); }); }; /** * 对数据进行分组adjustData * @param data 数据 * @param dim 分组的字段 * @return 分组结果 */ Adjust.prototype.groupData = function (data, dim) { // 补齐数据空数据为默认值 _.each(data, function (record) { if (record[dim] === undefined) { record[dim] = constant_1.DEFAULT_Y; } }); // 按照 dim 维度分组 return _.groupBy(data, dim); }; /** @override */ Adjust.prototype.adjustDim = function (dim, values, data, index) { }; /** * 获取可调整度量对应的值 * @param mergedData 数据 * @return 值的映射 */ Adjust.prototype.getDimValues = function (mergedData) { var _a = this, xField = _a.xField, yField = _a.yField; var dimValuesMap = {}; // 所有的维度 var dims = []; if (xField && this.isAdjust('x')) { dims.push(xField); } if (yField && this.isAdjust('y')) { dims.push(yField); } dims.forEach(function (dim) { // 在每个维度上,所有的值 dimValuesMap[dim] = _.valuesOfKey(mergedData, dim).sort(function (v1, v2) { return v1 - v2; }); }); // 只有一维的情况下,同时调整 y,赋予默认值 if (!yField && this.isAdjust('y')) { var dim = 'y'; dimValuesMap[dim] = [constant_1.DEFAULT_Y, 1]; // 默认分布在 y 轴的 0 与 1 之间 } return dimValuesMap; }; return Adjust; }()); exports.default = Adjust; },{"../constant":7,"@antv/util":803}],3:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var _ = require("@antv/util"); var constant_1 = require("../constant"); var adjust_1 = require("./adjust"); var Dodge = /** @class */ (function (_super) { tslib_1.__extends(Dodge, _super); function Dodge(cfg) { var _this = _super.call(this, cfg) || this; _this.cacheMap = {}; _this.adjustDataArray = []; _this.mergeData = []; var _a = cfg.marginRatio, marginRatio = _a === void 0 ? constant_1.MARGIN_RATIO : _a, _b = cfg.dodgeRatio, dodgeRatio = _b === void 0 ? constant_1.DODGE_RATIO : _b, dodgeBy = cfg.dodgeBy; _this.marginRatio = marginRatio; _this.dodgeRatio = dodgeRatio; _this.dodgeBy = dodgeBy; return _this; } Dodge.prototype.process = function (groupDataArray) { var groupedDataArray = _.clone(groupDataArray); // 将数据数组展开一层 var mergeData = _.flatten(groupedDataArray); var dodgeBy = this.dodgeBy; // 如果指定了分组 dim 的字段 var adjustDataArray = dodgeBy ? _.group(mergeData, dodgeBy) : groupedDataArray; this.cacheMap = {}; this.adjustDataArray = adjustDataArray; this.mergeData = mergeData; this.adjustData(adjustDataArray, mergeData); this.adjustDataArray = []; this.mergeData = []; return groupedDataArray; }; Dodge.prototype.adjustDim = function (dim, values, data, frameIndex) { var _this = this; var map = this.getDistribution(dim); var groupData = this.groupData(data, dim); // 根据值分组 _.each(groupData, function (group, key) { var range; // xField 中只有一个值,不需要做 dodge if (values.length === 1) { range = { pre: values[0] - 1, next: values[0] + 1, }; } else { // 如果有多个,则需要获取调整的范围 range = _this.getAdjustRange(dim, parseFloat(key), values); } _.each(group, function (d) { var value = d[dim]; var valueArr = map[value]; var valIndex = valueArr.indexOf(frameIndex); d[dim] = _this.getDodgeOffset(range, valIndex, valueArr.length); }); }); return []; }; Dodge.prototype.getDodgeOffset = function (range, idx, len) { var _a = this, dodgeRatio = _a.dodgeRatio, marginRatio = _a.marginRatio; var pre = range.pre, next = range.next; var tickLength = next - pre; var width = (tickLength * dodgeRatio) / len; var margin = marginRatio * width; var offset = (1 / 2) * (tickLength - len * width - (len - 1) * margin) + ((idx + 1) * width + idx * margin) - (1 / 2) * width - (1 / 2) * tickLength; return (pre + next) / 2 + offset; }; Dodge.prototype.getDistribution = function (dim) { var groupedDataArray = this.adjustDataArray; var cacheMap = this.cacheMap; var map = cacheMap[dim]; if (!map) { map = {}; _.each(groupedDataArray, function (data, index) { var values = _.valuesOfKey(data, dim); if (!values.length) { values.push(0); } _.each(values, function (val) { if (!map[val]) { map[val] = []; } map[val].push(index); }); }); cacheMap[dim] = map; } return map; }; return Dodge; }(adjust_1.default)); exports.default = Dodge; },{"../constant":7,"./adjust":2,"@antv/util":803,"tslib":894}],4:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var _ = require("@antv/util"); var constant_1 = require("../constant"); var adjust_1 = require("./adjust"); function randomNumber(min, max) { return (max - min) * Math.random() + min; } var Jitter = /** @class */ (function (_super) { tslib_1.__extends(Jitter, _super); function Jitter() { return _super !== null && _super.apply(this, arguments) || this; } Jitter.prototype.process = function (groupDataArray) { var groupedDataArray = _.clone(groupDataArray); // 之前分组之后的数据,然后有合并回去(和分组前可以理解成是一样的) var mergeData = _.flatten(groupedDataArray); // 返回值 this.adjustData(groupedDataArray, mergeData); return groupedDataArray; }; /** * 当前数据分组(index)中,按照维度 dim 进行 jitter 调整 * @param dim * @param values * @param dataArray */ Jitter.prototype.adjustDim = function (dim, values, dataArray) { var _this = this; // 在每一个分组中,将数据再按照 dim 分组,用于散列 var groupDataArray = this.groupData(dataArray, dim); return _.each(groupDataArray, function (data, dimValue) { return _this.adjustGroup(data, dim, parseFloat(dimValue), values); }); }; // 随机出来的字段值 Jitter.prototype.getAdjustOffset = function (range) { var pre = range.pre, next = range.next; // 随机的范围 var margin = (next - pre) * constant_1.GAP; return randomNumber(pre + margin, next - margin); }; // adjust group data Jitter.prototype.adjustGroup = function (group, dim, dimValue, values) { var _this = this; // 调整范围 var range = this.getAdjustRange(dim, dimValue, values); _.each(group, function (data) { data[dim] = _this.getAdjustOffset(range); // 获取调整的位置 }); return group; }; return Jitter; }(adjust_1.default)); exports.default = Jitter; },{"../constant":7,"./adjust":2,"@antv/util":803,"tslib":894}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var _ = require("@antv/util"); var adjust_1 = require("./adjust"); var Cache = _.Cache; var Stack = /** @class */ (function (_super) { tslib_1.__extends(Stack, _super); function Stack(cfg) { var _this = _super.call(this, cfg) || this; var _a = cfg.adjustNames, adjustNames = _a === void 0 ? ['y'] : _a, _b = cfg.height, height = _b === void 0 ? NaN : _b, _c = cfg.size, size = _c === void 0 ? 10 : _c, _d = cfg.reverseOrder, reverseOrder = _d === void 0 ? false : _d; _this.adjustNames = adjustNames; _this.height = height; _this.size = size; _this.reverseOrder = reverseOrder; return _this; } /** * 方法入参是经过数据分组、数据数字化之后的二维数组 * @param groupDataArray 分组之后的数据 */ Stack.prototype.process = function (groupDataArray) { var _a = this, yField = _a.yField, reverseOrder = _a.reverseOrder; // 如果有指定 y 字段,那么按照 y 字段来 stack // 否则,按照高度均分 var d = yField ? this.processStack(groupDataArray) : this.processOneDimStack(groupDataArray); return reverseOrder ? this.reverse(d) : d; }; Stack.prototype.reverse = function (groupedDataArray) { return groupedDataArray.slice(0).reverse(); }; Stack.prototype.processStack = function (groupDataArray) { var _a = this, xField = _a.xField, yField = _a.yField, reverseOrder = _a.reverseOrder; // 层叠顺序翻转 var groupedDataArray = reverseOrder ? this.reverse(groupDataArray) : groupDataArray; // 用来缓存,正数和负数的堆叠问题 var positive = new Cache(); var negative = new Cache(); return groupedDataArray.map(function (dataArray) { return dataArray.map(function (data) { var _a; var x = _.get(data, xField, 0); var y = _.get(data, yField); var xKey = x.toString(); // todo 是否应该取 _origin?因为 y 可能取到的值不正确,比如先 symmetric,再 stack! y = _.isArray(y) ? y[1] : y; if (!_.isNil(y)) { var cache = y >= 0 ? positive : negative; if (!cache.has(xKey)) { cache.set(xKey, 0); } var xValue = cache.get(xKey); var newXValue = y + xValue; // 存起来 cache.set(xKey, newXValue); return tslib_1.__assign(tslib_1.__assign({}, data), (_a = {}, _a[yField] = [xValue, newXValue], _a)); } // 没有修改,则直接返回 return data; }); }); }; Stack.prototype.processOneDimStack = function (groupDataArray) { var _this = this; var _a = this, xField = _a.xField, height = _a.height, reverseOrder = _a.reverseOrder; var yField = 'y'; // 如果层叠的顺序翻转 var groupedDataArray = reverseOrder ? this.reverse(groupDataArray) : groupDataArray; // 缓存累加数据 var cache = new Cache(); return groupedDataArray.map(function (dataArray) { return dataArray.map(function (data) { var _a; var size = _this.size; var xValue = data[xField]; // todo 没有看到这个 stack 计算原理 var stackHeight = (size * 2) / height; if (!cache.has(xValue)) { cache.set(xValue, stackHeight / 2); // 初始值大小 } var stackValue = cache.get(xValue); // 增加一层 stackHeight cache.set(xValue, stackValue + stackHeight); return tslib_1.__assign(tslib_1.__assign({}, data), (_a = {}, _a[yField] = stackValue, _a)); }); }); }; return Stack; }(adjust_1.default)); exports.default = Stack; },{"./adjust":2,"@antv/util":803,"tslib":894}],6:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var _ = require("@antv/util"); var adjust_1 = require("./adjust"); var Symmetric = /** @class */ (function (_super) { tslib_1.__extends(Symmetric, _super); function Symmetric() { return _super !== null && _super.apply(this, arguments) || this; } Symmetric.prototype.process = function (groupDataArray) { var mergeData = _.flatten(groupDataArray); var _a = this, xField = _a.xField, yField = _a.yField; // 每个 x 值对应的 最大值 var cache = this.getXValuesMaxMap(mergeData); // 所有数据的最大的值 var max = Math.max.apply(Math, Object.keys(cache).map(function (key) { return cache[key]; })); return _.map(groupDataArray, function (dataArray) { return _.map(dataArray, function (data) { var _a, _b; var yValue = data[yField]; var xValue = data[xField]; // 数组处理逻辑 if (_.isArray(yValue)) { var off_1 = (max - cache[xValue]) / 2; return tslib_1.__assign(tslib_1.__assign({}, data), (_a = {}, _a[yField] = _.map(yValue, function (y) { return off_1 + y; }), _a)); } // 非数组处理逻辑 var offset = (max - yValue) / 2; return tslib_1.__assign(tslib_1.__assign({}, data), (_b = {}, _b[yField] = [offset, yValue + offset], _b)); }); }); }; // 获取每个 x 对应的最大的值 Symmetric.prototype.getXValuesMaxMap = function (mergeData) { var _this = this; var _a = this, xField = _a.xField, yField = _a.yField; // 根据 xField 的值进行分组 var groupDataArray = _.groupBy(mergeData, function (data) { return data[xField]; }); // 获取每个 xField 值中的最大值 return _.mapValues(groupDataArray, function (dataArray) { return _this.getDimMaxValue(dataArray, yField); }); }; Symmetric.prototype.getDimMaxValue = function (mergeData, dim) { // 所有的 value 值 var dimValues = _.map(mergeData, function (data) { return _.get(data, dim, []); }); // 将数组打平(dim value 有可能是数组,比如 stack 之后的) var flattenValues = _.flatten(dimValues); // 求出数组的最大值 return Math.max.apply(Math, flattenValues); }; return Symmetric; }(adjust_1.default)); exports.default = Symmetric; },{"./adjust":2,"@antv/util":803,"tslib":894}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_Y = 0; // 默认的 y 的值 // 偏移之后,间距 exports.MARGIN_RATIO = 1 / 2; exports.DODGE_RATIO = 1 / 2; // 散点分开之后,距离边界的距离 exports.GAP = 0.05; },{}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var adjust_1 = require("./adjusts/adjust"); exports.Adjust = adjust_1.default; var ADJUST_MAP = {}; /** * 根据类型获取 Adjust 类 * @param type */ var getAdjust = function (type) { return ADJUST_MAP[type.toLowerCase()]; }; exports.getAdjust = getAdjust; /** * 注册自定义 Adjust * @param type * @param ctor */ var registerAdjust = function (type, ctor) { // 注册的时候,需要校验 type 重名,不区分大小写 if (getAdjust(type)) { throw new Error("Adjust type '" + type + "' existed."); } // 存储到 map 中 ADJUST_MAP[type.toLowerCase()] = ctor; }; exports.registerAdjust = registerAdjust; },{"./adjusts/adjust":2}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var factory_1 = require("./factory"); exports.getAdjust = factory_1.getAdjust; exports.registerAdjust = factory_1.registerAdjust; var adjust_1 = require("./adjusts/adjust"); exports.Adjust = adjust_1.default; var dodge_1 = require("./adjusts/dodge"); var jitter_1 = require("./adjusts/jitter"); var stack_1 = require("./adjusts/stack"); var symmetric_1 = require("./adjusts/symmetric"); // 注册内置的 adjust factory_1.registerAdjust('Dodge', dodge_1.default); factory_1.registerAdjust('Jitter', jitter_1.default); factory_1.registerAdjust('Stack', stack_1.default); factory_1.registerAdjust('Symmetric', symmetric_1.default); },{"./adjusts/adjust":2,"./adjusts/dodge":3,"./adjusts/jitter":4,"./adjusts/stack":5,"./adjusts/symmetric":6,"./factory":8}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); // todo 这个到底目的是什么? var toScaleString = function (scale, value) { if (util_1.isString(value)) { return value; } return scale.invert(scale.scale(value)); }; /** * 所有视觉通道属性的基类 * @class Base */ var Attribute = /** @class */ (function () { function Attribute(cfg) { this.names = []; this.scales = []; this.linear = false; this.values = []; this.callback = function () { return []; }; // 解析配置 this._parseCfg(cfg); } /** * 映射的值组成的数组 * @param params 对应 scale 顺序的值传入 */ Attribute.prototype.mapping = function () { var _this = this; var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } var values = params.map(function (param, idx) { return _this._toOriginParam(param, _this.scales[idx]); }); return this.callback.apply(this, values); }; /** * 如果进行线性映射,返回对应的映射值 * @param percent */ Attribute.prototype.getLinearValue = function (percent) { // 分段数量 var steps = this.values.length - 1; var step = Math.floor(steps * percent); var leftPercent = steps * percent - step; // todo 不懂这个逻辑 var start = this.values[step]; var end = step === steps ? start : this.values[step + 1]; // 线性方程 return start + (end - start) * leftPercent; }; /** * 根据度量获取属性名 */ Attribute.prototype.getNames = function () { var scales = this.scales; var names = this.names; var length = Math.min(scales.length, names.length); var rst = []; for (var i = 0; i < length; i += 1) { rst.push(names[i]); } return rst; }; /** * 获取所有的维度名 */ Attribute.prototype.getFields = function () { return this.scales.map(function (scale) { return scale.field; }); }; /** * 根据名称获取度量 * @param name */ Attribute.prototype.getScale = function (name) { return this.scales[this.names.indexOf(name)]; }; /** * 默认的回调函数(用户没有自定义 callback,或者用户自定义 callback 返回空的时候,使用 values 映射) * @param params */ Attribute.prototype.defaultCallback = function () { var _this = this; var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } // 没有 params 的情况,是指没有指定 fields,直接返回配置的 values 常量 if (params.length === 0) { return this.values; } return params.map(function (param, idx) { var scale = _this.scales[idx]; return scale.type === 'identity' ? scale.values[0] : _this._getAttributeValue(scale, param); }); }; // 解析配置 Attribute.prototype._parseCfg = function (cfg) { var _this = this; var _a = cfg.type, type = _a === void 0 ? 'base' : _a, _b = cfg.names, names = _b === void 0 ? [] : _b, _c = cfg.scales, scales = _c === void 0 ? [] : _c, _d = cfg.values, values = _d === void 0 ? [] : _d, callback = cfg.callback; this.type = type; this.scales = scales; this.values = values; this.names = names; // 构造 callback 方法 this.callback = function () { var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } /** * 当用户设置的 callback 返回 null 时, 应该返回默认 callback 中的值 */ if (callback) { // 使用用户返回的值处理 var ret = callback.apply(void 0, params); if (!util_1.isNil(ret)) { return [ret]; } } // 没有 callback 或者用户 callback 返回值为空,则使用默认的逻辑处理 return _this.defaultCallback.apply(_this, params); }; }; // 获取属性值,将值映射到视觉通道 Attribute.prototype._getAttributeValue = function (scale, value) { // 如果是非线性的字段,直接从 values 中取值即可 if (scale.isCategory && !this.linear) { // 离散 scale 变换成索引 var idx = scale.translate(value); return this.values[idx % this.values.length]; } // 线性则使用线性值 var percent = scale.scale(value); return this.getLinearValue(percent); }; /** * 通过 scale 拿到数据对应的原始的参数 * @param param * @param scale * @private */ Attribute.prototype._toOriginParam = function (param, scale) { // 是线性,直接返回 // 非线性,使用 scale 变换 return !scale.isLinear ? util_1.isArray(param) ? param.map(function (p) { return toScaleString(scale, p); }) : toScaleString(scale, param) : param; }; return Attribute; }()); exports.default = Attribute; },{"@antv/util":803}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var color_util_1 = require("@antv/color-util"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var Color = /** @class */ (function (_super) { tslib_1.__extends(Color, _super); function Color(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'color'; _this.names = ['color']; if (util_1.isString(_this.values)) { _this.linear = true; } _this.gradient = color_util_1.default.gradient(_this.values); return _this; } /** * @override */ Color.prototype.getLinearValue = function (percent) { return this.gradient(percent); }; return Color; }(base_1.default)); exports.default = Color; },{"./base":10,"@antv/color-util":19,"@antv/util":803,"tslib":894}],12:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var Opacity = /** @class */ (function (_super) { tslib_1.__extends(Opacity, _super); function Opacity(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'opacity'; _this.names = ['opacity']; return _this; } return Opacity; }(base_1.default)); exports.default = Opacity; },{"./base":10,"tslib":894}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var Position = /** @class */ (function (_super) { tslib_1.__extends(Position, _super); function Position(cfg) { var _this = _super.call(this, cfg) || this; _this.names = ['x', 'y']; _this.type = 'position'; return _this; } Position.prototype.mapping = function (x, y) { var _a = this.scales, scaleX = _a[0], scaleY = _a[1]; if (util_1.isNil(x) || util_1.isNil(y)) { return []; } return [ util_1.isArray(x) ? x.map(function (xi) { return scaleX.scale(xi); }) : scaleX.scale(x), util_1.isArray(y) ? y.map(function (yi) { return scaleY.scale(yi); }) : scaleY.scale(y), ]; }; return Position; }(base_1.default)); exports.default = Position; },{"./base":10,"@antv/util":803,"tslib":894}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var Shape = /** @class */ (function (_super) { tslib_1.__extends(Shape, _super); function Shape(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'shape'; _this.names = ['shape']; return _this; } /** * @override */ Shape.prototype.getLinearValue = function (percent) { var idx = Math.round((this.values.length - 1) * percent); return this.values[idx]; }; return Shape; }(base_1.default)); exports.default = Shape; },{"./base":10,"tslib":894}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var Size = /** @class */ (function (_super) { tslib_1.__extends(Size, _super); function Size(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'size'; _this.names = ['size']; return _this; } return Size; }(base_1.default)); exports.default = Size; },{"./base":10,"tslib":894}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./attributes/base"); exports.Attribute = base_1.default; // 所有的 attribute map var ATTRIBUTE_MAP = {}; /** * 通过类型获得 Attribute 类 * @param type */ var getAttribute = function (type) { return ATTRIBUTE_MAP[type.toLowerCase()]; }; exports.getAttribute = getAttribute; var registerAttribute = function (type, ctor) { // 注册的时候,需要校验 type 重名,不区分大小写 if (getAttribute(type)) { throw new Error("Attribute type '" + type + "' existed."); } // 存储到 map 中 ATTRIBUTE_MAP[type.toLowerCase()] = ctor; }; exports.registerAttribute = registerAttribute; tslib_1.__exportStar(require("./interface"), exports); },{"./attributes/base":10,"./interface":18,"tslib":894}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./attributes/base"); exports.Attribute = base_1.default; var color_1 = require("./attributes/color"); exports.Color = color_1.default; var opacity_1 = require("./attributes/opacity"); exports.Opacity = opacity_1.default; var position_1 = require("./attributes/position"); exports.Position = position_1.default; var shape_1 = require("./attributes/shape"); exports.Shape = shape_1.default; var size_1 = require("./attributes/size"); exports.Size = size_1.default; var factory_1 = require("./factory"); exports.getAttribute = factory_1.getAttribute; exports.registerAttribute = factory_1.registerAttribute; factory_1.registerAttribute('Color', color_1.default); factory_1.registerAttribute('Opacity', opacity_1.default); factory_1.registerAttribute('Position', position_1.default); factory_1.registerAttribute('Shape', shape_1.default); factory_1.registerAttribute('Size', size_1.default); tslib_1.__exportStar(require("./interface"), exports); },{"./attributes/base":10,"./attributes/color":11,"./attributes/opacity":12,"./attributes/position":13,"./attributes/shape":14,"./attributes/size":15,"./factory":16,"./interface":18,"tslib":894}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var scale_1 = require("@antv/scale"); exports.Scale = scale_1.Scale; },{"@antv/scale":747}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var RGB_REG = /rgba?\(([\s.,0-9]+)\)/; var regexLG = /^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i; var regexRG = /^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i; var regexColorStop = /[\d.]+:(#[^\s]+|[^\)]+\))/gi; var isGradientColor = function (val) { return /^[r,R,L,l]{1}[\s]*\(/.test(val); }; // 创建辅助 tag 取颜色 var createTmp = function () { var i = document.createElement('i'); i.title = 'Web Colour Picker'; i.style.display = 'none'; document.body.appendChild(i); return i; }; // 获取颜色之间的插值 var getValue = function (start, end, percent, index) { return start[index] + (end[index] - start[index]) * percent; }; // 数组转换成颜色 function arr2rgb(arr) { return "#" + toHex(arr[0]) + toHex(arr[1]) + toHex(arr[2]); } // rgb 颜色转换成数组 var rgb2arr = function (str) { return [ parseInt(str.substr(1, 2), 16), parseInt(str.substr(3, 2), 16), parseInt(str.substr(5, 2), 16), ]; }; // 将数值从 0-255 转换成16进制字符串 var toHex = function (value) { var x16Value = Math.round(value).toString(16); return x16Value.length === 1 ? "0" + x16Value : x16Value; }; // 计算颜色 var calColor = function (points, percent) { var fixedPercent = isNaN(Number(percent)) || percent < 0 ? 0 : percent > 1 ? 1 : Number(percent); var steps = points.length - 1; var step = Math.floor(steps * fixedPercent); var left = steps * fixedPercent - step; var start = points[step]; var end = step === steps ? start : points[step + 1]; return arr2rgb([ getValue(start, end, left, 0), getValue(start, end, left, 1), getValue(start, end, left, 2), ]); }; // 用于给 toRGB 的缓存(使用 memoize 方法替换) // const colorCache = {}; var iEl; /** * 将颜色转换到 rgb 的格式 * @param {color} color 颜色 * @return 将颜色转换到 '#ffffff' 的格式 */ var toRGB = function (color) { // 如果已经是 rgb的格式 if (color[0] === '#' && color.length === 7) { return color; } if (!iEl) { // 防止防止在页头报错 iEl = createTmp(); } iEl.style.color = color; var rst = document.defaultView.getComputedStyle(iEl, '').getPropertyValue('color'); var matches = RGB_REG.exec(rst); var cArray = matches[1].split(/\s*,\s*/).map(function (s) { return Number(s); }); rst = arr2rgb(cArray); return rst; }; /** * 获取渐变函数 * @param colors 多个颜色 * @return 颜色值 */ var gradient = function (colors) { var colorArray = util_1.isString(colors) ? colors.split('-') : colors; var points = util_1.map(colorArray, function (color) { return rgb2arr(color.indexOf('#') === -1 ? toRGB(color) : color); }); // 返回一个函数 return function (percent) { return calColor(points, percent); }; }; var toCSSGradient = function (gradientColor) { if (isGradientColor(gradientColor)) { var cssColor_1; var steps = void 0; if (gradientColor[0] === 'l') { // 线性渐变 var arr = regexLG.exec(gradientColor); var angle = +arr[1] + 90; // css 和 g 的渐变起始角度不同 steps = arr[2]; cssColor_1 = "linear-gradient(" + angle + "deg, "; } else if (gradientColor[0] === 'r') { // 径向渐变 cssColor_1 = 'radial-gradient('; var arr = regexRG.exec(gradientColor); steps = arr[4]; } var colorStops_1 = steps.match(regexColorStop); util_1.each(colorStops_1, function (item, index) { var itemArr = item.split(':'); cssColor_1 += itemArr[1] + " " + itemArr[0] * 100 + "%"; if (index !== (colorStops_1.length - 1)) { cssColor_1 += ', '; } }); cssColor_1 += ')'; return cssColor_1; } return gradientColor; }; exports.default = { rgb2arr: rgb2arr, gradient: gradient, toRGB: util_1.memoize(toRGB), toCSSGradient: toCSSGradient, }; },{"@antv/util":803}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var util_1 = require("@antv/util"); var LOCATION_FIELD_MAP = { none: [], point: ['x', 'y'], region: ['start', 'end'], points: ['points'], circle: ['center', 'radius', 'startAngle', 'endAngle'], }; var Component = /** @class */ (function (_super) { tslib_1.__extends(Component, _super); function Component(cfg) { var _this = _super.call(this, cfg) || this; _this.initCfg(); return _this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ Component.prototype.getDefaultCfg = function () { return { id: '', name: '', type: '', locationType: 'none', offsetX: 0, offsetY: 0, animate: false, capture: true, updateAutoRender: false, animateOption: { appear: null, update: { duration: 400, easing: 'easeQuadInOut', }, enter: { duration: 400, easing: 'easeQuadInOut', }, leave: { duration: 350, easing: 'easeQuadIn', }, }, events: null, defaultCfg: {}, visible: true, }; }; /** * 清理组件的内容,一般配合 render 使用 * @example * axis.clear(); * axis.render(); */ Component.prototype.clear = function () { }; /** * 更新组件 * @param {object} cfg 更新属性 */ Component.prototype.update = function (cfg) { var _this = this; var defaultCfg = this.get('defaultCfg'); util_1.each(cfg, function (value, name) { var originCfg = _this.get(name); var newCfg = value; if (originCfg !== value) { // 判断两者是否相等,主要是进行 null 的判定 if (util_1.isObject(value) && defaultCfg[name]) { // 新设置的属性与默认值进行合并 newCfg = util_1.deepMix({}, defaultCfg[name], value); } _this.set(name, newCfg); } }); this.updateInner(cfg); this.afterUpdate(cfg); }; // 更新内部 Component.prototype.updateInner = function (cfg) { }; Component.prototype.afterUpdate = function (cfg) { // 更新时考虑显示、隐藏 if (util_1.hasKey(cfg, 'visible')) { if (cfg.visible) { this.show(); } else { this.hide(); } } // 更新时考虑capture if (util_1.hasKey(cfg, 'capture')) { this.setCapture(cfg.capture); } }; Component.prototype.getLayoutBBox = function () { return this.getBBox(); // 默认返回 getBBox,不同的组件内部单独实现 }; Component.prototype.getLocationType = function () { return this.get('locationType'); }; Component.prototype.getOffset = function () { return { offsetX: this.get('offsetX'), offsetY: this.get('offsetY'), }; }; // 默认使用 update Component.prototype.setOffset = function (offsetX, offsetY) { this.update({ offsetX: offsetX, offsetY: offsetY, }); }; Component.prototype.setLocation = function (cfg) { var location = tslib_1.__assign({}, cfg); this.update(location); }; // 实现 ILocation 接口的 getLocation Component.prototype.getLocation = function () { var _this = this; var location = {}; var locationType = this.get('locationType'); var fields = LOCATION_FIELD_MAP[locationType]; util_1.each(fields, function (field) { location[field] = _this.get(field); }); return location; }; Component.prototype.isList = function () { return false; }; Component.prototype.isSlider = function () { return false; }; /** * @protected * 初始化,用于具体的组件继承 */ Component.prototype.init = function () { }; // 将组件默认的配置项设置合并到传入的配置项 Component.prototype.initCfg = function () { var _this = this; var defaultCfg = this.get('defaultCfg'); util_1.each(defaultCfg, function (value, name) { var cfg = _this.get(name); if (util_1.isObject(cfg)) { var newCfg = util_1.deepMix({}, value, cfg); _this.set(name, newCfg); } }); }; return Component; }(g_base_1.Base)); exports.default = Component; },{"@antv/g-base":115,"@antv/util":803,"tslib":894}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var event_1 = require("../util/event"); var matrix_1 = require("../util/matrix"); var util_2 = require("../util/util"); var component_1 = require("./component"); var STATUS_UPDATE = 'update_status'; var COPY_PROPERTIES = ['visible', 'tip', 'delegateObject']; // 更新对象时需要复制的属性 var COPY_PROPERTIES_EXCLUDES = ['container', 'group', 'shapesMap', 'isRegister', 'isUpdating', 'destroyed']; // 更新子组件时排除的属性 var GroupComponent = /** @class */ (function (_super) { tslib_1.__extends(GroupComponent, _super); function GroupComponent() { return _super !== null && _super.apply(this, arguments) || this; } GroupComponent.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { container: null, /** * @private * 缓存图形的 Map */ shapesMap: {}, group: null, capture: true, /** * @private 组件或者图形是否允许注册 * @type {false} */ isRegister: false, /** * @private 是否正在更新 * @type {false} */ isUpdating: false, /** * @private * 是否初始状态,一旦 render,update 后,这个状态就变成 false, clear 后恢复 */ isInit: true }); }; GroupComponent.prototype.remove = function () { this.clear(); var group = this.get('group'); group.remove(); }; GroupComponent.prototype.clear = function () { var group = this.get('group'); group.clear(); this.set('shapesMap', {}); this.clearOffScreenCache(); this.set('isInit', true); }; GroupComponent.prototype.getChildComponentById = function (id) { var group = this.getElementById(id); var inst = group && group.get('component'); return inst; }; GroupComponent.prototype.getElementById = function (id) { return this.get('shapesMap')[id]; }; GroupComponent.prototype.getElementByLocalId = function (localId) { var id = this.getElementId(localId); return this.getElementById(id); }; GroupComponent.prototype.getElementsByName = function (name) { var rst = []; util_1.each(this.get('shapesMap'), function (elem) { if (elem.get('name') === name) { rst.push(elem); } }); return rst; }; GroupComponent.prototype.getContainer = function () { return this.get('container'); }; GroupComponent.prototype.updateInner = function (cfg) { // this.updateInner(); // this.set('isUpdating', false); this.offScreenRender(); if (this.get('updateAutoRender')) { this.render(); } }; GroupComponent.prototype.render = function () { var offScreenGroup = this.get('offScreenGroup'); if (!offScreenGroup) { offScreenGroup = this.offScreenRender(); } var group = this.get('group'); this.updateElements(offScreenGroup, group); this.deleteElements(); this.applyOffset(); if (!this.get('eventInitted')) { this.initEvent(); this.set('eventInitted', true); } this.set('isInit', false); }; GroupComponent.prototype.show = function () { var group = this.get('group'); group.show(); this.set('visible', true); }; GroupComponent.prototype.hide = function () { var group = this.get('group'); group.hide(); this.set('visible', false); }; GroupComponent.prototype.setCapture = function (capture) { var group = this.get('group'); group.set('capture', capture); this.set('capture', capture); }; GroupComponent.prototype.destroy = function () { this.removeEvent(); this.remove(); _super.prototype.destroy.call(this); }; GroupComponent.prototype.getBBox = function () { return this.get('group').getCanvasBBox(); }; GroupComponent.prototype.getLayoutBBox = function () { var group = this.get('group'); // 防止被 clear 了,offScreenBBox 不存在 var bbox = this.getInnerLayoutBBox(); var matrix = group.getTotalMatrix(); if (matrix) { bbox = matrix_1.applyMatrix2BBox(matrix, bbox); } return bbox; // 默认返回 getBBox,不同的组件内部单独实现 }; // 复写 on, off, emit 透传到 group GroupComponent.prototype.on = function (evt, callback, once) { var group = this.get('group'); group.on(evt, callback, once); return this; }; GroupComponent.prototype.off = function (evt, callback) { var group = this.get('group'); group && group.off(evt, callback); return this; }; GroupComponent.prototype.emit = function (eventName, eventObject) { var group = this.get('group'); group.emit(eventName, eventObject); }; GroupComponent.prototype.init = function () { _super.prototype.init.call(this); if (!this.get('group')) { this.initGroup(); } this.offScreenRender(); // 绘制离屏 group }; // 获取组件内部布局占的包围盒 GroupComponent.prototype.getInnerLayoutBBox = function () { return this.get('offScreenBBox') || this.get('group').getBBox(); }; // 抛出委托对象 GroupComponent.prototype.delegateEmit = function (eventName, eventObject) { var group = this.get('group'); eventObject.target = group; group.emit(eventName, eventObject); event_1.propagationDelegate(group, eventName, eventObject); }; // 创建离屏的 group ,不添加在 canvas 中 GroupComponent.prototype.createOffScreenGroup = function () { var group = this.get('group'); var GroupClass = group.getGroupBase(); // 获取分组的构造函数 var newGroup = new GroupClass({ delegateObject: this.getDelegateObject(), }); return newGroup; }; // 应用 offset GroupComponent.prototype.applyOffset = function () { var offsetX = this.get('offsetX'); var offsetY = this.get('offsetY'); this.moveElementTo(this.get('group'), { x: offsetX, y: offsetY, }); }; GroupComponent.prototype.initGroup = function () { var container = this.get('container'); this.set('group', container.addGroup({ id: this.get('id'), name: this.get('name'), capture: this.get('capture'), visible: this.get('visible'), isComponent: true, component: this, delegateObject: this.getDelegateObject(), })); }; // 离屏渲染 GroupComponent.prototype.offScreenRender = function () { this.clearOffScreenCache(); var offScreenGroup = this.createOffScreenGroup(); this.renderInner(offScreenGroup); this.set('offScreenGroup', offScreenGroup); // 包含包围盒的 bbox this.set('offScreenBBox', util_2.getBBoxWithClip(offScreenGroup)); return offScreenGroup; }; /** * @protected * 在组件上添加分组,主要解决 isReigeter 的问题 * @param {IGroup} parent 父元素 * @param {object} cfg 分组的配置项 */ GroupComponent.prototype.addGroup = function (parent, cfg) { this.appendDelegateObject(parent, cfg); var group = parent.addGroup(cfg); if (this.get('isRegister')) { this.registerElement(group); } return group; }; /** * @protected * 在组件上添加图形,主要解决 isReigeter 的问题 * @param {IGroup} parent 父元素 * @param {object} cfg 分组的配置项 */ GroupComponent.prototype.addShape = function (parent, cfg) { this.appendDelegateObject(parent, cfg); var shape = parent.addShape(cfg); if (this.get('isRegister')) { this.registerElement(shape); } return shape; }; /** * 在组件上添加子组件 * * @param parent 父元素 * @param cfg 子组件配置项 */ GroupComponent.prototype.addComponent = function (parent, cfg) { var id = cfg.id, Ctor = cfg.component, restCfg = tslib_1.__rest(cfg, ["id", "component"]); // @ts-ignore var inst = new Ctor(tslib_1.__assign(tslib_1.__assign({}, restCfg), { id: id, container: parent, updateAutoRender: this.get('updateAutoRender') })); inst.init(); inst.render(); if (this.get('isRegister')) { this.registerElement(inst.get('group')); } return inst; }; GroupComponent.prototype.initEvent = function () { }; GroupComponent.prototype.removeEvent = function () { var group = this.get('group'); group.off(); }; GroupComponent.prototype.getElementId = function (localId) { var id = this.get('id'); // 组件的 Id var name = this.get('name'); // 组件的名称 return id + "-" + name + "-" + localId; }; GroupComponent.prototype.registerElement = function (element) { var id = element.get('id'); this.get('shapesMap')[id] = element; }; GroupComponent.prototype.unregisterElement = function (element) { var id = element.get('id'); delete this.get('shapesMap')[id]; }; // 移动元素 GroupComponent.prototype.moveElementTo = function (element, point) { var matrix = matrix_1.getMatrixByTranslate(point); element.attr('matrix', matrix); }; /** * 图形元素新出现时的动画,默认图形从透明度 0 到当前透明度 * @protected * @param {string} elmentName 图形元素名称 * @param {IElement} newElement 新的图形元素 * @param {object} animateCfg 动画的配置项 */ GroupComponent.prototype.addAnimation = function (elmentName, newElement, animateCfg) { // 缓存透明度 var originOpacity = newElement.attr('opacity'); if (util_1.isNil(originOpacity)) { originOpacity = 1; } newElement.attr('opacity', 0); newElement.animate({ opacity: originOpacity }, animateCfg); }; /** * 图形元素新出现时的动画,默认图形从透明度 0 到当前透明度 * @protected * @param {string} elmentName 图形元素名称 * @param {IElement} originElement 要删除的图形元素 * @param {object} animateCfg 动画的配置项 */ GroupComponent.prototype.removeAnimation = function (elementName, originElement, animateCfg) { originElement.animate({ opacity: 0 }, animateCfg); }; /** * 图形元素的更新动画 * @param {string} elmentName 图形元素名称 * @param {IElement} originElement 现有的图形元素 * @param {object} newAttrs 新的图形元素 * @param {object} animateCfg 动画的配置项 */ GroupComponent.prototype.updateAnimation = function (elementName, originElement, newAttrs, animateCfg) { originElement.animate(newAttrs, animateCfg); }; // 更新组件的图形 GroupComponent.prototype.updateElements = function (newGroup, originGroup) { var _this = this; var animate = this.get('animate'); var animateOption = this.get('animateOption'); var children = newGroup.getChildren().slice(0); // 创建一个新数组,防止添加到 originGroup 时, children 变动 var preElement; // 前面已经匹配到的图形元素,用于 util_1.each(children, function (element) { var elementId = element.get('id'); var originElement = _this.getElementById(elementId); var elementName = element.get('name'); if (originElement) { if (element.get('isComponent')) { // 嵌套子组件更新 var childComponent = element.get('component'); var origChildComponent = originElement.get('component'); var newCfg = util_1.pick(childComponent.cfg, util_1.difference(util_1.keys(childComponent.cfg), COPY_PROPERTIES_EXCLUDES)); origChildComponent.update(newCfg); originElement.set(STATUS_UPDATE, 'update'); } else { var replaceAttrs = _this.getReplaceAttrs(originElement, element); // 更新 if (animate && animateOption.update) { // 没有动画 _this.updateAnimation(elementName, originElement, replaceAttrs, animateOption.update); } else { // originElement.attrs = replaceAttrs; // 直接替换 originElement.attr(replaceAttrs); } // 如果是分组,则继续执行 if (element.isGroup()) { _this.updateElements(element, originElement); } // 复制属性 util_1.each(COPY_PROPERTIES, function (name) { originElement.set(name, element.get(name)); }); util_2.updateClip(originElement, element); preElement = originElement; // 执行完更新后设置状态位为更新 originElement.set(STATUS_UPDATE, 'update'); } } else { // 没有对应的图形,则插入当前图形 originGroup.add(element); // 应该在 group 加个 insertAt 的方法 var siblings = originGroup.getChildren(); // 兄弟节点 siblings.splice(siblings.length - 1, 1); // 先从数组中移除,然后放到合适的位置 if (preElement) { // 前面已经有更新的图形或者插入的图形,则在这个图形后面插入 var index = siblings.indexOf(preElement); siblings.splice(index + 1, 0, element); // 在已经更新的图形元素后面插入 } else { siblings.unshift(element); } _this.registerElement(element); // 注册节点 element.set(STATUS_UPDATE, 'add'); // 执行完更新后设置状态位为添加 if (element.get('isComponent')) { // 直接新增子组件container属性,实例不变 var childComponent = element.get('component'); childComponent.set('container', originGroup); } else if (element.isGroup()) { // 如果元素是新增加的元素,则遍历注册所有的子节点 _this.registerNewGroup(element); } preElement = element; if (animate) { var animateCfg = _this.get('isInit') ? animateOption.appear : animateOption.enter; if (animateCfg) { _this.addAnimation(elementName, element, animateCfg); } } } }); }; GroupComponent.prototype.clearUpdateStatus = function (group) { var children = group.getChildren(); util_1.each(children, function (el) { el.set(STATUS_UPDATE, null); // 清理掉更新状态 }); }; // 清理离屏缓存 GroupComponent.prototype.clearOffScreenCache = function () { var offScreenGroup = this.get('offScreenGroup'); if (offScreenGroup) { // 销毁原先的离线 Group offScreenGroup.destroy(); } this.set('offScreenGroup', null); this.set('offScreenBBox', null); }; // private updateInner() { // const group = this.get('group'); // const newGroup = this.createOffScreenGroup(); // this.renderInner(newGroup); // this.applyOffset(); // this.updateElements(newGroup, group); // this.deleteElements(); // newGroup.destroy(); // 销毁虚拟分组 // } // 获取发生委托时的对象,在事件中抛出 GroupComponent.prototype.getDelegateObject = function () { var _a; var name = this.get('name'); var delegateObject = (_a = {}, _a[name] = this, _a.component = this, _a); return delegateObject; }; // 附加委托信息,用于事件 GroupComponent.prototype.appendDelegateObject = function (parent, cfg) { var parentObject = parent.get('delegateObject'); if (!cfg.delegateObject) { cfg.delegateObject = {}; } util_1.mix(cfg.delegateObject, parentObject); // 将父元素上的委托信息复制到自身 }; // 获取需要替换的属性,如果原先图形元素存在,而新图形不存在,则设置 undefined GroupComponent.prototype.getReplaceAttrs = function (originElement, newElement) { var originAttrs = originElement.attr(); var newAttrs = newElement.attr(); util_1.each(originAttrs, function (v, k) { if (newAttrs[k] === undefined) { newAttrs[k] = undefined; } }); return newAttrs; }; GroupComponent.prototype.registerNewGroup = function (group) { var _this = this; var children = group.getChildren(); util_1.each(children, function (element) { _this.registerElement(element); // 注册节点 element.set(STATUS_UPDATE, 'add'); // 执行完更新后设置状态位为添加 if (element.isGroup()) { _this.registerNewGroup(element); } }); }; // 移除多余的元素 GroupComponent.prototype.deleteElements = function () { var _this = this; var shapesMap = this.get('shapesMap'); var deleteArray = []; // 遍历获取需要删除的图形元素 util_1.each(shapesMap, function (element, id) { if (!element.get(STATUS_UPDATE) || element.destroyed) { deleteArray.push([id, element]); } else { element.set(STATUS_UPDATE, null); // 清理掉更新状态 } }); var animate = this.get('animate'); var animateOption = this.get('animateOption'); // 删除图形元素 util_1.each(deleteArray, function (item) { var id = item[0], element = item[1]; if (!element.destroyed) { var elementName = element.get('name'); if (animate && animateOption.leave) { // 需要动画结束时移除图形 var callbackAnimCfg = util_1.mix({ callback: function () { _this.removeElement(element); }, }, animateOption.leave); _this.removeAnimation(elementName, element, callbackAnimCfg); } else { _this.removeElement(element); } } delete shapesMap[id]; // 从缓存中移除 }); }; GroupComponent.prototype.removeElement = function (element) { if (element.get('isGroup')) { var component = element.get('component'); if (component) { component.destroy(); } } element.remove(); }; return GroupComponent; }(component_1.default)); exports.default = GroupComponent; },{"../util/event":70,"../util/matrix":73,"../util/util":77,"./component":20,"@antv/util":803,"tslib":894}],22:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dom_util_1 = require("@antv/dom-util"); var util_1 = require("@antv/util"); var util_2 = require("../util/util"); var component_1 = require("./component"); var HtmlComponent = /** @class */ (function (_super) { tslib_1.__extends(HtmlComponent, _super); function HtmlComponent() { return _super !== null && _super.apply(this, arguments) || this; } HtmlComponent.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { container: null, containerTpl: '
', updateAutoRender: true, containerClassName: '', parent: null }); return cfg; }; HtmlComponent.prototype.getContainer = function () { return this.get('container'); }; /** * 显示组件 */ HtmlComponent.prototype.show = function () { var container = this.get('container'); container.style.display = ''; this.set('visible', true); }; /** * 隐藏组件 */ HtmlComponent.prototype.hide = function () { var container = this.get('container'); container.style.display = 'none'; this.set('visible', false); }; /** * 是否允许捕捉事件 * @param capture 事件捕捉 */ HtmlComponent.prototype.setCapture = function (capture) { var container = this.getContainer(); var value = capture ? 'auto' : 'none'; container.style.pointerEvents = value; this.set('capture', capture); }; HtmlComponent.prototype.getBBox = function () { var container = this.getContainer(); var x = parseFloat(container.style.left) || 0; var y = parseFloat(container.style.top) || 0; return util_2.createBBox(x, y, container.clientWidth, container.clientHeight); }; HtmlComponent.prototype.clear = function () { var container = this.get('container'); util_2.clearDom(container); }; HtmlComponent.prototype.destroy = function () { this.removeEvent(); this.removeDom(); _super.prototype.destroy.call(this); }; /** * 复写 init,主要是初始化 DOM 和事件 */ HtmlComponent.prototype.init = function () { _super.prototype.init.call(this); this.initContainer(); this.initDom(); this.resetStyles(); // 初始化样式 this.applyStyles(); // 应用样式 this.initEvent(); this.initCapture(); this.initVisible(); }; HtmlComponent.prototype.initCapture = function () { this.setCapture(this.get('capture')); }; HtmlComponent.prototype.initVisible = function () { if (!this.get('visible')) { // 设置初始显示状态 this.hide(); } else { this.show(); } }; HtmlComponent.prototype.initDom = function () { }; HtmlComponent.prototype.initContainer = function () { var container = this.get('container'); if (util_1.isNil(container)) { // 未指定 container 则创建 container = this.createDom(); var parent_1 = this.get('parent'); if (util_1.isString(parent_1)) { parent_1 = document.getElementById(parent_1); this.set('parent', parent_1); } parent_1.appendChild(container); this.set('container', container); } else if (util_1.isString(container)) { // 用户传入的 id, 作为 container container = document.getElementById(container); this.set('container', container); } // else container 是 DOM if (!this.get('parent')) { this.set('parent', container.parentNode); } }; // 样式需要进行合并,不能单纯的替换,否则使用非常不方便 HtmlComponent.prototype.resetStyles = function () { var style = this.get('domStyles'); var defaultStyles = this.get('defaultStyles'); if (!style) { style = defaultStyles; } else { style = util_1.deepMix({}, defaultStyles, style); } this.set('domStyles', style); }; // 应用所有的样式 HtmlComponent.prototype.applyStyles = function () { var domStyles = this.get('domStyles'); if (!domStyles) { return; } var container = this.getContainer(); this.applyChildrenStyles(container, domStyles); var containerClassName = this.get('containerClassName'); if (containerClassName && util_2.hasClass(container, containerClassName)) { var containerCss = domStyles[containerClassName]; dom_util_1.modifyCSS(container, containerCss); } }; HtmlComponent.prototype.applyChildrenStyles = function (element, styles) { util_1.each(styles, function (style, name) { var elements = element.getElementsByClassName(name); util_1.each(elements, function (el) { dom_util_1.modifyCSS(el, style); }); }); }; // 应用到单个 DOM HtmlComponent.prototype.applyStyle = function (cssName, dom) { var domStyles = this.get('domStyles'); dom_util_1.modifyCSS(dom, domStyles[cssName]); }; /** * @protected */ HtmlComponent.prototype.createDom = function () { var containerTpl = this.get('containerTpl'); return dom_util_1.createDom(containerTpl); }; /** * @protected * 初始化事件 */ HtmlComponent.prototype.initEvent = function () { }; /** * @protected * 清理 DOM */ HtmlComponent.prototype.removeDom = function () { var container = this.get('container'); container && container.parentNode.removeChild(container); }; /** * @protected * 清理事件 */ HtmlComponent.prototype.removeEvent = function () { }; HtmlComponent.prototype.updateInner = function (cfg) { // 更新样式 if (util_1.hasKey(cfg, 'domStyles')) { this.resetStyles(); this.applyStyles(); } // 只要属性发生变化,都调整一些位置 this.resetPosition(); }; HtmlComponent.prototype.resetPosition = function () { }; ; return HtmlComponent; }(component_1.default)); exports.default = HtmlComponent; },{"../util/util":77,"./component":20,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var util_1 = require("../util/util"); var ArcAnnotation = /** @class */ (function (_super) { tslib_1.__extends(ArcAnnotation, _super); function ArcAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ ArcAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'arc', locationType: 'circle', center: null, radius: 100, startAngle: -Math.PI / 2, endAngle: (Math.PI * 3) / 2, style: { stroke: '#999', lineWidth: 1, } }); }; ArcAnnotation.prototype.renderInner = function (group) { this.renderArc(group); }; ArcAnnotation.prototype.getArcPath = function () { var _a = this.getLocation(), center = _a.center, radius = _a.radius, startAngle = _a.startAngle, endAngle = _a.endAngle; var startPoint = util_1.getCirclePoint(center, radius, startAngle); var endPoint = util_1.getCirclePoint(center, radius, endAngle); var largeFlag = endAngle - startAngle > Math.PI ? 1 : 0; var path = [['M', startPoint.x, startPoint.y]]; if (endAngle - startAngle === Math.PI * 2) { // 整个圆是分割成两个圆 var middlePoint = util_1.getCirclePoint(center, radius, startAngle + Math.PI); path.push(['A', radius, radius, 0, largeFlag, 1, middlePoint.x, middlePoint.y]); path.push(['A', radius, radius, 0, largeFlag, 1, endPoint.x, endPoint.y]); } else { path.push(['A', radius, radius, 0, largeFlag, 1, endPoint.x, endPoint.y]); } return path; }; // 绘制 arc ArcAnnotation.prototype.renderArc = function (group) { // 也可以 通过 get('center') 类似的方式逐个获取 var path = this.getArcPath(); var style = this.get('style'); this.addShape(group, { type: 'path', id: this.getElementId('arc'), name: 'annotation-arc', attrs: tslib_1.__assign({ path: path }, style), }); }; return ArcAnnotation; }(group_component_1.default)); exports.default = ArcAnnotation; },{"../abstract/group-component":21,"../util/util":77,"tslib":894}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var graphic_1 = require("../util/graphic"); var matrix_1 = require("../util/matrix"); var theme_1 = require("../util/theme"); var DataMarkerAnnotation = /** @class */ (function (_super) { tslib_1.__extends(DataMarkerAnnotation, _super); function DataMarkerAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * 默认的配置项 * @returns {object} 默认的配置项 */ DataMarkerAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'dataMarker', locationType: 'point', x: 0, y: 0, point: {}, line: {}, text: {}, direction: 'upward', autoAdjust: true, coordinateBBox: null, defaultCfg: { point: { display: true, style: { r: 3, fill: '#FFFFFF', stroke: '#1890FF', lineWidth: 2, }, }, line: { display: true, length: 20, style: { stroke: theme_1.default.lineColor, lineWidth: 1, }, }, text: { content: '', display: true, style: { fill: theme_1.default.textColor, opacity: 0.65, fontSize: 12, textAlign: 'start', fontFamily: theme_1.default.fontFamily, }, }, } }); }; DataMarkerAnnotation.prototype.renderInner = function (group) { if (util_1.get(this.get('line'), 'display')) { this.renderLine(group); } if (util_1.get(this.get('text'), 'display')) { this.renderText(group); } if (util_1.get(this.get('point'), 'display')) { this.renderPoint(group); } if (this.get('autoAdjust')) { this.autoAdjust(group); } }; DataMarkerAnnotation.prototype.applyOffset = function () { this.moveElementTo(this.get('group'), { x: this.get('x') + this.get('offsetX'), y: this.get('y') + this.get('offsetY'), }); }; DataMarkerAnnotation.prototype.renderPoint = function (group) { var point = this.getShapeAttrs().point; this.addShape(group, { type: 'circle', id: this.getElementId('point'), name: 'annotation-point', attrs: point, }); }; DataMarkerAnnotation.prototype.renderLine = function (group) { var line = this.getShapeAttrs().line; this.addShape(group, { type: 'path', id: this.getElementId('line'), name: 'annotation-line', attrs: line, }); }; DataMarkerAnnotation.prototype.renderText = function (group) { var textAttrs = this.getShapeAttrs().text; var x = textAttrs.x, y = textAttrs.y, text = textAttrs.text, style = tslib_1.__rest(textAttrs, ["x", "y", "text"]); var _a = this.get('text'), background = _a.background, maxLength = _a.maxLength, autoEllipsis = _a.autoEllipsis, isVertival = _a.isVertival, ellipsisPosition = _a.ellipsisPosition; var tagCfg = { x: x, y: y, id: this.getElementId('text'), name: 'annotation-text', content: text, style: style, background: background, maxLength: maxLength, autoEllipsis: autoEllipsis, isVertival: isVertival, ellipsisPosition: ellipsisPosition, }; graphic_1.renderTag(group, tagCfg); }; DataMarkerAnnotation.prototype.autoAdjust = function (group) { var direction = this.get('direction'); var x = this.get('x'); var y = this.get('y'); var lineLength = util_1.get(this.get('line'), 'length', 0); var coordinateBBox = this.get('coordinateBBox'); var _a = group.getBBox(), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY; var textGroup = group.findById(this.getElementId('text-group')); var textShape = group.findById(this.getElementId('text')); var lineShape = group.findById(this.getElementId('line')); if (!coordinateBBox) { return; } if (textGroup) { if (x + minX <= coordinateBBox.minX) { // 左侧超出 var overflow = coordinateBBox.minX - (x + minX); matrix_1.applyTranslate(textGroup, textGroup.attr('x') + overflow, textGroup.attr('y')); } if (x + maxX >= coordinateBBox.maxX) { // 右侧超出 var overflow = x + maxX - coordinateBBox.maxX; matrix_1.applyTranslate(textGroup, textGroup.attr('x') - overflow, textGroup.attr('y')); } } if ((direction === 'upward' && y + minY <= coordinateBBox.minY) || (direction !== 'upward' && y + maxY >= coordinateBBox.maxY)) { // 上方或者下方超出 var textBaseline = void 0; var factor = void 0; if (direction === 'upward' && y + minY <= coordinateBBox.minY) { textBaseline = 'top'; factor = 1; } else { textBaseline = 'bottom'; factor = -1; } textShape.attr('textBaseline', textBaseline); if (lineShape) { lineShape.attr('path', [ ['M', 0, 0], ['L', 0, lineLength * factor], ]); } matrix_1.applyTranslate(textGroup, textGroup.attr('x'), (lineLength + 2) * factor); } }; DataMarkerAnnotation.prototype.getShapeAttrs = function () { var lineDisplay = util_1.get(this.get('line'), 'display'); var pointStyle = util_1.get(this.get('point'), 'style', {}); var lineStyle = util_1.get(this.get('line'), 'style', {}); var textStyle = util_1.get(this.get('text'), 'style', {}); var direction = this.get('direction'); var lineLength = lineDisplay ? util_1.get(this.get('line'), 'length', 0) : 0; var factor = direction === 'upward' ? -1 : 1; return { point: tslib_1.__assign({ x: 0, y: 0 }, pointStyle), line: tslib_1.__assign({ path: [ ['M', 0, 0], ['L', 0, lineLength * factor], ] }, lineStyle), text: tslib_1.__assign({ x: 0, y: (lineLength + 2) * factor, text: util_1.get(this.get('text'), 'content', ''), textBaseline: direction === 'upward' ? 'bottom' : 'top' }, textStyle), }; }; return DataMarkerAnnotation; }(group_component_1.default)); exports.default = DataMarkerAnnotation; },{"../abstract/group-component":21,"../util/graphic":71,"../util/matrix":73,"../util/theme":76,"@antv/util":803,"tslib":894}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var theme_1 = require("../util/theme"); var util_2 = require("../util/util"); var graphic_1 = require("../util/graphic"); var DataRegionAnnotation = /** @class */ (function (_super) { tslib_1.__extends(DataRegionAnnotation, _super); function DataRegionAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * 默认的配置项 * @returns {object} 默认的配置项 */ DataRegionAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'dataRegion', locationType: 'points', points: [], lineLength: 0, region: {}, text: {}, defaultCfg: { region: { style: { lineWidth: 0, fill: theme_1.default.regionColor, opacity: 0.4, }, }, text: { content: '', style: { textAlign: 'center', textBaseline: 'bottom', fontSize: 12, fill: theme_1.default.textColor, fontFamily: theme_1.default.fontFamily, }, }, } }); }; DataRegionAnnotation.prototype.renderInner = function (group) { var regionStyle = util_1.get(this.get('region'), 'style', {}); var textStyle = util_1.get(this.get('text'), 'style', {}); var lineLength = this.get('lineLength') || 0; var points = this.get('points'); if (!points.length) { return; } var bbox = util_2.pointsToBBox(points); // render region var path = []; path.push(['M', points[0].x, bbox.minY - lineLength]); points.forEach(function (point) { path.push(['L', point.x, point.y]); }); path.push(['L', points[points.length - 1].x, points[points.length - 1].y - lineLength]); this.addShape(group, { type: 'path', id: this.getElementId('region'), name: 'annotation-region', attrs: tslib_1.__assign({ path: path }, regionStyle), }); // render text var textCfg = tslib_1.__assign({ id: this.getElementId('text'), name: 'annotation-text', x: (bbox.minX + bbox.maxX) / 2, y: bbox.minY - lineLength }, this.get('text')); graphic_1.renderTag(group, textCfg); }; return DataRegionAnnotation; }(group_component_1.default)); exports.default = DataRegionAnnotation; },{"../abstract/group-component":21,"../util/graphic":71,"../util/theme":76,"../util/util":77,"@antv/util":803,"tslib":894}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var util_1 = require("../util/util"); var ImageAnnotation = /** @class */ (function (_super) { tslib_1.__extends(ImageAnnotation, _super); function ImageAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ ImageAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'image', locationType: 'region', start: null, end: null, src: null, style: {} }); }; ImageAnnotation.prototype.renderInner = function (group) { this.renderImage(group); }; ImageAnnotation.prototype.getImageAttrs = function () { var start = this.get('start'); var end = this.get('end'); var style = this.get('style'); var bbox = util_1.regionToBBox({ start: start, end: end }); var src = this.get('src'); return tslib_1.__assign({ x: bbox.x, y: bbox.y, img: src, width: bbox.width, height: bbox.height }, style); }; // 绘制图片 ImageAnnotation.prototype.renderImage = function (group) { this.addShape(group, { type: 'image', id: this.getElementId('image'), name: 'annotation-image', attrs: this.getImageAttrs(), }); }; return ImageAnnotation; }(group_component_1.default)); exports.default = ImageAnnotation; },{"../abstract/group-component":21,"../util/util":77,"tslib":894}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("./line"); Object.defineProperty(exports, "Line", { enumerable: true, get: function () { return line_1.default; } }); var text_1 = require("./text"); Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return text_1.default; } }); var arc_1 = require("./arc"); Object.defineProperty(exports, "Arc", { enumerable: true, get: function () { return arc_1.default; } }); var region_1 = require("./region"); Object.defineProperty(exports, "Region", { enumerable: true, get: function () { return region_1.default; } }); var image_1 = require("./image"); Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return image_1.default; } }); var data_marker_1 = require("./data-marker"); Object.defineProperty(exports, "DataMarker", { enumerable: true, get: function () { return data_marker_1.default; } }); var data_region_1 = require("./data-region"); Object.defineProperty(exports, "DataRegion", { enumerable: true, get: function () { return data_region_1.default; } }); var region_filter_1 = require("./region-filter"); Object.defineProperty(exports, "RegionFilter", { enumerable: true, get: function () { return region_filter_1.default; } }); },{"./arc":23,"./data-marker":24,"./data-region":25,"./image":26,"./line":28,"./region":30,"./region-filter":29,"./text":31}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var graphic_1 = require("../util/graphic"); var theme_1 = require("../util/theme"); var util_2 = require("../util/util"); var LineAnnotation = /** @class */ (function (_super) { tslib_1.__extends(LineAnnotation, _super); function LineAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ LineAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'line', locationType: 'region', start: null, end: null, style: {}, text: null, defaultCfg: { style: { fill: theme_1.default.textColor, fontSize: 12, textAlign: 'center', textBaseline: 'bottom', fontFamily: theme_1.default.fontFamily, }, text: { position: 'center', autoRotate: true, content: null, offsetX: 0, offsetY: 0, style: { stroke: theme_1.default.lineColor, lineWidth: 1, }, }, } }); }; LineAnnotation.prototype.renderInner = function (group) { this.renderLine(group); if (this.get('text')) { this.renderLabel(group); } }; // 绘制线 LineAnnotation.prototype.renderLine = function (group) { var start = this.get('start'); var end = this.get('end'); var style = this.get('style'); this.addShape(group, { type: 'line', id: this.getElementId('line'), name: 'annotation-line', attrs: tslib_1.__assign({ x1: start.x, y1: start.y, x2: end.x, y2: end.y }, style), }); }; // 获取 label 的位置 LineAnnotation.prototype.getLabelPoint = function (start, end, position) { var percent; if (position === 'start') { percent = 0; } else if (position === 'center') { percent = 0.5; } else if (util_1.isString(position) && position.indexOf('%') !== -1) { percent = parseInt(position, 10) / 100; } else if (util_1.isNumber(position)) { percent = position; } else { percent = 1; } if (percent > 1 || percent < 0) { percent = 1; } return { x: util_2.getValueByPercent(start.x, end.x, percent), y: util_2.getValueByPercent(start.y, end.y, percent), }; }; // 绘制 label LineAnnotation.prototype.renderLabel = function (group) { var text = this.get('text'); var start = this.get('start'); var end = this.get('end'); var position = text.position, content = text.content, style = text.style, offsetX = text.offsetX, offsetY = text.offsetY, autoRotate = text.autoRotate, maxLength = text.maxLength, autoEllipsis = text.autoEllipsis, ellipsisPosition = text.ellipsisPosition, background = text.background, _a = text.isVertical, isVertical = _a === void 0 ? false : _a; var point = this.getLabelPoint(start, end, position); var x = point.x + offsetX; var y = point.y + offsetY; var cfg = { id: this.getElementId('line-text'), name: 'annotation-line-text', x: x, y: y, content: content, style: style, maxLength: maxLength, autoEllipsis: autoEllipsis, ellipsisPosition: ellipsisPosition, background: background, isVertical: isVertical, }; // 如果自动旋转 if (autoRotate) { var vector = [end.x - start.x, end.y - start.y]; cfg.rotate = Math.atan2(vector[1], vector[0]); } graphic_1.renderTag(group, cfg); }; return LineAnnotation; }(group_component_1.default)); exports.default = LineAnnotation; },{"../abstract/group-component":21,"../util/graphic":71,"../util/theme":76,"../util/util":77,"@antv/util":803,"tslib":894}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var util_2 = require("../util/util"); var RegionFilterAnnotation = /** @class */ (function (_super) { tslib_1.__extends(RegionFilterAnnotation, _super); function RegionFilterAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * 默认的配置项 * @returns {object} 默认的配置项 */ RegionFilterAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'regionFilter', locationType: 'region', start: null, end: null, color: null, shape: [] }); }; RegionFilterAnnotation.prototype.renderInner = function (group) { var _this = this; var start = this.get('start'); var end = this.get('end'); // 1. add region layer var layer = this.addGroup(group, { id: this.getElementId('region-filter'), capture: false, }); // 2. clone shape & color it util_1.each(this.get('shapes'), function (shape, shapeIdx) { var type = shape.get('type'); var attrs = util_1.clone(shape.attr()); _this.adjustShapeAttrs(attrs); _this.addShape(layer, { id: _this.getElementId("shape-" + type + "-" + shapeIdx), capture: false, type: type, attrs: attrs, }); }); // 3. clip var clipBBox = util_2.regionToBBox({ start: start, end: end }); layer.setClip({ type: 'rect', attrs: { x: clipBBox.minX, y: clipBBox.minY, width: clipBBox.width, height: clipBBox.height, }, }); }; RegionFilterAnnotation.prototype.adjustShapeAttrs = function (attr) { var color = this.get('color'); if (attr.fill) { attr.fill = attr.fillStyle = color; } attr.stroke = attr.strokeStyle = color; }; return RegionFilterAnnotation; }(group_component_1.default)); exports.default = RegionFilterAnnotation; },{"../abstract/group-component":21,"../util/util":77,"@antv/util":803,"tslib":894}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var theme_1 = require("../util/theme"); var util_1 = require("../util/util"); var RegionAnnotation = /** @class */ (function (_super) { tslib_1.__extends(RegionAnnotation, _super); function RegionAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ RegionAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'region', locationType: 'region', start: null, end: null, style: {}, defaultCfg: { style: { lineWidth: 0, fill: theme_1.default.regionColor, opacity: 0.4, }, } }); }; RegionAnnotation.prototype.renderInner = function (group) { this.renderRegion(group); }; RegionAnnotation.prototype.renderRegion = function (group) { var start = this.get('start'); var end = this.get('end'); var style = this.get('style'); var bbox = util_1.regionToBBox({ start: start, end: end }); this.addShape(group, { type: 'rect', id: this.getElementId('region'), name: 'annotation-region', attrs: tslib_1.__assign({ x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height }, style), }); }; return RegionAnnotation; }(group_component_1.default)); exports.default = RegionAnnotation; },{"../abstract/group-component":21,"../util/theme":76,"../util/util":77,"tslib":894}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var graphic_1 = require("../util/graphic"); var matrix_1 = require("../util/matrix"); var theme_1 = require("../util/theme"); var TextAnnotation = /** @class */ (function (_super) { tslib_1.__extends(TextAnnotation, _super); function TextAnnotation() { return _super !== null && _super.apply(this, arguments) || this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ TextAnnotation.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'annotation', type: 'text', locationType: 'point', x: 0, y: 0, content: '', rotate: null, style: {}, background: null, maxLength: null, autoEllipsis: true, isVertical: false, ellipsisPosition: 'tail', defaultCfg: { style: { fill: theme_1.default.textColor, fontSize: 12, textAlign: 'center', textBaseline: 'middle', fontFamily: theme_1.default.fontFamily, }, } }); }; // 复写 setLocation 方法,不需要重新创建 text TextAnnotation.prototype.setLocation = function (location) { this.set('x', location.x); this.set('y', location.y); this.resetLocation(); }; TextAnnotation.prototype.renderInner = function (group) { var _a = this.getLocation(), x = _a.x, y = _a.y; var content = this.get('content'); var style = this.get('style'); var id = this.getElementId('text'); var name = this.get('name') + "-text"; var maxLength = this.get('maxLength'); var autoEllipsis = this.get('autoEllipsis'); var isVertical = this.get('isVertical'); var ellipsisPosition = this.get('ellipsisPosition'); var background = this.get('background'); var rotate = this.get('rotate'); var cfg = { id: id, name: name, x: x, y: y, content: content, style: style, maxLength: maxLength, autoEllipsis: autoEllipsis, isVertical: isVertical, ellipsisPosition: ellipsisPosition, background: background, rotate: rotate, }; graphic_1.renderTag(group, cfg); }; TextAnnotation.prototype.resetLocation = function () { var textGroup = this.getElementByLocalId('text-group'); if (textGroup) { var _a = this.getLocation(), x = _a.x, y = _a.y; var rotate = this.get('rotate'); matrix_1.applyTranslate(textGroup, x, y); matrix_1.applyRotate(textGroup, rotate, x, y); } }; return TextAnnotation; }(group_component_1.default)); exports.default = TextAnnotation; },{"../abstract/group-component":21,"../util/graphic":71,"../util/matrix":73,"../util/theme":76,"tslib":894}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var matrix_1 = require("../util/matrix"); var state_1 = require("../util/state"); var theme_1 = require("../util/theme"); var AxisBase = /** @class */ (function (_super) { tslib_1.__extends(AxisBase, _super); function AxisBase() { return _super !== null && _super.apply(this, arguments) || this; } AxisBase.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'axis', ticks: [], line: {}, tickLine: {}, subTickLine: null, title: null, /** * 文本标签的配置项 */ label: {}, /** * 垂直于坐标轴方向的因子,决定文本、title、tickLine 在坐标轴的哪一侧 */ verticalFactor: 1, // 垂直方向限制的长度,对文本自适应有很大影响 verticalLimitLength: null, overlapOrder: ['autoRotate', 'autoEllipsis', 'autoHide'], tickStates: {}, defaultCfg: { line: { // @type {Attrs} 坐标轴线的图形属性,如果设置成null,则不显示轴线 style: { lineWidth: 1, stroke: theme_1.default.lineColor, }, }, tickLine: { // @type {Attrs} 标注坐标线的图形属性 style: { lineWidth: 1, stroke: theme_1.default.lineColor, }, alignTick: true, length: 5, displayWithLabel: true, }, subTickLine: { // @type {Attrs} 标注坐标线的图形属性 style: { lineWidth: 1, stroke: theme_1.default.lineColor, }, count: 4, length: 2, }, label: { autoRotate: true, autoHide: false, autoEllipsis: false, style: { fontSize: 12, fill: theme_1.default.textColor, textBaseline: 'middle', fontFamily: theme_1.default.fontFamily, fontWeight: 'normal', }, offset: 10, }, title: { autoRotate: true, spacing: 5, position: 'center', style: { fontSize: 12, fill: theme_1.default.textColor, textBaseline: 'middle', fontFamily: theme_1.default.fontFamily, textAlign: 'center', }, }, tickStates: { active: { labelStyle: { fontWeight: 500, }, tickLineStyle: { lineWidth: 2, }, }, inactive: { labelStyle: { fill: theme_1.default.uncheckedColor, }, }, }, } }); }; /** * 绘制组件 */ AxisBase.prototype.renderInner = function (group) { if (this.get('line')) { this.drawLine(group); } // drawTicks 包括 drawLabels 和 drawTickLines this.drawTicks(group); if (this.get('title')) { this.drawTitle(group); } }; // 实现 IList 接口 AxisBase.prototype.isList = function () { return true; }; /** * 获取图例项 * @return {ListItem[]} 列表项集合 */ AxisBase.prototype.getItems = function () { return this.get('ticks'); }; /** * 设置列表项 * @param {ListItem[]} items 列表项集合 */ AxisBase.prototype.setItems = function (items) { this.update({ ticks: items, }); }; /** * 更新列表项 * @param {ListItem} item 列表项 * @param {object} cfg 列表项 */ AxisBase.prototype.updateItem = function (item, cfg) { util_1.mix(item, cfg); this.clear(); // 由于单个图例项变化,会引起全局变化,所以全部更新 this.render(); }; /** * 清空列表 */ AxisBase.prototype.clearItems = function () { var itemGroup = this.getElementByLocalId('label-group'); itemGroup && itemGroup.clear(); }; /** * 设置列表项的状态 * @param {ListItem} item 列表项 * @param {string} state 状态名 * @param {boolean} value 状态值, true, false */ AxisBase.prototype.setItemState = function (item, state, value) { item[state] = value; this.updateTickStates(item); // 应用状态样式 }; /** * 是否存在指定的状态 * @param {ListItem} item 列表项 * @param {boolean} state 状态名 */ AxisBase.prototype.hasState = function (item, state) { return !!item[state]; }; AxisBase.prototype.getItemStates = function (item) { var tickStates = this.get('tickStates'); var rst = []; util_1.each(tickStates, function (v, k) { if (item[k]) { // item.selected rst.push(k); } }); return rst; }; /** * 清楚所有列表项的状态 * @param {string} state 状态值 */ AxisBase.prototype.clearItemsState = function (state) { var _this = this; var items = this.getItemsByState(state); util_1.each(items, function (item) { _this.setItemState(item, state, false); }); }; /** * 根据状态获取图例项 * @param {string} state [description] * @return {ListItem[]} [description] */ AxisBase.prototype.getItemsByState = function (state) { var _this = this; var items = this.getItems(); return util_1.filter(items, function (item) { return _this.hasState(item, state); }); }; AxisBase.prototype.getSidePoint = function (point, offset) { var self = this; var vector = self.getSideVector(offset, point); return { x: point.x + vector[0], y: point.y + vector[1], }; }; AxisBase.prototype.getTextAnchor = function (vector) { var align; if (util_1.isNumberEqual(vector[0], 0)) { align = 'center'; } else if (vector[0] > 0) { align = 'start'; } else if (vector[0] < 0) { align = 'end'; } return align; }; AxisBase.prototype.processOverlap = function (labelGroup) { }; // 绘制坐标轴线 AxisBase.prototype.drawLine = function (group) { var path = this.getLinePath(); var line = this.get('line'); // line 的判空在调用 drawLine 之前,不在这里判定 this.addShape(group, { type: 'path', id: this.getElementId('line'), name: 'axis-line', attrs: util_1.mix({ path: path, }, line.style), }); }; AxisBase.prototype.getTickLineItems = function (ticks) { var _this = this; var tickLineItems = []; var tickLine = this.get('tickLine'); var alignTick = tickLine.alignTick; var tickLineLength = tickLine.length; var tickSegment = 1; var tickCount = ticks.length; if (tickCount >= 2) { tickSegment = ticks[1].value - ticks[0].value; } util_1.each(ticks, function (tick) { var point = tick.point; if (!alignTick) { // tickLine 不同 tick 对齐时需要调整 point point = _this.getTickPoint(tick.value - tickSegment / 2); } var endPoint = _this.getSidePoint(point, tickLineLength); tickLineItems.push({ startPoint: point, tickValue: tick.value, endPoint: endPoint, tickId: tick.id, id: "tickline-" + tick.id, }); }); // 如果 tickLine 不居中对齐,则需要在最后面补充一个 tickLine // if (!alignTick && tickCount > 0) { // const tick = ticks[tickCount - 1]; // const point = this.getTickPoint(tick.value + tickSegment / 2); // } return tickLineItems; }; AxisBase.prototype.getSubTickLineItems = function (tickLineItems) { var subTickLineItems = []; var subTickLine = this.get('subTickLine'); var subCount = subTickLine.count; var tickLineCount = tickLineItems.length; // 刻度线的数量大于 2 时,才绘制子刻度 if (tickLineCount >= 2) { for (var i = 0; i < tickLineCount - 1; i++) { var pre = tickLineItems[i]; var next = tickLineItems[i + 1]; for (var j = 0; j < subCount; j++) { var percent = (j + 1) / (subCount + 1); var tickValue = (1 - percent) * pre.tickValue + percent * next.tickValue; var point = this.getTickPoint(tickValue); var endPoint = this.getSidePoint(point, subTickLine.length); subTickLineItems.push({ startPoint: point, endPoint: endPoint, tickValue: tickValue, id: "sub-" + pre.id + "-" + j, }); } } } return subTickLineItems; }; AxisBase.prototype.getTickLineAttrs = function (tickItem, type) { var tickLineStyle = this.get(type).style; var startPoint = tickItem.startPoint, endPoint = tickItem.endPoint; var attrs = util_1.mix({ x1: startPoint.x, y1: startPoint.y, x2: endPoint.x, y2: endPoint.y, }, tickLineStyle); return attrs; }; // 绘制坐标轴刻度线 AxisBase.prototype.drawTick = function (tickItem, tickLineGroup, type) { this.addShape(tickLineGroup, { type: 'line', id: this.getElementId(tickItem.id), name: "axis-" + type, attrs: this.getTickLineAttrs(tickItem, type), }); }; // 绘制坐标轴刻度线,包括子刻度线 AxisBase.prototype.drawTickLines = function (group) { var _this = this; var ticks = this.get('ticks'); var subTickLine = this.get('subTickLine'); var tickLineItems = this.getTickLineItems(ticks); var tickLineGroup = this.addGroup(group, { name: 'axis-tickline-group', id: this.getElementId('tickline-group'), }); var tickCfg = this.get('tickLine'); util_1.each(tickLineItems, function (item) { if (tickCfg.displayWithLabel) { // 如果跟随 label 显示,则检测是否存在对应的 label var labelId = _this.getElementId("label-" + item.tickId); if (group.findById(labelId)) { _this.drawTick(item, tickLineGroup, 'tickLine'); } } else { _this.drawTick(item, tickLineGroup, 'tickLine'); } }); if (subTickLine) { var subTickLineItems = this.getSubTickLineItems(tickLineItems); util_1.each(subTickLineItems, function (item) { _this.drawTick(item, tickLineGroup, 'subTickLine'); }); } }; // 预处理 ticks 确定位置和补充 id AxisBase.prototype.processTicks = function () { var _this = this; var ticks = this.get('ticks'); util_1.each(ticks, function (tick) { tick.point = _this.getTickPoint(tick.value); // 补充 tick 的 id,为动画和更新做准备 if (util_1.isNil(tick.id)) { // 默认使用 tick.name 作为id tick.id = tick.name; } }); }; // 绘制 ticks 包括文本和 tickLine AxisBase.prototype.drawTicks = function (group) { var _this = this; this.processTicks(); if (this.get('label')) { this.drawLabels(group); } if (this.get('tickLine')) { this.drawTickLines(group); } var ticks = this.get('ticks'); util_1.each(ticks, function (tick) { _this.applyTickStates(tick, group); }); }; // 获取 label 的配置项 AxisBase.prototype.getLabelAttrs = function (tick, index) { var labelCfg = this.get('label'); var offset = labelCfg.offset, style = labelCfg.style, rotate = labelCfg.rotate, formatter = labelCfg.formatter; var point = this.getSidePoint(tick.point, offset); var vector = this.getSideVector(offset, point); var text = formatter ? formatter(tick.name, tick, index) : tick.name; var attrs = util_1.mix({ x: point.x, y: point.y, text: text, textAlign: this.getTextAnchor(vector), }, style); if (rotate) { attrs.matrix = matrix_1.getMatrixByAngle(point, rotate); } return attrs; }; // 绘制文本 AxisBase.prototype.drawLabels = function (group) { var _this = this; var ticks = this.get('ticks'); var labelGroup = this.addGroup(group, { name: 'axis-label-group', id: this.getElementId('label-group'), }); util_1.each(ticks, function (tick, index) { _this.addShape(labelGroup, { type: 'text', name: 'axis-label', id: _this.getElementId("label-" + tick.id), attrs: _this.getLabelAttrs(tick, index), delegateObject: { tick: tick, item: tick, index: index, }, }); }); this.processOverlap(labelGroup); }; // 标题的属性 AxisBase.prototype.getTitleAttrs = function () { var titleCfg = this.get('title'); var style = titleCfg.style, position = titleCfg.position, offset = titleCfg.offset, _a = titleCfg.spacing, spacing = _a === void 0 ? 0 : _a, autoRotate = titleCfg.autoRotate; var titleHeight = style.fontSize; var percent = 0.5; if (position === 'start') { percent = 0; } else if (position === 'end') { percent = 1; } var point = this.getTickPoint(percent); // 标题对应的坐标轴上的点 // 如果没有指定 titleOffset 也没有渲染 label,这里需要自动计算 offset var titlePoint = this.getSidePoint(point, offset || spacing + titleHeight / 2); // 标题的点 var attrs = util_1.mix({ x: titlePoint.x, y: titlePoint.y, text: titleCfg.text, }, style); var rotate = titleCfg.rotate; // rotate 是角度值 var angle = rotate; if (util_1.isNil(rotate) && autoRotate) { // 用户没有设定旋转角度,同时设置自动旋转 var vector = this.getAxisVector(point); var v1 = [1, 0]; // 水平方向的向量 angle = matrix_util_1.ext.angleTo(vector, v1, true); } if (angle) { var matrix = matrix_1.getMatrixByAngle(titlePoint, angle); attrs.matrix = matrix; } return attrs; }; // 绘制标题 AxisBase.prototype.drawTitle = function (group) { this.addShape(group, { type: 'text', id: this.getElementId('title'), name: 'axis-title', attrs: this.getTitleAttrs(), }); }; AxisBase.prototype.applyTickStates = function (tick, group) { var states = this.getItemStates(tick); if (states.length) { var tickStates = this.get('tickStates'); // 分别更新 label 和 tickLine var labelId = this.getElementId("label-" + tick.id); var labelShape = group.findById(labelId); if (labelShape) { var labelStateStyle = state_1.getStatesStyle(tick, 'label', tickStates); labelStateStyle && labelShape.attr(labelStateStyle); } var tickLineId = this.getElementId("tickline-" + tick.id); var tickLineShape = group.findById(tickLineId); if (tickLineShape) { var tickLineStateStyle = state_1.getStatesStyle(tick, 'tickLine', tickStates); tickLineStateStyle && tickLineShape.attr(tickLineStateStyle); } } }; AxisBase.prototype.updateTickStates = function (tick) { var states = this.getItemStates(tick); var tickStates = this.get('tickStates'); var labelCfg = this.get('label'); var labelShape = this.getElementByLocalId("label-" + tick.id); var tickLineCfg = this.get('tickLine'); var tickLineShape = this.getElementByLocalId("tickline-" + tick.id); if (states.length) { if (labelShape) { var labelStateStyle = state_1.getStatesStyle(tick, 'label', tickStates); labelStateStyle && labelShape.attr(labelStateStyle); } if (tickLineShape) { var tickLineStateStyle = state_1.getStatesStyle(tick, 'tickLine', tickStates); tickLineStateStyle && tickLineShape.attr(tickLineStateStyle); } } else { if (labelShape) { labelShape.attr(labelCfg.style); } if (tickLineShape) { tickLineShape.attr(tickLineCfg.style); } } }; return AxisBase; }(group_component_1.default)); exports.default = AxisBase; },{"../abstract/group-component":21,"../util/matrix":73,"../util/state":74,"../util/theme":76,"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var base_1 = require("./base"); var Circle = /** @class */ (function (_super) { tslib_1.__extends(Circle, _super); function Circle() { return _super !== null && _super.apply(this, arguments) || this; } Circle.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'circle', locationType: 'circle', center: null, radius: null, startAngle: -Math.PI / 2, endAngle: (Math.PI * 3) / 2 }); }; Circle.prototype.getLinePath = function () { var center = this.get('center'); var x = center.x; var y = center.y; var rx = this.get('radius'); var ry = rx; var startAngle = this.get('startAngle'); var endAngle = this.get('endAngle'); var path = []; if (Math.abs(endAngle - startAngle) === Math.PI * 2) { path = [['M', x, y - ry], ['A', rx, ry, 0, 1, 1, x, y + ry], ['A', rx, ry, 0, 1, 1, x, y - ry], ['Z']]; } else { var startPoint = this.getCirclePoint(startAngle); var endPoint = this.getCirclePoint(endAngle); var large = Math.abs(endAngle - startAngle) > Math.PI ? 1 : 0; var sweep = startAngle > endAngle ? 0 : 1; path = [ ['M', x, y], ['L', startPoint.x, startPoint.y], ['A', rx, ry, 0, large, sweep, endPoint.x, endPoint.y], ['L', x, y], ]; } return path; }; Circle.prototype.getTickPoint = function (tickValue) { var startAngle = this.get('startAngle'); var endAngle = this.get('endAngle'); var angle = startAngle + (endAngle - startAngle) * tickValue; return this.getCirclePoint(angle); }; // 获取垂直于坐标轴的向量 Circle.prototype.getSideVector = function (offset, point) { var center = this.get('center'); var vector = [point.x - center.x, point.y - center.y]; var factor = this.get('verticalFactor'); var vecLen = matrix_util_1.vec2.length(vector); matrix_util_1.vec2.scale(vector, vector, (factor * offset) / vecLen); return vector; }; // 获取沿坐标轴方向的向量 Circle.prototype.getAxisVector = function (point) { var center = this.get('center'); var vector = [point.x - center.x, point.y - center.y]; return [vector[1], -1 * vector[0]]; // 获取顺时针方向的向量 }; // 根据圆心和半径获取点 Circle.prototype.getCirclePoint = function (angle, radius) { var center = this.get('center'); radius = radius || this.get('radius'); return { x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius, }; }; return Circle; }(base_1.default)); exports.default = Circle; },{"./base":32,"@antv/matrix-util":717,"tslib":894}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("./line"); Object.defineProperty(exports, "Line", { enumerable: true, get: function () { return line_1.default; } }); var circle_1 = require("./circle"); Object.defineProperty(exports, "Circle", { enumerable: true, get: function () { return circle_1.default; } }); var base_1 = require("./base"); Object.defineProperty(exports, "Base", { enumerable: true, get: function () { return base_1.default; } }); },{"./base":32,"./circle":33,"./line":35}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var OverlapUtil = require("./overlap"); var Line = /** @class */ (function (_super) { tslib_1.__extends(Line, _super); function Line() { return _super !== null && _super.apply(this, arguments) || this; } Line.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'line', locationType: 'region', /** * 起始点, x, y * @type {object} */ start: null, /** * 结束点, x, y * @type {object} */ end: null }); }; // 获取坐标轴线的 path Line.prototype.getLinePath = function () { var start = this.get('start'); var end = this.get('end'); var path = []; path.push(['M', start.x, start.y]); path.push(['L', end.x, end.y]); return path; }; // 重新计算 layout bbox,考虑到 line 不显示 Line.prototype.getInnerLayoutBBox = function () { var start = this.get('start'); var end = this.get('end'); var bbox = _super.prototype.getInnerLayoutBBox.call(this); var minX = Math.min(start.x, end.x, bbox.x); var minY = Math.min(start.y, end.y, bbox.y); var maxX = Math.max(start.x, end.x, bbox.maxX); var maxY = Math.max(start.y, end.y, bbox.maxY); return { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; }; Line.prototype.isVertical = function () { var start = this.get('start'); var end = this.get('end'); return util_1.isNumberEqual(start.x, end.x); }; Line.prototype.isHorizontal = function () { var start = this.get('start'); var end = this.get('end'); return util_1.isNumberEqual(start.y, end.y); }; Line.prototype.getTickPoint = function (tickValue) { var self = this; var start = self.get('start'); var end = self.get('end'); var regionX = end.x - start.x; var regionY = end.y - start.y; return { x: start.x + regionX * tickValue, y: start.y + regionY * tickValue, }; }; // 直线坐标轴下任一点的向量方向都相同 Line.prototype.getSideVector = function (offset) { var axisVector = this.getAxisVector(); var normal = matrix_util_1.vec2.normalize([0, 0], axisVector); var factor = this.get('verticalFactor'); var verticalVector = [normal[1], normal[0] * -1]; // 垂直方向,逆时针方向 return matrix_util_1.vec2.scale([0, 0], verticalVector, offset * factor); }; // 获取坐标轴的向量 Line.prototype.getAxisVector = function () { var start = this.get('start'); var end = this.get('end'); return [end.x - start.x, end.y - start.y]; }; Line.prototype.processOverlap = function (labelGroup) { var _this = this; var isVertical = this.isVertical(); var isHorizontal = this.isHorizontal(); // 非垂直,或者非水平时不处理遮挡问题 if (!isVertical && !isHorizontal) { return; } var labelCfg = this.get('label'); var titleCfg = this.get('title'); var verticalLimitLength = this.get('verticalLimitLength'); var labelOffset = labelCfg.offset; var limitLength = verticalLimitLength; var titleHeight = 0; var titleSpacing = 0; if (titleCfg) { titleHeight = titleCfg.style.fontSize; titleSpacing = titleCfg.spacing; } if (limitLength) { limitLength = limitLength - labelOffset - titleSpacing - titleHeight; } var overlapOrder = this.get('overlapOrder'); util_1.each(overlapOrder, function (name) { if (labelCfg[name]) { _this.autoProcessOverlap(name, labelCfg[name], labelGroup, limitLength); } }); if (titleCfg) { // 调整 title 的 offset var bbox = labelGroup.getBBox(); var length_1 = isVertical ? bbox.width : bbox.height; if (util_1.isNil(titleCfg.offset)) { // 如果用户没有设置 offset,则自动计算 titleCfg.offset = labelOffset + length_1 + titleSpacing + titleHeight / 2; } } }; Line.prototype.autoProcessOverlap = function (name, value, labelGroup, limitLength) { var _this = this; var isVertical = this.isVertical(); var hasAdjusted = false; var util = OverlapUtil[name]; if (value === true) { // 默认使用固定角度的旋转方案 hasAdjusted = util.getDefault()(isVertical, labelGroup, limitLength); } else if (util_1.isFunction(value)) { // 用户可以传入回调函数 hasAdjusted = value(isVertical, labelGroup, limitLength); } else if (util[value]) { // 按照名称执行旋转函数 hasAdjusted = util[value](isVertical, labelGroup, limitLength); } if (name === 'autoRotate') { // 文本旋转后,文本的对齐方式可能就不合适了 if (hasAdjusted) { var labels = labelGroup.getChildren(); var verticalFactor_1 = this.get('verticalFactor'); util_1.each(labels, function (label) { var textAlign = label.attr('textAlign'); if (textAlign === 'center') { // 居中的文本需要调整旋转度 var newAlign = verticalFactor_1 > 0 ? 'end' : 'start'; label.attr('textAlign', newAlign); } }); } } else if (name === 'autoHide') { var children = labelGroup.getChildren().slice(0); // 复制数组,删除时不会出错 util_1.each(children, function (label) { if (!label.get('visible')) { if (_this.get('isRegister')) { // 已经注册过了,则删除 _this.unregisterElement(label); } label.remove(); // 防止 label 数量太多,所以统一删除 } }); } }; return Line; }(base_1.default)); exports.default = Line; },{"./base":32,"./overlap":39,"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ellipsisMiddle = exports.ellipsisTail = exports.ellipsisHead = exports.getDefault = void 0; var util_1 = require("@antv/util"); var label_1 = require("../../util/label"); function ellipseLabels(isVertical, labelGroup, limitLength, position) { var children = labelGroup.getChildren(); var ellipsised = false; util_1.each(children, function (label) { var rst = label_1.ellipsisLabel(isVertical, label, limitLength, position); ellipsised = ellipsised || rst; }); return ellipsised; } function getDefault() { return ellipsisTail; } exports.getDefault = getDefault; function ellipsisHead(isVertical, labelGroup, limitLength) { return ellipseLabels(isVertical, labelGroup, limitLength, 'head'); } exports.ellipsisHead = ellipsisHead; function ellipsisTail(isVertical, labelGroup, limitLength) { return ellipseLabels(isVertical, labelGroup, limitLength, 'tail'); } exports.ellipsisTail = ellipsisTail; function ellipsisMiddle(isVertical, labelGroup, limitLength) { return ellipseLabels(isVertical, labelGroup, limitLength, 'middle'); } exports.ellipsisMiddle = ellipsisMiddle; },{"../../util/label":72,"@antv/util":803}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.equidistance = exports.reserveBoth = exports.reserveLast = exports.reserveFirst = exports.getDefault = void 0; var label_1 = require("../../util/label"); // 文本是否旋转 function isRotate(label) { var matrix = label.attr('matrix'); return matrix && matrix[0] !== 1; // 仅在这个场景下判定 } // autohide 不再考虑超出限制 // function isOutLimit(isVertical: boolean, label: IElement, limitLength: number) { // if (!limitLength) { // // 如果没限制 limitLength 则直接返回 false // return false; // } // const canvasBBox = label.getCanvasBBox(); // let isOut = false; // if (isVertical) { // isOut = canvasBBox.width > limitLength; // } else { // isOut = canvasBBox.height > limitLength; // } // return isOut; // } // 是否重叠 function isOverlap(isVertical, rotated, preBox, curBox, reversed) { if (reversed === void 0) { reversed = false; } var overlap = false; if (isVertical) { // 垂直时检测边高 overlap = Math.abs(preBox.y - curBox.y) < preBox.height; } else { // 水平时检测 if (rotated) { // 如果旋转了,则检测两者 x 之间的间距是否小于前一个的高度 var height = reversed ? curBox.height : preBox.height; overlap = Math.abs(preBox.x - curBox.x) < height; } else { // 检测两者是否 x 方向重合 var width = reversed ? curBox.width : preBox.width; overlap = Math.abs(preBox.x - curBox.x) < width; } } return overlap; } // 保留第一个或者最后一个 function reserveOne(isVertical, labelsGroup, reversed) { var labels = labelsGroup.getChildren().slice(); // 复制数组 if (!labels.length) { return false; } var hasHide = false; if (reversed) { // 翻转 labels.reverse(); } var count = labels.length; var first = labels[0]; var rotated = isRotate(first); var preBox = first.getBBox(); for (var i = 1; i < count; i++) { var label = labels[i]; var curBBox = label.getBBox(); // 不再考虑超出限制,而仅仅根据是否重叠进行隐藏 isOutLimit(isVertical, label, limitLength) || var isHide = isOverlap(isVertical, rotated, preBox, curBBox, reversed); if (isHide) { label.hide(); hasHide = true; } else { preBox = curBBox; } } return hasHide; } function getDefault() { return equidistance; } exports.getDefault = getDefault; /** * 保证首个 label 可见,即使超过 limitLength 也不隐藏 * @param {boolean} isVertical 是否垂直 * @param {IGroup} labelsGroup label 的分组 */ function reserveFirst(isVertical, labelsGroup) { return reserveOne(isVertical, labelsGroup, false); } exports.reserveFirst = reserveFirst; /** * 保证最后一个 label 可见,即使超过 limitLength 也不隐藏 * @param {boolean} isVertical 是否垂直 * @param {IGroup} labelsGroup label 的分组 */ function reserveLast(isVertical, labelsGroup) { return reserveOne(isVertical, labelsGroup, true); } exports.reserveLast = reserveLast; /** * 保证第一个最后一个 label 可见,即使超过 limitLength 也不隐藏 * @param {boolean} isVertical 是否垂直 * @param {IGroup} labelsGroup label 的分组 */ function reserveBoth(isVertical, labelsGroup) { var labels = labelsGroup.getChildren().slice(); // 复制数组 if (labels.length <= 2) { // 如果数量小于或等于 2 则直接返回 return false; } var hasHide = false; var count = labels.length; var first = labels[0]; var last = labels[count - 1]; var rotated = isRotate(first); var preBox = first.getBBox(); var preLabel = first; // 按照先保存第一个的逻辑循环一遍,最后一个不参与循环 for (var i = 1; i < count - 1; i++) { var label = labels[i]; var curBBox = label.getBBox(); // 废弃 isOutLimit(isVertical, label, limitLength) || var isHide = isOverlap(isVertical, rotated, preBox, curBBox); if (isHide) { label.hide(); hasHide = true; } else { preBox = curBBox; preLabel = label; } } var lastBBox = last.getBBox(); var overlap = isOverlap(isVertical, rotated, preBox, lastBBox); // 不检测超出 limit if (overlap) { // 发生冲突,则隐藏前一个保留后一个 preLabel.hide(); hasHide = true; } return hasHide; } exports.reserveBoth = reserveBoth; /** * 保证 label 均匀显示,主要解决文本层叠的问题,对于 limitLength 不处理 * @param {boolean} isVertical 是否垂直 * @param {IGroup} labelsGroup label 的分组 */ function equidistance(isVertical, labelsGroup) { var labels = labelsGroup.getChildren().slice(); // 复制数组 if (labels.length < 2) { // 如果数量小于 2 则直接返回,等于 2 时可能也会重合 return false; } var hasHide = false; var first = labels[0]; var firstBBox = first.getBBox(); var second = labels[1]; var rotated = isRotate(first); var count = labels.length; var interval = 0; // 不重叠的坐标文本间距个数 if (isVertical) { // 垂直的坐标轴计算垂直方向的间距 var distance = Math.abs(second.attr('y') - first.attr('y')); interval = firstBBox.height / distance; } else { // 水平坐标轴 if (rotated) { var distance = Math.abs(second.attr('x') - first.attr('x')); interval = firstBBox.width / distance; } else { var maxWidth = label_1.getMaxLabelWidth(labels); var distance = Math.abs(second.attr('x') - first.attr('x')); interval = maxWidth / distance; } } // interval > 1 时需要对 label 进行隐藏 if (interval > 1) { interval = Math.ceil(interval); for (var i = 0; i < count; i++) { if (i % interval !== 0) { // 仅保留被整除的 label labels[i].hide(); hasHide = true; } } } return hasHide; } exports.equidistance = equidistance; },{"../../util/label":72}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.unfixedAngle = exports.fixedAngle = exports.getDefault = void 0; var util_1 = require("@antv/util"); var label_1 = require("../../util/label"); var matrix_1 = require("../../util/matrix"); var theme_1 = require("../../util/theme"); // 统一设置文本的角度 function setLabelsAngle(labels, angle) { util_1.each(labels, function (label) { var x = label.attr('x'); var y = label.attr('y'); var matrix = matrix_1.getMatrixByAngle({ x: x, y: y }, angle); label.attr('matrix', matrix); }); } // 旋转文本 function labelRotate(isVertical, labelsGroup, limitLength, getAngle) { var labels = labelsGroup.getChildren(); if (!labels.length) { return false; } if (!isVertical && labels.length < 2) { // 水平时至少有两个时才旋转 return false; } var maxWidth = label_1.getMaxLabelWidth(labels); var isOverlap = false; if (isVertical) { // limitLength 为 0 或者 null 时不生效 isOverlap = !!limitLength && maxWidth > limitLength; } else { // 同 limitLength 无关 var tickWidth = Math.abs(labels[1].attr('x') - labels[0].attr('x')); isOverlap = maxWidth > tickWidth; } if (isOverlap) { var angle = getAngle(limitLength, maxWidth); setLabelsAngle(labels, angle); } return isOverlap; } function getDefault() { return fixedAngle; } exports.getDefault = getDefault; /** * 固定角度旋转文本 * @param {boolean} isVertical 是否垂直方向 * @param {IGroup} labelsGroup 文本的 group * @param {number} limitLength 限定长度 * @return {boolean} 是否发生了旋转 */ function fixedAngle(isVertical, labelsGroup, limitLength) { return labelRotate(isVertical, labelsGroup, limitLength, function () { return isVertical ? theme_1.default.verticalAxisRotate : theme_1.default.horizontalAxisRotate; }); } exports.fixedAngle = fixedAngle; /** * 非固定角度旋转文本 * @param {boolean} isVertical 是否垂直方向 * @param {IGroup} labelsGroup 文本的 group * @param {number} limitLength 限定长度 * @return {boolean} 是否发生了旋转 */ function unfixedAngle(isVertical, labelsGroup, limitLength) { return labelRotate(isVertical, labelsGroup, limitLength, function (length, maxWidth) { if (!length) { // 如果没有设置 limitLength,则使用固定的角度旋转 return isVertical ? theme_1.default.verticalAxisRotate : theme_1.default.horizontalAxisRotate; } if (isVertical) { // 垂直时不需要判定 limitLength > maxWidth ,因为此时不会 overlap return -Math.acos(length / maxWidth); } else { var angle = 0; if (length > maxWidth) { // 需要判定,asin 的参数 -1, 1 angle = Math.PI / 4; } else { angle = Math.asin(length / maxWidth); if (angle > Math.PI / 4) { // 大于 Math.PI / 4 时没意义 angle = Math.PI / 4; } } return angle; } }); } exports.unfixedAngle = unfixedAngle; },{"../../util/label":72,"../../util/matrix":73,"../../util/theme":76,"@antv/util":803}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.autoEllipsis = exports.autoRotate = exports.autoHide = void 0; var autoEllipsis = require("./auto-ellipsis"); exports.autoEllipsis = autoEllipsis; var autoHide = require("./auto-hide"); exports.autoHide = autoHide; var autoRotate = require("./auto-rotate"); exports.autoRotate = autoRotate; },{"./auto-ellipsis":36,"./auto-hide":37,"./auto-rotate":38}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var matrix_1 = require("../util/matrix"); var theme_1 = require("../util/theme"); var util_2 = require("../util/util"); var CrosshairBase = /** @class */ (function (_super) { tslib_1.__extends(CrosshairBase, _super); function CrosshairBase() { return _super !== null && _super.apply(this, arguments) || this; } CrosshairBase.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'crosshair', type: 'base', line: {}, text: null, textBackground: {}, capture: false, defaultCfg: { line: { style: { lineWidth: 1, stroke: theme_1.default.lineColor, }, }, text: { position: 'start', offset: 10, autoRotate: false, content: null, style: { fill: theme_1.default.textColor, textAlign: 'center', textBaseline: 'middle', fontFamily: theme_1.default.fontFamily, }, }, textBackground: { padding: 5, style: { stroke: theme_1.default.lineColor, }, }, } }); }; CrosshairBase.prototype.renderInner = function (group) { if (this.get('line')) { this.renderLine(group); } if (this.get('text')) { this.renderText(group); this.renderBackground(group); } }; CrosshairBase.prototype.renderText = function (group) { var text = this.get('text'); var style = text.style, autoRotate = text.autoRotate, content = text.content; if (!util_1.isNil(content)) { var textPoint = this.getTextPoint(); var matrix = null; if (autoRotate) { var angle = this.getRotateAngle(); matrix = matrix_1.getMatrixByAngle(textPoint, angle); } this.addShape(group, { type: 'text', name: 'crosshair-text', id: this.getElementId('text'), attrs: tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, textPoint), { text: content, matrix: matrix }), style), }); } }; CrosshairBase.prototype.renderLine = function (group) { var path = this.getLinePath(); var line = this.get('line'); var style = line.style; this.addShape(group, { type: 'path', name: 'crosshair-line', id: this.getElementId('line'), attrs: tslib_1.__assign({ path: path }, style), }); }; // 绘制文本的背景 CrosshairBase.prototype.renderBackground = function (group) { var textId = this.getElementId('text'); var textShape = group.findById(textId); // 查找文本 var textBackground = this.get('textBackground'); if (textBackground && textShape) { var textBBox = textShape.getBBox(); var padding = util_2.formatPadding(textBackground.padding); // 用户传入的 padding 格式不定 var style = textBackground.style; var backgroundShape = this.addShape(group, { type: 'rect', name: 'crosshair-text-background', id: this.getElementId('text-background'), attrs: tslib_1.__assign({ x: textBBox.x - padding[3], y: textBBox.y - padding[0], width: textBBox.width + padding[1] + padding[3], height: textBBox.height + padding[0] + padding[2], matrix: textShape.attr('matrix') }, style), }); backgroundShape.toBack(); } }; return CrosshairBase; }(group_component_1.default)); exports.default = CrosshairBase; },{"../abstract/group-component":21,"../util/matrix":73,"../util/theme":76,"../util/util":77,"@antv/util":803,"tslib":894}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util/util"); var base_1 = require("./base"); var LineCrosshair = /** @class */ (function (_super) { tslib_1.__extends(LineCrosshair, _super); function LineCrosshair() { return _super !== null && _super.apply(this, arguments) || this; } LineCrosshair.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'circle', locationType: 'circle', center: null, radius: 100, startAngle: -Math.PI / 2, endAngle: (Math.PI * 3) / 2 }); }; LineCrosshair.prototype.getRotateAngle = function () { var _a = this.getLocation(), startAngle = _a.startAngle, endAngle = _a.endAngle; var position = this.get('text').position; var tangentAngle = position === 'start' ? startAngle + Math.PI / 2 : endAngle - Math.PI / 2; return tangentAngle; }; LineCrosshair.prototype.getTextPoint = function () { var text = this.get('text'); var position = text.position, offset = text.offset; var _a = this.getLocation(), center = _a.center, radius = _a.radius, startAngle = _a.startAngle, endAngle = _a.endAngle; var angle = position === 'start' ? startAngle : endAngle; var tangentAngle = this.getRotateAngle() - Math.PI; var point = util_1.getCirclePoint(center, radius, angle); // 这个地方其实应该求切线向量然后在乘以 offset,但是太啰嗦了,直接给出结果 // const tangent = [Math.cos(tangentAngle), Math.sin(tangentAngle)]; // const offsetVector = vec2.scale([], tangent, offset); var offsetX = Math.cos(tangentAngle) * offset; var offsetY = Math.sin(tangentAngle) * offset; return { x: point.x + offsetX, y: point.y + offsetY, }; }; LineCrosshair.prototype.getLinePath = function () { var _a = this.getLocation(), center = _a.center, radius = _a.radius, startAngle = _a.startAngle, endAngle = _a.endAngle; var path = null; if (endAngle - startAngle === Math.PI * 2) { // 整圆 var x = center.x, y = center.y; path = [ ['M', x, y - radius], ['A', radius, radius, 0, 1, 1, x, y + radius], ['A', radius, radius, 0, 1, 1, x, y - radius], ['Z'], ]; } else { var startPoint = util_1.getCirclePoint(center, radius, startAngle); var endPoint = util_1.getCirclePoint(center, radius, endAngle); var large = Math.abs(endAngle - startAngle) > Math.PI ? 1 : 0; var sweep = startAngle > endAngle ? 0 : 1; path = [ ['M', startPoint.x, startPoint.y], ['A', radius, radius, 0, large, sweep, endPoint.x, endPoint.y], ]; } return path; }; return LineCrosshair; }(base_1.default)); exports.default = LineCrosshair; },{"../util/util":77,"./base":40,"tslib":894}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CROSSHAIR_TEXT = exports.CROSSHAIR_LINE = exports.CONTAINER_CLASS = void 0; exports.CONTAINER_CLASS = 'g2-crosshair'; exports.CROSSHAIR_LINE = exports.CONTAINER_CLASS + "-line"; exports.CROSSHAIR_TEXT = exports.CONTAINER_CLASS + "-text"; },{}],43:[function(require,module,exports){ "use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../util/theme"); // tooltip 相关 dom 的 css 类名 var CssConst = require("./css-const"); exports.default = (_a = {}, // css style for tooltip _a["" + CssConst.CONTAINER_CLASS] = { position: 'relative' }, _a["" + CssConst.CROSSHAIR_LINE] = { position: 'absolute', backgroundColor: 'rgba(0, 0, 0, 0.25)', }, _a["" + CssConst.CROSSHAIR_TEXT] = { position: 'absolute', color: theme_1.default.textColor, fontFamily: theme_1.default.fontFamily, }, _a); },{"../util/theme":76,"./css-const":42}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dom_util_1 = require("@antv/dom-util"); var util_1 = require("@antv/util"); var util_2 = require("../util/util"); var html_component_1 = require("../abstract/html-component"); var CssConst = require("./css-const"); var html_theme_1 = require("./html-theme"); var HtmlCrosshair = /** @class */ (function (_super) { tslib_1.__extends(HtmlCrosshair, _super); function HtmlCrosshair() { return _super !== null && _super.apply(this, arguments) || this; } HtmlCrosshair.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'crosshair', type: 'html', locationType: 'region', start: { x: 0, y: 0 }, end: { x: 0, y: 0 }, capture: false, text: null, containerTpl: "
", crosshairTpl: "
", textTpl: "{content}", domStyles: null, containerClassName: CssConst.CONTAINER_CLASS, defaultStyles: html_theme_1.default, defaultCfg: { text: { position: 'start', content: null, align: 'center', offset: 10 } } }); }; HtmlCrosshair.prototype.render = function () { this.resetText(); this.resetPosition(); }; // 绘制 crosshair HtmlCrosshair.prototype.initCrossHair = function () { var container = this.getContainer(); var crosshairTpl = this.get('crosshairTpl'); var crosshairEl = dom_util_1.createDom(crosshairTpl); container.appendChild(crosshairEl); this.applyStyle(CssConst.CROSSHAIR_LINE, crosshairEl); this.set('crosshairEl', crosshairEl); }; // 获取文本的位置 HtmlCrosshair.prototype.getTextPoint = function () { var _a = this.getLocation(), start = _a.start, end = _a.end; var _b = this.get('text'), position = _b.position, offset = _b.offset; return util_2.getTextPoint(start, end, position, offset); }; // 设置 text HtmlCrosshair.prototype.resetText = function () { var text = this.get('text'); var textEl = this.get('textEl'); if (text) { var content = text.content; if (!textEl) { var container = this.getContainer(); var textTpl = util_1.substitute(this.get('textTpl'), text); textEl = dom_util_1.createDom(textTpl); container.appendChild(textEl); this.applyStyle(CssConst.CROSSHAIR_TEXT, textEl); this.set('textEl', textEl); } textEl.innerHTML = content; } else if (textEl) { textEl.remove(); } }; // 是否垂直 HtmlCrosshair.prototype.isVertical = function (start, end) { return start.x === end.x; }; // 重新调整位置 HtmlCrosshair.prototype.resetPosition = function () { var crosshairEl = this.get('crosshairEl'); if (!crosshairEl) { this.initCrossHair(); crosshairEl = this.get('crosshairEl'); } var start = this.get('start'); var end = this.get('end'); var minX = Math.min(start.x, end.x); var minY = Math.min(start.y, end.y); if (this.isVertical(start, end)) { dom_util_1.modifyCSS(crosshairEl, { width: '1px', height: util_2.toPx(Math.abs(end.y - start.y)) }); } else { dom_util_1.modifyCSS(crosshairEl, { height: '1px', width: util_2.toPx(Math.abs(end.x - start.x)) }); } dom_util_1.modifyCSS(crosshairEl, { top: util_2.toPx(minY), left: util_2.toPx(minX) }); this.alignText(); }; HtmlCrosshair.prototype.alignText = function () { // 重新设置 text 位置 var textEl = this.get('textEl'); if (textEl) { var align = this.get('text').align; var clientWidth = textEl.clientWidth; var point = this.getTextPoint(); switch (align) { case 'center': point.x = point.x - clientWidth / 2; break; case 'right': point.x = point.x - clientWidth; case 'left': break; } dom_util_1.modifyCSS(textEl, { top: util_2.toPx(point.y), left: util_2.toPx(point.x) }); } }; HtmlCrosshair.prototype.updateInner = function (cfg) { if (util_1.hasKey(cfg, 'text')) { this.resetText(); } _super.prototype.updateInner.call(this, cfg); }; return HtmlCrosshair; }(html_component_1.default)); exports.default = HtmlCrosshair; },{"../abstract/html-component":22,"../util/util":77,"./css-const":42,"./html-theme":43,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("./line"); Object.defineProperty(exports, "Line", { enumerable: true, get: function () { return line_1.default; } }); var circle_1 = require("./circle"); Object.defineProperty(exports, "Circle", { enumerable: true, get: function () { return circle_1.default; } }); var base_1 = require("./base"); Object.defineProperty(exports, "Base", { enumerable: true, get: function () { return base_1.default; } }); var html_1 = require("./html"); Object.defineProperty(exports, "Html", { enumerable: true, get: function () { return html_1.default; } }); },{"./base":40,"./circle":41,"./html":44,"./line":46}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util/util"); var base_1 = require("./base"); var LineCrosshair = /** @class */ (function (_super) { tslib_1.__extends(LineCrosshair, _super); function LineCrosshair() { return _super !== null && _super.apply(this, arguments) || this; } LineCrosshair.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'line', locationType: 'region', start: null, end: null }); }; // 直线的文本需要同直线垂直 LineCrosshair.prototype.getRotateAngle = function () { var _a = this.getLocation(), start = _a.start, end = _a.end; var position = this.get('text').position; var angle = Math.atan2(end.y - start.y, end.x - start.x); var tangentAngle = position === 'start' ? angle - Math.PI / 2 : angle + Math.PI / 2; return tangentAngle; }; LineCrosshair.prototype.getTextPoint = function () { var _a = this.getLocation(), start = _a.start, end = _a.end; var _b = this.get('text'), position = _b.position, offset = _b.offset; return util_1.getTextPoint(start, end, position, offset); }; LineCrosshair.prototype.getLinePath = function () { var _a = this.getLocation(), start = _a.start, end = _a.end; return [ ['M', start.x, start.y], ['L', end.x, end.y], ]; }; return LineCrosshair; }(base_1.default)); exports.default = LineCrosshair; },{"../util/util":77,"./base":40,"tslib":894}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var theme_1 = require("../util/theme"); var GridBase = /** @class */ (function (_super) { tslib_1.__extends(GridBase, _super); function GridBase() { return _super !== null && _super.apply(this, arguments) || this; } GridBase.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'grid', line: {}, alternateColor: null, capture: false, items: [], closed: false, defaultCfg: { line: { type: 'line', style: { lineWidth: 1, stroke: theme_1.default.lineColor, }, }, } }); }; /** * 获取栅格线的类型 * @return {string} 栅格线类型 */ GridBase.prototype.getLineType = function () { var line = this.get('line') || this.get('defaultCfg').line; return line.type; }; GridBase.prototype.renderInner = function (group) { this.drawGrid(group); }; GridBase.prototype.getAlternatePath = function (prePoints, points) { var regionPath = this.getGridPath(prePoints); var reversePoints = points.slice(0).reverse(); var nextPath = this.getGridPath(reversePoints, true); var closed = this.get('closed'); if (closed) { regionPath = regionPath.concat(nextPath); } else { nextPath[0][0] = 'L'; // 更新第一个节点 regionPath = regionPath.concat(nextPath); regionPath.push(['Z']); } return regionPath; }; // 获取路径的配置项 GridBase.prototype.getPathStyle = function () { return this.get('line').style; }; // 绘制栅格 GridBase.prototype.drawGrid = function (group) { var _this = this; var line = this.get('line'); var items = this.get('items'); var alternateColor = this.get('alternateColor'); var preItem = null; util_1.each(items, function (item, index) { var id = item.id || index; // 绘制栅格线 if (line) { var style = _this.getPathStyle(); var lineId = _this.getElementId("line-" + id); var gridPath = _this.getGridPath(item.points); _this.addShape(group, { type: 'path', name: 'grid-line', id: lineId, attrs: util_1.mix({ path: gridPath, }, style), }); } // 如果存在 alternateColor 则绘制矩形 // 从第二个栅格线开始绘制 if (alternateColor && index > 0) { var regionId = _this.getElementId("region-" + id); var isEven = index % 2 === 0; if (util_1.isString(alternateColor)) { // 如果颜色是单值,则是仅绘制偶数时的区域 if (isEven) { _this.drawAlternateRegion(regionId, group, preItem.points, item.points, alternateColor); } } else { var color = isEven ? alternateColor[1] : alternateColor[0]; _this.drawAlternateRegion(regionId, group, preItem.points, item.points, color); } } preItem = item; }); }; // 绘制栅格线间的间隔 GridBase.prototype.drawAlternateRegion = function (id, group, prePoints, points, color) { var regionPath = this.getAlternatePath(prePoints, points); this.addShape(group, { type: 'path', id: id, name: 'grid-region', attrs: { path: regionPath, fill: color, }, }); }; return GridBase; }(group_component_1.default)); exports.default = GridBase; },{"../abstract/group-component":21,"../util/theme":76,"@antv/util":803,"tslib":894}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("./base"); function distance(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); } var Circle = /** @class */ (function (_super) { tslib_1.__extends(Circle, _super); function Circle() { return _super !== null && _super.apply(this, arguments) || this; } Circle.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'circle', /** * 中心点 * @type {object} */ center: null, /** * 栅格线是否封闭 * @type {true} */ closed: true }); }; Circle.prototype.getGridPath = function (points, reversed) { var lineType = this.getLineType(); var closed = this.get('closed'); var path = []; if (points.length) { // 防止出错 if (lineType === 'circle') { var center = this.get('center'); var firstPoint = points[0]; var radius_1 = distance(center.x, center.y, firstPoint.x, firstPoint.y); var sweepFlag_1 = reversed ? 0 : 1; // 顺时针还是逆时针 if (closed) { // 封闭时,绘制整个圆 path.push(['M', center.x, center.y - radius_1]); path.push(['A', radius_1, radius_1, 0, 0, sweepFlag_1, center.x, center.y + radius_1]); path.push(['A', radius_1, radius_1, 0, 0, sweepFlag_1, center.x, center.y - radius_1]); path.push(['Z']); } else { util_1.each(points, function (point, index) { if (index === 0) { path.push(['M', point.x, point.y]); } else { path.push(['A', radius_1, radius_1, 0, 0, sweepFlag_1, point.x, point.y]); } }); } } else { util_1.each(points, function (point, index) { if (index === 0) { path.push(['M', point.x, point.y]); } else { path.push(['L', point.x, point.y]); } }); if (closed) { path.push(['Z']); } } } return path; }; return Circle; }(base_1.default)); exports.default = Circle; },{"./base":47,"@antv/util":803,"tslib":894}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("./base"); Object.defineProperty(exports, "Base", { enumerable: true, get: function () { return base_1.default; } }); var circle_1 = require("./circle"); Object.defineProperty(exports, "Circle", { enumerable: true, get: function () { return circle_1.default; } }); var line_1 = require("./line"); Object.defineProperty(exports, "Line", { enumerable: true, get: function () { return line_1.default; } }); },{"./base":47,"./circle":48,"./line":50}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var Line = /** @class */ (function (_super) { tslib_1.__extends(Line, _super); function Line() { return _super !== null && _super.apply(this, arguments) || this; } Line.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'line' }); }; Line.prototype.getGridPath = function (points) { var path = []; util_1.each(points, function (point, index) { if (index === 0) { path.push(['M', point.x, point.y]); } else { path.push(['L', point.x, point.y]); } }); return path; }; return Line; }(base_1.default)); exports.default = Line; },{"./base":47,"@antv/util":803,"tslib":894}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Crosshair = exports.Tooltip = exports.Legend = exports.Grid = exports.Annotation = exports.Axis = void 0; var Annotation = require("./annotation"); exports.Annotation = Annotation; var Axis = require("./axis"); exports.Axis = Axis; var Crosshair = require("./crosshair"); exports.Crosshair = Crosshair; var Grid = require("./grid"); exports.Grid = Grid; var Legend = require("./legend"); exports.Legend = Legend; var Tooltip = require("./tooltip"); exports.Tooltip = Tooltip; var component_1 = require("./abstract/component"); Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return component_1.default; } }); var group_component_1 = require("./abstract/group-component"); Object.defineProperty(exports, "GroupComponent", { enumerable: true, get: function () { return group_component_1.default; } }); var html_component_1 = require("./abstract/html-component"); Object.defineProperty(exports, "HtmlComponent", { enumerable: true, get: function () { return html_component_1.default; } }); var slider_1 = require("./slider"); Object.defineProperty(exports, "Slider", { enumerable: true, get: function () { return slider_1.Slider; } }); var scrollbar_1 = require("./scrollbar"); Object.defineProperty(exports, "Scrollbar", { enumerable: true, get: function () { return scrollbar_1.Scrollbar; } }); },{"./abstract/component":20,"./abstract/group-component":21,"./abstract/html-component":22,"./annotation":27,"./axis":34,"./crosshair":45,"./grid":49,"./legend":55,"./scrollbar":56,"./slider":60,"./tooltip":65}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var util_1 = require("../util/util"); var LegendBase = /** @class */ (function (_super) { tslib_1.__extends(LegendBase, _super); function LegendBase() { return _super !== null && _super.apply(this, arguments) || this; } LegendBase.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'legend', /** * 布局方式: horizontal,vertical * @type {String} */ layout: 'horizontal', locationType: 'point', x: 0, y: 0, offsetX: 0, offsetY: 0, title: null, background: null }); }; LegendBase.prototype.getLayoutBBox = function () { var bbox = _super.prototype.getLayoutBBox.call(this); var x = this.get('x'); var y = this.get('y'); var offsetX = this.get('offsetX'); var offsetY = this.get('offsetY'); var maxWidth = this.get('maxWidth'); var maxHeight = this.get('maxHeight'); var minX = x + offsetX; var minY = y + offsetY; var width = bbox.maxX - minX; var height = bbox.maxY - minY; if (maxWidth) { width = Math.min(width, maxWidth); } if (maxHeight) { height = Math.min(height, maxHeight); } return util_1.createBBox(minX, minY, width, height); }; LegendBase.prototype.setLocation = function (cfg) { this.set('x', cfg.x); this.set('y', cfg.y); this.resetLocation(); }; LegendBase.prototype.resetLocation = function () { var x = this.get('x'); var y = this.get('y'); var offsetX = this.get('offsetX'); var offsetY = this.get('offsetY'); this.moveElementTo(this.get('group'), { x: x + offsetX, y: y + offsetY, }); }; LegendBase.prototype.applyOffset = function () { this.resetLocation(); }; // 获取当前绘制的点 LegendBase.prototype.getDrawPoint = function () { return this.get('currentPoint'); }; LegendBase.prototype.setDrawPoint = function (point) { return this.set('currentPoint', point); }; // 复写父类定义的绘制方法 LegendBase.prototype.renderInner = function (group) { this.resetDraw(); if (this.get('title')) { this.drawTitle(group); } this.drawLegendContent(group); if (this.get('background')) { this.drawBackground(group); } // this.resetLocation(); // 在顶层已经在处理偏移时一起处理了 }; // 绘制背景 LegendBase.prototype.drawBackground = function (group) { var background = this.get('background'); var bbox = group.getBBox(); var padding = util_1.formatPadding(background.padding); var attrs = tslib_1.__assign({ // 背景从 (0,0) 开始绘制 x: 0, y: 0, width: bbox.width + padding[1] + padding[3], height: bbox.height + padding[0] + padding[2] }, background.style); var backgroundShape = this.addShape(group, { type: 'rect', id: this.getElementId('background'), name: 'legend-background', attrs: attrs, }); backgroundShape.toBack(); }; // 绘制标题,标题在图例项的上面 LegendBase.prototype.drawTitle = function (group) { var currentPoint = this.get('currentPoint'); var titleCfg = this.get('title'); var spacing = titleCfg.spacing, style = titleCfg.style, text = titleCfg.text; var shape = this.addShape(group, { type: 'text', id: this.getElementId('title'), name: 'legend-title', attrs: tslib_1.__assign({ text: text, x: currentPoint.x, y: currentPoint.y }, style), }); var bbox = shape.getBBox(); // 标题单独在一行 this.set('currentPoint', { x: currentPoint.x, y: bbox.maxY + spacing }); }; // 重置绘制时开始的位置,如果绘制边框,考虑边框的 padding LegendBase.prototype.resetDraw = function () { var background = this.get('background'); var currentPoint = { x: 0, y: 0 }; if (background) { var padding = util_1.formatPadding(background.padding); currentPoint.x = padding[3]; // 左边 padding currentPoint.y = padding[0]; // 上面 padding } this.set('currentPoint', currentPoint); // 设置绘制的初始位置 }; return LegendBase; }(group_component_1.default)); exports.default = LegendBase; },{"../abstract/group-component":21,"../util/util":77,"tslib":894}],53:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var label_1 = require("../util/label"); var matrix_1 = require("../util/matrix"); var state_1 = require("../util/state"); var theme_1 = require("../util/theme"); var base_1 = require("./base"); var Category = /** @class */ (function (_super) { tslib_1.__extends(Category, _super); function Category() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.currentPageIndex = 1; _this.totalPagesCnt = 1; _this.pageWidth = 0; _this.pageHeight = 0; _this.startX = 0; _this.startY = 0; _this.onNavigationBack = function () { var itemGroup = _this.getElementByLocalId('item-group'); if (_this.currentPageIndex > 1) { _this.currentPageIndex -= 1; _this.updateNavigation(); var matrix = _this.getCurrentNavigationMatrix(); if (_this.get('animate')) { itemGroup.animate({ matrix: matrix, }, 100); } else { itemGroup.attr({ matrix: matrix }); } } }; _this.onNavigationAfter = function () { var itemGroup = _this.getElementByLocalId('item-group'); if (_this.currentPageIndex < _this.totalPagesCnt) { _this.currentPageIndex += 1; _this.updateNavigation(); var matrix = _this.getCurrentNavigationMatrix(); if (_this.get('animate')) { itemGroup.animate({ matrix: matrix, }, 100); } else { itemGroup.attr({ matrix: matrix }); } } }; return _this; } Category.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'legend', type: 'category', itemSpacing: 24, maxItemWidth: null, itemWidth: null, itemHeight: null, itemName: {}, itemValue: null, maxWidth: null, maxHeight: null, marker: {}, items: [], itemStates: {}, itemBackground: {}, defaultCfg: { title: { spacing: 5, style: { fill: theme_1.default.textColor, fontSize: 12, textAlign: 'start', textBaseline: 'top', }, }, background: { padding: 5, style: { stroke: theme_1.default.lineColor, }, }, itemBackground: { style: { opacity: 0, fill: '#fff', }, }, itemName: { spacing: 16, style: { fill: theme_1.default.textColor, fontSize: 12, textAlign: 'start', textBaseline: 'middle', }, }, marker: { spacing: 8, style: { r: 6, symbol: 'circle', }, }, itemValue: { alignRight: false, formatter: null, style: { fill: theme_1.default.textColor, fontSize: 12, textAlign: 'start', textBaseline: 'middle', }, }, itemStates: { active: { nameStyle: { opacity: 0.8, }, }, unchecked: { nameStyle: { fill: theme_1.default.uncheckedColor, }, markerStyle: { fill: theme_1.default.uncheckedColor, stroke: theme_1.default.uncheckedColor, }, }, inactive: { nameStyle: { fill: theme_1.default.uncheckedColor, }, markerStyle: { opacity: 0.2, }, }, }, } }); }; // 实现 IList 接口 Category.prototype.isList = function () { return true; }; /** * 获取图例项 * @return {ListItem[]} 列表项集合 */ Category.prototype.getItems = function () { return this.get('items'); }; /** * 设置列表项 * @param {ListItem[]} items 列表项集合 */ Category.prototype.setItems = function (items) { this.update({ items: items, }); }; /** * 更新列表项 * @param {ListItem} item 列表项 * @param {object} cfg 列表项 */ Category.prototype.updateItem = function (item, cfg) { util_1.mix(item, cfg); this.clear(); // 由于单个图例项变化,会引起全局变化,所以全部更新 this.render(); }; /** * 清空列表 */ Category.prototype.clearItems = function () { var itemGroup = this.getElementByLocalId('item-group'); itemGroup && itemGroup.clear(); }; /** * 设置列表项的状态 * @param {ListItem} item 列表项 * @param {string} state 状态名 * @param {boolean} value 状态值, true, false */ Category.prototype.setItemState = function (item, state, value) { item[state] = value; var itemElement = this.getElementByLocalId("item-" + item.id); if (itemElement) { var items = this.getItems(); var index = items.indexOf(item); var offsetGroup = this.createOffScreenGroup(); // 离屏的 group var newElement = this.drawItem(item, index, this.getItemHeight(), offsetGroup); this.updateElements(newElement, itemElement); // 更新整个分组 this.clearUpdateStatus(itemElement); // 清理更新状态,防止出现 bug } }; /** * 是否存在指定的状态 * @param {ListItem} item 列表项 * @param {boolean} state 状态名 */ Category.prototype.hasState = function (item, state) { return !!item[state]; }; Category.prototype.getItemStates = function (item) { var itemStates = this.get('itemStates'); var rst = []; util_1.each(itemStates, function (v, k) { if (item[k]) { // item.selected rst.push(k); } }); return rst; }; /** * 清楚所有列表项的状态 * @param {string} state 状态值 */ Category.prototype.clearItemsState = function (state) { var _this = this; var items = this.getItemsByState(state); util_1.each(items, function (item) { _this.setItemState(item, state, false); }); }; /** * 根据状态获取图例项 * @param {string} state [description] * @return {ListItem[]} [description] */ Category.prototype.getItemsByState = function (state) { var _this = this; var items = this.getItems(); return util_1.filter(items, function (item) { return _this.hasState(item, state); }); }; // 绘制 legend 的选项 Category.prototype.drawLegendContent = function (group) { this.processItems(); this.drawItems(group); }; // 防止未设置 id Category.prototype.processItems = function () { var items = this.get('items'); util_1.each(items, function (item) { if (!item.id) { // 如果没有设置 id,默认使用 name item.id = item.name; } }); }; // 绘制所有的图例选项 Category.prototype.drawItems = function (group) { var _this = this; var itemContainerGroup = this.addGroup(group, { id: this.getElementId('item-container-group'), name: 'legend-item-container-group', }); var itemGroup = this.addGroup(itemContainerGroup, { id: this.getElementId('item-group'), name: 'legend-item-group', }); var itemHeight = this.getItemHeight(); var itemWidth = this.get('itemWidth'); var itemSpacing = this.get('itemSpacing'); var currentPoint = this.get('currentPoint'); var startX = currentPoint.x; var startY = currentPoint.y; var layout = this.get('layout'); var items = this.get('items'); var wrapped = false; var pageWidth = 0; var maxWidth = this.get('maxWidth'); // 最大宽度,会导致 layout : 'horizontal' 时自动换行 var maxHeight = this.get('maxHeight'); // 最大高度,会导致出现分页 // 暂时不考虑分页 util_1.each(items, function (item, index) { var subGroup = _this.drawItem(item, index, itemHeight, itemGroup); var bbox = subGroup.getBBox(); var width = itemWidth || bbox.width; if (width > pageWidth) { pageWidth = width; } if (layout === 'horizontal') { // 如果水平布局 if (maxWidth && maxWidth < currentPoint.x + width - startX) { // 检测是否换行 wrapped = true; currentPoint.x = startX; currentPoint.y += itemHeight; } _this.moveElementTo(subGroup, currentPoint); currentPoint.x += width + itemSpacing; } else { // 如果垂直布局 if (maxHeight && maxHeight < currentPoint.y + itemHeight - startY) { // 换行 wrapped = true; currentPoint.x += pageWidth + itemSpacing; currentPoint.y = startY; pageWidth = 0; } _this.moveElementTo(subGroup, currentPoint); currentPoint.y += itemHeight; // itemSpacing 仅影响水平间距 } }); if (wrapped && this.get('flipPage')) { this.pageHeight = 0; this.pageWidth = 0; this.totalPagesCnt = 1; this.startX = startX; this.startY = startY; this.adjustNavigation(group, itemGroup); } }; // 获取图例项的高度,如果未定义,则按照 name 的高度计算 Category.prototype.getItemHeight = function () { var itemHeight = this.get('itemHeight'); if (!itemHeight) { var nameCfg = this.get('itemName'); if (nameCfg) { itemHeight = nameCfg.style.fontSize + 8; } } return itemHeight; }; // 绘制 marker Category.prototype.drawMarker = function (container, markerCfg, item, itemHeight) { var markerAttrs = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ x: 0, y: itemHeight / 2 }, markerCfg.style), { symbol: util_1.get(item.marker, 'symbol', 'circle') }), util_1.get(item.marker, 'style', {})); var shape = this.addShape(container, { type: 'marker', id: this.getElementId("item-" + item.id + "-marker"), name: 'legend-item-marker', attrs: markerAttrs, }); var bbox = shape.getBBox(); shape.attr('x', bbox.width / 2); // marker 需要左对齐,所以不能占用左侧的空间 var _a = shape.attr(), stroke = _a.stroke, fill = _a.fill; if (stroke) { shape.set('isStroke', true); } if (fill) { shape.set('isFill', true); } return shape; }; // 绘制文本 Category.prototype.drawItemText = function (container, textName, cfg, item, itemHeight, xPosition, index) { var formatter = cfg.formatter; var attrs = tslib_1.__assign({ x: xPosition, y: itemHeight / 2, text: formatter ? formatter(item[textName], item, index) : item[textName] }, cfg.style); return this.addShape(container, { type: 'text', id: this.getElementId("item-" + item.id + "-" + textName), name: "legend-item-" + textName, attrs: attrs, }); }; // 绘制图例项 Category.prototype.drawItem = function (item, index, itemHeight, itemGroup) { var groupId = "item-" + item.id; // 设置单独的 Group 用于 setClip var subContainer = this.addGroup(itemGroup, { name: 'legend-item-container', id: this.getElementId("item-container-" + groupId), delegateObject: { item: item, index: index, }, }); var subGroup = this.addGroup(subContainer, { name: 'legend-item', id: this.getElementId(groupId), delegateObject: { item: item, index: index, }, }); var marker = this.get('marker'); var itemName = this.get('itemName'); var itemValue = this.get('itemValue'); var itemBackground = this.get('itemBackground'); var itemWidth = this.getLimitItemWidth(); var curX = 0; // 记录当前 x 的位置 if (marker) { var markerShape = this.drawMarker(subGroup, marker, item, itemHeight); curX = markerShape.getBBox().maxX + marker.spacing; } if (itemName) { var nameShape = this.drawItemText(subGroup, 'name', itemName, item, itemHeight, curX, index); if (itemWidth) { // 设置了 item 的最大宽度限制,并且超出了,进行省略处理 label_1.ellipsisLabel(true, nameShape, util_1.clamp(itemWidth - curX, 0, itemWidth)); } curX = nameShape.getBBox().maxX + itemName.spacing; } if (itemValue) { var valueShape = this.drawItemText(subGroup, 'value', itemValue, item, itemHeight, curX, index); if (itemWidth) { if (itemValue.alignRight) { valueShape.attr({ textAlign: 'right', x: itemWidth, }); label_1.ellipsisLabel(true, valueShape, util_1.clamp(itemWidth - curX, 0, itemWidth), 'head'); } else { label_1.ellipsisLabel(true, valueShape, util_1.clamp(itemWidth - curX, 0, itemWidth)); } } } // 添加透明的背景,便于拾取和包围盒计算 if (itemBackground) { var bbox = subGroup.getBBox(); var backShape = this.addShape(subGroup, { type: 'rect', name: 'legend-item-background', id: this.getElementId(groupId + "-background"), attrs: tslib_1.__assign({ x: 0, y: 0, width: bbox.width, height: itemHeight }, itemBackground.style), }); backShape.toBack(); } this.applyItemStates(item, subGroup); return subGroup; }; // 加上分页器并重新排序 items Category.prototype.adjustNavigation = function (container, itemGroup) { var _this = this; var startX = this.startX; var startY = this.startY; var layout = this.get('layout'); var subGroups = itemGroup.findAll(function (item) { return item.get('name') === 'legend-item'; }); var maxWidth = this.get('maxWidth'); var maxHeight = this.get('maxHeight'); var itemWidth = this.get('itemWidth'); var itemSpacing = this.get('itemSpacing'); var itemHeight = this.getItemHeight(); var navigation = this.drawNavigation(container, layout, '00/00', 12); var navigationBBox = navigation.getBBox(); var currentPoint = { x: startX, y: startY }; var pages = 1; var widthLimit = 0; var pageWidth = 0; var maxItemWidth = 0; if (layout === 'horizontal') { this.pageHeight = itemHeight; util_1.each(subGroups, function (item) { var bbox = item.getBBox(); var width = itemWidth || bbox.width; if ((widthLimit && widthLimit < currentPoint.x + width + itemSpacing) || maxWidth < currentPoint.x + width + itemSpacing + navigationBBox.width) { if (pages === 1) { widthLimit = currentPoint.x + itemSpacing; _this.pageWidth = widthLimit; _this.moveElementTo(navigation, { x: maxWidth - itemSpacing - navigationBBox.width - navigationBBox.minX, y: currentPoint.y + itemHeight / 2 - navigationBBox.height / 2 - navigationBBox.minY, }); } pages += 1; currentPoint.x = startX; currentPoint.y += itemHeight; } _this.moveElementTo(item, currentPoint); item.getParent().setClip({ type: 'rect', attrs: { x: currentPoint.x, y: currentPoint.y, width: width + itemSpacing, height: itemHeight, }, }); currentPoint.x += width + itemSpacing; }); } else { util_1.each(subGroups, function (item) { var bbox = item.getBBox(); if (bbox.width > pageWidth) { pageWidth = bbox.width; } }); maxItemWidth = pageWidth; pageWidth += itemSpacing; if (maxWidth) { // maxWidth 限制加上 pageWidth = Math.min(maxWidth, pageWidth); maxItemWidth = Math.min(maxWidth, maxItemWidth); } this.pageWidth = pageWidth; this.pageHeight = maxHeight - Math.max(navigationBBox.height, itemHeight); var cntPerPage_1 = Math.floor(this.pageHeight / itemHeight); util_1.each(subGroups, function (item, index) { if (index !== 0 && index % cntPerPage_1 === 0) { pages += 1; currentPoint.x += pageWidth; currentPoint.y = startY; } _this.moveElementTo(item, currentPoint); item.getParent().setClip({ type: 'rect', attrs: { x: currentPoint.x, y: currentPoint.y, width: pageWidth, height: itemHeight, }, }); currentPoint.y += itemHeight; }); this.totalPagesCnt = pages; this.moveElementTo(navigation, { x: startX + maxItemWidth / 2 - navigationBBox.width / 2 - navigationBBox.minX, y: maxHeight - navigationBBox.height - navigationBBox.minY, }); } if (this.pageHeight && this.pageWidth) { // 为了使固定的 clip 生效,clip 设置在 itemContainerGroup 上,itemGroup 需要在翻页时会设置 matrix itemGroup.getParent().setClip({ type: 'rect', attrs: { x: this.startX, y: this.startY, width: this.pageWidth, height: this.pageHeight, }, }); } this.totalPagesCnt = pages; if (this.currentPageIndex > this.totalPagesCnt) { this.currentPageIndex = 1; } this.updateNavigation(navigation); // update initial matrix itemGroup.attr('matrix', this.getCurrentNavigationMatrix()); }; Category.prototype.drawNavigation = function (group, layout, text, size) { var currentPoint = { x: 0, y: 0 }; var subGroup = this.addGroup(group, { id: this.getElementId('navigation-group'), name: 'legend-navigation', }); var leftArrow = this.drawArrow(subGroup, currentPoint, 'navigation-arrow-left', layout === 'horizontal' ? 'up' : 'left', size); leftArrow.on('click', this.onNavigationBack); var leftArrowBBox = leftArrow.getBBox(); currentPoint.x += leftArrowBBox.width + 2; var textShape = this.addShape(subGroup, { type: 'text', id: this.getElementId('navigation-text'), name: 'navigation-text', attrs: { x: currentPoint.x, y: currentPoint.y + size / 2, text: text, fontSize: 12, fill: '#ccc', textBaseline: 'middle', }, }); var textBBox = textShape.getBBox(); currentPoint.x += textBBox.width + 2; var rightArrow = this.drawArrow(subGroup, currentPoint, 'navigation-arrow-right', layout === 'horizontal' ? 'down' : 'right', size); rightArrow.on('click', this.onNavigationAfter); return subGroup; }; Category.prototype.updateNavigation = function (navigation) { var text = this.currentPageIndex + "/" + this.totalPagesCnt; var textShape = navigation ? navigation.getChildren()[1] : this.getElementByLocalId('navigation-text'); var leftArrow = navigation ? navigation.findById(this.getElementId('navigation-arrow-left')) : this.getElementByLocalId('navigation-arrow-left'); var rightArrow = navigation ? navigation.findById(this.getElementId('navigation-arrow-right')) : this.getElementByLocalId('navigation-arrow-right'); var origBBox = textShape.getBBox(); textShape.attr('text', text); var newBBox = textShape.getBBox(); textShape.attr('x', textShape.attr('x') - (newBBox.width - origBBox.width) / 2); leftArrow.attr('opacity', this.currentPageIndex === 1 ? 0.45 : 1); leftArrow.attr('cursor', this.currentPageIndex === 1 ? 'not-allowed' : 'pointer'); rightArrow.attr('opacity', this.currentPageIndex === this.totalPagesCnt ? 0.45 : 1); rightArrow.attr('cursor', this.currentPageIndex === this.totalPagesCnt ? 'not-allowed' : 'pointer'); }; Category.prototype.drawArrow = function (group, currentPoint, name, direction, size) { var x = currentPoint.x, y = currentPoint.y; var rotateMap = { right: (90 * Math.PI) / 180, left: ((360 - 90) * Math.PI) / 180, up: 0, down: (180 * Math.PI) / 180, }; var shape = this.addShape(group, { type: 'path', id: this.getElementId(name), name: name, attrs: { path: [['M', x + size / 2, y], ['L', x, y + size], ['L', x + size, y + size], ['Z']], fill: '#000', cursor: 'pointer', }, }); shape.attr('matrix', matrix_1.getMatrixByAngle({ x: x + size / 2, y: y + size / 2 }, rotateMap[direction])); return shape; }; Category.prototype.getCurrentNavigationMatrix = function () { var _a = this, currentPageIndex = _a.currentPageIndex, pageWidth = _a.pageWidth, pageHeight = _a.pageHeight; var layout = this.get('layout'); var translate = layout === 'horizontal' ? { x: 0, y: pageHeight * (1 - currentPageIndex), } : { x: pageWidth * (1 - currentPageIndex), y: 0, }; return matrix_1.getMatrixByTranslate(translate); }; // 附加状态对应的样式 Category.prototype.applyItemStates = function (item, subGroup) { var states = this.getItemStates(item); var hasStates = states.length > 0; if (hasStates) { var children = subGroup.getChildren(); var itemStates_1 = this.get('itemStates'); util_1.each(children, function (element) { var name = element.get('name'); var elName = name.split('-')[2]; // marker, name, value var statesStyle = state_1.getStatesStyle(item, elName, itemStates_1); if (statesStyle) { element.attr(statesStyle); if (elName === 'marker' && !(element.get('isStroke') && element.get('isFill'))) { // 如果 marker 是单填充或者单描边的话,就不要额外添加 stroke 或这 fill 属性,否则会影响 unchecked 后的显示 if (element.get('isStroke')) { element.attr('fill', null); } if (element.get('isFill')) { element.attr('stroke', null); } } } }); } }; // 获取 itemWidth 的最终设置 Category.prototype.getLimitItemWidth = function () { var itemWidth = this.get('itemWidth'); var maxItemWidth = this.get('maxItemWidth'); if (maxItemWidth) { // 设置了最大宽度 if (itemWidth) { maxItemWidth = itemWidth <= maxItemWidth ? itemWidth : maxItemWidth; } } else if (itemWidth) { maxItemWidth = itemWidth; } return maxItemWidth; }; return Category; }(base_1.default)); exports.default = Category; },{"../util/label":72,"../util/matrix":73,"../util/state":74,"../util/theme":76,"./base":52,"@antv/util":803,"tslib":894}],54:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var theme_1 = require("../util/theme"); var util_2 = require("../util/util"); var base_1 = require("./base"); var HANDLER_HEIGHT_RATIO = 1.4; var HANDLER_TRIANGLE_RATIO = 0.4; var ContinueLegend = /** @class */ (function (_super) { tslib_1.__extends(ContinueLegend, _super); function ContinueLegend() { return _super !== null && _super.apply(this, arguments) || this; } ContinueLegend.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { type: 'continue', min: 0, max: 100, value: null, colors: [], track: {}, rail: {}, label: {}, handler: {}, slidable: true, tip: null, step: null, maxWidth: null, maxHeight: null, defaultCfg: { label: { align: 'rail', spacing: 5, formatter: null, style: { fontSize: 12, fill: theme_1.default.textColor, textBaseline: 'middle', fontFamily: theme_1.default.fontFamily, }, }, handler: { size: 10, style: { fill: '#fff', stroke: '#333', }, }, track: {}, rail: { type: 'color', size: 20, defaultLength: 100, style: { fill: '#DCDEE2', }, }, title: { spacing: 5, style: { fill: theme_1.default.textColor, fontSize: 12, textAlign: 'start', textBaseline: 'top', }, }, } }); }; ContinueLegend.prototype.isSlider = function () { return true; }; // 实现 IList 接口 ContinueLegend.prototype.getValue = function () { return this.getCurrentValue(); }; ContinueLegend.prototype.getRange = function () { return { min: this.get('min'), max: this.get('max'), }; }; // 改变 range ContinueLegend.prototype.setRange = function (min, max) { this.update({ min: min, max: max, }); }; ContinueLegend.prototype.setValue = function (value) { var originValue = this.getValue(); this.set('value', value); var group = this.get('group'); this.resetTrackClip(); if (this.get('slidable')) { this.resetHandlers(group); } this.delegateEmit('valuechanged', { originValue: originValue, value: value, }); }; ContinueLegend.prototype.initEvent = function () { var group = this.get('group'); this.bindSliderEvent(group); this.bindRailEvent(group); this.bindTrackEvent(group); }; ContinueLegend.prototype.drawLegendContent = function (group) { this.drawRail(group); this.drawLabels(group); this.fixedElements(group); // 调整各个图形位置,适应宽高的限制 this.resetTrack(group); this.resetTrackClip(group); if (this.get('slidable')) { this.resetHandlers(group); } }; ContinueLegend.prototype.bindSliderEvent = function (group) { this.bindHandlersEvent(group); }; ContinueLegend.prototype.bindHandlersEvent = function (group) { var _this = this; group.on('legend-handler-min:drag', function (ev) { var minValue = _this.getValueByCanvasPoint(ev.x, ev.y); var currentValue = _this.getCurrentValue(); var maxValue = currentValue[1]; if (maxValue < minValue) { // 如果小于最小值,则调整最小值 maxValue = minValue; } _this.setValue([minValue, maxValue]); }); group.on('legend-handler-max:drag', function (ev) { var maxValue = _this.getValueByCanvasPoint(ev.x, ev.y); var currentValue = _this.getCurrentValue(); var minValue = currentValue[0]; if (minValue > maxValue) { // 如果小于最小值,则调整最小值 minValue = maxValue; } _this.setValue([minValue, maxValue]); }); }; ContinueLegend.prototype.bindRailEvent = function (group) { }; ContinueLegend.prototype.bindTrackEvent = function (group) { var _this = this; var prePoint = null; group.on('legend-track:dragstart', function (ev) { prePoint = { x: ev.x, y: ev.y, }; }); group.on('legend-track:drag', function (ev) { if (!prePoint) { return; } var preValue = _this.getValueByCanvasPoint(prePoint.x, prePoint.y); var curValue = _this.getValueByCanvasPoint(ev.x, ev.y); var currentValue = _this.getCurrentValue(); var curDiff = currentValue[1] - currentValue[0]; var range = _this.getRange(); var dValue = curValue - preValue; if (dValue < 0) { // 减小, 同时未出边界 if (currentValue[0] + dValue > range.min) { _this.setValue([currentValue[0] + dValue, currentValue[1] + dValue]); } else { _this.setValue([range.min, range.min + curDiff]); } // && || } else if (dValue > 0) { if (dValue > 0 && currentValue[1] + dValue < range.max) { _this.setValue([currentValue[0] + dValue, currentValue[1] + dValue]); } else { _this.setValue([range.max - curDiff, range.max]); } } prePoint = { x: ev.x, y: ev.y, }; }); group.on('legend-track:dragend', function (ev) { prePoint = null; }); }; ContinueLegend.prototype.drawLabels = function (group) { this.drawLabel('min', group); this.drawLabel('max', group); }; ContinueLegend.prototype.drawLabel = function (name, group) { var labelCfg = this.get('label'); var style = labelCfg.style; var labelAlign = labelCfg.align; var value = this.get(name); var alignAttrs = this.getLabelAlignAttrs(name, labelAlign); var localId = "label-" + name; this.addShape(group, { type: 'text', id: this.getElementId(localId), name: "legend-label-" + name, attrs: tslib_1.__assign(tslib_1.__assign({ x: 0, y: 0, text: value }, style), alignAttrs), }); }; // 获取文本的对齐方式,为了自适应真实操碎了心 ContinueLegend.prototype.getLabelAlignAttrs = function (name, align) { var isVertical = this.isVertical(); var textAlign = 'center'; var textBaseline = 'middle'; if (isVertical) { // 垂直布局的所有的文本都左对齐 textAlign = 'start'; if (align !== 'rail') { if (name === 'min') { textBaseline = 'top'; } else { textBaseline = 'bottom'; } } else { textBaseline = 'top'; } } else { if (align !== 'rail') { textBaseline = 'top'; if (name === 'min') { textAlign = 'start'; } else { textAlign = 'end'; } } else { textAlign = 'start'; textBaseline = 'middle'; } } return { textAlign: textAlign, textBaseline: textBaseline, }; }; ContinueLegend.prototype.getRailPath = function (x, y, w, h) { var railCfg = this.get('rail'); var size = railCfg.size, defaultLength = railCfg.defaultLength, type = railCfg.type; var isVertical = this.isVertical(); var length = defaultLength; var width = w; var height = h; if (!width) { width = isVertical ? size : length; } if (!height) { height = isVertical ? length : size; } var path = []; if (type === 'color') { path.push(['M', x, y]); path.push(['L', x + width, y]); path.push(['L', x + width, y + height]); path.push(['L', x, y + height]); path.push(['Z']); } else { path.push(['M', x + width, y]); path.push(['L', x + width, y + height]); path.push(['L', x, y + height]); path.push(['Z']); } return path; }; ContinueLegend.prototype.drawRail = function (group) { var railCfg = this.get('rail'); var style = railCfg.style; this.addShape(group, { type: 'path', id: this.getElementId('rail'), name: 'legend-rail', attrs: tslib_1.__assign({ path: this.getRailPath(0, 0) }, style), }); }; // 将传入的颜色转换成渐变色 ContinueLegend.prototype.getTrackColor = function (colors) { var count = colors.length; if (!count) { return null; } if (count === 1) { return colors[0]; } var color; // 最终形态 l(0) 0:colors[0] 0.5:colors[1] 1:colors[2]; if (this.isVertical()) { // 根据方向设置渐变方向 color = 'l(90)'; } else { color = 'l(0)'; } for (var i = 0; i < count; i++) { var percent = i / (count - 1); color += " " + percent + ":" + colors[i]; } return color; }; ContinueLegend.prototype.getTrackPath = function (group) { var railShape = this.getRailShape(group); var path = railShape.attr('path'); return util_1.clone(path); }; ContinueLegend.prototype.getClipTrackAttrs = function (group) { var value = this.getCurrentValue(); var min = value[0], max = value[1]; var railBBox = this.getRailBBox(group); var startPoint = this.getPointByValue(min, group); var endPoint = this.getPointByValue(max, group); var isVertical = this.isVertical(); var x; var y; var width; var height; if (isVertical) { x = railBBox.minX; y = startPoint.y; width = railBBox.width; height = endPoint.y - startPoint.y; } else { x = startPoint.x; y = railBBox.minY; width = endPoint.x - startPoint.x; height = railBBox.height; } return { x: x, y: y, width: width, height: height, }; }; // 获取 track 的属性,由 path 和 颜色构成 ContinueLegend.prototype.getTrackAttrs = function (group) { var trackCfg = this.get('track'); var colors = this.get('colors'); var path = this.getTrackPath(group); return util_1.mix({ path: path, fill: this.getTrackColor(colors), }, trackCfg.style); }; ContinueLegend.prototype.resetTrackClip = function (group) { var container = group || this.get('group'); var trackId = this.getElementId('track'); var trackShape = container.findById(trackId); var clipShape = trackShape.getClip(); var attrs = this.getClipTrackAttrs(group); if (!clipShape) { trackShape.setClip({ type: 'rect', attrs: attrs, }); } else { clipShape.attr(attrs); } }; ContinueLegend.prototype.resetTrack = function (group) { var trackId = this.getElementId('track'); var trackShape = group.findById(trackId); var trackAttrs = this.getTrackAttrs(group); if (trackShape) { trackShape.attr(trackAttrs); } else { this.addShape(group, { type: 'path', id: trackId, draggable: this.get('slidable'), name: 'legend-track', attrs: trackAttrs, }); } }; ContinueLegend.prototype.getPointByValue = function (value, group) { var _a = this.getRange(), min = _a.min, max = _a.max; var percent = (value - min) / (max - min); var bbox = this.getRailBBox(group); var isVertcal = this.isVertical(); var point = { x: 0, y: 0 }; if (isVertcal) { point.x = bbox.minX + bbox.width / 2; point.y = util_2.getValueByPercent(bbox.minY, bbox.maxY, percent); } else { point.x = util_2.getValueByPercent(bbox.minX, bbox.maxX, percent); point.y = bbox.minY + bbox.height / 2; } return point; }; ContinueLegend.prototype.getRailShape = function (group) { var container = group || this.get('group'); return container.findById(this.getElementId('rail')); }; // 获取滑轨的宽高信息 ContinueLegend.prototype.getRailBBox = function (group) { var railShape = this.getRailShape(group); var bbox = railShape.getBBox(); return bbox; }; ContinueLegend.prototype.getRailCanvasBBox = function () { var container = this.get('group'); var railShape = container.findById(this.getElementId('rail')); var bbox = railShape.getCanvasBBox(); return bbox; }; // 是否垂直 ContinueLegend.prototype.isVertical = function () { return this.get('layout') === 'vertical'; }; // 用于交互时 ContinueLegend.prototype.getValueByCanvasPoint = function (x, y) { var _a = this.getRange(), min = _a.min, max = _a.max; var bbox = this.getRailCanvasBBox(); // 因为 x, y 是画布坐标 var isVertcal = this.isVertical(); var step = this.get('step'); var percent; if (isVertcal) { // 垂直时计算 y percent = (y - bbox.minY) / bbox.height; } else { // 水平时计算 x percent = (x - bbox.minX) / bbox.width; } var value = util_2.getValueByPercent(min, max, percent); if (step) { var count = Math.round((value - min) / step); value = min + count * step; // 移动到最近的 } if (value > max) { value = max; } if (value < min) { value = min; } return value; }; // 当前选中的范围 ContinueLegend.prototype.getCurrentValue = function () { var value = this.get('value'); if (!value) { // 如果没有定义,取最大范围 value = [this.get('min'), this.get('max')]; } return value; }; // 重置滑块 handler ContinueLegend.prototype.resetHandlers = function (group) { var currentValue = this.getCurrentValue(); var min = currentValue[0], max = currentValue[1]; this.resetHandler(group, 'min', min); this.resetHandler(group, 'max', max); }; // 获取滑块的 path ContinueLegend.prototype.getHandlerPath = function (handlerCfg, point) { var isVertical = this.isVertical(); var path = []; var width = handlerCfg.size; var x = point.x, y = point.y; var height = width * HANDLER_HEIGHT_RATIO; var halfWidth = width / 2; var oneSixthWidth = width / 6; if (isVertical) { /** * 竖直情况下的滑块 handler,左侧顶点是 x,y * /----| * -- | * -- | * \----| */ var triangleX = x + height * HANDLER_TRIANGLE_RATIO; path.push(['M', x, y]); path.push(['L', triangleX, y + halfWidth]); path.push(['L', x + height, y + halfWidth]); path.push(['L', x + height, y - halfWidth]); path.push(['L', triangleX, y - halfWidth]); path.push(['Z']); // 绘制两条横线 path.push(['M', triangleX, y + oneSixthWidth]); path.push(['L', x + height - 2, y + oneSixthWidth]); path.push(['M', triangleX, y - oneSixthWidth]); path.push(['L', x + height - 2, y - oneSixthWidth]); } else { /** * 水平情况下的滑块,上面顶点处是 x,y * / \ * | | | | * | | | | * ----- */ var triangleY = y + height * HANDLER_TRIANGLE_RATIO; path.push(['M', x, y]); path.push(['L', x - halfWidth, triangleY]); path.push(['L', x - halfWidth, y + height]); path.push(['L', x + halfWidth, y + height]); path.push(['L', x + halfWidth, triangleY]); path.push(['Z']); // 绘制两条竖线 path.push(['M', x - oneSixthWidth, triangleY]); path.push(['L', x - oneSixthWidth, y + height - 2]); path.push(['M', x + oneSixthWidth, triangleY]); path.push(['L', x + oneSixthWidth, y + height - 2]); } return path; }; // 调整 handler 的位置,如果未存在则绘制 ContinueLegend.prototype.resetHandler = function (group, name, value) { var point = this.getPointByValue(value, group); var handlerCfg = this.get('handler'); var path = this.getHandlerPath(handlerCfg, point); var id = this.getElementId("handler-" + name); var handlerShape = group.findById(id); var isVertical = this.isVertical(); if (handlerShape) { handlerShape.attr('path', path); } else { this.addShape(group, { type: 'path', name: "legend-handler-" + name, draggable: true, id: id, attrs: tslib_1.__assign(tslib_1.__assign({ path: path }, handlerCfg.style), { cursor: isVertical ? 'ns-resize' : 'ew-resize' }), }); } }; // 当设置了 maxWidth, maxHeight 时调整 rail 的宽度, // 文本的位置 ContinueLegend.prototype.fixedElements = function (group) { var railShape = group.findById(this.getElementId('rail')); var minLabel = group.findById(this.getElementId('label-min')); var maxLabel = group.findById(this.getElementId('label-max')); var startPoint = this.getDrawPoint(); if (this.isVertical()) { // 横向布局 this.fixedVertail(minLabel, maxLabel, railShape, startPoint); } else { // 水平布局 this.fixedHorizontal(minLabel, maxLabel, railShape, startPoint); } }; ContinueLegend.prototype.fitRailLength = function (minLabelBBox, maxLabelBBox, railBBox, railShape) { var isVertical = this.isVertical(); var lengthField = isVertical ? 'height' : 'width'; var labelCfg = this.get('label'); var labelAlign = labelCfg.align; var spacing = labelCfg.spacing; var maxLength = this.get("max" + util_1.upperFirst(lengthField)); // get('maxWidth') if (maxLength) { var elementsLength = labelAlign === 'rail' ? railBBox[lengthField] + minLabelBBox[lengthField] + maxLabelBBox[lengthField] + spacing * 2 : railBBox[lengthField]; var diff = elementsLength - maxLength; if (diff > 0) { // 大于限制的长度 this.changeRailLength(railShape, lengthField, railBBox[lengthField] - diff); } } }; ContinueLegend.prototype.changeRailLength = function (railShape, lengthField, length) { var bbox = railShape.getBBox(); var path; if (lengthField === 'height') { path = this.getRailPath(bbox.x, bbox.y, bbox.width, length); } else { path = this.getRailPath(bbox.x, bbox.y, length, bbox.height); } railShape.attr('path', path); }; ContinueLegend.prototype.changeRailPosition = function (railShape, x, y) { var bbox = railShape.getBBox(); var path = this.getRailPath(x, y, bbox.width, bbox.height); railShape.attr('path', path); }; ContinueLegend.prototype.fixedHorizontal = function (minLabel, maxLabel, railShape, startPoint) { var labelCfg = this.get('label'); var labelAlign = labelCfg.align; var spacing = labelCfg.spacing; var railBBox = railShape.getBBox(); var minLabelBBox = minLabel.getBBox(); var maxLabelBBox = maxLabel.getBBox(); var railHeight = railBBox.height; // 取 rail 的高度,作为高度 this.fitRailLength(minLabelBBox, maxLabelBBox, railBBox, railShape); railBBox = railShape.getBBox(); if (labelAlign === 'rail') { // 沿着 rail 方向 minLabel.attr({ x: startPoint.x, y: startPoint.y + railHeight / 2, }); this.changeRailPosition(railShape, startPoint.x + minLabelBBox.width + spacing, startPoint.y); maxLabel.attr({ x: startPoint.x + minLabelBBox.width + railBBox.width + spacing * 2, y: startPoint.y + railHeight / 2, }); } else if (labelAlign === 'top') { minLabel.attr({ x: startPoint.x, y: startPoint.y, }); maxLabel.attr({ x: startPoint.x + railBBox.width, y: startPoint.y, }); this.changeRailPosition(railShape, startPoint.x, startPoint.y + minLabelBBox.height + spacing); } else { this.changeRailPosition(railShape, startPoint.x, startPoint.y); minLabel.attr({ x: startPoint.x, y: startPoint.y + railBBox.height + spacing, }); maxLabel.attr({ x: startPoint.x + railBBox.width, y: startPoint.y + railBBox.height + spacing, }); } }; ContinueLegend.prototype.fixedVertail = function (minLabel, maxLabel, railShape, startPoint) { var labelCfg = this.get('label'); var labelAlign = labelCfg.align; var spacing = labelCfg.spacing; var railBBox = railShape.getBBox(); var minLabelBBox = minLabel.getBBox(); var maxLabelBBox = maxLabel.getBBox(); this.fitRailLength(minLabelBBox, maxLabelBBox, railBBox, railShape); railBBox = railShape.getBBox(); if (labelAlign === 'rail') { // 沿着 rail 方向 minLabel.attr({ x: startPoint.x, y: startPoint.y, }); this.changeRailPosition(railShape, startPoint.x, startPoint.y + minLabelBBox.height + spacing); maxLabel.attr({ x: startPoint.x, y: startPoint.y + minLabelBBox.height + railBBox.height + spacing * 2, }); } else if (labelAlign === 'right') { minLabel.attr({ x: startPoint.x + railBBox.width + spacing, y: startPoint.y, }); this.changeRailPosition(railShape, startPoint.x, startPoint.y); maxLabel.attr({ x: startPoint.x + railBBox.width + spacing, y: startPoint.y + railBBox.height, }); } else { // left var maxLabelWidth = Math.max(minLabelBBox.width, maxLabelBBox.width); minLabel.attr({ x: startPoint.x, y: startPoint.y, }); this.changeRailPosition(railShape, startPoint.x + maxLabelWidth + spacing, startPoint.y); maxLabel.attr({ x: startPoint.x, y: startPoint.y + railBBox.height, }); } }; return ContinueLegend; }(base_1.default)); exports.default = ContinueLegend; },{"../util/theme":76,"../util/util":77,"./base":52,"@antv/util":803,"tslib":894}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var category_1 = require("./category"); Object.defineProperty(exports, "Category", { enumerable: true, get: function () { return category_1.default; } }); var continuous_1 = require("./continuous"); Object.defineProperty(exports, "Continuous", { enumerable: true, get: function () { return continuous_1.default; } }); var base_1 = require("./base"); Object.defineProperty(exports, "Base", { enumerable: true, get: function () { return base_1.default; } }); },{"./base":52,"./category":53,"./continuous":54}],56:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); tslib_1.__exportStar(require("./scrollbar"), exports); },{"./scrollbar":57,"tslib":894}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Scrollbar = exports.DEFAULT_THEME = void 0; var tslib_1 = require("tslib"); var dom_util_1 = require("@antv/dom-util"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var DEFAULT_STYLE = { trackColor: 'rgba(0,0,0,0)', thumbColor: 'rgba(0,0,0,0.15)', size: 8, lineCap: 'round', }; exports.DEFAULT_THEME = { // 默认样式 default: DEFAULT_STYLE, // 鼠标 hover 的样式 hover: { thumbColor: 'rgba(0,0,0,0.2)', }, }; var Scrollbar = /** @class */ (function (_super) { tslib_1.__extends(Scrollbar, _super); function Scrollbar() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.clearEvents = util_1.noop; _this.onStartEvent = function (isMobile) { return function (e) { _this.isMobile = isMobile; e.originalEvent.preventDefault(); var clientX = isMobile ? util_1.get(e.originalEvent, 'touches.0.clientX') : e.clientX; var clientY = isMobile ? util_1.get(e.originalEvent, 'touches.0.clientY') : e.clientY; // 将开始的点记录下来 _this.startPos = _this.cfg.isHorizontal ? clientX : clientY; _this.bindLaterEvent(); }; }; _this.bindLaterEvent = function () { var containerDOM = _this.getContainerDOM(); var events = []; if (_this.isMobile) { events = [ dom_util_1.addEventListener(containerDOM, 'touchmove', _this.onMouseMove), dom_util_1.addEventListener(containerDOM, 'touchend', _this.onMouseUp), dom_util_1.addEventListener(containerDOM, 'touchcancel', _this.onMouseUp), ]; } else { events = [ dom_util_1.addEventListener(containerDOM, 'mousemove', _this.onMouseMove), dom_util_1.addEventListener(containerDOM, 'mouseup', _this.onMouseUp), // 为了保证划出 canvas containerDom 时还没触发 mouseup dom_util_1.addEventListener(containerDOM, 'mouseleave', _this.onMouseUp), ]; } _this.clearEvents = function () { events.forEach(function (e) { e.remove(); }); }; }; // 拖拽滑块的事件回调 // 这里是 dom 原生事件,绑定在 dom 元素上的 _this.onMouseMove = function (e) { var _a = _this.cfg, isHorizontal = _a.isHorizontal, thumbOffset = _a.thumbOffset; e.preventDefault(); var clientX = _this.isMobile ? util_1.get(e, 'touches.0.clientX') : e.clientX; var clientY = _this.isMobile ? util_1.get(e, 'touches.0.clientY') : e.clientY; // 鼠标松开的位置 var endPos = isHorizontal ? clientX : clientY; // 滑块需要移动的距离, 由于这里是对滑块监听,所以移动的距离就是 diffDis, 如果监听对象是 container dom,则需要算比例 var diff = endPos - _this.startPos; // 更新 _startPos _this.startPos = endPos; _this.updateThumbOffset(thumbOffset + diff); }; _this.onMouseUp = function (e) { e.preventDefault(); _this.clearEvents(); }; // 点击滑道的事件回调,移动滑块位置 _this.onTrackClick = function (e) { var _a = _this.cfg, isHorizontal = _a.isHorizontal, x = _a.x, y = _a.y, thumbLen = _a.thumbLen; var containerDOM = _this.getContainerDOM(); var rect = containerDOM.getBoundingClientRect(); var clientX = e.clientX, clientY = e.clientY; var offset = isHorizontal ? clientX - rect.left - x - thumbLen / 2 : clientY - rect.top - y - thumbLen / 2; var newOffset = _this.validateRange(offset); _this.updateThumbOffset(newOffset); }; _this.onThumbMouseOver = function () { var thumbColor = _this.cfg.theme.hover.thumbColor; _this.getElementByLocalId('thumb').attr('stroke', thumbColor); _this.draw(); }; _this.onThumbMouseOut = function () { var thumbColor = _this.cfg.theme.default.thumbColor; _this.getElementByLocalId('thumb').attr('stroke', thumbColor); _this.draw(); }; return _this; } Scrollbar.prototype.setRange = function (min, max) { this.set('minLimit', min); this.set('maxLimit', max); var curValue = this.getValue(); var newValue = util_1.clamp(curValue, min, max); if (curValue !== newValue && !this.get('isInit')) { this.setValue(newValue); } }; Scrollbar.prototype.getRange = function () { var min = this.get('minLimit') || 0; var max = this.get('maxLimit') || 1; return { min: min, max: max }; }; Scrollbar.prototype.setValue = function (value) { var range = this.getRange(); var originalValue = this.getValue(); this.update({ thumbOffset: (this.get('trackLen') - this.get('thumbLen')) * util_1.clamp(value, range.min, range.max), }); this.delegateEmit('valuechange', { originalValue: originalValue, value: this.getValue(), }); }; Scrollbar.prototype.getValue = function () { return util_1.clamp(this.get('thumbOffset') / (this.get('trackLen') - this.get('thumbLen')), 0, 1); }; Scrollbar.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'scrollbar', isHorizontal: true, minThumbLen: 20, thumbOffset: 0, theme: exports.DEFAULT_THEME }); }; Scrollbar.prototype.renderInner = function (group) { this.renderTrackShape(group); this.renderThumbShape(group); }; Scrollbar.prototype.applyOffset = function () { this.moveElementTo(this.get('group'), { x: this.get('x'), y: this.get('y'), }); }; Scrollbar.prototype.initEvent = function () { this.bindEvents(); }; // 创建滑道的 shape Scrollbar.prototype.renderTrackShape = function (group) { var _a = this.cfg, trackLen = _a.trackLen, _b = _a.theme, theme = _b === void 0 ? { default: {} } : _b; var _c = theme.default, lineCap = _c.lineCap, trackColor = _c.trackColor, size = _c.size; var attrs = this.get('isHorizontal') ? { x1: 0 + size / 2, y1: size / 2, x2: trackLen - size / 2, y2: size / 2, lineWidth: size, stroke: trackColor, lineCap: lineCap, } : { x1: size / 2, y1: 0 + size / 2, x2: size / 2, y2: trackLen - size / 2, lineWidth: size, stroke: trackColor, lineCap: lineCap, }; return this.addShape(group, { id: this.getElementId('track'), name: 'track', type: 'line', attrs: attrs, }); }; // 创建滑块的 shape Scrollbar.prototype.renderThumbShape = function (group) { var _a = this.cfg, thumbOffset = _a.thumbOffset, thumbLen = _a.thumbLen, _b = _a.theme, theme = _b === void 0 ? { default: {} } : _b; var _c = theme.default, size = _c.size, lineCap = _c.lineCap, thumbColor = _c.thumbColor; var attrs = this.get('isHorizontal') ? { x1: thumbOffset + size / 2, y1: size / 2, x2: thumbOffset + thumbLen - size / 2, y2: size / 2, lineWidth: size, stroke: thumbColor, lineCap: lineCap, cursor: 'default', } : { x1: size / 2, y1: thumbOffset + size / 2, x2: size / 2, y2: thumbOffset + thumbLen - size / 2, lineWidth: size, stroke: thumbColor, lineCap: lineCap, cursor: 'default', }; return this.addShape(group, { id: this.getElementId('thumb'), name: 'thumb', type: 'line', attrs: attrs, }); }; Scrollbar.prototype.bindEvents = function () { var group = this.get('group'); group.on('mousedown', this.onStartEvent(false)); group.on('mouseup', this.onMouseUp); group.on('touchstart', this.onStartEvent(true)); group.on('touchend', this.onMouseUp); var trackShape = group.findById(this.getElementId('track')); trackShape.on('click', this.onTrackClick); var thumbShape = group.findById(this.getElementId('thumb')); thumbShape.on('mouseover', this.onThumbMouseOver); thumbShape.on('mouseout', this.onThumbMouseOut); }; Scrollbar.prototype.getContainerDOM = function () { var container = this.get('container'); var canvas = container && container.get('canvas'); return canvas && canvas.get('container'); }; Scrollbar.prototype.validateRange = function (offset) { var _a = this.cfg, thumbLen = _a.thumbLen, trackLen = _a.trackLen; var newOffset = offset; if (offset + thumbLen > trackLen) { newOffset = trackLen - thumbLen; } else if (offset + thumbLen < thumbLen) { newOffset = 0; } return newOffset; }; Scrollbar.prototype.draw = function () { var container = this.get('container'); var canvas = container && container.get('canvas'); if (canvas) { canvas.draw(); } }; Scrollbar.prototype.updateThumbOffset = function (offset) { var _a = this.cfg, thumbOffset = _a.thumbOffset, isHorizontal = _a.isHorizontal, thumbLen = _a.thumbLen, size = _a.size; var newOffset = this.validateRange(offset); if (newOffset === thumbOffset) { // 如果更新后的 offset 与原值相同,则不改变 return; } var thumbShape = this.getElementByLocalId('thumb'); if (isHorizontal) { thumbShape.attr({ x1: newOffset + size / 2, x2: newOffset + thumbLen - size / 2, }); } else { thumbShape.attr({ y1: newOffset + size / 2, y2: newOffset + thumbLen - size / 2, }); } this.emitOffsetChange(newOffset); }; Scrollbar.prototype.emitOffsetChange = function (offset) { var _a = this.cfg, originalValue = _a.thumbOffset, trackLen = _a.trackLen, thumbLen = _a.thumbLen; this.cfg.thumbOffset = offset; // 发送事件 this.emit('scrollchange', { thumbOffset: offset, ratio: util_1.clamp(offset / (trackLen - thumbLen), 0, 1), }); this.delegateEmit('valuechange', { originalValue: originalValue, value: offset, }); }; return Scrollbar; }(group_component_1.default)); exports.Scrollbar = Scrollbar; },{"../abstract/group-component":21,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],58:[function(require,module,exports){ "use strict"; /** * 一些默认的样式配置 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SLIDER_CHANGE = exports.TEXT_STYLE = exports.HANDLER_STYLE = exports.DEFAULT_HANDLER_WIDTH = exports.FOREGROUND_STYLE = exports.BACKGROUND_STYLE = void 0; exports.BACKGROUND_STYLE = { fill: '#416180', opacity: 0.05, }; exports.FOREGROUND_STYLE = { fill: '#5B8FF9', opacity: 0.15, cursor: 'move', }; exports.DEFAULT_HANDLER_WIDTH = 10; exports.HANDLER_STYLE = { width: exports.DEFAULT_HANDLER_WIDTH, height: 24, }; exports.TEXT_STYLE = { textBaseline: 'middle', fill: '#000', opacity: 0.45, }; exports.SLIDER_CHANGE = 'sliderchange'; },{}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Handler = void 0; var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var DEFAULT_STYLE = { fill: '#F7F7F7', stroke: '#BFBFBF', radius: 2, opacity: 1, cursor: 'ew-resize', // 高亮的颜色 highLightFill: '#FFF', }; var Handler = /** @class */ (function (_super) { tslib_1.__extends(Handler, _super); function Handler() { return _super !== null && _super.apply(this, arguments) || this; } Handler.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'handler', x: 0, y: 0, width: 10, height: 24, style: DEFAULT_STYLE }); }; Handler.prototype.renderInner = function (group) { var _a = this.cfg, width = _a.width, height = _a.height, style = _a.style; var fill = style.fill, stroke = style.stroke, radius = style.radius, opacity = style.opacity, cursor = style.cursor; // 按钮框框 this.addShape(group, { type: 'rect', id: this.getElementId('background'), attrs: { x: 0, y: 0, width: width, height: height, fill: fill, stroke: stroke, radius: radius, opacity: opacity, cursor: cursor, }, }); // 两根竖线 var x1 = (1 / 3) * width; var x2 = (2 / 3) * width; var y1 = (1 / 4) * height; var y2 = (3 / 4) * height; this.addShape(group, { id: this.getElementId('line-left'), type: 'line', attrs: { x1: x1, y1: y1, x2: x1, y2: y2, stroke: stroke, cursor: cursor, }, }); this.addShape(group, { id: this.getElementId('line-right'), type: 'line', attrs: { x1: x2, y1: y1, x2: x2, y2: y2, stroke: stroke, cursor: cursor, }, }); }; Handler.prototype.applyOffset = function () { this.moveElementTo(this.get('group'), { x: this.get('x'), y: this.get('y'), }); }; Handler.prototype.initEvent = function () { this.bindEvents(); }; Handler.prototype.bindEvents = function () { var _this = this; this.get('group').on('mouseenter', function () { var highLightFill = _this.get('style').highLightFill; _this.getElementByLocalId('background').attr('fill', highLightFill); _this.draw(); }); this.get('group').on('mouseleave', function () { var fill = _this.get('style').fill; _this.getElementByLocalId('background').attr('fill', fill); _this.draw(); }); }; Handler.prototype.draw = function () { var canvas = this.get('container').get('canvas'); if (canvas) { canvas.draw(); } }; return Handler; }(group_component_1.default)); exports.Handler = Handler; exports.default = Handler; },{"../abstract/group-component":21,"tslib":894}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var slider_1 = require("./slider"); Object.defineProperty(exports, "Slider", { enumerable: true, get: function () { return slider_1.Slider; } }); },{"./slider":61}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Slider = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var group_component_1 = require("../abstract/group-component"); var trend_1 = require("../trend/trend"); var constant_1 = require("./constant"); var handler_1 = require("./handler"); var Slider = /** @class */ (function (_super) { tslib_1.__extends(Slider, _super); function Slider() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.onMouseDown = function (target) { return function (e) { _this.currentTarget = target; // 取出原生事件 var event = e.originalEvent; // 2. 存储当前点击位置 event.stopPropagation(); event.preventDefault(); // 兼容移动端获取数据 _this.prevX = util_1.get(event, 'touches.0.pageX', event.pageX); _this.prevY = util_1.get(event, 'touches.0.pageY', event.pageY); // 3. 开始滑动的时候,绑定 move 和 up 事件 var containerDOM = _this.getContainerDOM(); containerDOM.addEventListener('mousemove', _this.onMouseMove); containerDOM.addEventListener('mouseup', _this.onMouseUp); containerDOM.addEventListener('mouseleave', _this.onMouseUp); // 移动端事件 containerDOM.addEventListener('touchmove', _this.onMouseMove); containerDOM.addEventListener('touchend', _this.onMouseUp); containerDOM.addEventListener('touchcancel', _this.onMouseUp); }; }; _this.onMouseMove = function (event) { var width = _this.cfg.width; var originValue = [_this.get('start'), _this.get('end')]; // 滑动过程中,计算偏移,更新滑块,然后 emit 数据出去 event.stopPropagation(); event.preventDefault(); var x = util_1.get(event, 'touches.0.pageX', event.pageX); var y = util_1.get(event, 'touches.0.pageY', event.pageY); // 横向的 slider 只处理 x var offsetX = x - _this.prevX; var offsetXRange = _this.adjustOffsetRange(offsetX / width); // 更新 start end range 范围 _this.updateStartEnd(offsetXRange); // 更新 ui _this.updateUI(_this.getElementByLocalId('foreground'), _this.getElementByLocalId('minText'), _this.getElementByLocalId('maxText')); _this.prevX = x; _this.prevY = y; _this.draw(); // 因为存储的 start、end 可能不一定是按大小存储的,所以排序一下,对外是 end >= start _this.emit(constant_1.SLIDER_CHANGE, [_this.get('start'), _this.get('end')].sort()); _this.delegateEmit('valuechanged', { originValue: originValue, value: [_this.get('start'), _this.get('end')], }); }; _this.onMouseUp = function () { // 结束之后,取消绑定的事件 if (_this.currentTarget) { _this.currentTarget = undefined; } var containerDOM = _this.getContainerDOM(); if (containerDOM) { containerDOM.removeEventListener('mousemove', _this.onMouseMove); containerDOM.removeEventListener('mouseup', _this.onMouseUp); // 防止滑动到 canvas 外部之后,状态丢失 containerDOM.removeEventListener('mouseleave', _this.onMouseUp); // 移动端事件 containerDOM.removeEventListener('touchmove', _this.onMouseMove); containerDOM.removeEventListener('touchend', _this.onMouseUp); containerDOM.removeEventListener('touchcancel', _this.onMouseUp); } }; return _this; } Slider.prototype.setRange = function (min, max) { this.set('minLimit', min); this.set('maxLimit', max); var oldStart = this.get('start'); var oldEnd = this.get('end'); var newStart = util_1.clamp(oldStart, min, max); var newEnd = util_1.clamp(oldEnd, min, max); if (!this.get('isInit') && (oldStart !== newStart || oldEnd !== newEnd)) { this.setValue([newStart, newEnd]); } }; Slider.prototype.getRange = function () { return { min: this.get('minLimit') || 0, max: this.get('maxLimit') || 1, }; }; Slider.prototype.setValue = function (value) { var range = this.getRange(); if (util_1.isArray(value) && value.length === 2) { var originValue = [this.get('start'), this.get('end')]; this.update({ start: util_1.clamp(value[0], range.min, range.max), end: util_1.clamp(value[1], range.min, range.max), }); if (!this.get('updateAutoRender')) { this.render(); } this.delegateEmit('valuechanged', { originValue: originValue, value: value, }); } }; Slider.prototype.getValue = function () { return [this.get('start'), this.get('end')]; }; Slider.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'slider', x: 0, y: 0, width: 100, height: 16, backgroundStyle: {}, foregroundStyle: {}, handlerStyle: {}, textStyle: {}, defaultCfg: { backgroundStyle: constant_1.BACKGROUND_STYLE, foregroundStyle: constant_1.FOREGROUND_STYLE, handlerStyle: constant_1.HANDLER_STYLE, textStyle: constant_1.TEXT_STYLE, } }); }; Slider.prototype.update = function (cfg) { var start = cfg.start, end = cfg.end; var validCfg = tslib_1.__assign({}, cfg); if (!util_1.isNil(start)) { validCfg.start = util_1.clamp(start, 0, 1); } if (!util_1.isNil(end)) { validCfg.end = util_1.clamp(end, 0, 1); } _super.prototype.update.call(this, validCfg); this.minHandler = this.getChildComponentById(this.getElementId('minHandler')); this.maxHandler = this.getChildComponentById(this.getElementId('maxHandler')); }; Slider.prototype.init = function () { this.set('start', util_1.clamp(this.get('start'), 0, 1)); this.set('end', util_1.clamp(this.get('end'), 0, 1)); _super.prototype.init.call(this); }; Slider.prototype.renderInner = function (group) { var _a = this.cfg, start = _a.start, end = _a.end, width = _a.width, height = _a.height, _b = _a.trendCfg, trendCfg = _b === void 0 ? {} : _b, minText = _a.minText, maxText = _a.maxText, _c = _a.backgroundStyle, backgroundStyle = _c === void 0 ? {} : _c, _d = _a.foregroundStyle, foregroundStyle = _d === void 0 ? {} : _d, _e = _a.textStyle, textStyle = _e === void 0 ? {} : _e, _f = _a.handlerStyle, handlerStyle = _f === void 0 ? {} : _f; var min = start * width; var max = end * width; // 趋势图数据 if (util_1.size(util_1.get(trendCfg, 'data'))) { this.addComponent(group, tslib_1.__assign({ component: trend_1.Trend, id: this.getElementId('trend'), x: 0, y: 0, width: width, height: height }, trendCfg)); } // 1. 背景 this.addShape(group, { id: this.getElementId('background'), type: 'rect', attrs: tslib_1.__assign({ x: 0, y: 0, width: width, height: height }, backgroundStyle), }); // 2. 左右文字 var minTextShape = this.addShape(group, { id: this.getElementId('minText'), type: 'text', attrs: tslib_1.__assign({ // x: 0, y: height / 2, textAlign: 'right', text: minText, silent: false }, textStyle), }); var maxTextShape = this.addShape(group, { id: this.getElementId('maxText'), type: 'text', attrs: tslib_1.__assign({ // x: 0, y: height / 2, textAlign: 'left', text: maxText, silent: false }, textStyle), }); // 3. 前景 选中背景框 var foregroundShape = this.addShape(group, { id: this.getElementId('foreground'), name: 'foreground', type: 'rect', attrs: tslib_1.__assign({ // x: 0, y: 0, // width: 0, height: height }, foregroundStyle), }); // 滑块相关的大小信息 // const handlerWidth = get(handlerStyle, 'width', 10); var handlerHeight = util_1.get(handlerStyle, 'height', 24); // 4. 左右滑块 this.minHandler = this.addComponent(group, tslib_1.__assign({ component: handler_1.Handler, id: this.getElementId('minHandler'), name: 'handler-min', x: 0, y: (height - handlerHeight) / 2, width: width, height: handlerHeight, cursor: 'ew-resize' }, handlerStyle)); this.maxHandler = this.addComponent(group, tslib_1.__assign({ component: handler_1.Handler, id: this.getElementId('maxHandler'), name: 'handler-max', x: 0, y: (height - handlerHeight) / 2, width: width, height: handlerHeight, cursor: 'ew-resize' }, handlerStyle)); this.updateUI(foregroundShape, minTextShape, maxTextShape); }; Slider.prototype.applyOffset = function () { this.moveElementTo(this.get('group'), { x: this.get('x'), y: this.get('y'), }); }; Slider.prototype.initEvent = function () { this.bindEvents(); }; Slider.prototype.updateUI = function (foregroundShape, minTextShape, maxTextShape) { var _a = this.cfg, start = _a.start, end = _a.end, width = _a.width, minText = _a.minText, maxText = _a.maxText, handlerStyle = _a.handlerStyle; var min = start * width; var max = end * width; // 1. foreground foregroundShape.attr('x', min); foregroundShape.attr('width', max - min); // 滑块相关的大小信息 var handlerWidth = util_1.get(handlerStyle, 'width', constant_1.DEFAULT_HANDLER_WIDTH); // 设置文本 minTextShape.attr('text', minText); maxTextShape.attr('text', maxText); var _b = this._dodgeText([min, max], minTextShape, maxTextShape), minAttrs = _b[0], maxAttrs = _b[1]; // 2. 左侧滑块和文字位置 if (this.minHandler) { this.minHandler.update({ x: min - handlerWidth / 2, }); if (!this.get('updateAutoRender')) { this.minHandler.render(); } } util_1.each(minAttrs, function (v, k) { return minTextShape.attr(k, v); }); // 3. 右侧滑块和文字位置 if (this.maxHandler) { this.maxHandler.update({ x: max - handlerWidth / 2, }); if (!this.get('updateAutoRender')) { this.maxHandler.render(); } } util_1.each(maxAttrs, function (v, k) { return maxTextShape.attr(k, v); }); }; Slider.prototype.bindEvents = function () { var group = this.get('group'); group.on('handler-min:mousedown', this.onMouseDown('minHandler')); group.on('handler-min:touchstart', this.onMouseDown('minHandler')); // 2. 右滑块的滑动 group.on('handler-max:mousedown', this.onMouseDown('maxHandler')); group.on('handler-max:touchstart', this.onMouseDown('maxHandler')); // 3. 前景选中区域 var foreground = group.findById(this.getElementId('foreground')); foreground.on('mousedown', this.onMouseDown('foreground')); foreground.on('touchstart', this.onMouseDown('foreground')); }; /** * 调整 offsetRange,因为一些范围的限制 * @param offsetRange */ Slider.prototype.adjustOffsetRange = function (offsetRange) { var _a = this.cfg, start = _a.start, end = _a.end; // 针对不同的滑动组件,处理的方式不同 switch (this.currentTarget) { case 'minHandler': { var min = 0 - start; var max = 1 - start; return Math.min(max, Math.max(min, offsetRange)); } case 'maxHandler': { var min = 0 - end; var max = 1 - end; return Math.min(max, Math.max(min, offsetRange)); } case 'foreground': { var min = 0 - start; var max = 1 - end; return Math.min(max, Math.max(min, offsetRange)); } } }; Slider.prototype.updateStartEnd = function (offsetRange) { var _a = this.cfg, start = _a.start, end = _a.end; // 操作不同的组件,反馈不一样 switch (this.currentTarget) { case 'minHandler': start += offsetRange; break; case 'maxHandler': end += offsetRange; break; case 'foreground': start += offsetRange; end += offsetRange; break; } this.set('start', start); this.set('end', end); }; /** * 调整 text 的位置,自动躲避 * 根据位置,调整返回新的位置 * @param range */ Slider.prototype._dodgeText = function (range, minTextShape, maxTextShape) { var _a, _b; var _c = this.cfg, handlerStyle = _c.handlerStyle, width = _c.width; var PADDING = 2; var handlerWidth = util_1.get(handlerStyle, 'width', constant_1.DEFAULT_HANDLER_WIDTH); var min = range[0], max = range[1]; var sorted = false; // 如果交换了位置,则对应的 min max 也交互 if (min > max) { _a = [max, min], min = _a[0], max = _a[1]; _b = [maxTextShape, minTextShape], minTextShape = _b[0], maxTextShape = _b[1]; sorted = true; } // 避让规则,优先显示在两侧,只有显示不下的时候,才显示在中间 var minBBox = minTextShape.getBBox(); var maxBBox = maxTextShape.getBBox(); var minAttrs = minBBox.width > min - PADDING ? { x: min + handlerWidth / 2 + PADDING, textAlign: 'left' } : { x: min - handlerWidth / 2 - PADDING, textAlign: 'right' }; var maxAttrs = maxBBox.width > width - max - PADDING ? { x: max - handlerWidth / 2 - PADDING, textAlign: 'right' } : { x: max + handlerWidth / 2 + PADDING, textAlign: 'left' }; return !sorted ? [minAttrs, maxAttrs] : [maxAttrs, minAttrs]; }; Slider.prototype.draw = function () { var container = this.get('container'); var canvas = container && container.get('canvas'); if (canvas) { canvas.draw(); } }; Slider.prototype.getContainerDOM = function () { var container = this.get('container'); var canvas = container && container.get('canvas'); return canvas && canvas.get('container'); }; return Slider; }(group_component_1.default)); exports.Slider = Slider; exports.default = Slider; },{"../abstract/group-component":21,"../trend/trend":68,"./constant":58,"./handler":59,"@antv/util":803,"tslib":894}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CROSSHAIR_Y = exports.CROSSHAIR_X = exports.NAME_CLASS = exports.VALUE_CLASS = exports.MARKER_CLASS = exports.LIST_ITEM_CLASS = exports.LIST_CLASS = exports.TITLE_CLASS = exports.CONTAINER_CLASS = void 0; exports.CONTAINER_CLASS = 'g2-tooltip'; exports.TITLE_CLASS = 'g2-tooltip-title'; exports.LIST_CLASS = 'g2-tooltip-list'; exports.LIST_ITEM_CLASS = 'g2-tooltip-list-item'; exports.MARKER_CLASS = 'g2-tooltip-marker'; exports.VALUE_CLASS = 'g2-tooltip-value'; exports.NAME_CLASS = 'g2-tooltip-name'; exports.CROSSHAIR_X = 'g2-tooltip-crosshair-x'; exports.CROSSHAIR_Y = 'g2-tooltip-crosshair-y'; },{}],63:[function(require,module,exports){ "use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../util/theme"); // tooltip 相关 dom 的 css 类名 var CssConst = require("./css-const"); exports.default = (_a = {}, // css style for tooltip _a["" + CssConst.CONTAINER_CLASS] = { position: 'absolute', visibility: 'visible', // @2018-07-25 by blue.lb 这里去掉浮动,火狐上存在样式错位 // whiteSpace: 'nowrap', zIndex: 8, transition: 'visibility 0.2s cubic-bezier(0.23, 1, 0.32, 1), ' + 'left 0.4s cubic-bezier(0.23, 1, 0.32, 1), ' + 'top 0.4s cubic-bezier(0.23, 1, 0.32, 1)', backgroundColor: 'rgba(255, 255, 255, 0.9)', boxShadow: '0px 0px 10px #aeaeae', borderRadius: '3px', color: 'rgb(87, 87, 87)', fontSize: '12px', fontFamily: theme_1.default.fontFamily, lineHeight: '20px', padding: '10px 10px 6px 10px', }, _a["" + CssConst.TITLE_CLASS] = { marginBottom: '4px', }, _a["" + CssConst.LIST_CLASS] = { margin: '0px', listStyleType: 'none', padding: '0px', }, _a["" + CssConst.LIST_ITEM_CLASS] = { listStyleType: 'none', marginBottom: '4px', }, _a["" + CssConst.MARKER_CLASS] = { width: '8px', height: '8px', borderRadius: '50%', display: 'inline-block', marginRight: '8px', }, _a["" + CssConst.VALUE_CLASS] = { display: 'inline-block', float: 'right', marginLeft: '30px', }, _a["" + CssConst.CROSSHAIR_X] = { position: 'absolute', width: '1px', backgroundColor: 'rgba(0, 0, 0, 0.25)', }, _a["" + CssConst.CROSSHAIR_Y] = { position: 'absolute', height: '1px', backgroundColor: 'rgba(0, 0, 0, 0.25)', }, _a); },{"../util/theme":76,"./css-const":62}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var color_util_1 = require("@antv/color-util"); var dom_util_1 = require("@antv/dom-util"); var util_1 = require("@antv/util"); var html_component_1 = require("../abstract/html-component"); var util_2 = require("../util/util"); var CssConst = require("./css-const"); var html_theme_1 = require("./html-theme"); var align_1 = require("../util/align"); function hasOneKey(obj, keys) { var result = false; util_1.each(keys, function (key) { if (util_1.hasKey(obj, key)) { result = true; return false; } }); return result; } var Tooltip = /** @class */ (function (_super) { tslib_1.__extends(Tooltip, _super); function Tooltip() { return _super !== null && _super.apply(this, arguments) || this; } Tooltip.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'tooltip', type: 'html', x: 0, y: 0, items: [], customContent: null, containerTpl: "
", itemTpl: "
  • \n \n {name}:\n {value}\n
  • ", xCrosshairTpl: "
    ", yCrosshairTpl: "
    ", title: null, showTitle: true, /** * tooltip 限制的区域 * @type {Region} */ region: null, // crosshair 的限制区域 crosshairsRegion: null, containerClassName: CssConst.CONTAINER_CLASS, // x, y, xy crosshairs: null, offset: 10, position: 'right', domStyles: null, defaultStyles: html_theme_1.default }); }; // tooltip 渲染时,渲染 title,items 和 corosshairs Tooltip.prototype.render = function () { if (this.get('customContent')) { this.renderCustomContent(); } else { this.resetTitle(); this.renderItems(); } // 绘制完成后,再定位 this.resetPosition(); }; // 复写清空函数,因为有模板的存在,所以默认的写法不合适 Tooltip.prototype.clear = function () { // 由于 crosshair 没有在 container 内,所以需要单独清理 this.clearCrosshairs(); this.setTitle(''); // 清空标题 this.clearItemDoms(); }; Tooltip.prototype.show = function () { var container = this.getContainer(); if (!container || this.destroyed) { // 防止容器不存在或者被销毁时报错 return; } this.set('visible', true); dom_util_1.modifyCSS(container, { visibility: 'visible', }); this.setCrossHairsVisible(true); }; Tooltip.prototype.hide = function () { var container = this.getContainer(); // relative: https://github.com/antvis/g2/issues/1221 if (!container || this.destroyed) { return; } this.set('visible', false); dom_util_1.modifyCSS(container, { visibility: 'hidden', }); this.setCrossHairsVisible(false); }; // 实现 IPointLocation 的接口 Tooltip.prototype.getLocation = function () { return { x: this.get('x'), y: this.get('y') }; }; // 实现 IPointLocation 的接口 Tooltip.prototype.setLocation = function (point) { this.set('x', point.x); this.set('y', point.y); this.resetPosition(); }; Tooltip.prototype.setCrossHairsVisible = function (visible) { var display = visible ? '' : 'none'; var xCrosshairDom = this.get('xCrosshairDom'); var yCrosshairDom = this.get('yCrosshairDom'); xCrosshairDom && dom_util_1.modifyCSS(xCrosshairDom, { display: display, }); yCrosshairDom && dom_util_1.modifyCSS(yCrosshairDom, { display: display, }); }; // 如有 customContent 则根据 customContent 设置 container Tooltip.prototype.initContainer = function () { _super.prototype.initContainer.call(this); if (this.get('customContent')) { if (this.get('container')) { this.get('container').remove(); } var container = this.getHtmlContentNode(); this.get('parent').appendChild(container); this.set('container', container); this.resetStyles(); this.applyStyles(); } }; // 更新属性的同时,可能会引起 DOM 的变化,这里对可能引起 DOM 变化的场景做了处理 Tooltip.prototype.updateInner = function (cfg) { if (this.get('customContent')) { this.renderCustomContent(); } else { // 更新标题 if (hasOneKey(cfg, ['title', 'showTitle'])) { this.resetTitle(); } // 更新内容 if (util_1.hasKey(cfg, 'items')) { this.renderItems(); } } _super.prototype.updateInner.call(this, cfg); }; Tooltip.prototype.initDom = function () { this.cacheDoms(); }; // 清理 DOM Tooltip.prototype.removeDom = function () { _super.prototype.removeDom.call(this); this.clearCrosshairs(); }; // 调整位置 Tooltip.prototype.resetPosition = function () { var x = this.get('x'); var y = this.get('y'); var offset = this.get('offset'); var _a = this.getOffset(), offsetX = _a.offsetX, offsetY = _a.offsetY; var position = this.get('position'); var region = this.get('region'); var container = this.getContainer(); var bbox = this.getBBox(); var width = bbox.width, height = bbox.height; var limitBox; if (region) { // 不限制位置 limitBox = util_2.regionToBBox(region); } var point = align_1.getAlignPoint(x, y, offset, width, height, position, limitBox); dom_util_1.modifyCSS(container, { left: util_2.toPx(point.x + offsetX), top: util_2.toPx(point.y + offsetY), }); this.resetCrosshairs(); }; // 根据 customContent 渲染 Tooltip.prototype.renderCustomContent = function () { var node = this.getHtmlContentNode(); var parent = this.get('parent'); var curContainer = this.get('container'); if (curContainer && curContainer.parentNode === parent) { parent.replaceChild(node, curContainer); } else { parent.appendChild(node); } this.set('container', node); this.resetStyles(); this.applyStyles(); }; Tooltip.prototype.getHtmlContentNode = function () { var node; var customContent = this.get('customContent'); if (customContent) { var elem = customContent(this.get('title'), this.get('items')); if (util_1.isElement(elem)) { node = elem; } else { node = dom_util_1.createDom(elem); } } return node; }; // 缓存模板设置的各种 DOM Tooltip.prototype.cacheDoms = function () { var container = this.getContainer(); var titleDom = container.getElementsByClassName(CssConst.TITLE_CLASS)[0]; var listDom = container.getElementsByClassName(CssConst.LIST_CLASS)[0]; this.set('titleDom', titleDom); this.set('listDom', listDom); }; // 重置 title Tooltip.prototype.resetTitle = function () { var title = this.get('title'); var showTitle = this.get('showTitle'); if (showTitle && title) { this.setTitle(title); } else { this.setTitle(''); } }; // 设置 title 文本 Tooltip.prototype.setTitle = function (text) { var titleDom = this.get('titleDom'); if (titleDom) { titleDom.innerText = text; } }; // 终止 crosshair Tooltip.prototype.resetCrosshairs = function () { var crosshairsRegion = this.get('crosshairsRegion'); var crosshairs = this.get('crosshairs'); if (!crosshairsRegion || !crosshairs) { // 不显示 crosshair,都移除,没有设定 region 也都移除掉 this.clearCrosshairs(); } else { var crosshairBox = util_2.regionToBBox(crosshairsRegion); var xCrosshairDom = this.get('xCrosshairDom'); var yCrosshairDom = this.get('yCrosshairDom'); if (crosshairs === 'x') { this.resetCrosshair('x', crosshairBox); // 仅显示 x 的 crosshair,y 移除 if (yCrosshairDom) { yCrosshairDom.remove(); this.set('yCrosshairDom', null); } } else if (crosshairs === 'y') { this.resetCrosshair('y', crosshairBox); // 仅显示 y 的 crosshair,x 移除 if (xCrosshairDom) { xCrosshairDom.remove(); this.set('xCrosshairDom', null); } } else { this.resetCrosshair('x', crosshairBox); this.resetCrosshair('y', crosshairBox); } this.setCrossHairsVisible(this.get('visible')); } }; // 设定 crosshair 的位置,需要区分 x,y Tooltip.prototype.resetCrosshair = function (name, bbox) { var croshairDom = this.checkCrosshair(name); var value = this.get(name); if (name === 'x') { dom_util_1.modifyCSS(croshairDom, { left: util_2.toPx(value), top: util_2.toPx(bbox.y), height: util_2.toPx(bbox.height), }); } else { dom_util_1.modifyCSS(croshairDom, { top: util_2.toPx(value), left: util_2.toPx(bbox.x), width: util_2.toPx(bbox.width), }); } }; // 如果 crosshair 对应的 dom 不存在,则创建 Tooltip.prototype.checkCrosshair = function (name) { var domName = name + "CrosshairDom"; var tplName = name + "CrosshairTpl"; var constName = "CROSSHAIR_" + name.toUpperCase(); var styleName = CssConst[constName]; var croshairDom = this.get(domName); var parent = this.get('parent'); if (!croshairDom) { croshairDom = dom_util_1.createDom(this.get(tplName)); // 创建 this.applyStyle(styleName, croshairDom); // 设置初始样式 parent.appendChild(croshairDom); // 添加到跟 tooltip 同级的目录下 this.set(domName, croshairDom); } return croshairDom; }; Tooltip.prototype.renderItems = function () { this.clearItemDoms(); var items = this.get('items'); var itemTpl = this.get('itemTpl'); var listDom = this.get('listDom'); if (listDom) { util_1.each(items, function (item) { var color = color_util_1.default.toCSSGradient(item.color); var substituteObj = tslib_1.__assign(tslib_1.__assign({}, item), { color: color }); var domStr = util_1.substitute(itemTpl, substituteObj); var itemDom = dom_util_1.createDom(domStr); listDom.appendChild(itemDom); }); this.applyChildrenStyles(listDom, this.get('domStyles')); } }; Tooltip.prototype.clearItemDoms = function () { if (this.get('listDom')) { util_2.clearDom(this.get('listDom')); } }; Tooltip.prototype.clearCrosshairs = function () { var xCrosshairDom = this.get('xCrosshairDom'); var yCrosshairDom = this.get('yCrosshairDom'); xCrosshairDom && xCrosshairDom.remove(); yCrosshairDom && yCrosshairDom.remove(); this.set('xCrosshairDom', null); this.set('yCrosshairDom', null); }; return Tooltip; }(html_component_1.default)); exports.default = Tooltip; },{"../abstract/html-component":22,"../util/align":69,"../util/util":77,"./css-const":62,"./html-theme":63,"@antv/color-util":19,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var html_1 = require("./html"); Object.defineProperty(exports, "Html", { enumerable: true, get: function () { return html_1.default; } }); },{"./html":64}],66:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AREA_STYLE = exports.LINE_STYLE = exports.BACKGROUND_STYLE = void 0; exports.BACKGROUND_STYLE = { // fill: 'red', opacity: 0, }; exports.LINE_STYLE = { stroke: '#C5C5C5', strokeOpacity: 0.85, }; exports.AREA_STYLE = { fill: '#CACED4', opacity: 0.85, }; },{}],67:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.linePathToAreaPath = exports.dataToPath = exports.getSmoothLinePath = exports.getLinePath = void 0; var tslib_1 = require("tslib"); var path_util_1 = require("@antv/path-util"); var scale_1 = require("@antv/scale"); var util_1 = require("@antv/util"); /** * 点数组转 path * @param points */ function pointsToPath(points) { return util_1.map(points, function (p, idx) { var command = idx === 0 ? 'M' : 'L'; var x = p[0], y = p[1]; return [command, x, y]; }); } /** * 将点连接成路径 path * @param points */ function getLinePath(points) { return pointsToPath(points); } exports.getLinePath = getLinePath; /** * 将点连成平滑的曲线 * @param points */ function getSmoothLinePath(points) { if (points.length <= 2) { // 两点以内直接绘制成路径 return getLinePath(points); } var data = []; util_1.each(points, function (p) { // 当前点和上一个点一样的时候,忽略掉 if (!util_1.isEqual(p, data.slice(data.length - 2))) { data.push(p[0], p[1]); } }); // const constraint = [ // 范围 // [ 0, 0 ], // [ 1, 1 ], // ]; var path = path_util_1.catmullRom2Bezier(data, false); var _a = util_1.head(points), x = _a[0], y = _a[1]; path.unshift(['M', x, y]); return path; } exports.getSmoothLinePath = getSmoothLinePath; /** * 将数据转成 path,利用 scale 的归一化能力 * @param data * @param width * @param height * @param smooth */ function dataToPath(data, width, height, smooth) { if (smooth === void 0) { smooth = true; } // 利用 scale 来获取 y 上的映射 var y = new scale_1.Linear({ values: data, }); var x = new scale_1.Category({ values: util_1.map(data, function (v, idx) { return idx; }), }); var points = util_1.map(data, function (v, idx) { return [x.scale(idx) * width, height - y.scale(v) * height]; }); return smooth ? getSmoothLinePath(points) : getLinePath(points); } exports.dataToPath = dataToPath; /** * 线 path 转 area path * @param path * @param width * @param height */ function linePathToAreaPath(path, width, height) { var areaPath = tslib_1.__spreadArrays(path); areaPath.push(['L', width, 0]); areaPath.push(['L', 0, height]); areaPath.push(['Z']); return areaPath; } exports.linePathToAreaPath = linePathToAreaPath; },{"@antv/path-util":724,"@antv/scale":747,"@antv/util":803,"tslib":894}],68:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Trend = void 0; var tslib_1 = require("tslib"); var group_component_1 = require("../abstract/group-component"); var constant_1 = require("./constant"); var path_1 = require("./path"); var Trend = /** @class */ (function (_super) { tslib_1.__extends(Trend, _super); function Trend() { return _super !== null && _super.apply(this, arguments) || this; } Trend.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'trend', x: 0, y: 0, width: 200, height: 16, smooth: true, isArea: false, data: [], backgroundStyle: constant_1.BACKGROUND_STYLE, lineStyle: constant_1.LINE_STYLE, areaStyle: constant_1.AREA_STYLE }); }; Trend.prototype.renderInner = function (group) { var _a = this.cfg, width = _a.width, height = _a.height, data = _a.data, smooth = _a.smooth, isArea = _a.isArea, backgroundStyle = _a.backgroundStyle, lineStyle = _a.lineStyle, areaStyle = _a.areaStyle; // 背景 this.addShape(group, { id: this.getElementId('background'), type: 'rect', attrs: tslib_1.__assign({ x: 0, y: 0, width: width, height: height }, backgroundStyle), }); var path = path_1.dataToPath(data, width, height, smooth); // 线 this.addShape(group, { id: this.getElementId('line'), type: 'path', attrs: tslib_1.__assign({ path: path }, lineStyle), }); // area // 在 path 的基础上,增加两个坐标点 if (isArea) { var areaPath = path_1.linePathToAreaPath(path, width, height); this.addShape(group, { id: this.getElementId('area'), type: 'path', attrs: tslib_1.__assign({ path: areaPath }, areaStyle), }); } }; Trend.prototype.applyOffset = function () { var _a = this.cfg, x = _a.x, y = _a.y; // 统一移动到对应的位置 this.moveElementTo(this.get('group'), { x: x, y: y, }); }; return Trend; }(group_component_1.default)); exports.Trend = Trend; exports.default = Trend; },{"../abstract/group-component":21,"./constant":66,"./path":67,"tslib":894}],69:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAlignPoint = exports.getPointByPosition = exports.getOutSides = void 0; // 检测各边是否超出 function getOutSides(x, y, width, height, limitBox) { var hits = { left: x < limitBox.x, right: x + width > limitBox.x + limitBox.width, top: y < limitBox.y, bottom: y + height > limitBox.y + limitBox.height, }; return hits; } exports.getOutSides = getOutSides; function getPointByPosition(x, y, offset, width, height, position) { var px = x; var py = y; switch (position) { case 'left': // left center px = x - width - offset; py = y - height / 2; break; case 'right': px = x + offset; py = y - height / 2; break; case 'top': px = x - width / 2; py = y - height - offset; break; case 'bottom': // bottom px = x - width / 2; py = y + offset; break; default: // auto, 在 top-right px = x + offset; py = y - height - offset; break; } return { x: px, y: py, }; } exports.getPointByPosition = getPointByPosition; function getAlignPoint(x, y, offset, width, height, position, limitBox) { var point = getPointByPosition(x, y, offset, width, height, position); if (limitBox) { var outSides = getOutSides(point.x, point.y, width, height, limitBox); if (position === 'auto') { // 如果是 auto,默认 tooltip 在右上角,仅需要判定右侧和上测冲突即可 if (outSides.right) { point.x = Math.max(0, x - width - offset); } if (outSides.top) { point.y = Math.max(0, y - height - offset); } } else if (position === 'top' || position === 'bottom') { if (outSides.left) { // 左侧躲避 point.x = limitBox.x; } if (outSides.right) { // 右侧躲避 point.x = limitBox.x + limitBox.width - width; } if (position === 'top' && outSides.top) { // 如果上面对齐检测上面,不检测下面 point.y = y + offset; } if (position === 'bottom' && outSides.bottom) { point.y = y - height - offset; } } else { // 检测左右位置 if (outSides.top) { point.y = limitBox.y; } if (outSides.bottom) { point.y = limitBox.y + limitBox.height - height; } if (position === 'left' && outSides.left) { point.x = x + offset; } if (position === 'right' && outSides.right) { point.x = x - width - offset; } } } return point; } exports.getAlignPoint = getAlignPoint; },{}],70:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.propagationDelegate = void 0; var graph_event_1 = require("@antv/g-base/lib/event/graph-event"); /** * * @param group 分组 * @param eventName 事件名 * @param eventObject 事件对象 */ function propagationDelegate(group, eventName, eventObject) { var event = new graph_event_1.default(eventName, eventObject); event.target = group; event.propagationPath.push(group); // 从当前 group 开始触发 delegation group.emitDelegation(eventName, event); var parent = group.getParent(); // 执行冒泡 while (parent) { // 委托事件要先触发 parent.emitDelegation(eventName, event); event.propagationPath.push(parent); parent = parent.getParent(); } } exports.propagationDelegate = propagationDelegate; },{"@antv/g-base/lib/event/graph-event":114}],71:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.renderTag = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var label_1 = require("./label"); var matrix_1 = require("./matrix"); var util_2 = require("./util"); function renderTag(container, tagCfg) { var x = tagCfg.x, y = tagCfg.y, content = tagCfg.content, style = tagCfg.style, id = tagCfg.id, name = tagCfg.name, rotate = tagCfg.rotate, maxLength = tagCfg.maxLength, autoEllipsis = tagCfg.autoEllipsis, isVertical = tagCfg.isVertical, ellipsisPosition = tagCfg.ellipsisPosition, background = tagCfg.background; var tagGroup = container.addGroup({ id: id + "-group", name: name + "-group", attrs: { x: x, y: y, } }); // Text shape var text = tagGroup.addShape({ type: 'text', id: id, name: name, attrs: tslib_1.__assign({ x: 0, y: 0, text: content }, style), }); // maxLength 应包含 background 中的 padding 值 var padding = util_2.formatPadding(util_1.get(background, 'padding', 0)); if (maxLength && autoEllipsis) { var maxTextLength = maxLength - (padding[1] + padding[3]); // 超出自动省略 label_1.ellipsisLabel(!isVertical, text, maxTextLength, ellipsisPosition); } if (background) { // 渲染文本背景 var backgroundStyle = util_1.get(background, 'style', {}); var _a = text.getCanvasBBox(), minX = _a.minX, minY = _a.minY, width = _a.width, height = _a.height; var tagBg = tagGroup.addShape('rect', { id: id + "-bg", name: id + "-bg", attrs: tslib_1.__assign({ x: minX - padding[3], y: minY - padding[0], width: width + padding[1] + padding[3], height: height + padding[0] + padding[2] }, backgroundStyle), }); tagBg.toBack(); } matrix_1.applyTranslate(tagGroup, x, y); matrix_1.applyRotate(tagGroup, rotate, x, y); } exports.renderTag = renderTag; },{"./label":72,"./matrix":73,"./util":77,"@antv/util":803,"tslib":894}],72:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ellipsisLabel = exports.testLabel = exports.getLabelLength = exports.getMaxLabelWidth = void 0; var util_1 = require("@antv/util"); var text_1 = require("./text"); var ELLIPSIS_CODE = '\u2026'; var ELLIPSIS_CODE_LENGTH = 2; // 省略号的长度 /** 获取最长的 label */ function getMaxLabelWidth(labels) { var max = 0; util_1.each(labels, function (label) { var bbox = label.getBBox(); var width = bbox.width; if (max < width) { max = width; } }); return max; } exports.getMaxLabelWidth = getMaxLabelWidth; /** 获取label长度 */ function getLabelLength(isVertical, label) { var bbox = label.getCanvasBBox(); return isVertical ? bbox.width : bbox.height; } exports.getLabelLength = getLabelLength; /* label长度是否超过约束值 */ function testLabel(label, limitLength) { return label.getBBox().width < limitLength; } exports.testLabel = testLabel; /** 处理 text shape 的自动省略 */ function ellipsisLabel(isVertical, label, limitLength, position) { if (position === void 0) { position = 'tail'; } var text = label.attr('text'); var labelLength = getLabelLength(isVertical, label); var codeLength = text_1.strLen(text); var ellipsised = false; if (limitLength < labelLength) { var reseveLength = Math.floor((limitLength / labelLength) * codeLength) - ELLIPSIS_CODE_LENGTH; // 计算出来的应该保存的长度 var newText = void 0; if (reseveLength >= 0) { newText = text_1.ellipsisString(text, reseveLength, position); } else { newText = ELLIPSIS_CODE; } if (newText) { label.attr('text', newText); ellipsised = true; } } if (ellipsised) { label.set('tip', text); } else { label.set('tip', null); } return ellipsised; } exports.ellipsisLabel = ellipsisLabel; },{"./text":75,"@antv/util":803}],73:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyTranslate = exports.applyRotate = exports.applyMatrix2BBox = exports.getAngleByMatrix = exports.getMatrixByTranslate = exports.getMatrixByAngle = void 0; var matrix_util_1 = require("@antv/matrix-util"); var identityMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; function getMatrixByAngle(point, angle, matrix) { if (matrix === void 0) { matrix = identityMatrix; } if (!angle) { // 角度为 0 或者 null 时返回 null return null; } var m = matrix_util_1.ext.transform(matrix, [ ['t', -point.x, -point.y], ['r', angle], ['t', point.x, point.y], ]); return m; } exports.getMatrixByAngle = getMatrixByAngle; function getMatrixByTranslate(point, currentMatrix) { if (!point.x && !point.y) { // 0,0 或者 nan 的情况下返回 null return null; } return matrix_util_1.ext.transform(currentMatrix || identityMatrix, [['t', point.x, point.y]]); } exports.getMatrixByTranslate = getMatrixByTranslate; // 从矩阵获取旋转的角度 function getAngleByMatrix(matrix) { var xVector = [1, 0, 0]; var out = [0, 0, 0]; matrix_util_1.vec3.transformMat3(out, xVector, matrix); return Math.atan2(out[1], out[0]); } exports.getAngleByMatrix = getAngleByMatrix; // 矩阵 * 向量 function multiplyVec2(matrix, v) { var out = [0, 0]; matrix_util_1.vec2.transformMat3(out, v, matrix); return out; } function applyMatrix2BBox(matrix, bbox) { var topLeft = multiplyVec2(matrix, [bbox.minX, bbox.minY]); var topRight = multiplyVec2(matrix, [bbox.maxX, bbox.minY]); var bottomLeft = multiplyVec2(matrix, [bbox.minX, bbox.maxY]); var bottomRight = multiplyVec2(matrix, [bbox.maxX, bbox.maxY]); var minX = Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]); var maxX = Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]); var minY = Math.min(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]); var maxY = Math.max(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]); return { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; } exports.applyMatrix2BBox = applyMatrix2BBox; function applyRotate(shape, rotate, x, y) { if (rotate) { var matrix = getMatrixByAngle({ x: x, y: y }, rotate, shape.getMatrix()); shape.setMatrix(matrix); } } exports.applyRotate = applyRotate; function applyTranslate(shape, x, y) { var translateMatrix = getMatrixByTranslate({ x: x, y: y }); shape.attr('matrix', translateMatrix); } exports.applyTranslate = applyTranslate; },{"@antv/matrix-util":717}],74:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStatesStyle = void 0; var util_1 = require("@antv/util"); // 获取多个状态量的合并值 function getStatesStyle(item, elementName, stateStyles) { var styleName = elementName + "Style"; // activeStyle var styles = null; util_1.each(stateStyles, function (v, state) { if (item[state] && v[styleName]) { if (!styles) { styles = {}; } util_1.mix(styles, v[styleName]); // 合并样式 } }); return styles; } exports.getStatesStyle = getStatesStyle; },{"@antv/util":803}],75:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ellipsisString = exports.charAtLength = exports.strLen = void 0; var ELLIPSIS_CODE = '\u2026'; /** 获取字符串长度 */ function strLen(str) { var len = 0; for (var i = 0; i < str.length; i++) { len += charAtLength(str, i); } return len; } exports.strLen = strLen; /** 是否属于ASCII编码范畴 */ function charAtLength(str, i) { if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) { return 1; } else { return 2; } } exports.charAtLength = charAtLength; /** 文本省略 */ function ellipsisString(str, reseveLength, position) { if (position === void 0) { position = 'tail'; } var count = str.length; var rst = ''; if (position === 'tail') { for (var i = 0, index = 0; i < reseveLength;) { var charLength = charAtLength(str, index); if (i + charLength <= reseveLength) { rst += str[index]; i += charAtLength(str, index); index++; } else { break; } } rst += ELLIPSIS_CODE; } else if (position === 'head') { for (var i = 0, index = count - 1; i < reseveLength;) { var charLength = charAtLength(str, index); if (i + charLength <= reseveLength) { rst += str[index]; i += charAtLength(str, index); index--; } else { break; } } rst = ELLIPSIS_CODE + rst; } else { var startStr = ''; var endStr = ''; for (var i = 0, startIndex = 0, endIndex = count - 1; i < reseveLength;) { var startCodeLen = charAtLength(str, startIndex); var hasAdd = false; // 设置标志位,防止头尾都没有附加字符 if (startCodeLen + i <= reseveLength) { startStr += str[startIndex]; startIndex++; i += startCodeLen; hasAdd = true; } var endCodeLen = charAtLength(str, endIndex); if (endCodeLen + i <= reseveLength) { endStr = str[endIndex] + endStr; i += endCodeLen; endIndex--; hasAdd = true; } if (!hasAdd) { // 如果都没有增加字符,说明都不适合则中断 break; } } rst = startStr + ELLIPSIS_CODE + endStr; } return rst; } exports.ellipsisString = ellipsisString; },{}],76:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = { fontFamily: "\n \"-apple-system\", BlinkMacSystemFont, \"Segoe UI\", Roboto,\"Helvetica Neue\",\n Helvetica, \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\",\n SimSun, \"sans-serif\"", textColor: '#2C3542', activeTextColor: '#333333', uncheckedColor: '#D8D8D8', lineColor: '#416180', regionColor: '#CCD7EB', verticalAxisRotate: -Math.PI / 4, horizontalAxisRotate: Math.PI / 4, }; },{}],77:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTextPoint = exports.toPx = exports.updateClip = exports.getBBoxWithClip = exports.mergeBBox = exports.intersectBBox = exports.near = exports.wait = exports.distance = exports.getCirclePoint = exports.getValueByPercent = exports.createBBox = exports.pointsToBBox = exports.regionToBBox = exports.hasClass = exports.clearDom = exports.formatPadding = void 0; var util_1 = require("@antv/util"); function formatPadding(padding) { var top = 0; var left = 0; var right = 0; var bottom = 0; if (util_1.isNumber(padding)) { top = left = right = bottom = padding; } else if (util_1.isArray(padding)) { top = padding[0]; right = !util_1.isNil(padding[1]) ? padding[1] : padding[0]; bottom = !util_1.isNil(padding[2]) ? padding[2] : padding[0]; left = !util_1.isNil(padding[3]) ? padding[3] : right; } return [top, right, bottom, left]; } exports.formatPadding = formatPadding; function clearDom(container) { var children = container.childNodes; var length = children.length; for (var i = length - 1; i >= 0; i--) { container.removeChild(children[i]); } } exports.clearDom = clearDom; function hasClass(elements, cName) { return !!elements.className.match(new RegExp("(\\s|^)" + cName + "(\\s|$)")); } exports.hasClass = hasClass; function regionToBBox(region) { var start = region.start, end = region.end; var minX = Math.min(start.x, end.x); var minY = Math.min(start.y, end.y); var maxX = Math.max(start.x, end.x); var maxY = Math.max(start.y, end.y); return { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; } exports.regionToBBox = regionToBBox; function pointsToBBox(points) { var xs = points.map(function (point) { return point.x; }); var ys = points.map(function (point) { return point.y; }); var minX = Math.min.apply(Math, xs); var minY = Math.min.apply(Math, ys); var maxX = Math.max.apply(Math, xs); var maxY = Math.max.apply(Math, ys); return { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; } exports.pointsToBBox = pointsToBBox; function createBBox(x, y, width, height) { return { x: x, y: y, width: width, height: height, minX: x, minY: y, maxX: x + width, maxY: y + height, }; } exports.createBBox = createBBox; function getValueByPercent(min, max, percent) { return (1 - percent) * min + max * percent; } exports.getValueByPercent = getValueByPercent; function getCirclePoint(center, radius, angle) { return { x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius, }; } exports.getCirclePoint = getCirclePoint; function distance(p1, p2) { var dx = p2.x - p1.x; var dy = p2.y - p1.y; return Math.sqrt(dx * dx + dy * dy); } exports.distance = distance; exports.wait = function (interval) { return new Promise(function (resolve) { setTimeout(resolve, interval); }); }; exports.near = function (x, y) { return [x, y].includes(Infinity) ? Math.abs(x) === Math.abs(y) : Math.abs(x - y) < Math.pow(Number.EPSILON, 0.5); }; function intersectBBox(box1, box2) { var minX = Math.max(box1.minX, box2.minX); var minY = Math.max(box1.minY, box2.minY); var maxX = Math.min(box1.maxX, box2.maxX); var maxY = Math.min(box1.maxY, box2.maxY); return createBBox(minX, minY, maxX - minX, maxY - minY); } exports.intersectBBox = intersectBBox; function mergeBBox(box1, box2) { var minX = Math.min(box1.minX, box2.minX); var minY = Math.min(box1.minY, box2.minY); var maxX = Math.max(box1.maxX, box2.maxX); var maxY = Math.max(box1.maxY, box2.maxY); return createBBox(minX, minY, maxX - minX, maxY - minY); } exports.mergeBBox = mergeBBox; function getBBoxWithClip(element) { var clipShape = element.getClip(); var clipBBox = clipShape && clipShape.getBBox(); var bbox; if (!element.isGroup()) { // 如果是普通的图形 bbox = element.getBBox(); } else { var minX_1 = Infinity; var maxX_1 = -Infinity; var minY_1 = Infinity; var maxY_1 = -Infinity; var children = element.getChildren(); if (children.length > 0) { util_1.each(children, function (child) { if (child.get('visible')) { // 如果分组没有子元素,则直接跳过 if (child.isGroup() && child.get('children').length === 0) { return true; } var box = getBBoxWithClip(child); // 计算 4 个顶点 var leftTop = child.applyToMatrix([box.minX, box.minY, 1]); var leftBottom = child.applyToMatrix([box.minX, box.maxY, 1]); var rightTop = child.applyToMatrix([box.maxX, box.minY, 1]); var rightBottom = child.applyToMatrix([box.maxX, box.maxY, 1]); // 从中取最小的范围 var boxMinX = Math.min(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0]); var boxMaxX = Math.max(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0]); var boxMinY = Math.min(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1]); var boxMaxY = Math.max(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1]); if (boxMinX < minX_1) { minX_1 = boxMinX; } if (boxMaxX > maxX_1) { maxX_1 = boxMaxX; } if (boxMinY < minY_1) { minY_1 = boxMinY; } if (boxMaxY > maxY_1) { maxY_1 = boxMaxY; } } }); } else { minX_1 = 0; maxX_1 = 0; minY_1 = 0; maxY_1 = 0; } bbox = createBBox(minX_1, minY_1, maxX_1 - minX_1, maxY_1 - minY_1); } if (clipBBox) { return intersectBBox(bbox, clipBBox); } else { return bbox; } } exports.getBBoxWithClip = getBBoxWithClip; function updateClip(element, newElement) { if (!element.getClip() && !newElement.getClip()) { // 两者都没有 clip return; } var newClipShape = newElement.getClip(); if (!newClipShape) { // 新的 element 没有 clip element.setClip(null); // 移除 clip return; } var clipCfg = { type: newClipShape.get('type'), attrs: newClipShape.attr(), }; element.setClip(clipCfg); } exports.updateClip = updateClip; function toPx(number) { return number + "px"; } exports.toPx = toPx; function getTextPoint(start, end, position, offset) { var lineLength = distance(start, end); var offsetPercent = offset / lineLength; // 计算间距同线的比例,用于计算最终的位置 var percent = 0; if (position === 'start') { percent = 0 - offsetPercent; } else if (position === 'end') { percent = 1 + offsetPercent; } return { x: getValueByPercent(start.x, end.x, percent), y: getValueByPercent(start.y, end.y, percent), }; } exports.getTextPoint = getTextPoint; },{"@antv/util":803}],78:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); /** * Coordinate Base Class */ var Coordinate = /** @class */ (function () { function Coordinate(cfg) { // 自身属性 this.type = 'coordinate'; this.isRect = false; this.isHelix = false; this.isPolar = false; this.isReflectX = false; this.isReflectY = false; var start = cfg.start, end = cfg.end, _a = cfg.matrix, matrix = _a === void 0 ? [1, 0, 0, 0, 1, 0, 0, 0, 1] : _a, _b = cfg.isTransposed, isTransposed = _b === void 0 ? false : _b; this.start = start; this.end = end; this.matrix = matrix; this.originalMatrix = tslib_1.__spreadArrays(matrix); // 去除引用 this.isTransposed = isTransposed; } /** * 初始化流程 */ Coordinate.prototype.initial = function () { // center、width、height this.center = { x: (this.start.x + this.end.x) / 2, y: (this.start.y + this.end.y) / 2, }; this.width = Math.abs(this.end.x - this.start.x); this.height = Math.abs(this.end.y - this.start.y); }; /** * 更新配置 * @param cfg */ Coordinate.prototype.update = function (cfg) { util_1.assign(this, cfg); this.initial(); }; Coordinate.prototype.convertDim = function (percent, dim) { var _a; var _b = this[dim], start = _b.start, end = _b.end; // 交换 if (this.isReflect(dim)) { _a = [end, start], start = _a[0], end = _a[1]; } return start + percent * (end - start); }; Coordinate.prototype.invertDim = function (value, dim) { var _a; var _b = this[dim], start = _b.start, end = _b.end; // 交换 if (this.isReflect(dim)) { _a = [end, start], start = _a[0], end = _a[1]; } return (value - start) / (end - start); }; /** * 将坐标点进行矩阵变换 * @param x 对应 x 轴画布坐标 * @param y 对应 y 轴画布坐标 * @param tag 默认为 0,可取值 0, 1 * @return 返回变换后的三阶向量 [x, y, z] */ Coordinate.prototype.applyMatrix = function (x, y, tag) { if (tag === void 0) { tag = 0; } var matrix = this.matrix; var vector = [x, y, tag]; matrix_util_1.vec3.transformMat3(vector, vector, matrix); return vector; }; /** * 将坐标点进行矩阵逆变换 * @param x 对应 x 轴画布坐标 * @param y 对应 y 轴画布坐标 * @param tag 默认为 0,可取值 0, 1 * @return 返回矩阵逆变换后的三阶向量 [x, y, z] */ Coordinate.prototype.invertMatrix = function (x, y, tag) { if (tag === void 0) { tag = 0; } var matrix = this.matrix; var inverted = matrix_util_1.mat3.invert([0, 0, 0, 0, 0, 0, 0, 0, 0], matrix); var vector = [x, y, tag]; if (inverted) { // 如果为空则不进行矩阵变化,防止报错 matrix_util_1.vec3.transformMat3(vector, vector, inverted); } return vector; }; /** * 将归一化的坐标点数据转换为画布坐标,并根据坐标系当前矩阵进行变换 * @param point 归一化的坐标点 * @return 返回进行矩阵变换后的画布坐标 */ Coordinate.prototype.convert = function (point) { var _a = this.convertPoint(point), x = _a.x, y = _a.y; var vector = this.applyMatrix(x, y, 1); return { x: vector[0], y: vector[1], }; }; /** * 将进行过矩阵变换画布坐标转换为归一化坐标 * @param point 画布坐标 * @return 返回归一化的坐标点 */ Coordinate.prototype.invert = function (point) { var vector = this.invertMatrix(point.x, point.y, 1); return this.invertPoint({ x: vector[0], y: vector[1], }); }; /** * 坐标系旋转变换 * @param radian 旋转弧度 * @return 返回坐标系对象 */ Coordinate.prototype.rotate = function (radian) { var matrix = this.matrix; var center = this.center; matrix_util_1.ext.leftTranslate(matrix, matrix, [-center.x, -center.y]); matrix_util_1.ext.leftRotate(matrix, matrix, radian); matrix_util_1.ext.leftTranslate(matrix, matrix, [center.x, center.y]); return this; }; /** * 坐标系反射变换 * @param dim 反射维度 * @return 返回坐标系对象 */ Coordinate.prototype.reflect = function (dim) { if (dim === 'x') { this.isReflectX = !this.isReflectX; } else { this.isReflectY = !this.isReflectY; } return this; }; /** * 坐标系比例变换 * @param s1 x 方向缩放比例 * @param s2 y 方向缩放比例 * @return 返回坐标系对象 */ Coordinate.prototype.scale = function (s1, s2) { var matrix = this.matrix; var center = this.center; matrix_util_1.ext.leftTranslate(matrix, matrix, [-center.x, -center.y]); matrix_util_1.ext.leftScale(matrix, matrix, [s1, s2]); matrix_util_1.ext.leftTranslate(matrix, matrix, [center.x, center.y]); return this; }; /** * 坐标系平移变换 * @param x x 方向平移像素 * @param y y 方向平移像素 * @return 返回坐标系对象 */ Coordinate.prototype.translate = function (x, y) { var matrix = this.matrix; matrix_util_1.ext.leftTranslate(matrix, matrix, [x, y]); return this; }; /** * 将坐标系 x y 两个轴进行转置 * @return 返回坐标系对象 */ Coordinate.prototype.transpose = function () { this.isTransposed = !this.isTransposed; return this; }; Coordinate.prototype.getCenter = function () { return this.center; }; Coordinate.prototype.getWidth = function () { return this.width; }; Coordinate.prototype.getHeight = function () { return this.height; }; Coordinate.prototype.getRadius = function () { return this.radius; }; /** * whether has reflect * @param dim */ Coordinate.prototype.isReflect = function (dim) { return dim === 'x' ? this.isReflectX : this.isReflectY; }; /** * 重置 matrix * @param matrix 如果传入,则使用,否则使用构造函数中传入的默认 matrix */ Coordinate.prototype.resetMatrix = function (matrix) { // 去除引用关系 this.matrix = matrix ? matrix : tslib_1.__spreadArrays(this.originalMatrix); }; return Coordinate; }()); exports.default = Coordinate; },{"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],79:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); /** * 笛卡尔坐标系 * https://www.zhihu.com/question/20665303 */ var Cartesian = /** @class */ (function (_super) { tslib_1.__extends(Cartesian, _super); function Cartesian(cfg) { var _this = _super.call(this, cfg) || this; _this.isRect = true; _this.type = 'cartesian'; _this.initial(); return _this; } Cartesian.prototype.initial = function () { _super.prototype.initial.call(this); var start = this.start; var end = this.end; this.x = { start: start.x, end: end.x, }; this.y = { start: start.y, end: end.y, }; }; Cartesian.prototype.convertPoint = function (point) { var _a; var x = point.x, y = point.y; // 交换 if (this.isTransposed) { _a = [y, x], x = _a[0], y = _a[1]; } return { x: this.convertDim(x, 'x'), y: this.convertDim(y, 'y'), }; }; Cartesian.prototype.invertPoint = function (point) { var _a; var x = this.invertDim(point.x, 'x'); var y = this.invertDim(point.y, 'y'); if (this.isTransposed) { _a = [y, x], x = _a[0], y = _a[1]; } return { x: x, y: y }; }; return Cartesian; }(base_1.default)); exports.default = Cartesian; },{"./base":78,"tslib":894}],80:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var base_1 = require("./base"); /** * 螺旋坐标系 */ var Helix = /** @class */ (function (_super) { tslib_1.__extends(Helix, _super); function Helix(cfg) { var _this = _super.call(this, cfg) || this; _this.isHelix = true; _this.type = 'helix'; var _a = cfg.startAngle, startAngle = _a === void 0 ? 1.25 * Math.PI : _a, _b = cfg.endAngle, endAngle = _b === void 0 ? 7.25 * Math.PI : _b, _c = cfg.innerRadius, innerRadius = _c === void 0 ? 0 : _c, radius = cfg.radius; _this.startAngle = startAngle; _this.endAngle = endAngle; _this.innerRadius = innerRadius; _this.radius = radius; _this.initial(); return _this; } Helix.prototype.initial = function () { _super.prototype.initial.call(this); var index = (this.endAngle - this.startAngle) / (2 * Math.PI) + 1; // 螺线圈数 var maxRadius = Math.min(this.width, this.height) / 2; if (this.radius && this.radius >= 0 && this.radius <= 1) { maxRadius = maxRadius * this.radius; } this.d = Math.floor((maxRadius * (1 - this.innerRadius)) / index); this.a = this.d / (Math.PI * 2); // 螺线系数 this.x = { start: this.startAngle, end: this.endAngle, }; this.y = { start: this.innerRadius * maxRadius, end: this.innerRadius * maxRadius + this.d * 0.99, }; }; /** * 将百分比数据变成屏幕坐标 * @param point 归一化的点坐标 * @return 返回对应的屏幕坐标 */ Helix.prototype.convertPoint = function (point) { var _a; var x = point.x, y = point.y; if (this.isTransposed) { _a = [y, x], x = _a[0], y = _a[1]; } var thi = this.convertDim(x, 'x'); var r = this.a * thi; var newY = this.convertDim(y, 'y'); return { x: this.center.x + Math.cos(thi) * (r + newY), y: this.center.y + Math.sin(thi) * (r + newY), }; }; /** * 将屏幕坐标点还原成百分比数据 * @param point 屏幕坐标 * @return 返回对应的归一化后的数据 */ Helix.prototype.invertPoint = function (point) { var _a; var d = this.d + this.y.start; var v = matrix_util_1.vec2.subtract([0, 0], [point.x, point.y], [this.center.x, this.center.y]); var thi = matrix_util_1.ext.angleTo(v, [1, 0], true); var rMin = thi * this.a; // 坐标与原点的连线在第一圈上的交点,最小r值 if (matrix_util_1.vec2.length(v) < rMin) { // 坐标与原点的连线不可能小于最小r值,但不排除因小数计算产生的略小于rMin的情况 rMin = matrix_util_1.vec2.length(v); } var index = Math.floor((matrix_util_1.vec2.length(v) - rMin) / d); // 当前点位于第index圈 thi = 2 * index * Math.PI + thi; var r = this.a * thi; var newY = matrix_util_1.vec2.length(v) - r; newY = util_1.isNumberEqual(newY, 0) ? 0 : newY; var x = this.invertDim(thi, 'x'); var y = this.invertDim(newY, 'y'); x = util_1.isNumberEqual(x, 0) ? 0 : x; y = util_1.isNumberEqual(y, 0) ? 0 : y; if (this.isTransposed) { _a = [y, x], x = _a[0], y = _a[1]; } return { x: x, y: y }; }; return Helix; }(base_1.default)); exports.default = Helix; },{"./base":78,"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],81:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var Polar = /** @class */ (function (_super) { tslib_1.__extends(Polar, _super); function Polar(cfg) { var _this = _super.call(this, cfg) || this; _this.isPolar = true; _this.type = 'polar'; var _a = cfg.startAngle, startAngle = _a === void 0 ? -Math.PI / 2 : _a, _b = cfg.endAngle, endAngle = _b === void 0 ? (Math.PI * 3) / 2 : _b, _c = cfg.innerRadius, innerRadius = _c === void 0 ? 0 : _c, radius = cfg.radius; _this.startAngle = startAngle; _this.endAngle = endAngle; _this.innerRadius = innerRadius; _this.radius = radius; _this.initial(); return _this; } Polar.prototype.initial = function () { _super.prototype.initial.call(this); while (this.endAngle < this.startAngle) { this.endAngle += Math.PI * 2; } var oneBox = this.getOneBox(); var oneWidth = oneBox.maxX - oneBox.minX; var oneHeight = oneBox.maxY - oneBox.minY; var left = Math.abs(oneBox.minX) / oneWidth; var top = Math.abs(oneBox.minY) / oneHeight; var maxRadius; if (this.height / oneHeight > this.width / oneWidth) { // width 为主 maxRadius = this.width / oneWidth; this.circleCenter = { x: this.center.x - (0.5 - left) * this.width, y: this.center.y - (0.5 - top) * maxRadius * oneHeight, }; } else { // height 为主 maxRadius = this.height / oneHeight; this.circleCenter = { x: this.center.x - (0.5 - left) * maxRadius * oneWidth, y: this.center.y - (0.5 - top) * this.height, }; } this.polarRadius = this.radius; if (!this.radius) { this.polarRadius = maxRadius; } else if (this.radius > 0 && this.radius <= 1) { this.polarRadius = maxRadius * this.radius; } else if (this.radius <= 0 || this.radius > maxRadius) { this.polarRadius = maxRadius; } this.x = { start: this.startAngle, end: this.endAngle, }; this.y = { start: this.innerRadius * this.polarRadius, end: this.polarRadius, }; }; Polar.prototype.getRadius = function () { return this.polarRadius; }; Polar.prototype.convertPoint = function (point) { var _a; var center = this.getCenter(); var x = point.x, y = point.y; if (this.isTransposed) { _a = [y, x], x = _a[0], y = _a[1]; } x = this.convertDim(x, 'x'); y = this.convertDim(y, 'y'); return { x: center.x + Math.cos(x) * y, y: center.y + Math.sin(x) * y, }; }; Polar.prototype.invertPoint = function (point) { var center = this.getCenter(); var vPoint = [point.x - center.x, point.y - center.y]; var m = [1, 0, 0, 0, 1, 0, 0, 0, 1]; matrix_util_1.ext.leftRotate(m, m, this.startAngle); var vStart3 = [1, 0, 0]; matrix_util_1.vec3.transformMat3(vStart3, vStart3, m); var vStart2 = [vStart3[0], vStart3[1]]; var angle = matrix_util_1.ext.angleTo(vStart2, vPoint, this.endAngle < this.startAngle); if (util_1.isNumberEqual(angle, Math.PI * 2)) { angle = 0; } var radius = matrix_util_1.vec2.length(vPoint); var xPercent = angle / (this.endAngle - this.startAngle); xPercent = this.endAngle - this.startAngle > 0 ? xPercent : -xPercent; var yPercent = this.invertDim(radius, 'y'); var rst = { x: 0, y: 0 }; rst.x = this.isTransposed ? yPercent : xPercent; rst.y = this.isTransposed ? xPercent : yPercent; return rst; }; Polar.prototype.getCenter = function () { return this.circleCenter; }; Polar.prototype.getOneBox = function () { var startAngle = this.startAngle; var endAngle = this.endAngle; if (Math.abs(endAngle - startAngle) >= Math.PI * 2) { return { minX: -1, maxX: 1, minY: -1, maxY: 1, }; } var xs = [0, Math.cos(startAngle), Math.cos(endAngle)]; var ys = [0, Math.sin(startAngle), Math.sin(endAngle)]; for (var i = Math.min(startAngle, endAngle); i < Math.max(startAngle, endAngle); i += Math.PI / 18) { xs.push(Math.cos(i)); ys.push(Math.sin(i)); } return { minX: Math.min.apply(Math, xs), maxX: Math.max.apply(Math, xs), minY: Math.min.apply(Math, ys), maxY: Math.max.apply(Math, ys), }; }; return Polar; }(base_1.default)); exports.default = Polar; },{"./base":78,"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],82:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // 所有的 Coordinate map var COORDINATE_MAP = {}; /** * 通过类型获得 coordinate 类 * @param type */ exports.getCoordinate = function (type) { return COORDINATE_MAP[type.toLowerCase()]; }; /** * 注册 coordinate 类 * @param type * @param ctor */ exports.registerCoordinate = function (type, ctor) { // 存储到 map 中 COORDINATE_MAP[type.toLowerCase()] = ctor; }; },{}],83:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("./coord/base"); exports.Coordinate = base_1.default; var cartesian_1 = require("./coord/cartesian"); var helix_1 = require("./coord/helix"); var polar_1 = require("./coord/polar"); var factory_1 = require("./factory"); exports.getCoordinate = factory_1.getCoordinate; exports.registerCoordinate = factory_1.registerCoordinate; factory_1.registerCoordinate('rect', cartesian_1.default); factory_1.registerCoordinate('cartesian', cartesian_1.default); factory_1.registerCoordinate('polar', polar_1.default); factory_1.registerCoordinate('helix', helix_1.default); },{"./coord/base":78,"./coord/cartesian":79,"./coord/helix":80,"./coord/polar":81,"./factory":82}],84:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function addEventListener(target, eventType, callback) { if (target) { if (typeof target.addEventListener === 'function') { target.addEventListener(eventType, callback, false); return { remove: function () { target.removeEventListener(eventType, callback, false); }, }; // @ts-ignore } if (typeof target.attachEvent === 'function') { // @ts-ignore target.attachEvent('on' + eventType, callback); return { remove: function () { // @ts-ignore target.detachEvent('on' + eventType, callback); }, }; } } } exports.default = addEventListener; },{}],85:[function(require,module,exports){ "use strict"; /** * 创建DOM 节点 * @param {String} str Dom 字符串 * @return {HTMLElement} DOM 节点 */ Object.defineProperty(exports, "__esModule", { value: true }); var TABLE; var TABLE_TR; var FRAGMENT_REG; var CONTAINERS; function initConstants() { TABLE = document.createElement('table'); TABLE_TR = document.createElement('tr'); FRAGMENT_REG = /^\s*<(\w+|!)[^>]*>/; CONTAINERS = { tr: document.createElement('tbody'), tbody: TABLE, thead: TABLE, tfoot: TABLE, td: TABLE_TR, th: TABLE_TR, '*': document.createElement('div'), }; } function createDom(str) { if (!TABLE) { initConstants(); } var name = FRAGMENT_REG.test(str) && RegExp.$1; if (!name || !(name in CONTAINERS)) { name = '*'; } var container = CONTAINERS[name]; str = str.replace(/(^\s*)|(\s*$)/g, ''); container.innerHTML = '' + str; var dom = container.childNodes[0]; container.removeChild(dom); return dom; } exports.default = createDom; },{}],86:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var get_style_1 = require("./get-style"); function getHeight(el, defaultValue) { var height = get_style_1.default(el, 'height', defaultValue); if (height === 'auto') { height = el.offsetHeight; } return parseFloat(height); } exports.default = getHeight; },{"./get-style":90}],87:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var get_style_1 = require("./get-style"); var get_height_1 = require("./get-height"); function getOuterHeight(el, defaultValue) { var height = get_height_1.default(el, defaultValue); var bTop = parseFloat(get_style_1.default(el, 'borderTopWidth')) || 0; var pTop = parseFloat(get_style_1.default(el, 'paddingTop')) || 0; var pBottom = parseFloat(get_style_1.default(el, 'paddingBottom')) || 0; var bBottom = parseFloat(get_style_1.default(el, 'borderBottomWidth')) || 0; var mTop = parseFloat(get_style_1.default(el, 'marginTop')) || 0; var mBottom = parseFloat(get_style_1.default(el, 'marginBottom')) || 0; return height + bTop + bBottom + pTop + pBottom + mTop + mBottom; } exports.default = getOuterHeight; },{"./get-height":86,"./get-style":90}],88:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var get_style_1 = require("./get-style"); var get_width_1 = require("./get-width"); function getOuterWidth(el, defaultValue) { var width = get_width_1.default(el, defaultValue); var bLeft = parseFloat(get_style_1.default(el, 'borderLeftWidth')) || 0; var pLeft = parseFloat(get_style_1.default(el, 'paddingLeft')) || 0; var pRight = parseFloat(get_style_1.default(el, 'paddingRight')) || 0; var bRight = parseFloat(get_style_1.default(el, 'borderRightWidth')) || 0; var mRight = parseFloat(get_style_1.default(el, 'marginRight')) || 0; var mLeft = parseFloat(get_style_1.default(el, 'marginLeft')) || 0; return width + bLeft + bRight + pLeft + pRight + mLeft + mRight; } exports.default = getOuterWidth; },{"./get-style":90,"./get-width":91}],89:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function getRatio() { return window.devicePixelRatio ? window.devicePixelRatio : 2; } exports.default = getRatio; },{}],90:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 获取样式 * @param {Object} dom DOM节点 * @param {String} name 样式名 * @param {Any} defaultValue 默认值 * @return {String} 属性值 */ function getStyle(dom, name, defaultValue) { var v; try { v = window.getComputedStyle ? window.getComputedStyle(dom, null)[name] : dom.style[name]; // 一般不会走到这个逻辑,dom.style 获取的是标签 style 属性,也不准确 } catch (e) { // do nothing } finally { v = v === undefined ? defaultValue : v; } return v; } exports.default = getStyle; },{}],91:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var get_style_1 = require("./get-style"); function getHeight(el, defaultValue) { var width = get_style_1.default(el, 'width', defaultValue); if (width === 'auto') { width = el.offsetWidth; } return parseFloat(width); } exports.default = getHeight; },{"./get-style":90}],92:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // dom var add_event_listener_1 = require("./add-event-listener"); exports.addEventListener = add_event_listener_1.default; var create_dom_1 = require("./create-dom"); exports.createDom = create_dom_1.default; var get_height_1 = require("./get-height"); exports.getHeight = get_height_1.default; var get_outer_height_1 = require("./get-outer-height"); exports.getOuterHeight = get_outer_height_1.default; var get_outer_width_1 = require("./get-outer-width"); exports.getOuterWidth = get_outer_width_1.default; var get_ratio_1 = require("./get-ratio"); exports.getRatio = get_ratio_1.default; var get_style_1 = require("./get-style"); exports.getStyle = get_style_1.default; var get_width_1 = require("./get-width"); exports.getWidth = get_width_1.default; var modify_css_1 = require("./modify-css"); exports.modifyCSS = modify_css_1.default; },{"./add-event-listener":84,"./create-dom":85,"./get-height":86,"./get-outer-height":87,"./get-outer-width":88,"./get-ratio":89,"./get-style":90,"./get-width":91,"./modify-css":93}],93:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function modifyCSS(dom, css) { if (dom) { for (var key in css) { if (css.hasOwnProperty(key)) { dom.style[key] = css[key]; } } } return dom; } exports.default = modifyCSS; },{}],94:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var WILDCARD = '*'; /* event-emitter */ var EventEmitter = /** @class */ (function () { function EventEmitter() { this._events = {}; } /** * 监听一个事件 * @param evt * @param callback * @param once */ EventEmitter.prototype.on = function (evt, callback, once) { if (!this._events[evt]) { this._events[evt] = []; } this._events[evt].push({ callback: callback, once: !!once, }); return this; }; /** * 监听一个事件一次 * @param evt * @param callback */ EventEmitter.prototype.once = function (evt, callback) { this.on(evt, callback, true); return this; }; /** * 触发一个事件 * @param evt * @param args */ EventEmitter.prototype.emit = function (evt) { var _this = this; var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var events = this._events[evt] || []; var wildcardEvents = this._events[WILDCARD] || []; // 实际的处理 emit 方法 var doEmit = function (es) { var length = es.length; for (var i = 0; i < length; i++) { if (!es[i]) { continue; } var _a = es[i], callback = _a.callback, once = _a.once; if (once) { es.splice(i, 1); if (es.length === 0) { delete _this._events[evt]; } length--; i--; } callback.apply(_this, args); } }; doEmit(events); doEmit(wildcardEvents); }; /** * 取消监听一个事件,或者一个channel * @param evt * @param callback */ EventEmitter.prototype.off = function (evt, callback) { if (!evt) { // evt 为空全部清除 this._events = {}; } else { if (!callback) { // evt 存在,callback 为空,清除事件所有方法 delete this._events[evt]; } else { // evt 存在,callback 存在,清除匹配的 var events = this._events[evt] || []; var length_1 = events.length; for (var i = 0; i < length_1; i++) { if (events[i].callback === callback) { events.splice(i, 1); length_1--; i--; } } if (events.length === 0) { delete this._events[evt]; } } } return this; }; /* 当前所有的事件 */ EventEmitter.prototype.getEvents = function () { return this._events; }; return EventEmitter; }()); exports.default = EventEmitter; },{}],95:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = require("@antv/event-emitter"); var util_1 = require("../util/util"); var Base = /** @class */ (function (_super) { tslib_1.__extends(Base, _super); function Base(cfg) { var _this = _super.call(this) || this; /** * 是否被销毁 * @type {boolean} */ _this.destroyed = false; var defaultCfg = _this.getDefaultCfg(); _this.cfg = util_1.mix(defaultCfg, cfg); return _this; } /** * @protected * 默认的配置项 * @returns {object} 默认的配置项 */ Base.prototype.getDefaultCfg = function () { return {}; }; // 实现接口的方法 Base.prototype.get = function (name) { return this.cfg[name]; }; // 实现接口的方法 Base.prototype.set = function (name, value) { this.cfg[name] = value; }; // 实现接口的方法 Base.prototype.destroy = function () { this.cfg = { destroyed: true, }; this.off(); this.destroyed = true; }; return Base; }(event_emitter_1.default)); exports.default = Base; },{"../util/util":123,"@antv/event-emitter":94,"tslib":894}],96:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var detect_browser_1 = require("detect-browser"); var container_1 = require("./container"); var util_1 = require("../util/util"); var timeline_1 = require("../animate/timeline"); var event_contoller_1 = require("../event/event-contoller"); var PX_SUFFIX = 'px'; var browser = detect_browser_1.detect(); var isFirefox = browser && browser.name === 'firefox'; var Canvas = /** @class */ (function (_super) { tslib_1.__extends(Canvas, _super); function Canvas(cfg) { var _this = _super.call(this, cfg) || this; _this.initContainer(); _this.initDom(); _this.initEvents(); _this.initTimeline(); return _this; } Canvas.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); // set default cursor style for canvas cfg['cursor'] = 'default'; // CSS transform 目前尚未经过长时间验证,为了避免影响上层业务,默认关闭,上层按需开启 cfg['supportCSSTransform'] = false; return cfg; }; /** * @protected * 初始化容器 */ Canvas.prototype.initContainer = function () { var container = this.get('container'); if (util_1.isString(container)) { container = document.getElementById(container); this.set('container', container); } }; /** * @protected * 初始化 DOM */ Canvas.prototype.initDom = function () { var el = this.createDom(); this.set('el', el); // 附加到容器 var container = this.get('container'); container.appendChild(el); // 设置初始宽度 this.setDOMSize(this.get('width'), this.get('height')); }; /** * @protected * 初始化绑定的事件 */ Canvas.prototype.initEvents = function () { var eventController = new event_contoller_1.default({ canvas: this, }); eventController.init(); this.set('eventController', eventController); }; /** * @protected * 初始化时间轴 */ Canvas.prototype.initTimeline = function () { var timeline = new timeline_1.default(this); this.set('timeline', timeline); }; /** * @protected * 修改画布对应的 DOM 的大小 * @param {number} width 宽度 * @param {number} height 高度 */ Canvas.prototype.setDOMSize = function (width, height) { var el = this.get('el'); if (util_1.isBrowser) { el.style.width = width + PX_SUFFIX; el.style.height = height + PX_SUFFIX; } }; // 实现接口 Canvas.prototype.changeSize = function (width, height) { this.setDOMSize(width, height); this.set('width', width); this.set('height', height); this.onCanvasChange('changeSize'); }; /** * 获取当前的渲染引擎 * @return {Renderer} 返回当前的渲染引擎 */ Canvas.prototype.getRenderer = function () { return this.get('renderer'); }; /** * 获取画布的 cursor 样式 * @return {Cursor} */ Canvas.prototype.getCursor = function () { return this.get('cursor'); }; /** * 设置画布的 cursor 样式 * @param {Cursor} cursor cursor 样式 */ Canvas.prototype.setCursor = function (cursor) { this.set('cursor', cursor); var el = this.get('el'); if (util_1.isBrowser && el) { // 直接设置样式,不等待鼠标移动时再设置 el.style.cursor = cursor; } }; // 实现接口 Canvas.prototype.getPointByEvent = function (ev) { var supportCSSTransform = this.get('supportCSSTransform'); if (supportCSSTransform) { // For Firefox <= 38 if (isFirefox && !util_1.isNil(ev.layerX) && ev.layerX !== ev.offsetX) { return { x: ev.layerX, y: ev.layerY, }; } if (!util_1.isNil(ev.offsetX)) { // For IE6+, Firefox >= 39, Chrome, Safari, Opera return { x: ev.offsetX, y: ev.offsetY, }; } } // should calculate by self for other cases, like Safari in ios // TODO: support CSS transform var _a = this.getClientByEvent(ev), clientX = _a.x, clientY = _a.y; return this.getPointByClient(clientX, clientY); }; // 获取 touch 事件的 clientX 和 clientY 需要单独处理 Canvas.prototype.getClientByEvent = function (ev) { var clientInfo = ev; if (ev.touches) { if (ev.type === 'touchend') { clientInfo = ev.changedTouches[0]; } else { clientInfo = ev.touches[0]; } } return { x: clientInfo.clientX, y: clientInfo.clientY, }; }; // 实现接口 Canvas.prototype.getPointByClient = function (clientX, clientY) { var el = this.get('el'); var bbox = el.getBoundingClientRect(); return { x: clientX - bbox.left, y: clientY - bbox.top, }; }; // 实现接口 Canvas.prototype.getClientByPoint = function (x, y) { var el = this.get('el'); var bbox = el.getBoundingClientRect(); return { x: x + bbox.left, y: y + bbox.top, }; }; // 实现接口 Canvas.prototype.draw = function () { }; /** * @protected * 销毁 DOM 容器 */ Canvas.prototype.removeDom = function () { var el = this.get('el'); el.parentNode.removeChild(el); }; /** * @protected * 清理所有的事件 */ Canvas.prototype.clearEvents = function () { var eventController = this.get('eventController'); eventController.destroy(); }; Canvas.prototype.isCanvas = function () { return true; }; Canvas.prototype.getParent = function () { return null; }; Canvas.prototype.destroy = function () { var timeline = this.get('timeline'); if (this.get('destroyed')) { return; } this.clear(); // 同初始化时相反顺序调用 if (timeline) { // 画布销毁时自动停止动画 timeline.stop(); } this.clearEvents(); this.removeDom(); _super.prototype.destroy.call(this); }; return Canvas; }(container_1.default)); exports.default = Canvas; },{"../animate/timeline":101,"../event/event-contoller":113,"../util/util":123,"./container":97,"detect-browser":880,"tslib":894}],97:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var element_1 = require("./element"); var util_1 = require("../util/util"); var SHAPE_MAP = {}; var INDEX = '_INDEX'; function afterAdd(element) { if (element.isGroup()) { if (element.isEntityGroup() || element.get('children').length) { element.onCanvasChange('add'); } } else { element.onCanvasChange('add'); } } /** * 设置 canvas * @param {IElement} element 元素 * @param {ICanvas} canvas 画布 */ function setCanvas(element, canvas) { element.set('canvas', canvas); if (element.isGroup()) { var children = element.get('children'); if (children.length) { children.forEach(function (child) { setCanvas(child, canvas); }); } } } /** * 设置 timeline * @param {IElement} element 元素 * @param {Timeline} timeline 时间轴 */ function setTimeline(element, timeline) { element.set('timeline', timeline); if (element.isGroup()) { var children = element.get('children'); if (children.length) { children.forEach(function (child) { setTimeline(child, timeline); }); } } } function contains(container, element) { var children = container.getChildren(); return children.indexOf(element) >= 0; } function removeChild(container, element, destroy) { if (destroy === void 0) { destroy = true; } // 不再调用 element.remove() 方法,会出现循环调用 if (destroy) { element.destroy(); } else { element.set('parent', null); element.set('canvas', null); } util_1.removeFromArray(container.getChildren(), element); } function getComparer(compare) { return function (left, right) { var result = compare(left, right); return result === 0 ? left[INDEX] - right[INDEX] : result; }; } var Container = /** @class */ (function (_super) { tslib_1.__extends(Container, _super); function Container() { return _super !== null && _super.apply(this, arguments) || this; } Container.prototype.isCanvas = function () { return false; }; // 根据子节点确定 BBox Container.prototype.getBBox = function () { // 所有的值可能在画布的可视区外 var minX = Infinity; var maxX = -Infinity; var minY = Infinity; var maxY = -Infinity; var xArr = []; var yArr = []; // 将可见元素、图形以及不为空的图形分组筛选出来,用于包围盒合并 var children = this.getChildren().filter(function (child) { return child.get('visible') && (!child.isGroup() || (child.isGroup() && child.getChildren().length > 0)); }); if (children.length > 0) { util_1.each(children, function (child) { var box = child.getBBox(); xArr.push(box.minX, box.maxX); yArr.push(box.minY, box.maxY); }); minX = Math.min.apply(null, xArr); maxX = Math.max.apply(null, xArr); minY = Math.min.apply(null, yArr); maxY = Math.max.apply(null, yArr); } else { minX = 0; maxX = 0; minY = 0; maxY = 0; } var box = { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; return box; }; // 获取画布的包围盒 Container.prototype.getCanvasBBox = function () { var minX = Infinity; var maxX = -Infinity; var minY = Infinity; var maxY = -Infinity; var xArr = []; var yArr = []; // 将可见元素、图形以及不为空的图形分组筛选出来,用于包围盒合并 var children = this.getChildren().filter(function (child) { return child.get('visible') && (!child.isGroup() || (child.isGroup() && child.getChildren().length > 0)); }); if (children.length > 0) { util_1.each(children, function (child) { var box = child.getCanvasBBox(); xArr.push(box.minX, box.maxX); yArr.push(box.minY, box.maxY); }); minX = Math.min.apply(null, xArr); maxX = Math.max.apply(null, xArr); minY = Math.min.apply(null, yArr); maxY = Math.max.apply(null, yArr); } else { minX = 0; maxX = 0; minY = 0; maxY = 0; } var box = { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; return box; }; Container.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); cfg['children'] = []; return cfg; }; Container.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); if (name === 'matrix') { var totalMatrix = this.getTotalMatrix(); this._applyChildrenMarix(totalMatrix); } }; // 不但应用到自己身上还要应用于子元素 Container.prototype.applyMatrix = function (matrix) { var preTotalMatrix = this.getTotalMatrix(); _super.prototype.applyMatrix.call(this, matrix); var totalMatrix = this.getTotalMatrix(); // totalMatrix 没有发生变化时,这里仅考虑两者都为 null 时 // 不继续向下传递矩阵 if (totalMatrix === preTotalMatrix) { return; } this._applyChildrenMarix(totalMatrix); }; // 在子元素上设置矩阵 Container.prototype._applyChildrenMarix = function (totalMatrix) { var children = this.getChildren(); util_1.each(children, function (child) { child.applyMatrix(totalMatrix); }); }; // 兼容老版本的接口 Container.prototype.addShape = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var type = args[0]; var cfg = args[1]; if (util_1.isObject(type)) { cfg = type; } else { cfg['type'] = type; } var shapeType = SHAPE_MAP[cfg.type]; if (!shapeType) { shapeType = util_1.upperFirst(cfg.type); SHAPE_MAP[cfg.type] = shapeType; } var ShapeBase = this.getShapeBase(); var shape = new ShapeBase[shapeType](cfg); this.add(shape); return shape; }; Container.prototype.addGroup = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var groupClass = args[0], cfg = args[1]; var group; if (util_1.isFunction(groupClass)) { if (cfg) { group = new groupClass(cfg); } else { group = new groupClass({ // canvas, parent: this, }); } } else { var tmpCfg = groupClass || {}; var TmpGroupClass = this.getGroupBase(); group = new TmpGroupClass(tmpCfg); } this.add(group); return group; }; Container.prototype.getCanvas = function () { var canvas; if (this.isCanvas()) { canvas = this; } else { canvas = this.get('canvas'); } return canvas; }; Container.prototype.getShape = function (x, y, ev) { // 如果不支持拾取,则直接返回 if (!util_1.isAllowCapture(this)) { return null; } var children = this.getChildren(); var shape; // 如果容器是 group if (!this.isCanvas()) { var v = [x, y, 1]; // 将 x, y 转换成对应于 group 的局部坐标 v = this.invertFromMatrix(v); if (!this.isClipped(v[0], v[1])) { shape = this._findShape(children, v[0], v[1], ev); } } else { shape = this._findShape(children, x, y, ev); } return shape; }; Container.prototype._findShape = function (children, x, y, ev) { var shape = null; for (var i = children.length - 1; i >= 0; i--) { var child = children[i]; if (util_1.isAllowCapture(child)) { if (child.isGroup()) { shape = child.getShape(x, y, ev); } else if (child.isHit(x, y)) { shape = child; } } if (shape) { break; } } return shape; }; Container.prototype.add = function (element) { var canvas = this.getCanvas(); var children = this.getChildren(); var timeline = this.get('timeline'); var preParent = element.getParent(); if (preParent) { removeChild(preParent, element, false); } element.set('parent', this); if (canvas) { setCanvas(element, canvas); } if (timeline) { setTimeline(element, timeline); } children.push(element); afterAdd(element); this._applyElementMatrix(element); }; // 将当前容器的矩阵应用到子元素 Container.prototype._applyElementMatrix = function (element) { var totalMatrix = this.getTotalMatrix(); // 添加图形或者分组时,需要把当前图元的矩阵设置进去 if (totalMatrix) { element.applyMatrix(totalMatrix); } }; Container.prototype.getChildren = function () { return this.get('children'); }; Container.prototype.sort = function () { var children = this.getChildren(); // 稳定排序 util_1.each(children, function (child, index) { child[INDEX] = index; return child; }); children.sort(getComparer(function (obj1, obj2) { return obj1.get('zIndex') - obj2.get('zIndex'); })); this.onCanvasChange('sort'); }; Container.prototype.clear = function () { this.set('clearing', true); if (this.destroyed) { return; } var children = this.getChildren(); for (var i = children.length - 1; i >= 0; i--) { children[i].destroy(); // 销毁子元素 } this.set('children', []); this.onCanvasChange('clear'); this.set('clearing', false); }; Container.prototype.destroy = function () { if (this.get('destroyed')) { return; } this.clear(); _super.prototype.destroy.call(this); }; /** * 获取第一个子元素 * @return {IElement} 第一个元素 */ Container.prototype.getFirst = function () { return this.getChildByIndex(0); }; /** * 获取最后一个子元素 * @return {IElement} 元素 */ Container.prototype.getLast = function () { var children = this.getChildren(); return this.getChildByIndex(children.length - 1); }; /** * 根据索引获取子元素 * @return {IElement} 第一个元素 */ Container.prototype.getChildByIndex = function (index) { var children = this.getChildren(); return children[index]; }; /** * 子元素的数量 * @return {number} 子元素数量 */ Container.prototype.getCount = function () { var children = this.getChildren(); return children.length; }; /** * 是否包含对应元素 * @param {IElement} element 元素 * @return {boolean} */ Container.prototype.contain = function (element) { var children = this.getChildren(); return children.indexOf(element) > -1; }; /** * 移除对应子元素 * @param {IElement} element 子元素 * @param {boolean} destroy 是否销毁子元素,默认为 true */ Container.prototype.removeChild = function (element, destroy) { if (destroy === void 0) { destroy = true; } if (this.contain(element)) { element.remove(destroy); } }; /** * 查找所有匹配的元素 * @param {ElementFilterFn} fn 匹配函数 * @return {IElement[]} 元素数组 */ Container.prototype.findAll = function (fn) { var rst = []; var children = this.getChildren(); util_1.each(children, function (element) { if (fn(element)) { rst.push(element); } if (element.isGroup()) { rst = rst.concat(element.findAll(fn)); } }); return rst; }; /** * 查找元素,找到第一个返回 * @param {ElementFilterFn} fn 匹配函数 * @return {IElement|null} 元素,可以为空 */ Container.prototype.find = function (fn) { var rst = null; var children = this.getChildren(); util_1.each(children, function (element) { if (fn(element)) { rst = element; } else if (element.isGroup()) { rst = element.find(fn); } if (rst) { return false; } }); return rst; }; /** * 根据 ID 查找元素 * @param {string} id 元素 id * @return {IElement|null} 元素 */ Container.prototype.findById = function (id) { return this.find(function (element) { return element.get('id') === id; }); }; /** * 该方法即将废弃,不建议使用 * 根据 className 查找元素 * TODO: 该方式定义暂时只给 G6 3.3 以后的版本使用,待 G6 中的 findByClassName 方法移除后,G 也需要同步移除 * @param {string} className 元素 className * @return {IElement | null} 元素 */ Container.prototype.findByClassName = function (className) { return this.find(function (element) { return element.get('className') === className; }); }; /** * 根据 name 查找元素列表 * @param {string} name 元素名称 * @return {IElement[]} 元素 */ Container.prototype.findAllByName = function (name) { return this.findAll(function (element) { return element.get('name') === name; }); }; return Container; }(element_1.default)); exports.default = Container; },{"../util/util":123,"./element":98,"tslib":894}],98:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var matrix_util_1 = require("@antv/matrix-util"); var util_2 = require("../util/util"); var matrix_1 = require("../util/matrix"); var base_1 = require("./base"); var MATRIX = 'matrix'; var CLONE_CFGS = ['zIndex', 'capture', 'visible', 'type']; // 可以在 toAttrs 中设置,但不属于绘图属性的字段 var RESERVED_PORPS = ['repeat']; var DELEGATION_SPLIT = ':'; var WILDCARD = '*'; // 需要考虑数组嵌套数组的场景 // 数组嵌套对象的场景不考虑 function _cloneArrayAttr(arr) { var result = []; for (var i = 0; i < arr.length; i++) { if (util_1.isArray(arr[i])) { result.push([].concat(arr[i])); } else { result.push(arr[i]); } } return result; } function getFormatFromAttrs(toAttrs, shape) { var fromAttrs = {}; var attrs = shape.attrs; for (var k in toAttrs) { fromAttrs[k] = attrs[k]; } return fromAttrs; } function getFormatToAttrs(props, shape) { var toAttrs = {}; var attrs = shape.attr(); util_1.each(props, function (v, k) { if (RESERVED_PORPS.indexOf(k) === -1 && !util_1.isEqual(attrs[k], v)) { toAttrs[k] = v; } }); return toAttrs; } function checkExistedAttrs(animations, animation) { if (animation.onFrame) { return animations; } var startTime = animation.startTime, delay = animation.delay, duration = animation.duration; var hasOwnProperty = Object.prototype.hasOwnProperty; util_1.each(animations, function (item) { // 后一个动画开始执行的时间 < 前一个动画的结束时间 && 后一个动画的执行时间 > 前一个动画的延迟 if (startTime + delay < item.startTime + item.delay + item.duration && duration > item.delay) { util_1.each(animation.toAttrs, function (v, k) { if (hasOwnProperty.call(item.toAttrs, k)) { delete item.toAttrs[k]; delete item.fromAttrs[k]; } }); } }); return animations; } var Element = /** @class */ (function (_super) { tslib_1.__extends(Element, _super); function Element(cfg) { var _this = _super.call(this, cfg) || this; /** * @protected * 图形属性 * @type {ShapeAttrs} */ _this.attrs = {}; var attrs = _this.getDefaultAttrs(); util_1.mix(attrs, cfg.attrs); _this.attrs = attrs; _this.initAttrs(attrs); _this.initAnimate(); // 初始化动画 return _this; } // override Element.prototype.getDefaultCfg = function () { return { visible: true, capture: true, zIndex: 0, }; }; /** * @protected * 获取默认的属相 */ Element.prototype.getDefaultAttrs = function () { return { matrix: this.getDefaultMatrix(), opacity: 1, }; }; /** * @protected * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ Element.prototype.onCanvasChange = function (changeType) { }; /** * @protected * 初始化属性,有些属性需要加工 * @param {object} attrs 属性值 */ Element.prototype.initAttrs = function (attrs) { }; /** * @protected * 初始化动画 */ Element.prototype.initAnimate = function () { this.set('animable', true); this.set('animating', false); }; Element.prototype.isGroup = function () { return false; }; Element.prototype.getParent = function () { return this.get('parent'); }; Element.prototype.getCanvas = function () { return this.get('canvas'); }; Element.prototype.attr = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var name = args[0], value = args[1]; if (!name) return this.attrs; if (util_1.isObject(name)) { for (var k in name) { this.setAttr(k, name[k]); } this.afterAttrsChange(name); return this; } if (args.length === 2) { this.setAttr(name, value); this.afterAttrsChange((_a = {}, _a[name] = value, _a)); return this; } return this.attrs[name]; }; // 是否被裁剪,被裁剪则不显示,不参与拾取 Element.prototype.isClipped = function (refX, refY) { var clip = this.getClip(); return clip && !clip.isHit(refX, refY); }; /** * 内部设置属性值的接口 * @param {string} name 属性名 * @param {any} value 属性值 */ Element.prototype.setAttr = function (name, value) { var originValue = this.attrs[name]; if (originValue !== value) { this.attrs[name] = value; this.onAttrChange(name, value, originValue); } }; /** * @protected * 属性值发生改变 * @param {string} name 属性名 * @param {any} value 属性值 * @param {any} originValue 属性值 */ Element.prototype.onAttrChange = function (name, value, originValue) { if (name === 'matrix') { this.set('totalMatrix', null); } }; /** * 属性更改后需要做的事情 * @protected */ Element.prototype.afterAttrsChange = function (targetAttrs) { this.onCanvasChange('attr'); }; Element.prototype.show = function () { // 不是高频操作直接使用 set this.set('visible', true); this.onCanvasChange('show'); return this; }; Element.prototype.hide = function () { // 不是高频操作直接使用 set this.set('visible', false); this.onCanvasChange('hide'); return this; }; Element.prototype.setZIndex = function (zIndex) { this.set('zIndex', zIndex); var parent = this.getParent(); if (parent) { // 改变 zIndex 不应该立即触发渲染 (调用 onCanvasChange('zIndex')),需要经过 sort 再触发 parent.sort(); } return this; }; Element.prototype.toFront = function () { var parent = this.getParent(); if (!parent) { return; } var children = parent.getChildren(); var el = this.get('el'); var index = children.indexOf(this); children.splice(index, 1); children.push(this); this.onCanvasChange('zIndex'); }; Element.prototype.toBack = function () { var parent = this.getParent(); if (!parent) { return; } var children = parent.getChildren(); var el = this.get('el'); var index = children.indexOf(this); children.splice(index, 1); children.unshift(this); this.onCanvasChange('zIndex'); }; Element.prototype.remove = function (destroy) { if (destroy === void 0) { destroy = true; } var parent = this.getParent(); if (parent) { util_2.removeFromArray(parent.getChildren(), this); if (!parent.get('clearing')) { // 如果父元素正在清理,当前元素不触发 remove this.onCanvasChange('remove'); } } else { this.onCanvasChange('remove'); } if (destroy) { this.destroy(); } }; Element.prototype.resetMatrix = function () { this.attr(MATRIX, this.getDefaultMatrix()); this.onCanvasChange('matrix'); }; Element.prototype.getMatrix = function () { return this.attr(MATRIX); }; Element.prototype.setMatrix = function (m) { this.attr(MATRIX, m); this.onCanvasChange('matrix'); }; // 获取总的 matrix Element.prototype.getTotalMatrix = function () { var totalMatrix = this.get('totalMatrix'); if (!totalMatrix) { var currentMatrix = this.attr('matrix'); var parentMatrix = this.get('parentMatrix'); if (parentMatrix && currentMatrix) { totalMatrix = matrix_1.multiplyMatrix(parentMatrix, currentMatrix); } else { totalMatrix = currentMatrix || parentMatrix; } this.set('totalMatrix', totalMatrix); } return totalMatrix; }; // 上层分组设置 matrix Element.prototype.applyMatrix = function (matrix) { var currentMatrix = this.attr('matrix'); var totalMatrix = null; if (matrix && currentMatrix) { totalMatrix = matrix_1.multiplyMatrix(matrix, currentMatrix); } else { totalMatrix = currentMatrix || matrix; } this.set('totalMatrix', totalMatrix); this.set('parentMatrix', matrix); }; /** * @protected * 获取默认的矩阵 * @returns {number[]|null} 默认的矩阵 */ Element.prototype.getDefaultMatrix = function () { return null; }; // 将向量应用设置的矩阵 Element.prototype.applyToMatrix = function (v) { var matrix = this.attr('matrix'); if (matrix) { return matrix_1.multiplyVec2(matrix, v); } return v; }; // 根据设置的矩阵,将向量转换相对于图形/分组的位置 Element.prototype.invertFromMatrix = function (v) { var matrix = this.attr('matrix'); if (matrix) { var invertMatrix = matrix_1.invert(matrix); if (invertMatrix) { return matrix_1.multiplyVec2(invertMatrix, v); } } return v; }; // 设置 clip Element.prototype.setClip = function (clipCfg) { var canvas = this.getCanvas(); // 应该只设置当前元素的 clip,不应该去修改 clip 本身,方便 clip 被复用 // TODO: setClip 的传参既 shape 配置,也支持 shape 对象 // const preShape = this.get('clipShape'); // if (preShape) { // // 将之前的 clipShape 销毁 // preShape.destroy(); // } var clipShape = null; // 如果配置项为 null,则不移除 clipShape if (clipCfg) { var ShapeBase = this.getShapeBase(); var shapeType = util_1.upperFirst(clipCfg.type); var Cons = ShapeBase[shapeType]; if (Cons) { clipShape = new Cons({ type: clipCfg.type, isClipShape: true, attrs: clipCfg.attrs, canvas: canvas, }); } } this.set('clipShape', clipShape); this.onCanvasChange('clip'); return clipShape; }; Element.prototype.getClip = function () { // 高频率调用的地方直接使用 this.cfg.xxx var clipShape = this.cfg.clipShape; // 未设置时返回 Null,保证一致性 if (!clipShape) { return null; } return clipShape; }; Element.prototype.clone = function () { var _this = this; var originAttrs = this.attrs; var attrs = {}; util_1.each(originAttrs, function (i, k) { if (util_1.isArray(originAttrs[k])) { attrs[k] = _cloneArrayAttr(originAttrs[k]); } else { attrs[k] = originAttrs[k]; } }); var cons = this.constructor; // @ts-ignore var clone = new cons({ attrs: attrs }); util_1.each(CLONE_CFGS, function (cfgName) { clone.set(cfgName, _this.get(cfgName)); }); return clone; }; Element.prototype.destroy = function () { var destroyed = this.destroyed; if (destroyed) { return; } this.attrs = {}; _super.prototype.destroy.call(this); // this.onCanvasChange('destroy'); }; /** * 是否处于动画暂停状态 * @return {boolean} 是否处于动画暂停状态 */ Element.prototype.isAnimatePaused = function () { return this.get('_pause').isPaused; }; /** * 执行动画,支持多种函数签名 * 1. animate(toAttrs: ElementAttrs, duration: number, easing?: string, callback?: () => void, delay?: number) * 2. animate(onFrame: OnFrame, duration: number, easing?: string, callback?: () => void, delay?: number) * 3. animate(toAttrs: ElementAttrs, cfg: AnimateCfg) * 4. animate(onFrame: OnFrame, cfg: AnimateCfg) * 各个参数的含义为: * toAttrs 动画最终状态 * onFrame 自定义帧动画函数 * duration 动画执行时间 * easing 动画缓动效果 * callback 动画执行后的回调 * delay 动画延迟时间 */ Element.prototype.animate = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.set('animating', true); var timeline = this.get('timeline'); if (!timeline) { timeline = this.get('canvas').get('timeline'); this.set('timeline', timeline); } var animations = this.get('animations') || []; // 初始化 tick if (!timeline.timer) { timeline.initTimer(); } var toAttrs = args[0], duration = args[1], _a = args[2], easing = _a === void 0 ? 'easeLinear' : _a, _b = args[3], callback = _b === void 0 ? util_1.noop : _b, _c = args[4], delay = _c === void 0 ? 0 : _c; var onFrame; var repeat; var pauseCallback; var resumeCallback; var animateCfg; // 第二个参数,既可以是动画最终状态 toAttrs,也可以是自定义帧动画函数 onFrame if (util_1.isFunction(toAttrs)) { onFrame = toAttrs; toAttrs = {}; } else if (util_1.isObject(toAttrs) && toAttrs.onFrame) { // 兼容 3.0 中的写法,onFrame 和 repeat 可在 toAttrs 中设置 onFrame = toAttrs.onFrame; repeat = toAttrs.repeat; } // 第二个参数,既可以是执行时间 duration,也可以是动画参数 animateCfg if (util_1.isObject(duration)) { animateCfg = duration; duration = animateCfg.duration; easing = animateCfg.easing || 'easeLinear'; delay = animateCfg.delay || 0; // animateCfg 中的设置优先级更高 repeat = animateCfg.repeat || repeat || false; callback = animateCfg.callback || util_1.noop; pauseCallback = animateCfg.pauseCallback || util_1.noop; resumeCallback = animateCfg.resumeCallback || util_1.noop; } else { // 第四个参数,既可以是回调函数 callback,也可以是延迟时间 delay if (util_1.isNumber(callback)) { delay = callback; callback = null; } // 第三个参数,既可以是缓动参数 easing,也可以是回调函数 callback if (util_1.isFunction(easing)) { callback = easing; easing = 'easeLinear'; } else { easing = easing || 'easeLinear'; } } var formatToAttrs = getFormatToAttrs(toAttrs, this); var animation = { fromAttrs: getFormatFromAttrs(formatToAttrs, this), toAttrs: formatToAttrs, duration: duration, easing: easing, repeat: repeat, callback: callback, pauseCallback: pauseCallback, resumeCallback: resumeCallback, delay: delay, startTime: timeline.getTime(), id: util_1.uniqueId(), onFrame: onFrame, pathFormatted: false, }; // 如果动画元素队列中已经有这个图形了 if (animations.length > 0) { // 先检查是否需要合并属性。若有相同的动画,将该属性从前一个动画中删除,直接用后一个动画中 animations = checkExistedAttrs(animations, animation); } else { // 否则将图形添加到动画元素队列 timeline.addAnimator(this); } animations.push(animation); this.set('animations', animations); this.set('_pause', { isPaused: false }); }; /** * 停止动画 * @param {boolean} toEnd 是否到动画的最终状态 */ Element.prototype.stopAnimate = function (toEnd) { var _this = this; if (toEnd === void 0) { toEnd = true; } var animations = this.get('animations'); util_1.each(animations, function (animation) { // 将动画执行到最后一帧 if (toEnd) { if (animation.onFrame) { _this.attr(animation.onFrame(1)); } else { _this.attr(animation.toAttrs); } } if (animation.callback) { // 动画停止时的回调 animation.callback(); } }); this.set('animating', false); this.set('animations', []); }; /** * 暂停动画 */ Element.prototype.pauseAnimate = function () { var timeline = this.get('timeline'); var animations = this.get('animations'); var pauseTime = timeline.getTime(); util_1.each(animations, function (animation) { animation._paused = true; animation._pauseTime = pauseTime; if (animation.pauseCallback) { // 动画暂停时的回调 animation.pauseCallback(); } }); // 记录下是在什么时候暂停的 this.set('_pause', { isPaused: true, pauseTime: pauseTime, }); return this; }; /** * 恢复动画 */ Element.prototype.resumeAnimate = function () { var timeline = this.get('timeline'); var current = timeline.getTime(); var animations = this.get('animations'); var pauseTime = this.get('_pause').pauseTime; // 之后更新属性需要计算动画已经执行的时长,如果暂停了,就把初始时间调后 util_1.each(animations, function (animation) { animation.startTime = animation.startTime + (current - pauseTime); animation._paused = false; animation._pauseTime = null; if (animation.resumeCallback) { animation.resumeCallback(); } }); this.set('_pause', { isPaused: false, }); this.set('animations', animations); return this; }; /** * 触发委托事件 * @param {string} type 事件类型 * @param {GraphEvent} eventObj 事件对象 */ Element.prototype.emitDelegation = function (type, eventObj) { var _this = this; var paths = eventObj.propagationPath; var events = this.getEvents(); var relativeShape; if (type === 'mouseenter') { relativeShape = eventObj.fromShape; } else if (type === 'mouseleave') { relativeShape = eventObj.toShape; } var _loop_1 = function (i) { var element = paths[i]; // 暂定跟 name 绑定 var name_1 = element.get('name'); if (name_1) { // 第一个 mouseenter 和 mouseleave 的停止即可,因为后面的都是前面的 Parent if ( // 只有 element 是 Group 或者 Canvas 的时候,才需要判断 isParent (element.isGroup() || (element.isCanvas && element.isCanvas())) && relativeShape && util_2.isParent(element, relativeShape)) { return "break"; } if (util_1.isArray(name_1)) { util_1.each(name_1, function (subName) { _this.emitDelegateEvent(element, subName, eventObj); }); } else { this_1.emitDelegateEvent(element, name_1, eventObj); } } }; var this_1 = this; // 至少有一个对象,且第一个对象为 shape for (var i = 0; i < paths.length; i++) { var state_1 = _loop_1(i); if (state_1 === "break") break; } }; Element.prototype.emitDelegateEvent = function (element, name, eventObj) { var events = this.getEvents(); // 事件委托的形式 name:type var eventName = name + DELEGATION_SPLIT + eventObj.type; if (events[eventName] || events[WILDCARD]) { // 对于通配符 *,事件名称 = 委托事件名称 eventObj.name = eventName; eventObj.currentTarget = element; eventObj.delegateTarget = this; // 将委托事件的监听对象 delegateObject 挂载到事件对象上 eventObj.delegateObject = element.get('delegateObject'); this.emit(eventName, eventObj); } }; /** * 移动元素 * @param {number} translateX 水平移动距离 * @param {number} translateY 垂直移动距离 * @return {IElement} 元素 */ Element.prototype.translate = function (translateX, translateY) { if (translateX === void 0) { translateX = 0; } if (translateY === void 0) { translateY = 0; } var matrix = this.getMatrix(); var newMatrix = matrix_util_1.ext.transform(matrix, [['t', translateX, translateY]]); this.setMatrix(newMatrix); return this; }; /** * 移动元素到目标位置 * @param {number} targetX 目标位置的水平坐标 * @param {number} targetX 目标位置的垂直坐标 * @return {IElement} 元素 */ Element.prototype.move = function (targetX, targetY) { var x = this.attr('x') || 0; var y = this.attr('y') || 0; this.translate(targetX - x, targetY - y); return this; }; /** * 移动元素到目标位置,等价于 move 方法。由于 moveTo 的语义性更强,因此在文档中推荐使用 moveTo 方法 * @param {number} targetX 目标位置的 x 轴坐标 * @param {number} targetY 目标位置的 y 轴坐标 * @return {IElement} 元素 */ Element.prototype.moveTo = function (targetX, targetY) { return this.move(targetX, targetY); }; /** * 缩放元素 * @param {number} ratioX 水平缩放比例 * @param {number} ratioY 垂直缩放比例 * @return {IElement} 元素 */ Element.prototype.scale = function (ratioX, ratioY) { var matrix = this.getMatrix(); var newMatrix = matrix_util_1.ext.transform(matrix, [['s', ratioX, ratioY || ratioX]]); this.setMatrix(newMatrix); return this; }; /** * 以画布左上角 (0, 0) 为中心旋转元素 * @param {number} radian 旋转角度(弧度值) * @return {IElement} 元素 */ Element.prototype.rotate = function (radian) { var matrix = this.getMatrix(); var newMatrix = matrix_util_1.ext.transform(matrix, [['r', radian]]); this.setMatrix(newMatrix); return this; }; /** * 以起始点为中心旋转元素 * @param {number} radian 旋转角度(弧度值) * @return {IElement} 元素 */ Element.prototype.rotateAtStart = function (rotate) { var _a = this.attr(), x = _a.x, y = _a.y; var matrix = this.getMatrix(); var newMatrix = matrix_util_1.ext.transform(matrix, [ ['t', -x, -y], ['r', rotate], ['t', x, y], ]); this.setMatrix(newMatrix); return this; }; /** * 以任意点 (x, y) 为中心旋转元素 * @param {number} radian 旋转角度(弧度值) * @return {IElement} 元素 */ Element.prototype.rotateAtPoint = function (x, y, rotate) { var matrix = this.getMatrix(); var newMatrix = matrix_util_1.ext.transform(matrix, [ ['t', -x, -y], ['r', rotate], ['t', x, y], ]); this.setMatrix(newMatrix); return this; }; return Element; }(base_1.default)); exports.default = Element; },{"../util/matrix":119,"../util/util":123,"./base":95,"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],99:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var container_1 = require("./container"); var AbstractGroup = /** @class */ (function (_super) { tslib_1.__extends(AbstractGroup, _super); function AbstractGroup() { return _super !== null && _super.apply(this, arguments) || this; } AbstractGroup.prototype.isGroup = function () { return true; }; AbstractGroup.prototype.isEntityGroup = function () { return false; }; AbstractGroup.prototype.clone = function () { var clone = _super.prototype.clone.call(this); // 获取构造函数 var children = this.getChildren(); for (var i = 0; i < children.length; i++) { var child = children[i]; clone.add(child.clone()); } return clone; }; return AbstractGroup; }(container_1.default)); exports.default = AbstractGroup; },{"./container":97,"tslib":894}],100:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var element_1 = require("./element"); var matrix_1 = require("../util/matrix"); var AbstractShape = /** @class */ (function (_super) { tslib_1.__extends(AbstractShape, _super); function AbstractShape(cfg) { return _super.call(this, cfg) || this; } // 是否在包围盒内 AbstractShape.prototype._isInBBox = function (refX, refY) { var bbox = this.getBBox(); return bbox.minX <= refX && bbox.maxX >= refX && bbox.minY <= refY && bbox.maxY >= refY; }; /** * 属性更改后需要做的事情 * @protected * @param {ShapeAttrs} targetAttrs 渲染的图像属性 */ AbstractShape.prototype.afterAttrsChange = function (targetAttrs) { _super.prototype.afterAttrsChange.call(this, targetAttrs); this.clearCacheBBox(); }; // 计算包围盒时,需要缓存,这是一个高频的操作 AbstractShape.prototype.getBBox = function () { var bbox = this.get('bbox'); if (!bbox) { bbox = this.calculateBBox(); this.set('bbox', bbox); } return bbox; }; // 计算相对于画布的包围盒 AbstractShape.prototype.getCanvasBBox = function () { var canvasBox = this.get('canvasBox'); if (!canvasBox) { canvasBox = this.calculateCanvasBBox(); this.set('canvasBox', canvasBox); } return canvasBox; }; AbstractShape.prototype.applyMatrix = function (matrix) { _super.prototype.applyMatrix.call(this, matrix); // 清理掉缓存的包围盒 this.set('canvasBox', null); }; /** * 计算相对于画布的包围盒,默认等同于 bbox * @return {BBox} 包围盒 */ AbstractShape.prototype.calculateCanvasBBox = function () { var bbox = this.getBBox(); var totalMatrix = this.getTotalMatrix(); var minX = bbox.minX, minY = bbox.minY, maxX = bbox.maxX, maxY = bbox.maxY; if (totalMatrix) { var topLeft = matrix_1.multiplyVec2(totalMatrix, [bbox.minX, bbox.minY]); var topRight = matrix_1.multiplyVec2(totalMatrix, [bbox.maxX, bbox.minY]); var bottomLeft = matrix_1.multiplyVec2(totalMatrix, [bbox.minX, bbox.maxY]); var bottomRight = matrix_1.multiplyVec2(totalMatrix, [bbox.maxX, bbox.maxY]); minX = Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]); maxX = Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]); minY = Math.min(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]); maxY = Math.max(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]); } var attrs = this.attrs; // 如果存在 shadow 则计算 shadow if (attrs.shadowColor) { var _a = attrs.shadowBlur, shadowBlur = _a === void 0 ? 0 : _a, _b = attrs.shadowOffsetX, shadowOffsetX = _b === void 0 ? 0 : _b, _c = attrs.shadowOffsetY, shadowOffsetY = _c === void 0 ? 0 : _c; var shadowLeft = minX - shadowBlur + shadowOffsetX; var shadowRight = maxX + shadowBlur + shadowOffsetX; var shadowTop = minY - shadowBlur + shadowOffsetY; var shadowBottom = maxY + shadowBlur + shadowOffsetY; minX = Math.min(minX, shadowLeft); maxX = Math.max(maxX, shadowRight); minY = Math.min(minY, shadowTop); maxY = Math.max(maxY, shadowBottom); } return { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: maxX - minX, height: maxY - minY, }; }; /** * @protected * 清理缓存的 bbox */ AbstractShape.prototype.clearCacheBBox = function () { this.set('bbox', null); this.set('canvasBox', null); }; // 实现接口 AbstractShape.prototype.isClipShape = function () { return this.get('isClipShape'); }; /** * @protected * 不同的图形自己实现是否在图形内部的逻辑,要判断边和填充区域 * @param {number} refX 相对于图形的坐标 x * @param {number} refY 相对于图形的坐标 Y * @return {boolean} 点是否在图形内部 */ AbstractShape.prototype.isInShape = function (refX, refY) { return false; }; /** * 是否仅仅使用 BBox 检测就可以判定拾取到图形 * 默认是 false,但是有些图形例如 image、marker 等都可直接使用 BBox 的检测而不需要使用图形拾取 * @return {Boolean} 仅仅使用 BBox 进行拾取 */ AbstractShape.prototype.isOnlyHitBox = function () { return false; }; // 不同的 Shape 各自实现 AbstractShape.prototype.isHit = function (x, y) { var startArrowShape = this.get('startArrowShape'); var endArrowShape = this.get('endArrowShape'); var vec = [x, y, 1]; vec = this.invertFromMatrix(vec); var refX = vec[0], refY = vec[1]; var inBBox = this._isInBBox(refX, refY); // 跳过图形的拾取,在某些图形中可以省略一倍的检测成本 if (this.isOnlyHitBox()) { return inBBox; } // 被裁减掉的和不在包围盒内的不进行计算 if (inBBox && !this.isClipped(refX, refY)) { // 对图形进行拾取判断 if (this.isInShape(refX, refY)) { return true; } // 对起始箭头进行拾取判断 if (startArrowShape && startArrowShape.isHit(refX, refY)) { return true; } // 对结束箭头进行拾取判断 if (endArrowShape && endArrowShape.isHit(refX, refY)) { return true; } } return false; }; return AbstractShape; }(element_1.default)); exports.default = AbstractShape; },{"../util/matrix":119,"./element":98,"tslib":894}],101:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var d3Timer = require("d3-timer"); var d3Ease = require("d3-ease"); var d3_interpolate_1 = require("d3-interpolate"); // 目前整体动画只需要数值和数组的差值计算 var PathUtil = require("../util/path"); var color_1 = require("../util/color"); var IDENTITY_MATRIX = [1, 0, 0, 0, 1, 0, 0, 0, 1]; /** * 使用 ratio 进行插值计算来更新属性 * @param {IElement} shape 元素 * @param {Animation} animation 动画 * @param {number} ratio 比例 * @return {boolean} 动画是否执行完成 */ function _update(shape, animation, ratio) { var cProps = {}; // 此刻属性 var fromAttrs = animation.fromAttrs, toAttrs = animation.toAttrs; if (shape.destroyed) { return; } var interf; // 差值函数 for (var k in toAttrs) { if (!util_1.isEqual(fromAttrs[k], toAttrs[k])) { if (k === 'path') { var toPath = toAttrs[k]; var fromPath = fromAttrs[k]; if (toPath.length > fromPath.length) { toPath = PathUtil.parsePathString(toAttrs[k]); // 终点状态 fromPath = PathUtil.parsePathString(fromAttrs[k]); // 起始状态 fromPath = PathUtil.fillPathByDiff(fromPath, toPath); fromPath = PathUtil.formatPath(fromPath, toPath); animation.fromAttrs.path = fromPath; animation.toAttrs.path = toPath; } else if (!animation.pathFormatted) { toPath = PathUtil.parsePathString(toAttrs[k]); fromPath = PathUtil.parsePathString(fromAttrs[k]); fromPath = PathUtil.formatPath(fromPath, toPath); animation.fromAttrs.path = fromPath; animation.toAttrs.path = toPath; animation.pathFormatted = true; } cProps[k] = []; for (var i = 0; i < toPath.length; i++) { var toPathPoint = toPath[i]; var fromPathPoint = fromPath[i]; var cPathPoint = []; for (var j = 0; j < toPathPoint.length; j++) { if (util_1.isNumber(toPathPoint[j]) && fromPathPoint && util_1.isNumber(fromPathPoint[j])) { interf = d3_interpolate_1.interpolate(fromPathPoint[j], toPathPoint[j]); cPathPoint.push(interf(ratio)); } else { cPathPoint.push(toPathPoint[j]); } } cProps[k].push(cPathPoint); } } else if (k === 'matrix') { /* 对矩阵进行插值时,需要保证矩阵不为空,为空则使用单位矩阵 TODO: 二维和三维场景下单位矩阵不同,之后 WebGL 版需要做进一步处理 */ var matrixFn = d3_interpolate_1.interpolateArray(fromAttrs[k] || IDENTITY_MATRIX, toAttrs[k] || IDENTITY_MATRIX); var currentMatrix = matrixFn(ratio); cProps[k] = currentMatrix; } else if (color_1.isColorProp(k) && color_1.isGradientColor(toAttrs[k])) { cProps[k] = toAttrs[k]; } else if (!util_1.isFunction(toAttrs[k])) { // 非函数类型的值才能做插值 interf = d3_interpolate_1.interpolate(fromAttrs[k], toAttrs[k]); cProps[k] = interf(ratio); } } } shape.attr(cProps); } /** * 根据自定义帧动画函数 onFrame 来更新属性 * @param {IElement} shape 元素 * @param {Animation} animation 动画 * @param {number} elapsed 动画执行时间(毫秒) * @return {boolean} 动画是否执行完成 */ function update(shape, animation, elapsed) { var startTime = animation.startTime, delay = animation.delay; // 如果还没有开始执行或暂停,先不更新 if (elapsed < startTime + delay || animation._paused) { return false; } var ratio; var duration = animation.duration; var easing = animation.easing; // 已执行时间 elapsed = elapsed - startTime - animation.delay; if (animation.repeat) { // 如果动画重复执行,则 elapsed > duration,计算 ratio 时需取模 ratio = (elapsed % duration) / duration; ratio = d3Ease[easing](ratio); } else { ratio = elapsed / duration; if (ratio < 1) { // 动画未执行完 ratio = d3Ease[easing](ratio); } else { // 动画已执行完 if (animation.onFrame) { shape.attr(animation.onFrame(1)); } else { shape.attr(animation.toAttrs); } return true; } } if (animation.onFrame) { var attrs = animation.onFrame(ratio); shape.attr(attrs); } else { _update(shape, animation, ratio); } return false; } var Timeline = /** @class */ (function () { /** * 时间轴构造函数,依赖于画布 * @param {} */ function Timeline(canvas) { /** * 执行动画的元素列表 * @type {IElement[]} */ this.animators = []; /** * 当前时间 * @type {number} */ this.current = 0; /** * 定时器 * @type {d3Timer.Timer} */ this.timer = null; this.canvas = canvas; } /** * 初始化定时器 */ Timeline.prototype.initTimer = function () { var _this = this; var isFinished = false; var shape; var animations; var animation; this.timer = d3Timer.timer(function (elapsed) { _this.current = elapsed; if (_this.animators.length > 0) { for (var i = _this.animators.length - 1; i >= 0; i--) { shape = _this.animators[i]; if (shape.destroyed) { // 如果已经被销毁,直接移出队列 _this.removeAnimator(i); continue; } if (!shape.isAnimatePaused()) { animations = shape.get('animations'); for (var j = animations.length - 1; j >= 0; j--) { animation = animations[j]; isFinished = update(shape, animation, elapsed); if (isFinished) { animations.splice(j, 1); isFinished = false; if (animation.callback) { animation.callback(); } } } } if (animations.length === 0) { _this.removeAnimator(i); } } var autoDraw = _this.canvas.get('autoDraw'); // 非自动渲染模式下,手动调用 canvas.draw() 重新渲染 if (!autoDraw) { _this.canvas.draw(); } } }); }; /** * 增加动画元素 */ Timeline.prototype.addAnimator = function (shape) { this.animators.push(shape); }; /** * 移除动画元素 */ Timeline.prototype.removeAnimator = function (index) { this.animators.splice(index, 1); }; /** * 是否有动画在执行 */ Timeline.prototype.isAnimating = function () { return !!this.animators.length; }; /** * 停止定时器 */ Timeline.prototype.stop = function () { if (this.timer) { this.timer.stop(); } }; /** * 停止时间轴上所有元素的动画,并置空动画元素列表 * @param {boolean} toEnd 是否到动画的最终状态,用来透传给动画元素的 stopAnimate 方法 */ Timeline.prototype.stopAllAnimations = function (toEnd) { if (toEnd === void 0) { toEnd = true; } this.animators.forEach(function (animator) { animator.stopAnimate(toEnd); }); this.animators = []; this.canvas.draw(); }; /** * 获取当前时间 */ Timeline.prototype.getTime = function () { return this.current; }; return Timeline; }()); exports.default = Timeline; },{"../util/color":118,"../util/path":121,"@antv/util":803,"d3-ease":876,"d3-interpolate":877,"d3-timer":879}],102:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function default_1(shape) { var _a = shape.attr(), x = _a.x, y = _a.y, r = _a.r; return { x: x - r, y: y - r, width: r * 2, height: r * 2, }; } exports.default = default_1; },{}],103:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function default_1(shape) { var attrs = shape.attr(); var x = attrs.x, y = attrs.y, rx = attrs.rx, ry = attrs.ry; return { x: x - rx, y: y - ry, width: rx * 2, height: ry * 2, }; } exports.default = default_1; },{}],104:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var register_1 = require("./register"); exports.getBBoxMethod = register_1.getMethod; var rect_1 = require("./rect"); var circle_1 = require("./circle"); var polyline_1 = require("./polyline"); var polygon_1 = require("./polygon"); var text_1 = require("./text"); var path_1 = require("./path"); var line_1 = require("./line"); var ellipse_1 = require("./ellipse"); register_1.register('rect', rect_1.default); register_1.register('image', rect_1.default); // image 使用 rect 的包围盒计算 register_1.register('circle', circle_1.default); register_1.register('marker', circle_1.default); // marker 使用 circle 的计算方案 register_1.register('polyline', polyline_1.default); register_1.register('polygon', polygon_1.default); register_1.register('text', text_1.default); register_1.register('path', path_1.default); register_1.register('line', line_1.default); register_1.register('ellipse', ellipse_1.default); },{"./circle":102,"./ellipse":103,"./line":105,"./path":106,"./polygon":107,"./polyline":108,"./rect":109,"./register":110,"./text":111}],105:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); function default_1(shape) { var attrs = shape.attr(); var x1 = attrs.x1, y1 = attrs.y1, x2 = attrs.x2, y2 = attrs.y2; var minX = Math.min(x1, x2); var maxX = Math.max(x1, x2); var minY = Math.min(y1, y2); var maxY = Math.max(y1, y2); var bbox = { minX: minX, maxX: maxX, minY: minY, maxY: maxY, }; bbox = util_1.mergeArrowBBox(shape, bbox); return { x: bbox.minX, y: bbox.minY, width: bbox.maxX - bbox.minX, height: bbox.maxY - bbox.minY, }; } exports.default = default_1; },{"./util":112}],106:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var quadratic_1 = require("@antv/g-math/lib/quadratic"); var cubic_1 = require("@antv/g-math/lib/cubic"); var arc_1 = require("@antv/g-math/lib/arc"); var path_2_segments_1 = require("@antv/path-util/lib/path-2-segments"); var is_number_equal_1 = require("@antv/util/lib/is-number-equal"); var util_1 = require("./util"); function getPathBox(segments, lineWidth) { var xArr = []; var yArr = []; var segmentsWithAngle = []; for (var i = 0; i < segments.length; i++) { var segment = segments[i]; var currentPoint = segment.currentPoint, params = segment.params, prePoint = segment.prePoint; var box = void 0; switch (segment.command) { case 'Q': box = quadratic_1.default.box(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4]); break; case 'C': box = cubic_1.default.box(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], params[5], params[6]); break; case 'A': var arcParams = segment.arcParams; box = arc_1.default.box(arcParams.cx, arcParams.cy, arcParams.rx, arcParams.ry, arcParams.xRotation, arcParams.startAngle, arcParams.endAngle); break; default: xArr.push(currentPoint[0]); yArr.push(currentPoint[1]); break; } if (box) { segment.box = box; xArr.push(box.x, box.x + box.width); yArr.push(box.y, box.y + box.height); } if (lineWidth && (segment.command === 'L' || segment.command === 'M') && segment.prePoint && segment.nextPoint) { segmentsWithAngle.push(segment); } } // bbox calculation should ignore NaN for path attribute // ref: https://github.com/antvis/g/issues/210 xArr = xArr.filter(function (item) { return !Number.isNaN(item); }); yArr = yArr.filter(function (item) { return !Number.isNaN(item); }); var minX = Math.min.apply(null, xArr); var minY = Math.min.apply(null, yArr); var maxX = Math.max.apply(null, xArr); var maxY = Math.max.apply(null, yArr); if (segmentsWithAngle.length === 0) { return { x: minX, y: minY, width: maxX - minX, height: maxY - minY, }; } for (var i = 0; i < segmentsWithAngle.length; i++) { var segment = segmentsWithAngle[i]; var currentPoint = segment.currentPoint; var extra = void 0; if (currentPoint[0] === minX) { extra = getExtraFromSegmentWithAngle(segment, lineWidth); minX = minX - extra.xExtra; } else if (currentPoint[0] === maxX) { extra = getExtraFromSegmentWithAngle(segment, lineWidth); maxX = maxX + extra.xExtra; } if (currentPoint[1] === minY) { extra = getExtraFromSegmentWithAngle(segment, lineWidth); minY = minY - extra.yExtra; } else if (currentPoint[1] === maxY) { extra = getExtraFromSegmentWithAngle(segment, lineWidth); maxY = maxY + extra.yExtra; } } return { x: minX, y: minY, width: maxX - minX, height: maxY - minY, }; } function getExtraFromSegmentWithAngle(segment, lineWidth) { var prePoint = segment.prePoint, currentPoint = segment.currentPoint, nextPoint = segment.nextPoint; var currentAndPre = Math.pow(currentPoint[0] - prePoint[0], 2) + Math.pow(currentPoint[1] - prePoint[1], 2); var currentAndNext = Math.pow(currentPoint[0] - nextPoint[0], 2) + Math.pow(currentPoint[1] - nextPoint[1], 2); var preAndNext = Math.pow(prePoint[0] - nextPoint[0], 2) + Math.pow(prePoint[1] - nextPoint[1], 2); // 以 currentPoint 为顶点的夹角 var currentAngle = Math.acos((currentAndPre + currentAndNext - preAndNext) / (2 * Math.sqrt(currentAndPre) * Math.sqrt(currentAndNext))); // 夹角为空、 0 或 PI 时,不需要计算夹角处的额外宽度 // 注意: 由于计算精度问题,夹角为 0 的情况计算出来的角度可能是一个很小的值,还需要判断其与 0 是否近似相等 if (!currentAngle || Math.sin(currentAngle) === 0 || is_number_equal_1.default(currentAngle, 0)) { return { xExtra: 0, yExtra: 0, }; } var xAngle = Math.abs(Math.atan2(nextPoint[1] - currentPoint[1], nextPoint[0] - currentPoint[0])); var yAngle = Math.abs(Math.atan2(nextPoint[0] - currentPoint[0], nextPoint[1] - currentPoint[1])); // 将夹角转为锐角 xAngle = xAngle > Math.PI / 2 ? Math.PI - xAngle : xAngle; yAngle = yAngle > Math.PI / 2 ? Math.PI - yAngle : yAngle; // 这里不考虑在水平和垂直方向的投影,直接使用最大差值 // 由于上层统一加减了二分之一线宽,这里需要进行弥补 var extra = { // 水平方向投影 xExtra: Math.cos(currentAngle / 2 - xAngle) * ((lineWidth / 2) * (1 / Math.sin(currentAngle / 2))) - lineWidth / 2 || 0, // 垂直方向投影 yExtra: Math.cos(yAngle - currentAngle / 2) * ((lineWidth / 2) * (1 / Math.sin(currentAngle / 2))) - lineWidth / 2 || 0, }; return extra; } function default_1(shape) { var attrs = shape.attr(); var path = attrs.path, stroke = attrs.stroke; var lineWidth = stroke ? attrs.lineWidth : 0; // 只有有 stroke 时,lineWidth 才生效 var segments = shape.get('segments') || path_2_segments_1.default(path); var _a = getPathBox(segments, lineWidth), x = _a.x, y = _a.y, width = _a.width, height = _a.height; var bbox = { minX: x, minY: y, maxX: x + width, maxY: y + height, }; bbox = util_1.mergeArrowBBox(shape, bbox); return { x: bbox.minX, y: bbox.minY, width: bbox.maxX - bbox.minX, height: bbox.maxY - bbox.minY, }; } exports.default = default_1; },{"./util":112,"@antv/g-math/lib/arc":168,"@antv/g-math/lib/cubic":170,"@antv/g-math/lib/quadratic":174,"@antv/path-util/lib/path-2-segments":731,"@antv/util/lib/is-number-equal":823}],107:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/g-math/lib/util"); function default_1(shape) { var attrs = shape.attr(); var points = attrs.points; var xArr = []; var yArr = []; for (var i = 0; i < points.length; i++) { var point = points[i]; xArr.push(point[0]); yArr.push(point[1]); } return util_1.getBBoxByArray(xArr, yArr); } exports.default = default_1; },{"@antv/g-math/lib/util":176}],108:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/g-math/lib/util"); var util_2 = require("./util"); function default_1(shape) { var attrs = shape.attr(); var points = attrs.points; var xArr = []; var yArr = []; for (var i = 0; i < points.length; i++) { var point = points[i]; xArr.push(point[0]); yArr.push(point[1]); } var _a = util_1.getBBoxByArray(xArr, yArr), x = _a.x, y = _a.y, width = _a.width, height = _a.height; var bbox = { minX: x, minY: y, maxX: x + width, maxY: y + height, }; bbox = util_2.mergeArrowBBox(shape, bbox); return { x: bbox.minX, y: bbox.minY, width: bbox.maxX - bbox.minX, height: bbox.maxY - bbox.minY, }; } exports.default = default_1; },{"./util":112,"@antv/g-math/lib/util":176}],109:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function default_1(shape) { var attrs = shape.attr(); var x = attrs.x, y = attrs.y, width = attrs.width, height = attrs.height; return { x: x, y: y, width: width, height: height, }; } exports.default = default_1; },{}],110:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var cache = new Map(); /** * 注册计算包围盒的算法 * @param type 方法名 * @param method 方法 */ function register(type, method) { cache.set(type, method); } exports.register = register; /** * 获取计算包围盒的算法 * @param type 方法名 */ function getMethod(type) { return cache.get(type); } exports.getMethod = getMethod; },{}],111:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var text_1 = require("../util/text"); function default_1(shape) { var attrs = shape.attr(); var x = attrs.x, y = attrs.y, text = attrs.text, fontSize = attrs.fontSize, lineHeight = attrs.lineHeight; var font = attrs.font; if (!font) { // 如果未组装 font font = text_1.assembleFont(attrs); } var width = text_1.getTextWidth(text, font); var bbox; if (!width) { // 如果width不存在,四点共其实点 bbox = { x: x, y: y, width: 0, height: 0, }; } else { var textAlign = attrs.textAlign, textBaseline = attrs.textBaseline; var height = text_1.getTextHeight(text, fontSize, lineHeight); // attrs.height // 默认左右对齐:left, 默认上下对齐 bottom var point = { x: x, y: y - height, }; if (textAlign) { if (textAlign === 'end' || textAlign === 'right') { point.x -= width; } else if (textAlign === 'center') { point.x -= width / 2; } } if (textBaseline) { if (textBaseline === 'top') { point.y += height; } else if (textBaseline === 'middle') { point.y += height / 2; } } bbox = { x: point.x, y: point.y, width: width, height: height, }; } return bbox; } exports.default = default_1; },{"../util/text":122}],112:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // 合并包围盒 function mergeBBox(bbox1, bbox2) { if (!bbox1 || !bbox2) { return bbox1 || bbox2; } return { minX: Math.min(bbox1.minX, bbox2.minX), minY: Math.min(bbox1.minY, bbox2.minY), maxX: Math.max(bbox1.maxX, bbox2.maxX), maxY: Math.max(bbox1.maxY, bbox2.maxY), }; } exports.mergeBBox = mergeBBox; // 合并箭头的包围盒 function mergeArrowBBox(shape, bbox) { var startArrowShape = shape.get('startArrowShape'); var endArrowShape = shape.get('endArrowShape'); var startArrowBBox = null; var endArrowBBox = null; if (startArrowShape) { startArrowBBox = startArrowShape.getCanvasBBox(); bbox = mergeBBox(bbox, startArrowBBox); } if (endArrowShape) { endArrowBBox = endArrowShape.getCanvasBBox(); bbox = mergeBBox(bbox, endArrowBBox); } return bbox; } exports.mergeArrowBBox = mergeArrowBBox; },{}],113:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @fileoverview 事件处理器 * @author dxq613@gmail.com */ var graph_event_1 = require("./graph-event"); var util_1 = require("../util/util"); var CLICK_OFFSET = 40; var LEFT_BTN_CODE = 0; var DELEGATION_SPLIT = ':'; var EVENTS = [ 'mousedown', 'mouseup', 'dblclick', 'mouseout', 'mouseover', 'mousemove', 'mouseleave', 'mouseenter', 'touchstart', 'touchmove', 'touchend', 'dragenter', 'dragover', 'dragleave', 'drop', 'contextmenu', 'mousewheel', ]; // 是否有委托事件监听 function hasDelegation(events, type) { for (var key in events) { if (events.hasOwnProperty(key) && key.indexOf(DELEGATION_SPLIT + type) >= 0) { return true; } } return false; } // 触发目标事件,目标只能是 shape 或 canvas function emitTargetEvent(target, type, eventObj) { eventObj.name = type; eventObj.target = target; eventObj.currentTarget = target; eventObj.delegateTarget = target; target.emit(type, eventObj); } // 事件冒泡, enter 和 leave 需要对 fromShape 和 toShape 进行判同 function bubbleEvent(container, type, eventObj) { if (eventObj.bubbles) { var relativeShape = void 0; var isOverEvent = false; if (type === 'mouseenter') { relativeShape = eventObj.fromShape; isOverEvent = true; } else if (type === 'mouseleave') { isOverEvent = true; relativeShape = eventObj.toShape; } // canvas 上的 mouseenter, mouseleave 事件,仅当进入或者移出 canvas 时触发 if (container.isCanvas() && isOverEvent) { return; } // 如果相关图形同当前图形在同一个容器内,不触发事件 if (relativeShape && util_1.isParent(container, relativeShape)) { // 阻止继续向上冒泡 eventObj.bubbles = false; return; } // 事件名称可能在委托过程中被修改,因此事件冒泡时需要重新设置事件名称 eventObj.name = type; eventObj.currentTarget = container; eventObj.delegateTarget = container; container.emit(type, eventObj); } } var EventController = /** @class */ (function () { function EventController(cfg) { var _this = this; // 正在被拖拽的图形 this.draggingShape = null; this.dragging = false; // 当前鼠标/touch所在位置的图形 this.currentShape = null; this.mousedownShape = null; this.mousedownPoint = null; // 统一处理所有的回调 this._eventCallback = function (ev) { var type = ev.type; _this._triggerEvent(type, ev); }; // 在 document 处理拖拽到画布外的事件,处理从图形上移除画布未被捕捉的问题 this._onDocumentMove = function (ev) { var canvas = _this.canvas; var el = canvas.get('el'); if (el !== ev.target) { // 不在 canvas 上移动 if (_this.dragging || _this.currentShape) { var pointInfo = _this._getPointInfo(ev); // 还在拖拽过程中 if (_this.dragging) { _this._emitEvent('drag', ev, pointInfo, _this.draggingShape); } // 说明从某个图形直接移动到了画布外面, // 修复了 mouseleave 的 bug 后不再出现这种情况 // if (this.currentShape) { // this._emitEvent('mouseleave', ev, pointInfo, this.currentShape, this.currentShape, null); // this.currentShape = null; // } } } }; // 在 document 上处理拖拽到外面,释放鼠标时触发 dragend this._onDocumentMouseUp = function (ev) { var canvas = _this.canvas; var el = canvas.get('el'); if (el !== ev.target) { // 不在 canvas 上移动 if (_this.dragging) { var pointInfo = _this._getPointInfo(ev); if (_this.draggingShape) { // 如果存在拖拽的图形,则也触发 drop 事件 _this._emitEvent('drop', ev, pointInfo, null); } _this._emitEvent('dragend', ev, pointInfo, _this.draggingShape); _this._afterDrag(_this.draggingShape, pointInfo, ev); } } }; this.canvas = cfg.canvas; } EventController.prototype.init = function () { this._bindEvents(); }; // 注册事件 EventController.prototype._bindEvents = function () { var _this = this; var el = this.canvas.get('el'); util_1.each(EVENTS, function (eventName) { el.addEventListener(eventName, _this._eventCallback); }); if (document) { // 处理移动到外面没有触发 shape mouse leave 的事件 // 处理拖拽到外部的问题 document.addEventListener('mousemove', this._onDocumentMove); // 处理拖拽过程中在外部释放鼠标的问题 document.addEventListener('mouseup', this._onDocumentMouseUp); } }; // 清理事件 EventController.prototype._clearEvents = function () { var _this = this; var el = this.canvas.get('el'); util_1.each(EVENTS, function (eventName) { el.removeEventListener(eventName, _this._eventCallback); }); if (document) { document.removeEventListener('mousemove', this._onDocumentMove); document.removeEventListener('mouseup', this._onDocumentMouseUp); } }; EventController.prototype._getEventObj = function (type, event, point, target, fromShape, toShape) { var eventObj = new graph_event_1.default(type, event); eventObj.fromShape = fromShape; eventObj.toShape = toShape; eventObj.x = point.x; eventObj.y = point.y; eventObj.clientX = point.clientX; eventObj.clientY = point.clientY; eventObj.propagationPath.push(target); // 事件的x,y应该是基于画布左上角的,与canvas的matrix无关 return eventObj; }; // 根据点获取图形,提取成独立方法,便于后续优化 EventController.prototype._getShape = function (point, ev) { return this.canvas.getShape(point.x, point.y, ev); }; // 获取事件的当前点的信息 EventController.prototype._getPointInfo = function (ev) { var canvas = this.canvas; var clientPoint = canvas.getClientByEvent(ev); var point = canvas.getPointByEvent(ev); return { x: point.x, y: point.y, clientX: clientPoint.x, clientY: clientPoint.y, }; }; // 触发事件 EventController.prototype._triggerEvent = function (type, ev) { var pointInfo = this._getPointInfo(ev); // 每次都获取图形有一定成本,后期可以考虑进行缓存策略 var shape = this._getShape(pointInfo, ev); var method = this["_on" + type]; var leaveCanvas = false; if (method) { method.call(this, pointInfo, shape, ev); } else { var preShape = this.currentShape; // 如果进入、移出画布时存在图形,则要分别触发事件 if (type === 'mouseenter' || type === 'dragenter' || type === 'mouseover') { this._emitEvent(type, ev, pointInfo, null, null, shape); // 先进入画布 if (shape) { this._emitEvent(type, ev, pointInfo, shape, null, shape); // 再触发图形的事件 } if (type === 'mouseenter' && this.draggingShape) { // 如果正在拖拽图形, 则触发 dragleave this._emitEvent('dragenter', ev, pointInfo, null); } } else if (type === 'mouseleave' || type === 'dragleave' || type === 'mouseout') { leaveCanvas = true; if (preShape) { this._emitEvent(type, ev, pointInfo, preShape, preShape, null); // 先触发图形的事件 } this._emitEvent(type, ev, pointInfo, null, preShape, null); // 再触发离开画布事件 if (type === 'mouseleave' && this.draggingShape) { this._emitEvent('dragleave', ev, pointInfo, null); } } else { this._emitEvent(type, ev, pointInfo, shape, null, null); // 一般事件中不需要考虑 from, to } } if (!leaveCanvas) { this.currentShape = shape; } // 当鼠标从画布移动到 shape 或者从 preShape 移动到 shape 时,应用 shape 上的鼠标样式 if (shape && !shape.get('destroyed')) { var canvas = this.canvas; var el = canvas.get('el'); el.style.cursor = shape.attr('cursor') || canvas.get('cursor'); } }; // 记录下点击的位置、图形,便于拖拽事件、click 事件的判定 EventController.prototype._onmousedown = function (pointInfo, shape, event) { // 只有鼠标左键的 mousedown 事件才会设置 mousedownShape 等属性,避免鼠标右键的 mousedown 事件引起其他事件发生 if (event.button === LEFT_BTN_CODE) { this.mousedownShape = shape; this.mousedownPoint = pointInfo; this.mousedownTimeStamp = event.timeStamp; } this._emitEvent('mousedown', event, pointInfo, shape, null, null); // mousedown 不考虑fromShape, toShape }; // mouseleave 和 mouseenter 都是成对存在的 // mouseenter 和 mouseover 同时触发 EventController.prototype._emitMouseoverEvents = function (event, pointInfo, fromShape, toShape) { var el = this.canvas.get('el'); if (fromShape !== toShape) { if (fromShape) { this._emitEvent('mouseout', event, pointInfo, fromShape, fromShape, toShape); this._emitEvent('mouseleave', event, pointInfo, fromShape, fromShape, toShape); // 当鼠标从 fromShape 移动到画布上时,重置鼠标样式 if (!toShape || toShape.get('destroyed')) { el.style.cursor = this.canvas.get('cursor'); } } if (toShape) { this._emitEvent('mouseover', event, pointInfo, toShape, fromShape, toShape); this._emitEvent('mouseenter', event, pointInfo, toShape, fromShape, toShape); } } }; // dragover 不等同于 mouseover,而等同于 mousemove EventController.prototype._emitDragoverEvents = function (event, pointInfo, fromShape, toShape, isCanvasEmit) { if (toShape) { if (toShape !== fromShape) { if (fromShape) { this._emitEvent('dragleave', event, pointInfo, fromShape, fromShape, toShape); } this._emitEvent('dragenter', event, pointInfo, toShape, fromShape, toShape); } if (!isCanvasEmit) { this._emitEvent('dragover', event, pointInfo, toShape); } } else if (fromShape) { // TODO: 此处判断有问题,当 drag 图形时,也会触发一次 dragleave 事件,因为此时 toShape 为 null,这不是所期望的 // 经过空白区域 this._emitEvent('dragleave', event, pointInfo, fromShape, fromShape, toShape); } if (isCanvasEmit) { this._emitEvent('dragover', event, pointInfo, toShape); } }; // drag 完成后,需要做一些清理工作 EventController.prototype._afterDrag = function (draggingShape, pointInfo, event) { if (draggingShape) { draggingShape.set('capture', true); // 恢复可以拾取 this.draggingShape = null; } this.dragging = false; // drag 完成后,有可能 draggingShape 已经移动到了当前位置,所以不能直接取当前图形 var shape = this._getShape(pointInfo, event); // 拖拽完成后,进行 enter,leave 的判定 if (shape !== draggingShape) { this._emitMouseoverEvents(event, pointInfo, draggingShape, shape); } this.currentShape = shape; // 更新当前 shape,如果不处理当前图形的 mouseleave 事件可能会出问题 }; // 按键抬起时,会终止拖拽、触发点击 EventController.prototype._onmouseup = function (pointInfo, shape, event) { // eevent.button === 0 表示鼠标左键事件,此处加上判断主要是为了避免右键鼠标会触发 mouseup 和 click 事件 // ref: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button if (event.button === LEFT_BTN_CODE) { var draggingShape = this.draggingShape; if (this.dragging) { // 存在可以拖拽的图形,同时拖拽到其他图形上时触发 drag 事件 if (draggingShape) { this._emitEvent('drop', event, pointInfo, shape); } this._emitEvent('dragend', event, pointInfo, draggingShape); this._afterDrag(draggingShape, pointInfo, event); } else { this._emitEvent('mouseup', event, pointInfo, shape); // 先触发 mouseup 再触发 click if (shape === this.mousedownShape) { this._emitEvent('click', event, pointInfo, shape); } this.mousedownShape = null; this.mousedownPoint = null; } } }; // 当触发浏览器的 dragover 事件时,不会再触发 mousemove ,所以这时候的 dragenter, dragleave 事件需要重新处理 EventController.prototype._ondragover = function (pointInfo, shape, event) { event.preventDefault(); // 如果不对 dragover 进行 preventDefault,则不会在 canvas 上触发 drop 事件 var preShape = this.currentShape; this._emitDragoverEvents(event, pointInfo, preShape, shape, true); }; // 大量的图形事件,都通过 mousemove 模拟 EventController.prototype._onmousemove = function (pointInfo, shape, event) { var canvas = this.canvas; var preShape = this.currentShape; var draggingShape = this.draggingShape; // 正在拖拽时 if (this.dragging) { // 正在拖拽中 if (draggingShape) { // 如果拖拽了 shape 会触发 dragenter, dragleave, dragover 和 drag 事件 this._emitDragoverEvents(event, pointInfo, preShape, shape, false); } // 如果存在 draggingShape 则会在 draggingShape 上触发 drag 事件,冒泡到 canvas 上 // 否则在 canvas 上触发 drag 事件 this._emitEvent('drag', event, pointInfo, draggingShape); } else { var mousedownPoint = this.mousedownPoint; if (mousedownPoint) { // 当鼠标点击下去,同时移动时,进行 drag 判定 var mousedownShape = this.mousedownShape; var now = event.timeStamp; var timeWindow = now - this.mousedownTimeStamp; var dx = mousedownPoint.clientX - pointInfo.clientX; var dy = mousedownPoint.clientY - pointInfo.clientY; var dist = dx * dx + dy * dy; if (timeWindow > 120 || dist > CLICK_OFFSET) { if (mousedownShape && mousedownShape.get('draggable')) { // 设置了 draggable 的 shape 才能触发 drag 相关的事件 draggingShape = this.mousedownShape; // 拖动鼠标点下时的 shape draggingShape.set('capture', false); // 禁止继续拾取,否则无法进行 dragover,dragenter,dragleave,drop的判定 this.draggingShape = draggingShape; this.dragging = true; this._emitEvent('dragstart', event, pointInfo, draggingShape); // 清理按下鼠标时缓存的值 this.mousedownShape = null; this.mousedownPoint = null; } else if (!mousedownShape && canvas.get('draggable')) { // 设置了 draggable 的 canvas 才能触发 drag 相关的事件 this.dragging = true; this._emitEvent('dragstart', event, pointInfo, null); // 清理按下鼠标时缓存的值 this.mousedownShape = null; this.mousedownPoint = null; } else { this._emitMouseoverEvents(event, pointInfo, preShape, shape); this._emitEvent('mousemove', event, pointInfo, shape); } } else { this._emitMouseoverEvents(event, pointInfo, preShape, shape); this._emitEvent('mousemove', event, pointInfo, shape); } } else { // 没有按键按下时,则直接触发 mouse over 相关的各种事件 this._emitMouseoverEvents(event, pointInfo, preShape, shape); // 始终触发移动 this._emitEvent('mousemove', event, pointInfo, shape); } } }; // 触发事件 EventController.prototype._emitEvent = function (type, event, pointInfo, shape, fromShape, toShape) { var eventObj = this._getEventObj(type, event, pointInfo, shape, fromShape, toShape); // 存在 shape 触发,则进行冒泡处理 if (shape) { eventObj.shape = shape; // 触发 shape 上的事件 emitTargetEvent(shape, type, eventObj); var parent_1 = shape.getParent(); // 执行冒泡 while (parent_1) { // 委托事件要先触发 parent_1.emitDelegation(type, eventObj); // 事件冒泡停止,不能妨碍委托事件 if (!eventObj.propagationStopped) { bubbleEvent(parent_1, type, eventObj); } eventObj.propagationPath.push(parent_1); parent_1 = parent_1.getParent(); } } else { // 如果没有 shape 直接在 canvas 上触发 var canvas = this.canvas; // 直接触发 canvas 上的事件 emitTargetEvent(canvas, type, eventObj); } }; EventController.prototype.destroy = function () { // 清理事件 this._clearEvents(); // 清理缓存的对象 this.canvas = null; this.currentShape = null; this.draggingShape = null; this.mousedownPoint = null; this.mousedownShape = null; this.mousedownTimeStamp = null; }; return EventController; }()); exports.default = EventController; },{"../util/util":123,"./graph-event":114}],114:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var GraphEvent = /** @class */ (function () { function GraphEvent(type, event) { /** * 是否允许冒泡 * @type {boolean} */ this.bubbles = true; /** * 触发对象 * @type {object} */ this.target = null; /** * 监听对象 * @type {object} */ this.currentTarget = null; /** * 委托对象 * @type {object} */ this.delegateTarget = null; /** * 委托事件监听对象的代理对象,即 ev.delegateObject = ev.currentTarget.get('delegateObject') * @type {object} */ this.delegateObject = null; /** * 是否阻止了原生事件 * @type {boolean} */ this.defaultPrevented = false; /** * 是否阻止传播(向上冒泡) * @type {boolean} */ this.propagationStopped = false; /** * 触发事件的图形 * @type {IShape} */ this.shape = null; /** * 开始触发事件的图形 * @type {IShape} */ this.fromShape = null; /** * 事件结束时的触发图形 * @type {IShape} */ this.toShape = null; // 触发事件的路径 this.propagationPath = []; this.type = type; this.name = type; this.originalEvent = event; this.timeStamp = event.timeStamp; } /** * 阻止浏览器默认的行为 */ GraphEvent.prototype.preventDefault = function () { this.defaultPrevented = true; if (this.originalEvent.preventDefault) { this.originalEvent.preventDefault(); } }; /** * 阻止冒泡 */ GraphEvent.prototype.stopPropagation = function () { this.propagationStopped = true; }; GraphEvent.prototype.toString = function () { var type = this.type; return "[Event (type=" + type + ")]"; }; GraphEvent.prototype.save = function () { }; GraphEvent.prototype.restore = function () { }; return GraphEvent; }()); exports.default = GraphEvent; },{}],115:[function(require,module,exports){ "use strict"; /** * @fileoverview G 的基础接口定义和所有的抽象类 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var PathUtil = require("./util/path"); exports.PathUtil = PathUtil; var pkg = require('../package.json'); exports.version = pkg.version; var graph_event_1 = require("./event/graph-event"); exports.Event = graph_event_1.default; var base_1 = require("./abstract/base"); exports.Base = base_1.default; var canvas_1 = require("./abstract/canvas"); exports.AbstractCanvas = canvas_1.default; var group_1 = require("./abstract/group"); exports.AbstractGroup = group_1.default; var shape_1 = require("./abstract/shape"); exports.AbstractShape = shape_1.default; },{"../package.json":124,"./abstract/base":95,"./abstract/canvas":96,"./abstract/group":99,"./abstract/shape":100,"./event/graph-event":114,"./util/path":121}],116:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); },{}],117:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); },{}],118:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isColorProp = function (prop) { return ['fill', 'stroke', 'fillStyle', 'strokeStyle'].includes(prop); }; exports.isGradientColor = function (val) { return /^[r,R,L,l]{1}[\s]*\(/.test(val); }; },{}],119:[function(require,module,exports){ "use strict"; /** * @fileoverview 矩阵运算,本来是要引入 gl-matrix, 但是考虑到 g-mobile 对大小有限制,同时 g-webgl 使用的 matrix 不一致 * 所以,这里仅实现 2D 几个运算,上层自己引入 gl-matrix * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); /** * 3阶矩阵相乘 * @param {number[]} a 矩阵1 * @param {number[]} b 矩阵2 */ function multiplyMatrix(a, b) { var out = []; var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a10 = a[3]; var a11 = a[4]; var a12 = a[5]; var a20 = a[6]; var a21 = a[7]; var a22 = a[8]; var b00 = b[0]; var b01 = b[1]; var b02 = b[2]; var b10 = b[3]; var b11 = b[4]; var b12 = b[5]; var b20 = b[6]; var b21 = b[7]; var b22 = b[8]; out[0] = b00 * a00 + b01 * a10 + b02 * a20; out[1] = b00 * a01 + b01 * a11 + b02 * a21; out[2] = b00 * a02 + b01 * a12 + b02 * a22; out[3] = b10 * a00 + b11 * a10 + b12 * a20; out[4] = b10 * a01 + b11 * a11 + b12 * a21; out[5] = b10 * a02 + b11 * a12 + b12 * a22; out[6] = b20 * a00 + b21 * a10 + b22 * a20; out[7] = b20 * a01 + b21 * a11 + b22 * a21; out[8] = b20 * a02 + b21 * a12 + b22 * a22; return out; } exports.multiplyMatrix = multiplyMatrix; /** * 3阶矩阵同2阶向量相乘 * @param {number[]} m 矩阵 * @param {number[]} v 二阶向量 */ function multiplyVec2(m, v) { var out = []; var x = v[0]; var y = v[1]; out[0] = m[0] * x + m[3] * y + m[6]; out[1] = m[1] * x + m[4] * y + m[7]; return out; } exports.multiplyVec2 = multiplyVec2; /** * 矩阵的逆 * @param {number[]} a 矩阵 */ function invert(a) { var out = []; var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a10 = a[3]; var a11 = a[4]; var a12 = a[5]; var a20 = a[6]; var a21 = a[7]; var a22 = a[8]; var b01 = a22 * a11 - a12 * a21; var b11 = -a22 * a10 + a12 * a20; var b21 = a21 * a10 - a11 * a20; // Calculate the determinant var det = a00 * b01 + a01 * b11 + a02 * b21; if (!det) { return null; } det = 1.0 / det; out[0] = b01 * det; out[1] = (-a22 * a01 + a02 * a21) * det; out[2] = (a12 * a01 - a02 * a11) * det; out[3] = b11 * det; out[4] = (a22 * a00 - a02 * a20) * det; out[5] = (-a12 * a00 + a02 * a10) * det; out[6] = b21 * det; out[7] = (-a21 * a00 + a01 * a20) * det; out[8] = (a11 * a00 - a01 * a10) * det; return out; } exports.invert = invert; },{}],120:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // 全局设置一个唯一离屏的 ctx,用于计算 isPointInPath var offScreenCtx = null; function getOffScreenContext() { if (!offScreenCtx) { var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; offScreenCtx = canvas.getContext('2d'); } return offScreenCtx; } exports.getOffScreenContext = getOffScreenContext; },{}],121:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var SPACES = '\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029'; var PATH_COMMAND = new RegExp("([a-z])[" + SPACES + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + SPACES + "]*,?[" + SPACES + "]*)+)", 'ig'); var PATH_VALUES = new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + SPACES + "]*,?[" + SPACES + "]*", 'ig'); // Parse given path string into an array of arrays of path segments var parsePathString = function (pathString) { if (!pathString) { return null; } if (util_1.isArray(pathString)) { return pathString; } var paramCounts = { a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0, }; var data = []; String(pathString).replace(PATH_COMMAND, function (a, b, c) { var params = []; var name = b.toLowerCase(); c.replace(PATH_VALUES, function (a, b) { b && params.push(+b); }); if (name === 'm' && params.length > 2) { data.push([b].concat(params.splice(0, 2))); name = 'l'; b = b === 'm' ? 'l' : 'L'; } if (name === 'o' && params.length === 1) { data.push([b, params[0]]); } if (name === 'r') { data.push([b].concat(params)); } else { while (params.length >= paramCounts[name]) { data.push([b].concat(params.splice(0, paramCounts[name]))); if (!paramCounts[name]) { break; } } } return pathString; }); return data; }; exports.parsePathString = parsePathString; // http://schepers.cc/getting-to-the-point var catmullRomToBezier = function (crp, z) { var d = []; // @ts-ignore for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { var p = [ { x: +crp[i - 2], y: +crp[i - 1], }, { x: +crp[i], y: +crp[i + 1], }, { x: +crp[i + 2], y: +crp[i + 3], }, { x: +crp[i + 4], y: +crp[i + 5], }, ]; if (z) { if (!i) { p[0] = { x: +crp[iLen - 2], y: +crp[iLen - 1], }; } else if (iLen - 4 === i) { p[3] = { x: +crp[0], y: +crp[1], }; } else if (iLen - 2 === i) { p[2] = { x: +crp[0], y: +crp[1], }; p[3] = { x: +crp[2], y: +crp[3], }; } } else { if (iLen - 4 === i) { p[3] = p[2]; } else if (!i) { p[0] = { x: +crp[i], y: +crp[i + 1], }; } } d.push([ 'C', (-p[0].x + 6 * p[1].x + p[2].x) / 6, (-p[0].y + 6 * p[1].y + p[2].y) / 6, (p[1].x + 6 * p[2].x - p[3].x) / 6, (p[1].y + 6 * p[2].y - p[3].y) / 6, p[2].x, p[2].y, ]); } return d; }; exports.catmullRomToBezier = catmullRomToBezier; var ellipsePath = function (x, y, rx, ry, a) { var res = []; if (a === null && ry === null) { ry = rx; } x = +x; y = +y; rx = +rx; ry = +ry; if (a !== null) { var rad = Math.PI / 180; var x1 = x + rx * Math.cos(-ry * rad); var x2 = x + rx * Math.cos(-a * rad); var y1 = y + rx * Math.sin(-ry * rad); var y2 = y + rx * Math.sin(-a * rad); res = [ ['M', x1, y1], ['A', rx, rx, 0, +(a - ry > 180), 0, x2, y2], ]; } else { res = [['M', x, y], ['m', 0, -ry], ['a', rx, ry, 0, 1, 1, 0, 2 * ry], ['a', rx, ry, 0, 1, 1, 0, -2 * ry], ['z']]; } return res; }; var pathToAbsolute = function (pathArray) { pathArray = parsePathString(pathArray); if (!pathArray || !pathArray.length) { return [['M', 0, 0]]; } var res = []; var x = 0; var y = 0; var mx = 0; var my = 0; var start = 0; var pa0; var dots; if (pathArray[0][0] === 'M') { x = +pathArray[0][1]; y = +pathArray[0][2]; mx = x; my = y; start++; res[0] = ['M', x, y]; } var crz = pathArray.length === 3 && pathArray[0][0] === 'M' && pathArray[1][0].toUpperCase() === 'R' && pathArray[2][0].toUpperCase() === 'Z'; for (var r = void 0, pa = void 0, i = start, ii = pathArray.length; i < ii; i++) { res.push((r = [])); pa = pathArray[i]; pa0 = pa[0]; if (pa0 !== pa0.toUpperCase()) { r[0] = pa0.toUpperCase(); switch (r[0]) { case 'A': r[1] = pa[1]; r[2] = pa[2]; r[3] = pa[3]; r[4] = pa[4]; r[5] = pa[5]; r[6] = +pa[6] + x; r[7] = +pa[7] + y; break; case 'V': r[1] = +pa[1] + y; break; case 'H': r[1] = +pa[1] + x; break; case 'R': dots = [x, y].concat(pa.slice(1)); for (var j = 2, jj = dots.length; j < jj; j++) { dots[j] = +dots[j] + x; dots[++j] = +dots[j] + y; } res.pop(); res = res.concat(catmullRomToBezier(dots, crz)); break; case 'O': res.pop(); dots = ellipsePath(x, y, pa[1], pa[2]); dots.push(dots[0]); res = res.concat(dots); break; case 'U': res.pop(); res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); r = ['U'].concat(res[res.length - 1].slice(-2)); break; case 'M': mx = +pa[1] + x; my = +pa[2] + y; break; // for lint default: for (var j = 1, jj = pa.length; j < jj; j++) { r[j] = +pa[j] + (j % 2 ? x : y); } } } else if (pa0 === 'R') { dots = [x, y].concat(pa.slice(1)); res.pop(); res = res.concat(catmullRomToBezier(dots, crz)); r = ['R'].concat(pa.slice(-2)); } else if (pa0 === 'O') { res.pop(); dots = ellipsePath(x, y, pa[1], pa[2]); dots.push(dots[0]); res = res.concat(dots); } else if (pa0 === 'U') { res.pop(); res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); r = ['U'].concat(res[res.length - 1].slice(-2)); } else { for (var k = 0, kk = pa.length; k < kk; k++) { r[k] = pa[k]; } } pa0 = pa0.toUpperCase(); if (pa0 !== 'O') { switch (r[0]) { case 'Z': x = +mx; y = +my; break; case 'H': x = r[1]; break; case 'V': y = r[1]; break; case 'M': mx = r[r.length - 2]; my = r[r.length - 1]; break; // for lint default: x = r[r.length - 2]; y = r[r.length - 1]; } } } return res; }; exports.pathToAbsolute = pathToAbsolute; var l2c = function (x1, y1, x2, y2) { return [x1, y1, x2, y2, x2, y2]; }; var q2c = function (x1, y1, ax, ay, x2, y2) { var _13 = 1 / 3; var _23 = 2 / 3; return [_13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2]; }; var a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { // for more information of where this math came from visit: // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes if (rx === ry) { rx += 1; } var _120 = (Math.PI * 120) / 180; var rad = (Math.PI / 180) * (+angle || 0); var res = []; var xy; var f1; var f2; var cx; var cy; var rotate = function (x, y, rad) { var X = x * Math.cos(rad) - y * Math.sin(rad); var Y = x * Math.sin(rad) + y * Math.cos(rad); return { x: X, y: Y, }; }; if (!recursive) { xy = rotate(x1, y1, -rad); x1 = xy.x; y1 = xy.y; xy = rotate(x2, y2, -rad); x2 = xy.x; y2 = xy.y; if (x1 === x2 && y1 === y2) { // 若弧的起始点和终点重叠则错开一点 x2 += 1; y2 += 1; } // const cos = Math.cos(Math.PI / 180 * angle); // const sin = Math.sin(Math.PI / 180 * angle); var x = (x1 - x2) / 2; var y = (y1 - y2) / 2; var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); if (h > 1) { h = Math.sqrt(h); rx = h * rx; ry = h * ry; } var rx2 = rx * rx; var ry2 = ry * ry; var k = (large_arc_flag === sweep_flag ? -1 : 1) * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))); cx = (k * rx * y) / ry + (x1 + x2) / 2; cy = (k * -ry * x) / rx + (y1 + y2) / 2; // @ts-ignore f1 = Math.asin(((y1 - cy) / ry).toFixed(9)); // @ts-ignore f2 = Math.asin(((y2 - cy) / ry).toFixed(9)); f1 = x1 < cx ? Math.PI - f1 : f1; f2 = x2 < cx ? Math.PI - f2 : f2; f1 < 0 && (f1 = Math.PI * 2 + f1); f2 < 0 && (f2 = Math.PI * 2 + f2); if (sweep_flag && f1 > f2) { f1 = f1 - Math.PI * 2; } if (!sweep_flag && f2 > f1) { f2 = f2 - Math.PI * 2; } } else { f1 = recursive[0]; f2 = recursive[1]; cx = recursive[2]; cy = recursive[3]; } var df = f2 - f1; if (Math.abs(df) > _120) { var f2old = f2; var x2old = x2; var y2old = y2; f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); x2 = cx + rx * Math.cos(f2); y2 = cy + ry * Math.sin(f2); res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); } df = f2 - f1; var c1 = Math.cos(f1); var s1 = Math.sin(f1); var c2 = Math.cos(f2); var s2 = Math.sin(f2); var t = Math.tan(df / 4); var hx = (4 / 3) * rx * t; var hy = (4 / 3) * ry * t; var m1 = [x1, y1]; var m2 = [x1 + hx * s1, y1 - hy * c1]; var m3 = [x2 + hx * s2, y2 - hy * c2]; var m4 = [x2, y2]; m2[0] = 2 * m1[0] - m2[0]; m2[1] = 2 * m1[1] - m2[1]; if (recursive) { return [m2, m3, m4].concat(res); } res = [m2, m3, m4] .concat(res) .join() .split(','); var newres = []; for (var i = 0, ii = res.length; i < ii; i++) { newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; } return newres; }; var pathToCurve = function (path, path2) { var p = pathToAbsolute(path); var p2 = path2 && pathToAbsolute(path2); var attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null, }; var attrs2 = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null, }; var pcoms1 = []; // path commands of original path p var pcoms2 = []; // path commands of original path p2 var pfirst = ''; // temporary holder for original path command var pcom = ''; // holder for previous path command of original path var ii; var processPath = function (path, d, pcom) { var nx; var ny; if (!path) { return ['C', d.x, d.y, d.x, d.y, d.x, d.y]; } !(path[0] in { T: 1, Q: 1, }) && (d.qx = d.qy = null); switch (path[0]) { case 'M': d.X = path[1]; d.Y = path[2]; break; case 'A': path = ['C'].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1)))); break; case 'S': if (pcom === 'C' || pcom === 'S') { // In "S" case we have to take into account, if the previous command is C/S. nx = d.x * 2 - d.bx; // And reflect the previous ny = d.y * 2 - d.by; // command's control point relative to the current point. } else { // or some else or nothing nx = d.x; ny = d.y; } path = ['C', nx, ny].concat(path.slice(1)); break; case 'T': if (pcom === 'Q' || pcom === 'T') { // In "T" case we have to take into account, if the previous command is Q/T. d.qx = d.x * 2 - d.qx; // And make a reflection similar d.qy = d.y * 2 - d.qy; // to case "S". } else { // or something else or nothing d.qx = d.x; d.qy = d.y; } path = ['C'].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); break; case 'Q': d.qx = path[1]; d.qy = path[2]; path = ['C'].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4])); break; case 'L': path = ['C'].concat(l2c(d.x, d.y, path[1], path[2])); break; case 'H': path = ['C'].concat(l2c(d.x, d.y, path[1], d.y)); break; case 'V': path = ['C'].concat(l2c(d.x, d.y, d.x, path[1])); break; case 'Z': path = ['C'].concat(l2c(d.x, d.y, d.X, d.Y)); break; default: break; } return path; }; var fixArc = function (pp, i) { if (pp[i].length > 7) { pp[i].shift(); var pi = pp[i]; while (pi.length) { pcoms1[i] = 'A'; // if created multiple C:s, their original seg is saved p2 && (pcoms2[i] = 'A'); // the same as above pp.splice(i++, 0, ['C'].concat(pi.splice(0, 6))); } pp.splice(i, 1); ii = Math.max(p.length, (p2 && p2.length) || 0); } }; var fixM = function (path1, path2, a1, a2, i) { if (path1 && path2 && path1[i][0] === 'M' && path2[i][0] !== 'M') { path2.splice(i, 0, ['M', a2.x, a2.y]); a1.bx = 0; a1.by = 0; a1.x = path1[i][1]; a1.y = path1[i][2]; ii = Math.max(p.length, (p2 && p2.length) || 0); } }; ii = Math.max(p.length, (p2 && p2.length) || 0); for (var i = 0; i < ii; i++) { p[i] && (pfirst = p[i][0]); // save current path command if (pfirst !== 'C') { // C is not saved yet, because it may be result of conversion pcoms1[i] = pfirst; // Save current path command i && (pcom = pcoms1[i - 1]); // Get previous path command pcom } p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath if (pcoms1[i] !== 'A' && pfirst === 'C') pcoms1[i] = 'C'; // A is the only command // which may produce multiple C:s // so we have to make sure that C is also C in original path fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1 if (p2) { // the same procedures is done to p2 p2[i] && (pfirst = p2[i][0]); if (pfirst !== 'C') { pcoms2[i] = pfirst; i && (pcom = pcoms2[i - 1]); } p2[i] = processPath(p2[i], attrs2, pcom); if (pcoms2[i] !== 'A' && pfirst === 'C') { pcoms2[i] = 'C'; } fixArc(p2, i); } fixM(p, p2, attrs, attrs2, i); fixM(p2, p, attrs2, attrs, i); var seg = p[i]; var seg2 = p2 && p2[i]; var seglen = seg.length; var seg2len = p2 && seg2.length; attrs.x = seg[seglen - 2]; attrs.y = seg[seglen - 1]; attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x; attrs.by = parseFloat(seg[seglen - 3]) || attrs.y; attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x); attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y); attrs2.x = p2 && seg2[seg2len - 2]; attrs2.y = p2 && seg2[seg2len - 1]; } return p2 ? [p, p2] : p; }; exports.pathToCurve = pathToCurve; var p2s = /,?([a-z]),?/gi; var parsePathArray = function (path) { return path.join(',').replace(p2s, '$1'); }; exports.parsePathArray = parsePathArray; var base3 = function (t, p1, p2, p3, p4) { var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4; var t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; return t * t2 - 3 * p1 + 3 * p2; }; var bezlen = function (x1, y1, x2, y2, x3, y3, x4, y4, z) { if (z === null) { z = 1; } z = z > 1 ? 1 : z < 0 ? 0 : z; var z2 = z / 2; var n = 12; var Tvalues = [ -0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816, 0.9816, ]; var Cvalues = [0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472]; var sum = 0; for (var i = 0; i < n; i++) { var ct = z2 * Tvalues[i] + z2; var xbase = base3(ct, x1, x2, x3, x4); var ybase = base3(ct, y1, y2, y3, y4); var comb = xbase * xbase + ybase * ybase; sum += Cvalues[i] * Math.sqrt(comb); } return z2 * sum; }; var curveDim = function (x0, y0, x1, y1, x2, y2, x3, y3) { var tvalues = []; var bounds = [[], []]; var a; var b; var c; var t; for (var i = 0; i < 2; ++i) { if (i === 0) { b = 6 * x0 - 12 * x1 + 6 * x2; a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; c = 3 * x1 - 3 * x0; } else { b = 6 * y0 - 12 * y1 + 6 * y2; a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; c = 3 * y1 - 3 * y0; } if (Math.abs(a) < 1e-12) { if (Math.abs(b) < 1e-12) { continue; } t = -c / b; if (t > 0 && t < 1) { tvalues.push(t); } continue; } var b2ac = b * b - 4 * c * a; var sqrtb2ac = Math.sqrt(b2ac); if (b2ac < 0) { continue; } var t1 = (-b + sqrtb2ac) / (2 * a); if (t1 > 0 && t1 < 1) { tvalues.push(t1); } var t2 = (-b - sqrtb2ac) / (2 * a); if (t2 > 0 && t2 < 1) { tvalues.push(t2); } } var j = tvalues.length; var jlen = j; var mt; while (j--) { t = tvalues[j]; mt = 1 - t; bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; } bounds[0][jlen] = x0; bounds[1][jlen] = y0; bounds[0][jlen + 1] = x3; bounds[1][jlen + 1] = y3; bounds[0].length = bounds[1].length = jlen + 2; return { min: { x: Math.min.apply(0, bounds[0]), y: Math.min.apply(0, bounds[1]), }, max: { x: Math.max.apply(0, bounds[0]), y: Math.max.apply(0, bounds[1]), }, }; }; var intersect = function (x1, y1, x2, y2, x3, y3, x4, y4) { if (Math.max(x1, x2) < Math.min(x3, x4) || Math.min(x1, x2) > Math.max(x3, x4) || Math.max(y1, y2) < Math.min(y3, y4) || Math.min(y1, y2) > Math.max(y3, y4)) { return; } var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4); var ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4); var denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (!denominator) { return; } var px = nx / denominator; var py = ny / denominator; var px2 = +px.toFixed(2); var py2 = +py.toFixed(2); if (px2 < +Math.min(x1, x2).toFixed(2) || px2 > +Math.max(x1, x2).toFixed(2) || px2 < +Math.min(x3, x4).toFixed(2) || px2 > +Math.max(x3, x4).toFixed(2) || py2 < +Math.min(y1, y2).toFixed(2) || py2 > +Math.max(y1, y2).toFixed(2) || py2 < +Math.min(y3, y4).toFixed(2) || py2 > +Math.max(y3, y4).toFixed(2)) { return; } return { x: px, y: py, }; }; var isPointInsideBBox = function (bbox, x, y) { return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; }; var rectPath = function (x, y, w, h, r) { if (r) { return [ ['M', +x + +r, y], ['l', w - r * 2, 0], ['a', r, r, 0, 0, 1, r, r], ['l', 0, h - r * 2], ['a', r, r, 0, 0, 1, -r, r], ['l', r * 2 - w, 0], ['a', r, r, 0, 0, 1, -r, -r], ['l', 0, r * 2 - h], ['a', r, r, 0, 0, 1, r, -r], ['z'], ]; } var res = [['M', x, y], ['l', w, 0], ['l', 0, h], ['l', -w, 0], ['z']]; // @ts-ignore res.parsePathArray = parsePathArray; return res; }; exports.rectPath = rectPath; var box = function (x, y, width, height) { if (x === null) { x = y = width = height = 0; } if (y === null) { y = x.y; width = x.width; height = x.height; x = x.x; } return { x: x, y: y, width: width, w: width, height: height, h: height, x2: x + width, y2: y + height, cx: x + width / 2, cy: y + height / 2, r1: Math.min(width, height) / 2, r2: Math.max(width, height) / 2, r0: Math.sqrt(width * width + height * height) / 2, path: rectPath(x, y, width, height), vb: [x, y, width, height].join(' '), }; }; var isBBoxIntersect = function (bbox1, bbox2) { bbox1 = box(bbox1); bbox2 = box(bbox2); return (isPointInsideBBox(bbox2, bbox1.x, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) || (((bbox1.x < bbox2.x2 && bbox1.x > bbox2.x) || (bbox2.x < bbox1.x2 && bbox2.x > bbox1.x)) && ((bbox1.y < bbox2.y2 && bbox1.y > bbox2.y) || (bbox2.y < bbox1.y2 && bbox2.y > bbox1.y)))); }; var bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { if (!util_1.isArray(p1x)) { p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]; } var bbox = curveDim.apply(null, p1x); return box(bbox.min.x, bbox.min.y, bbox.max.x - bbox.min.x, bbox.max.y - bbox.min.y); }; var findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { var t1 = 1 - t; var t13 = Math.pow(t1, 3); var t12 = Math.pow(t1, 2); var t2 = t * t; var t3 = t2 * t; var x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x; var y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y; var mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x); var my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y); var nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x); var ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y); var ax = t1 * p1x + t * c1x; var ay = t1 * p1y + t * c1y; var cx = t1 * c2x + t * p2x; var cy = t1 * c2y + t * p2y; var alpha = 90 - (Math.atan2(mx - nx, my - ny) * 180) / Math.PI; // (mx > nx || my < ny) && (alpha += 180); return { x: x, y: y, m: { x: mx, y: my, }, n: { x: nx, y: ny, }, start: { x: ax, y: ay, }, end: { x: cx, y: cy, }, alpha: alpha, }; }; var interHelper = function (bez1, bez2, justCount) { var bbox1 = bezierBBox(bez1); var bbox2 = bezierBBox(bez2); if (!isBBoxIntersect(bbox1, bbox2)) { return justCount ? 0 : []; } var l1 = bezlen.apply(0, bez1); var l2 = bezlen.apply(0, bez2); var n1 = ~~(l1 / 8); var n2 = ~~(l2 / 8); var dots1 = []; var dots2 = []; var xy = {}; var res = justCount ? 0 : []; for (var i = 0; i < n1 + 1; i++) { var d = findDotsAtSegment.apply(0, bez1.concat(i / n1)); dots1.push({ x: d.x, y: d.y, t: i / n1, }); } for (var i = 0; i < n2 + 1; i++) { var d = findDotsAtSegment.apply(0, bez2.concat(i / n2)); dots2.push({ x: d.x, y: d.y, t: i / n2, }); } for (var i = 0; i < n1; i++) { for (var j = 0; j < n2; j++) { var di = dots1[i]; var di1 = dots1[i + 1]; var dj = dots2[j]; var dj1 = dots2[j + 1]; var ci = Math.abs(di1.x - di.x) < 0.001 ? 'y' : 'x'; var cj = Math.abs(dj1.x - dj.x) < 0.001 ? 'y' : 'x'; var is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y); if (is) { if (xy[is.x.toFixed(4)] === is.y.toFixed(4)) { continue; } xy[is.x.toFixed(4)] = is.y.toFixed(4); var t1 = di.t + Math.abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t); var t2 = dj.t + Math.abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { if (justCount) { // @ts-ignore res += 1; } else { // @ts-ignore res.push({ x: is.x, y: is.y, t1: t1, t2: t2, }); } } } } } return res; }; var interPathHelper = function (path1, path2, justCount) { path1 = pathToCurve(path1); path2 = pathToCurve(path2); var x1; var y1; var x2; var y2; var x1m; var y1m; var x2m; var y2m; var bez1; var bez2; var res = justCount ? 0 : []; for (var i = 0, ii = path1.length; i < ii; i++) { var pi = path1[i]; if (pi[0] === 'M') { x1 = x1m = pi[1]; y1 = y1m = pi[2]; } else { if (pi[0] === 'C') { bez1 = [x1, y1].concat(pi.slice(1)); x1 = bez1[6]; y1 = bez1[7]; } else { bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; x1 = x1m; y1 = y1m; } for (var j = 0, jj = path2.length; j < jj; j++) { var pj = path2[j]; if (pj[0] === 'M') { x2 = x2m = pj[1]; y2 = y2m = pj[2]; } else { if (pj[0] === 'C') { bez2 = [x2, y2].concat(pj.slice(1)); x2 = bez2[6]; y2 = bez2[7]; } else { bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; x2 = x2m; y2 = y2m; } var intr = interHelper(bez1, bez2, justCount); if (justCount) { // @ts-ignore res += intr; } else { // @ts-ignore for (var k = 0, kk = intr.length; k < kk; k++) { intr[k].segment1 = i; intr[k].segment2 = j; intr[k].bez1 = bez1; intr[k].bez2 = bez2; } // @ts-ignore res = res.concat(intr); } } } } } return res; }; var intersection = function (path1, path2) { return interPathHelper(path1, path2); }; exports.intersection = intersection; function decasteljau(points, t) { var left = []; var right = []; function recurse(points, t) { if (points.length === 1) { left.push(points[0]); right.push(points[0]); } else { var middlePoints = []; for (var i = 0; i < points.length - 1; i++) { if (i === 0) { left.push(points[0]); } if (i === points.length - 2) { right.push(points[i + 1]); } middlePoints[i] = [ (1 - t) * points[i][0] + t * points[i + 1][0], (1 - t) * points[i][1] + t * points[i + 1][1], ]; } recurse(middlePoints, t); } } if (points.length) { recurse(points, t); } return { left: left, right: right.reverse() }; } function splitCurve(start, end, count) { var points = [[start[1], start[2]]]; count = count || 2; var segments = []; if (end[0] === 'A') { points.push(end[6]); points.push(end[7]); } else if (end[0] === 'C') { points.push([end[1], end[2]]); points.push([end[3], end[4]]); points.push([end[5], end[6]]); } else if (end[0] === 'S' || end[0] === 'Q') { points.push([end[1], end[2]]); points.push([end[3], end[4]]); } else { points.push([end[1], end[2]]); } var leftSegments = points; var t = 1 / count; for (var i = 0; i < count - 1; i++) { var rt = t / (1 - t * i); var split = decasteljau(leftSegments, rt); segments.push(split.left); leftSegments = split.right; } segments.push(leftSegments); var result = segments.map(function (segment) { var cmd = []; if (segment.length === 4) { cmd.push('C'); cmd = cmd.concat(segment[2]); } if (segment.length >= 3) { if (segment.length === 3) { cmd.push('Q'); } cmd = cmd.concat(segment[1]); } if (segment.length === 2) { cmd.push('L'); } cmd = cmd.concat(segment[segment.length - 1]); return cmd; }); return result; } var splitSegment = function (start, end, count) { if (count === 1) { return [[].concat(start)]; } var segments = []; if (end[0] === 'L' || end[0] === 'C' || end[0] === 'Q') { segments = segments.concat(splitCurve(start, end, count)); } else { var temp = [].concat(start); if (temp[0] === 'M') { temp[0] = 'L'; } for (var i = 0; i <= count - 1; i++) { segments.push(temp); } } return segments; }; var fillPath = function (source, target) { if (source.length === 1) { return source; } var sourceLen = source.length - 1; var targetLen = target.length - 1; var ratio = sourceLen / targetLen; var segmentsToFill = []; if (source.length === 1 && source[0][0] === 'M') { for (var i = 0; i < targetLen - sourceLen; i++) { source.push(source[0]); } return source; } for (var i = 0; i < targetLen; i++) { var index = Math.floor(ratio * i); segmentsToFill[index] = (segmentsToFill[index] || 0) + 1; } var filled = segmentsToFill.reduce(function (filled, count, i) { if (i === sourceLen) { return filled.concat(source[sourceLen]); } return filled.concat(splitSegment(source[i], source[i + 1], count)); }, []); filled.unshift(source[0]); if (target[targetLen] === 'Z' || target[targetLen] === 'z') { filled.push('Z'); } return filled; }; exports.fillPath = fillPath; var isEqual = function (obj1, obj2) { if (obj1.length !== obj2.length) { return false; } var result = true; util_1.each(obj1, function (item, i) { if (item !== obj2[i]) { result = false; return false; } }); return result; }; function getMinDiff(del, add, modify) { var type = null; var min = modify; if (add < min) { min = add; type = 'add'; } if (del < min) { min = del; type = 'del'; } return { type: type, min: min, }; } /* * https://en.wikipedia.org/wiki/Levenshtein_distance * 计算两条path的编辑距离 */ var levenshteinDistance = function (source, target) { var sourceLen = source.length; var targetLen = target.length; var sourceSegment; var targetSegment; var temp = 0; if (sourceLen === 0 || targetLen === 0) { return null; } var dist = []; for (var i = 0; i <= sourceLen; i++) { dist[i] = []; dist[i][0] = { min: i }; } for (var j = 0; j <= targetLen; j++) { dist[0][j] = { min: j }; } for (var i = 1; i <= sourceLen; i++) { sourceSegment = source[i - 1]; for (var j = 1; j <= targetLen; j++) { targetSegment = target[j - 1]; if (isEqual(sourceSegment, targetSegment)) { temp = 0; } else { temp = 1; } var del = dist[i - 1][j].min + 1; var add = dist[i][j - 1].min + 1; var modify = dist[i - 1][j - 1].min + temp; dist[i][j] = getMinDiff(del, add, modify); } } return dist; }; var fillPathByDiff = function (source, target) { var diffMatrix = levenshteinDistance(source, target); var sourceLen = source.length; var targetLen = target.length; var changes = []; var index = 1; var minPos = 1; // 如果source和target不是完全不相等 if (diffMatrix[sourceLen][targetLen].min !== sourceLen) { // 获取从source到target所需改动 for (var i = 1; i <= sourceLen; i++) { var min = diffMatrix[i][i].min; minPos = i; for (var j = index; j <= targetLen; j++) { if (diffMatrix[i][j].min < min) { min = diffMatrix[i][j].min; minPos = j; } } index = minPos; if (diffMatrix[i][index].type) { changes.push({ index: i - 1, type: diffMatrix[i][index].type }); } } // 对source进行增删path for (var i = changes.length - 1; i >= 0; i--) { index = changes[i].index; if (changes[i].type === 'add') { source.splice(index, 0, [].concat(source[index])); } else { source.splice(index, 1); } } } // source尾部补齐 sourceLen = source.length; var diff = targetLen - sourceLen; if (sourceLen < targetLen) { for (var i = 0; i < diff; i++) { if (source[sourceLen - 1][0] === 'z' || source[sourceLen - 1][0] === 'Z') { source.splice(sourceLen - 2, 0, source[sourceLen - 2]); } else { source.push(source[sourceLen - 1]); } sourceLen += 1; } } return source; }; exports.fillPathByDiff = fillPathByDiff; // 将两个点均分成count个点 function _splitPoints(points, former, count) { var result = [].concat(points); var index; var t = 1 / (count + 1); var formerEnd = _getSegmentPoints(former)[0]; for (var i = 1; i <= count; i++) { t *= i; index = Math.floor(points.length * t); if (index === 0) { result.unshift([formerEnd[0] * t + points[index][0] * (1 - t), formerEnd[1] * t + points[index][1] * (1 - t)]); } else { result.splice(index, 0, [ formerEnd[0] * t + points[index][0] * (1 - t), formerEnd[1] * t + points[index][1] * (1 - t), ]); } } return result; } /* * 抽取pathSegment中的关键点 * M,L,A,Q,H,V一个端点 * Q, S抽取一个端点,一个控制点 * C抽取一个端点,两个控制点 */ function _getSegmentPoints(segment) { var points = []; switch (segment[0]) { case 'M': points.push([segment[1], segment[2]]); break; case 'L': points.push([segment[1], segment[2]]); break; case 'A': points.push([segment[6], segment[7]]); break; case 'Q': points.push([segment[3], segment[4]]); points.push([segment[1], segment[2]]); break; case 'T': points.push([segment[1], segment[2]]); break; case 'C': points.push([segment[5], segment[6]]); points.push([segment[1], segment[2]]); points.push([segment[3], segment[4]]); break; case 'S': points.push([segment[3], segment[4]]); points.push([segment[1], segment[2]]); break; case 'H': points.push([segment[1], segment[1]]); break; case 'V': points.push([segment[1], segment[1]]); break; default: } return points; } var formatPath = function (fromPath, toPath) { if (fromPath.length <= 1) { return fromPath; } var points; for (var i = 0; i < toPath.length; i++) { if (fromPath[i][0] !== toPath[i][0]) { // 获取fromPath的pathSegment的端点,根据toPath的指令对其改造 points = _getSegmentPoints(fromPath[i]); switch (toPath[i][0]) { case 'M': fromPath[i] = ['M'].concat(points[0]); break; case 'L': fromPath[i] = ['L'].concat(points[0]); break; case 'A': fromPath[i] = [].concat(toPath[i]); fromPath[i][6] = points[0][0]; fromPath[i][7] = points[0][1]; break; case 'Q': if (points.length < 2) { if (i > 0) { points = _splitPoints(points, fromPath[i - 1], 1); } else { fromPath[i] = toPath[i]; break; } } fromPath[i] = ['Q'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, [])); break; case 'T': fromPath[i] = ['T'].concat(points[0]); break; case 'C': if (points.length < 3) { if (i > 0) { points = _splitPoints(points, fromPath[i - 1], 2); } else { fromPath[i] = toPath[i]; break; } } fromPath[i] = ['C'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, [])); break; case 'S': if (points.length < 2) { if (i > 0) { points = _splitPoints(points, fromPath[i - 1], 1); } else { fromPath[i] = toPath[i]; break; } } fromPath[i] = ['S'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, [])); break; default: fromPath[i] = toPath[i]; } } } return fromPath; }; exports.formatPath = formatPath; },{"@antv/util":803}],122:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); var offscreen_1 = require("./offscreen"); /** * 获取文本的高度 * @param text 文本 * @param fontSize 字体大小 * @param lineHeight 行高,可以为空 */ function getTextHeight(text, fontSize, lineHeight) { var lineCount = 1; if (util_1.isString(text)) { lineCount = text.split('\n').length; } if (lineCount > 1) { var spaceingY = getLineSpaceing(fontSize, lineHeight); return fontSize * lineCount + spaceingY * (lineCount - 1); } return fontSize; } exports.getTextHeight = getTextHeight; /** * 获取行间距如果文本多行,需要获取文本间距 * @param fontSize 字体大小 * @param lineHeight 行高 */ function getLineSpaceing(fontSize, lineHeight) { return lineHeight ? lineHeight - fontSize : fontSize * 0.14; } exports.getLineSpaceing = getLineSpaceing; /** * 字体宽度 * @param text 文本 * @param font 字体 */ function getTextWidth(text, font) { var context = offscreen_1.getOffScreenContext(); // 获取离屏的 ctx 进行计算 var width = 0; // null 或者 undefined 时,宽度为 0 if (util_1.isNil(text) || text === '') { return width; } context.save(); context.font = font; if (util_1.isString(text) && text.includes('\n')) { var textArr = text.split('\n'); util_1.each(textArr, function (subText) { var measureWidth = context.measureText(subText).width; if (width < measureWidth) { width = measureWidth; } }); } else { width = context.measureText(text).width; } context.restore(); return width; } exports.getTextWidth = getTextWidth; function assembleFont(attrs) { var fontSize = attrs.fontSize, fontFamily = attrs.fontFamily, fontWeight = attrs.fontWeight, fontStyle = attrs.fontStyle, fontVariant = attrs.fontVariant; return [fontStyle, fontVariant, fontWeight, fontSize + "px", fontFamily].join(' ').trim(); } exports.assembleFont = assembleFont; },{"./offscreen":120,"./util":123}],123:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function removeFromArray(arr, obj) { var index = arr.indexOf(obj); if (index !== -1) { arr.splice(index, 1); } } exports.removeFromArray = removeFromArray; exports.isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; var is_nil_1 = require("@antv/util/lib/is-nil"); exports.isNil = is_nil_1.default; var is_function_1 = require("@antv/util/lib/is-function"); exports.isFunction = is_function_1.default; var is_string_1 = require("@antv/util/lib/is-string"); exports.isString = is_string_1.default; var is_object_1 = require("@antv/util/lib/is-object"); exports.isObject = is_object_1.default; var is_array_1 = require("@antv/util/lib/is-array"); exports.isArray = is_array_1.default; var mix_1 = require("@antv/util/lib/mix"); exports.mix = mix_1.default; var each_1 = require("@antv/util/lib/each"); exports.each = each_1.default; var upper_first_1 = require("@antv/util/lib/upper-first"); exports.upperFirst = upper_first_1.default; // 是否元素的父容器 function isParent(container, shape) { // 所有 shape 都是 canvas 的子元素 if (container.isCanvas()) { return true; } var parent = shape.getParent(); var isParent = false; while (parent) { if (parent === container) { isParent = true; break; } parent = parent.getParent(); } return isParent; } exports.isParent = isParent; function isAllowCapture(element) { // @ts-ignore return element.cfg.visible && element.cfg.capture; } exports.isAllowCapture = isAllowCapture; },{"@antv/util/lib/each":778,"@antv/util/lib/is-array":806,"@antv/util/lib/is-function":817,"@antv/util/lib/is-nil":821,"@antv/util/lib/is-object":826,"@antv/util/lib/is-string":832,"@antv/util/lib/mix":844,"@antv/util/lib/upper-first":871}],124:[function(require,module,exports){ module.exports={ "__npminstall_done": false, "_args": [ [ "@antv/g-base@0.4.7", "C:\\xampp\\htdocs\\icehrm\\web" ] ], "_from": "@antv/g-base@0.4.7", "_id": "@antv/g-base@0.4.7", "_inBundle": false, "_integrity": "sha512-wKSpS3/M1slU92iOgi2QV4MCd82J1d2PyPcQArqSFRUZU0KnVMIl95v79dG0Be4YvFaZ3bVrT6Ns1Czr8oplhA==", "_location": "/@antv/g-base", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, "raw": "@antv/g-base@0.4.7", "name": "@antv/g-base", "escapedName": "@antv%2fg-base", "scope": "@antv", "rawSpec": "0.4.7", "saveSpec": null, "fetchSpec": "0.4.7" }, "_requiredBy": [ "/@antv/component", "/@antv/g-canvas", "/@antv/g-svg", "/@antv/g2", "/@antv/g2plot" ], "_resolved": "https://registry.npmjs.org/@antv/g-base/-/g-base-0.4.7.tgz", "_spec": "0.4.7", "_where": "C:\\xampp\\htdocs\\icehrm\\web", "author": { "name": "https://github.com/orgs/antvis/people" }, "bugs": { "url": "https://github.com/antvis/util/issues" }, "dependencies": { "@antv/event-emitter": "^0.1.1", "@antv/g-math": "^0.1.3", "@antv/matrix-util": "^3.1.0-beta.1", "@antv/path-util": "~2.0.5", "@antv/util": "~2.0.0", "@types/d3-timer": "^1.0.9", "d3-ease": "^1.0.5", "d3-interpolate": "^1.3.2", "d3-timer": "^1.0.9", "detect-browser": "^5.1.0" }, "description": "A common util collection for antv projects", "devDependencies": { "@antv/torch": "^1.0.0", "gl-matrix": "^3.0.0", "less": "^3.9.0", "npm-run-all": "^4.1.5", "tsc-watch": "^4.0.0" }, "files": [ "package.json", "esm", "lib", "LICENSE", "README.md" ], "gitHead": "eb6a2503cb7bb8154697592b10680939d954a31a", "homepage": "https://github.com/antvis/util#readme", "keywords": [ "util", "antv", "g" ], "license": "ISC", "main": "lib/index.js", "module": "esm/index.js", "name": "@antv/g-base", "publishConfig": { "access": "public" }, "repository": { "type": "git", "url": "git+https://github.com/antvis/util.git" }, "scripts": { "build": "npm run clean && run-p build:*", "build:cjs": "tsc -p tsconfig.json --target ES5 --module commonjs --outDir lib", "build:esm": "tsc -p tsconfig.json --target ES5 --module ESNext --outDir esm", "clean": "rm -rf esm lib", "coverage": "npm run coverage-generator && npm run coverage-viewer", "coverage-generator": "torch --coverage --compile --source-pattern src/*.js,src/**/*.js --opts tests/mocha.opts", "coverage-viewer": "torch-coverage", "test": "torch --renderer --compile --opts tests/mocha.opts", "test-live": "torch --compile --interactive --opts tests/mocha.opts", "tsc": "tsc --noEmit", "typecheck": "tsc --noEmit", "watch:cjs": "tsc-watch -p tsconfig.json --target ES5 --module commonjs --outDir lib --compiler typescript/bin/tsc" }, "types": "lib/index.d.ts", "version": "0.4.7" } },{}],125:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var hit_1 = require("./util/hit"); var Shape = require("./shape"); var group_1 = require("./group"); var draw_1 = require("./util/draw"); var util_1 = require("./util/util"); var Canvas = /** @class */ (function (_super) { tslib_1.__extends(Canvas, _super); function Canvas() { return _super !== null && _super.apply(this, arguments) || this; } Canvas.prototype.getDefaultCfg = function () { var cfg = _super.prototype.getDefaultCfg.call(this); // 设置渲染引擎为 canvas,只读属性 cfg['renderer'] = 'canvas'; // 是否自动绘制,不需要用户调用 draw 方法 cfg['autoDraw'] = true; // 是否允许局部刷新图表 cfg['localRefresh'] = true; cfg['refreshElements'] = []; // 是否在视图内自动裁剪 cfg['clipView'] = true; cfg['quickHit'] = false; return cfg; }; /** * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ Canvas.prototype.onCanvasChange = function (changeType) { /** * 触发画布更新的三种 changeType * 1. attr: 修改画布的绘图属性 * 2. sort: 画布排序,图形的层次会发生变化 * 3. changeSize: 改变画布大小 */ if (changeType === 'attr' || changeType === 'sort' || changeType === 'changeSize') { this.set('refreshElements', [this]); this.draw(); } }; Canvas.prototype.getShapeBase = function () { return Shape; }; Canvas.prototype.getGroupBase = function () { return group_1.default; }; /** * 获取屏幕像素比 */ Canvas.prototype.getPixelRatio = function () { var pixelRatio = this.get('pixelRatio') || util_1.getPixelRatio(); // 不足 1 的取 1,超出 1 的取整 return pixelRatio >= 1 ? Math.ceil(pixelRatio) : 1; }; Canvas.prototype.getViewRange = function () { return { minX: 0, minY: 0, maxX: this.get('width'), maxY: this.get('height'), }; }; // 复写基类的方法生成标签 Canvas.prototype.createDom = function () { var element = document.createElement('canvas'); var context = element.getContext('2d'); // 缓存 context 对象 this.set('context', context); return element; }; Canvas.prototype.setDOMSize = function (width, height) { _super.prototype.setDOMSize.call(this, width, height); var context = this.get('context'); var el = this.get('el'); var pixelRatio = this.getPixelRatio(); el.width = pixelRatio * width; el.height = pixelRatio * height; // 设置 canvas 元素的宽度和高度,会重置缩放,因此 context.scale 需要在每次设置宽、高后调用 if (pixelRatio > 1) { context.scale(pixelRatio, pixelRatio); } }; // 复写基类方法 Canvas.prototype.clear = function () { _super.prototype.clear.call(this); this._clearFrame(); // 需要清理掉延迟绘制的帧 var context = this.get('context'); var element = this.get('el'); context.clearRect(0, 0, element.width, element.height); }; Canvas.prototype.getShape = function (x, y) { if (this.get('quickHit')) { return hit_1.getShape(this, x, y); } return _super.prototype.getShape.call(this, x, y, null); }; // 对绘制区域边缘取整,避免浮点数问题 Canvas.prototype._getRefreshRegion = function () { var elements = this.get('refreshElements'); var viewRegion = this.getViewRange(); var region; // 如果是当前画布整体发生了变化,则直接重绘整个画布 if (elements.length && elements[0] === this) { region = viewRegion; } else { region = draw_1.getMergedRegion(elements); if (region) { region.minX = Math.floor(region.minX); region.minY = Math.floor(region.minY); region.maxX = Math.ceil(region.maxX); region.maxY = Math.ceil(region.maxY); var clipView = this.get('clipView'); // 自动裁剪不在 view 内的区域 if (clipView) { region = draw_1.mergeView(region, viewRegion); } } } return region; }; /** * 刷新图形元素,这里仅仅是放入队列,下次绘制时进行绘制 * @param {IElement} element 图形元素 */ Canvas.prototype.refreshElement = function (element) { var refreshElements = this.get('refreshElements'); refreshElements.push(element); // if (this.get('autoDraw')) { // this._startDraw(); // } }; // 清理还在进行的绘制 Canvas.prototype._clearFrame = function () { var drawFrame = this.get('drawFrame'); if (drawFrame) { // 如果全部渲染时,存在局部渲染,则抛弃掉局部渲染 util_1.clearAnimationFrame(drawFrame); this.set('drawFrame', null); this.set('refreshElements', []); } }; // 手工调用绘制接口 Canvas.prototype.draw = function () { var drawFrame = this.get('drawFrame'); if (this.get('autoDraw') && drawFrame) { return; } this._startDraw(); }; // 绘制所有图形 Canvas.prototype._drawAll = function () { var context = this.get('context'); var element = this.get('el'); var children = this.getChildren(); context.clearRect(0, 0, element.width, element.height); draw_1.applyAttrsToContext(context, this); draw_1.drawChildren(context, children); // 对于 https://github.com/antvis/g/issues/422 的场景,全局渲染的模式下也会记录更新的元素队列,因此全局渲染完后也需要置空 this.set('refreshElements', []); }; // 绘制局部 Canvas.prototype._drawRegion = function () { var context = this.get('context'); var refreshElements = this.get('refreshElements'); var children = this.getChildren(); var region = this._getRefreshRegion(); // 需要注意可能没有 region 的场景 // 一般发生在设置了 localRefresh ,在没有图形发生变化的情况下,用户调用了 draw if (region) { // 清理指定区域 context.clearRect(region.minX, region.minY, region.maxX - region.minX, region.maxY - region.minY); // 保存上下文,设置 clip context.save(); context.beginPath(); context.rect(region.minX, region.minY, region.maxX - region.minX, region.maxY - region.minY); context.clip(); draw_1.applyAttrsToContext(context, this); // 绘制子元素 draw_1.drawChildren(context, children, region); context.restore(); } util_1.each(refreshElements, function (element) { if (element.get('hasChanged')) { // 在视窗外的 Group 元素会加入到更新队列里,但实际却没有执行 draw() 逻辑,也就没有清除 hasChanged 标记 // 即已经重绘完、但 hasChanged 标记没有清除的元素,需要统一清除掉。主要是 Group 存在问题,具体原因待排查 element.set('hasChanged', false); } }); this.set('refreshElements', []); }; // 触发绘制 Canvas.prototype._startDraw = function () { var _this = this; var drawFrame = this.get('drawFrame'); if (!drawFrame) { drawFrame = util_1.requestAnimationFrame(function () { if (_this.get('localRefresh')) { _this._drawRegion(); } else { _this._drawAll(); } _this.set('drawFrame', null); }); this.set('drawFrame', drawFrame); } }; Canvas.prototype.skipDraw = function () { }; return Canvas; }(g_base_1.AbstractCanvas)); exports.default = Canvas; },{"./group":126,"./shape":133,"./util/draw":144,"./util/hit":145,"./util/util":155,"@antv/g-base":115,"tslib":894}],126:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var Shape = require("./shape"); var draw_1 = require("./util/draw"); var Group = /** @class */ (function (_super) { tslib_1.__extends(Group, _super); function Group() { return _super !== null && _super.apply(this, arguments) || this; } /** * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ Group.prototype.onCanvasChange = function (changeType) { draw_1.refreshElement(this, changeType); }; Group.prototype.getShapeBase = function () { return Shape; }; Group.prototype.getGroupBase = function () { return Group; }; // 同 shape 中的方法重复了 Group.prototype._applyClip = function (context, clip) { if (clip) { context.save(); // 将 clip 的属性挂载到 context 上 draw_1.applyAttrsToContext(context, clip); // 绘制 clip 路径 clip.createPath(context); context.restore(); // 裁剪 context.clip(); clip._afterDraw(); } }; Group.prototype.draw = function (context, region) { var children = this.getChildren(); if (children.length) { context.save(); // group 上的矩阵和属性也会应用到上下文上 // 先将 attrs 应用到上下文中,再设置 clip。因为 clip 应该被当前元素的 matrix 所影响 draw_1.applyAttrsToContext(context, this); this._applyClip(context, this.getClip()); draw_1.drawChildren(context, children, region); context.restore(); } // 这里的成本比较大 this.set('cacheCanvasBBox', this.getCanvasBBox()); // 绘制后,消除更新标记 this.set('hasChanged', false); }; // 绘制时被跳过,一般发生在分组隐藏时 Group.prototype.skipDraw = function () { this.set('cacheCanvasBBox', null); this.set('hasChanged', false); }; return Group; }(g_base_1.AbstractGroup)); exports.default = Group; },{"./shape":133,"./util/draw":144,"@antv/g-base":115,"tslib":894}],127:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Shape = exports.version = void 0; var tslib_1 = require("tslib"); var Shape = require("./shape"); exports.Shape = Shape; var pkg = require('../package.json'); exports.version = pkg.version; tslib_1.__exportStar(require("./types"), exports); tslib_1.__exportStar(require("./interfaces"), exports); var g_base_1 = require("@antv/g-base"); Object.defineProperty(exports, "Event", { enumerable: true, get: function () { return g_base_1.Event; } }); var canvas_1 = require("./canvas"); Object.defineProperty(exports, "Canvas", { enumerable: true, get: function () { return canvas_1.default; } }); var group_1 = require("./group"); Object.defineProperty(exports, "Group", { enumerable: true, get: function () { return group_1.default; } }); },{"../package.json":156,"./canvas":125,"./group":126,"./interfaces":128,"./shape":133,"./types":141,"@antv/g-base":115,"tslib":894}],128:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); // 导出 g-base 中的 interfaces tslib_1.__exportStar(require("@antv/g-base/lib/interfaces"), exports); },{"@antv/g-base/lib/interfaces":116,"tslib":894}],129:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var util_1 = require("../util/util"); var draw_1 = require("../util/draw"); var index_1 = require("@antv/g-base/lib/bbox/index"); var Shape = require("./index"); var group_1 = require("../group"); var ShapeBase = /** @class */ (function (_super) { tslib_1.__extends(ShapeBase, _super); function ShapeBase() { return _super !== null && _super.apply(this, arguments) || this; } ShapeBase.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); // 设置默认值 return tslib_1.__assign(tslib_1.__assign({}, attrs), { lineWidth: 1, lineAppendWidth: 0, strokeOpacity: 1, fillOpacity: 1 }); }; ShapeBase.prototype.getShapeBase = function () { return Shape; }; ShapeBase.prototype.getGroupBase = function () { return group_1.default; }; /** * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ ShapeBase.prototype.onCanvasChange = function (changeType) { draw_1.refreshElement(this, changeType); }; ShapeBase.prototype.calculateBBox = function () { var type = this.get('type'); var lineWidth = this.getHitLineWidth(); // const attrs = this.attr(); var bboxMethod = index_1.getBBoxMethod(type); var box = bboxMethod(this); var halfLineWidth = lineWidth / 2; var minX = box.x - halfLineWidth; var minY = box.y - halfLineWidth; var maxX = box.x + box.width + halfLineWidth; var maxY = box.y + box.height + halfLineWidth; return { x: minX, minX: minX, y: minY, minY: minY, width: box.width + lineWidth, height: box.height + lineWidth, maxX: maxX, maxY: maxY, }; }; ShapeBase.prototype.isFill = function () { return !!this.attrs['fill'] || this.isClipShape(); }; ShapeBase.prototype.isStroke = function () { return !!this.attrs['stroke']; }; // 同 shape 中的方法重复了 ShapeBase.prototype._applyClip = function (context, clip) { if (clip) { context.save(); // 将 clip 的属性挂载到 context 上 draw_1.applyAttrsToContext(context, clip); // 绘制 clip 路径 clip.createPath(context); context.restore(); // 裁剪 context.clip(); clip._afterDraw(); } }; // 绘制图形时需要考虑 region 限制 ShapeBase.prototype.draw = function (context, region) { var clip = this.getClip(); // 如果指定了区域,当与指定区域相交时,才会触发渲染 if (region) { // 是否相交需要考虑 clip 的包围盒 var bbox = clip ? draw_1.getMergedRegion([this, clip]) : this.getCanvasBBox(); if (!util_1.intersectRect(region, bbox)) { // 图形的包围盒与重绘区域不相交时,也需要清除标记 this.set('hasChanged', false); return; } } context.save(); // 先将 attrs 应用到上下文中,再设置 clip。因为 clip 应该被当前元素的 matrix 所影响 draw_1.applyAttrsToContext(context, this); this._applyClip(context, this.getClip()); this.drawPath(context); context.restore(); this._afterDraw(); }; ShapeBase.prototype._afterDraw = function () { var bbox = this.getCanvasBBox(); var canvas = this.getCanvas(); // 绘制的时候缓存包围盒 this.set('cacheCanvasBBox', bbox); if (canvas) { // @ts-ignore var viewRange = canvas.getViewRange(); this.set('isInView', util_1.intersectRect(bbox, viewRange)); } // 绘制后消除标记 this.set('hasChanged', false); }; ShapeBase.prototype.skipDraw = function () { this.set('cacheCanvasBBox', null); this.set('isInView', null); this.set('hasChanged', false); }; /** * 绘制图形的路径 * @param {CanvasRenderingContext2D} context 上下文 */ ShapeBase.prototype.drawPath = function (context) { this.createPath(context); this.strokeAndFill(context); this.afterDrawPath(context); }; /** * @protected * 填充图形 * @param {CanvasRenderingContext2D} context context 上下文 */ ShapeBase.prototype.fill = function (context) { context.fill(); }; /** * @protected * 绘制图形边框 * @param {CanvasRenderingContext2D} context context 上下文 */ ShapeBase.prototype.stroke = function (context) { context.stroke(); }; // 绘制或者填充 ShapeBase.prototype.strokeAndFill = function (context) { var _a = this.attrs, lineWidth = _a.lineWidth, opacity = _a.opacity, strokeOpacity = _a.strokeOpacity, fillOpacity = _a.fillOpacity; if (this.isFill()) { if (!util_1.isNil(fillOpacity) && fillOpacity !== 1) { context.globalAlpha = fillOpacity; this.fill(context); context.globalAlpha = opacity; } else { this.fill(context); } } if (this.isStroke()) { if (lineWidth > 0) { if (!util_1.isNil(strokeOpacity) && strokeOpacity !== 1) { context.globalAlpha = strokeOpacity; } this.stroke(context); } } this.afterDrawPath(context); }; /** * @protected * 绘制图形的路径 * @param {CanvasRenderingContext2D} context 上下文 */ ShapeBase.prototype.createPath = function (context) { }; /** * 绘制完成 path 后的操作 * @param {CanvasRenderingContext2D} context 上下文 */ ShapeBase.prototype.afterDrawPath = function (context) { }; ShapeBase.prototype.isInShape = function (refX, refY) { // return HitUtil.isHitShape(this, refX, refY); var isStroke = this.isStroke(); var isFill = this.isFill(); var lineWidth = this.getHitLineWidth(); return this.isInStrokeOrPath(refX, refY, isStroke, isFill, lineWidth); }; // 之所以不拆成 isInStroke 和 isInPath 在于两者存在一些共同的计算 ShapeBase.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { return false; }; /** * 获取线拾取的宽度 * @returns {number} 线的拾取宽度 */ ShapeBase.prototype.getHitLineWidth = function () { if (!this.isStroke()) { return 0; } var attrs = this.attrs; return attrs['lineWidth'] + attrs['lineAppendWidth']; }; return ShapeBase; }(g_base_1.AbstractShape)); exports.default = ShapeBase; },{"../group":126,"../util/draw":144,"../util/util":155,"./index":133,"@antv/g-base":115,"@antv/g-base/lib/bbox/index":104,"tslib":894}],130:[function(require,module,exports){ "use strict"; /** * @fileoverview 圆 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var util_1 = require("../util/util"); // TODO: 暂时不需要圆的工具方法,后续如果需要支持 pointAt,tangentAngle 时再引入 // import CircleUtil from '@antv/g-math/lib/circle'; var Circle = /** @class */ (function (_super) { tslib_1.__extends(Circle, _super); function Circle() { return _super !== null && _super.apply(this, arguments) || this; } Circle.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, r: 0 }); }; Circle.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { var attrs = this.attr(); var cx = attrs.x; var cy = attrs.y; var r = attrs.r; var halfLineWidth = lineWidth / 2; var absDistance = util_1.distance(cx, cy, x, y); // 直接用距离,如果同时存在边和填充时,可以减少两次计算 if (isFill && isStroke) { return absDistance <= r + halfLineWidth; } if (isFill) { return absDistance <= r; } if (isStroke) { return absDistance >= r - halfLineWidth && absDistance <= r + halfLineWidth; } return false; }; Circle.prototype.createPath = function (context) { var attrs = this.attr(); var cx = attrs.x; var cy = attrs.y; var r = attrs.r; context.beginPath(); context.arc(cx, cy, r, 0, Math.PI * 2, false); context.closePath(); }; return Circle; }(base_1.default)); exports.default = Circle; },{"../util/util":155,"./base":129,"tslib":894}],131:[function(require,module,exports){ "use strict"; /** * @fileoverview 椭圆 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); // 暂时不需要 // import EllipseUtil from '@antv/g-math/lib/ellipse'; // 根据椭圆公式计算 x*x/rx*rx + y*y/ry*ry; function ellipseDistance(squareX, squareY, rx, ry) { return squareX / (rx * rx) + squareY / (ry * ry); } var Ellipse = /** @class */ (function (_super) { tslib_1.__extends(Ellipse, _super); function Ellipse() { return _super !== null && _super.apply(this, arguments) || this; } Ellipse.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, rx: 0, ry: 0 }); }; Ellipse.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { var attrs = this.attr(); var halfLineWith = lineWidth / 2; var cx = attrs.x; var cy = attrs.y; var rx = attrs.rx, ry = attrs.ry; var squareX = (x - cx) * (x - cx); var squareY = (y - cy) * (y - cy); // 使用椭圆的公式: x*x/rx*rx + y*y/ry*ry = 1; if (isFill && isStroke) { return ellipseDistance(squareX, squareY, rx + halfLineWith, ry + halfLineWith) <= 1; } if (isFill) { return ellipseDistance(squareX, squareY, rx, ry) <= 1; } if (isStroke) { return (ellipseDistance(squareX, squareY, rx - halfLineWith, ry - halfLineWith) >= 1 && ellipseDistance(squareX, squareY, rx + halfLineWith, ry + halfLineWith) <= 1); } return false; }; Ellipse.prototype.createPath = function (context) { var attrs = this.attr(); var cx = attrs.x; var cy = attrs.y; var rx = attrs.rx; var ry = attrs.ry; context.beginPath(); // 兼容逻辑 if (context.ellipse) { context.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2, false); } else { // 如果不支持,则使用圆来绘制,进行变形 var r = rx > ry ? rx : ry; var scaleX = rx > ry ? 1 : rx / ry; var scaleY = rx > ry ? ry / rx : 1; context.save(); context.translate(cx, cy); context.scale(scaleX, scaleY); context.arc(0, 0, r, 0, Math.PI * 2); context.restore(); context.closePath(); } }; return Ellipse; }(base_1.default)); exports.default = Ellipse; },{"./base":129,"tslib":894}],132:[function(require,module,exports){ "use strict"; /** * @fileoverview 图片 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var util_1 = require("../util/util"); function isCanvas(dom) { return dom instanceof HTMLElement && util_1.isString(dom.nodeName) && dom.nodeName.toUpperCase() === 'CANVAS'; } var ImageShape = /** @class */ (function (_super) { tslib_1.__extends(ImageShape, _super); function ImageShape() { return _super !== null && _super.apply(this, arguments) || this; } ImageShape.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, width: 0, height: 0 }); }; ImageShape.prototype.initAttrs = function (attrs) { this._setImage(attrs.img); }; // image 不计算 stroke ImageShape.prototype.isStroke = function () { return false; }; // 仅仅使用包围盒检测来进行拾取 // 所以不需要复写 isInStrokeOrPath 的方法 ImageShape.prototype.isOnlyHitBox = function () { return true; }; ImageShape.prototype._afterLoading = function () { if (this.get('toDraw') === true) { var canvas = this.get('canvas'); if (canvas) { // 这段应该改成局部渲染 canvas.draw(); } else { // 这种方式如果发生遮挡会出现问题 this.createPath(this.get('context')); } } }; ImageShape.prototype._setImage = function (img) { var _this = this; var attrs = this.attrs; if (util_1.isString(img)) { var image_1 = new Image(); image_1.onload = function () { // 图片未加载完,则已经被销毁 if (_this.destroyed) { return false; } // 缓存原始地址,可以做对比,防止重复加载图片 // 如果考虑到在加载过程中可能替换 img 属性,则情况更加复杂 // this.set('imgSrc', img); // 这里会循环调用 _setImage 方法,但不会再走这个分支 _this.attr('img', image_1); _this.set('loading', false); _this._afterLoading(); var callback = _this.get('callback'); if (callback) { callback.call(_this); } }; image_1.src = img; // 设置跨域 image_1.crossOrigin = 'Anonymous'; // loading 过程中不绘制 this.set('loading', true); } else if (img instanceof Image) { // 如果是一个 image 对象,则设置宽高 if (!attrs.width) { attrs.width = img.width; } if (!attrs.height) { attrs.height = img.height; } } else if (isCanvas(img)) { // 如果设置了 canvas 对象 if (!attrs.width) { attrs.width = Number(img.getAttribute('width')); } if (!attrs.height) { attrs.height, Number(img.getAttribute('height')); } } }; ImageShape.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); // 如果加载的已经是当前图片,则不再处理 if (name === 'img') { // 可以加缓冲,&& this.get('imgSrc') !== value this._setImage(value); } }; ImageShape.prototype.createPath = function (context) { // 正在加载则不绘制 if (this.get('loading')) { this.set('toDraw', true); // 加载完成后绘制 this.set('context', context); return; } var attrs = this.attr(); var x = attrs.x, y = attrs.y, width = attrs.width, height = attrs.height, sx = attrs.sx, sy = attrs.sy, swidth = attrs.swidth, sheight = attrs.sheight; var img = attrs.img; if (img instanceof Image || isCanvas(img)) { if (!util_1.isNil(sx) && !util_1.isNil(sy) && !util_1.isNil(swidth) && !util_1.isNil(sheight)) { context.drawImage(img, sx, sy, swidth, sheight, x, y, width, height); } else { context.drawImage(img, x, y, width, height); } } }; return ImageShape; }(base_1.default)); exports.default = ImageShape; },{"../util/util":155,"./base":129,"tslib":894}],133:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("./base"); Object.defineProperty(exports, "Base", { enumerable: true, get: function () { return base_1.default; } }); var circle_1 = require("./circle"); Object.defineProperty(exports, "Circle", { enumerable: true, get: function () { return circle_1.default; } }); var ellipse_1 = require("./ellipse"); Object.defineProperty(exports, "Ellipse", { enumerable: true, get: function () { return ellipse_1.default; } }); var image_1 = require("./image"); Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return image_1.default; } }); var line_1 = require("./line"); Object.defineProperty(exports, "Line", { enumerable: true, get: function () { return line_1.default; } }); var marker_1 = require("./marker"); Object.defineProperty(exports, "Marker", { enumerable: true, get: function () { return marker_1.default; } }); var path_1 = require("./path"); Object.defineProperty(exports, "Path", { enumerable: true, get: function () { return path_1.default; } }); var polygon_1 = require("./polygon"); Object.defineProperty(exports, "Polygon", { enumerable: true, get: function () { return polygon_1.default; } }); var polyline_1 = require("./polyline"); Object.defineProperty(exports, "Polyline", { enumerable: true, get: function () { return polyline_1.default; } }); var rect_1 = require("./rect"); Object.defineProperty(exports, "Rect", { enumerable: true, get: function () { return rect_1.default; } }); var text_1 = require("./text"); Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return text_1.default; } }); },{"./base":129,"./circle":130,"./ellipse":131,"./image":132,"./line":134,"./marker":135,"./path":136,"./polygon":137,"./polyline":138,"./rect":139,"./text":140}],134:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * @fileoverview 圆 * @author dxq613@gmail.com */ var line_1 = require("@antv/g-math/lib/line"); var base_1 = require("./base"); var line_2 = require("../util/in-stroke/line"); var ArrowUtil = require("../util/arrow"); var Line = /** @class */ (function (_super) { tslib_1.__extends(Line, _super); function Line() { return _super !== null && _super.apply(this, arguments) || this; } Line.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x1: 0, y1: 0, x2: 0, y2: 0, startArrow: false, endArrow: false }); }; Line.prototype.initAttrs = function (attrs) { this.setArrow(); }; // 更新属性时,检测是否更改了箭头 Line.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); // 由于箭头的绘制依赖于 line 的诸多 attrs,因此这里不再对每个 attr 进行判断,attr 每次变化都会影响箭头的更新 this.setArrow(); }; Line.prototype.setArrow = function () { var attrs = this.attr(); var x1 = attrs.x1, y1 = attrs.y1, x2 = attrs.x2, y2 = attrs.y2, startArrow = attrs.startArrow, endArrow = attrs.endArrow; if (startArrow) { ArrowUtil.addStartArrow(this, attrs, x2, y2, x1, y1); } if (endArrow) { ArrowUtil.addEndArrow(this, attrs, x1, y1, x2, y2); } }; Line.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { if (!isStroke || !lineWidth) { return false; } var _a = this.attr(), x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2; return line_2.default(x1, y1, x2, y2, lineWidth, x, y); }; Line.prototype.createPath = function (context) { var attrs = this.attr(); var x1 = attrs.x1, y1 = attrs.y1, x2 = attrs.x2, y2 = attrs.y2, startArrow = attrs.startArrow, endArrow = attrs.endArrow; var startArrowDistance = { dx: 0, dy: 0, }; var endArrowDistance = { dx: 0, dy: 0, }; if (startArrow && startArrow.d) { startArrowDistance = ArrowUtil.getShortenOffset(x1, y1, x2, y2, attrs.startArrow.d); } if (endArrow && endArrow.d) { endArrowDistance = ArrowUtil.getShortenOffset(x1, y1, x2, y2, attrs.endArrow.d); } context.beginPath(); // 如果自定义箭头,线条相应缩进 context.moveTo(x1 + startArrowDistance.dx, y1 + startArrowDistance.dy); context.lineTo(x2 - endArrowDistance.dx, y2 - endArrowDistance.dy); }; Line.prototype.afterDrawPath = function (context) { var startArrowShape = this.get('startArrowShape'); var endArrowShape = this.get('endArrowShape'); if (startArrowShape) { startArrowShape.draw(context); } if (endArrowShape) { endArrowShape.draw(context); } }; /** * Get length of line * @return {number} length */ Line.prototype.getTotalLength = function () { var _a = this.attr(), x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2; return line_1.default.length(x1, y1, x2, y2); }; /** * Get point according to ratio * @param {number} ratio * @return {Point} point */ Line.prototype.getPoint = function (ratio) { var _a = this.attr(), x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2; return line_1.default.pointAt(x1, y1, x2, y2, ratio); }; return Line; }(base_1.default)); exports.default = Line; },{"../util/arrow":143,"../util/in-stroke/line":149,"./base":129,"@antv/g-math/lib/line":172,"tslib":894}],135:[function(require,module,exports){ "use strict"; /** * @fileoverview Marker * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var path_2_absolute_1 = require("@antv/path-util/lib/path-2-absolute"); var base_1 = require("./base"); var util_2 = require("../util/util"); var draw_1 = require("../util/draw"); var Symbols = { // 圆 circle: function (x, y, r) { return [ ['M', x - r, y], ['A', r, r, 0, 1, 0, x + r, y], ['A', r, r, 0, 1, 0, x - r, y], ]; }, // 正方形 square: function (x, y, r) { return [['M', x - r, y - r], ['L', x + r, y - r], ['L', x + r, y + r], ['L', x - r, y + r], ['Z']]; }, // 菱形 diamond: function (x, y, r) { return [['M', x - r, y], ['L', x, y - r], ['L', x + r, y], ['L', x, y + r], ['Z']]; }, // 三角形 triangle: function (x, y, r) { var diffY = r * Math.sin((1 / 3) * Math.PI); return [['M', x - r, y + diffY], ['L', x, y - diffY], ['L', x + r, y + diffY], ['Z']]; }, // 倒三角形 'triangle-down': function (x, y, r) { var diffY = r * Math.sin((1 / 3) * Math.PI); return [['M', x - r, y - diffY], ['L', x + r, y - diffY], ['L', x, y + diffY], ['Z']]; }, }; var Marker = /** @class */ (function (_super) { tslib_1.__extends(Marker, _super); function Marker() { return _super !== null && _super.apply(this, arguments) || this; } Marker.prototype.initAttrs = function (attrs) { this._resetParamsCache(); }; // 重置绘制 path 存储的缓存 Marker.prototype._resetParamsCache = function () { // 为了加速 path 的绘制、拾取和计算,这个地方可以缓存很多东西 // 这些缓存都是第一次需要时计算和存储,虽然增加了复杂度,但是频繁调用的方法,性能有很大提升 this.set('paramsCache', {}); // 清理缓存 }; // 更新属性时,检测是否更改了 path Marker.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); if (['symbol', 'x', 'y', 'r', 'radius'].indexOf(name) !== -1) { // path 相关属性更改时,清理缓存 this._resetParamsCache(); } }; // 仅仅使用包围盒检测来进行拾取 // 所以不需要复写 isInStrokeOrPath 的方法 Marker.prototype.isOnlyHitBox = function () { return true; }; Marker.prototype._getR = function (attrs) { // 兼容 r 和 radius 两种写法,推荐使用 r return util_1.isNil(attrs.r) ? attrs.radius : attrs.r; }; Marker.prototype._getPath = function () { var attrs = this.attr(); var x = attrs.x, y = attrs.y; var symbol = attrs.symbol || 'circle'; var r = this._getR(attrs); var method; var path; if (util_2.isFunction(symbol)) { method = symbol; path = method(x, y, r); // 将 path 转成绝对路径 path = path_2_absolute_1.default(path); } else { // 内置 symbol 的 path 都是绝对路径,直接绘制即可,不需要对 path 进行特殊处理 method = Marker.Symbols[symbol]; path = method(x, y, r); } if (!method) { console.warn(symbol + " marker is not supported."); return null; } return path; }; Marker.prototype.createPath = function (context) { var path = this._getPath(); var paramsCache = this.get('paramsCache'); draw_1.drawPath(this, context, { path: path }, paramsCache); }; Marker.Symbols = Symbols; return Marker; }(base_1.default)); exports.default = Marker; },{"../util/draw":144,"../util/util":155,"./base":129,"@antv/path-util/lib/path-2-absolute":729,"@antv/util":803,"tslib":894}],136:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var cubic_1 = require("@antv/g-math/lib/cubic"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var path_2_absolute_1 = require("@antv/path-util/lib/path-2-absolute"); var path_2_segments_1 = require("@antv/path-util/lib/path-2-segments"); var draw_1 = require("../util/draw"); var point_in_path_1 = require("../util/in-path/point-in-path"); var polygon_1 = require("../util/in-path/polygon"); var path_1 = require("../util/path"); var ArrowUtil = require("../util/arrow"); // 是否在多个多边形内部 function isInPolygons(polygons, x, y) { var isHit = false; for (var i = 0; i < polygons.length; i++) { var points = polygons[i]; isHit = polygon_1.default(points, x, y); if (isHit) { break; } } return isHit; } var Path = /** @class */ (function (_super) { tslib_1.__extends(Path, _super); function Path() { return _super !== null && _super.apply(this, arguments) || this; } Path.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { startArrow: false, endArrow: false }); }; Path.prototype.initAttrs = function (attrs) { this._setPathArr(attrs.path); this.setArrow(); }; // 更新属性时,检测是否更改了 path Path.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); if (name === 'path') { this._setPathArr(value); } // 由于箭头的绘制依赖于 line 的诸多 attrs,因此这里不再对每个 attr 进行判断,attr 每次变化都会影响箭头的更新 this.setArrow(); }; // 将 path 转换成绝对路径 Path.prototype._setPathArr = function (path) { // 转换 path 的格式 this.attrs.path = path_2_absolute_1.default(path); var hasArc = path_1.default.hasArc(path); // 为了加速 path 的绘制、拾取和计算,这个地方可以缓存很多东西 // 这些缓存都是第一次需要时计算和存储,虽然增加了复杂度,但是频繁调用的方法,性能有很大提升 this.set('hasArc', hasArc); this.set('paramsCache', {}); // 清理缓存 this.set('segments', null); // 延迟生成 path,在动画场景下可能不会有拾取 this.set('curve', null); this.set('tCache', null); this.set('totalLength', null); }; Path.prototype.getSegments = function () { var segments = this.get('segements'); if (!segments) { segments = path_2_segments_1.default(this.attr('path')); this.set('segments', segments); } return segments; }; Path.prototype.setArrow = function () { var attrs = this.attr(); var startArrow = attrs.startArrow, endArrow = attrs.endArrow; if (startArrow) { var tangent = this.getStartTangent(); ArrowUtil.addStartArrow(this, attrs, tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1]); } if (endArrow) { var tangent = this.getEndTangent(); ArrowUtil.addEndArrow(this, attrs, tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1]); } }; Path.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { var segments = this.getSegments(); var hasArc = this.get('hasArc'); var isHit = false; if (isStroke) { isHit = path_1.default.isPointInStroke(segments, lineWidth, x, y); } if (!isHit && isFill) { if (hasArc) { // 存在曲线时,暂时使用 canvas 的 api 计算,后续可以进行多边形切割 isHit = point_in_path_1.default(this, x, y); } else { var path = this.attr('path'); var extractResutl = path_1.default.extractPolygons(path); // 提取出来的多边形包含闭合的和非闭合的,在这里统一按照多边形处理 isHit = isInPolygons(extractResutl.polygons, x, y) || isInPolygons(extractResutl.polylines, x, y); } } return isHit; }; Path.prototype.createPath = function (context) { var attrs = this.attr(); var paramsCache = this.get('paramsCache'); // 由于计算圆弧的参数成本很大,所以要缓存 draw_1.drawPath(this, context, attrs, paramsCache); }; Path.prototype.afterDrawPath = function (context) { var startArrowShape = this.get('startArrowShape'); var endArrowShape = this.get('endArrowShape'); if (startArrowShape) { startArrowShape.draw(context); } if (endArrowShape) { endArrowShape.draw(context); } }; /** * Get total length of path * @return {number} length */ Path.prototype.getTotalLength = function () { var totalLength = this.get('totalLength'); if (!util_1.isNil(totalLength)) { return totalLength; } this._calculateCurve(); this._setTcache(); return this.get('totalLength'); }; /** * Get point according to ratio * @param {number} ratio * @return {Point} point */ Path.prototype.getPoint = function (ratio) { var tCache = this.get('tCache'); if (!tCache) { this._calculateCurve(); this._setTcache(); tCache = this.get('tCache'); } var subt; var index; var curve = this.get('curve'); if (!tCache || tCache.length === 0) { if (curve) { return { x: curve[0][1], y: curve[0][2], }; } return null; } util_1.each(tCache, function (v, i) { if (ratio >= v[0] && ratio <= v[1]) { subt = (ratio - v[0]) / (v[1] - v[0]); index = i; } }); var seg = curve[index]; if (util_1.isNil(seg) || util_1.isNil(index)) { return null; } var l = seg.length; var nextSeg = curve[index + 1]; return cubic_1.default.pointAt(seg[l - 2], seg[l - 1], nextSeg[1], nextSeg[2], nextSeg[3], nextSeg[4], nextSeg[5], nextSeg[6], subt); }; Path.prototype._calculateCurve = function () { var path = this.attr().path; this.set('curve', path_1.default.pathToCurve(path)); }; Path.prototype._setTcache = function () { var totalLength = 0; var tempLength = 0; // 每段 curve 对应起止点的长度比例列表,形如: [[0, 0.25], [0.25, 0.6]. [0.6, 0.9], [0.9, 1]] var tCache = []; var segmentT; var segmentL; var segmentN; var l; var curve = this.get('curve'); if (!curve) { return; } util_1.each(curve, function (segment, i) { segmentN = curve[i + 1]; l = segment.length; if (segmentN) { totalLength += cubic_1.default.length(segment[l - 2], segment[l - 1], segmentN[1], segmentN[2], segmentN[3], segmentN[4], segmentN[5], segmentN[6]) || 0; } }); this.set('totalLength', totalLength); if (totalLength === 0) { this.set('tCache', []); return; } util_1.each(curve, function (segment, i) { segmentN = curve[i + 1]; l = segment.length; if (segmentN) { segmentT = []; segmentT[0] = tempLength / totalLength; segmentL = cubic_1.default.length(segment[l - 2], segment[l - 1], segmentN[1], segmentN[2], segmentN[3], segmentN[4], segmentN[5], segmentN[6]); // 当 path 不连续时,segmentL 可能为空,为空时需要作为 0 处理 tempLength += segmentL || 0; segmentT[1] = tempLength / totalLength; tCache.push(segmentT); } }); this.set('tCache', tCache); }; /** * Get start tangent vector * @return {Array} */ Path.prototype.getStartTangent = function () { var segments = this.getSegments(); var result; if (segments.length > 1) { var startPoint = segments[0].currentPoint; var endPoint = segments[1].currentPoint; var tangent = segments[1].startTangent; result = []; if (tangent) { result.push([startPoint[0] - tangent[0], startPoint[1] - tangent[1]]); result.push([startPoint[0], startPoint[1]]); } else { result.push([endPoint[0], endPoint[1]]); result.push([startPoint[0], startPoint[1]]); } } return result; }; /** * Get end tangent vector * @return {Array} */ Path.prototype.getEndTangent = function () { var segments = this.getSegments(); var length = segments.length; var result; if (length > 1) { var startPoint = segments[length - 2].currentPoint; var endPoint = segments[length - 1].currentPoint; var tangent = segments[length - 1].endTangent; result = []; if (tangent) { result.push([endPoint[0] - tangent[0], endPoint[1] - tangent[1]]); result.push([endPoint[0], endPoint[1]]); } else { result.push([startPoint[0], startPoint[1]]); result.push([endPoint[0], endPoint[1]]); } } return result; }; return Path; }(base_1.default)); exports.default = Path; },{"../util/arrow":143,"../util/draw":144,"../util/in-path/point-in-path":146,"../util/in-path/polygon":147,"../util/path":154,"./base":129,"@antv/g-math/lib/cubic":170,"@antv/path-util/lib/path-2-absolute":729,"@antv/path-util/lib/path-2-segments":731,"@antv/util":803,"tslib":894}],137:[function(require,module,exports){ "use strict"; /** * @fileoverview 多边形 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var polyline_1 = require("../util/in-stroke/polyline"); var polygon_1 = require("../util/in-path/polygon"); var Polygon = /** @class */ (function (_super) { tslib_1.__extends(Polygon, _super); function Polygon() { return _super !== null && _super.apply(this, arguments) || this; } Polygon.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { var points = this.attr().points; var isHit = false; if (isStroke) { isHit = polyline_1.default(points, lineWidth, x, y, true); } if (!isHit && isFill) { isHit = polygon_1.default(points, x, y); // isPointInPath(shape, x, y); } return isHit; }; Polygon.prototype.createPath = function (context) { var attrs = this.attr(); var points = attrs.points; if (points.length < 2) { return; } context.beginPath(); for (var i = 0; i < points.length; i++) { var point = points[i]; if (i === 0) { context.moveTo(point[0], point[1]); } else { context.lineTo(point[0], point[1]); } } context.closePath(); }; return Polygon; }(base_1.default)); exports.default = Polygon; },{"../util/in-path/polygon":147,"../util/in-stroke/polyline":150,"./base":129,"tslib":894}],138:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var line_1 = require("@antv/g-math/lib/line"); var polyline_1 = require("@antv/g-math/lib/polyline"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var polyline_2 = require("../util/in-stroke/polyline"); var ArrowUtil = require("../util/arrow"); var PolyLine = /** @class */ (function (_super) { tslib_1.__extends(PolyLine, _super); function PolyLine() { return _super !== null && _super.apply(this, arguments) || this; } PolyLine.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { startArrow: false, endArrow: false }); }; PolyLine.prototype.initAttrs = function (attrs) { this.setArrow(); }; // 更新属性时,检测是否更改了 points PolyLine.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); this.setArrow(); if (['points'].indexOf(name) !== -1) { this._resetCache(); } }; PolyLine.prototype._resetCache = function () { this.set('totalLength', null); this.set('tCache', null); }; PolyLine.prototype.setArrow = function () { var attrs = this.attr(); var _a = this.attrs, points = _a.points, startArrow = _a.startArrow, endArrow = _a.endArrow; var length = points.length; var x1 = points[0][0]; var y1 = points[0][1]; var x2 = points[length - 1][0]; var y2 = points[length - 1][1]; if (startArrow) { ArrowUtil.addStartArrow(this, attrs, points[1][0], points[1][1], x1, y1); } if (endArrow) { ArrowUtil.addEndArrow(this, attrs, points[length - 2][0], points[length - 2][1], x2, y2); } }; // 不允许 fill PolyLine.prototype.isFill = function () { return false; }; PolyLine.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { // 没有设置 stroke 不能被拾取, 没有线宽不能被拾取 if (!isStroke || !lineWidth) { return false; } var points = this.attr().points; return polyline_2.default(points, lineWidth, x, y, false); }; // 始终填充 PolyLine.prototype.isStroke = function () { return true; }; PolyLine.prototype.createPath = function (context) { var _a = this.attr(), points = _a.points, startArrow = _a.startArrow, endArrow = _a.endArrow; var length = points.length; if (points.length < 2) { return; } var x1 = points[0][0]; var y1 = points[0][1]; var x2 = points[length - 1][0]; var y2 = points[length - 1][1]; // 如果定义了箭头,并且是自定义箭头,线条相应缩进 if (startArrow && startArrow.d) { var distance = ArrowUtil.getShortenOffset(x1, y1, points[1][0], points[1][1], startArrow.d); x1 += distance.dx; y1 += distance.dy; } if (endArrow && endArrow.d) { var distance = ArrowUtil.getShortenOffset(points[length - 2][0], points[length - 2][1], x2, y2, endArrow.d); x2 -= distance.dx; y2 -= distance.dy; } context.beginPath(); context.moveTo(x1, y1); for (var i = 0; i < length - 1; i++) { var point = points[i]; context.lineTo(point[0], point[1]); } context.lineTo(x2, y2); }; PolyLine.prototype.afterDrawPath = function (context) { var startArrowShape = this.get('startArrowShape'); var endArrowShape = this.get('endArrowShape'); if (startArrowShape) { startArrowShape.draw(context); } if (endArrowShape) { endArrowShape.draw(context); } }; /** * Get length of polyline * @return {number} length */ PolyLine.prototype.getTotalLength = function () { var points = this.attr().points; // get totalLength from cache var totalLength = this.get('totalLength'); if (!util_1.isNil(totalLength)) { return totalLength; } this.set('totalLength', polyline_1.default.length(points)); return this.get('totalLength'); }; /** * Get point according to ratio * @param {number} ratio * @return {Point} point */ PolyLine.prototype.getPoint = function (ratio) { var points = this.attr().points; // get tCache from cache var tCache = this.get('tCache'); if (!tCache) { this._setTcache(); tCache = this.get('tCache'); } var subt; var index; util_1.each(tCache, function (v, i) { if (ratio >= v[0] && ratio <= v[1]) { subt = (ratio - v[0]) / (v[1] - v[0]); index = i; } }); return line_1.default.pointAt(points[index][0], points[index][1], points[index + 1][0], points[index + 1][1], subt); }; PolyLine.prototype._setTcache = function () { var points = this.attr().points; if (!points || points.length === 0) { return; } var totalLength = this.getTotalLength(); if (totalLength <= 0) { return; } var tempLength = 0; var tCache = []; var segmentT; var segmentL; util_1.each(points, function (p, i) { if (points[i + 1]) { segmentT = []; segmentT[0] = tempLength / totalLength; segmentL = line_1.default.length(p[0], p[1], points[i + 1][0], points[i + 1][1]); tempLength += segmentL; segmentT[1] = tempLength / totalLength; tCache.push(segmentT); } }); this.set('tCache', tCache); }; /** * Get start tangent vector * @return {Array} */ PolyLine.prototype.getStartTangent = function () { var points = this.attr().points; var result = []; result.push([points[1][0], points[1][1]]); result.push([points[0][0], points[0][1]]); return result; }; /** * Get end tangent vector * @return {Array} */ PolyLine.prototype.getEndTangent = function () { var points = this.attr().points; var l = points.length - 1; var result = []; result.push([points[l - 1][0], points[l - 1][1]]); result.push([points[l][0], points[l][1]]); return result; }; return PolyLine; }(base_1.default)); exports.default = PolyLine; },{"../util/arrow":143,"../util/in-stroke/polyline":150,"./base":129,"@antv/g-math/lib/line":172,"@antv/g-math/lib/polyline":173,"@antv/util":803,"tslib":894}],139:[function(require,module,exports){ "use strict"; /** * @fileoverview 矩形 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var parse_1 = require("../util/parse"); var util_1 = require("../util/util"); var rect_1 = require("../util/in-stroke/rect"); var rect_radius_1 = require("../util/in-stroke/rect-radius"); var point_in_path_1 = require("../util/in-path/point-in-path"); var Rect = /** @class */ (function (_super) { tslib_1.__extends(Rect, _super); function Rect() { return _super !== null && _super.apply(this, arguments) || this; } Rect.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, width: 0, height: 0, radius: 0 }); }; Rect.prototype.isInStrokeOrPath = function (x, y, isStroke, isFill, lineWidth) { var attrs = this.attr(); var minX = attrs.x; var minY = attrs.y; var width = attrs.width; var height = attrs.height; var radius = attrs.radius; // 无圆角时的策略 if (!radius) { var halfWidth = lineWidth / 2; // 同时填充和带有边框 if (isFill && isStroke) { return util_1.inBox(minX - halfWidth, minY - halfWidth, width + halfWidth, height + halfWidth, x, y); } // 仅填充 if (isFill) { return util_1.inBox(minX, minY, width, height, x, y); } if (isStroke) { return rect_1.default(minX, minY, width, height, lineWidth, x, y); } } else { var isHit = false; if (isStroke) { isHit = rect_radius_1.default(minX, minY, width, height, radius, lineWidth, x, y); } // 仅填充时带有圆角的矩形直接通过图形拾取 // 以后可以改成纯数学的近似拾取,将圆弧切割成多边形 if (!isHit && isFill) { isHit = point_in_path_1.default(this, x, y); } return isHit; } }; Rect.prototype.createPath = function (context) { var attrs = this.attr(); var x = attrs.x; var y = attrs.y; var width = attrs.width; var height = attrs.height; var radius = attrs.radius; context.beginPath(); if (radius === 0) { // 改成原生的rect方法 context.rect(x, y, width, height); } else { var _a = parse_1.parseRadius(radius), r1 = _a[0], r2 = _a[1], r3 = _a[2], r4 = _a[3]; context.moveTo(x + r1, y); context.lineTo(x + width - r2, y); r2 !== 0 && context.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0); context.lineTo(x + width, y + height - r3); r3 !== 0 && context.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2); context.lineTo(x + r4, y + height); r4 !== 0 && context.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI); context.lineTo(x, y + r1); r1 !== 0 && context.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5); context.closePath(); } }; return Rect; }(base_1.default)); exports.default = Rect; },{"../util/in-path/point-in-path":146,"../util/in-stroke/rect":152,"../util/in-stroke/rect-radius":151,"../util/parse":153,"../util/util":155,"./base":129,"tslib":894}],140:[function(require,module,exports){ "use strict"; /** * @fileoverview 文本 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var util_1 = require("../util/util"); var text_1 = require("@antv/g-base/lib/util/text"); var Text = /** @class */ (function (_super) { tslib_1.__extends(Text, _super); function Text() { return _super !== null && _super.apply(this, arguments) || this; } // 默认文本属性 Text.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, text: null, fontSize: 12, fontFamily: 'sans-serif', fontStyle: 'normal', fontWeight: 'normal', fontVariant: 'normal', textAlign: 'start', textBaseline: 'bottom' }); }; // 仅仅使用包围盒检测来进行拾取 Text.prototype.isOnlyHitBox = function () { return true; }; // 初始化时组合 font,同时判断 text 是否换行 Text.prototype.initAttrs = function (attrs) { this._assembleFont(); if (attrs.text) { this._setText(attrs.text); } }; // 组装字体 Text.prototype._assembleFont = function () { var attrs = this.attrs; attrs.font = text_1.assembleFont(attrs); }; // 如果文本换行,则缓存数组 Text.prototype._setText = function (text) { var textArr = null; if (util_1.isString(text) && text.indexOf('\n') !== -1) { textArr = text.split('\n'); } this.set('textArr', textArr); }; // 更新属性时,检测是否更改了 font、text Text.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); if (name.startsWith('font')) { this._assembleFont(); } if (name === 'text') { this._setText(value); } }; // 这个方法在 text 时没有可以做的事情,如果要支持文字背景时可以考虑 // createPath(context) { // } // 如果文本多行,需要获取文本间距 Text.prototype._getSpaceingY = function () { var attrs = this.attrs; var lineHeight = attrs.lineHeight; var fontSize = attrs.fontSize * 1; return lineHeight ? lineHeight - fontSize : fontSize * 0.14; }; // 绘制文本,考虑多行的场景 Text.prototype._drawTextArr = function (context, textArr, isFill) { var attrs = this.attrs; var textBaseline = attrs.textBaseline; var x = attrs.x; var y = attrs.y; var fontSize = attrs.fontSize * 1; var spaceingY = this._getSpaceingY(); var height = text_1.getTextHeight(attrs.text, attrs.fontSize, attrs.lineHeight); var subY; util_1.each(textArr, function (subText, index) { subY = y + index * (spaceingY + fontSize) - height + fontSize; // bottom; if (textBaseline === 'middle') subY += height - fontSize - (height - fontSize) / 2; if (textBaseline === 'top') subY += height - fontSize; if (isFill) { context.fillText(subText, x, subY); } else { context.strokeText(subText, x, subY); } }); }; // 绘制文本,同时考虑填充和绘制边框 Text.prototype._drawText = function (context, isFill) { var attrs = this.attr(); var x = attrs.x; var y = attrs.y; var textArr = this.get('textArr'); if (textArr) { this._drawTextArr(context, textArr, isFill); } else { var text = attrs.text; if (isFill) { context.fillText(text, x, y); } else { context.strokeText(text, x, y); } } }; // 复写绘制和填充的逻辑:对于文本,应该先绘制边框,再进行填充 Text.prototype.strokeAndFill = function (context) { var _a = this.attrs, lineWidth = _a.lineWidth, opacity = _a.opacity, strokeOpacity = _a.strokeOpacity, fillOpacity = _a.fillOpacity; if (this.isStroke()) { if (lineWidth > 0) { if (!util_1.isNil(strokeOpacity) && strokeOpacity !== 1) { context.globalAlpha = opacity; } this.stroke(context); } } if (this.isFill()) { if (!util_1.isNil(fillOpacity) && fillOpacity !== 1) { context.globalAlpha = fillOpacity; this.fill(context); context.globalAlpha = opacity; } else { this.fill(context); } } this.afterDrawPath(context); }; // 复写填充逻辑 Text.prototype.fill = function (context) { this._drawText(context, true); }; // 复写绘制边框的逻辑 Text.prototype.stroke = function (context) { this._drawText(context, false); }; return Text; }(base_1.default)); exports.default = Text; },{"../util/util":155,"./base":129,"@antv/g-base/lib/util/text":122,"tslib":894}],141:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); // 导出 g-base 中的 types tslib_1.__exportStar(require("@antv/g-base/lib/types"), exports); },{"@antv/g-base/lib/types":117,"tslib":894}],142:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); // 向量长度 function vMag(v) { return Math.sqrt(v[0] * v[0] + v[1] * v[1]); } // u.v/|u||v|,计算夹角的余弦值 function vRatio(u, v) { // 当存在一个向量的长度为 0 时,夹角也为 0,即夹角的余弦值为 1 return vMag(u) * vMag(v) ? (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)) : 1; } // 向量角度 function vAngle(u, v) { return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v)); } // A 0:rx 1:ry 2:x-axis-rotation 3:large-arc-flag 4:sweep-flag 5: x 6: y function getArcParams(startPoint, params) { var rx = params[1]; var ry = params[2]; var xRotation = util_1.mod(util_1.toRadian(params[3]), Math.PI * 2); var arcFlag = params[4]; var sweepFlag = params[5]; // 弧形起点坐标 var x1 = startPoint[0]; var y1 = startPoint[1]; // 弧形终点坐标 var x2 = params[6]; var y2 = params[7]; var xp = (Math.cos(xRotation) * (x1 - x2)) / 2.0 + (Math.sin(xRotation) * (y1 - y2)) / 2.0; var yp = (-1 * Math.sin(xRotation) * (x1 - x2)) / 2.0 + (Math.cos(xRotation) * (y1 - y2)) / 2.0; var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); if (lambda > 1) { rx *= Math.sqrt(lambda); ry *= Math.sqrt(lambda); } var diff = rx * rx * (yp * yp) + ry * ry * (xp * xp); var f = diff ? Math.sqrt((rx * rx * (ry * ry) - diff) / diff) : 1; if (arcFlag === sweepFlag) { f *= -1; } if (isNaN(f)) { f = 0; } // 旋转前的起点坐标,且当长半轴和短半轴的长度为 0 时,坐标按 (0, 0) 处理 var cxp = ry ? (f * rx * yp) / ry : 0; var cyp = rx ? (f * -ry * xp) / rx : 0; // 椭圆圆心坐标 var cx = (x1 + x2) / 2.0 + Math.cos(xRotation) * cxp - Math.sin(xRotation) * cyp; var cy = (y1 + y2) / 2.0 + Math.sin(xRotation) * cxp + Math.cos(xRotation) * cyp; // 起始点的单位向量 var u = [(xp - cxp) / rx, (yp - cyp) / ry]; // 终止点的单位向量 var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry]; // 计算起始点和圆心的连线,与 x 轴正方向的夹角 var theta = vAngle([1, 0], u); // 计算圆弧起始点和终止点与椭圆圆心连线的夹角 var dTheta = vAngle(u, v); if (vRatio(u, v) <= -1) { dTheta = Math.PI; } if (vRatio(u, v) >= 1) { dTheta = 0; } if (sweepFlag === 0 && dTheta > 0) { dTheta = dTheta - 2 * Math.PI; } if (sweepFlag === 1 && dTheta < 0) { dTheta = dTheta + 2 * Math.PI; } return { cx: cx, cy: cy, // 弧形的起点和终点相同时,长轴和短轴的长度按 0 处理 rx: util_1.isSamePoint(startPoint, [x2, y2]) ? 0 : rx, ry: util_1.isSamePoint(startPoint, [x2, y2]) ? 0 : ry, startAngle: theta, endAngle: theta + dTheta, xRotation: xRotation, arcFlag: arcFlag, sweepFlag: sweepFlag, }; } exports.default = getArcParams; },{"./util":155}],143:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addEndArrow = exports.addStartArrow = exports.getShortenOffset = void 0; var tslib_1 = require("tslib"); var shape_1 = require("../shape"); var sin = Math.sin, cos = Math.cos, atan2 = Math.atan2, PI = Math.PI; function _addDefaultArrow(shape, attrs, x1, y1, x2, y2, isStart) { var stroke = attrs.stroke, lineWidth = attrs.lineWidth; var x = x1 - x2; var y = y1 - y2; var rad = atan2(y, x); var arrowShape = new shape_1.Path({ type: 'path', canvas: shape.get('canvas'), isArrowShape: true, attrs: { // 默认箭头的边长为 10,夹角为 60 度 path: "M" + 10 * cos(PI / 6) + "," + 10 * sin(PI / 6) + " L0,0 L" + 10 * cos(PI / 6) + ",-" + 10 * sin(PI / 6), // 使用 shape stroke 值 stroke: stroke, lineWidth: lineWidth, }, }); arrowShape.translate(x2, y2); arrowShape.rotateAtPoint(x2, y2, rad); shape.set(isStart ? 'startArrowShape' : 'endArrowShape', arrowShape); } /** * 箭头 path 的设置要求 * 1. 箭头顶点坐标需要为 (0, 0) * 2. 箭头夹角的中心分割线需要与 X 轴正方向对齐 */ function _addCustomizedArrow(shape, attrs, x1, y1, x2, y2, isStart) { var startArrow = attrs.startArrow, endArrow = attrs.endArrow, stroke = attrs.stroke, lineWidth = attrs.lineWidth; var arrowAttrs = isStart ? startArrow : endArrow; var d = arrowAttrs.d, arrowFill = arrowAttrs.fill, arrowStroke = arrowAttrs.stroke, arrowLineWidth = arrowAttrs.lineWidth, restAttrs = tslib_1.__rest(arrowAttrs, ["d", "fill", "stroke", "lineWidth"]); var x = x1 - x2; var y = y1 - y2; var rad = atan2(y, x); if (d) { x2 = x2 - cos(rad) * d; y2 = y2 - sin(rad) * d; } var arrowShape = new shape_1.Path({ type: 'path', canvas: shape.get('canvas'), isArrowShape: true, attrs: tslib_1.__assign(tslib_1.__assign({}, restAttrs), { // 支持单独设置箭头的 stroke 和 lineWidth,若为空则使用 shape 的值 stroke: arrowStroke || stroke, lineWidth: arrowLineWidth || lineWidth, // 箭头是否填充需要手动设置,不会继承自 shape 的值 fill: arrowFill }), }); arrowShape.translate(x2, y2); arrowShape.rotateAtPoint(x2, y2, rad); shape.set(isStart ? 'startArrowShape' : 'endArrowShape', arrowShape); } /** * 如果自定义箭头并且有 d 需要做偏移,如果直接画,线条会超出箭头尖端,因此需要根据箭头偏移 d, 返回线需要缩短的距离 * |---------------- * |<|-------------- * | * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 箭头作用点 x * @param {number} y2 箭头作用点 y * @param {number} d 箭头沿线条方向的偏移距离 * @return {{dx: number, dy: number}} 返回线条偏移距离 */ function getShortenOffset(x1, y1, x2, y2, d) { var rad = atan2(y2 - y1, x2 - x1); return { dx: cos(rad) * d, dy: sin(rad) * d, }; } exports.getShortenOffset = getShortenOffset; /** * 绘制起始箭头 * @param {IShape} shape 图形 * @param {ShapeAttrs} attrs shape 的绘图属性 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 箭头作用点 x * @param {number} y2 箭头作用点 y */ function addStartArrow(shape, attrs, x1, y1, x2, y2) { if (typeof attrs.startArrow === 'object') { _addCustomizedArrow(shape, attrs, x1, y1, x2, y2, true); } else if (attrs.startArrow) { _addDefaultArrow(shape, attrs, x1, y1, x2, y2, true); } else { shape.set('startArrowShape', null); } } exports.addStartArrow = addStartArrow; /** * 绘制结束箭头 * @param {IShape} shape 图形 * @param {ShapeAttrs} attrs shape 的绘图属性 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 箭头作用点 x * @param {number} y2 箭头作用点 y */ function addEndArrow(shape, attrs, x1, y1, x2, y2) { if (typeof attrs.endArrow === 'object') { _addCustomizedArrow(shape, attrs, x1, y1, x2, y2, false); } else if (attrs.endArrow) { _addDefaultArrow(shape, attrs, x1, y1, x2, y2, false); } else { shape.set('startArrowShape', null); } } exports.addEndArrow = addEndArrow; },{"../shape":133,"tslib":894}],144:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mergeView = exports.getMergedRegion = exports.getRefreshRegion = exports.refreshElement = exports.drawPath = exports.drawChildren = exports.applyAttrsToContext = void 0; var util_1 = require("@antv/util"); var parse_1 = require("./parse"); var arc_params_1 = require("./arc-params"); var util_2 = require("./util"); var ArrowUtil = require("../util/arrow"); var SHAPE_ATTRS_MAP = { fill: 'fillStyle', stroke: 'strokeStyle', opacity: 'globalAlpha', }; function applyAttrsToContext(context, element) { var attrs = element.attr(); for (var k in attrs) { var v = attrs[k]; // 转换一下不与 canvas 兼容的属性名 var name_1 = SHAPE_ATTRS_MAP[k] ? SHAPE_ATTRS_MAP[k] : k; if (name_1 === 'matrix' && v) { // 设置矩阵 context.transform(v[0], v[1], v[3], v[4], v[6], v[7]); } else if (name_1 === 'lineDash' && context.setLineDash) { // 设置虚线,只支持数组形式,非数组形式不做任何操作 util_1.isArray(v) && context.setLineDash(v); } else { if (name_1 === 'strokeStyle' || name_1 === 'fillStyle') { // 如果存在渐变、pattern 这个开销有些大 // 可以考虑缓存机制,通过 hasUpdate 来避免一些运算 v = parse_1.parseStyle(context, element, v); } else if (name_1 === 'globalAlpha') { // opacity 效果可以叠加,子元素的 opacity 需要与父元素 opacity 相乘 v = v * context.globalAlpha; } context[name_1] = v; } } } exports.applyAttrsToContext = applyAttrsToContext; function drawChildren(context, children, region) { for (var i = 0; i < children.length; i++) { var child = children[i]; if (child.get('visible')) { child.draw(context, region); } else { child.skipDraw(); } } } exports.drawChildren = drawChildren; // 绘制 path function drawPath(shape, context, attrs, arcParamsCache) { var path = attrs.path, startArrow = attrs.startArrow, endArrow = attrs.endArrow; var currentPoint = [0, 0]; // 当前图形 var startMovePoint = [0, 0]; // 开始 M 的点,可能会有多个 var distance = { dx: 0, dy: 0, }; context.beginPath(); for (var i = 0; i < path.length; i++) { var params = path[i]; var command = params[0]; if (i === 0 && startArrow && startArrow.d) { var tangent = shape.getStartTangent(); distance = ArrowUtil.getShortenOffset(tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1], startArrow.d); } else if (i === path.length - 2 && path[i + 1][0] === 'Z' && endArrow && endArrow.d) { // 为了防止结尾为 Z 的 segment 缩短不起效,需要取最后两个 segment 特殊处理 var lastPath = path[i + 1]; if (lastPath[0] === 'Z') { var tangent = shape.getEndTangent(); distance = ArrowUtil.getShortenOffset(tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1], endArrow.d); } } else if (i === path.length - 1 && endArrow && endArrow.d) { if (path[0] !== 'Z') { var tangent = shape.getEndTangent(); distance = ArrowUtil.getShortenOffset(tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1], endArrow.d); } } var dx = distance.dx, dy = distance.dy; // V,H,S,T 都在前面被转换成标准形式 switch (command) { case 'M': context.moveTo(params[1] - dx, params[2] - dy); startMovePoint = [params[1], params[2]]; break; case 'L': context.lineTo(params[1] - dx, params[2] - dy); break; case 'Q': context.quadraticCurveTo(params[1], params[2], params[3] - dx, params[4] - dy); break; case 'C': context.bezierCurveTo(params[1], params[2], params[3], params[4], params[5] - dx, params[6] - dy); break; case 'A': { var arcParams = void 0; // 为了加速绘制,可以提供参数的缓存,各个图形自己缓存 if (arcParamsCache) { arcParams = arcParamsCache[i]; if (!arcParams) { arcParams = arc_params_1.default(currentPoint, params); arcParamsCache[i] = arcParams; } } else { arcParams = arc_params_1.default(currentPoint, params); } var cx = arcParams.cx, cy = arcParams.cy, rx = arcParams.rx, ry = arcParams.ry, startAngle = arcParams.startAngle, endAngle = arcParams.endAngle, xRotation = arcParams.xRotation, sweepFlag = arcParams.sweepFlag; // 直接使用椭圆的 api if (context.ellipse) { context.ellipse(cx, cy, rx, ry, xRotation, startAngle, endAngle, 1 - sweepFlag); } else { var r = rx > ry ? rx : ry; var scaleX = rx > ry ? 1 : rx / ry; var scaleY = rx > ry ? ry / rx : 1; context.translate(cx, cy); context.rotate(xRotation); context.scale(scaleX, scaleY); context.arc(0, 0, r, startAngle, endAngle, 1 - sweepFlag); context.scale(1 / scaleX, 1 / scaleY); context.rotate(-xRotation); context.translate(-cx, -cy); } break; } case 'Z': context.closePath(); break; default: break; } // 有了 Z 后,当前节点从开始 M 的点开始 if (command === 'Z') { currentPoint = startMovePoint; } else { var len = params.length; currentPoint = [params[len - 2], params[len - 1]]; } } } exports.drawPath = drawPath; // 刷新图形元素(Shape 或者 Group) function refreshElement(element, changeType) { var canvas = element.get('canvas'); // 只有存在于 canvas 上时生效 if (canvas) { if (changeType === 'remove') { // 一旦 remove,则无法在 element 上拿到包围盒 // destroy 后所有属性都拿不到,所以需要暂存一下 // 这是一段 hack 的代码 element._cacheCanvasBBox = element.get('cacheCanvasBBox'); } // 防止反复刷新 if (!element.get('hasChanged')) { // 本来只有局部渲染模式下,才需要记录更新的元素队列 // if (canvas.get('localRefresh')) { // canvas.refreshElement(element, changeType, canvas); // } // 但对于 https://github.com/antvis/g/issues/422 的场景,全局渲染的模式下也需要记录更新的元素队列 canvas.refreshElement(element, changeType, canvas); if (canvas.get('autoDraw')) { canvas.draw(); } element.set('hasChanged', true); } } } exports.refreshElement = refreshElement; function getRefreshRegion(element) { var region; if (!element.destroyed) { var cacheBox = element.get('cacheCanvasBBox'); var validCache = cacheBox && !!(cacheBox.width && cacheBox.height); var bbox = element.getCanvasBBox(); var validBBox = bbox && !!(bbox.width && bbox.height); // 是否是有效 bbox 判定,一些 NaN 或者 宽高为 0 的情况过滤掉 if (validCache && validBBox) { region = util_2.mergeRegion(cacheBox, bbox); } else if (validCache) { region = cacheBox; } else if (validBBox) { region = bbox; } } else { // 因为元素已经销毁所以无法获取到缓存的包围盒 region = element['_cacheCanvasBBox']; } return region; } exports.getRefreshRegion = getRefreshRegion; function getMergedRegion(elements) { if (!elements.length) { return null; } var minXArr = []; var minYArr = []; var maxXArr = []; var maxYArr = []; util_1.each(elements, function (el) { var region = getRefreshRegion(el); if (region) { minXArr.push(region.minX); minYArr.push(region.minY); maxXArr.push(region.maxX); maxYArr.push(region.maxY); } }); return { minX: Math.min.apply(null, minXArr), minY: Math.min.apply(null, minYArr), maxX: Math.max.apply(null, maxXArr), maxY: Math.max.apply(null, maxYArr), }; } exports.getMergedRegion = getMergedRegion; function mergeView(region, viewRegion) { if (!region || !viewRegion) { return null; } // 不相交,则直接返回 null if (!util_2.intersectRect(region, viewRegion)) { return null; } return { minX: Math.max(region.minX, viewRegion.minX), minY: Math.max(region.minY, viewRegion.minY), maxX: Math.min(region.maxX, viewRegion.maxX), maxY: Math.min(region.maxY, viewRegion.maxY), }; } exports.mergeView = mergeView; },{"../util/arrow":143,"./arc-params":142,"./parse":153,"./util":155,"@antv/util":803}],145:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getShape = void 0; var util_1 = require("@antv/g-base/lib/util/util"); var matrix_1 = require("@antv/g-base/lib/util/matrix"); function invertFromMatrix(v, matrix) { if (matrix) { var invertMatrix = matrix_1.invert(matrix); return matrix_1.multiplyVec2(invertMatrix, v); } return v; } function getRefXY(element, x, y) { // @ts-ignore var totalMatrix = element.getTotalMatrix(); if (totalMatrix) { var _a = invertFromMatrix([x, y, 1], totalMatrix), refX = _a[0], refY = _a[1]; return [refX, refY]; } return [x, y]; } // 拾取前的检测,只有通过检测才能继续拾取 function preTest(element, x, y) { // @ts-ignore if (element.isCanvas && element.isCanvas()) { return true; } // 不允许被拾取,则返回 null // @ts-ignore if (!util_1.isAllowCapture(element) && element.cfg.isInView === false) { return false; } if (element.cfg.clipShape) { // 如果存在 clip var _a = getRefXY(element, x, y), refX = _a[0], refY = _a[1]; if (element.isClipped(refX, refY)) { return false; } } // @ts-ignore ,这个地方调用过于频繁 var bbox = element.cfg.cacheCanvasBBox; if (!bbox) { bbox = element.getCanvasBBox(); } if (!(x >= bbox.minX && x <= bbox.maxX && y >= bbox.minY && y <= bbox.maxY)) { return false; } return true; } function getShape(container, x, y) { // 没有通过检测,则返回 null if (!preTest(container, x, y)) { return null; } var shape = null; var children = container.getChildren(); var count = children.length; for (var i = count - 1; i >= 0; i--) { var child = children[i]; if (child.isGroup()) { shape = getShape(child, x, y); } else if (preTest(child, x, y)) { var curShape = child; var _a = getRefXY(child, x, y), refX = _a[0], refY = _a[1]; // @ts-ignore if (curShape.isInShape(refX, refY)) { shape = child; } } if (shape) { break; } } return shape; } exports.getShape = getShape; },{"@antv/g-base/lib/util/matrix":119,"@antv/g-base/lib/util/util":123}],146:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var offscreen_1 = require("@antv/g-base/lib/util/offscreen"); function isPointInPath(shape, x, y) { var ctx = offscreen_1.getOffScreenContext(); shape.createPath(ctx); return ctx.isPointInPath(x, y); } exports.default = isPointInPath; },{"@antv/g-base/lib/util/offscreen":120}],147:[function(require,module,exports){ "use strict"; /** * @fileoverview 判断点是否在多边形内 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); // 多边形的射线检测,参考:https://blog.csdn.net/WilliamSun0122/article/details/77994526 var tolerance = 1e-6; // 三态函数,判断两个double在eps精度下的大小关系 function dcmp(x) { if (Math.abs(x) < tolerance) { return 0; } return x < 0 ? -1 : 1; } // 判断点Q是否在p1和p2的线段上 function onSegment(p1, p2, q) { if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) && Math.min(p1[0], p2[0]) <= q[0] && q[0] <= Math.max(p1[0], p2[0]) && Math.min(p1[1], p2[1]) <= q[1] && q[1] <= Math.max(p1[1], p2[1])) { return true; } return false; } // 判断点P在多边形内-射线法 function isInPolygon(points, x, y) { var isHit = false; var n = points.length; if (n <= 2) { // svg 中点小于 3 个时,不显示,也无法被拾取 return false; } for (var i = 0; i < n; i++) { var p1 = points[i]; var p2 = points[(i + 1) % n]; if (onSegment(p1, p2, [x, y])) { // 点在多边形一条边上 return true; } // 前一个判断min(p1[1],p2[1]) 0 !== dcmp(p2[1] - y) > 0 && dcmp(x - ((y - p1[1]) * (p1[0] - p2[0])) / (p1[1] - p2[1]) - p1[0]) < 0) { isHit = !isHit; } } return isHit; } exports.default = isInPolygon; },{}],148:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("../util"); function arc(cx, cy, r, startAngle, endAngle, lineWidth, x, y) { var angle = (Math.atan2(y - cy, x - cx) + Math.PI * 2) % (Math.PI * 2); // 转换到 0 - 2 * Math.PI 之间 if (angle < startAngle || angle > endAngle) { return false; } var point = { x: cx + r * Math.cos(angle), y: cy + r * Math.sin(angle), }; return util_1.distance(point.x, point.y, x, y) <= lineWidth / 2; } exports.default = arc; },{"../util":155}],149:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("@antv/g-math/lib/line"); function inLine(x1, y1, x2, y2, lineWidth, x, y) { var minX = Math.min(x1, x2); var maxX = Math.max(x1, x2); var minY = Math.min(y1, y2); var maxY = Math.max(y1, y2); var halfWidth = lineWidth / 2; // 因为目前的方案是计算点到直线的距离,而有可能会在延长线上,所以要先判断是否在包围盒内 // 这种方案会在水平或者竖直的情况下载线的延长线上有半 lineWidth 的误差 if (!(x >= minX - halfWidth && x <= maxX + halfWidth && y >= minY - halfWidth && y <= maxY + halfWidth)) { return false; } // 因为已经计算了包围盒,所以仅需要计算到直线的距离即可,可以显著提升性能 return line_1.default.pointToLine(x1, y1, x2, y2, x, y) <= lineWidth / 2; } exports.default = inLine; },{"@antv/g-math/lib/line":172}],150:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("./line"); function inPolyline(points, lineWidth, x, y, isClose) { var count = points.length; if (count < 2) { return false; } for (var i = 0; i < count - 1; i++) { var x1 = points[i][0]; var y1 = points[i][1]; var x2 = points[i + 1][0]; var y2 = points[i + 1][1]; if (line_1.default(x1, y1, x2, y2, lineWidth, x, y)) { return true; } } // 如果封闭,则计算起始点和结束点的边 if (isClose) { var first = points[0]; var last = points[count - 1]; if (line_1.default(first[0], first[1], last[0], last[1], lineWidth, x, y)) { return true; } } return false; } exports.default = inPolyline; },{"./line":149}],151:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("./line"); var arc_1 = require("./arc"); function rectWithRadius(minX, minY, width, height, radius, lineWidth, x, y) { var halfWidth = lineWidth / 2; return (line_1.default(minX + radius, minY, minX + width - radius, minY, lineWidth, x, y) || line_1.default(minX + width, minY + radius, minX + width, minY + height - radius, lineWidth, x, y) || line_1.default(minX + width - radius, minY + height, minX + radius, minY + height, lineWidth, x, y) || line_1.default(minX, minY + height - radius, minX, minY + radius, lineWidth, x, y) || arc_1.default(minX + width - radius, minY + radius, radius, 1.5 * Math.PI, 2 * Math.PI, lineWidth, x, y) || arc_1.default(minX + width - radius, minY + height - radius, radius, 0, 0.5 * Math.PI, lineWidth, x, y) || arc_1.default(minX + radius, minY + height - radius, radius, 0.5 * Math.PI, Math.PI, lineWidth, x, y) || arc_1.default(minX + radius, minY + radius, radius, Math.PI, 1.5 * Math.PI, lineWidth, x, y)); } exports.default = rectWithRadius; },{"./arc":148,"./line":149}],152:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("../util"); function inRect(minX, minY, width, height, lineWidth, x, y) { var halfWidth = lineWidth / 2; // 将四个边看做矩形来检测,比边的检测算法要快 return (util_1.inBox(minX - halfWidth, minY - halfWidth, width, lineWidth, x, y) || // 上边 util_1.inBox(minX + width - halfWidth, minY - halfWidth, lineWidth, height, x, y) || // 右边 util_1.inBox(minX + halfWidth, minY + height - halfWidth, width, lineWidth, x, y) || // 下边 util_1.inBox(minX - halfWidth, minY + halfWidth, lineWidth, height, x, y)); // 左边 } exports.default = inRect; },{"../util":155}],153:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseRadius = exports.parseStyle = exports.parsePattern = exports.parseRadialGradient = exports.parseLineGradient = void 0; var util_1 = require("./util"); var regexTags = /[MLHVQTCSAZ]([^MLHVQTCSAZ]*)/gi; var regexDot = /[^\s\,]+/gi; var regexLG = /^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i; var regexRG = /^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i; var regexPR = /^p\s*\(\s*([axyn])\s*\)\s*(.*)/i; var regexColorStop = /[\d.]+:(#[^\s]+|[^\)]+\))/gi; function addStop(steps, gradient) { var arr = steps.match(regexColorStop); util_1.each(arr, function (item) { var itemArr = item.split(':'); gradient.addColorStop(itemArr[0], itemArr[1]); }); } /** * 将边和填充设置的颜色转换成线性渐变对象 * @param {CanvasRenderingContext2D} context canvas 上下文 * @param {IElement} element 图形元素 * @param {string} gradientStr 颜色 * @returns {any} 渐变对象 */ function parseLineGradient(context, element, gradientStr) { var arr = regexLG.exec(gradientStr); var angle = (parseFloat(arr[1]) % 360) * (Math.PI / 180); var steps = arr[2]; var box = element.getBBox(); var start; var end; if (angle >= 0 && angle < (1 / 2) * Math.PI) { start = { x: box.minX, y: box.minY, }; end = { x: box.maxX, y: box.maxY, }; } else if ((1 / 2) * Math.PI <= angle && angle < Math.PI) { start = { x: box.maxX, y: box.minY, }; end = { x: box.minX, y: box.maxY, }; } else if (Math.PI <= angle && angle < (3 / 2) * Math.PI) { start = { x: box.maxX, y: box.maxY, }; end = { x: box.minX, y: box.minY, }; } else { start = { x: box.minX, y: box.maxY, }; end = { x: box.maxX, y: box.minY, }; } var tanTheta = Math.tan(angle); var tanTheta2 = tanTheta * tanTheta; var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x; var y = (tanTheta * (end.x - start.x + tanTheta * (end.y - start.y))) / (tanTheta2 + 1) + start.y; var gradient = context.createLinearGradient(start.x, start.y, x, y); addStop(steps, gradient); return gradient; } exports.parseLineGradient = parseLineGradient; /** * 将边和填充设置的颜色转换成圆形渐变对象 * @param {CanvasRenderingContext2D} context canvas 上下文 * @param {IElement} element 图形元素 * @param {string} gradientStr 颜色 * @returns {any} 渐变对象 */ function parseRadialGradient(context, element, gradientStr) { var arr = regexRG.exec(gradientStr); var fx = parseFloat(arr[1]); var fy = parseFloat(arr[2]); var fr = parseFloat(arr[3]); var steps = arr[4]; // 环半径为0时,默认无渐变,取渐变序列的最后一个颜色 if (fr === 0) { var colors = steps.match(regexColorStop); return colors[colors.length - 1].split(':')[1]; } var box = element.getBBox(); var width = box.maxX - box.minX; var height = box.maxY - box.minY; var r = Math.sqrt(width * width + height * height) / 2; var gradient = context.createRadialGradient(box.minX + width * fx, box.minY + height * fy, 0, box.minX + width / 2, box.minY + height / 2, fr * r); addStop(steps, gradient); return gradient; } exports.parseRadialGradient = parseRadialGradient; /** * 边和填充设置的颜色转换成 pattern * @param {CanvasRenderingContext2D} context canvas 上下文 * @param {IElement} element 图形元素 * @param {string} patternStr 生成 pattern 的字符串 */ function parsePattern(context, element, patternStr) { // 在转换过程中进行了缓存 if (element.get('patternSource') && element.get('patternSource') === patternStr) { return element.get('pattern'); } var pattern; var img; var arr = regexPR.exec(patternStr); var repeat = arr[1]; var source = arr[2]; // Function to be called when pattern loads function onload() { // Create pattern pattern = context.createPattern(img, repeat); element.set('pattern', pattern); // be a cache element.set('patternSource', patternStr); } switch (repeat) { case 'a': repeat = 'repeat'; break; case 'x': repeat = 'repeat-x'; break; case 'y': repeat = 'repeat-y'; break; case 'n': repeat = 'no-repeat'; break; default: repeat = 'no-repeat'; } img = new Image(); // If source URL is not a data URL if (!source.match(/^data:/i)) { // Set crossOrigin for this image img.crossOrigin = 'Anonymous'; } img.src = source; if (img.complete) { onload(); } else { img.onload = onload; // Fix onload() bug in IE9 img.src = img.src; } return pattern; } exports.parsePattern = parsePattern; function parseStyle(context, element, color) { if (util_1.isString(color)) { if (color[1] === '(' || color[2] === '(') { if (color[0] === 'l') { // regexLG.test(color) return parseLineGradient(context, element, color); } if (color[0] === 'r') { // regexRG.test(color) return parseRadialGradient(context, element, color); } if (color[0] === 'p') { // regexPR.test(color) return parsePattern(context, element, color); } } return color; } } exports.parseStyle = parseStyle; function parseRadius(radius) { var r1 = 0; var r2 = 0; var r3 = 0; var r4 = 0; if (util_1.isArray(radius)) { if (radius.length === 1) { r1 = r2 = r3 = r4 = radius[0]; } else if (radius.length === 2) { r1 = r3 = radius[0]; r2 = r4 = radius[1]; } else if (radius.length === 3) { r1 = radius[0]; r2 = r4 = radius[1]; r3 = radius[2]; } else { r1 = radius[0]; r2 = radius[1]; r3 = radius[2]; r4 = radius[3]; } } else { r1 = r2 = r3 = r4 = radius; } return [r1, r2, r3, r4]; } exports.parseRadius = parseRadius; },{"./util":155}],154:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * @fileoverview path 的一些工具 * @author dxq613@gmail.com */ var g_base_1 = require("@antv/g-base"); var quadratic_1 = require("@antv/g-math/lib/quadratic"); var cubic_1 = require("@antv/g-math/lib/cubic"); var util_1 = require("./util"); var line_1 = require("./in-stroke/line"); var arc_1 = require("./in-stroke/arc"); var mat3 = require("gl-matrix/mat3"); var vec3 = require("gl-matrix/vec3"); function hasArc(path) { var hasArc = false; var count = path.length; for (var i = 0; i < count; i++) { var params = path[i]; var cmd = params[0]; if (cmd === 'C' || cmd === 'A' || cmd === 'Q') { hasArc = true; break; } } return hasArc; } function isPointInStroke(segments, lineWidth, x, y) { var isHit = false; var halfWidth = lineWidth / 2; for (var i = 0; i < segments.length; i++) { var segment = segments[i]; var currentPoint = segment.currentPoint, params = segment.params, prePoint = segment.prePoint, box = segment.box; // 如果在前面已经生成过包围盒,直接按照包围盒计算 if (box && !util_1.inBox(box.x - halfWidth, box.y - halfWidth, box.width + lineWidth, box.height + lineWidth, x, y)) { continue; } switch (segment.command) { // L 和 Z 都是直线, M 不进行拾取 case 'L': case 'Z': isHit = line_1.default(prePoint[0], prePoint[1], currentPoint[0], currentPoint[1], lineWidth, x, y); break; case 'Q': var qDistance = quadratic_1.default.pointDistance(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], x, y); isHit = qDistance <= lineWidth / 2; break; case 'C': var cDistance = cubic_1.default.pointDistance(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], params[5], params[6], x, y); isHit = cDistance <= lineWidth / 2; break; case 'A': // 计算点到椭圆圆弧的距离,暂时使用近似算法,后面可以改成切割法求最近距离 var arcParams = segment.arcParams; var cx = arcParams.cx, cy = arcParams.cy, rx = arcParams.rx, ry = arcParams.ry, startAngle = arcParams.startAngle, endAngle = arcParams.endAngle, xRotation = arcParams.xRotation; var p = [x, y, 1]; var m = [1, 0, 0, 0, 1, 0, 0, 0, 1]; var r = rx > ry ? rx : ry; var scaleX = rx > ry ? 1 : rx / ry; var scaleY = rx > ry ? ry / rx : 1; mat3.translate(m, m, [-cx, -cy]); mat3.rotate(m, m, -xRotation); mat3.scale(m, m, [1 / scaleX, 1 / scaleY]); vec3.transformMat3(p, p, m); isHit = arc_1.default(0, 0, r, startAngle, endAngle, lineWidth, p[0], p[1]); break; default: break; } if (isHit) { break; } } return isHit; } /** * 提取出内部的闭合多边形和非闭合的多边形,假设 path 不存在圆弧 * @param {Array} path 路径 * @returns {Array} 点的集合 */ function extractPolygons(path) { var count = path.length; var polygons = []; var polylines = []; var points = []; // 防止第一个命令不是 'M' for (var i = 0; i < count; i++) { var params = path[i]; var cmd = params[0]; if (cmd === 'M') { // 遇到 'M' 判定是否是新数组,新数组中没有点 if (points.length) { // 如果存在点,则说明没有遇到 'Z',开始了一个新的多边形 polylines.push(points); points = []; // 创建新的点 } points.push([params[1], params[2]]); } else if (cmd === 'Z') { if (points.length) { // 存在点 polygons.push(points); points = []; // 开始新的点集合 } // 如果不存在点,同时 'Z',则说明是错误,不处理 } else { points.push([params[1], params[2]]); } } // 说明 points 未放入 polygons 或者 polyline // 仅当只有一个 M,没有 Z 时会发生这种情况 if (points.length > 0) { polylines.push(points); } return { polygons: polygons, polylines: polylines, }; } exports.default = tslib_1.__assign({ hasArc: hasArc, extractPolygons: extractPolygons, isPointInStroke: isPointInStroke }, g_base_1.PathUtil); },{"./in-stroke/arc":148,"./in-stroke/line":149,"./util":155,"@antv/g-base":115,"@antv/g-math/lib/cubic":170,"@antv/g-math/lib/quadratic":174,"gl-matrix/mat3":886,"gl-matrix/vec3":891,"tslib":894}],155:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isSamePoint = exports.mergeRegion = exports.intersectRect = exports.inBox = exports.distance = exports.getPixelRatio = void 0; function getPixelRatio() { return window ? window.devicePixelRatio : 1; } exports.getPixelRatio = getPixelRatio; /** * 两点之间的距离 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y */ function distance(x1, y1, x2, y2) { var dx = x1 - x2; var dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); } exports.distance = distance; /** * 是否在包围盒内 * @param {number} minX 包围盒开始的点 x * @param {number} minY 包围盒开始的点 y * @param {number} width 宽度 * @param {number} height 高度 * @param {[type]} x 检测点的 x * @param {[type]} y 监测点的 y */ function inBox(minX, minY, width, height, x, y) { return x >= minX && x <= minX + width && y >= minY && y <= minY + height; } exports.inBox = inBox; function intersectRect(box1, box2) { return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY); } exports.intersectRect = intersectRect; // 合并两个区域 function mergeRegion(region1, region2) { if (!region1 || !region2) { return region1 || region2; } return { minX: Math.min(region1.minX, region2.minX), minY: Math.min(region1.minY, region2.minY), maxX: Math.max(region1.maxX, region2.maxX), maxY: Math.max(region1.maxY, region2.maxY), }; } exports.mergeRegion = mergeRegion; /** * 判断两个点是否重合,点坐标的格式为 [x, y] * @param {Array} point1 第一个点 * @param {Array} point2 第二个点 */ function isSamePoint(point1, point2) { return point1[0] === point2[0] && point1[1] === point2[1]; } exports.isSamePoint = isSamePoint; var is_nil_1 = require("@antv/util/lib/is-nil"); Object.defineProperty(exports, "isNil", { enumerable: true, get: function () { return is_nil_1.default; } }); var is_string_1 = require("@antv/util/lib/is-string"); Object.defineProperty(exports, "isString", { enumerable: true, get: function () { return is_string_1.default; } }); var is_function_1 = require("@antv/util/lib/is-function"); Object.defineProperty(exports, "isFunction", { enumerable: true, get: function () { return is_function_1.default; } }); var is_array_1 = require("@antv/util/lib/is-array"); Object.defineProperty(exports, "isArray", { enumerable: true, get: function () { return is_array_1.default; } }); var each_1 = require("@antv/util/lib/each"); Object.defineProperty(exports, "each", { enumerable: true, get: function () { return each_1.default; } }); var to_radian_1 = require("@antv/util/lib/to-radian"); Object.defineProperty(exports, "toRadian", { enumerable: true, get: function () { return to_radian_1.default; } }); var mod_1 = require("@antv/util/lib/mod"); Object.defineProperty(exports, "mod", { enumerable: true, get: function () { return mod_1.default; } }); var is_number_equal_1 = require("@antv/util/lib/is-number-equal"); Object.defineProperty(exports, "isNumberEqual", { enumerable: true, get: function () { return is_number_equal_1.default; } }); var request_animation_frame_1 = require("@antv/util/lib/request-animation-frame"); Object.defineProperty(exports, "requestAnimationFrame", { enumerable: true, get: function () { return request_animation_frame_1.default; } }); var clear_animation_frame_1 = require("@antv/util/lib/clear-animation-frame"); Object.defineProperty(exports, "clearAnimationFrame", { enumerable: true, get: function () { return clear_animation_frame_1.default; } }); },{"@antv/util/lib/clear-animation-frame":772,"@antv/util/lib/each":778,"@antv/util/lib/is-array":806,"@antv/util/lib/is-function":817,"@antv/util/lib/is-nil":821,"@antv/util/lib/is-number-equal":823,"@antv/util/lib/is-string":832,"@antv/util/lib/mod":845,"@antv/util/lib/request-animation-frame":854,"@antv/util/lib/to-radian":865}],156:[function(require,module,exports){ module.exports={ "__npminstall_done": false, "_args": [ [ "@antv/g-canvas@0.4.14", "C:\\xampp\\htdocs\\icehrm\\web" ] ], "_from": "@antv/g-canvas@0.4.14", "_id": "@antv/g-canvas@0.4.14", "_inBundle": false, "_integrity": "sha512-BPpEbHvszEPQHhssPQrIOF2zKztiogabhiBQ/MCX3qvLUXgBRRzN6ktwS816fQPa82RYiGUmzEUDhgCXUWXAcg==", "_location": "/@antv/g-canvas", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, "raw": "@antv/g-canvas@0.4.14", "name": "@antv/g-canvas", "escapedName": "@antv%2fg-canvas", "scope": "@antv", "rawSpec": "0.4.14", "saveSpec": null, "fetchSpec": "0.4.14" }, "_requiredBy": [ "/@antv/g2", "/@antv/g2plot" ], "_resolved": "https://registry.npmjs.org/@antv/g-canvas/-/g-canvas-0.4.14.tgz", "_spec": "0.4.14", "_where": "C:\\xampp\\htdocs\\icehrm\\web", "author": { "name": "https://github.com/orgs/antvis/people" }, "bugs": { "url": "https://github.com/antvis/g/issues" }, "dependencies": { "@antv/g-base": "^0.4.7", "@antv/g-math": "^0.1.3", "@antv/path-util": "~2.0.5", "@antv/util": "~2.0.0", "gl-matrix": "^3.0.0" }, "description": "A canvas library which providing 2d", "devDependencies": { "@antv/torch": "^1.0.0", "less": "^3.9.0", "npm-run-all": "^4.1.5", "webpack": "^4.26.1", "webpack-cli": "^3.1.2" }, "files": [ "package.json", "esm", "lib", "dist", "LICENSE", "README.md" ], "gitHead": "6b4107c8cfae1b893c385758ad8e870236f73f6b", "homepage": "https://github.com/antvis/g#readme", "keywords": [ "util", "antv", "g" ], "license": "ISC", "main": "lib/index.js", "module": "esm/index.js", "name": "@antv/g-canvas", "publishConfig": { "access": "public" }, "repository": { "type": "git", "url": "git+https://github.com/antvis/g.git" }, "scripts": { "build": "npm run clean && run-p build:*", "build:cjs": "tsc -p tsconfig.json --target ES5 --module commonjs --outDir lib", "build:esm": "tsc -p tsconfig.json --target ES5 --module ESNext --outDir esm", "build:umd": "webpack --config webpack.config.js --mode production", "clean": "rm -rf esm lib dist", "coverage": "npm run coverage-generator && npm run coverage-viewer", "coverage-generator": "torch --coverage --compile --source-pattern src/*.js,src/**/*.js --opts tests/mocha.opts", "coverage-viewer": "torch-coverage", "dist": "webpack --config webpack.config.js --mode production", "test": "torch --renderer --compile --opts tests/mocha.opts", "test-live": "torch --compile --interactive --opts tests/mocha.opts", "tsc": "tsc --noEmit", "typecheck": "tsc --noEmit" }, "types": "lib/index.d.ts", "unpkg": "dist/g.min.js", "version": "0.4.14" } },{}],157:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var wheel_1 = require("./wheel"); exports.Wheel = wheel_1.Wheel; },{"./wheel":158}],158:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = require("@antv/event-emitter"); var d3Ease = require("d3-ease"); var gm_1 = require("../gm"); var clock_1 = require("../utils/clock"); // 看那个曲线跟合适了 var ease = d3Ease.easeCubicIn; var TOTAL_MS = 800; // 惯性滚动时间;调参工程师,或者根据速度来计算这个时间 var SWIPE = 'swipe'; var PAN = 'pan'; var WHEEL = 'wheel'; /** * 给 view 添加移动端的滚动能力: * - 监听 touch 事件,emit wheel 事件 * - 滚动惯性包装 * - 和 pc 的 wheel 事件保持基本一致 */ var Wheel = /** @class */ (function (_super) { tslib_1.__extends(Wheel, _super); function Wheel(element) { var _this = _super.call(this) || this; _this.rafMs = 0; /** * pan 事件 * @param ev */ _this.onPan = function (ev) { var deltaX = ev.deltaX, deltaY = ev.deltaY; var e = _this.getWrapperEvent(ev, deltaX, deltaY); _this.emit(WHEEL, e); }; /** * 当出现 swipe 事件的时候 * @param ev */ _this.onSwipe = function (ev) { var speedX = ev.speedX, speedY = ev.speedY; // raf 循环执行的时间戳 _this.rafMs = clock_1.clock.now(); _this.ms = _this.rafMs; // 对于没有滑动的情况下,不做处理 if (speedX !== 0 || speedY !== 0) { _this.rafInertia(ev); } }; _this.element = element; _this.gm = new gm_1.GM(element, { gestures: ['Pan', 'Swipe'] }); _this.gm.on(SWIPE, _this.onSwipe); _this.gm.on(PAN, _this.onPan); return _this; } Wheel.prototype.destroy = function () { window.cancelAnimationFrame(this.raf); this.gm.destroy(); this.off(); }; // 使用 raf 进行惯性滑动 Wheel.prototype.rafInertia = function (ev) { var _this = this; var speedX = ev.speedX, speedY = ev.speedY; this.raf = window.requestAnimationFrame(function () { var now = clock_1.clock.now(); var ratio = (now - _this.ms) / TOTAL_MS; if (ratio < 1) { ratio = ease(1 - ratio); // 折损之后的速度 * 时间,等于距离 var t = now - _this.rafMs; var movedX = speedX * ratio * t; var movedY = speedY * ratio * t; var e = _this.getWrapperEvent(ev, movedX, movedY); // 发出 wheel 事件 _this.emit(WHEEL, e); _this.rafMs = now; // 记录时间 // 进行下一次 _this.rafInertia(ev); } }); }; Wheel.prototype.getWrapperEvent = function (ev, deltaX, deltaY) { // 移动端的滑动应该是跟随手指 return tslib_1.__assign(tslib_1.__assign({}, ev), { deltaX: -deltaX, deltaY: -deltaY }); }; return Wheel; }(event_emitter_1.default)); exports.Wheel = Wheel; },{"../gm":165,"../utils/clock":167,"@antv/event-emitter":94,"d3-ease":876,"tslib":894}],159:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Gesture = /** @class */ (function () { function Gesture(gm) { this.EVENT = 'gesture'; this.gm = gm; } /** * 处理事件 * @param ev */ Gesture.prototype.do = function (ev) { var type = ev.type; switch (type) { case 'touchstart': this.onTouchStart(ev); break; case 'touchmove': this.onTouchMove(ev); break; case 'touchend': this.onTouchEnd(ev); break; case 'touchcancel': this.onTouchCancel(ev); break; default: return; } }; /** * 触发事件 * @param e */ Gesture.prototype.emit = function (e) { this.gm.emit(this.EVENT, e); }; return Gesture; }()); exports.Gesture = Gesture; },{}],160:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gesture_1 = require("./gesture"); exports.Gesture = gesture_1.Gesture; var pan_1 = require("./pan"); var press_1 = require("./press"); var swipe_1 = require("./swipe"); var tap_1 = require("./tap"); var MAP = { Pan: pan_1.Pan, Press: press_1.Press, Swipe: swipe_1.Swipe, Tap: tap_1.Tap, }; exports.getGesture = function (g) { return MAP[g]; }; },{"./gesture":159,"./pan":161,"./press":162,"./swipe":163,"./tap":164}],161:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var gesture_1 = require("./gesture"); var Pan = /** @class */ (function (_super) { tslib_1.__extends(Pan, _super); function Pan() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.EVENT = 'pan'; return _this; } Pan.prototype.onTouchCancel = function (ev) { }; Pan.prototype.onTouchEnd = function (ev) { }; Pan.prototype.onTouchMove = function (ev) { var x = ev.x, y = ev.y; var deltaX = x - this.preX; var deltaY = y - this.preY; this.preX = x; this.preY = y; this.emit({ x: x, y: y, deltaX: deltaX, deltaY: deltaY, event: ev }); }; Pan.prototype.onTouchStart = function (ev) { var x = ev.x, y = ev.y; this.preX = x; this.preY = y; }; return Pan; }(gesture_1.Gesture)); exports.Pan = Pan; },{"./gesture":159,"tslib":894}],162:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var clock_1 = require("../utils/clock"); var gesture_1 = require("./gesture"); var TIME = 300; var DISTANCE = 10; var Press = /** @class */ (function (_super) { tslib_1.__extends(Press, _super); function Press() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.EVENT = 'press'; return _this; } Press.prototype.onTouchCancel = function (ev) { this.clearTimeout(); }; Press.prototype.onTouchEnd = function (ev) { this.clearTimeout(); }; Press.prototype.onTouchMove = function (ev) { var x = ev.x, y = ev.y; if (x - this.touchStartX > DISTANCE || y - this.touchStartY > DISTANCE) { this.clearTimeout(); } }; Press.prototype.onTouchStart = function (ev) { var _this = this; this.clearTimeout(); var x = ev.x, y = ev.y; this.touchStartTime = clock_1.clock.now(); this.touchStartX = x; this.touchStartY = y; this.pressTimeout = window.setTimeout(function () { _this.emit({ x: x, y: y, event: ev }); }, TIME); }; Press.prototype.clearTimeout = function () { window.clearTimeout(this.pressTimeout); }; return Press; }(gesture_1.Gesture)); exports.Press = Press; },{"../utils/clock":167,"./gesture":159,"tslib":894}],163:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var clock_1 = require("../utils/clock"); var gesture_1 = require("./gesture"); var SWIPE_TIME_GAP = 100; var Swipe = /** @class */ (function (_super) { tslib_1.__extends(Swipe, _super); function Swipe() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.EVENT = 'swipe'; // 最后一次 move 的事件,用于区分 swipe 和 pan _this.latestMoveTime = 0; // 最后交互的时间,用于计算速度 _this.ms = 0; // 最后的 move 速度,用于touchend 之后做惯性 _this.speedX = 0; _this.speedY = 0; // 最后 move 的 x,y 位置 _this.preX = 0; _this.preY = 0; return _this; } Swipe.prototype.onTouchCancel = function (ev) { }; Swipe.prototype.onTouchEnd = function (ev) { var speedX = this.speedX; var speedY = this.speedY; if (clock_1.clock.now() - this.latestMoveTime < SWIPE_TIME_GAP) { var x = ev.x, y = ev.y; // 抛出事件 this.emit({ x: x, y: y, speedX: speedX, speedY: speedY, event: ev }); } }; Swipe.prototype.onTouchMove = function (ev) { var x = ev.x, y = ev.y; var ms = clock_1.clock.now(); // 1. 计算 wheel 偏移 var deltaX = x - this.preX; var deltaY = y - this.preY; var deltaTime = ms - this.ms; // 2. 计算速度(简版吧) this.speedX = deltaX / deltaTime; this.speedY = deltaY / deltaTime; // 记录最后一次移动事件 this.latestMoveTime = ms; }; Swipe.prototype.onTouchStart = function (ev) { var x = ev.x, y = ev.y; // 初始化 this.speedX = this.speedY = 0; this.preX = x; this.preY = y; this.ms = clock_1.clock.now(); }; return Swipe; }(gesture_1.Gesture)); exports.Swipe = Swipe; },{"../utils/clock":167,"./gesture":159,"tslib":894}],164:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var clock_1 = require("../utils/clock"); var gesture_1 = require("./gesture"); var TIME = 300; var DISTANCE = 2; var Tap = /** @class */ (function (_super) { tslib_1.__extends(Tap, _super); function Tap() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.EVENT = 'tap'; return _this; } Tap.prototype.onTouchCancel = function (ev) { }; Tap.prototype.onTouchEnd = function (ev) { var x = ev.x, y = ev.y; if (x - this.touchStartX < DISTANCE && y - this.touchStartY < DISTANCE && clock_1.clock.now() - this.touchStartTime < TIME) { this.emit({ x: x, y: y, event: ev }); } }; Tap.prototype.onTouchMove = function (ev) { }; Tap.prototype.onTouchStart = function (ev) { var x = ev.x, y = ev.y; this.touchStartTime = clock_1.clock.now(); this.touchStartX = x; this.touchStartY = y; }; return Tap; }(gesture_1.Gesture)); exports.Tap = Tap; },{"../utils/clock":167,"./gesture":159,"tslib":894}],165:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = require("@antv/event-emitter"); var gestures_1 = require("./gestures"); /** * 给 view 添加移动端的滚动能力: * - 监听 touch 事件,emit wheel 事件 * - 滚动惯性包装 * - 和 pc 的 wheel 事件保持基本一致 */ var GM = /** @class */ (function (_super) { tslib_1.__extends(GM, _super); function GM(element, options) { if (options === void 0) { options = {}; } var _this = _super.call(this) || this; /** * touchstart 触发 * @param ev */ _this.onTouchStart = function (ev) { _this.preventEvent(ev); _this.element.on('touchmove', _this.onTouchMove); _this.element.on('touchend', _this.onTouchEnd); _this.element.on('touchcancel', _this.onTouchCancel); _this.emit('touchdown', ev); _this.doGestures(ev); }; /** * touchmove 触发 * @param ev */ _this.onTouchMove = function (ev) { _this.preventEvent(ev); _this.emit('touchmove', ev); _this.doGestures(ev); }; /** * touchend 触发 * @param ev */ _this.onTouchEnd = function (ev) { _this.preventEvent(ev); _this.emit('touchend', ev); _this.element.off('touchmove', _this.onTouchMove); _this.element.off('touchend', _this.onTouchEnd); _this.element.off('touchcancel', _this.onTouchCancel); _this.doGestures(ev); }; /** * touchcancel 触发 * @param ev */ _this.onTouchCancel = function (ev) { _this.preventEvent(ev); _this.emit('touchcancel', ev); _this.element.off('touchmove', _this.onTouchMove); _this.element.off('touchend', _this.onTouchEnd); _this.element.off('touchcancel', _this.onTouchCancel); _this.doGestures(ev); }; _this.element = element; _this.options = options; _this.initialGestures(); _this.bindTouchStart(); return _this; } /** * 销毁,取消事件绑定 */ GM.prototype.destroy = function () { this.element.off('touchstart', this.onTouchStart); this.off(); }; /** * 实例化手势 */ GM.prototype.initialGestures = function () { var _this = this; var gestures = this.options.gestures || ['Pan', 'Press', 'Swipe', 'Tap']; this.gestures = gestures.map(function (gesture) { var Ctor = gestures_1.getGesture(gesture); return new Ctor(_this); }); }; /** * 绑定 touchstart 事件 */ GM.prototype.bindTouchStart = function () { this.element.on('touchstart', this.onTouchStart); }; GM.prototype.preventEvent = function (ev) { var type = ev.type; var prevents = this.options.prevents || []; if (prevents.includes(type)) { ev.preventDefault(); } }; GM.prototype.doGestures = function (ev) { this.gestures.forEach(function (g) { g.do(ev); }); }; return GM; }(event_emitter_1.default)); exports.GM = GM; },{"./gestures":160,"@antv/event-emitter":94,"tslib":894}],166:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gm_1 = require("./gm"); exports.GM = gm_1.GM; // 包装的上层 wheel 事件 var event_1 = require("./event"); exports.Wheel = event_1.Wheel; },{"./event":157,"./gm":165}],167:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // 时钟 exports.clock = typeof performance === 'object' && performance.now ? performance : Date; },{}],168:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); var ellipse_1 = require("./ellipse"); // 偏导数 x function derivativeXAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle) { return -1 * rx * Math.cos(xRotation) * Math.sin(angle) - ry * Math.sin(xRotation) * Math.cos(angle); } // 偏导数 y function derivativeYAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle) { return -1 * rx * Math.sin(xRotation) * Math.sin(angle) + ry * Math.cos(xRotation) * Math.cos(angle); } // x 的极值 function xExtrema(rx, ry, xRotation) { return Math.atan((-ry / rx) * Math.tan(xRotation)); } // y 的极值 function yExtrema(rx, ry, xRotation) { return Math.atan(ry / (rx * Math.tan(xRotation))); } // 根据角度求 x 坐标 function xAt(cx, cy, rx, ry, xRotation, angle) { return rx * Math.cos(xRotation) * Math.cos(angle) - ry * Math.sin(xRotation) * Math.sin(angle) + cx; } // 根据角度求 y 坐标 function yAt(cx, cy, rx, ry, xRotation, angle) { return rx * Math.sin(xRotation) * Math.cos(angle) + ry * Math.cos(xRotation) * Math.sin(angle) + cy; } // 获取点在椭圆上的角度 function getAngle(rx, ry, x0, y0) { var angle = Math.atan2(y0 * rx, x0 * ry); // 转换到 0 - 2PI 内 return (angle + Math.PI * 2) % (Math.PI * 2); } // 根据角度获取,x,y function getPoint(rx, ry, angle) { return { x: rx * Math.cos(angle), y: ry * Math.sin(angle), }; } // 旋转 function rotate(x, y, angle) { var cos = Math.cos(angle); var sin = Math.sin(angle); return [x * cos - y * sin, x * sin + y * cos]; } exports.default = { /** * 计算包围盒 * @param {number} cx 圆心 x * @param {number} cy 圆心 y * @param {number} rx x 轴方向的半径 * @param {number} ry y 轴方向的半径 * @param {number} xRotation 旋转角度 * @param {number} startAngle 起始角度 * @param {number} endAngle 结束角度 * @return {object} 包围盒对象 */ box: function (cx, cy, rx, ry, xRotation, startAngle, endAngle) { var xDim = xExtrema(rx, ry, xRotation); var minX = Infinity; var maxX = -Infinity; var xs = [startAngle, endAngle]; for (var i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) { var xAngle = xDim + i; if (startAngle < endAngle) { if (startAngle < xAngle && xAngle < endAngle) { xs.push(xAngle); } } else { if (endAngle < xAngle && xAngle < startAngle) { xs.push(xAngle); } } } for (var i = 0; i < xs.length; i++) { var x = xAt(cx, cy, rx, ry, xRotation, xs[i]); if (x < minX) { minX = x; } if (x > maxX) { maxX = x; } } var yDim = yExtrema(rx, ry, xRotation); var minY = Infinity; var maxY = -Infinity; var ys = [startAngle, endAngle]; for (var i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) { var yAngle = yDim + i; if (startAngle < endAngle) { if (startAngle < yAngle && yAngle < endAngle) { ys.push(yAngle); } } else { if (endAngle < yAngle && yAngle < startAngle) { ys.push(yAngle); } } } for (var i = 0; i < ys.length; i++) { var y = yAt(cx, cy, rx, ry, xRotation, ys[i]); if (y < minY) { minY = y; } if (y > maxY) { maxY = y; } } return { x: minX, y: minY, width: maxX - minX, height: maxY - minY, }; }, /** * 获取圆弧的长度,计算圆弧长度时不考虑旋转角度, * 仅跟 rx, ry, startAngle, endAngle 相关 * @param {number} cx 圆心 x * @param {number} cy 圆心 y * @param {number} rx x 轴方向的半径 * @param {number} ry y 轴方向的半径 * @param {number} xRotation 旋转角度 * @param {number} startAngle 起始角度 * @param {number} endAngle 结束角度 */ length: function (cx, cy, rx, ry, xRotation, startAngle, endAngle) { }, /** * 获取指定点到圆弧的最近距离的点 * @param {number} cx 圆心 x * @param {number} cy 圆心 y * @param {number} rx x 轴方向的半径 * @param {number} ry y 轴方向的半径 * @param {number} xRotation 旋转角度 * @param {number} startAngle 起始角度 * @param {number} endAngle 结束角度 * @param {number} x0 指定点的 x * @param {number} y0 指定点的 y * @return {object} 到指定点最近距离的点 */ nearestPoint: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, x0, y0) { // 将最近距离问题转换成到椭圆中心 0,0 没有旋转的椭圆问题 var relativeVector = rotate(x0 - cx, y0 - cy, -xRotation); var x1 = relativeVector[0], y1 = relativeVector[1]; // 计算点到椭圆的最近的点 var relativePoint = ellipse_1.default.nearestPoint(0, 0, rx, ry, x1, y1); // 获取点在椭圆上的角度 var angle = getAngle(rx, ry, relativePoint.x, relativePoint.y); // 点没有在圆弧上 if (angle < startAngle) { // 小于起始圆弧 relativePoint = getPoint(rx, ry, startAngle); } else if (angle > endAngle) { // 大于结束圆弧 relativePoint = getPoint(rx, ry, endAngle); } // 旋转到 xRotation 的角度 var vector = rotate(relativePoint.x, relativePoint.y, xRotation); return { x: vector[0] + cx, y: vector[1] + cy, }; }, pointDistance: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, x0, y0) { var nearestPoint = this.nearestPoint(cx, cy, rx, ry, x0, y0); return util_1.distance(nearestPoint.x, nearestPoint.y, x0, y0); }, pointAt: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, t) { var angle = (endAngle - startAngle) * t + startAngle; return { x: xAt(cx, cy, rx, ry, xRotation, angle), y: yAt(cx, cy, rx, ry, xRotation, angle), }; }, tangentAngle: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, t) { var angle = (endAngle - startAngle) * t + startAngle; var dx = derivativeXAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle); var dy = derivativeYAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle); return util_1.piMod(Math.atan2(dy, dx)); }, }; },{"./ellipse":171,"./util":176}],169:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.snapLength = exports.nearestPoint = void 0; var util_1 = require("./util"); var EPSILON = 0.0001; /** * 使用牛顿切割法求最近的点 * @param {number[]} xArr 点的 x 数组 * @param {number[]} yArr 点的 y 数组 * @param {number} x 指定的点 x * @param {number} y 指定的点 y * @param {Function} tCallback 差值函数 */ function nearestPoint(xArr, yArr, x, y, tCallback, length) { var t; var d = Infinity; var v0 = [x, y]; var segNum = 20; if (length && length > 200) { segNum = length / 10; } var increaseRate = 1 / segNum; var interval = increaseRate / 10; for (var i = 0; i <= segNum; i++) { var _t = i * increaseRate; var v1 = [tCallback.apply(null, xArr.concat([_t])), tCallback.apply(null, yArr.concat([_t]))]; var d1 = util_1.distance(v0[0], v0[1], v1[0], v1[1]); if (d1 < d) { t = _t; d = d1; } } // 提前终止 if (t === 0) { return { x: xArr[0], y: yArr[0], }; } if (t === 1) { var count = xArr.length; return { x: xArr[count - 1], y: yArr[count - 1], }; } d = Infinity; for (var i = 0; i < 32; i++) { if (interval < EPSILON) { break; } var prev = t - interval; var next = t + interval; var v1 = [tCallback.apply(null, xArr.concat([prev])), tCallback.apply(null, yArr.concat([prev]))]; var d1 = util_1.distance(v0[0], v0[1], v1[0], v1[1]); if (prev >= 0 && d1 < d) { t = prev; d = d1; } else { var v2 = [tCallback.apply(null, xArr.concat([next])), tCallback.apply(null, yArr.concat([next]))]; var d2 = util_1.distance(v0[0], v0[1], v2[0], v2[1]); if (next <= 1 && d2 < d) { t = next; d = d2; } else { interval *= 0.5; } } } return { x: tCallback.apply(null, xArr.concat([t])), y: tCallback.apply(null, yArr.concat([t])), }; } exports.nearestPoint = nearestPoint; // 近似求解 https://community.khronos.org/t/3d-cubic-bezier-segment-length/62363/2 function snapLength(xArr, yArr) { var totalLength = 0; var count = xArr.length; for (var i = 0; i < count; i++) { var x = xArr[i]; var y = yArr[i]; var nextX = xArr[(i + 1) % count]; var nextY = yArr[(i + 1) % count]; totalLength += util_1.distance(x, y, nextX, nextY); } return totalLength / 2; } exports.snapLength = snapLength; },{"./util":176}],170:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); var line_1 = require("./line"); var bezier_1 = require("./bezier"); function cubicAt(p0, p1, p2, p3, t) { var onet = 1 - t; // t * t * t 的性能大概是 Math.pow(t, 3) 的三倍 return onet * onet * onet * p0 + 3 * p1 * t * onet * onet + 3 * p2 * t * t * onet + p3 * t * t * t; } function derivativeAt(p0, p1, p2, p3, t) { var onet = 1 - t; return 3 * (onet * onet * (p1 - p0) + 2 * onet * t * (p2 - p1) + t * t * (p3 - p2)); } function extrema(p0, p1, p2, p3) { var a = -3 * p0 + 9 * p1 - 9 * p2 + 3 * p3; var b = 6 * p0 - 12 * p1 + 6 * p2; var c = 3 * p1 - 3 * p0; var extremas = []; var t1; var t2; var discSqrt; if (util_1.isNumberEqual(a, 0)) { if (!util_1.isNumberEqual(b, 0)) { t1 = -c / b; if (t1 >= 0 && t1 <= 1) { extremas.push(t1); } } } else { var disc = b * b - 4 * a * c; if (util_1.isNumberEqual(disc, 0)) { extremas.push(-b / (2 * a)); } else if (disc > 0) { discSqrt = Math.sqrt(disc); t1 = (-b + discSqrt) / (2 * a); t2 = (-b - discSqrt) / (2 * a); if (t1 >= 0 && t1 <= 1) { extremas.push(t1); } if (t2 >= 0 && t2 <= 1) { extremas.push(t2); } } } return extremas; } // 分割贝塞尔曲线 function divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, t) { // 划分点 var xt = cubicAt(x1, x2, x3, x4, t); var yt = cubicAt(y1, y2, y3, y4, t); // 计算两点之间的差值点 var c1 = line_1.default.pointAt(x1, y1, x2, y2, t); var c2 = line_1.default.pointAt(x2, y2, x3, y3, t); var c3 = line_1.default.pointAt(x3, y3, x4, y4, t); var c12 = line_1.default.pointAt(c1.x, c1.y, c2.x, c2.y, t); var c23 = line_1.default.pointAt(c2.x, c2.y, c3.x, c3.y, t); return [ [x1, y1, c1.x, c1.y, c12.x, c12.y, xt, yt], [xt, yt, c23.x, c23.y, c3.x, c3.y, x4, y4], ]; } // 使用迭代法取贝塞尔曲线的长度,二阶和三阶分开写,更清晰和便于调试 function cubicLength(x1, y1, x2, y2, x3, y3, x4, y4, iterationCount) { if (iterationCount === 0) { return bezier_1.snapLength([x1, x2, x3, x4], [y1, y2, y3, y4]); } var cubics = divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0.5); var left = cubics[0]; var right = cubics[1]; left.push(iterationCount - 1); right.push(iterationCount - 1); return cubicLength.apply(null, left) + cubicLength.apply(null, right); } exports.default = { extrema: extrema, box: function (x1, y1, x2, y2, x3, y3, x4, y4) { var xArr = [x1, x4]; var yArr = [y1, y4]; var xExtrema = extrema(x1, x2, x3, x4); var yExtrema = extrema(y1, y2, y3, y4); for (var i = 0; i < xExtrema.length; i++) { xArr.push(cubicAt(x1, x2, x3, x4, xExtrema[i])); } for (var i = 0; i < yExtrema.length; i++) { yArr.push(cubicAt(y1, y2, y3, y4, yExtrema[i])); } return util_1.getBBoxByArray(xArr, yArr); }, length: function (x1, y1, x2, y2, x3, y3, x4, y4) { // 迭代三次,划分成 8 段求长度 return cubicLength(x1, y1, x2, y2, x3, y3, x4, y4, 3); }, nearestPoint: function (x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) { return bezier_1.nearestPoint([x1, x2, x3, x4], [y1, y2, y3, y4], x0, y0, cubicAt, length); }, pointDistance: function (x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) { var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length); return util_1.distance(point.x, point.y, x0, y0); }, interpolationAt: cubicAt, pointAt: function (x1, y1, x2, y2, x3, y3, x4, y4, t) { return { x: cubicAt(x1, x2, x3, x4, t), y: cubicAt(y1, y2, y3, y4, t), }; }, divide: function (x1, y1, x2, y2, x3, y3, x4, y4, t) { return divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, t); }, tangentAngle: function (x1, y1, x2, y2, x3, y3, x4, y4, t) { var dx = derivativeAt(x1, x2, x3, x4, t); var dy = derivativeAt(y1, y2, y3, y4, t); return util_1.piMod(Math.atan2(dy, dx)); }, }; },{"./bezier":169,"./line":172,"./util":176}],171:[function(require,module,exports){ "use strict"; /** * @fileoverview 椭圆的一些计算, * - 周长计算参考:https://www.mathsisfun.com/geometry/ellipse-perimeter.html * - 距离计算参考:https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/ * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); function copysign(v1, v2) { var absv = Math.abs(v1); return v2 > 0 ? absv : absv * -1; } exports.default = { /** * 包围盒计算 * @param {number} x 椭圆中心 x * @param {number} y 椭圆中心 y * @param {number} rx 椭圆 x 方向半径 * @param {number} ry 椭圆 y 方向半径 * @return {object} 包围盒 */ box: function (x, y, rx, ry) { return { x: x - rx, y: y - ry, width: rx * 2, height: ry * 2, }; }, /** * 计算周长,使用近似法 * @param {number} x 椭圆中心 x * @param {number} y 椭圆中心 y * @param {number} rx 椭圆 x 方向半径 * @param {number} ry 椭圆 y 方向半径 * @return {number} 椭圆周长 */ length: function (x, y, rx, ry) { return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry))); }, /** * 距离椭圆最近的点 * @param {number} x 椭圆中心 x * @param {number} y 椭圆中心 y * @param {number} rx 椭圆 x 方向半径 * @param {number} ry 椭圆 y 方向半径 * @param {number} x0 指定的点 x * @param {number} y0 指定的点 y * @return {object} 椭圆上距离指定点最近的点 */ nearestPoint: function (x, y, rx, ry, x0, y0) { var a = rx; var b = ry; // 假如椭圆半径为0则返回圆心 if (a === 0 || b === 0) { return { x: x, y: y, }; } // 转换成 0, 0 为中心的椭圆计算 var relativeX = x0 - x; var relativeY = y0 - y; var px = Math.abs(relativeX); var py = Math.abs(relativeY); var squareA = a * a; var squareB = b * b; // const angle0 = Math.atan2(relativeY, relativeX); var t = Math.PI / 4; var nearestX; // 椭圆上的任一点 var nearestY; // 迭代 4 次 for (var i = 0; i < 4; i++) { nearestX = a * Math.cos(t); nearestY = b * Math.sin(t); var ex = ((squareA - squareB) * Math.pow(Math.cos(t), 3)) / a; var ey = ((squareB - squareA) * Math.pow(Math.sin(t), 3)) / b; var rx1 = nearestX - ex; var ry1 = nearestY - ey; var qx = px - ex; var qy = py - ey; var r = Math.hypot(ry1, rx1); var q = Math.hypot(qy, qx); var delta_c = r * Math.asin((rx1 * qy - ry1 * qx) / (r * q)); var delta_t = delta_c / Math.sqrt(squareA + squareB - nearestX * nearestX - nearestY * nearestY); t += delta_t; t = Math.min(Math.PI / 2, Math.max(0, t)); } return { x: x + copysign(nearestX, relativeX), y: y + copysign(nearestY, relativeY), }; }, /** * 点到椭圆最近的距离 * @param {number} x 椭圆中心 x * @param {number} y 椭圆中心 y * @param {number} rx 椭圆 x 方向半径 * @param {number} ry 椭圆 y 方向半径 * @param {number} x0 指定的点 x * @param {number} y0 指定的点 y * @return {number} 点到椭圆的距离 */ pointDistance: function (x, y, rx, ry, x0, y0) { var nearestPoint = this.nearestPoint(x, y, rx, ry, x0, y0); return util_1.distance(nearestPoint.x, nearestPoint.y, x0, y0); }, /** * 根据比例获取点 * @param {number} x 椭圆中心 x * @param {number} y 椭圆中心 y * @param {number} rx 椭圆 x 方向半径 * @param {number} ry 椭圆 y 方向半径 * @param {number} t 指定比例,x轴方向为 0 * @return {object} 点 */ pointAt: function (x, y, rx, ry, t) { var angle = 2 * Math.PI * t; // 按照角度进行计算,而不按照周长计算 return { x: x + rx * Math.cos(angle), y: y + ry * Math.sin(angle), }; }, /** * 根据比例计算切线角度 * @param {number} x 椭圆中心 x * @param {number} y 椭圆中心 y * @param {number} rx 椭圆 x 方向半径 * @param {number} ry 椭圆 y 方向半径 * @param {number} t 指定比例 0 - 1 之间,x轴方向为 0。在 0-1 范围之外是循环还是返回 null,还需要调整 * @return {number} 角度,在 0 - 2PI 之间 */ tangentAngle: function (x, y, rx, ry, t) { var angle = 2 * Math.PI * t; // 按照角度进行计算,而不按照周长计算 // 直接使用 x,y 的导数计算, x' = -rx * sin(t); y' = ry * cos(t); var tangentAngle = Math.atan2(ry * Math.cos(angle), -rx * Math.sin(angle)); // 也可以使用指定点的切线方程计算,成本有些高 // const point = this.pointAt(0, 0, rx, ry, t); // 椭圆的切线同椭圆的中心不相关 // let tangentAngle = -1 * Math.atan((ry * ry * point.x) / (rx * rx * point.y)); // if (angle >= 0 && angle <= Math.PI) { // tangentAngle += Math.PI; // } return util_1.piMod(tangentAngle); }, }; },{"./util":176}],172:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./util"); var vec2 = require("gl-matrix/vec2"); exports.default = { /** * 计算线段的包围盒 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @return {object} 包围盒对象 */ box: function (x1, y1, x2, y2) { return util_1.getBBoxByArray([x1, x2], [y1, y2]); }, /** * 线段的长度 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @return {number} 距离 */ length: function (x1, y1, x2, y2) { return util_1.distance(x1, y1, x2, y2); }, /** * 根据比例获取点 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @param {number} t 指定比例 * @return {object} 包含 x, y 的点 */ pointAt: function (x1, y1, x2, y2, t) { return { x: (1 - t) * x1 + t * x2, y: (1 - t) * y1 + t * y2, }; }, /** * 点到线段的距离 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @param {number} x 测试点 x * @param {number} y 测试点 y * @return {number} 距离 */ pointDistance: function (x1, y1, x2, y2, x, y) { // 投影距离 x1, y1 的向量,假设 p, p1, p2 三个点,投影点为 a // p1a = p1p.p1p2/|p1p2| * (p1p 的单位向量) var cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1); if (cross < 0) { return util_1.distance(x1, y1, x, y); } var lengthSquare = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); if (cross > lengthSquare) { return util_1.distance(x2, y2, x, y); } return this.pointToLine(x1, y1, x2, y2, x, y); }, /** * 点到直线的距离,而不是点到线段的距离 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @param {number} x 测试点 x * @param {number} y 测试点 y * @return {number} 距离 */ pointToLine: function (x1, y1, x2, y2, x, y) { var d = [x2 - x1, y2 - y1]; // 如果端点相等,则判定点到点的距离 if (vec2.exactEquals(d, [0, 0])) { return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)); } var u = [-d[1], d[0]]; vec2.normalize(u, u); var a = [x - x1, y - y1]; return Math.abs(vec2.dot(a, u)); }, /** * 线段的角度 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @return {number} 导数 */ tangentAngle: function (x1, y1, x2, y2) { return Math.atan2(y2 - y1, x2 - x1); }, }; },{"./util":176,"gl-matrix/vec2":890}],173:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var segments_1 = require("./segments"); var util_1 = require("./util"); exports.default = { /** * 计算多折线的包围盒 * @param {array} points 点的集合 [x,y] 的形式 * @return {object} 包围盒 */ box: function (points) { var xArr = []; var yArr = []; for (var i = 0; i < points.length; i++) { var point = points[i]; xArr.push(point[0]); yArr.push(point[1]); } return util_1.getBBoxByArray(xArr, yArr); }, /** * 计算多折线的长度 * @param {array} points 点的集合 [x,y] 的形式 * @return {object} 多条边的长度 */ length: function (points) { return segments_1.lengthOfSegment(points); }, /** * 根据比例获取多折线的点 * @param {array} points 点的集合 [x,y] 的形式 * @param {number} t 在多折线的长度上的比例 * @return {object} 根据比例值计算出来的点 */ pointAt: function (points, t) { return segments_1.pointAtSegments(points, t); }, /** * 指定点到多折线的距离 * @param {array} points 点的集合 [x,y] 的形式 * @param {number} x 指定点的 x * @param {number} y 指定点的 y * @return {number} 点到多折线的距离 */ pointDistance: function (points, x, y) { return segments_1.distanceAtSegment(points, x, y); }, /** * 根据比例获取多折线的切线角度 * @param {array} points 点的集合 [x,y] 的形式 * @param {number} t 在多折线的长度上的比例 * @return {object} 根据比例值计算出来的角度 */ tangentAngle: function (points, t) { return segments_1.angleAtSegments(points, t); }, }; },{"./segments":175,"./util":176}],174:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var line_1 = require("./line"); var util_1 = require("./util"); var bezier_1 = require("./bezier"); // 差值公式 function quadraticAt(p0, p1, p2, t) { var onet = 1 - t; return onet * onet * p0 + 2 * t * onet * p1 + t * t * p2; } // 求极值 function extrema(p0, p1, p2) { var a = p0 + p2 - 2 * p1; if (util_1.isNumberEqual(a, 0)) { return [0.5]; } var rst = (p0 - p1) / a; if (rst <= 1 && rst >= 0) { return [rst]; } return []; } function derivativeAt(p0, p1, p2, t) { return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1); } // 分割贝塞尔曲线 function divideQuadratic(x1, y1, x2, y2, x3, y3, t) { // 划分点 var xt = quadraticAt(x1, x2, x3, t); var yt = quadraticAt(y1, y2, y3, t); // 分割的第一条曲线的控制点 var controlPoint1 = line_1.default.pointAt(x1, y1, x2, y2, t); // 分割的第二条曲线的控制点 var controlPoint2 = line_1.default.pointAt(x2, y2, x3, y3, t); return [ [x1, y1, controlPoint1.x, controlPoint1.y, xt, yt], [xt, yt, controlPoint2.x, controlPoint2.y, x3, y3], ]; } // 使用迭代法取贝塞尔曲线的长度 function quadraticLength(x1, y1, x2, y2, x3, y3, iterationCount) { if (iterationCount === 0) { return (util_1.distance(x1, y1, x2, y2) + util_1.distance(x2, y2, x3, y3) + util_1.distance(x1, y1, x3, y3)) / 2; } var quadratics = divideQuadratic(x1, y1, x2, y2, x3, y3, 0.5); var left = quadratics[0]; var right = quadratics[1]; left.push(iterationCount - 1); right.push(iterationCount - 1); return quadraticLength.apply(null, left) + quadraticLength.apply(null, right); } exports.default = { box: function (x1, y1, x2, y2, x3, y3) { var xExtrema = extrema(x1, x2, x3)[0]; var yExtrema = extrema(y1, y2, y3)[0]; // 控制点不加入 box 的计算 var xArr = [x1, x3]; var yArr = [y1, y3]; if (xExtrema !== undefined) { xArr.push(quadraticAt(x1, x2, x3, xExtrema)); } if (yExtrema !== undefined) { yArr.push(quadraticAt(y1, y2, y3, yExtrema)); } return util_1.getBBoxByArray(xArr, yArr); }, length: function (x1, y1, x2, y2, x3, y3) { return quadraticLength(x1, y1, x2, y2, x3, y3, 3); }, nearestPoint: function (x1, y1, x2, y2, x3, y3, x0, y0) { return bezier_1.nearestPoint([x1, x2, x3], [y1, y2, y3], x0, y0, quadraticAt); }, pointDistance: function (x1, y1, x2, y2, x3, y3, x0, y0) { var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x0, y0); return util_1.distance(point.x, point.y, x0, y0); }, interpolationAt: quadraticAt, pointAt: function (x1, y1, x2, y2, x3, y3, t) { return { x: quadraticAt(x1, x2, x3, t), y: quadraticAt(y1, y2, y3, t), }; }, divide: function (x1, y1, x2, y2, x3, y3, t) { return divideQuadratic(x1, y1, x2, y2, x3, y3, t); }, tangentAngle: function (x1, y1, x2, y2, x3, y3, t) { var dx = derivativeAt(x1, x2, x3, t); var dy = derivativeAt(y1, y2, y3, t); var angle = Math.atan2(dy, dx); return util_1.piMod(angle); }, }; },{"./bezier":169,"./line":172,"./util":176}],175:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.distanceAtSegment = exports.angleAtSegments = exports.pointAtSegments = exports.lengthOfSegment = void 0; var line_1 = require("./line"); var util_1 = require("./util"); function analyzePoints(points) { // 计算每段的长度和总的长度 var totalLength = 0; var segments = []; for (var i = 0; i < points.length - 1; i++) { var from = points[i]; var to = points[i + 1]; var length_1 = util_1.distance(from[0], from[1], to[0], to[1]); var seg = { from: from, to: to, length: length_1, }; segments.push(seg); totalLength += length_1; } return { segments: segments, totalLength: totalLength }; } function lengthOfSegment(points) { if (points.length < 2) { return 0; } var totalLength = 0; for (var i = 0; i < points.length - 1; i++) { var from = points[i]; var to = points[i + 1]; totalLength += util_1.distance(from[0], from[1], to[0], to[1]); } return totalLength; } exports.lengthOfSegment = lengthOfSegment; /** * 按照比例在数据片段中获取点 * @param {array} points 点的集合 * @param {number} t 百分比 0-1 * @return {object} 点的坐标 */ function pointAtSegments(points, t) { // 边界判断 if (t > 1 || t < 0 || points.length < 2) { return null; } var _a = analyzePoints(points), segments = _a.segments, totalLength = _a.totalLength; // 多个点有可能重合 if (totalLength === 0) { return { x: points[0][0], y: points[0][1], }; } // 计算比例 var startRatio = 0; var point = null; for (var i = 0; i < segments.length; i++) { var seg = segments[i]; var from = seg.from, to = seg.to; var currentRatio = seg.length / totalLength; if (t >= startRatio && t <= startRatio + currentRatio) { var localRatio = (t - startRatio) / currentRatio; point = line_1.default.pointAt(from[0], from[1], to[0], to[1], localRatio); break; } startRatio += currentRatio; } return point; } exports.pointAtSegments = pointAtSegments; /** * 按照比例在数据片段中获取切线的角度 * @param {array} points 点的集合 * @param {number} t 百分比 0-1 */ function angleAtSegments(points, t) { // 边界判断 if (t > 1 || t < 0 || points.length < 2) { return 0; } var _a = analyzePoints(points), segments = _a.segments, totalLength = _a.totalLength; // 计算比例 var startRatio = 0; var angle = 0; for (var i = 0; i < segments.length; i++) { var seg = segments[i]; var from = seg.from, to = seg.to; var currentRatio = seg.length / totalLength; if (t >= startRatio && t <= startRatio + currentRatio) { angle = Math.atan2(to[1] - from[1], to[0] - from[0]); break; } startRatio += currentRatio; } return angle; } exports.angleAtSegments = angleAtSegments; function distanceAtSegment(points, x, y) { var minDistance = Infinity; for (var i = 0; i < points.length - 1; i++) { var point = points[i]; var nextPoint = points[i + 1]; var distance_1 = line_1.default.pointDistance(point[0], point[1], nextPoint[0], nextPoint[1], x, y); if (distance_1 < minDistance) { minDistance = distance_1; } } return minDistance; } exports.distanceAtSegment = distanceAtSegment; },{"./line":172,"./util":176}],176:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.piMod = exports.getBBoxRange = exports.getBBoxByArray = exports.isNumberEqual = exports.distance = void 0; function minNum(array) { return Math.min.apply(null, array); } function maxNum(array) { return Math.max.apply(null, array); } /** * 两点之间的距离 * @param {number} x1 起始点 x * @param {number} y1 起始点 y * @param {number} x2 结束点 x * @param {number} y2 结束点 y * @return {number} 距离 */ function distance(x1, y1, x2, y2) { var dx = x1 - x2; var dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); } exports.distance = distance; function isNumberEqual(v1, v2) { return Math.abs(v1 - v2) < 0.001; } exports.isNumberEqual = isNumberEqual; function getBBoxByArray(xArr, yArr) { var minX = minNum(xArr); var minY = minNum(yArr); var maxX = maxNum(xArr); var maxY = maxNum(yArr); return { x: minX, y: minY, width: maxX - minX, height: maxY - minY, }; } exports.getBBoxByArray = getBBoxByArray; function getBBoxRange(x1, y1, x2, y2) { return { minX: minNum([x1, x2]), maxX: maxNum([x1, x2]), minY: minNum([y1, y2]), maxY: maxNum([y1, y2]), }; } exports.getBBoxRange = getBBoxRange; function piMod(angle) { return (angle + Math.PI * 2) % (Math.PI * 2); } exports.piMod = piMod; },{}],177:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var constant_1 = require("./constant"); var draw_1 = require("./util/draw"); var svg_1 = require("./util/svg"); var dom_1 = require("./util/dom"); var Shape = require("./shape"); var group_1 = require("./group"); var defs_1 = require("./defs"); var Canvas = /** @class */ (function (_super) { tslib_1.__extends(Canvas, _super); function Canvas(cfg) { return _super.call(this, tslib_1.__assign(tslib_1.__assign({}, cfg), { autoDraw: true, // 设置渲染引擎为 canvas,只读属性 renderer: 'svg' })) || this; } Canvas.prototype.getShapeBase = function () { return Shape; }; Canvas.prototype.getGroupBase = function () { return group_1.default; }; // 覆盖 Container 中通过遍历的方式获取 shape 对象的逻辑,直接走 SVG 的 dom 拾取即可 Canvas.prototype.getShape = function (x, y, ev) { var target = ev.target || ev.srcElement; if (!constant_1.SHAPE_TO_TAGS[target.tagName]) { var parent_1 = target.parentNode; while (parent_1 && !constant_1.SHAPE_TO_TAGS[parent_1.tagName]) { parent_1 = parent_1.parentNode; } target = parent_1; } return this.find(function (child) { return child.get('el') === target; }); }; // 复写基类的方法生成标签 Canvas.prototype.createDom = function () { var element = dom_1.createSVGElement('svg'); var context = new defs_1.default(element); element.setAttribute('width', "" + this.get('width')); element.setAttribute('height', "" + this.get('height')); // 缓存 context 对象 this.set('context', context); return element; }; /** * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ Canvas.prototype.onCanvasChange = function (changeType) { var context = this.get('context'); var el = this.get('el'); if (changeType === 'sort') { var children_1 = this.get('children'); if (children_1 && children_1.length) { dom_1.sortDom(this, function (a, b) { return children_1.indexOf(a) - children_1.indexOf(b) ? 1 : 0; }); } } else if (changeType === 'clear') { // el maybe null for canvas if (el) { // 清空 SVG 元素 el.innerHTML = ''; var defsEl = context.el; // 清空 defs 元素 defsEl.innerHTML = ''; // 将清空后的 defs 元素挂载到 el 下 el.appendChild(defsEl); } } else if (changeType === 'matrix') { svg_1.setTransform(this); } else if (changeType === 'clip') { svg_1.setClip(this, context); } else if (changeType === 'changeSize') { el.setAttribute('width', "" + this.get('width')); el.setAttribute('height', "" + this.get('height')); } }; // 复写基类的 draw 方法 Canvas.prototype.draw = function () { var context = this.get('context'); var children = this.getChildren(); svg_1.setClip(this, context); if (children.length) { draw_1.drawChildren(context, children); } }; return Canvas; }(g_base_1.AbstractCanvas)); exports.default = Canvas; },{"./constant":178,"./defs":182,"./group":185,"./shape":192,"./util/dom":201,"./util/draw":202,"./util/svg":204,"@antv/g-base":115,"tslib":894}],178:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SHAPE_TO_TAGS = { rect: 'path', circle: 'circle', line: 'line', path: 'path', marker: 'path', text: 'text', polyline: 'polyline', polygon: 'polygon', image: 'image', ellipse: 'ellipse', dom: 'foreignObject', }; exports.SVG_ATTR_MAP = { opacity: 'opacity', fillStyle: 'fill', fill: 'fill', fillOpacity: 'fill-opacity', strokeStyle: 'stroke', strokeOpacity: 'stroke-opacity', stroke: 'stroke', x: 'x', y: 'y', r: 'r', rx: 'rx', ry: 'ry', width: 'width', height: 'height', x1: 'x1', x2: 'x2', y1: 'y1', y2: 'y2', lineCap: 'stroke-linecap', lineJoin: 'stroke-linejoin', lineWidth: 'stroke-width', lineDash: 'stroke-dasharray', lineDashOffset: 'stroke-dashoffset', miterLimit: 'stroke-miterlimit', font: 'font', fontSize: 'font-size', fontStyle: 'font-style', fontVariant: 'font-variant', fontWeight: 'font-weight', fontFamily: 'font-family', startArrow: 'marker-start', endArrow: 'marker-end', path: 'd', class: 'class', id: 'id', style: 'style', preserveAspectRatio: 'preserveAspectRatio', }; exports.EVENTS = [ 'click', 'mousedown', 'mouseup', 'dblclick', 'contextmenu', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mousemove', 'wheel', ]; },{}],179:[function(require,module,exports){ "use strict"; /** * @fileoverview arrow * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var dom_1 = require("../util/dom"); var Arrow = /** @class */ (function () { function Arrow(attrs, type) { this.cfg = {}; var el = dom_1.createSVGElement('marker'); var id = util_1.uniqueId('marker_'); el.setAttribute('id', id); var shape = dom_1.createSVGElement('path'); shape.setAttribute('stroke', attrs.stroke || 'none'); shape.setAttribute('fill', attrs.fill || 'none'); el.appendChild(shape); el.setAttribute('overflow', 'visible'); el.setAttribute('orient', 'auto-start-reverse'); this.el = el; this.child = shape; this.id = id; var cfg = attrs[type === 'marker-start' ? 'startArrow' : 'endArrow']; this.stroke = attrs.stroke || '#000'; if (cfg === true) { this._setDefaultPath(type, shape); } else { this.cfg = cfg; // when arrow config exists this._setMarker(attrs.lineWidth, shape); } return this; } Arrow.prototype.match = function () { return false; }; Arrow.prototype._setDefaultPath = function (type, el) { var parent = this.el; // 默认箭头的边长为 10,夹角为 60 度 el.setAttribute('d', "M0,0 L" + 10 * Math.cos(Math.PI / 6) + ",5 L0,10"); parent.setAttribute('refX', "" + 10 * Math.cos(Math.PI / 6)); parent.setAttribute('refY', "" + 5); }; Arrow.prototype._setMarker = function (r, el) { var parent = this.el; var path = this.cfg.path; var d = this.cfg.d; if (util_1.isArray(path)) { path = path .map(function (segment) { return segment.join(' '); }) .join(''); } el.setAttribute('d', path); parent.appendChild(el); if (d) { parent.setAttribute('refX', "" + d / r); } }; Arrow.prototype.update = function (fill) { var child = this.child; if (child.attr) { child.attr('fill', fill); } else { child.setAttribute('fill', fill); } }; return Arrow; }()); exports.default = Arrow; },{"../util/dom":201,"@antv/util":803}],180:[function(require,module,exports){ "use strict"; /** * @fileoverview clip * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var dom_1 = require("../util/dom"); var Clip = /** @class */ (function () { function Clip(cfg) { this.type = 'clip'; this.cfg = {}; var el = dom_1.createSVGElement('clipPath'); this.el = el; this.id = util_1.uniqueId('clip_'); el.id = this.id; var shapeEl = cfg.cfg.el; el.appendChild(shapeEl); this.cfg = cfg; return this; } Clip.prototype.match = function () { return false; }; Clip.prototype.remove = function () { var el = this.el; el.parentNode.removeChild(el); }; return Clip; }()); exports.default = Clip; },{"../util/dom":201,"@antv/util":803}],181:[function(require,module,exports){ "use strict"; /** * @fileoverview gradient * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var dom_1 = require("../util/dom"); var regexLG = /^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i; var regexRG = /^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i; var regexColorStop = /[\d.]+:(#[^\s]+|[^\)]+\))/gi; function addStop(steps) { var arr = steps.match(regexColorStop); if (!arr) { return ''; } var stops = ''; arr.sort(function (a, b) { a = a.split(':'); b = b.split(':'); return Number(a[0]) - Number(b[0]); }); util_1.each(arr, function (item) { item = item.split(':'); stops += ""; }); return stops; } function parseLineGradient(color, el) { var arr = regexLG.exec(color); var angle = util_1.mod(util_1.toRadian(parseFloat(arr[1])), Math.PI * 2); var steps = arr[2]; var start; var end; if (angle >= 0 && angle < 0.5 * Math.PI) { start = { x: 0, y: 0, }; end = { x: 1, y: 1, }; } else if (0.5 * Math.PI <= angle && angle < Math.PI) { start = { x: 1, y: 0, }; end = { x: 0, y: 1, }; } else if (Math.PI <= angle && angle < 1.5 * Math.PI) { start = { x: 1, y: 1, }; end = { x: 0, y: 0, }; } else { start = { x: 0, y: 1, }; end = { x: 1, y: 0, }; } var tanTheta = Math.tan(angle); var tanTheta2 = tanTheta * tanTheta; var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x; var y = (tanTheta * (end.x - start.x + tanTheta * (end.y - start.y))) / (tanTheta2 + 1) + start.y; el.setAttribute('x1', start.x); el.setAttribute('y1', start.y); el.setAttribute('x2', x); el.setAttribute('y2', y); el.innerHTML = addStop(steps); } function parseRadialGradient(color, self) { var arr = regexRG.exec(color); var cx = parseFloat(arr[1]); var cy = parseFloat(arr[2]); var r = parseFloat(arr[3]); var steps = arr[4]; self.setAttribute('cx', cx); self.setAttribute('cy', cy); self.setAttribute('r', r); self.innerHTML = addStop(steps); } var Gradient = /** @class */ (function () { function Gradient(cfg) { this.cfg = {}; var el = null; var id = util_1.uniqueId('gradient_'); if (cfg.toLowerCase()[0] === 'l') { el = dom_1.createSVGElement('linearGradient'); parseLineGradient(cfg, el); } else { el = dom_1.createSVGElement('radialGradient'); parseRadialGradient(cfg, el); } el.setAttribute('id', id); this.el = el; this.id = id; this.cfg = cfg; return this; } Gradient.prototype.match = function (type, attr) { return this.cfg === attr; }; return Gradient; }()); exports.default = Gradient; },{"../util/dom":201,"@antv/util":803}],182:[function(require,module,exports){ "use strict"; /** * @fileoverview defs * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var gradient_1 = require("./gradient"); var shadow_1 = require("./shadow"); var arrow_1 = require("./arrow"); var clip_1 = require("./clip"); var pattern_1 = require("./pattern"); var dom_1 = require("../util/dom"); var Defs = /** @class */ (function () { function Defs(canvas) { var el = dom_1.createSVGElement('defs'); var id = util_1.uniqueId('defs_'); el.id = id; canvas.appendChild(el); this.children = []; this.defaultArrow = {}; this.el = el; this.canvas = canvas; } Defs.prototype.find = function (type, attr) { var children = this.children; var result = null; for (var i = 0; i < children.length; i++) { if (children[i].match(type, attr)) { result = children[i].id; break; } } return result; }; Defs.prototype.findById = function (id) { var children = this.children; var flag = null; for (var i = 0; i < children.length; i++) { if (children[i].id === id) { flag = children[i]; break; } } return flag; }; Defs.prototype.add = function (item) { this.children.push(item); item.canvas = this.canvas; item.parent = this; }; Defs.prototype.getDefaultArrow = function (attrs, name) { var stroke = attrs.stroke || attrs.strokeStyle; if (this.defaultArrow[stroke]) { return this.defaultArrow[stroke].id; } var arrow = new arrow_1.default(attrs, name); this.defaultArrow[stroke] = arrow; this.el.appendChild(arrow.el); this.add(arrow); return arrow.id; }; Defs.prototype.addGradient = function (cfg) { var gradient = new gradient_1.default(cfg); this.el.appendChild(gradient.el); this.add(gradient); return gradient.id; }; Defs.prototype.addArrow = function (attrs, name) { var arrow = new arrow_1.default(attrs, name); this.el.appendChild(arrow.el); this.add(arrow); return arrow.id; }; Defs.prototype.addShadow = function (cfg) { var shadow = new shadow_1.default(cfg); this.el.appendChild(shadow.el); this.add(shadow); return shadow.id; }; Defs.prototype.addPattern = function (cfg) { var pattern = new pattern_1.default(cfg); this.el.appendChild(pattern.el); this.add(pattern); return pattern.id; }; Defs.prototype.addClip = function (cfg) { var clip = new clip_1.default(cfg); this.el.appendChild(clip.el); this.add(clip); return clip.id; }; return Defs; }()); exports.default = Defs; },{"../util/dom":201,"./arrow":179,"./clip":180,"./gradient":181,"./pattern":183,"./shadow":184,"@antv/util":803}],183:[function(require,module,exports){ "use strict"; /** * @fileoverview pattern * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var dom_1 = require("../util/dom"); var regexPR = /^p\s*\(\s*([axyn])\s*\)\s*(.*)/i; var Pattern = /** @class */ (function () { function Pattern(cfg) { this.cfg = {}; var el = dom_1.createSVGElement('pattern'); el.setAttribute('patternUnits', 'userSpaceOnUse'); var child = dom_1.createSVGElement('image'); el.appendChild(child); var id = util_1.uniqueId('pattern_'); el.id = id; this.el = el; this.id = id; this.cfg = cfg; var arr = regexPR.exec(cfg); var source = arr[2]; child.setAttribute('href', source); var img = new Image(); if (!source.match(/^data:/i)) { img.crossOrigin = 'Anonymous'; } img.src = source; function onload() { el.setAttribute('width', "" + img.width); el.setAttribute('height', "" + img.height); } if (img.complete) { onload(); } else { img.onload = onload; // Fix onload() bug in IE9 img.src = img.src; } return this; } Pattern.prototype.match = function (type, attr) { return this.cfg === attr; }; return Pattern; }()); exports.default = Pattern; },{"../util/dom":201,"@antv/util":803}],184:[function(require,module,exports){ "use strict"; /** * @fileoverview shadow * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var dom_1 = require("../util/dom"); var ATTR_MAP = { shadowColor: 'color', shadowOpacity: 'opacity', shadowBlur: 'blur', shadowOffsetX: 'dx', shadowOffsetY: 'dy', }; var SHADOW_DIMENSION = { x: '-40%', y: '-40%', width: '200%', height: '200%', }; var Shadow = /** @class */ (function () { function Shadow(cfg) { this.type = 'filter'; this.cfg = {}; this.type = 'filter'; var el = dom_1.createSVGElement('filter'); // expand the filter region to fill in shadows util_1.each(SHADOW_DIMENSION, function (v, k) { el.setAttribute(k, v); }); this.el = el; this.id = util_1.uniqueId('filter_'); this.el.id = this.id; this.cfg = cfg; this._parseShadow(cfg, el); return this; } Shadow.prototype.match = function (type, cfg) { if (this.type !== type) { return false; } var flag = true; var config = this.cfg; util_1.each(Object.keys(config), function (attr) { if (config[attr] !== cfg[attr]) { flag = false; return false; } }); return flag; }; Shadow.prototype.update = function (name, value) { var config = this.cfg; config[ATTR_MAP[name]] = value; this._parseShadow(config, this.el); return this; }; Shadow.prototype._parseShadow = function (config, el) { var child = ""; el.innerHTML = child; }; return Shadow; }()); exports.default = Shadow; },{"../util/dom":201,"@antv/util":803}],185:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var util_1 = require("@antv/util"); var Shape = require("./shape"); var draw_1 = require("./util/draw"); var svg_1 = require("./util/svg"); var constant_1 = require("./constant"); var dom_1 = require("./util/dom"); var Group = /** @class */ (function (_super) { tslib_1.__extends(Group, _super); function Group() { return _super !== null && _super.apply(this, arguments) || this; } // SVG 中分组对应实体标签 Group.prototype.isEntityGroup = function () { return true; }; Group.prototype.createDom = function () { var element = dom_1.createSVGElement('g'); this.set('el', element); var parent = this.getParent(); if (parent) { var parentNode = parent.get('el'); if (parentNode) { parentNode.appendChild(element); } else { // parentNode maybe null for group parentNode = parent.createDom(); parent.set('el', parentNode); parentNode.appendChild(element); } } return element; }; // 覆盖基类的 afterAttrsChange 方法 Group.prototype.afterAttrsChange = function (targetAttrs) { _super.prototype.afterAttrsChange.call(this, targetAttrs); var canvas = this.get('canvas'); // 只有挂载到画布下,才对元素进行实际渲染 if (canvas && canvas.get('autoDraw')) { var context = canvas.get('context'); this.createPath(context, targetAttrs); } }; /** * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ Group.prototype.onCanvasChange = function (changeType) { draw_1.refreshElement(this, changeType); }; Group.prototype.getShapeBase = function () { return Shape; }; Group.prototype.getGroupBase = function () { return Group; }; Group.prototype.draw = function (context) { var children = this.getChildren(); var el = this.get('el'); if (this.get('destroyed')) { if (el) { el.parentNode.removeChild(el); } } else { if (!el) { this.createDom(); } svg_1.setClip(this, context); this.createPath(context); if (children.length) { draw_1.drawChildren(context, children); } } }; /** * 绘制分组的路径 * @param {Defs} context 上下文 * @param {ShapeAttrs} targetAttrs 渲染的目标属性 */ Group.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); svg_1.setTransform(this); }; return Group; }(g_base_1.AbstractGroup)); exports.default = Group; },{"./constant":178,"./shape":192,"./util/dom":201,"./util/draw":202,"./util/svg":204,"@antv/g-base":115,"@antv/util":803,"tslib":894}],186:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Shape = require("./shape"); exports.Shape = Shape; var pkg = require('../package.json'); exports.version = pkg.version; var g_base_1 = require("@antv/g-base"); exports.Event = g_base_1.Event; var canvas_1 = require("./canvas"); exports.Canvas = canvas_1.default; var group_1 = require("./group"); exports.Group = group_1.default; },{"../package.json":206,"./canvas":177,"./group":185,"./shape":192,"@antv/g-base":115}],187:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var g_base_1 = require("@antv/g-base"); var svg_1 = require("../util/svg"); var dom_1 = require("../util/dom"); var draw_1 = require("../util/draw"); var constant_1 = require("../constant"); var Shape = require("./index"); var group_1 = require("../group"); var index_1 = require("@antv/g-base/lib/bbox/index"); var ShapeBase = /** @class */ (function (_super) { tslib_1.__extends(ShapeBase, _super); function ShapeBase() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'svg'; _this.canFill = false; _this.canStroke = false; return _this; } ShapeBase.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); // 设置默认值 return tslib_1.__assign(tslib_1.__assign({}, attrs), { lineWidth: 1, lineAppendWidth: 0, strokeOpacity: 1, fillOpacity: 1 }); }; // 覆盖基类的 afterAttrsChange 方法 ShapeBase.prototype.afterAttrsChange = function (targetAttrs) { _super.prototype.afterAttrsChange.call(this, targetAttrs); var canvas = this.get('canvas'); // 只有挂载到画布下,才对元素进行实际渲染 if (canvas && canvas.get('autoDraw')) { var context = canvas.get('context'); this.draw(context, targetAttrs); } }; ShapeBase.prototype.getShapeBase = function () { return Shape; }; ShapeBase.prototype.getGroupBase = function () { return group_1.default; }; /** * 一些方法调用会引起画布变化 * @param {ChangeType} changeType 改变的类型 */ ShapeBase.prototype.onCanvasChange = function (changeType) { draw_1.refreshElement(this, changeType); }; ShapeBase.prototype.calculateBBox = function () { var el = this.get('el'); var bbox = null; // 包围盒计算依赖于绘制,如果还没有生成对应的 Dom 元素,则包围盒的长宽均为 0 if (el) { bbox = el.getBBox(); } else { var bboxMethod = index_1.getBBoxMethod(this.get('type')); if (bboxMethod) { bbox = bboxMethod(this); } } if (bbox) { var x = bbox.x, y = bbox.y, width = bbox.width, height = bbox.height; var lineWidth = this.getHitLineWidth(); var halfWidth = lineWidth / 2; var minX = x - halfWidth; var minY = y - halfWidth; var maxX = x + width + halfWidth; var maxY = y + height + halfWidth; return { x: minX, y: minY, minX: minX, minY: minY, maxX: maxX, maxY: maxY, width: width + lineWidth, height: height + lineWidth, }; } return { x: 0, y: 0, minX: 0, minY: 0, maxX: 0, maxY: 0, width: 0, height: 0, }; }; ShapeBase.prototype.isFill = function () { var _a = this.attr(), fill = _a.fill, fillStyle = _a.fillStyle; return (fill || fillStyle || this.isClipShape()) && this.canFill; }; ShapeBase.prototype.isStroke = function () { var _a = this.attr(), stroke = _a.stroke, strokeStyle = _a.strokeStyle; return (stroke || strokeStyle) && this.canStroke; }; ShapeBase.prototype.draw = function (context, targetAttrs) { var el = this.get('el'); if (this.get('destroyed')) { if (el) { el.parentNode.removeChild(el); } } else { if (!el) { dom_1.createDom(this); } svg_1.setClip(this, context); this.createPath(context, targetAttrs); this.shadow(context, targetAttrs); this.strokeAndFill(context, targetAttrs); this.transform(targetAttrs); } }; /** * @protected * 绘制图形的路径 * @param {Defs} context 上下文 * @param {ShapeAttrs} targetAttrs 渲染的目标属性 */ ShapeBase.prototype.createPath = function (context, targetAttrs) { }; // stroke and fill ShapeBase.prototype.strokeAndFill = function (context, targetAttrs) { var attrs = targetAttrs || this.attr(); var fill = attrs.fill, fillStyle = attrs.fillStyle, stroke = attrs.stroke, strokeStyle = attrs.strokeStyle, fillOpacity = attrs.fillOpacity, strokeOpacity = attrs.strokeOpacity, lineWidth = attrs.lineWidth; var el = this.get('el'); if (this.canFill) { // 初次渲染和更新渲染的逻辑有所不同: 初次渲染值为空时,需要设置为 none,否则就会是黑色,而更新渲染则不需要 if (!targetAttrs) { this._setColor(context, 'fill', fill || fillStyle); } else if ('fill' in attrs) { this._setColor(context, 'fill', fill); } else if ('fillStyle' in attrs) { // compatible with fillStyle this._setColor(context, 'fill', fillStyle); } if (fillOpacity) { el.setAttribute(constant_1.SVG_ATTR_MAP['fillOpacity'], fillOpacity); } } if (this.canStroke && lineWidth > 0) { if (!targetAttrs) { this._setColor(context, 'stroke', stroke || strokeStyle); } else if ('stroke' in attrs) { this._setColor(context, 'stroke', stroke); } else if ('strokeStyle' in attrs) { // compatible with strokeStyle this._setColor(context, 'stroke', strokeStyle); } if (strokeOpacity) { el.setAttribute(constant_1.SVG_ATTR_MAP['strokeOpacity'], strokeOpacity); } if (lineWidth) { el.setAttribute(constant_1.SVG_ATTR_MAP['lineWidth'], lineWidth); } } }; ShapeBase.prototype._setColor = function (context, attr, value) { var el = this.get('el'); if (!value) { // need to set `none` to avoid default value el.setAttribute(constant_1.SVG_ATTR_MAP[attr], 'none'); return; } value = value.trim(); if (/^[r,R,L,l]{1}[\s]*\(/.test(value)) { var id = context.find('gradient', value); if (!id) { id = context.addGradient(value); } el.setAttribute(constant_1.SVG_ATTR_MAP[attr], "url(#" + id + ")"); } else if (/^[p,P]{1}[\s]*\(/.test(value)) { var id = context.find('pattern', value); if (!id) { id = context.addPattern(value); } el.setAttribute(constant_1.SVG_ATTR_MAP[attr], "url(#" + id + ")"); } else { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }; ShapeBase.prototype.shadow = function (context, targetAttrs) { var attrs = this.attr(); var _a = targetAttrs || attrs, shadowOffsetX = _a.shadowOffsetX, shadowOffsetY = _a.shadowOffsetY, shadowBlur = _a.shadowBlur, shadowColor = _a.shadowColor; if (shadowOffsetX || shadowOffsetY || shadowBlur || shadowColor) { svg_1.setShadow(this, context); } }; ShapeBase.prototype.transform = function (targetAttrs) { var attrs = this.attr(); var matrix = (targetAttrs || attrs).matrix; if (matrix) { svg_1.setTransform(this); } }; ShapeBase.prototype.isInShape = function (refX, refY) { return this.isPointInPath(refX, refY); }; ShapeBase.prototype.isPointInPath = function (refX, refY) { var el = this.get('el'); var canvas = this.get('canvas'); var bbox = canvas.get('el').getBoundingClientRect(); var clientX = refX + bbox.left; var clientY = refY + bbox.top; var element = document.elementFromPoint(clientX, clientY); if (element && element.isEqualNode(el)) { return true; } return false; }; /** * 获取线拾取的宽度 * @returns {number} 线的拾取宽度 */ ShapeBase.prototype.getHitLineWidth = function () { var _a = this.attrs, lineWidth = _a.lineWidth, lineAppendWidth = _a.lineAppendWidth; if (this.isStroke()) { return lineWidth + lineAppendWidth; } return 0; }; return ShapeBase; }(g_base_1.AbstractShape)); exports.default = ShapeBase; },{"../constant":178,"../group":185,"../util/dom":201,"../util/draw":202,"../util/svg":204,"./index":192,"@antv/g-base":115,"@antv/g-base/lib/bbox/index":104,"tslib":894}],188:[function(require,module,exports){ "use strict"; /** * @fileoverview circle * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Circle = /** @class */ (function (_super) { tslib_1.__extends(Circle, _super); function Circle() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'circle'; _this.canFill = true; _this.canStroke = true; return _this; } Circle.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, r: 0 }); }; Circle.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { // 圆和椭圆的点坐标属性不是 x, y,而是 cx, cy if (attr === 'x' || attr === 'y') { el.setAttribute("c" + attr, value); } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; return Circle; }(base_1.default)); exports.default = Circle; },{"../constant":178,"./base":187,"@antv/util":803,"tslib":894}],189:[function(require,module,exports){ "use strict"; /** * @fileoverview dom * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Dom = /** @class */ (function (_super) { tslib_1.__extends(Dom, _super); function Dom() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'dom'; _this.canFill = false; _this.canStroke = false; return _this; } Dom.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); el.innerHTML = attrs['html']; // set innerHTML }; return Dom; }(base_1.default)); exports.default = Dom; },{"../constant":178,"./base":187,"@antv/util":803,"tslib":894}],190:[function(require,module,exports){ "use strict"; /** * @fileoverview ellipse * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Ellipse = /** @class */ (function (_super) { tslib_1.__extends(Ellipse, _super); function Ellipse() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'ellipse'; _this.canFill = true; _this.canStroke = true; return _this; } Ellipse.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, rx: 0, ry: 0 }); }; Ellipse.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { // 圆和椭圆的点坐标属性不是 x, y,而是 cx, cy if (attr === 'x' || attr === 'y') { el.setAttribute("c" + attr, value); } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; return Ellipse; }(base_1.default)); exports.default = Ellipse; },{"../constant":178,"./base":187,"@antv/util":803,"tslib":894}],191:[function(require,module,exports){ "use strict"; /** * @fileoverview image * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Image = /** @class */ (function (_super) { tslib_1.__extends(Image, _super); function Image() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'image'; _this.canFill = false; _this.canStroke = false; return _this; } Image.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, width: 0, height: 0 }); }; Image.prototype.createPath = function (context, targetAttrs) { var _this = this; var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (attr === 'img') { _this._setImage(attrs.img); } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; Image.prototype.setAttr = function (name, value) { this.attrs[name] = value; if (name === 'img') { this._setImage(value); } }; Image.prototype._setImage = function (img) { var attrs = this.attr(); var el = this.get('el'); if (util_1.isString(img)) { el.setAttribute('href', img); } else if (img instanceof window.Image) { if (!attrs.width) { el.setAttribute('width', img.width); this.attr('width', img.width); } if (!attrs.height) { el.setAttribute('height', img.height); this.attr('height', img.height); } el.setAttribute('href', img.src); } else if (img instanceof HTMLElement && util_1.isString(img.nodeName) && img.nodeName.toUpperCase() === 'CANVAS') { // @ts-ignore el.setAttribute('href', img.toDataURL()); } else if (img instanceof ImageData) { var canvas = document.createElement('canvas'); canvas.setAttribute('width', "" + img.width); canvas.setAttribute('height', "" + img.height); canvas.getContext('2d').putImageData(img, 0, 0); if (!attrs.width) { el.setAttribute('width', "" + img.width); this.attr('width', img.width); } if (!attrs.height) { el.setAttribute('height', "" + img.height); this.attr('height', img.height); } el.setAttribute('href', canvas.toDataURL()); } }; return Image; }(base_1.default)); exports.default = Image; },{"../constant":178,"./base":187,"@antv/util":803,"tslib":894}],192:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("./base"); exports.Base = base_1.default; var circle_1 = require("./circle"); exports.Circle = circle_1.default; var dom_1 = require("./dom"); exports.Dom = dom_1.default; var ellipse_1 = require("./ellipse"); exports.Ellipse = ellipse_1.default; var image_1 = require("./image"); exports.Image = image_1.default; var line_1 = require("./line"); exports.Line = line_1.default; var marker_1 = require("./marker"); exports.Marker = marker_1.default; var path_1 = require("./path"); exports.Path = path_1.default; var polygon_1 = require("./polygon"); exports.Polygon = polygon_1.default; var polyline_1 = require("./polyline"); exports.Polyline = polyline_1.default; var rect_1 = require("./rect"); exports.Rect = rect_1.default; var text_1 = require("./text"); exports.Text = text_1.default; },{"./base":187,"./circle":188,"./dom":189,"./ellipse":190,"./image":191,"./line":193,"./marker":194,"./path":196,"./polygon":197,"./polyline":198,"./rect":199,"./text":200}],193:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * @fileoverview line * @author dengfuping_develop@163.com */ var line_1 = require("@antv/g-math/lib/line"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Line = /** @class */ (function (_super) { tslib_1.__extends(Line, _super); function Line() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'line'; _this.canFill = false; _this.canStroke = true; return _this; } Line.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x1: 0, y1: 0, x2: 0, y2: 0, startArrow: false, endArrow: false }); }; Line.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (attr === 'startArrow' || attr === 'endArrow') { if (value) { var id = util_1.isObject(value) ? context.addArrow(attrs, constant_1.SVG_ATTR_MAP[attr]) : context.getDefaultArrow(attrs, constant_1.SVG_ATTR_MAP[attr]); el.setAttribute(constant_1.SVG_ATTR_MAP[attr], "url(#" + id + ")"); } else { el.removeAttribute(constant_1.SVG_ATTR_MAP[attr]); } } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; /** * Use math calculation to get length of line * @return {number} length */ Line.prototype.getTotalLength = function () { var _a = this.attr(), x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2; return line_1.default.length(x1, y1, x2, y2); }; /** * Use math calculation to get point according to ratio as same sa Canvas version * @param {number} ratio * @return {Point} point */ Line.prototype.getPoint = function (ratio) { var _a = this.attr(), x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2; return line_1.default.pointAt(x1, y1, x2, y2, ratio); }; return Line; }(base_1.default)); exports.default = Line; },{"../constant":178,"./base":187,"@antv/g-math/lib/line":172,"@antv/util":803,"tslib":894}],194:[function(require,module,exports){ "use strict"; /** * @fileoverview marker * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var symbols_1 = require("./symbols"); var Marker = /** @class */ (function (_super) { tslib_1.__extends(Marker, _super); function Marker() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'marker'; _this.canFill = true; _this.canStroke = true; return _this; } Marker.prototype.createPath = function (context) { var el = this.get('el'); el.setAttribute('d', this._assembleMarker()); }; Marker.prototype._assembleMarker = function () { var d = this._getPath(); if (util_1.isArray(d)) { return d .map(function (path) { return path.join(' '); }) .join(''); } return d; }; Marker.prototype._getPath = function () { var attrs = this.attr(); var x = attrs.x, y = attrs.y; // 兼容 r 和 radius 两种写法,推荐使用 r var r = attrs.r || attrs.radius; var symbol = attrs.symbol || 'circle'; var method; if (util_1.isFunction(symbol)) { method = symbol; } else { method = symbols_1.default.get(symbol); } if (!method) { console.warn(method + " symbol is not exist."); return null; } return method(x, y, r); }; // 作为其静态属性 Marker.symbolsFactory = symbols_1.default; return Marker; }(base_1.default)); exports.default = Marker; },{"../base":187,"./symbols":195,"@antv/util":803,"tslib":894}],195:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Symbols = { // 圆 circle: function (x, y, r) { return [['M', x, y], ['m', -r, 0], ['a', r, r, 0, 1, 0, r * 2, 0], ['a', r, r, 0, 1, 0, -r * 2, 0]]; }, // 正方形 square: function (x, y, r) { return [['M', x - r, y - r], ['L', x + r, y - r], ['L', x + r, y + r], ['L', x - r, y + r], ['Z']]; }, // 菱形 diamond: function (x, y, r) { return [['M', x - r, y], ['L', x, y - r], ['L', x + r, y], ['L', x, y + r], ['Z']]; }, // 三角形 triangle: function (x, y, r) { var diffY = r * Math.sin((1 / 3) * Math.PI); return [['M', x - r, y + diffY], ['L', x, y - diffY], ['L', x + r, y + diffY], ['z']]; }, // 倒三角形 triangleDown: function (x, y, r) { var diffY = r * Math.sin((1 / 3) * Math.PI); return [['M', x - r, y - diffY], ['L', x + r, y - diffY], ['L', x, y + diffY], ['Z']]; }, }; exports.default = { get: function (type) { return Symbols[type]; }, register: function (type, func) { Symbols[type] = func; }, remove: function (type) { delete Symbols[type]; }, getAll: function () { return Symbols; }, }; },{}],196:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Path = /** @class */ (function (_super) { tslib_1.__extends(Path, _super); function Path() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'path'; _this.canFill = true; _this.canStroke = true; return _this; } Path.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { startArrow: false, endArrow: false }); }; Path.prototype.createPath = function (context, targetAttrs) { var _this = this; var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (attr === 'path' && util_1.isArray(value)) { el.setAttribute('d', _this._formatPath(value)); } else if (attr === 'startArrow' || attr === 'endArrow') { if (value) { var id = util_1.isObject(value) ? context.addArrow(attrs, constant_1.SVG_ATTR_MAP[attr]) : context.getDefaultArrow(attrs, constant_1.SVG_ATTR_MAP[attr]); el.setAttribute(constant_1.SVG_ATTR_MAP[attr], "url(#" + id + ")"); } else { el.removeAttribute(constant_1.SVG_ATTR_MAP[attr]); } } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; Path.prototype._formatPath = function (value) { var newValue = value .map(function (path) { return path.join(' '); }) .join(''); if (~newValue.indexOf('NaN')) { return ''; } return newValue; }; /** * Get total length of path * 尽管通过浏览器的 SVGPathElement.getTotalLength() 接口获取的 path 长度, * 与 Canvas 版本通过数学计算的方式得到的长度有一些细微差异,但最大误差在个位数像素,精度上可以能接受 * @return {number} length */ Path.prototype.getTotalLength = function () { var el = this.get('el'); return el ? el.getTotalLength() : null; }; /** * Get point according to ratio * @param {number} ratio * @return {Point} point */ Path.prototype.getPoint = function (ratio) { var el = this.get('el'); var totalLength = this.getTotalLength(); var point = el ? el.getPointAtLength(ratio * totalLength) : null; return point ? { x: point.x, y: point.y, } : null; }; return Path; }(base_1.default)); exports.default = Path; },{"../constant":178,"./base":187,"@antv/util":803,"tslib":894}],197:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * @fileoverview polygon * @author dengfuping_develop@163.com */ var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Polygon = /** @class */ (function (_super) { tslib_1.__extends(Polygon, _super); function Polygon() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'polygon'; _this.canFill = true; _this.canStroke = true; return _this; } Polygon.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (attr === 'points' && util_1.isArray(value) && value.length >= 2) { el.setAttribute('points', value.map(function (point) { return point[0] + "," + point[1]; }).join(' ')); } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; return Polygon; }(base_1.default)); exports.default = Polygon; },{"../constant":178,"./base":187,"@antv/util":803,"tslib":894}],198:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var line_1 = require("@antv/g-math/lib/line"); var polyline_1 = require("@antv/g-math/lib/polyline"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = require("./base"); var Polyline = /** @class */ (function (_super) { tslib_1.__extends(Polyline, _super); function Polyline() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'polyline'; _this.canFill = true; _this.canStroke = true; return _this; } Polyline.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { startArrow: false, endArrow: false }); }; // 更新属性时,检测是否更改了 points Polyline.prototype.onAttrChange = function (name, value, originValue) { _super.prototype.onAttrChange.call(this, name, value, originValue); if (['points'].indexOf(name) !== -1) { this._resetCache(); } }; Polyline.prototype._resetCache = function () { this.set('totalLength', null); this.set('tCache', null); }; Polyline.prototype.createPath = function (context, targetAttrs) { var attrs = this.attr(); var el = this.get('el'); util_1.each(targetAttrs || attrs, function (value, attr) { if (attr === 'points' && util_1.isArray(value) && value.length >= 2) { el.setAttribute('points', value.map(function (point) { return point[0] + "," + point[1]; }).join(' ')); } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; /** * Get length of polyline * @return {number} length */ Polyline.prototype.getTotalLength = function () { var points = this.attr().points; // get totalLength from cache var totalLength = this.get('totalLength'); if (!util_1.isNil(totalLength)) { return totalLength; } this.set('totalLength', polyline_1.default.length(points)); return this.get('totalLength'); }; /** * Get point according to ratio * @param {number} ratio * @return {Point} point */ Polyline.prototype.getPoint = function (ratio) { var points = this.attr().points; // get tCache from cache var tCache = this.get('tCache'); if (!tCache) { this._setTcache(); tCache = this.get('tCache'); } var subt; var index; util_1.each(tCache, function (v, i) { if (ratio >= v[0] && ratio <= v[1]) { subt = (ratio - v[0]) / (v[1] - v[0]); index = i; } }); return line_1.default.pointAt(points[index][0], points[index][1], points[index + 1][0], points[index + 1][1], subt); }; Polyline.prototype._setTcache = function () { var points = this.attr().points; if (!points || points.length === 0) { return; } var totalLength = this.getTotalLength(); if (totalLength <= 0) { return; } var tempLength = 0; var tCache = []; var segmentT; var segmentL; util_1.each(points, function (p, i) { if (points[i + 1]) { segmentT = []; segmentT[0] = tempLength / totalLength; segmentL = line_1.default.length(p[0], p[1], points[i + 1][0], points[i + 1][1]); tempLength += segmentL; segmentT[1] = tempLength / totalLength; tCache.push(segmentT); } }); this.set('tCache', tCache); }; /** * Get start tangent vector * @return {Array} */ Polyline.prototype.getStartTangent = function () { var points = this.attr().points; var result = []; result.push([points[1][0], points[1][1]]); result.push([points[0][0], points[0][1]]); return result; }; /** * Get end tangent vector * @return {Array} */ Polyline.prototype.getEndTangent = function () { var points = this.attr().points; var l = points.length - 1; var result = []; result.push([points[l - 1][0], points[l - 1][1]]); result.push([points[l][0], points[l][1]]); return result; }; return Polyline; }(base_1.default)); exports.default = Polyline; },{"../constant":178,"./base":187,"@antv/g-math/lib/line":172,"@antv/g-math/lib/polyline":173,"@antv/util":803,"tslib":894}],199:[function(require,module,exports){ "use strict"; /** * @fileoverview rect * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var constant_1 = require("../constant"); var format_1 = require("../util/format"); var Rect = /** @class */ (function (_super) { tslib_1.__extends(Rect, _super); function Rect() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'rect'; _this.canFill = true; _this.canStroke = true; return _this; } Rect.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, width: 0, height: 0, radius: 0 }); }; Rect.prototype.createPath = function (context, targetAttrs) { var _this = this; var attrs = this.attr(); var el = this.get('el'); // 加上状态量,用来标记 path 是否已组装 var completed = false; // 和组装 path 相关的绘图属性 var pathRelatedAttrs = ['x', 'y', 'width', 'height', 'radius']; util_1.each(targetAttrs || attrs, function (value, attr) { if (pathRelatedAttrs.indexOf(attr) !== -1 && !completed) { el.setAttribute('d', _this._assembleRect(attrs)); completed = true; } else if (pathRelatedAttrs.indexOf(attr) === -1 && constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); }; Rect.prototype._assembleRect = function (attrs) { var x = attrs.x; var y = attrs.y; var w = attrs.width; var h = attrs.height; var radius = attrs.radius; if (!radius) { return "M " + x + "," + y + " l " + w + ",0 l 0," + h + " l" + -w + " 0 z"; } var r = format_1.parseRadius(radius); if (util_1.isArray(radius)) { if (radius.length === 1) { r.r1 = r.r2 = r.r3 = r.r4 = radius[0]; } else if (radius.length === 2) { r.r1 = r.r3 = radius[0]; r.r2 = r.r4 = radius[1]; } else if (radius.length === 3) { r.r1 = radius[0]; r.r2 = r.r4 = radius[1]; r.r3 = radius[2]; } else { r.r1 = radius[0]; r.r2 = radius[1]; r.r3 = radius[2]; r.r4 = radius[3]; } } else { r.r1 = r.r2 = r.r3 = r.r4 = radius; } var d = [ ["M " + (x + r.r1) + "," + y], ["l " + (w - r.r1 - r.r2) + ",0"], ["a " + r.r2 + "," + r.r2 + ",0,0,1," + r.r2 + "," + r.r2], ["l 0," + (h - r.r2 - r.r3)], ["a " + r.r3 + "," + r.r3 + ",0,0,1," + -r.r3 + "," + r.r3], ["l " + (r.r3 + r.r4 - w) + ",0"], ["a " + r.r4 + "," + r.r4 + ",0,0,1," + -r.r4 + "," + -r.r4], ["l 0," + (r.r4 + r.r1 - h)], ["a " + r.r1 + "," + r.r1 + ",0,0,1," + r.r1 + "," + -r.r1], ['z'], ]; return d.join(' '); }; return Rect; }(base_1.default)); exports.default = Rect; },{"../constant":178,"../util/format":203,"./base":187,"@antv/util":803,"tslib":894}],200:[function(require,module,exports){ "use strict"; /** * @fileoverview text * @author dengfuping_develop@163.com */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var detect_browser_1 = require("detect-browser"); var svg_1 = require("../util/svg"); var constant_1 = require("../constant"); var base_1 = require("./base"); var LETTER_SPACING = 0.3; var BASELINE_MAP = { top: 'before-edge', middle: 'central', bottom: 'after-edge', alphabetic: 'baseline', hanging: 'hanging', }; // for FireFox var BASELINE_MAP_FOR_FIREFOX = { top: 'text-before-edge', middle: 'central', bottom: 'text-after-edge', alphabetic: 'alphabetic', hanging: 'hanging', }; var ANCHOR_MAP = { left: 'left', start: 'left', center: 'middle', right: 'end', end: 'end', }; var Text = /** @class */ (function (_super) { tslib_1.__extends(Text, _super); function Text() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'text'; _this.canFill = true; _this.canStroke = true; return _this; } Text.prototype.getDefaultAttrs = function () { var attrs = _super.prototype.getDefaultAttrs.call(this); return tslib_1.__assign(tslib_1.__assign({}, attrs), { x: 0, y: 0, text: null, fontSize: 12, fontFamily: 'sans-serif', fontStyle: 'normal', fontWeight: 'normal', fontVariant: 'normal', textAlign: 'start', textBaseline: 'bottom' }); }; Text.prototype.createPath = function (context, targetAttrs) { var _this = this; var attrs = this.attr(); var el = this.get('el'); this._setFont(); util_1.each(targetAttrs || attrs, function (value, attr) { if (attr === 'text') { _this._setText("" + value); } else if (attr === 'matrix' && value) { svg_1.setTransform(_this); } else if (constant_1.SVG_ATTR_MAP[attr]) { el.setAttribute(constant_1.SVG_ATTR_MAP[attr], value); } }); el.setAttribute('paint-order', 'stroke'); el.setAttribute('style', 'stroke-linecap:butt; stroke-linejoin:miter;'); }; Text.prototype._setFont = function () { var el = this.get('el'); var _a = this.attr(), textBaseline = _a.textBaseline, textAlign = _a.textAlign; var browser = detect_browser_1.detect(); if (browser && browser.name === 'firefox') { // compatible with FireFox browser, ref: https://github.com/antvis/g/issues/119 el.setAttribute('dominant-baseline', BASELINE_MAP_FOR_FIREFOX[textBaseline] || 'alphabetic'); } else { el.setAttribute('alignment-baseline', BASELINE_MAP[textBaseline] || 'baseline'); } el.setAttribute('text-anchor', ANCHOR_MAP[textAlign] || 'left'); }; Text.prototype._setText = function (text) { var el = this.get('el'); var _a = this.attr(), x = _a.x, _b = _a.textBaseline, baseline = _b === void 0 ? 'bottom' : _b; if (!text) { el.innerHTML = ''; } else if (~text.indexOf('\n')) { var textArr = text.split('\n'); var textLen_1 = textArr.length - 1; var arr_1 = ''; util_1.each(textArr, function (segment, i) { if (i === 0) { if (baseline === 'alphabetic') { arr_1 += "" + segment + ""; } else if (baseline === 'top') { arr_1 += "" + segment + ""; } else if (baseline === 'middle') { arr_1 += "" + segment + ""; } else if (baseline === 'bottom') { arr_1 += "" + segment + ""; } else if (baseline === 'hanging') { arr_1 += "" + segment + ""; } } else { arr_1 += "" + segment + ""; } }); el.innerHTML = arr_1; } else { el.innerHTML = text; } }; return Text; }(base_1.default)); exports.default = Text; },{"../constant":178,"../util/svg":204,"./base":187,"@antv/util":803,"detect-browser":205,"tslib":894}],201:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); /** * 创建并返回图形的 svg 元素 * @param type svg类型 */ function createSVGElement(type) { return document.createElementNS('http://www.w3.org/2000/svg', type); } exports.createSVGElement = createSVGElement; /** * 创建并返回图形的 dom 元素 * @param {IShape} shape 图形 * @return {SVGElement} */ function createDom(shape) { var type = constant_1.SHAPE_TO_TAGS[shape.type]; var parent = shape.getParent(); if (!type) { throw new Error("the type " + shape.type + " is not supported by svg"); } var element = createSVGElement(type); if (shape.get('id')) { element.id = shape.get('id'); } shape.set('el', element); shape.set('attrs', {}); // 对于 defs 下的 dom 节点,parent 为空,通过 context 统一挂载到 defs 节点下 if (parent) { var parentNode = parent.get('el'); if (parentNode) { parentNode.appendChild(element); } else { // parentNode maybe null for group parentNode = parent.createDom(); parent.set('el', parentNode); parentNode.appendChild(element); } } return element; } exports.createDom = createDom; /** * 对 dom 元素进行排序 * @param {IElement} element 元素 * @param {sorter} function 排序函数 */ function sortDom(element, sorter) { var el = element.get('el'); var childList = util_1.toArray(el.children).sort(sorter); // create empty fragment var fragment = document.createDocumentFragment(); childList.forEach(function (child) { fragment.appendChild(child); }); el.appendChild(fragment); } exports.sortDom = sortDom; /** * 将 dom 元素移动到父元素下的指定位置 * @param {SVGElement} element dom 元素 * @param {number} targetIndex 目标位置(从 0 开始) */ function moveTo(element, targetIndex) { var parentNode = element.parentNode; var siblings = Array.from(parentNode.childNodes).filter( // 要求为元素节点,且不能为 defs 节点 function (node) { return node.nodeType === 1 && node.nodeName.toLowerCase() !== 'defs'; }); // 获取目标节点 var target = siblings[targetIndex]; var currentIndex = siblings.indexOf(element); // 如果目标节点存在 if (target) { // 当前索引 > 目标索引,直接插入到目标节点之前即可 if (currentIndex > targetIndex) { parentNode.insertBefore(element, target); } else if (currentIndex < targetIndex) { // 当前索引 < 目标索引 // 获取目标节点的下一个节点 var targetNext = siblings[targetIndex + 1]; // 如果目标节点的下一个节点存在,插入到该节点之前 if (targetNext) { parentNode.insertBefore(element, targetNext); } else { // 如果该节点不存在,则追加到末尾 parentNode.appendChild(element); } } } else { parentNode.appendChild(element); } } exports.moveTo = moveTo; },{"../constant":178,"@antv/util":803}],202:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var svg_1 = require("./svg"); var dom_1 = require("./dom"); function drawChildren(context, children) { children.forEach(function (child) { child.draw(context); }); } exports.drawChildren = drawChildren; /** * 更新元素,包括 group 和 shape * @param {IElement} element SVG 元素 * @param {ChangeType} changeType 更新类型 */ function refreshElement(element, changeType) { // 对于还没有挂载到画布下的元素,canvas 可能为空 var canvas = element.get('canvas'); // 只有挂载到画布下,才对元素进行实际渲染 if (canvas && canvas.get('autoDraw')) { var context = canvas.get('context'); var parent_1 = element.getParent(); var parentChildren = parent_1 ? parent_1.getChildren() : [canvas]; var el = element.get('el'); if (changeType === 'remove') { var isClipShape = element.get('isClipShape'); // 对于 clip,不仅需要将 clipShape 对于的 SVG 元素删除,还需要将上层的 clipPath 元素也删除 if (isClipShape) { var clipPathEl = el && el.parentNode; var defsEl = clipPathEl && clipPathEl.parentNode; if (clipPathEl && defsEl) { defsEl.removeChild(clipPathEl); } } else if (el && el.parentNode) { el.parentNode.removeChild(el); } } else if (changeType === 'show') { el.setAttribute('visibility', 'visible'); } else if (changeType === 'hide') { el.setAttribute('visibility', 'hidden'); } else if (changeType === 'zIndex') { dom_1.moveTo(el, parentChildren.indexOf(element)); } else if (changeType === 'sort') { var children_1 = element.get('children'); if (children_1 && children_1.length) { dom_1.sortDom(element, function (a, b) { return children_1.indexOf(a) - children_1.indexOf(b) ? 1 : 0; }); } } else if (changeType === 'clear') { // el maybe null for group if (el) { el.innerHTML = ''; } } else if (changeType === 'matrix') { svg_1.setTransform(element); } else if (changeType === 'clip') { svg_1.setClip(element, context); } else if (changeType === 'attr') { // 已在 afterAttrsChange 进行了处理,此处 do nothing } else if (changeType === 'add') { element.draw(context); } } } exports.refreshElement = refreshElement; },{"./dom":201,"./svg":204}],203:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var regexTags = /[MLHVQTCSAZ]([^MLHVQTCSAZ]*)/gi; var regexDot = /[^\s\,]+/gi; function parseRadius(radius) { var r1 = 0; var r2 = 0; var r3 = 0; var r4 = 0; if (util_1.isArray(radius)) { if (radius.length === 1) { r1 = r2 = r3 = r4 = radius[0]; } else if (radius.length === 2) { r1 = r3 = radius[0]; r2 = r4 = radius[1]; } else if (radius.length === 3) { r1 = radius[0]; r2 = r4 = radius[1]; r3 = radius[2]; } else { r1 = radius[0]; r2 = radius[1]; r3 = radius[2]; r4 = radius[3]; } } else { r1 = r2 = r3 = r4 = radius; } return { r1: r1, r2: r2, r3: r3, r4: r4, }; } exports.parseRadius = parseRadius; function parsePath(path) { path = path || []; if (util_1.isArray(path)) { return path; } if (util_1.isString(path)) { path = path.match(regexTags); util_1.each(path, function (item, index) { item = item.match(regexDot); if (item[0].length > 1) { var tag = item[0].charAt(0); item.splice(1, 0, item[0].substr(1)); item[0] = tag; } util_1.each(item, function (sub, i) { if (!isNaN(sub)) { item[i] = +sub; } }); path[index] = item; }); return path; } } exports.parsePath = parsePath; },{"@antv/util":803}],204:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dom_1 = require("./dom"); function setShadow(model, context) { var el = model.cfg.el; var attrs = model.attr(); var cfg = { dx: attrs.shadowOffsetX, dy: attrs.shadowOffsetY, blur: attrs.shadowBlur, color: attrs.shadowColor, }; if (!cfg.dx && !cfg.dy && !cfg.blur && !cfg.color) { el.removeAttribute('filter'); } else { var id = context.find('filter', cfg); if (!id) { id = context.addShadow(cfg); } el.setAttribute('filter', "url(#" + id + ")"); } } exports.setShadow = setShadow; function setTransform(model) { var matrix = model.attr().matrix; if (matrix) { var el = model.cfg.el; var transform = []; for (var i = 0; i < 9; i += 3) { transform.push(matrix[i] + "," + matrix[i + 1]); } transform = transform.join(','); if (transform.indexOf('NaN') === -1) { el.setAttribute('transform', "matrix(" + transform + ")"); } else { console.warn('invalid matrix:', matrix); } } } exports.setTransform = setTransform; function setClip(model, context) { var clip = model.getClip(); var el = model.get('el'); if (!clip) { el.removeAttribute('clip-path'); } else if (clip && !el.hasAttribute('clip-path')) { dom_1.createDom(clip); clip.createPath(context); var id = context.addClip(clip); el.setAttribute('clip-path', "url(#" + id + ")"); } } exports.setClip = setClip; },{"./dom":201}],205:[function(require,module,exports){ (function (process){ "use strict"; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); var BrowserInfo = /** @class */ (function () { function BrowserInfo(name, version, os) { this.name = name; this.version = version; this.os = os; } return BrowserInfo; }()); exports.BrowserInfo = BrowserInfo; var NodeInfo = /** @class */ (function () { function NodeInfo(version) { this.version = version; this.name = 'node'; this.os = process.platform; } return NodeInfo; }()); exports.NodeInfo = NodeInfo; var BotInfo = /** @class */ (function () { function BotInfo() { this.bot = true; // NOTE: deprecated test name instead this.name = 'bot'; this.version = null; this.os = null; } return BotInfo; }()); exports.BotInfo = BotInfo; // tslint:disable-next-line:max-line-length var SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/; var SEARCHBOT_OS_REGEX = /(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/; var REQUIRED_VERSION_PARTS = 3; var userAgentRules = [ ['aol', /AOLShield\/([0-9\._]+)/], ['edge', /Edge\/([0-9\._]+)/], ['edge-ios', /EdgiOS\/([0-9\._]+)/], ['yandexbrowser', /YaBrowser\/([0-9\._]+)/], ['vivaldi', /Vivaldi\/([0-9\.]+)/], ['kakaotalk', /KAKAOTALK\s([0-9\.]+)/], ['samsung', /SamsungBrowser\/([0-9\.]+)/], ['silk', /\bSilk\/([0-9._-]+)\b/], ['miui', /MiuiBrowser\/([0-9\.]+)$/], ['beaker', /BeakerBrowser\/([0-9\.]+)/], ['edge-chromium', /Edg\/([0-9\.]+)/], [ 'chromium-webview', /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/, ], ['chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/], ['phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/], ['crios', /CriOS\/([0-9\.]+)(:?\s|$)/], ['firefox', /Firefox\/([0-9\.]+)(?:\s|$)/], ['fxios', /FxiOS\/([0-9\.]+)/], ['opera-mini', /Opera Mini.*Version\/([0-9\.]+)/], ['opera', /Opera\/([0-9\.]+)(?:\s|$)/], ['opera', /OPR\/([0-9\.]+)(:?\s|$)/], ['ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/], ['ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/], ['ie', /MSIE\s(7\.0)/], ['bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/], ['android', /Android\s([0-9\.]+)/], ['ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/], ['safari', /Version\/([0-9\._]+).*Safari/], ['facebook', /FBAV\/([0-9\.]+)/], ['instagram', /Instagram\s([0-9\.]+)/], ['ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/], ['ios-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/], ['searchbot', SEARCHBOX_UA_REGEX], ]; var operatingSystemRules = [ ['iOS', /iP(hone|od|ad)/], ['Android OS', /Android/], ['BlackBerry OS', /BlackBerry|BB10/], ['Windows Mobile', /IEMobile/], ['Amazon OS', /Kindle/], ['Windows 3.11', /Win16/], ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/], ['Windows 98', /(Windows 98)|(Win98)/], ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/], ['Windows XP', /(Windows NT 5.1)|(Windows XP)/], ['Windows Server 2003', /(Windows NT 5.2)/], ['Windows Vista', /(Windows NT 6.0)/], ['Windows 7', /(Windows NT 6.1)/], ['Windows 8', /(Windows NT 6.2)/], ['Windows 8.1', /(Windows NT 6.3)/], ['Windows 10', /(Windows NT 10.0)/], ['Windows ME', /Windows ME/], ['Open BSD', /OpenBSD/], ['Sun OS', /SunOS/], ['Chrome OS', /CrOS/], ['Linux', /(Linux)|(X11)/], ['Mac OS', /(Mac_PowerPC)|(Macintosh)/], ['QNX', /QNX/], ['BeOS', /BeOS/], ['OS/2', /OS\/2/], ['Search Bot', SEARCHBOT_OS_REGEX], ]; function detect(userAgent) { if (!!userAgent) { return parseUserAgent(userAgent); } if (typeof navigator !== 'undefined') { return parseUserAgent(navigator.userAgent); } return getNodeVersion(); } exports.detect = detect; function parseUserAgent(ua) { // opted for using reduce here rather than Array#first with a regex.test call // this is primarily because using the reduce we only perform the regex // execution once rather than once for the test and for the exec again below // probably something that needs to be benchmarked though var matchedRule = ua !== '' && userAgentRules.reduce(function (matched, _a) { var browser = _a[0], regex = _a[1]; if (matched) { return matched; } var uaMatch = regex.exec(ua); return !!uaMatch && [browser, uaMatch]; }, false); if (!matchedRule) { return null; } var name = matchedRule[0], match = matchedRule[1]; if (name === 'searchbot') { return new BotInfo(); } var versionParts = match[1] && match[1].split(/[._]/).slice(0, 3); if (versionParts) { if (versionParts.length < REQUIRED_VERSION_PARTS) { versionParts = __spreadArrays(versionParts, createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length)); } } else { versionParts = []; } return new BrowserInfo(name, versionParts.join('.'), detectOS(ua)); } exports.parseUserAgent = parseUserAgent; function detectOS(ua) { for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) { var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1]; var match = regex.test(ua); if (match) { return os; } } return null; } exports.detectOS = detectOS; function getNodeVersion() { var isNode = typeof process !== 'undefined' && process.version; return isNode ? new NodeInfo(process.version.slice(1)) : null; } exports.getNodeVersion = getNodeVersion; function createVersionParts(count) { var output = []; for (var ii = 0; ii < count; ii++) { output.push('0'); } return output; } }).call(this,require('_process')) },{"_process":1}],206:[function(require,module,exports){ module.exports={ "__npminstall_done": false, "_args": [ [ "@antv/g-svg@0.4.7", "C:\\xampp\\htdocs\\icehrm\\web" ] ], "_from": "@antv/g-svg@0.4.7", "_id": "@antv/g-svg@0.4.7", "_inBundle": false, "_integrity": "sha512-+lqlBK+qylP4t/vyUgEaPthp1XmTiImfkPl/ZmRp3L1knH64OI9XTfOGGuBUFAt3JBt7VHKf6t0L/MCf0BR88Q==", "_location": "/@antv/g-svg", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, "raw": "@antv/g-svg@0.4.7", "name": "@antv/g-svg", "escapedName": "@antv%2fg-svg", "scope": "@antv", "rawSpec": "0.4.7", "saveSpec": null, "fetchSpec": "0.4.7" }, "_requiredBy": [ "/@antv/g2", "/@antv/g2plot" ], "_resolved": "https://registry.npmjs.org/@antv/g-svg/-/g-svg-0.4.7.tgz", "_spec": "0.4.7", "_where": "C:\\xampp\\htdocs\\icehrm\\web", "author": { "name": "https://github.com/orgs/antvis/people" }, "bugs": { "url": "https://github.com/antvis/g/issues" }, "dependencies": { "@antv/g-base": "^0.4.7", "@antv/g-math": "^0.1.3", "@antv/util": "~2.0.0", "detect-browser": "^4.6.0" }, "description": "A canvas library which providing 2d", "devDependencies": { "@antv/torch": "^1.0.0", "less": "^3.9.0", "npm-run-all": "^4.1.5", "webpack": "^4.39.3", "webpack-cli": "^3.3.7" }, "files": [ "package.json", "esm", "lib", "dist", "LICENSE", "README.md" ], "gitHead": "eb6a2503cb7bb8154697592b10680939d954a31a", "homepage": "https://github.com/antvis/g#readme", "keywords": [ "util", "antv", "g" ], "license": "ISC", "main": "lib/index.js", "module": "esm/index.js", "name": "@antv/g-svg", "publishConfig": { "access": "public" }, "repository": { "type": "git", "url": "git+https://github.com/antvis/g.git" }, "scripts": { "build": "npm run clean && run-p build:*", "build:cjs": "tsc -p tsconfig.json --target ES5 --module commonjs --outDir lib", "build:esm": "tsc -p tsconfig.json --target ES5 --module ESNext --outDir esm", "build:umd": "webpack --config webpack.config.js --mode production", "clean": "rm -rf esm lib dist", "coverage": "npm run coverage-generator && npm run coverage-viewer", "coverage-generator": "torch --coverage --compile --source-pattern src/*.js,src/**/*.js --opts tests/mocha.opts", "coverage-viewer": "torch-coverage", "test": "torch --renderer --compile --opts tests/mocha.opts", "test-live": "torch --compile --interactive --opts tests/mocha.opts", "tsc": "tsc --noEmit", "typecheck": "tsc --noEmit" }, "types": "lib/index.d.ts", "unpkg": "dist/g.min.js", "version": "0.4.7" } },{}],207:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fadeOut = exports.fadeIn = void 0; var util_1 = require("@antv/util"); /** * @ignore * 单个 shape 动画 * 渐现动画 * @param shape 执行动画的图形元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function fadeIn(shape, animateCfg, cfg) { var endState = { fillOpacity: util_1.isNil(shape.attr('fillOpacity')) ? 1 : shape.attr('fillOpacity'), strokeOpacity: util_1.isNil(shape.attr('strokeOpacity')) ? 1 : shape.attr('strokeOpacity'), opacity: util_1.isNil(shape.attr('opacity')) ? 1 : shape.attr('opacity'), }; shape.attr({ fillOpacity: 0, strokeOpacity: 0, opacity: 0, }); shape.animate(endState, animateCfg); } exports.fadeIn = fadeIn; /** * @ignore * 单个 shape 动画 * 渐隐动画 * @param shape 执行动画的图形元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function fadeOut(shape, animateCfg, cfg) { var endState = { fillOpacity: 0, strokeOpacity: 0, opacity: 0, }; var easing = animateCfg.easing, duration = animateCfg.duration, delay = animateCfg.delay; shape.animate(endState, duration, easing, function () { shape.remove(true); }, delay); } exports.fadeOut = fadeOut; },{"@antv/util":803}],208:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.growInXY = exports.growInY = exports.growInX = void 0; var util_1 = require("./util"); /** * @ignore * 入场动画 * x 方向的生长 * @param element 执行动画的元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function growInX(element, animateCfg, cfg) { var coordinate = cfg.coordinate, minYPoint = cfg.minYPoint; util_1.doScaleAnimate(element, animateCfg, coordinate, minYPoint, 'x'); } exports.growInX = growInX; /** * @ignore * 入场动画 * y 轴方向上的生长 * @param element 执行动画的元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function growInY(element, animateCfg, cfg) { var coordinate = cfg.coordinate, minYPoint = cfg.minYPoint; util_1.doScaleAnimate(element, animateCfg, coordinate, minYPoint, 'y'); } exports.growInY = growInY; /** * @ignore * 入场 * 中心点的向四周的生长动画 * @param element 执行动画的元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function growInXY(element, animateCfg, cfg) { var coordinate = cfg.coordinate, minYPoint = cfg.minYPoint; util_1.doScaleAnimate(element, animateCfg, coordinate, minYPoint, 'xy'); } exports.growInXY = growInXY; },{"./util":214}],209:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerAnimation = exports.getAnimation = void 0; var ANIMATIONS_MAP = {}; /** * 根据名称获取对应的动画执行函数 * @param type 动画函数名称 */ function getAnimation(type) { return ANIMATIONS_MAP[type.toLowerCase()]; } exports.getAnimation = getAnimation; /** * 注册动画执行函数 * @param type 动画执行函数名称 * @param animation 动画执行函数 */ function registerAnimation(type, animation) { ANIMATIONS_MAP[type.toLowerCase()] = animation; } exports.registerAnimation = registerAnimation; },{}],210:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pathIn = void 0; /** * @ignore * 入场动画 * path 的入场动画 * @param element 执行动画的元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function pathIn(element, animateCfg, cfg) { // @ts-ignore var length = element.getTotalLength(); // 设置虚线样式 element.attr('lineDash', [length]); element.animate(function (ratio) { return { // 对虚线偏移量做动画 lineDashOffset: (1 - ratio) * length, }; }, animateCfg); } exports.pathIn = pathIn; },{}],211:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.positionUpdate = void 0; /** * @ignore * 坐标移动动画 * @param shape 图形 * @param animateCfg * @param cfg */ function positionUpdate(shape, animateCfg, cfg) { var toAttrs = cfg.toAttrs; // @ts-ignore var x = toAttrs.x; // @ts-ignore var y = toAttrs.y; // @ts-ignore delete toAttrs.x; // @ts-ignore delete toAttrs.y; shape.attr(toAttrs); shape.animate({ x: x, y: y, }, animateCfg); } exports.positionUpdate = positionUpdate; },{}],212:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.scaleInY = exports.scaleInX = void 0; var matrix_util_1 = require("@antv/matrix-util"); /** * @ignore * 沿着 x 方向放大的动画 * @param shape * @param animateCfg * @param shapeModel */ function scaleInX(shape, animateCfg, cfg) { var box = shape.getBBox(); var mappingData = shape.get('origin').mappingData; var points = mappingData.points; // x 数值如果为负值,那么应该从右往左生长 var x = points[0].y - points[1].y > 0 ? box.maxX : box.minX; var y = (box.minY + box.maxY) / 2; shape.applyToMatrix([x, y, 1]); var matrix = matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 0.01, 1], ['t', x, y], ]); shape.setMatrix(matrix); shape.animate({ matrix: matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 100, 1], ['t', x, y], ]), }, animateCfg); } exports.scaleInX = scaleInX; /** * @ignore * 沿着 y 方向放大的动画 * @param shape * @param animateCfg * @param shapeModel */ function scaleInY(shape, animateCfg, cfg) { var box = shape.getBBox(); var mappingData = shape.get('origin').mappingData; var x = (box.minX + box.maxX) / 2; var points = mappingData.points; // 数值如果为负值,那么应该从上往下生长,通过 shape 的关键点进行判断 var y = points[0].y - points[1].y <= 0 ? box.maxY : box.minY; shape.applyToMatrix([x, y, 1]); var matrix = matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 1, 0.01], ['t', x, y], ]); shape.setMatrix(matrix); shape.animate({ matrix: matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 1, 100], ['t', x, y], ]), }, animateCfg); } exports.scaleInY = scaleInY; },{"@antv/matrix-util":717}],213:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sectorPathUpdate = void 0; var tslib_1 = require("tslib"); var arc_params_1 = tslib_1.__importDefault(require("@antv/g-canvas/lib/util/arc-params")); var util_1 = require("@antv/util"); var graphics_1 = require("../../util/graphics"); function getAngle(startPoint, arcPath) { var _a; var _b = arc_params_1.default(startPoint, arcPath), startAngle = _b.startAngle, endAngle = _b.endAngle; if (!util_1.isNumberEqual(startAngle, -Math.PI * 0.5) && startAngle < -Math.PI * 0.5) { startAngle += Math.PI * 2; } if (!util_1.isNumberEqual(endAngle, -Math.PI * 0.5) && endAngle < -Math.PI * 0.5) { endAngle += Math.PI * 2; } if (arcPath[5] === 0) { // 逆时针,需要将 startAngle 和 endAngle 转置,因为 G2 极坐标系为顺时针方向 _a = [endAngle, startAngle], startAngle = _a[0], endAngle = _a[1]; } if (util_1.isNumberEqual(startAngle, Math.PI * 1.5)) { startAngle = Math.PI * -0.5; } if (util_1.isNumberEqual(endAngle, Math.PI * -0.5)) { endAngle = Math.PI * 1.5; } return { startAngle: startAngle, endAngle: endAngle, }; } function getArcStartPoint(path) { var startPoint; if (path[0] === 'M' || path[0] === 'L') { startPoint = [path[1], path[2]]; } else if (path[0] === 'a' || path[0] === 'A') { startPoint = [path[path.length - 2], path[path.length - 1]]; } return startPoint; } /** * path 存在以下情况 * 1. 饼图不为整圆的 path,命令为 M, L, A, L, Z * 2. 饼图为整圆的 path,命令为 M, M, A, A, M, Z * 3. 环图不为整圆的 path,命令为 M, A, L, A, L, Z * 4. 环图为整圆的 path,命令为 M, A, A, M, A, A, M, Z * 5. radial-line, 不为整圆时的 path, 命令为 M, A, A, Z * 6. radial-line, 为整圆时的 path,命令为 M, A, A, A, A, Z * @param path theta 坐标系下圆弧的 path 命令 */ function getArcInfo(path) { var _a; var startAngle; var endAngle; var arcPaths = path.filter(function (command) { return command[0] === 'A' || command[0] === 'a'; }); var firstArcPathCommand = arcPaths[0]; var lastArcPathCommand = arcPaths.length > 1 ? arcPaths[1] : arcPaths[0]; var firstIndex = path.indexOf(firstArcPathCommand); var lastIndex = path.indexOf(lastArcPathCommand); var firstStartPoint = getArcStartPoint(path[firstIndex - 1]); var lastStartPoint = getArcStartPoint(path[lastIndex - 1]); var _b = getAngle(firstStartPoint, firstArcPathCommand), firstStartAngle = _b.startAngle, firstEndAngle = _b.endAngle; var _c = getAngle(lastStartPoint, lastArcPathCommand), lastStartAngle = _c.startAngle, lastEndAngle = _c.endAngle; if (util_1.isNumberEqual(firstStartAngle, lastStartAngle) && util_1.isNumberEqual(firstEndAngle, lastEndAngle)) { startAngle = firstStartAngle; endAngle = firstEndAngle; } else { startAngle = Math.min(firstStartAngle, lastStartAngle); endAngle = Math.max(firstEndAngle, lastEndAngle); } var radius = firstArcPathCommand[1]; var innerRadius = arcPaths[arcPaths.length - 1][1]; if (radius < innerRadius) { _a = [innerRadius, radius], radius = _a[0], innerRadius = _a[1]; } else if (radius === innerRadius) { innerRadius = 0; } return { startAngle: startAngle, endAngle: endAngle, radius: radius, innerRadius: innerRadius, }; } /** * @ignore * 饼图更新动画 * @param shape 文本图形 * @param animateCfg * @param cfg */ function sectorPathUpdate(shape, animateCfg, cfg) { var toAttrs = cfg.toAttrs, coordinate = cfg.coordinate; // @ts-ignore var path = toAttrs.path; var pathCommands = path.map(function (command) { return command[0]; }); var _a = getArcInfo(path), curStartAngle = _a.startAngle, curEndAngle = _a.endAngle, radius = _a.radius, innerRadius = _a.innerRadius; var _b = getArcInfo(shape.attr('path')), preStartAngle = _b.startAngle, preEndAngle = _b.endAngle; var center = coordinate.getCenter(); var diffStartAngle = curStartAngle - preStartAngle; var diffEndAngle = curEndAngle - preEndAngle; shape.animate(function (ratio) { var onFrameStartAngle = preStartAngle + ratio * diffStartAngle; var onFrameEndAngle = preEndAngle + ratio * diffEndAngle; return tslib_1.__assign(tslib_1.__assign({}, toAttrs), { path: // hack, 兼容 /examples/bar/basic/demo/radial-line.ts 动画 util_1.isEqual(pathCommands, ['M', 'A', 'A', 'Z']) ? graphics_1.getArcPath(center.x, center.y, radius, onFrameStartAngle, onFrameEndAngle) : graphics_1.getSectorPath(center.x, center.y, radius, onFrameStartAngle, onFrameEndAngle, innerRadius) }); }, tslib_1.__assign(tslib_1.__assign({}, animateCfg), { callback: function () { // 将 path 保持原始态,否则会影响 setState() 的动画 shape.attr('path', path); } })); } exports.sectorPathUpdate = sectorPathUpdate; },{"../../util/graphics":375,"@antv/g-canvas/lib/util/arc-params":142,"@antv/util":803,"tslib":385}],214:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.doScaleAnimate = exports.transformShape = void 0; var matrix_util_1 = require("@antv/matrix-util"); /** * @ignore * 对图形元素进行矩阵变换,同时返回变换前的图形矩阵 * @param shape 进行矩阵变换的图形 * @param vector 矩阵变换的中心点 * @param direct 矩阵变换的类型 */ function transformShape(shape, vector, direct) { var scaledMatrix; var x = vector[0], y = vector[1]; shape.applyToMatrix([x, y, 1]); if (direct === 'x') { shape.setMatrix(matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 0.01, 1], ['t', x, y], ])); scaledMatrix = matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 100, 1], ['t', x, y], ]); } else if (direct === 'y') { shape.setMatrix(matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 1, 0.01], ['t', x, y], ])); scaledMatrix = matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 1, 100], ['t', x, y], ]); } else if (direct === 'xy') { shape.setMatrix(matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 0.01, 0.01], ['t', x, y], ])); scaledMatrix = matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 100, 100], ['t', x, y], ]); } return scaledMatrix; } exports.transformShape = transformShape; /** * 对图形元素进行剪切动画 * @param element 进行动画的图形元素 * @param animateCfg 动画配置 * @param coordinate 当前坐标系 * @param yMinPoint y 轴的最小值对应的图形坐标点 * @param type 剪切动画的类型 */ function doScaleAnimate(element, animateCfg, coordinate, yMinPoint, type) { var start = coordinate.start, end = coordinate.end; var width = coordinate.getWidth(); var height = coordinate.getHeight(); var x; var y; if (type === 'y') { x = start.x + width / 2; y = yMinPoint.y < start.y ? yMinPoint.y : start.y; } else if (type === 'x') { x = yMinPoint.x > start.x ? yMinPoint.x : start.x; y = start.y + height / 2; } else if (type === 'xy') { if (coordinate.isPolar) { x = coordinate.getCenter().x; y = coordinate.getCenter().y; } else { x = (start.x + end.x) / 2; y = (start.y + end.y) / 2; } } var endMatrix = transformShape(element, [x, y], type); element.animate({ matrix: endMatrix, }, animateCfg); } exports.doScaleAnimate = doScaleAnimate; },{"@antv/matrix-util":717}],215:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.waveIn = void 0; var tslib_1 = require("tslib"); var coordinate_1 = require("../../util/coordinate"); /** * @ignore * 整体动画 * 划入入场动画效果 * @todo 放两张直角坐标系和极坐标系的图 * @param element 参与动画的图形元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function waveIn(element, animateCfg, cfg) { var _a = coordinate_1.getCoordinateClipCfg(cfg.coordinate, 20), type = _a.type, startState = _a.startState, endState = _a.endState; // 根据坐标系类型获取整体的剪切区域配置信息 var clipShape = element.setClip({ type: type, attrs: startState, }); // 为 shape 设置剪切区域 // 对剪切图形做动画 clipShape.animate(endState, tslib_1.__assign(tslib_1.__assign({}, animateCfg), { callback: function () { if (element && !element.get('destroyed')) { element.set('clipShape', null); } clipShape.remove(true); // 动画结束需要将剪切图形销毁 } })); } exports.waveIn = waveIn; },{"../../util/coordinate":371,"tslib":385}],216:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.zoomOut = exports.zoomIn = void 0; var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); function doShapeZoom(shape, animateCfg, type) { if (shape.isGroup()) { util_1.each(shape.getChildren(), function (child) { doShapeZoom(child, animateCfg, type); }); } else { var bbox = shape.getBBox(); var x = (bbox.minX + bbox.maxX) / 2; var y = (bbox.minY + bbox.maxY) / 2; shape.applyToMatrix([x, y, 1]); if (type === 'zoomIn') { // 放大 var matrix = matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 0.01, 0.01], ['t', x, y], ]); shape.setMatrix(matrix); shape.animate({ matrix: matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 100, 100], ['t', x, y], ]), }, animateCfg); } else { shape.animate({ matrix: matrix_util_1.ext.transform(shape.getMatrix(), [ ['t', -x, -y], ['s', 0.01, 0.01], ['t', x, y], ]), }, tslib_1.__assign(tslib_1.__assign({}, animateCfg), { callback: function () { shape.remove(true); } })); } } } /** * @ignore * 单个 shape 动画 * shape 以自身中心点逐渐放大的进入动画 * @param shape 参与动画的图形元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function zoomIn(shape, animateCfg, cfg) { doShapeZoom(shape, animateCfg, 'zoomIn'); } exports.zoomIn = zoomIn; /** * @ignore * 单个 shape 动画 * 消失动画,shape 以自身为中心点的逐渐缩小 * @param shape 参与动画的图形元素 * @param animateCfg 动画配置 * @param cfg 额外信息 */ function zoomOut(shape, animateCfg, cfg) { doShapeZoom(shape, animateCfg, 'zoomOut'); } exports.zoomOut = zoomOut; },{"@antv/matrix-util":717,"@antv/util":803,"tslib":385}],217:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.doGroupAppearAnimate = exports.doAnimate = exports.getDefaultAnimateCfg = exports.DEFAULT_ANIMATE_CFG = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var animation_1 = require("./animation"); // 默认的动画参数配置 exports.DEFAULT_ANIMATE_CFG = { appear: { duration: 450, easing: 'easeQuadOut', }, update: { duration: 400, easing: 'easeQuadInOut', }, enter: { duration: 400, easing: 'easeQuadInOut', }, leave: { duration: 350, easing: 'easeQuadIn', }, }; // 各个 Geometry 默认的动画执行函数 var GEOMETRY_ANIMATE_CFG = { interval: function (coordinate) { return { enter: { animation: coordinate.isRect ? (coordinate.isTransposed ? 'scale-in-x' : 'scale-in-y') : 'fade-in', }, update: { animation: coordinate.isPolar && coordinate.isTransposed ? 'sector-path-update' : null, }, leave: { animation: 'fade-out', }, }; }, line: { enter: { animation: 'fade-in', }, leave: { animation: 'fade-out', }, }, path: { enter: { animation: 'fade-in', }, leave: { animation: 'fade-out', }, }, point: { appear: { animation: 'zoom-in', }, enter: { animation: 'zoom-in', }, leave: { animation: 'zoom-out', }, }, area: { enter: { animation: 'fade-in', }, leave: { animation: 'fade-out', }, }, polygon: { enter: { animation: 'fade-in', }, leave: { animation: 'fade-out', }, }, schema: { enter: { animation: 'fade-in', }, leave: { animation: 'fade-out', }, }, edge: { enter: { animation: 'fade-in', }, leave: { animation: 'fade-out', }, }, label: { appear: { animation: 'fade-in', delay: 450, }, enter: { animation: 'fade-in', }, update: { animation: 'position-update', }, leave: { animation: 'fade-out', }, }, }; // 各个 Geometry 默认的群组出场动画 var GEOMETRY_GROUP_APPEAR_ANIMATION = { line: function () { return { animation: 'wave-in', }; }, area: function () { return { animation: 'wave-in', }; }, path: function () { return { animation: 'fade-in', }; }, interval: function (coordinate) { var animation; if (coordinate.isRect) { animation = coordinate.isTransposed ? 'grow-in-x' : 'grow-in-y'; } else { animation = 'grow-in-xy'; if (coordinate.isPolar && coordinate.isTransposed) { // pie chart animation = 'wave-in'; } } return { animation: animation, }; }, schema: function (coordinate) { var animation; if (coordinate.isRect) { animation = coordinate.isTransposed ? 'grow-in-x' : 'grow-in-y'; } else { animation = 'grow-in-xy'; } return { animation: animation, }; }, polygon: function () { return { animation: 'fade-in', duration: 500, }; }, edge: function () { return { animation: 'fade-in', }; }, }; // 解析用户的动画配置 function parseAnimateConfig(animateCfg, data) { return { delay: util_1.isFunction(animateCfg.delay) ? animateCfg.delay(data) : animateCfg.delay, easing: util_1.isFunction(animateCfg.easing) ? animateCfg.easing(data) : animateCfg.easing, duration: util_1.isFunction(animateCfg.duration) ? animateCfg.duration(data) : animateCfg.duration, callback: animateCfg.callback, }; } /** * @ignore * 获取 elementName 对应的动画配置,当声明了 `animateType`,则返回 `animateType` 对应的动画配置 * @param elementName 元素名称 * @param coordinate 做表弟类型 * @param animateType 可选,动画类型 */ function getDefaultAnimateCfg(elementName, coordinate, animateType) { var animateCfg = GEOMETRY_ANIMATE_CFG[elementName]; if (animateCfg) { if (util_1.isFunction(animateCfg)) { animateCfg = animateCfg(coordinate); } animateCfg = util_1.deepMix({}, exports.DEFAULT_ANIMATE_CFG, animateCfg); if (animateType) { return animateCfg[animateType]; } } return animateCfg; } exports.getDefaultAnimateCfg = getDefaultAnimateCfg; /** * @ignore * 工具函数 * 根据用户传入的配置为 shape 执行动画 * @param shape 执行动画的图形元素 * @param animateCfg 动画配置 * @param cfg 额外的信息 */ function doAnimate(shape, animateCfg, cfg) { var data = util_1.get(shape.get('origin'), 'data', constant_1.FIELD_ORIGIN); var animation = animateCfg.animation; // 获取动画执行函数 var parsedAnimateCfg = parseAnimateConfig(animateCfg, data); if (animation) { // 用户声明了动画执行函数 var animateFunction = animation_1.getAnimation(animation); if (animateFunction) { animateFunction(shape, parsedAnimateCfg, cfg); } } else { // 没有声明,则根据 toAttrs 做差值动画 shape.animate(cfg.toAttrs, parsedAnimateCfg); } } exports.doAnimate = doAnimate; /** * @ignore * 执行 Geometry 群组入场动画 * @param container 执行群组动画的图形元素 * @param animateCfg 动画配置 * @param geometryType geometry 类型 * @param coordinate 坐标系对象 * @param minYPoint y 轴最小值对应的画布坐标点 */ function doGroupAppearAnimate(container, animateCfg, geometryType, coordinate, minYPoint) { if (GEOMETRY_GROUP_APPEAR_ANIMATION[geometryType]) { var defaultCfg = GEOMETRY_GROUP_APPEAR_ANIMATION[geometryType](coordinate); var animation = animation_1.getAnimation(util_1.get(defaultCfg, 'animation', '')); if (animation) { var cfg = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, exports.DEFAULT_ANIMATE_CFG.appear), defaultCfg), animateCfg); container.stopAnimate(); // 先结束当前 container 动画 animation(container, cfg, { coordinate: coordinate, minYPoint: minYPoint, toAttrs: null, }); } } } exports.doGroupAppearAnimate = doGroupAppearAnimate; },{"../constant":237,"./animation":209,"@antv/util":803,"tslib":385}],218:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); /** * G2 Chart、View、Geometry 以及 Element 等的基类,提供事件以及一些通用的方法。 */ var Base = /** @class */ (function (_super) { tslib_1.__extends(Base, _super); function Base(cfg) { var _this = _super.call(this) || this; /** 标识对象是否已销毁 */ _this.destroyed = false; var _a = cfg.visible, visible = _a === void 0 ? true : _a; _this.visible = visible; return _this; } /** * 显示。 */ Base.prototype.show = function () { var visible = this.visible; if (!visible) { this.changeVisible(true); } }; /** * 隐藏。 */ Base.prototype.hide = function () { var visible = this.visible; if (visible) { this.changeVisible(false); } }; /** * 销毁。 */ Base.prototype.destroy = function () { this.off(); this.destroyed = true; }; /** * 显示或者隐藏。 * @param visible * @returns */ Base.prototype.changeVisible = function (visible) { if (this.visible === visible) { return; } this.visible = visible; }; return Base; }(event_emitter_1.default)); exports.default = Base; },{"@antv/event-emitter":94,"tslib":385}],219:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var engine_1 = require("../engine"); var dom_1 = require("../util/dom"); var view_1 = tslib_1.__importDefault(require("./view")); /** * Chart 类,是使用 G2 进行绘图的入口。 */ var Chart = /** @class */ (function (_super) { tslib_1.__extends(Chart, _super); // @ts-ignore function Chart(props) { var _this = this; var container = props.container, width = props.width, height = props.height, _a = props.autoFit, autoFit = _a === void 0 ? false : _a, padding = props.padding, appendPadding = props.appendPadding, _b = props.renderer, renderer = _b === void 0 ? 'canvas' : _b, pixelRatio = props.pixelRatio, _c = props.localRefresh, localRefresh = _c === void 0 ? true : _c, _d = props.visible, visible = _d === void 0 ? true : _d, _e = props.defaultInteractions, defaultInteractions = _e === void 0 ? ['tooltip', 'legend-filter', 'legend-active', 'continuous-filter', 'ellipsis-text'] : _e, options = props.options, limitInPlot = props.limitInPlot, theme = props.theme; var ele = util_1.isString(container) ? document.getElementById(container) : container; // 生成内部正式绘制的 div 元素 var wrapperElement = dom_1.createDom('
    '); ele.appendChild(wrapperElement); // if autoFit, use the container size, to avoid the graph render twice. var size = dom_1.getChartSize(ele, autoFit, width, height); var G = engine_1.getEngine(renderer); var canvas = new G.Canvas(tslib_1.__assign({ container: wrapperElement, pixelRatio: pixelRatio, localRefresh: localRefresh }, size)); // 调用 view 的创建 _this = _super.call(this, { parent: null, canvas: canvas, // create 3 group layers for views. backgroundGroup: canvas.addGroup({ zIndex: constant_1.GROUP_Z_INDEX.BG }), middleGroup: canvas.addGroup({ zIndex: constant_1.GROUP_Z_INDEX.MID }), foregroundGroup: canvas.addGroup({ zIndex: constant_1.GROUP_Z_INDEX.FORE }), padding: padding, appendPadding: appendPadding, visible: visible, options: options, limitInPlot: limitInPlot, theme: theme, }) || this; /** * when container size changed, change chart size props, and re-render. */ _this.onResize = util_1.debounce(function () { _this.forceFit(); }, 300); _this.ele = ele; _this.canvas = canvas; _this.width = size.width; _this.height = size.height; _this.autoFit = autoFit; _this.localRefresh = localRefresh; _this.renderer = renderer; _this.wrapperElement = wrapperElement; // 自适应大小 _this.updateCanvasStyle(); _this.bindAutoFit(); _this.initDefaultInteractions(defaultInteractions); return _this; } Chart.prototype.initDefaultInteractions = function (interactions) { var _this = this; util_1.each(interactions, function (interaction) { _this.interaction(interaction); }); }; /** * 改变图表大小,同时重新渲染。 * @param width 图表宽度 * @param height 图表高度 * @returns */ Chart.prototype.changeSize = function (width, height) { // 如果宽高一致,那么 changeSize 不执行任何操作 if (this.width === width && this.height === height) { return this; } this.width = width; this.height = height; this.canvas.changeSize(width, height); // 重新渲染 this.render(true); return this; }; /** * 销毁图表,同时解绑事件,销毁创建的 G.Canvas 实例。 * @returns void */ Chart.prototype.destroy = function () { _super.prototype.destroy.call(this); this.unbindAutoFit(); this.canvas.destroy(); dom_1.removeDom(this.wrapperElement); this.wrapperElement = null; }; /** * 显示或隐藏图表 * @param visible 是否可见,true 表示显示,false 表示隐藏 * @returns */ Chart.prototype.changeVisible = function (visible) { _super.prototype.changeVisible.call(this, visible); // 需要更新 visible 变量 this.wrapperElement.style.display = visible ? '' : 'none'; return this; }; /** * 自动根据容器大小 resize 画布 */ Chart.prototype.forceFit = function () { // skip if already destroyed if (!this.destroyed) { // 注意第二参数用 true,意思是即时 autoFit = false,forceFit() 调用之后一样是适配容器 var _a = dom_1.getChartSize(this.ele, true, this.width, this.height), width = _a.width, height = _a.height; this.changeSize(width, height); } }; Chart.prototype.updateCanvasStyle = function () { dom_1.modifyCSS(this.canvas.get('el'), { display: 'inline-block', verticalAlign: 'middle', }); }; Chart.prototype.bindAutoFit = function () { if (this.autoFit) { window.addEventListener('resize', this.onResize); } }; Chart.prototype.unbindAutoFit = function () { if (this.autoFit) { window.removeEventListener('resize', this.onResize); } }; return Chart; }(view_1.default)); exports.default = Chart; },{"../constant":237,"../engine":240,"../util/dom":373,"./view":235,"@antv/util":803,"tslib":385}],220:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../dependents"); var animate_1 = require("../../animate/"); var constant_1 = require("../../constant"); var coordinate_1 = require("../../util/coordinate"); var helper_1 = require("../../util/helper"); var base_1 = require("./base"); /** * Annotation controller, 主要作用: * 1. 创建 Annotation: line、text、arc ... * 2. 生命周期: init、layout、render、clear、destroy */ var Annotation = /** @class */ (function (_super) { tslib_1.__extends(Annotation, _super); function Annotation(view) { var _this = _super.call(this, view) || this; /* 组件更新的 cache,组件配置 object : 组件 */ _this.cache = new Map(); _this.foregroundContainer = _this.view.getLayer(constant_1.LAYER.FORE).addGroup(); _this.backgroundContainer = _this.view.getLayer(constant_1.LAYER.BG).addGroup(); _this.option = []; return _this; } Object.defineProperty(Annotation.prototype, "name", { get: function () { return 'annotation'; }, enumerable: false, configurable: true }); Annotation.prototype.init = function () { }; Annotation.prototype.layout = function () { var _this = this; var components = this.getComponents(); var updateComponentFn = function (co) { var component = co.component, extra = co.extra; var type = extra.type; var theme = _this.getAnnotationTheme(type); component.update(_this.getAnnotationCfg(type, extra, theme)); }; var createComponentFn = function (option) { var co = _this.createAnnotation(option); if (co) { co.component.init(); // Note:regionFilter 特殊处理,regionFilter需要取到 Geometry 中的 Shape,需要在 view render 之后处理 // 其他组件使用外层的统一 render 逻辑 if (option.type === 'regionFilter') { co.component.render(); } // 缓存起来 _this.cache.set(option, co); } }; if (components.length) { util_1.each(components, function (co) { var component = co.component; if (component.get('type') === 'regionFilter') { // regionFilter 依赖绘制后的 Geometry Shapes _this.view.getRootView().once(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, function () { updateComponentFn(co); }); } else { updateComponentFn(co); } }); } else { util_1.each(this.option, function (option) { if (option.type === 'regionFilter') { _this.view.getRootView().once(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, function () { // regionFilter 依赖绘制后的 Geometry Shapes createComponentFn(option); }); } else { createComponentFn(option); } }); } }; Annotation.prototype.render = function () { // 因为 Annotation 不参与布局,但是渲染的位置依赖于坐标系,所以可以将绘制阶段延迟到 layout() 进行 }; /** * 更新 */ Annotation.prototype.update = function () { var _this = this; // 已经处理过的 legend var updated = new WeakMap(); var updateComponentFn = function (option) { var type = option.type; var theme = _this.getAnnotationTheme(type); var cfg = _this.getAnnotationCfg(type, option, theme); var existCo = _this.cache.get(option); // 存在,则更新 if (existCo) { // 忽略掉一些配置 helper_1.omit(cfg, ['container']); existCo.component.update(cfg); updated.set(option, true); } else { // 不存在,则创建 var co = _this.createAnnotation(option); if (co) { co.component.init(); // Note:regionFilter 特殊处理,regionFilter需要取到 Geometry 中的 Shape,需要在 view render 之后处理 // 其他组件使用外层的统一 render 逻辑 if (option.type === 'regionFilter') { co.component.render(); } // 缓存起来 _this.cache.set(option, co); updated.set(option, true); } } }; this.view.once(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, function () { // 先看是否有 regionFilter 要更新 util_1.each(_this.option, function (option) { if (option.type === 'regionFilter') { updateComponentFn(option); } }); // 处理完成之后,销毁删除的 // 不在处理中的 var newCache = new Map(); _this.cache.forEach(function (value, key) { if (updated.has(key)) { newCache.set(key, value); } else { // 不存在,则是所有需要被销毁的组件 value.component.destroy(); } }); // 更新缓存 _this.cache = newCache; }); util_1.each(this.option, function (option) { if (option.type !== 'regionFilter') { updateComponentFn(option); } }); }; /** * 清空 * @param includeOption 是否清空 option 配置项 */ Annotation.prototype.clear = function (includeOption) { if (includeOption === void 0) { includeOption = false; } _super.prototype.clear.call(this); this.cache.clear(); this.foregroundContainer.clear(); this.backgroundContainer.clear(); // clear all option if (includeOption) { this.option = []; } }; Annotation.prototype.destroy = function () { this.clear(true); this.foregroundContainer.remove(true); this.backgroundContainer.remove(true); }; /** * 复写基类的方法 */ Annotation.prototype.getComponents = function () { var co = []; this.cache.forEach(function (value) { co.push(value); }); return co; }; Annotation.prototype.createAnnotation = function (option) { var type = option.type; var Ctor = dependents_1.Annotation[util_1.upperFirst(type)]; if (Ctor) { var theme = this.getAnnotationTheme(type); var cfg = this.getAnnotationCfg(type, option, theme); var annotation = new Ctor(cfg); return { component: annotation, layer: this.isTop(cfg) ? constant_1.LAYER.FORE : constant_1.LAYER.BG, direction: constant_1.DIRECTION.NONE, type: constant_1.COMPONENT_TYPE.ANNOTATION, extra: option, }; } }; // APIs for creating annotation component Annotation.prototype.annotation = function (option) { this.option.push(option); }; /** * 创建 Arc * @param option * @returns AnnotationController */ Annotation.prototype.arc = function (option) { this.annotation(tslib_1.__assign({ type: 'arc' }, option)); return this; }; /** * 创建 image * @param option * @returns AnnotationController */ Annotation.prototype.image = function (option) { this.annotation(tslib_1.__assign({ type: 'image' }, option)); return this; }; /** * 创建 Line * @param option * @returns AnnotationController */ Annotation.prototype.line = function (option) { this.annotation(tslib_1.__assign({ type: 'line' }, option)); return this; }; /** * 创建 Region * @param option * @returns AnnotationController */ Annotation.prototype.region = function (option) { this.annotation(tslib_1.__assign({ type: 'region' }, option)); return this; }; /** * 创建 Text * @param option * @returns AnnotationController */ Annotation.prototype.text = function (option) { this.annotation(tslib_1.__assign({ type: 'text' }, option)); return this; }; /** * 创建 DataMarker * @param option * @returns AnnotationController */ Annotation.prototype.dataMarker = function (option) { this.annotation(tslib_1.__assign({ type: 'dataMarker' }, option)); return this; }; /** * 创建 DataRegion * @param option * @returns AnnotationController */ Annotation.prototype.dataRegion = function (option) { this.annotation(tslib_1.__assign({ type: 'dataRegion' }, option)); }; /** * 创建 RegionFilter * @param option * @returns AnnotationController */ Annotation.prototype.regionFilter = function (option) { this.annotation(tslib_1.__assign({ type: 'regionFilter' }, option)); }; // end API /** * parse the point position to [x, y] * @param p Position * @returns { x, y } */ Annotation.prototype.parsePosition = function (p) { var xScale = this.view.getXScale(); // 转成 object var yScales = this.view.getScalesByDim('y'); var position = util_1.isFunction(p) ? p.call(null, xScale, yScales) : p; var x = 0; var y = 0; // 入参是 [24, 24] 这类时 if (util_1.isArray(position)) { var xPos = position[0], yPos = position[1]; // 如果数据格式是 ['50%', '50%'] 的格式 // fix: 原始数据中可能会包含 'xxx5%xxx' 这样的数据,需要判断下 https://github.com/antvis/f2/issues/590 // @ts-ignore if (util_1.isString(xPos) && xPos.indexOf('%') !== -1 && !isNaN(xPos.slice(0, -1))) { return this.parsePercentPosition(position); } x = this.getNormalizedValue(xPos, xScale); y = this.getNormalizedValue(yPos, Object.values(yScales)[0]); } else if (!util_1.isNil(position)) { // 入参是 object 结构,数据点 for (var _i = 0, _a = util_1.keys(position); _i < _a.length; _i++) { var key = _a[_i]; var value = position[key]; if (key === xScale.field) { x = this.getNormalizedValue(value, xScale); } if (yScales[key]) { y = this.getNormalizedValue(value, yScales[key]); } } } return this.view.getCoordinate().convert({ x: x, y: y }); }; /** * parse all the points between start and end * @param start * @param end * @return Point[] */ Annotation.prototype.getRegionPoints = function (start, end) { var _this = this; var xScale = this.view.getXScale(); var yScales = this.view.getScalesByDim('y'); var yScale = Object.values(yScales)[0]; var xField = xScale.field; var viewData = this.view.getData(); var startXValue = util_1.isArray(start) ? start[0] : start[xField]; var endXValue = util_1.isArray(end) ? end[0] : end[xField]; var arr = []; var startIndex; util_1.each(viewData, function (item, idx) { if (item[xField] === startXValue) { startIndex = idx; } if (idx >= startIndex) { var point = _this.parsePosition([item[xField], item[yScale.field]]); if (point) { arr.push(point); } } if (item[xField] === endXValue) { return false; } }); return arr; }; /** * parse the value position * @param val * @param scale */ Annotation.prototype.getNormalizedValue = function (val, scale) { var result; var scaled; switch (val) { case 'start': result = 0; break; case 'end': result = 1; break; case 'median': { scaled = scale.isCategory ? (scale.values.length - 1) / 2 : (scale.min + scale.max) / 2; result = scale.scale(scaled); break; } case 'min': case 'max': if (scale.isCategory) { scaled = val === 'min' ? 0 : scale.values.length - 1; } else { scaled = scale[val]; } result = scale.scale(scaled); break; default: result = scale.scale(val); } return result; }; /** * parse percent position * @param position */ Annotation.prototype.parsePercentPosition = function (position) { var xPercent = parseFloat(position[0]) / 100; var yPercent = parseFloat(position[1]) / 100; var coordinate = this.view.getCoordinate(); var start = coordinate.start, end = coordinate.end; var topLeft = { x: Math.min(start.x, end.x), y: Math.min(start.y, end.y), }; var x = coordinate.getWidth() * xPercent + topLeft.x; var y = coordinate.getHeight() * yPercent + topLeft.y; return { x: x, y: y }; }; /** * get coordinate bbox */ Annotation.prototype.getCoordinateBBox = function () { var coordinate = this.view.getCoordinate(); var start = coordinate.start, end = coordinate.end; var width = coordinate.getWidth(); var height = coordinate.getHeight(); var topLeft = { x: Math.min(start.x, end.x), y: Math.min(start.y, end.y), }; return { x: topLeft.x, y: topLeft.y, minX: topLeft.x, minY: topLeft.y, maxX: topLeft.x + width, maxY: topLeft.y + height, width: width, height: height, }; }; /** * get annotation component config by different type * @param type * @param option 用户的配置 * @param theme */ Annotation.prototype.getAnnotationCfg = function (type, option, theme) { var coordinate = this.view.getCoordinate(); var o = {}; if (util_1.isNil(option)) { return null; } if (type === 'arc') { var _a = option, start = _a.start, end = _a.end; var sp = this.parsePosition(start); var ep = this.parsePosition(end); var startAngle = coordinate_1.getAngleByPoint(coordinate, sp); var endAngle = coordinate_1.getAngleByPoint(coordinate, ep); if (startAngle > endAngle) { endAngle = Math.PI * 2 + endAngle; } o = { center: coordinate.getCenter(), radius: coordinate_1.getDistanceToCenter(coordinate, sp), startAngle: startAngle, endAngle: endAngle, }; } else if (type === 'image') { var _b = option, start = _b.start, end = _b.end; o = { start: this.parsePosition(start), end: this.parsePosition(end), src: option.src, }; } else if (type === 'line') { var _c = option, start = _c.start, end = _c.end; o = { start: this.parsePosition(start), end: this.parsePosition(end), text: util_1.get(option, 'text', null), }; } else if (type === 'region') { var _d = option, start = _d.start, end = _d.end; o = { start: this.parsePosition(start), end: this.parsePosition(end), }; } else if (type === 'text') { var filteredData = this.view.getData(); var _e = option, position = _e.position, content = _e.content, rest = tslib_1.__rest(_e, ["position", "content"]); var textContent = content; if (util_1.isFunction(content)) { textContent = content(filteredData); } o = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, this.parsePosition(position)), rest), { content: textContent }); } else if (type === 'dataMarker') { var _f = option, position = _f.position, point = _f.point, line = _f.line, text = _f.text, autoAdjust = _f.autoAdjust, direction = _f.direction; o = tslib_1.__assign(tslib_1.__assign({}, this.parsePosition(position)), { coordinateBBox: this.getCoordinateBBox(), point: point, line: line, text: text, autoAdjust: autoAdjust, direction: direction }); } else if (type === 'dataRegion') { var _g = option, start = _g.start, end = _g.end, region = _g.region, text = _g.text, lineLength = _g.lineLength; o = { points: this.getRegionPoints(start, end), region: region, text: text, lineLength: lineLength, }; } else if (type === 'regionFilter') { var _h = option, start = _h.start, end = _h.end, apply_1 = _h.apply, color = _h.color; var geometries = this.view.geometries; var shapes_1 = []; var addShapes_1 = function (item) { if (!item) { return; } if (item.isGroup()) { item.getChildren().forEach(function (child) { return addShapes_1(child); }); } else { shapes_1.push(item); } }; util_1.each(geometries, function (geom) { if (apply_1) { if (util_1.contains(apply_1, geom.type)) { util_1.each(geom.elements, function (elem) { addShapes_1(elem.shape); }); } } else { util_1.each(geom.elements, function (elem) { addShapes_1(elem.shape); }); } }); o = { color: color, shapes: shapes_1, start: this.parsePosition(start), end: this.parsePosition(end), }; } // 合并主题,用户配置优先级高于默认主题 var cfg = util_1.deepMix({}, theme, tslib_1.__assign(tslib_1.__assign({}, o), { top: option.top, style: option.style, offsetX: option.offsetX, offsetY: option.offsetY })); cfg.container = this.getComponentContainer(cfg); cfg.animate = this.view.getOptions().animate && cfg.animate && util_1.get(option, 'animate', cfg.animate); // 如果 view 关闭动画,则不执行 cfg.animateOption = util_1.deepMix({}, animate_1.DEFAULT_ANIMATE_CFG, cfg.animateOption, option.animateOption); return cfg; }; /** * is annotation render on top * @param option * @return whethe on top */ Annotation.prototype.isTop = function (option) { return util_1.get(option, 'top', true); }; /** * get the container by option.top * default is on top * @param option * @returns the container */ Annotation.prototype.getComponentContainer = function (option) { return this.isTop(option) ? this.foregroundContainer : this.backgroundContainer; }; Annotation.prototype.getAnnotationTheme = function (type) { return util_1.get(this.view.getTheme(), ['components', 'annotation', type], {}); }; return Annotation; }(base_1.Controller)); exports.default = Annotation; },{"../../animate/":217,"../../constant":237,"../../dependents":239,"../../util/coordinate":371,"../../util/helper":377,"./base":222,"@antv/util":803,"tslib":385}],221:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../../constant"); var dependents_1 = require("../../dependents"); var animate_1 = require("../../animate/"); var axis_1 = require("../../util/axis"); var axis_2 = require("../../util/axis"); var grid_1 = require("../../util/grid"); var helper_1 = require("../../util/helper"); var base_1 = require("./base"); // update 组件的时候,忽略的数据更新 var OMIT_CFG = ['container']; // 坐标轴默认动画配置 var AXIS_DEFAULT_ANIMATE_CFG = tslib_1.__assign(tslib_1.__assign({}, animate_1.DEFAULT_ANIMATE_CFG), { appear: null }); /** * @ignore * G2 Axis controller, will: * - create component * - axis * - grid * - life circle */ var Axis = /** @class */ (function (_super) { tslib_1.__extends(Axis, _super); function Axis(view) { var _this = _super.call(this, view) || this; /** 使用 object 存储组件 */ _this.cache = new Map(); // 先创建 gridContainer,将 grid 放到 axis 底层 _this.gridContainer = _this.view.getLayer(constant_1.LAYER.BG).addGroup(); _this.axisContainer = _this.view.getLayer(constant_1.LAYER.BG).addGroup(); return _this; } Object.defineProperty(Axis.prototype, "name", { get: function () { return 'axis'; }, enumerable: false, configurable: true }); Axis.prototype.init = function () { }; Axis.prototype.render = function () { this.update(); }; /** * 更新组件布局,位置大小 */ Axis.prototype.layout = function () { var _this = this; var coordinate = this.view.getCoordinate(); util_1.each(this.getComponents(), function (co) { var component = co.component, direction = co.direction, type = co.type, extra = co.extra; var dim = extra.dim, scale = extra.scale, alignTick = extra.alignTick; var updated; if (type === constant_1.COMPONENT_TYPE.AXIS) { if (coordinate.isPolar) { if (dim === 'x') { updated = coordinate.isTransposed ? axis_1.getAxisRegion(coordinate, direction) : axis_1.getCircleAxisCenterRadius(coordinate); } else if (dim === 'y') { updated = coordinate.isTransposed ? axis_1.getCircleAxisCenterRadius(coordinate) : axis_1.getAxisRegion(coordinate, direction); } } else { updated = axis_1.getAxisRegion(coordinate, direction); } } else if (type === constant_1.COMPONENT_TYPE.GRID) { if (coordinate.isPolar) { var items = void 0; if (coordinate.isTransposed) { items = dim === 'x' ? grid_1.getCircleGridItems(coordinate, _this.view.getYScales()[0], scale, alignTick, dim) : grid_1.getLineGridItems(coordinate, scale, dim, alignTick); } else { items = dim === 'x' ? grid_1.getLineGridItems(coordinate, scale, dim, alignTick) : grid_1.getCircleGridItems(coordinate, _this.view.getXScale(), scale, alignTick, dim); } updated = { items: items, // coordinate 更新之后,center 也变化了 center: _this.view.getCoordinate().getCenter(), }; } else { updated = { items: grid_1.getLineGridItems(coordinate, scale, dim, alignTick) }; } } component.update(updated); }); }; /** * 更新 axis 组件 */ Axis.prototype.update = function () { this.option = this.view.getOptions().axes; var updatedCache = new Map(); this.updateXAxes(updatedCache); this.updateYAxes(updatedCache); // 处理完成之后,销毁删除的 // 不在处理中的 var newCache = new Map(); this.cache.forEach(function (co, key) { if (updatedCache.has(key)) { newCache.set(key, co); } else { // 不存在,则是所有需要被销毁的组件 co.component.destroy(); } }); // 更新缓存 this.cache = newCache; }; Axis.prototype.clear = function () { _super.prototype.clear.call(this); this.cache.clear(); this.gridContainer.clear(); this.axisContainer.clear(); }; Axis.prototype.destroy = function () { _super.prototype.destroy.call(this); this.gridContainer.remove(true); this.axisContainer.remove(true); }; /** * @override */ Axis.prototype.getComponents = function () { var co = []; this.cache.forEach(function (value) { co.push(value); }); return co; }; /** * 更新 x axis * @param updatedCache */ Axis.prototype.updateXAxes = function (updatedCache) { // x axis var scale = this.view.getXScale(); if (!scale || scale.isIdentity) { return; } var xAxisOption = axis_2.getAxisOption(this.option, scale.field); if (xAxisOption === false) { return; } var direction = axis_1.getAxisDirection(xAxisOption, constant_1.DIRECTION.BOTTOM); var layer = constant_1.LAYER.BG; var dim = 'x'; var coordinate = this.view.getCoordinate(); var axisId = this.getId('axis', scale.field); var gridId = this.getId('grid', scale.field); if (coordinate.isRect) { // 1. do axis update var axis = this.cache.get(axisId); // 存在则更新 if (axis) { var cfg = this.getLineAxisCfg(scale, xAxisOption, direction); helper_1.omit(cfg, OMIT_CFG); axis.component.update(cfg); updatedCache.set(axisId, axis); } else { // 不存在,则创建 axis = this.createLineAxis(scale, xAxisOption, layer, direction, dim); this.cache.set(axisId, axis); updatedCache.set(axisId, axis); } // 2. do grid update var grid = this.cache.get(gridId); // 存在则更新 if (grid) { var cfg = this.getLineGridCfg(scale, xAxisOption, direction, dim); helper_1.omit(cfg, OMIT_CFG); grid.component.update(cfg); updatedCache.set(gridId, grid); } else { // 不存在则创建 grid = this.createLineGrid(scale, xAxisOption, layer, direction, dim); if (grid) { this.cache.set(gridId, grid); updatedCache.set(gridId, grid); } } } else if (coordinate.isPolar) { // 1. do axis update var axis = this.cache.get(axisId); // 存在则更新 if (axis) { var cfg = coordinate.isTransposed ? this.getLineAxisCfg(scale, xAxisOption, constant_1.DIRECTION.RADIUS) : this.getCircleAxisCfg(scale, xAxisOption, direction); helper_1.omit(cfg, OMIT_CFG); axis.component.update(cfg); updatedCache.set(axisId, axis); } else { // 不存在,则创建 if (coordinate.isTransposed) { if (util_1.isUndefined(xAxisOption)) { // 默认不渲染转置极坐标下的坐标轴 return; } else { // 如果用户打开了隐藏的坐标轴 chart.axis(true)/chart.axis('x', true) // 那么对于转置了的极坐标,半径轴显示的是 x 轴对应的数据 axis = this.createLineAxis(scale, xAxisOption, layer, constant_1.DIRECTION.RADIUS, dim); } } else { axis = this.createCircleAxis(scale, xAxisOption, layer, direction, dim); } this.cache.set(axisId, axis); updatedCache.set(axisId, axis); } // 2. do grid update var grid = this.cache.get(gridId); // 存在则更新 if (grid) { var cfg = coordinate.isTransposed ? this.getCircleGridCfg(scale, xAxisOption, constant_1.DIRECTION.RADIUS, dim) : this.getLineGridCfg(scale, xAxisOption, constant_1.DIRECTION.CIRCLE, dim); helper_1.omit(cfg, OMIT_CFG); grid.component.update(cfg); updatedCache.set(gridId, grid); } else { // 不存在则创建 if (coordinate.isTransposed) { if (util_1.isUndefined(xAxisOption)) { return; } else { grid = this.createCircleGrid(scale, xAxisOption, layer, constant_1.DIRECTION.RADIUS, dim); } } else { // grid,极坐标下的 x 轴网格线沿着半径方向绘制 grid = this.createLineGrid(scale, xAxisOption, layer, constant_1.DIRECTION.CIRCLE, dim); } if (grid) { this.cache.set(gridId, grid); updatedCache.set(gridId, grid); } } } else { // helix and other, do not draw axis } }; Axis.prototype.updateYAxes = function (updatedCache) { var _this = this; // y axes var yScales = this.view.getYScales(); util_1.each(yScales, function (scale, idx) { // @ts-ignore if (!scale || scale.isIdentity) { return; } var field = scale.field; var yAxisOption = axis_2.getAxisOption(_this.option, field); if (yAxisOption !== false) { var layer = constant_1.LAYER.BG; var dim = 'y'; var axisId = _this.getId('axis', field); var gridId = _this.getId('grid', field); var coordinate = _this.view.getCoordinate(); if (coordinate.isRect) { var direction = axis_1.getAxisDirection(yAxisOption, idx === 0 ? constant_1.DIRECTION.LEFT : constant_1.DIRECTION.RIGHT); // 1. do axis update var axis = _this.cache.get(axisId); // 存在则更新 if (axis) { var cfg = _this.getLineAxisCfg(scale, yAxisOption, direction); helper_1.omit(cfg, OMIT_CFG); axis.component.update(cfg); updatedCache.set(axisId, axis); } else { // 不存在,则创建 axis = _this.createLineAxis(scale, yAxisOption, layer, direction, dim); _this.cache.set(axisId, axis); updatedCache.set(axisId, axis); } // 2. do grid update var grid = _this.cache.get(gridId); // 存在则更新 if (grid) { var cfg = _this.getLineGridCfg(scale, yAxisOption, direction, dim); helper_1.omit(cfg, OMIT_CFG); grid.component.update(cfg); updatedCache.set(gridId, grid); } else { // 不存在则创建 grid = _this.createLineGrid(scale, yAxisOption, layer, direction, dim); if (grid) { _this.cache.set(gridId, grid); updatedCache.set(gridId, grid); } } } else if (coordinate.isPolar) { // 1. do axis update var axis = _this.cache.get(axisId); // 存在则更新 if (axis) { var cfg = coordinate.isTransposed ? _this.getCircleAxisCfg(scale, yAxisOption, constant_1.DIRECTION.CIRCLE) : _this.getLineAxisCfg(scale, yAxisOption, constant_1.DIRECTION.RADIUS); // @ts-ignore helper_1.omit(cfg, OMIT_CFG); axis.component.update(cfg); updatedCache.set(axisId, axis); } else { // 不存在,则创建 if (coordinate.isTransposed) { if (util_1.isUndefined(yAxisOption)) { return; } else { axis = _this.createCircleAxis(scale, yAxisOption, layer, constant_1.DIRECTION.CIRCLE, dim); } } else { axis = _this.createLineAxis(scale, yAxisOption, layer, constant_1.DIRECTION.RADIUS, dim); } _this.cache.set(axisId, axis); updatedCache.set(axisId, axis); } // 2. do grid update var grid = _this.cache.get(gridId); // 存在则更新 if (grid) { var cfg = coordinate.isTransposed ? _this.getLineGridCfg(scale, yAxisOption, constant_1.DIRECTION.CIRCLE, dim) : _this.getCircleGridCfg(scale, yAxisOption, constant_1.DIRECTION.RADIUS, dim); helper_1.omit(cfg, OMIT_CFG); grid.component.update(cfg); updatedCache.set(gridId, grid); } else { // 不存在则创建 if (coordinate.isTransposed) { if (util_1.isUndefined(yAxisOption)) { return; } else { grid = _this.createLineGrid(scale, yAxisOption, layer, constant_1.DIRECTION.CIRCLE, dim); } } else { grid = _this.createCircleGrid(scale, yAxisOption, layer, constant_1.DIRECTION.RADIUS, dim); } if (grid) { _this.cache.set(gridId, grid); updatedCache.set(gridId, grid); } } } else { // helix and other, do not draw axis } } }); }; /** * 创建 line axis * @param scale * @param option * @param layer * @param direction * @param dim */ Axis.prototype.createLineAxis = function (scale, option, layer, direction, dim) { // axis var axis = { component: new dependents_1.LineAxis(this.getLineAxisCfg(scale, option, direction)), layer: layer, direction: direction === constant_1.DIRECTION.RADIUS ? constant_1.DIRECTION.NONE : direction, type: constant_1.COMPONENT_TYPE.AXIS, extra: { dim: dim, scale: scale }, }; axis.component.set('field', scale.field); axis.component.init(); return axis; }; Axis.prototype.createLineGrid = function (scale, option, layer, direction, dim) { var cfg = this.getLineGridCfg(scale, option, direction, dim); if (cfg) { var grid = { component: new dependents_1.LineGrid(cfg), layer: layer, direction: constant_1.DIRECTION.NONE, type: constant_1.COMPONENT_TYPE.GRID, extra: { dim: dim, scale: scale, alignTick: util_1.get(cfg, 'alignTick', true), }, }; grid.component.init(); return grid; } }; Axis.prototype.createCircleAxis = function (scale, option, layer, direction, dim) { var axis = { component: new dependents_1.CircleAxis(this.getCircleAxisCfg(scale, option, direction)), layer: layer, direction: direction, type: constant_1.COMPONENT_TYPE.AXIS, extra: { dim: dim, scale: scale }, }; axis.component.set('field', scale.field); axis.component.init(); return axis; }; Axis.prototype.createCircleGrid = function (scale, option, layer, direction, dim) { var cfg = this.getCircleGridCfg(scale, option, direction, dim); if (cfg) { var grid = { component: new dependents_1.CircleGrid(cfg), layer: layer, direction: constant_1.DIRECTION.NONE, type: constant_1.COMPONENT_TYPE.GRID, extra: { dim: dim, scale: scale, alignTick: util_1.get(cfg, 'alignTick', true), }, }; grid.component.init(); return grid; } }; /** * generate line axis cfg * @param scale * @param axisOption * @param direction * @return line axis cfg */ Axis.prototype.getLineAxisCfg = function (scale, axisOption, direction) { var container = this.axisContainer; var coordinate = this.view.getCoordinate(); var region = axis_1.getAxisRegion(coordinate, direction); var titleText = axis_1.getAxisTitleText(scale, axisOption); var axisThemeCfg = axis_1.getAxisThemeCfg(this.view.getTheme(), direction); // the cfg order should be ensure var optionWithTitle = util_1.get(axisOption, ['title']) ? util_1.deepMix({ title: { style: { text: titleText } } }, axisOption) : axisOption; var cfg = util_1.deepMix(tslib_1.__assign(tslib_1.__assign({ container: container }, region), { ticks: scale.getTicks().map(function (tick) { return ({ id: "" + tick.tickValue, name: tick.text, value: tick.value }); }), verticalFactor: coordinate.isPolar ? axis_1.getAxisFactorByRegion(region, coordinate.getCenter()) * -1 : axis_1.getAxisFactorByRegion(region, coordinate.getCenter()) }), axisThemeCfg, optionWithTitle); var _a = this.getAnimateCfg(cfg), animate = _a.animate, animateOption = _a.animateOption; cfg.animateOption = animateOption; cfg.animate = animate; // 计算 verticalLimitLength var isAxisVertical = axis_1.isVertical(region); // TODO: 1 / 3 等默认值需要有一个全局的配置的地方 var verticalLimitLength = util_1.get(cfg, 'verticalLimitLength', isAxisVertical ? 1 / 3 : 1 / 2); if (verticalLimitLength <= 1) { // 配置的相对值,相对于画布 var canvasWidth = this.view.getCanvas().get('width'); var canvasHeight = this.view.getCanvas().get('height'); cfg.verticalLimitLength = verticalLimitLength * (isAxisVertical ? canvasWidth : canvasHeight); } return cfg; }; /** * generate line grid cfg * @param scale * @param axisOption * @param direction * @param dim * @return line grid cfg */ Axis.prototype.getLineGridCfg = function (scale, axisOption, direction, dim) { if (!grid_1.showGrid(axis_1.getAxisThemeCfg(this.view.getTheme(), direction), axisOption)) { return undefined; } var gridThemeCfg = grid_1.getGridThemeCfg(this.view.getTheme(), direction); // the cfg order should be ensure // grid 动画以 axis 为准 var gridCfg = util_1.deepMix({ container: this.gridContainer, }, gridThemeCfg, util_1.get(axisOption, 'grid'), this.getAnimateCfg(axisOption)); gridCfg.items = grid_1.getLineGridItems(this.view.getCoordinate(), scale, dim, util_1.get(gridCfg, 'alignTick', true)); return gridCfg; }; /** * generate circle axis cfg * @param scale * @param axisOption * @param direction * @return circle axis cfg */ Axis.prototype.getCircleAxisCfg = function (scale, axisOption, direction) { var container = this.axisContainer; var coordinate = this.view.getCoordinate(); var ticks = scale.getTicks().map(function (tick) { return ({ id: "" + tick.tickValue, name: tick.text, value: tick.value }); }); if (!scale.isCategory && Math.abs(coordinate.endAngle - coordinate.startAngle) === Math.PI * 2) { // x 轴对应的值如果是非 cat 类型,在整圆的情况下坐标轴第一个和最后一个文本会重叠,默认只展示第一个文本 ticks.pop(); } var titleText = axis_1.getAxisTitleText(scale, axisOption); var axisThemeCfg = axis_1.getAxisThemeCfg(this.view.getTheme(), constant_1.DIRECTION.CIRCLE); // the cfg order should be ensure var optionWithTitle = util_1.get(axisOption, ['title']) ? util_1.deepMix({ title: { style: { text: titleText } } }, axisOption) : axisOption; var cfg = util_1.deepMix(tslib_1.__assign(tslib_1.__assign({ container: container }, axis_1.getCircleAxisCenterRadius(this.view.getCoordinate())), { ticks: ticks, verticalFactor: 1 }), axisThemeCfg, optionWithTitle); var _a = this.getAnimateCfg(cfg), animate = _a.animate, animateOption = _a.animateOption; cfg.animate = animate; cfg.animateOption = animateOption; return cfg; }; /** * generate circle grid cfg * @param scale * @param axisOption * @param direction * @return circle grid cfg */ Axis.prototype.getCircleGridCfg = function (scale, axisOption, direction, dim) { if (!grid_1.showGrid(axis_1.getAxisThemeCfg(this.view.getTheme(), direction), axisOption)) { return undefined; } // the cfg order should be ensure // grid 动画以 axis 为准 var gridThemeCfg = grid_1.getGridThemeCfg(this.view.getTheme(), constant_1.DIRECTION.RADIUS); var gridCfg = util_1.deepMix({ container: this.gridContainer, center: this.view.getCoordinate().getCenter(), }, gridThemeCfg, util_1.get(axisOption, 'grid'), this.getAnimateCfg(axisOption)); var alignTick = util_1.get(gridCfg, 'alignTick', true); var verticalScale = dim === 'x' ? this.view.getYScales()[0] : this.view.getXScale(); gridCfg.items = grid_1.getCircleGridItems(this.view.getCoordinate(), verticalScale, scale, alignTick, dim); // the cfg order should be ensure // grid 动画以 axis 为准 return gridCfg; }; Axis.prototype.getId = function (name, key) { var coordinate = this.view.getCoordinate(); // 坐标系类型也作为组件的 key return name + "-" + key + "-" + coordinate.type; }; Axis.prototype.getAnimateCfg = function (cfg) { return { animate: this.view.getOptions().animate && util_1.get(cfg, 'animate'), animateOption: cfg && cfg.animateOption ? util_1.deepMix({}, AXIS_DEFAULT_ANIMATE_CFG, cfg.animateOption) : AXIS_DEFAULT_ANIMATE_CFG, }; }; return Axis; }(base_1.Controller)); exports.default = Axis; },{"../../animate/":217,"../../constant":237,"../../dependents":239,"../../util/axis":369,"../../util/grid":376,"../../util/helper":377,"./base":222,"@antv/util":803,"tslib":385}],222:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Controller = void 0; var util_1 = require("@antv/util"); /** * Component Controller 规范需要定义的基类 * 1. 规范的 option 输入 * 2. 统一的信息获取 API * 3. 明确定义的组件事件(名称、数据) */ var Controller = /** @class */ (function () { function Controller(view) { /** 是否可见 */ this.visible = true; /** 所有的 component */ this.components = []; this.view = view; } /** * clear */ Controller.prototype.clear = function () { // destroy all components util_1.each(this.components, function (co) { co.component.destroy(); }); // clear all component instance this.components = []; }; /** * destroy the component */ Controller.prototype.destroy = function () { this.clear(); }; /** * get all components * @returns components array */ Controller.prototype.getComponents = function () { return this.components; }; /** * change visibility of component * @param visible */ Controller.prototype.changeVisible = function (visible) { if (this.visible === visible) { return; } this.components.forEach(function (co) { if (visible) { co.component.show(); } else { co.component.hide(); } }); this.visible = visible; }; return Controller; }()); exports.Controller = Controller; },{"@antv/util":803}],223:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../dependents"); /** * coordinate controller,职责: * 1. 创建实例 * 2. 暂存配置 */ var CoordinateController = /** @class */ (function () { function CoordinateController(option) { // 设置默认值,并存储配置 this.option = this.wrapperOption(option); } /** * 更新配置 * @param option */ CoordinateController.prototype.update = function (option) { this.option = this.wrapperOption(option); return this; }; /** * 是否存在某一个 action * @param actionName */ CoordinateController.prototype.hasAction = function (actionName) { var actions = this.option.actions; return util_1.some(actions, function (action) { return action[0] === actionName; }); }; /** * 创建坐标系对象 * @param start 起始位置 * @param end 结束位置 * @return 坐标系实例 */ CoordinateController.prototype.create = function (start, end) { var _a = this.option, type = _a.type, cfg = _a.cfg; var isTheta = type === 'theta'; // 1. 起始位置 var props = tslib_1.__assign({ start: start, end: end }, cfg); // 2. 创建实例 var C = dependents_1.getCoordinate(isTheta ? 'polar' : type); this.coordinate = new C(props); // @ts-ignore FIXME coordinate 包问题导致 type 不正确 this.coordinate.type = type; // 3. 添加默认 action if (isTheta) { // 不存在 transpose,为其自动设置一个 action if (!this.hasAction('transpose')) { this.transpose(); } } // 4. 执行 action this.execActions(); return this.coordinate; }; /** * 更新坐标系对象 * @param start 起始位置 * @param end 结束位置 * @return 坐标系实例 */ CoordinateController.prototype.adjust = function (start, end) { this.coordinate.update({ start: start, end: end, }); // 更新坐标系大小的时候,需要: // 1. 重置 matrix // 2. 重新执行作用于 matrix 的 action this.coordinate.resetMatrix(); this.execActions(['scale', 'rotate', 'translate']); return this.coordinate; }; /** * 旋转弧度 * @param angle */ CoordinateController.prototype.rotate = function (angle) { this.option.actions.push(['rotate', angle]); return this; }; /** * 镜像 * @param dim */ CoordinateController.prototype.reflect = function (dim) { this.option.actions.push(['reflect', dim]); return this; }; /** * scale * @param sx * @param sy */ CoordinateController.prototype.scale = function (sx, sy) { this.option.actions.push(['scale', sx, sy]); return this; }; /** * 对角变换 */ CoordinateController.prototype.transpose = function () { this.option.actions.push(['transpose']); return this; }; /** * 获取配置 */ CoordinateController.prototype.getOption = function () { return this.option; }; /** * 获得 coordinate 实例 */ CoordinateController.prototype.getCoordinate = function () { return this.coordinate; }; /** * 包装配置的默认值 * @param option */ CoordinateController.prototype.wrapperOption = function (option) { return tslib_1.__assign({ type: 'rect', actions: [], cfg: {} }, option); }; /** * coordinate 实例执行 actions * @params includeActions 如果没有指定,则执行全部,否则,执行指定的 action */ CoordinateController.prototype.execActions = function (includeActions) { var _this = this; var actions = this.option.actions; util_1.each(actions, function (action) { var _a; var actionName = action[0], args = action.slice(1); var shouldExec = util_1.isNil(includeActions) ? true : includeActions.includes(actionName); if (shouldExec) { (_a = _this.coordinate)[actionName].apply(_a, args); } }); }; return CoordinateController; }()); exports.default = CoordinateController; },{"../../dependents":239,"@antv/util":803,"tslib":385}],224:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); var PRESS_DELAY = 250; // 计算滑动的方向 var calcDirection = function (start, end) { var xDistance = end.x - start.x; var yDistance = end.y - start.y; // x 的距离大于y 说明是横向,否则就是纵向 if (Math.abs(xDistance) > Math.abs(yDistance)) { return xDistance > 0 ? 'right' : 'left'; } return yDistance > 0 ? 'down' : 'up'; }; // 计算2点之间的距离 var calcDistance = function (point1, point2) { var xDistance = Math.abs(point2.x - point1.x); var yDistance = Math.abs(point2.y - point1.y); return Math.sqrt(xDistance * xDistance + yDistance * yDistance); }; var getCenter = function (point1, point2) { var x = (point1.x + point2.x) / 2; var y = (point1.y + point2.y) / 2; return { x: x, y: y }; }; var convertPoints = function (touches, canvas) { if (!touches) { return; } var points = []; var len = touches.length; for (var i = 0; i < len; i++) { var touch = touches[i]; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置 var clientX = touch.clientX, clientY = touch.clientY; var point = canvas.getPointByClient(clientX, clientY); points.push(point); } return points; }; var GestureController = /** @class */ (function (_super) { tslib_1.__extends(GestureController, _super); function GestureController(view) { var _this = _super.call(this, view) || this; _this.processEvent = {}; _this.touchStart = function (ev) { var points = convertPoints(ev.originalEvent.touches, _this.canvas); if (!points) { return; } ev.points = points; // 防止上次的内容没有清理掉,重新reset下 _this.reset(); // 记录touch start 的时间 _this.startTime = Date.now(); // 记录touch start 的点 _this.startPoints = points; if (points.length > 1) { _this.startDistance = calcDistance(points[0], points[1]); _this.center = getCenter(points[0], points[1]); } else { // 如果touchstart后停顿250ms, 则也触发press事件 _this.pressTimeout = setTimeout(function () { // 这里固定触发press事件 var eventType = 'press'; ev.direction = 'none'; _this.emitStart(eventType, ev); _this.emitEvent(eventType, ev); _this.eventType = eventType; }, PRESS_DELAY); } }; _this.touchMove = function (ev) { var points = convertPoints(ev.originalEvent.touches, _this.canvas); if (!points) { return; } _this.clearPressTimeout(); ev.points = points; var startPoints = _this.startPoints; if (!startPoints) { return; } // 多指触控 if (points.length > 1) { // touchstart的距离 var startDistance = _this.startDistance; var currentDistance = calcDistance(points[0], points[1]); ev.zoom = currentDistance / startDistance; ev.center = _this.center; // 触发缩放事件 _this.emitStart('pinch', ev); _this.emitEvent('pinch', ev); } else { var deltaX = points[0].x - startPoints[0].x; var deltaY = points[0].y - startPoints[0].y; var direction = _this.direction || calcDirection(startPoints[0], points[0]); _this.direction = direction; // 获取press或者pan的事件类型 // press 按住滑动, pan表示平移 // 如果start后立刻move,则触发pan, 如果有停顿,则触发press var eventType = _this.getEventType(points); ev.direction = direction; ev.deltaX = deltaX; ev.deltaY = deltaY; _this.emitStart(eventType, ev); _this.emitEvent(eventType, ev); // 记录最后2次move的时间和坐标,为了给swipe事件用 var prevMoveTime = _this.lastMoveTime; var now = Date.now(); // 最后2次的时间间隔一定要大于0,否则swipe没发计算 if (now - prevMoveTime > 0) { _this.prevMoveTime = prevMoveTime; _this.prevMovePoints = _this.lastMovePoints; _this.lastMoveTime = now; _this.lastMovePoints = points; } } }; _this.touchEnd = function (ev) { _this.emitEnd(ev); // swipe事件处理, 在touchend之后触发 var lastMoveTime = _this.lastMoveTime; var now = Date.now(); // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程 // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内 if (now - lastMoveTime < 100) { var prevMoveTime = _this.prevMoveTime || _this.startTime; var intervalTime = lastMoveTime - prevMoveTime; // 时间间隔一定要大于0, 否则计算没意义 if (intervalTime > 0) { var prevMovePoints = _this.prevMovePoints || _this.startPoints; var lastMovePoints = _this.lastMovePoints; // move速率 var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime; // 0.3 是参考hammerjs的设置 if (velocity > 0.3) { ev.velocity = velocity; ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]); _this.emitEvent('swipe', ev); } } } _this.reset(); var touches = ev.touches; // 当多指只释放了1指时也会触发end, 这时重新触发一次start if (touches && touches.length > 0) { _this.touchStart(ev); } }; _this.canvas = view.getCanvas(); _this.delegateEvent(); // 用来记录当前触发的事件 _this.processEvent = {}; return _this; } Object.defineProperty(GestureController.prototype, "name", { get: function () { return 'gesture'; }, enumerable: false, configurable: true }); GestureController.prototype.init = function () { }; GestureController.prototype.render = function () { }; GestureController.prototype.layout = function () { }; GestureController.prototype.update = function () { }; GestureController.prototype.destroy = function () { this.reset(); this.offEvent(); this.processEvent = null; }; GestureController.prototype.delegateEvent = function () { // 代理这几个事件 this.canvas.on('touchstart', this.touchStart); this.canvas.on('touchmove', this.touchMove); this.canvas.on('touchend', this.touchEnd); }; GestureController.prototype.offEvent = function () { this.canvas.off('touchstart', this.touchStart); this.canvas.off('touchmove', this.touchMove); this.canvas.off('touchend', this.touchEnd); }; GestureController.prototype.emitEvent = function (type, ev) { var view = this.view; view.emit(type, ev); }; // 触发start事件 GestureController.prototype.emitStart = function (type, ev) { if (this.isProcess(type)) { return; } this.enable(type); this.emitEvent(type + "start", ev); }; // 触发end事件 GestureController.prototype.emitEnd = function (ev) { var _this = this; var processEvent = this.processEvent; Object.keys(processEvent).forEach(function (type) { _this.emitEvent(type + "end", ev); delete processEvent[type]; }); }; GestureController.prototype.enable = function (eventType) { this.processEvent[eventType] = true; }; // 是否进行中的事件 GestureController.prototype.isProcess = function (eventType) { return this.processEvent[eventType]; }; GestureController.prototype.reset = function () { this.clearPressTimeout(); this.startTime = 0; this.startPoints = null; this.startDistance = 0; this.direction = null; this.eventType = null; this.prevMoveTime = 0; this.prevMovePoints = null; this.lastMoveTime = 0; this.lastMovePoints = null; }; GestureController.prototype.clearPressTimeout = function () { if (this.pressTimeout) { clearTimeout(this.pressTimeout); this.pressTimeout = 0; } }; GestureController.prototype.getEventType = function (points) { var _a = this, eventType = _a.eventType, view = _a.view, startTime = _a.startTime, startPoints = _a.startPoints; if (eventType) { return eventType; } var type; var panEventListeners = view.getEvents().pan; // 如果 view 上没有 pan 事件的监听,默认都是 press if (!panEventListeners || !panEventListeners.length) { type = 'press'; } else { // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10 var now = Date.now(); if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) { type = 'press'; } else { type = 'pan'; } } this.eventType = type; return type; }; return GestureController; }(base_1.Controller)); exports.default = GestureController; },{"./base":222,"tslib":385}],225:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getComponentController = exports.getComponentControllerNames = exports.unregisterComponentController = exports.registerComponentController = void 0; var LOAD_COMPONENT_CONTROLLERS = {}; /** * 全局注册组件。 * @param name 组件名称 * @param plugin 注册的组件类 * @returns void */ function registerComponentController(name, plugin) { LOAD_COMPONENT_CONTROLLERS[name] = plugin; } exports.registerComponentController = registerComponentController; /** * 删除全局组件。 * @param name 组件名 * @returns void */ function unregisterComponentController(name) { delete LOAD_COMPONENT_CONTROLLERS[name]; } exports.unregisterComponentController = unregisterComponentController; /** * 获取以注册的组件名。 * @returns string[] 返回已注册的组件名称 */ function getComponentControllerNames() { return Object.keys(LOAD_COMPONENT_CONTROLLERS); } exports.getComponentControllerNames = getComponentControllerNames; /** * 根据组件名获取组件类。 * @param name 组件名 * @returns 返回组件类 */ function getComponentController(name) { return LOAD_COMPONENT_CONTROLLERS[name]; } exports.getComponentController = getComponentController; },{}],226:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../../constant"); var dependents_1 = require("../../dependents"); var animate_1 = require("../../animate"); var bbox_1 = require("../../util/bbox"); var direction_1 = require("../../util/direction"); var helper_1 = require("../../util/helper"); var legend_1 = require("../../util/legend"); var scale_1 = require("../../util/scale"); var base_1 = require("./base"); /** * 从配置中获取单个字段的 legend 配置 * @param legends * @param field * @returns the option of one legend field */ function getLegendOption(legends, field) { if (util_1.isBoolean(legends)) { return legends === false ? false : {}; } return util_1.get(legends, [field], legends); } function getDirection(legendOption) { return util_1.get(legendOption, 'position', constant_1.DIRECTION.BOTTOM); } /** * @ignore * legend Controller */ var Legend = /** @class */ (function (_super) { tslib_1.__extends(Legend, _super); function Legend(view) { var _this = _super.call(this, view) || this; _this.container = _this.view.getLayer(constant_1.LAYER.FORE).addGroup(); return _this; } Object.defineProperty(Legend.prototype, "name", { get: function () { return 'legend'; }, enumerable: false, configurable: true }); Legend.prototype.init = function () { }; /** * render the legend component by legend options */ Legend.prototype.render = function () { var _this = this; this.option = this.view.getOptions().legends; var doEachLegend = function (geometry, attr, scale) { var legend = _this.createFieldLegend(geometry, attr, scale); if (legend) { legend.component.init(); _this.components.push(legend); } }; // 全局自定义图例 if (util_1.get(this.option, 'custom')) { var component = this.createCustomLegend(undefined, undefined, undefined, this.option); if (component) { component.init(); var layer = constant_1.LAYER.FORE; var direction = getDirection(this.option); this.components.push({ id: 'global-custom', component: component, layer: layer, direction: direction, type: constant_1.COMPONENT_TYPE.LEGEND, extra: undefined, }); } } else { // 遍历处理每一个创建逻辑 this.loopLegends(doEachLegend); } }; /** * layout legend * 计算出 legend 的 direction 位置 x, y */ Legend.prototype.layout = function () { var _this = this; this.layoutBBox = this.view.viewBBox; var margin = util_1.get(this.view.getTheme(), ['components', 'legend', 'margin'], [0, 0, 0, 0]); util_1.each(this.components, function (co) { var component = co.component, direction = co.direction; var layout = legend_1.getLegendLayout(direction); var maxSize = _this.getCategoryLegendSizeCfg(layout); var maxWidth = component.get('maxWidth'); var maxHeight = component.get('maxHeight'); // 先更新 maxSize,更新 layoutBBox,以便计算正确的 x y component.update({ maxWidth: Math.min(maxSize.maxWidth, maxWidth || 0), maxHeight: Math.min(maxSize.maxHeight, maxHeight || 0), }); var bboxObject = component.getLayoutBBox(); // 这里只需要他的 width、height 信息做位置调整 var bbox = new bbox_1.BBox(bboxObject.x, bboxObject.y, bboxObject.width, bboxObject.height); var _a = direction_1.directionToPosition(_this.view.viewBBox, bbox, direction), x1 = _a[0], y1 = _a[1]; var _b = direction_1.directionToPosition(_this.layoutBBox, bbox, direction), x2 = _b[0], y2 = _b[1]; var x = 0; var y = 0; // 因为 legend x y 要和 coordinateBBox 对齐,所以要做一个简单的判断 if (direction.startsWith('top') || direction.startsWith('bottom')) { x = x1; y = y2; } else { x = x2; y = y1; } // 加上 margin if (direction.indexOf('left') >= 0) { x += margin[3]; } if (direction.indexOf('right') >= 0) { x -= margin[1]; } if (direction.indexOf('top') >= 0) { y += margin[0]; } if (direction.indexOf('bottom') >= 0) { y -= margin[2]; } // 更新位置 component.update({ x: x, y: y, }); _this.layoutBBox = _this.layoutBBox.cut(bbox, direction); }); }; /** * legend 的更新逻辑 */ Legend.prototype.update = function () { var _this = this; this.option = this.view.getOptions().legends; // 已经处理过的 legend var updated = {}; var eachLegend = function (geometry, attr, scale) { var id = _this.getId(scale.field); var existCo = _this.getComponentById(id); // 存在则 update if (existCo) { var cfg = void 0; var legendOption = getLegendOption(_this.option, scale.field); // if the legend option is not false, means legend should be created. if (legendOption !== false) { if (util_1.get(legendOption, 'custom')) { cfg = _this.getCategoryCfg(geometry, attr, scale, legendOption, true); } else { if (scale.isLinear) { // linear field, create continuous legend cfg = _this.getContinuousCfg(geometry, attr, scale, legendOption); } else if (scale.isCategory) { // category field, create category legend cfg = _this.getCategoryCfg(geometry, attr, scale, legendOption); } } } // 如果 cfg 为空,则不在 updated 标记,那么会在后面逻辑中删除 if (cfg) { // omit 掉一些属性,比如 container 等 helper_1.omit(cfg, ['container']); existCo.direction = getDirection(legendOption); existCo.component.update(cfg); // 标记为新的 updated[id] = true; } } else { // 不存在则 create var legend = _this.createFieldLegend(geometry, attr, scale); if (legend) { legend.component.init(); _this.components.push(legend); // 标记为新的 updated[id] = true; } } }; // 全局自定义图例 if (util_1.get(this.option, 'custom')) { var id = 'global-custom'; var existCo = this.getComponentById(id); if (existCo) { var customCfg = this.getCategoryCfg(undefined, undefined, undefined, this.option, true); helper_1.omit(customCfg, ['container']); existCo.component.update(customCfg); updated[id] = true; } else { var component = this.createCustomLegend(undefined, undefined, undefined, this.option); if (component) { component.init(); var layer = constant_1.LAYER.FORE; var direction = getDirection(this.option); this.components.push({ id: id, component: component, layer: layer, direction: direction, type: constant_1.COMPONENT_TYPE.LEGEND, extra: undefined, }); // 标记为更新 updated[id] = true; } } } else { // 遍历处理每一个创建逻辑 this.loopLegends(eachLegend); } // 处理完成之后,销毁删除的 // 不在处理中的 var components = []; util_1.each(this.getComponents(), function (co) { if (updated[co.id]) { components.push(co); } else { co.component.destroy(); } }); // 更新当前已有的 components this.components = components; }; Legend.prototype.clear = function () { _super.prototype.clear.call(this); this.container.clear(); }; Legend.prototype.destroy = function () { _super.prototype.destroy.call(this); this.container.remove(true); }; /** * 递归获取所有的 Geometry */ Legend.prototype.getGeometries = function (view) { var _this = this; var geometries = view.geometries; util_1.each(view.views, function (v) { geometries = geometries.concat(_this.getGeometries(v)); }); return geometries; }; /** * 遍历 Geometry,处理 legend 逻辑 * @param doEach 每个 loop 中的处理方法 */ Legend.prototype.loopLegends = function (doEach) { var isRootView = this.view.getRootView() === this.view; // 非根 view,不处理 legend if (!isRootView) { return; } // 递归 view 中所有的 Geometry,进行创建 legend var geometries = this.getGeometries(this.view); var looped = {}; // 防止一个字段创建两个 legend util_1.each(geometries, function (geometry) { var attributes = geometry.getGroupAttributes(); util_1.each(attributes, function (attr) { var scale = attr.getScale(attr.type); // 如果在视觉通道上映射常量值,如 size(2) shape('circle') 不创建 legend if (!scale || scale.type === 'identity' || looped[scale.field]) { return; } doEach(geometry, attr, scale); looped[scale.field] = true; }); }); }; /** * 创建一个 legend * @param geometry * @param attr * @param scale */ Legend.prototype.createFieldLegend = function (geometry, attr, scale) { var component; var legendOption = getLegendOption(this.option, scale.field); var layer = constant_1.LAYER.FORE; var direction = getDirection(legendOption); // if the legend option is not false, means legend should be created. if (legendOption !== false) { if (util_1.get(legendOption, 'custom')) { component = this.createCustomLegend(geometry, attr, scale, legendOption); } else { if (scale.isLinear) { // linear field, create continuous legend component = this.createContinuousLegend(geometry, attr, scale, legendOption); } else if (scale.isCategory) { // category field, create category legend component = this.createCategoryLegend(geometry, attr, scale, legendOption); } } } if (component) { component.set('field', scale.field); return { id: this.getId(scale.field), component: component, layer: layer, direction: direction, type: constant_1.COMPONENT_TYPE.LEGEND, extra: { scale: scale }, }; } }; /** * 自定义图例使用 category 图例去渲染 * @param geometry * @param attr * @param scale * @param legendOption */ Legend.prototype.createCustomLegend = function (geometry, attr, scale, legendOption) { // 直接使用 分类图例渲染 var cfg = this.getCategoryCfg(geometry, attr, scale, legendOption, true); return new dependents_1.CategoryLegend(cfg); }; /** * 创建连续图例 * @param geometry * @param attr * @param scale * @param legendOption */ Legend.prototype.createContinuousLegend = function (geometry, attr, scale, legendOption) { var cfg = this.getContinuousCfg(geometry, attr, scale, legendOption); return new dependents_1.ContinuousLegend(cfg); }; /** * 创建分类图例 * @param geometry * @param attr * @param scale * @param legendOption */ Legend.prototype.createCategoryLegend = function (geometry, attr, scale, legendOption) { var cfg = this.getCategoryCfg(geometry, attr, scale, legendOption); return new dependents_1.CategoryLegend(cfg); }; /** * 获得连续图例的配置 * @param geometry * @param attr * @param scale * @param legendOption */ Legend.prototype.getContinuousCfg = function (geometry, attr, scale, legendOption) { var ticks = scale.getTicks(); var containMin = util_1.find(ticks, function (tick) { return tick.value === 0; }); var containMax = util_1.find(ticks, function (tick) { return tick.value === 1; }); var items = ticks.map(function (tick) { var value = tick.value, tickValue = tick.tickValue; var attrValue = attr.mapping(scale.invert(value)).join(''); return { value: tickValue, attrValue: attrValue, color: attrValue, scaleValue: value, }; }); if (!containMin) { items.push({ value: scale.min, attrValue: attr.mapping(scale.invert(0)).join(''), color: attr.mapping(scale.invert(0)).join(''), scaleValue: 0, }); } if (!containMax) { items.push({ value: scale.max, attrValue: attr.mapping(scale.invert(1)).join(''), color: attr.mapping(scale.invert(1)).join(''), scaleValue: 1, }); } // 排序 items.sort(function (a, b) { return a.value - b.value; }); // 跟 attr 相关的配置 // size color 区别的配置 var attrLegendCfg = { min: util_1.head(items).value, max: util_1.last(items).value, colors: [], rail: { type: attr.type, }, track: {}, }; if (attr.type === 'size') { attrLegendCfg.track = { style: { // size 的选中前景色,对于 color,则直接使用 color 标识 // @ts-ignore fill: attr.type === 'size' ? this.view.getTheme().defaultColor : undefined, }, }; } if (attr.type === 'color') { attrLegendCfg.colors = items.map(function (item) { return item.attrValue; }); } var container = this.container; // if position is not set, use top as default var direction = getDirection(legendOption); var layout = legend_1.getLegendLayout(direction); var title = util_1.get(legendOption, 'title'); if (title) { title = util_1.deepMix({ text: scale_1.getName(scale), }, title); } // 基础配置,从当前数据中读到的配置 attrLegendCfg.container = container; attrLegendCfg.layout = layout; attrLegendCfg.title = title; attrLegendCfg.animateOption = animate_1.DEFAULT_ANIMATE_CFG; // @ts-ignore return this.mergeLegendCfg(attrLegendCfg, legendOption, 'continuous'); }; /** * 获取分类图例的配置项 * @param geometry * @param attr * @param scale * @param custom * @param legendOption */ Legend.prototype.getCategoryCfg = function (geometry, attr, scale, legendOption, custom) { var container = this.container; // if position is not set, use top as default var direction = util_1.get(legendOption, 'position', constant_1.DIRECTION.BOTTOM); // the default marker style var themeMarker = util_1.get(this.view.getTheme(), ['components', 'legend', direction, 'marker']); var userMarker = util_1.get(legendOption, 'marker'); var layout = legend_1.getLegendLayout(direction); var items = custom ? legend_1.getCustomLegendItems(themeMarker, userMarker, legendOption.items) : legend_1.getLegendItems(this.view, geometry, attr, themeMarker, userMarker); var title = util_1.get(legendOption, 'title'); if (title) { title = util_1.deepMix({ text: scale ? scale_1.getName(scale) : '', }, title); } var baseCfg = this.getCategoryLegendSizeCfg(layout); baseCfg.container = container; baseCfg.layout = layout; baseCfg.items = items; baseCfg.title = title; baseCfg.animateOption = animate_1.DEFAULT_ANIMATE_CFG; var categoryCfg = this.mergeLegendCfg(baseCfg, legendOption, direction); if (categoryCfg.reversed) { // 图例项需要逆序 categoryCfg.items.reverse(); } var maxItemWidth = util_1.get(categoryCfg, 'maxItemWidth'); if (maxItemWidth && maxItemWidth <= 1) { // 转换成像素值 categoryCfg.maxItemWidth = this.view.viewBBox.width * maxItemWidth; } return categoryCfg; }; /** * get legend config, use option > suggestion > theme * @param baseCfg * @param legendOption * @param direction */ Legend.prototype.mergeLegendCfg = function (baseCfg, legendOption, direction) { var position = direction.split('-')[0]; var themeObject = util_1.get(this.view.getTheme(), ['components', 'legend', position], {}); return util_1.deepMix({}, themeObject, baseCfg, legendOption); }; /** * 生成 id * @param key */ Legend.prototype.getId = function (key) { return this.name + "-" + key; }; /** * 根据 id 来获取组件 * @param id */ Legend.prototype.getComponentById = function (id) { return util_1.find(this.components, function (co) { return co.id === id; }); }; Legend.prototype.getCategoryLegendSizeCfg = function (layout) { var _a = this.view.viewBBox, vw = _a.width, vh = _a.height; // 目前 legend 的布局是以 viewBBox 为参照 // const { width: cw, height: ch } = this.view.coordinateBBox; return layout === 'vertical' ? { maxWidth: vw * constant_1.COMPONENT_MAX_VIEW_PERCENTAGE, maxHeight: vh, } : { maxWidth: vw, maxHeight: vh * constant_1.COMPONENT_MAX_VIEW_PERCENTAGE, }; }; return Legend; }(base_1.Controller)); exports.default = Legend; },{"../../animate":217,"../../constant":237,"../../dependents":239,"../../util/bbox":370,"../../util/direction":372,"../../util/helper":377,"../../util/legend":378,"../../util/scale":381,"./base":222,"@antv/util":803,"tslib":385}],227:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../../constant"); var dependents_1 = require("../../dependents"); var bbox_1 = require("../../util/bbox"); var direction_1 = require("../../util/direction"); var helper_1 = require("../../util/helper"); var base_1 = require("./base"); /** * @ignore * slider Controller */ var Slider = /** @class */ (function (_super) { tslib_1.__extends(Slider, _super); function Slider(view) { var _this = _super.call(this, view) || this; /** * 滑块滑动的时候出发 * @param v */ _this.onValueChanged = function (v) { var min = v[0], max = v[1]; _this.updateMinMaxText(min, max); _this.view.render(true); }; _this.container = _this.view.getLayer(constant_1.LAYER.FORE).addGroup(); return _this; } Object.defineProperty(Slider.prototype, "name", { get: function () { return 'slider'; }, enumerable: false, configurable: true }); /** * 初始化 */ Slider.prototype.init = function () { }; /** * 渲染 */ Slider.prototype.render = function () { this.option = this.view.getOptions().slider; if (this.option) { if (this.slider) { // exist, update this.slider = this.updateSlider(); } else { // not exist, create this.slider = this.createSlider(); // 监听事件,绑定交互 this.slider.component.on('sliderchange', this.onValueChanged); } // changeData 的时候同样需要更新 // 设置初始的 text var min = this.slider.component.get('start') || 0; var max = this.slider.component.get('end') || 1; this.updateMinMaxText(min, max); } else { if (this.slider) { // exist, destroy this.slider.component.destroy(); this.slider = undefined; } else { // do nothing } } }; /** * 布局 */ Slider.prototype.layout = function () { if (this.slider) { var width = this.view.coordinateBBox.width; // 获取组件的 layout bbox var bboxObject = this.slider.component.getLayoutBBox(); var bbox = new bbox_1.BBox(bboxObject.x, bboxObject.y, Math.min(bboxObject.width, width), bboxObject.height); var _a = direction_1.directionToPosition(this.view.viewBBox, bbox, constant_1.DIRECTION.BOTTOM), x1 = _a[0], y1 = _a[1]; var _b = direction_1.directionToPosition(this.view.coordinateBBox, bbox, constant_1.DIRECTION.BOTTOM), x2 = _b[0], y2 = _b[1]; // 默认放在 bottom this.slider.component.update({ x: x2, y: y1, width: width, }); } }; /** * 更新 */ Slider.prototype.update = function () { // 逻辑和 render 保持一致 this.render(); }; /** * 创建 slider 组件 */ Slider.prototype.createSlider = function () { var cfg = this.getSliderCfg(); // 添加 slider 组件 var component = new dependents_1.Slider(tslib_1.__assign({ container: this.container }, cfg)); component.init(); return { component: component, layer: constant_1.LAYER.FORE, direction: constant_1.DIRECTION.BOTTOM, type: constant_1.COMPONENT_TYPE.OTHER, }; }; /** * 更新配置 */ Slider.prototype.updateSlider = function () { var cfg = this.getSliderCfg(); helper_1.omit(cfg, ['x', 'y', 'width', 'start', 'end', 'minText', 'maxText']); this.slider.component.update(cfg); return this.slider; }; /** * 生成 slider 配置 */ Slider.prototype.getSliderCfg = function () { if (util_1.isObject(this.option)) { // 用户配置的数据,优先级更高 var trendCfg = tslib_1.__assign({ data: this.getData() }, util_1.get(this.option, 'trendCfg', {})); // 初始的位置大小信息 var x = 0; var y = 0; var width = this.view.coordinateBBox.width; // 因为有样式,所以深层覆盖 var cfg = util_1.deepMix({}, { x: x, y: y, width: width }, this.option); // trendCfg 因为有数据数组,所以使用浅替换 return tslib_1.__assign(tslib_1.__assign({}, cfg), { trendCfg: trendCfg }); } return {}; }; /** * 从 view 中获取数据,缩略轴使用全量的数据 */ Slider.prototype.getData = function () { var data = this.view.getOptions().data; var yScale = this.view.getYScales()[0]; var groupScales = this.view.getGroupScales(); if (groupScales.length) { var _a = groupScales[0], field_1 = _a.field, ticks_1 = _a.ticks; return data.reduce(function (pre, cur) { if (cur[field_1] === ticks_1[0]) { pre.push(cur[yScale.field]); } return pre; }, []); } return data.map(function (datum) { return datum[yScale.field] || 0; }); }; Slider.prototype.updateMinMaxText = function (min, max) { var data = this.view.getOptions().data; var xScale = this.view.getXScale(); var dataSize = util_1.size(data); if (!xScale || !dataSize) { return; } var x = xScale.field; // x 轴刻度 var xTicks = data.reduce(function (pre, datum) { if (!pre.includes(datum[x])) pre.push(datum[x]); return pre; }, []); var xTickCount = util_1.size(xTicks); var minIndex = Math.floor(min * (xTickCount - 1)); var maxIndex = Math.floor(max * (xTickCount - 1)); var minText = util_1.get(xTicks, [minIndex]); var maxText = util_1.get(xTicks, [maxIndex]); var formatter = this.getSliderCfg().formatter; if (formatter) { minText = formatter(minText, data[minIndex], minIndex); maxText = formatter(maxText, data[maxIndex], maxIndex); } // 更新文本 this.slider.component.update({ minText: minText, maxText: maxText, start: min, end: max, }); // 增加 x 轴的过滤器 this.view.filter(xScale.field, function (value, datum) { var idx = xTicks.indexOf(value); return idx > -1 ? helper_1.isBetween(idx, minIndex, maxIndex) : true; }); }; /** * 覆写父类方法 */ Slider.prototype.getComponents = function () { return this.slider ? [this.slider] : []; }; return Slider; }(base_1.Controller)); exports.default = Slider; },{"../../constant":237,"../../dependents":239,"../../util/bbox":370,"../../util/direction":372,"../../util/helper":377,"./base":222,"@antv/util":803,"tslib":385}],228:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../dependents"); var coordinate_1 = require("../../util/coordinate"); var graphics_1 = require("../../util/graphics"); var tooltip_1 = require("../../util/tooltip"); var base_1 = require("./base"); // Filter duplicates, use `name`, `color`, `value` and `title` property values as condition function uniq(items) { var uniqItems = []; var _loop_1 = function (index) { var item = items[index]; var result = util_1.find(uniqItems, function (subItem) { return (subItem.color === item.color && subItem.name === item.name && subItem.value === item.value && subItem.title === item.title); }); if (!result) { uniqItems.push(item); } }; for (var index = 0; index < items.length; index++) { _loop_1(index); } return uniqItems; } /** @ignore */ var Tooltip = /** @class */ (function (_super) { tslib_1.__extends(Tooltip, _super); function Tooltip() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.isLocked = false; return _this; } Object.defineProperty(Tooltip.prototype, "name", { get: function () { return 'tooltip'; }, enumerable: false, configurable: true }); Tooltip.prototype.init = function () { }; Tooltip.prototype.isVisible = function () { var option = this.view.getOptions().tooltip; return option !== false; }; Tooltip.prototype.render = function () { }; /** * Shows tooltip * @param point */ Tooltip.prototype.showTooltip = function (point) { this.point = point; if (!this.isVisible()) { // 如果设置 tooltip(false) 则始终不显示 return; } var view = this.view; var items = this.getTooltipItems(point); if (!items.length) { // 无内容则不展示,同时 tooltip 需要隐藏 this.hideTooltip(); return; } var title = this.getTitle(items); var dataPoint = { x: items[0].x, y: items[0].y, }; // 数据点位置 view.emit('tooltip:show', tslib_1.__assign({ items: items, title: title }, point)); var cfg = this.getTooltipCfg(); var follow = cfg.follow, showMarkers = cfg.showMarkers, showCrosshairs = cfg.showCrosshairs, showContent = cfg.showContent, marker = cfg.marker; var lastItems = this.items; var lastTitle = this.title; if (!util_1.isEqual(lastTitle, title) || !util_1.isEqual(lastItems, items)) { // 内容发生变化了更新 tooltip view.emit('tooltip:change', tslib_1.__assign({ items: items, title: title }, point)); if (showContent) { // 展示 tooltip 内容框才渲染 tooltip if (!this.tooltip) { // 延迟生成 this.renderTooltip(); } this.tooltip.update(util_1.mix({}, cfg, { items: items, title: title, }, follow ? point : {})); this.tooltip.show(); } if (showMarkers) { // 展示 tooltipMarkers,tooltipMarkers 跟随数据 this.renderTooltipMarkers(items, marker); } } else { // 内容未发生变化,则更新位置 if (this.tooltip && follow) { this.tooltip.update(point); this.tooltip.show(); // tooltip 有可能被隐藏,需要保证显示状态 } if (this.tooltipMarkersGroup) { this.tooltipMarkersGroup.show(); } } this.items = items; this.title = title; if (showCrosshairs) { // 展示 tooltip 辅助线 var isCrosshairsFollowCursor = util_1.get(cfg, ['crosshairs', 'follow'], false); // 辅助线是否要跟随鼠标 this.renderCrosshairs(isCrosshairsFollowCursor ? point : dataPoint, cfg); } }; Tooltip.prototype.hideTooltip = function () { var follow = this.getTooltipCfg().follow; if (!follow) { this.point = null; return; } // hide the tooltipMarkers var tooltipMarkersGroup = this.tooltipMarkersGroup; if (tooltipMarkersGroup) { tooltipMarkersGroup.hide(); } // hide crosshairs var xCrosshair = this.xCrosshair; var yCrosshair = this.yCrosshair; if (xCrosshair) { xCrosshair.hide(); } if (yCrosshair) { yCrosshair.hide(); } var tooltip = this.tooltip; if (tooltip) { tooltip.hide(); } this.view.emit('tooltip:hide', {}); this.point = null; }; /** * lockTooltip */ Tooltip.prototype.lockTooltip = function () { this.isLocked = true; if (this.tooltip) { // tooltip contianer 可捕获事件 this.tooltip.setCapture(true); } }; /** * unlockTooltip */ Tooltip.prototype.unlockTooltip = function () { this.isLocked = false; var cfg = this.getTooltipCfg(); if (this.tooltip) { // 重置 capture 属性 this.tooltip.setCapture(cfg.capture); } }; /** * isTooltipLocked */ Tooltip.prototype.isTooltipLocked = function () { return this.isLocked; }; Tooltip.prototype.clear = function () { var _a = this, tooltip = _a.tooltip, xCrosshair = _a.xCrosshair, yCrosshair = _a.yCrosshair, tooltipMarkersGroup = _a.tooltipMarkersGroup; if (tooltip) { tooltip.hide(); tooltip.clear(); } if (xCrosshair) { xCrosshair.clear(); } if (yCrosshair) { yCrosshair.clear(); } if (tooltipMarkersGroup) { tooltipMarkersGroup.clear(); } }; Tooltip.prototype.destroy = function () { if (this.tooltip) { this.tooltip.destroy(); } if (this.xCrosshair) { this.xCrosshair.destroy(); } if (this.yCrosshair) { this.yCrosshair.destroy(); } if (this.guideGroup) { this.guideGroup.remove(true); } this.items = null; this.title = null; this.tooltipMarkersGroup = null; this.tooltipCrosshairsGroup = null; this.xCrosshair = null; this.yCrosshair = null; this.tooltip = null; this.guideGroup = null; this.isLocked = false; this.point = null; }; Tooltip.prototype.changeVisible = function (visible) { if (this.visible === visible) { return; } var _a = this, tooltip = _a.tooltip, tooltipMarkersGroup = _a.tooltipMarkersGroup, xCrosshair = _a.xCrosshair, yCrosshair = _a.yCrosshair; if (visible) { if (tooltip) { tooltip.show(); } if (tooltipMarkersGroup) { tooltipMarkersGroup.show(); } if (xCrosshair) { xCrosshair.show(); } if (yCrosshair) { yCrosshair.show(); } } else { if (tooltip) { tooltip.hide(); } if (tooltipMarkersGroup) { tooltipMarkersGroup.hide(); } if (xCrosshair) { xCrosshair.hide(); } if (yCrosshair) { yCrosshair.hide(); } } this.visible = visible; }; Tooltip.prototype.getTooltipItems = function (point) { var items = this.findItemsFromView(this.view, point); if (items.length) { // 三层 items = util_1.flatten(items); for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { var itemArr = items_1[_i]; for (var _a = 0, itemArr_1 = itemArr; _a < itemArr_1.length; _a++) { var item = itemArr_1[_a]; var _b = item.mappingData, x = _b.x, y = _b.y; item.x = util_1.isArray(x) ? x[x.length - 1] : x; item.y = util_1.isArray(y) ? y[y.length - 1] : y; } } var shared = this.getTooltipCfg().shared; // shared: false 代表只显示当前拾取到的 shape 的数据,但是一个 view 会有多个 Geometry,所以有可能会拾取到多个 shape if (shared === false && items.length > 1) { var snapItem = items[0]; var min = Math.abs(point.y - snapItem[0].y); for (var _c = 0, items_2 = items; _c < items_2.length; _c++) { var aItem = items_2[_c]; var yDistance = Math.abs(point.y - aItem[0].y); if (yDistance <= min) { snapItem = aItem; min = yDistance; } } items = [snapItem]; } return uniq(util_1.flatten(items)); } return []; }; Tooltip.prototype.layout = function () { }; Tooltip.prototype.update = function () { if (this.point) { this.showTooltip(this.point); } if (this.tooltip) { // #2279 修复resize之后tooltip越界的问题 // 确保tooltip已经创建的情况下 var canvas = this.view.getCanvas(); // 更新 region this.tooltip.set('region', { start: { x: 0, y: 0 }, end: { x: canvas.get('width'), y: canvas.get('height') }, }); } }; // 获取 tooltip 配置,因为用户可能会通过 view.tooltip() 重新配置 tooltip,所以就不做缓存,每次直接读取 Tooltip.prototype.getTooltipCfg = function () { var view = this.view; var option = view.getOptions().tooltip; var theme = view.getTheme(); var defaultCfg = util_1.get(theme, ['components', 'tooltip'], {}); var enterable = util_1.isUndefined(util_1.get(option, 'enterable')) ? defaultCfg.enterable : util_1.get(option, 'enterable'); return util_1.deepMix({}, defaultCfg, option, { capture: enterable || this.isLocked ? true : false, }); }; Tooltip.prototype.getTitle = function (items) { var title = items[0].title || items[0].name; this.title = title; return title; }; Tooltip.prototype.renderTooltip = function () { var canvas = this.view.getCanvas(); var region = { start: { x: 0, y: 0 }, end: { x: canvas.get('width'), y: canvas.get('height') }, }; var cfg = this.getTooltipCfg(); var tooltip = new dependents_1.HtmlTooltip(tslib_1.__assign(tslib_1.__assign({ parent: canvas.get('el').parentNode, region: region }, cfg), { visible: false, crosshairs: null })); tooltip.init(); this.tooltip = tooltip; }; Tooltip.prototype.renderTooltipMarkers = function (items, marker) { var tooltipMarkersGroup = this.getTooltipMarkersGroup(); for (var _i = 0, items_3 = items; _i < items_3.length; _i++) { var item = items_3[_i]; var x = item.x, y = item.y; var attrs = tslib_1.__assign(tslib_1.__assign({ fill: item.color, symbol: 'circle', shadowColor: item.color }, marker), { x: x, y: y }); tooltipMarkersGroup.addShape('marker', { attrs: attrs, }); } }; Tooltip.prototype.renderCrosshairs = function (point, cfg) { var crosshairsType = util_1.get(cfg, ['crosshairs', 'type'], 'x'); // 默认展示 x 轴上的辅助线 if (crosshairsType === 'x') { if (this.yCrosshair) { this.yCrosshair.hide(); } this.renderXCrosshairs(point, cfg); } else if (crosshairsType === 'y') { if (this.xCrosshair) { this.xCrosshair.hide(); } this.renderYCrosshairs(point, cfg); } else if (crosshairsType === 'xy') { this.renderXCrosshairs(point, cfg); this.renderYCrosshairs(point, cfg); } }; // 渲染 x 轴上的 tooltip 辅助线 Tooltip.prototype.renderXCrosshairs = function (point, tooltipCfg) { var coordinate = this.getViewWithGeometry(this.view).getCoordinate(); if (!coordinate_1.isPointInCoordinate(coordinate, point)) { return; } var start; var end; if (coordinate.isRect) { if (coordinate.isTransposed) { start = { x: coordinate.start.x, y: point.y, }; end = { x: coordinate.end.x, y: point.y, }; } else { start = { x: point.x, y: coordinate.end.y, }; end = { x: point.x, y: coordinate.start.y, }; } } else { // 极坐标下 x 轴上的 crosshairs 表现为半径 var angle = coordinate_1.getAngleByPoint(coordinate, point); var center = coordinate.getCenter(); var radius = coordinate.getRadius(); end = graphics_1.polarToCartesian(center.x, center.y, radius, angle); start = center; } var cfg = util_1.deepMix({ start: start, end: end, container: this.getTooltipCrosshairsGroup(), }, util_1.get(tooltipCfg, 'crosshairs', {}), this.getCrosshairsText('x', point, tooltipCfg)); delete cfg.type; // 与 Crosshairs 组件的 type 冲突故删除 var xCrosshair = this.xCrosshair; if (xCrosshair) { xCrosshair.update(cfg); } else { xCrosshair = new dependents_1.Crosshair.Line(cfg); xCrosshair.init(); } xCrosshair.render(); xCrosshair.show(); this.xCrosshair = xCrosshair; }; // 渲染 y 轴上的辅助线 Tooltip.prototype.renderYCrosshairs = function (point, tooltipCfg) { var coordinate = this.getViewWithGeometry(this.view).getCoordinate(); if (!coordinate_1.isPointInCoordinate(coordinate, point)) { return; } var cfg; var type; if (coordinate.isRect) { var start = void 0; var end = void 0; if (coordinate.isTransposed) { start = { x: point.x, y: coordinate.end.y, }; end = { x: point.x, y: coordinate.start.y, }; } else { start = { x: coordinate.start.x, y: point.y, }; end = { x: coordinate.end.x, y: point.y, }; } cfg = { start: start, end: end, }; type = 'Line'; } else { // 极坐标下 y 轴上的 crosshairs 表现为圆弧 cfg = { center: coordinate.getCenter(), // @ts-ignore radius: coordinate_1.getDistanceToCenter(coordinate, point), startAngle: coordinate.startAngle, endAngle: coordinate.endAngle, }; type = 'Circle'; } cfg = util_1.deepMix({ container: this.getTooltipCrosshairsGroup(), }, cfg, util_1.get(tooltipCfg, 'crosshairs', {}), this.getCrosshairsText('y', point, tooltipCfg)); delete cfg.type; // 与 Crosshairs 组件的 type 冲突故删除 var yCrosshair = this.yCrosshair; if (yCrosshair) { // 如果坐标系发生直角坐标系与极坐标的切换操作 if ((coordinate.isRect && yCrosshair.get('type') === 'circle') || (!coordinate.isRect && yCrosshair.get('type') === 'line')) { yCrosshair = new dependents_1.Crosshair[type](cfg); yCrosshair.init(); } else { yCrosshair.update(cfg); } } else { yCrosshair = new dependents_1.Crosshair[type](cfg); yCrosshair.init(); } yCrosshair.render(); yCrosshair.show(); this.yCrosshair = yCrosshair; }; Tooltip.prototype.getCrosshairsText = function (type, point, tooltipCfg) { var textCfg = util_1.get(tooltipCfg, ['crosshairs', 'text']); var follow = util_1.get(tooltipCfg, ['crosshairs', 'follow']); var items = this.items; if (textCfg) { var view = this.getViewWithGeometry(this.view); // 需要展示文本 var firstItem = items[0]; var xScale = view.getXScale(); var yScale = view.getYScales()[0]; var xValue = void 0; var yValue = void 0; if (follow) { // 如果需要跟随鼠标移动,就需要将当前鼠标坐标点转换为对应的数值 var invertPoint = this.view.getCoordinate().invert(point); xValue = xScale.invert(invertPoint.x); // 转换为原始值 yValue = yScale.invert(invertPoint.y); // 转换为原始值 } else { xValue = firstItem.data[xScale.field]; yValue = firstItem.data[yScale.field]; } var content = type === 'x' ? xValue : yValue; if (util_1.isFunction(textCfg)) { textCfg = textCfg(type, content, items, point); } else { textCfg.content = content; } return { text: textCfg, }; } }; // 获取存储 tooltipMarkers 和 crosshairs 的容器 Tooltip.prototype.getGuideGroup = function () { if (!this.guideGroup) { var foregroundGroup = this.view.foregroundGroup; this.guideGroup = foregroundGroup.addGroup({ name: 'tooltipGuide', capture: false, }); } return this.guideGroup; }; // 获取 tooltipMarkers 存储的容器 Tooltip.prototype.getTooltipMarkersGroup = function () { var tooltipMarkersGroup = this.tooltipMarkersGroup; if (tooltipMarkersGroup && !tooltipMarkersGroup.destroyed) { tooltipMarkersGroup.clear(); tooltipMarkersGroup.show(); } else { tooltipMarkersGroup = this.getGuideGroup().addGroup({ name: 'tooltipMarkersGroup', }); tooltipMarkersGroup.toFront(); this.tooltipMarkersGroup = tooltipMarkersGroup; } return tooltipMarkersGroup; }; // 获取 tooltip crosshairs 存储的容器 Tooltip.prototype.getTooltipCrosshairsGroup = function () { var tooltipCrosshairsGroup = this.tooltipCrosshairsGroup; if (!tooltipCrosshairsGroup) { tooltipCrosshairsGroup = this.getGuideGroup().addGroup({ name: 'tooltipCrosshairsGroup', capture: false, }); tooltipCrosshairsGroup.toBack(); this.tooltipCrosshairsGroup = tooltipCrosshairsGroup; } return tooltipCrosshairsGroup; }; Tooltip.prototype.getTooltipItemsByHitShape = function (geometry, point, title) { var result = []; var container = geometry.container; var shape = container.getShape(point.x, point.y); if (shape && shape.get('visible') && shape.get('origin')) { var mappingData = shape.get('origin').mappingData; var items = tooltip_1.getTooltipItems(mappingData, geometry, title); if (items.length) { result.push(items); } } return result; }; Tooltip.prototype.getTooltipItemsByFindData = function (geometry, point, title) { var result = []; var dataArray = geometry.dataArray; geometry.sort(dataArray); // 先进行排序,便于 tooltip 查找 for (var _i = 0, dataArray_1 = dataArray; _i < dataArray_1.length; _i++) { var data = dataArray_1[_i]; var record = tooltip_1.findDataByPoint(point, data, geometry); if (record) { var elementId = geometry.getElementId(record); var element = geometry.elementsMap[elementId]; if (geometry.type === 'heatmap' || element.visible) { // Heatmap 没有 Element // 如果图形元素隐藏了,怎不再 tooltip 上展示相关数据 var items = tooltip_1.getTooltipItems(record, geometry, title); if (items.length) { result.push(items); } } } } return result; }; Tooltip.prototype.findItemsFromView = function (view, point) { if (view.getOptions().tooltip === false) { // 如果 view 关闭了 tooltip return []; } var result = []; // 先从 view 本身查找 var geometries = view.geometries; var _a = this.getTooltipCfg(), shared = _a.shared, title = _a.title; for (var _i = 0, geometries_1 = geometries; _i < geometries_1.length; _i++) { var geometry = geometries_1[_i]; if (geometry.visible && geometry.tooltipOption !== false) { // geometry 可见同时未关闭 tooltip var geometryType = geometry.type; var tooltipItems = void 0; if (['point', 'edge', 'polygon'].includes(geometryType)) { // 始终通过图形拾取 tooltipItems = this.getTooltipItemsByHitShape(geometry, point, title); } else if (['area', 'line', 'path', 'heatmap'].includes(geometryType)) { // 如果是 'area', 'line', 'path',始终通过数据查找方法查找 tooltip tooltipItems = this.getTooltipItemsByFindData(geometry, point, title); } else { if (shared !== false) { tooltipItems = this.getTooltipItemsByFindData(geometry, point, title); } else { tooltipItems = this.getTooltipItemsByHitShape(geometry, point, title); } } if (tooltipItems.length) { // geometry 有可能会有多个 item,因为用户可以设置 geometry.tooltip('x*y*z') result.push(tooltipItems); } } } // 递归查找,并合并结果 for (var _b = 0, _c = view.views; _b < _c.length; _b++) { var childView = _c[_b]; result = result.concat(this.findItemsFromView(childView, point)); } return result; }; // FIXME: hack 方法 // 因为 tooltip 的交互是挂载在 Chart 上,所以当chart 上没有绘制 Geometry 的时候,就查找不到数据,并且绘图区域同子 View 的区域不同 Tooltip.prototype.getViewWithGeometry = function (view) { var _this = this; if (view.geometries.length) { return view; } return util_1.find(view.views, function (childView) { return _this.getViewWithGeometry(childView); }); }; return Tooltip; }(base_1.Controller)); exports.default = Tooltip; },{"../../dependents":239,"../../util/coordinate":371,"../../util/graphics":375,"../../util/tooltip":383,"./base":222,"@antv/util":803,"tslib":385}],229:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @todo Whether it can(or necessary to) keep consistent with the structure of G.Event or directly use the structure of G.Event * G2 事件的事件包装类,基于 G.Event */ var Event = /** @class */ (function () { function Event(view, gEvent, data) { this.view = view; this.gEvent = gEvent; this.data = data; this.type = gEvent.type; } Object.defineProperty(Event.prototype, "target", { // below props are proxy props of G.event convenient /** the real trigger shape of the event */ get: function () { // @todo G 中事件定义为 object 不正确,这里先 ignore // @ts-ignore return this.gEvent.target; }, enumerable: false, configurable: true }); Object.defineProperty(Event.prototype, "event", { /** 获取对应的 dom 原生时间 */ get: function () { return this.gEvent.originalEvent; }, enumerable: false, configurable: true }); Object.defineProperty(Event.prototype, "x", { /** x 画布坐标 */ get: function () { return this.gEvent.x; }, enumerable: false, configurable: true }); Object.defineProperty(Event.prototype, "y", { /** y 画布坐标 */ get: function () { return this.gEvent.y; }, enumerable: false, configurable: true }); Object.defineProperty(Event.prototype, "clientX", { /** x 窗口坐标 */ get: function () { return this.gEvent.clientX; }, enumerable: false, configurable: true }); Object.defineProperty(Event.prototype, "clientY", { /** y 窗口坐标 */ get: function () { return this.gEvent.clientY; }, enumerable: false, configurable: true }); // end for proxy events /** * event string * @returns string */ Event.prototype.toString = function () { return "[Event (type=" + this.type + ")]"; }; /** * clone a new event with same attributes * @returns [[Event]] */ Event.prototype.clone = function () { return new Event(this.view, this.gEvent, this.data); }; return Event; }()); exports.default = Event; },{}],230:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var chart_1 = require("./chart"); Object.defineProperty(exports, "Chart", { enumerable: true, get: function () { return chart_1.default; } }); var view_1 = require("./view"); Object.defineProperty(exports, "View", { enumerable: true, get: function () { return view_1.default; } }); Object.defineProperty(exports, "registerGeometry", { enumerable: true, get: function () { return view_1.registerGeometry; } }); var event_1 = require("./event"); Object.defineProperty(exports, "Event", { enumerable: true, get: function () { return event_1.default; } }); var controller_1 = require("./controller"); Object.defineProperty(exports, "registerComponentController", { enumerable: true, get: function () { return controller_1.registerComponentController; } }); },{"./chart":219,"./controller":225,"./event":229,"./view":235}],231:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculatePadding = void 0; var util_1 = require("@antv/util"); var constant_1 = require("../../constant"); var bbox_1 = require("../../util/bbox"); var padding_1 = require("../../util/padding"); var padding_cal_1 = require("./padding-cal"); /** * @ignore * 根据 view 中的组件,计算实际的 padding 数值 * @param view */ function calculatePadding(view) { var padding = view.padding; // 如果不是 auto padding,那么直接解析之后返回 if (!padding_1.isAutoPadding(padding)) { return padding_1.parsePadding(padding); } // 是 auto padding,根据组件的情况,来计算 padding var viewBBox = view.viewBBox, autoPadding = view.autoPadding; var paddingCal = new padding_cal_1.PaddingCal(); util_1.each(view.getComponents(), function (co) { var component = co.component, type = co.type; // grid, tooltip 不参入 padding 布局 if (type === constant_1.COMPONENT_TYPE.GRID || type === constant_1.COMPONENT_TYPE.TOOLTIP) { return; } var bboxObject = component.getLayoutBBox(); var componentBBox = new bbox_1.BBox(bboxObject.x, bboxObject.y, bboxObject.width, bboxObject.height); if (type === constant_1.COMPONENT_TYPE.AXIS) { var exceed = componentBBox.exceed(viewBBox); paddingCal.shrink(exceed); } else { // 按照方向计算 padding var direction = co.direction; // const direction = // type === COMPONENT_TYPE.AXIS ? getTranslateDirection(co.direction, view.getCoordinate()) : co.direction; paddingCal.inc(componentBBox, direction); } }); var calculatedPadding = paddingCal.getPadding(); if (autoPadding) { var appendPadding = padding_1.parsePadding(view.appendPadding); // 取上一次以及当前计算结果的最大区间 return [ Math.max(autoPadding[0] - appendPadding[0], calculatedPadding[0]), Math.max(autoPadding[1] - appendPadding[1], calculatedPadding[1]), Math.max(autoPadding[2] - appendPadding[2], calculatedPadding[2]), Math.max(autoPadding[3] - appendPadding[3], calculatedPadding[3]), ]; } return calculatedPadding; } exports.calculatePadding = calculatePadding; },{"../../constant":237,"../../util/bbox":370,"../../util/padding":380,"./padding-cal":233,"@antv/util":803}],232:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var padding_1 = require("../../util/padding"); var auto_1 = require("./auto"); /** * @ignore * G2 默认提供的 layout 函数 * 内置布局函数处理的逻辑: * * 1. 如果 padding = 'auto',那么自动根据组件的 direction 来计算 padding 数组 * 2. 根据 padding 和 direction 去分配对应方向的 padding 数值 * 3. 移动组件位置 * * 对于组件响应式布局,可以尝试使用约束布局的方式去求解位置信息。 * @param view */ function defaultLayout(view) { var axis = view.getController('axis'); var legend = view.getController('legend'); var annotation = view.getController('annotation'); var slider = view.getController('slider'); // 1. 自动加 auto padding -> absolute padding var padding = auto_1.calculatePadding(view); // 2. 计算出新的 coordinateBBox view.coordinateBBox = view.viewBBox.shrink(padding).shrink(padding_1.parsePadding(view.appendPadding)); view.adjustCoordinate(); // 3. 根据最新的 coordinate 重新布局组件 [axis, slider, legend, annotation].forEach(function (controller) { if (controller) { controller.layout(); } }); } exports.default = defaultLayout; },{"../../util/padding":380,"./auto":231}],233:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PaddingCal = void 0; var constant_1 = require("../../constant"); /** @ignore */ var PaddingCal = /** @class */ (function () { /** * 初始的 padding 数据 * @param top * @param right * @param bottom * @param left */ function PaddingCal(top, right, bottom, left) { if (top === void 0) { top = 0; } if (right === void 0) { right = 0; } if (bottom === void 0) { bottom = 0; } if (left === void 0) { left = 0; } this.top = top; this.right = right; this.bottom = bottom; this.left = left; } /** * 四周增加 padding * @param padding */ PaddingCal.prototype.shrink = function (padding) { var top = padding[0], right = padding[1], bottom = padding[2], left = padding[3]; this.top += top; this.right += right; this.bottom += bottom; this.left += left; return this; }; /** * 在某一个方向增加 padding * @param bbox * @param direction */ PaddingCal.prototype.inc = function (bbox, direction) { var width = bbox.width, height = bbox.height; switch (direction) { case constant_1.DIRECTION.TOP: case constant_1.DIRECTION.TOP_LEFT: case constant_1.DIRECTION.TOP_RIGHT: this.top += height; break; case constant_1.DIRECTION.RIGHT: case constant_1.DIRECTION.RIGHT_TOP: case constant_1.DIRECTION.RIGHT_BOTTOM: this.right += width; break; case constant_1.DIRECTION.BOTTOM: case constant_1.DIRECTION.BOTTOM_LEFT: case constant_1.DIRECTION.BOTTOM_RIGHT: this.bottom += height; break; case constant_1.DIRECTION.LEFT: case constant_1.DIRECTION.LEFT_TOP: case constant_1.DIRECTION.LEFT_BOTTOM: this.left += width; break; default: break; } return this; }; /** * 获得最终的 padding */ PaddingCal.prototype.getPadding = function () { return [this.top, this.right, this.bottom, this.left]; }; return PaddingCal; }()); exports.PaddingCal = PaddingCal; },{"../../constant":237}],234:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ScalePool = void 0; /** * view 中缓存 scale 的类 */ var util_1 = require("@antv/util"); var scale_1 = require("../../util/scale"); /** @ignore */ var ScalePool = /** @class */ (function () { function ScalePool() { /** 所有的 scales */ this.scales = new Map(); /** 需要同步的 scale 分组, key: scaleKeyArray */ this.syncScales = new Map(); } /** * 创建 scale * @param field * @param data * @param scaleDef * @param key */ ScalePool.prototype.createScale = function (field, data, scaleDef, key) { var finalScaleDef = scaleDef; var cacheScaleMeta = this.getScaleMeta(key); if (data.length === 0 && cacheScaleMeta) { // 在更新过程中数据变为空,同时 key 对应的 scale 已存在则保持 scale 同类型 var cacheScale = cacheScaleMeta.scale; var cacheScaleDef = { type: cacheScale.type, }; if (cacheScale.isCategory) { // 如果是分类类型,保持 values cacheScaleDef.values = cacheScale.values; } finalScaleDef = util_1.deepMix(cacheScaleDef, cacheScaleMeta.scaleDef, scaleDef); } var scale = scale_1.createScaleByField(field, data, finalScaleDef); // 缓存起来 this.cacheScale(scale, scaleDef, key); return scale; }; /** * 同步 scale */ ScalePool.prototype.sync = function () { var _this = this; // 对于 syncScales 中每一个 syncKey 下面的 scale 数组进行同步处理 this.syncScales.forEach(function (scaleKeys, syncKey) { // min, max, values var min = Number.MAX_SAFE_INTEGER; var max = Number.MIN_SAFE_INTEGER; var values = []; // 1. 遍历求得最大最小值,values 等 util_1.each(scaleKeys, function (key) { var scale = _this.getScale(key); max = util_1.isNumber(scale.max) ? Math.max(max, scale.max) : max; min = util_1.isNumber(scale.min) ? Math.min(min, scale.min) : min; // 去重 util_1.each(scale.values, function (v) { if (!values.includes(v)) { values.push(v); } }); }); // 2. 同步 util_1.each(scaleKeys, function (key) { var scale = _this.getScale(key); if (scale.isContinuous) { scale.change({ min: min, max: max, values: values, }); } else if (scale.isCategory) { scale.change({ values: values, }); } }); }); }; /** * 缓存一个 scale * @param scale * @param scaleDef * @param key */ ScalePool.prototype.cacheScale = function (scale, scaleDef, key) { // 1. 缓存到 scales var sm = this.getScaleMeta(key); // 存在则更新,同时检测类型是否一致 if (sm && sm.scale.type === scale.type) { scale_1.syncScale(sm.scale, scale); sm.scaleDef = scaleDef; // 更新 scaleDef } else { sm = { key: key, scale: scale, scaleDef: scaleDef, }; this.scales.set(key, sm); } // 2. 缓存到 syncScales,构造 Record 数据结构 var syncKey = this.getSyncKey(sm); sm.syncKey = syncKey; // 设置 sync 同步的 key // 因为存在更新 scale 机制,所以在缓存之前,先从原 syncScales 中去除 sync 的缓存引用 this.removeFromSyncScales(key); // 存在 sync 标记才进行 sync if (syncKey) { // 不存在这个 syncKey,则创建一个空数组 var scaleKeys = this.syncScales.get(syncKey); if (!scaleKeys) { scaleKeys = []; this.syncScales.set(syncKey, scaleKeys); } scaleKeys.push(key); } }; /** * 通过 key 获取 scale * @param key */ ScalePool.prototype.getScale = function (key) { var scaleMeta = this.getScaleMeta(key); if (!scaleMeta) { var field = util_1.last(key.split('-')); var scaleKeys = this.syncScales.get(field); if (scaleKeys && scaleKeys.length) { scaleMeta = this.getScaleMeta(scaleKeys[0]); } } return scaleMeta && scaleMeta.scale; }; /** * 在 view 销毁的时候,删除 scale 实例,防止内存泄露 * @param key */ ScalePool.prototype.deleteScale = function (key) { var scaleMeta = this.getScaleMeta(key); if (scaleMeta) { var syncKey = scaleMeta.syncKey; var scaleKeys = this.syncScales.get(syncKey); // 移除同步的关系 if (scaleKeys && scaleKeys.length) { var idx = scaleKeys.indexOf(key); if (idx !== -1) { scaleKeys.splice(idx, 1); } } } // 删除 scale 实例 this.scales.delete(key); }; /** * 清空 */ ScalePool.prototype.clear = function () { this.scales.clear(); this.syncScales.clear(); }; /** * 删除 sync scale 引用 * @param key */ ScalePool.prototype.removeFromSyncScales = function (key) { var _this = this; this.syncScales.forEach(function (scaleKeys, syncKey) { var idx = scaleKeys.indexOf(key); if (idx !== -1) { scaleKeys.splice(idx, 1); // 删除空数组值 if (scaleKeys.length === 0) { _this.syncScales.delete(syncKey); } return false; // 跳出循环 } }); }; /** * get sync key * @param sm */ ScalePool.prototype.getSyncKey = function (sm) { var scale = sm.scale, scaleDef = sm.scaleDef; var field = scale.field; var sync = util_1.get(scaleDef, ['sync']); // 如果 sync = true,则直接使用字段名作为 syncKey return sync === true ? field : sync === false ? undefined : sync; }; /** * 通过 key 获取 scale * @param key */ ScalePool.prototype.getScaleMeta = function (key) { return this.scales.get(key); }; return ScalePool; }()); exports.ScalePool = ScalePool; },{"../../util/scale":381,"@antv/util":803}],235:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerGeometry = exports.View = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = tslib_1.__importDefault(require("../base")); var facet_1 = require("../facet"); var interaction_1 = require("../interaction"); var theme_1 = require("../theme"); var bbox_1 = require("../util/bbox"); var coordinate_1 = require("../util/coordinate"); var helper_1 = require("../util/helper"); var tooltip_1 = require("../util/tooltip"); var controller_1 = require("./controller"); var coordinate_2 = tslib_1.__importDefault(require("./controller/coordinate")); var event_1 = tslib_1.__importDefault(require("./event")); var layout_1 = tslib_1.__importDefault(require("./layout")); var scale_pool_1 = require("./util/scale-pool"); var padding_1 = require("../util/padding"); /** * G2 视图 View 类 */ var View = /** @class */ (function (_super) { tslib_1.__extends(View, _super); function View(props) { var _this = _super.call(this, { visible: props.visible }) || this; /** view id,全局唯一。 */ _this.id = util_1.uniqueId('view'); /** 所有的子 view。 */ _this.views = []; /** 所有的 geometry 实例。 */ _this.geometries = []; /** 所有的组件 controllers。 */ _this.controllers = []; /** 所有的 Interaction 实例。 */ _this.interactions = {}; /** 是否对超出坐标系范围的 Geometry 进行剪切 */ _this.limitInPlot = false; // 配置信息存储 _this.options = { data: [], animate: true, }; // 初始化为空 /** 配置开启的组件插件,默认为全局配置的组件。 */ _this.usedControllers = controller_1.getComponentControllerNames(); /** 所有的 scales */ _this.scalePool = new scale_pool_1.ScalePool(); /** 布局函数 */ _this.layoutFunc = layout_1.default; /** 当前鼠标是否在 plot 内(CoordinateBBox) */ _this.isPreMouseInPlot = false; /** 默认标识位,用于判定数据是否更新 */ _this.isDataChanged = false; /** 用于判断坐标系范围是否发生变化的标志位 */ _this.isCoordinateChanged = false; /** 从当前这个 view 创建的 scale key */ _this.createdScaleKeys = new Map(); _this.onCanvasEvent = function (evt) { var name = evt.name; if (!name.includes(':')) { // 非委托事件 var e = _this.createViewEvent(evt); // 处理 plot 事件 _this.doPlotEvent(e); _this.emit(name, e); } }; /** * 触发事件之后 * @param evt */ _this.onDelegateEvents = function (evt) { // 阻止继续冒泡,防止重复事件触发 // evt.preventDefault(); var name = evt.name; if (!name.includes(':')) { return; } // 事件在 view 嵌套中冒泡(暂不提供阻止冒泡的机制) var e = _this.createViewEvent(evt); // 包含有基本事件、组合事件 _this.emit(name, e); // const currentTarget = evt.currentTarget as IShape; // const inheritNames = currentTarget.get('inheritNames'); // if (evt.delegateObject || inheritNames) { // const events = this.getEvents(); // each(inheritNames, (subName) => { // const eventName = `${subName}:${type}`; // if (events[eventName]) { // this.emit(eventName, e); // } // }); // } }; var parent = props.parent, canvas = props.canvas, backgroundGroup = props.backgroundGroup, middleGroup = props.middleGroup, foregroundGroup = props.foregroundGroup, _a = props.region, region = _a === void 0 ? { start: { x: 0, y: 0 }, end: { x: 1, y: 1 } } : _a, padding = props.padding, appendPadding = props.appendPadding, theme = props.theme, options = props.options, limitInPlot = props.limitInPlot; _this.parent = parent; _this.canvas = canvas; _this.backgroundGroup = backgroundGroup; _this.middleGroup = middleGroup; _this.foregroundGroup = foregroundGroup; _this.region = region; _this.padding = padding; _this.appendPadding = appendPadding; // 接受父 view 传入的参数 _this.options = tslib_1.__assign(tslib_1.__assign({}, _this.options), options); _this.limitInPlot = limitInPlot; // 初始化 theme _this.themeObject = util_1.isObject(theme) ? util_1.deepMix({}, theme_1.getTheme('default'), theme) : theme_1.getTheme(theme); _this.init(); return _this; } /** * 设置 layout 布局函数 * @param layout 布局函数 * @returns void */ View.prototype.setLayout = function (layout) { this.layoutFunc = layout; }; /** * 生命周期:初始化 * @returns voids */ View.prototype.init = function () { // 计算画布的 viewBBox this.calculateViewBBox(); // 事件委托机制 this.initEvents(); // 初始化组件 controller this.initComponentController(); // 创建 coordinate controller this.coordinateController = new coordinate_2.default(this.options.coordinate); this.initOptions(); // 递归初始化子 view var views = this.views; for (var i = 0; i < views.length; i++) { views[i].init(); } }; /** * 生命周期:渲染流程,渲染过程需要处理数据更新的情况。 * render 函数仅仅会处理 view 和子 view。 * @param isUpdate 是否触发更新流程。 */ View.prototype.render = function (isUpdate) { if (isUpdate === void 0) { isUpdate = false; } this.emit(constant_1.VIEW_LIFE_CIRCLE.BEFORE_RENDER); // 递归渲染 this.paint(isUpdate); this.emit(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER); if (this.visible === false) { // 用户在初始化的时候声明 visible: false this.changeVisible(false); } }; /** * 生命周期:清空图表上所有的绘制内容,但是不销毁图表,chart 仍可使用。 * @returns void */ View.prototype.clear = function () { var _this = this; this.emit(constant_1.VIEW_LIFE_CIRCLE.BEFORE_CLEAR); // 1. 清空缓存和计算数据 this.filteredData = []; this.coordinateInstance = undefined; this.isDataChanged = false; // 复位 this.isCoordinateChanged = false; // 复位 // 2. 清空 geometries var geometries = this.geometries; for (var i = 0; i < geometries.length; i++) { geometries[i].clear(); } this.geometries = []; // 3. 清空 controllers var controllers = this.controllers; for (var i = 0; i < controllers.length; i++) { controllers[i].clear(); } // 4. 删除 scale 缓存 this.createdScaleKeys.forEach(function (v, k) { _this.getRootView().scalePool.deleteScale(k); }); this.createdScaleKeys.clear(); // 递归处理子 view var views = this.views; for (var i = 0; i < views.length; i++) { views[i].clear(); } this.emit(constant_1.VIEW_LIFE_CIRCLE.AFTER_CLEAR); }; /** * 生命周期:销毁,完全无法使用。 * @returns void */ View.prototype.destroy = function () { // 销毁前事件,销毁之后已经没有意义了,所以不抛出事件 this.emit(constant_1.VIEW_LIFE_CIRCLE.BEFORE_DESTROY); var interactions = this.interactions; // 销毁 interactions util_1.each(interactions, function (interaction) { if (interaction) { // 有可能已经销毁,设置了 undefined interaction.destroy(); } }); this.clear(); // 销毁 controller 中的组件 var controllers = this.controllers; for (var i = 0, len = controllers.length; i < len; i++) { var controller = controllers[i]; controller.destroy(); } this.backgroundGroup.remove(true); this.middleGroup.remove(true); this.foregroundGroup.remove(true); _super.prototype.destroy.call(this); }; /* end 生命周期函数 */ /** * 显示或者隐藏整个 view。 * @param visible 是否可见 * @returns View */ View.prototype.changeVisible = function (visible) { _super.prototype.changeVisible.call(this, visible); var geometries = this.geometries; for (var i = 0, len = geometries.length; i < len; i++) { var geometry = geometries[i]; geometry.changeVisible(visible); } var controllers = this.controllers; for (var i = 0, len = controllers.length; i < len; i++) { var controller = controllers[i]; controller.changeVisible(visible); } this.foregroundGroup.set('visible', visible); this.middleGroup.set('visible', visible); this.backgroundGroup.set('visible', visible); // group.set('visible', visible) 不会触发自动刷新 this.getCanvas().draw(); return this; }; /** * 装载数据源。 * * ```ts * view.data([{ city: '杭州', sale: 100 }, { city: '上海', sale: 110 } ]); * ``` * * @param data 数据源,json 数组。 * @returns View */ View.prototype.data = function (data) { util_1.set(this.options, 'data', data); this.isDataChanged = true; return this; }; /** * @deprecated * This method will be removed at G2 V4.1. Replaced by {@link #data(data)} */ View.prototype.source = function (data) { console.warn('This method will be removed at G2 V4.1. Please use chart.data() instead.'); return this.data(data); }; /** * 设置数据筛选规则。 * * ```ts * view.filter('city', (value: any, datum: Datum) => value !== '杭州'); * * // 删除 'city' 字段对应的筛选规则。 * view.filter('city', null); * ``` * * @param field 数据字段 * @param condition 筛选规则 * @returns View */ View.prototype.filter = function (field, condition) { if (util_1.isFunction(condition)) { util_1.set(this.options, ['filters', field], condition); return this; } // condition 为空,则表示删除过滤条件 if (!condition && util_1.get(this.options, ['filters', field])) { delete this.options.filters[field]; } return this; }; View.prototype.axis = function (field, axisOption) { if (util_1.isBoolean(field)) { util_1.set(this.options, ['axes'], field); } else { util_1.set(this.options, ['axes', field], axisOption); } return this; }; View.prototype.legend = function (field, legendOption) { if (util_1.isBoolean(field)) { util_1.set(this.options, ['legends'], field); } else if (util_1.isString(field)) { util_1.set(this.options, ['legends', field], legendOption); } else { // 设置全局的 legend 配置 util_1.set(this.options, ['legends'], field); } return this; }; View.prototype.scale = function (field, scaleOption) { var _this = this; if (util_1.isString(field)) { util_1.set(this.options, ['scales', field], scaleOption); } else if (util_1.isObject(field)) { util_1.each(field, function (v, k) { util_1.set(_this.options, ['scales', k], v); }); } return this; }; /** * tooltip 提示信息配置。 * * ```ts * view.tooltip(false); // 关闭 tooltip * * view.tooltip({ * shared: true * }); * ``` * * @param cfg Tooltip 配置,更详细的配置项参考:https://github.com/antvis/component#tooltip * @returns View */ View.prototype.tooltip = function (cfg) { util_1.set(this.options, 'tooltip', cfg); return this; }; /** * 辅助标记配置。 * * ```ts * view.annotation().line({ * start: ['min', 85], * end: ['max', 85], * style: { * stroke: '#595959', * lineWidth: 1, * lineDash: [3, 3], * }, * }); * ``` * 更详细的配置项:https://github.com/antvis/component#annotation * @returns [[Annotation]] */ View.prototype.annotation = function () { return this.getController('annotation'); }; /** * @deprecated * This method will be removed at G2 V4.1. Replaced by {@link #guide()} */ View.prototype.guide = function () { console.warn('This method will be removed at G2 V4.1. Please use chart.annotation() instead.'); return this.annotation(); }; View.prototype.coordinate = function (type, coordinateCfg) { // 提供语法糖,使用更简单 if (util_1.isString(type)) { util_1.set(this.options, 'coordinate', { type: type, cfg: coordinateCfg }); } else { util_1.set(this.options, 'coordinate', type); } // 更新 coordinate 配置 this.coordinateController.update(this.options.coordinate); return this.coordinateController; }; /** * @deprecated * This method will be removed at G2 V4.1. Replaced by {@link #coordinate()} */ View.prototype.coord = function (type, coordinateCfg) { console.warn('This method will be removed at G2 V4.1. Please use chart.coordinate() instead.'); // @ts-ignore return this.coordinate(type, coordinateCfg); }; /** * view 分面绘制。 * * ```ts * view.facet('rect', { * rowField: 'province', * columnField: 'category', * eachView: (innerView: View, facet?: FacetData) => { * innerView.line().position('city*sale'); * }, * }); * ``` * * @param type 分面类型 * @param cfg 分面配置, [[FacetCfgMap]] * @returns View */ View.prototype.facet = function (type, cfg) { // 先销毁掉之前的分面 if (this.facetInstance) { this.facetInstance.destroy(); } // 创建新的分面 var Ctor = facet_1.getFacet(type); if (!Ctor) { throw new Error("facet '" + type + "' is not exist!"); } this.facetInstance = new Ctor(this, tslib_1.__assign(tslib_1.__assign({}, cfg), { type: type })); return this; }; /* * 开启或者关闭动画。 * * ```ts * view.animate(false); * ``` * * @param status 动画状态,true 表示开始,false 表示关闭 * @returns View */ View.prototype.animate = function (status) { util_1.set(this.options, 'animate', status); return this; }; /** * 更新配置项,用于配置项式声明。 * @param options 配置项 */ View.prototype.updateOptions = function (options) { this.clear(); // 清空 util_1.mix(this.options, options); this.initOptions(); return this; }; /** * 往 `view.options` 属性中存储配置项。 * @param name 属性名称 * @param opt 属性值 * @returns view */ View.prototype.option = function (name, opt) { // 对于内置的 option,避免覆盖。 // name 在原型上,说明可能是内置 API,存在 option 被覆盖的风险,不处理 if (View.prototype[name]) { throw new Error("Can't use built in variable name \"" + name + "\", please change another one."); } // 存入到 option 中 util_1.set(this.options, name, opt); return this; }; /** * 设置主题。 * * ```ts * view.theme('dark'); // 'dark' 需要事先通过 `registerTheme()` 接口注册完成 * * view.theme({ defaultColor: 'red' }); * ``` * * @param theme 主题名或者主题配置 * @returns View */ View.prototype.theme = function (theme) { this.themeObject = util_1.isObject(theme) ? util_1.deepMix({}, this.themeObject, theme) : theme_1.getTheme(theme); return this; }; /* end 一系列传入配置的 API */ /** * Call the interaction based on the interaction name * * ```ts * view.interaction('my-interaction', { extra: 'hello world' }); * ``` * 详细文档可以参考:https://g2.antv.vision/zh/docs/manual/tutorial/interaction * @param name interaction name * @param cfg interaction config * @returns */ View.prototype.interaction = function (name, cfg) { var existInteraction = this.interactions[name]; // 存在则先销毁已有的 if (existInteraction) { existInteraction.destroy(); } // 新建交互实例 var interaction = interaction_1.createInteraction(name, this, cfg); if (interaction) { interaction.init(); this.interactions[name] = interaction; } return this; }; /** * 移除当前 View 的 interaction * ```ts * view.removeInteraction('my-interaction'); * ``` * @param name interaction name */ View.prototype.removeInteraction = function (name) { var existInteraction = this.interactions[name]; // 存在则先销毁已有的 if (existInteraction) { existInteraction.destroy(); this.interactions[name] = undefined; } }; /** * 修改数据,数据更新逻辑,数据更新仅仅影响当前这一层的 view * * ```ts * view.changeData([{ city: '北京', sale: '200' }]); * ``` * * @param data * @returns void */ View.prototype.changeData = function (data) { this.isDataChanged = true; this.emit(constant_1.VIEW_LIFE_CIRCLE.BEFORE_CHANGE_DATA); // 1. 保存数据 this.data(data); // 2. 渲染 this.paint(true); // 3. 遍历子 view 进行 change data var views = this.views; for (var i = 0, len = views.length; i < len; i++) { var view = views[i]; // FIXME 子 view 有自己的数据的情况,该如何处理? view.changeData(data); } this.emit(constant_1.VIEW_LIFE_CIRCLE.AFTER_CHANGE_DATA); }; /* View 管理相关的 API */ /** * 创建子 view * * ```ts * const innerView = view.createView({ * start: { x: 0, y: 0 }, * end: { x: 0.5, y: 0.5 }, * padding: 8, * }); * ``` * * @param cfg * @returns View */ View.prototype.createView = function (cfg) { // 子 view 共享 options 配置数据 var sharedOptions = { data: this.options.data, scales: util_1.clone(this.options.scales), axes: util_1.clone(this.options.axes), coordinate: util_1.clone(this.coordinateController.getOption()), tooltip: util_1.clone(this.options.tooltip), legends: util_1.clone(this.options.legends), animate: this.options.animate, visible: this.visible, }; var v = new View(tslib_1.__assign(tslib_1.__assign({ parent: this, canvas: this.canvas, // 子 view 共用三层 group backgroundGroup: this.backgroundGroup.addGroup({ zIndex: constant_1.GROUP_Z_INDEX.BG }), middleGroup: this.middleGroup.addGroup({ zIndex: constant_1.GROUP_Z_INDEX.MID }), foregroundGroup: this.foregroundGroup.addGroup({ zIndex: constant_1.GROUP_Z_INDEX.FORE }), theme: this.themeObject, padding: this.padding }, cfg), { options: tslib_1.__assign(tslib_1.__assign({}, sharedOptions), util_1.get(cfg, 'options', {})) })); this.views.push(v); return v; }; /** * @deprecated * This method will be removed at G2 V4.1. Replaced by {@link #createView()} */ View.prototype.view = function (cfg) { console.warn('This method will be removed at G2 V4.1. Please use chart.createView() instead.'); return this.createView(cfg); }; /** * 删除一个子 view * @param view * @return removedView */ View.prototype.removeView = function (view) { var removedView = util_1.remove(this.views, function (v) { return v === view; })[0]; if (removedView) { removedView.destroy(); } return removedView; }; /* end View 管理相关的 API */ // 一些 get 方法 /** * 获取当前坐标系实例。 * @returns [[Coordinate]] */ View.prototype.getCoordinate = function () { return this.coordinateInstance; }; /** * 获取当前 view 的主题配置。 * @returns themeObject */ View.prototype.getTheme = function () { return this.themeObject; }; /** * 获得 x 轴字段的 scale 实例。 * @returns view 中 Geometry 对于的 x scale */ View.prototype.getXScale = function () { // 拿第一个 Geometry 的 X scale // 隐藏逻辑:一个 view 中的 Geometry 必须 x 字段一致 var g = this.geometries[0]; return g ? g.getXScale() : null; }; /** * 获取 y 轴字段的 scales 实例。 * @returns view 中 Geometry 对于的 y scale 数组 */ View.prototype.getYScales = function () { // 拿到所有的 Geometry 的 Y scale,然后去重 var tmpMap = {}; return this.geometries.map(function (g) { var yScale = g.getYScale(); var field = yScale.field; if (!tmpMap[field]) { tmpMap[field] = true; return yScale; } }); }; /** * 获取 x 轴或者 y 轴对应的所有 scale 实例。 * @param dimType x | y * @returns x 轴或者 y 轴对应的所有 scale 实例。 */ View.prototype.getScalesByDim = function (dimType) { var geometries = this.geometries; var scales = {}; for (var i = 0, len = geometries.length; i < len; i++) { var geometry = geometries[i]; var scale = dimType === 'x' ? geometry.getXScale() : geometry.getYScale(); if (scale && !scales[scale.field]) { scales[scale.field] = scale; } } return scales; }; /** * 根据字段名去获取 scale 实例。 * @param field 数据字段名称 * @param key id */ View.prototype.getScaleByField = function (field, key) { var defaultKey = key ? key : this.getScaleKey(field); // 调用根节点 view 的方法获取 return this.getRootView().scalePool.getScale(defaultKey); }; /** * 返回所有配置信息。 * @returns 所有的 view API 配置。 */ View.prototype.getOptions = function () { return this.options; }; /** * 获取 view 的数据(过滤后的数据)。 * @returns 处理过滤器之后的数据。 */ View.prototype.getData = function () { return this.filteredData; }; /** * 获得绘制的层级 group。 * @param layer 层级名称。 * @returns 对应层级的 Group。 */ View.prototype.getLayer = function (layer) { return layer === constant_1.LAYER.BG ? this.backgroundGroup : layer === constant_1.LAYER.MID ? this.middleGroup : layer === constant_1.LAYER.FORE ? this.foregroundGroup : this.foregroundGroup; }; /** * 对外暴露方法,判断一个点是否在绘图区域(即坐标系范围)内部。 * @param point 坐标点 */ View.prototype.isPointInPlot = function (point) { return coordinate_1.isPointInCoordinate(this.getCoordinate(), point); }; /** * 获得所有的 legend 对应的 attribute 实例。 * @returns 维度字段的 Attribute 数组 */ View.prototype.getLegendAttributes = function () { return util_1.flatten(this.geometries.map(function (g) { return g.getGroupAttributes(); })); }; /** * 获取所有的分组字段的 scale 实例。 * @returns 获得分组字段的 scale 实例数组。 */ View.prototype.getGroupScales = function () { // 拿到所有的 Geometry 的 分组字段 scale,然后打平去重 var scales = this.geometries.map(function (g) { return g.getGroupScales(); }); return helper_1.uniq(util_1.flatten(scales)); }; /** * 获取 G.Canvas 实例。 * @returns G.Canvas 画布实例。 */ View.prototype.getCanvas = function () { return this.getRootView().canvas; }; /** * 获得根节点 view。 */ View.prototype.getRootView = function () { var v = this; while (true) { if (v.parent) { v = v.parent; continue; } break; } return v; }; /** * 获取该数据在可视化后,对应的画布坐标点。 * @param data 原始数据记录 * @returns 对应的画布坐标点 */ View.prototype.getXY = function (data) { var coordinate = this.getCoordinate(); var xScales = this.getScalesByDim('x'); var yScales = this.getScalesByDim('y'); var x; var y; util_1.each(data, function (value, key) { if (xScales[key]) { x = xScales[key].scale(value); } if (yScales[key]) { y = yScales[key].scale(value); } }); if (!util_1.isNil(x) && !util_1.isNil(y)) { return coordinate.convert({ x: x, y: y }); } }; /** * 获取 name 对应的 controller 实例 * @param name */ View.prototype.getController = function (name) { return util_1.find(this.controllers, function (c) { return c.name === name; }); }; /** * 显示 point 坐标点对应的 tooltip。 * @param point 画布坐标点 * @returns View */ View.prototype.showTooltip = function (point) { var tooltip = this.getController('tooltip'); if (tooltip) { tooltip.showTooltip(point); } return this; }; /** * 隐藏 tooltip。 * @returns View */ View.prototype.hideTooltip = function () { var tooltip = this.getController('tooltip'); if (tooltip) { tooltip.hideTooltip(); } return this; }; /** * 将 tooltip 锁定到当前位置不能移动。 * @returns View */ View.prototype.lockTooltip = function () { var tooltip = this.getController('tooltip'); if (tooltip) { tooltip.lockTooltip(); } return this; }; /** * 将 tooltip 锁定解除。 * @returns View */ View.prototype.unlockTooltip = function () { var tooltip = this.getController('tooltip'); if (tooltip) { tooltip.unlockTooltip(); } return this; }; /** * 是否锁定 tooltip。 * @returns 是否锁定 */ View.prototype.isTooltipLocked = function () { var tooltip = this.getController('tooltip'); return tooltip && tooltip.isTooltipLocked(); }; /** * 获取当前 point 对应的 tooltip 数据项。 * @param point 坐标点 * @returns tooltip 数据项 */ View.prototype.getTooltipItems = function (point) { var tooltip = this.getController('tooltip'); return tooltip ? tooltip.getTooltipItems(point) : []; }; /** * 获取逼近的点的数据集合 * @param point 当前坐标点 * @returns 数据 */ View.prototype.getSnapRecords = function (point) { var geometries = this.geometries; var rst = []; for (var i = 0, len = geometries.length; i < len; i++) { var geom = geometries[i]; var dataArray = geom.dataArray; geom.sort(dataArray); // 先进行排序,便于 tooltip 查找 var record = void 0; for (var j = 0, dataLen = dataArray.length; j < dataLen; j++) { var data = dataArray[j]; record = tooltip_1.findDataByPoint(point, data, geom); if (record) { rst.push(record); } } } // 同样递归处理子 views var views = this.views; for (var i = 0, len = views.length; i < len; i++) { var view = views[i]; var snapRecords = view.getSnapRecords(point); rst = rst.concat(snapRecords); } return rst; }; /** * 获取所有的 pure component 组件,用于布局。 */ View.prototype.getComponents = function () { var components = []; var controllers = this.controllers; for (var i = 0, len = controllers.length; i < len; i++) { var controller = controllers[i]; components = components.concat(controller.getComponents()); } return components; }; /** * 将 data 数据进行过滤。 * @param data * @returns 过滤之后的数据 */ View.prototype.filterData = function (data) { var filters = this.options.filters; // 不存在 filters,则不需要进行数据过滤 if (util_1.size(filters) === 0) { return data; } // 存在过滤器,则逐个执行过滤,过滤器之间是 与 的关系 return util_1.filter(data, function (datum, idx) { // 所有的 filter 字段 var fields = Object.keys(filters); // 所有的条件都通过,才算通过 return fields.every(function (field) { var condition = filters[field]; // condition 返回 true,则保留 return condition(datum[field], datum, idx); }); }); }; /** * 对某一个字段进行过滤 * @param field * @param data */ View.prototype.filterFieldData = function (field, data) { var filters = this.options.filters; var condition = util_1.get(filters, field); if (util_1.isUndefined(condition)) { return data; } return data.filter(function (datum, idx) { return condition(datum[field], datum, idx); }); }; /** * 调整 coordinate 的坐标范围。 */ View.prototype.adjustCoordinate = function () { var _a = this.getCoordinate(), curStart = _a.start, curEnd = _a.end; var start = this.coordinateBBox.bl; var end = this.coordinateBBox.tr; // 在 defaultLayoutFn 中只会在 coordinateBBox 发生变化的时候会调用 adjustCoorinate(),所以不用担心被置位 if (util_1.isEqual(curStart, start) && util_1.isEqual(curEnd, end)) { this.isCoordinateChanged = false; // 如果大小没有变化则不更新 return; } this.isCoordinateChanged = true; this.coordinateInstance = this.coordinateController.adjust(start, end); }; View.prototype.paint = function (isUpdate) { this.renderDataRecursive(isUpdate); // 处理 sync scale 的逻辑 this.syncScale(); this.emit(constant_1.VIEW_LIFE_CIRCLE.BEFORE_PAINT); this.renderBackgroundStyleShape(); this.renderLayoutRecursive(isUpdate); this.renderPaintRecursive(isUpdate); this.emit(constant_1.VIEW_LIFE_CIRCLE.AFTER_PAINT); this.isDataChanged = false; // 渲染完毕复位 }; /** 渲染背景样式的 shape */ View.prototype.renderBackgroundStyleShape = function () { // 只有根节点才处理 if (!this.parent) { var background = util_1.get(this.themeObject, 'background'); // 1. 配置了背景色 if (background) { // 1. 不存在则创建 if (!this.backgruondStyleRectShape) { this.backgruondStyleRectShape = this.backgroundGroup.addShape('rect', { attrs: { zIndex: -1, }, }); } // 2. 有了 shape 之后设置背景,位置(更新的时候) var _a = this.viewBBox, x = _a.x, y = _a.y, width = _a.width, height = _a.height; this.backgruondStyleRectShape.attr({ fill: background, x: x, y: y, width: width, height: height, }); } else { // 没有配置背景色 if (this.backgruondStyleRectShape) { this.backgruondStyleRectShape.remove(true); this.backgruondStyleRectShape = undefined; } } } }; /** * 替换处理 view 的布局,最终是计算各个 view 的 coordinateBBox 和 coordinateInstance * @param isUpdate */ View.prototype.renderLayoutRecursive = function (isUpdate) { // 1. 子 view 大小相对 coordinateBBox,changeSize 的时候需要重新计算 this.calculateViewBBox(); // 2. 更新 coordinate this.adjustCoordinate(); // 3. 初始化组件 component this.initComponents(isUpdate); // 4. 进行布局,计算 coordinateBBox,进行组件布局,update 位置 this.doLayout(); // 5. 更新并存储最终的 padding 值 var viewBBox = this.viewBBox; var coordinateBBox = this.coordinateBBox; if (padding_1.isAutoPadding(this.padding)) { // 用户未设置 padding 时,将自动计算的 padding 保存至 autoPadding 属性中 this.autoPadding = [ coordinateBBox.tl.y - viewBBox.tl.y, viewBBox.tr.x - coordinateBBox.tr.x, viewBBox.bl.y - coordinateBBox.bl.y, coordinateBBox.tl.x - viewBBox.tl.x, ]; } // 同样递归处理子 views var views = this.views; for (var i = 0, len = views.length; i < len; i++) { var view = views[i]; view.renderLayoutRecursive(isUpdate); } }; /** * 最终递归绘制组件和图形 * @param isUpdate */ View.prototype.renderPaintRecursive = function (isUpdate) { if (this.limitInPlot) { var middleGroup = this.middleGroup; var _a = coordinate_1.getCoordinateClipCfg(this.coordinateInstance), type = _a.type, attrs = _a.attrs; middleGroup.setClip({ type: type, attrs: attrs, }); } // 1. 渲染几何标记 this.paintGeometries(isUpdate); // 2. 绘制组件 this.renderComponents(isUpdate); // 同样递归处理子 views var views = this.views; for (var i = 0, len = views.length; i < len; i++) { var view = views[i]; view.renderPaintRecursive(isUpdate); } }; // end Get 方法 /** * 创建 scale,递归到顶层 view 去创建和缓存 scale * @param field * @param data * @param scaleDef * @param key */ View.prototype.createScale = function (field, data, scaleDef, key) { // 1. 合并 field 对应的 scaleDef,合并原则是底层覆盖顶层(就近原则) var currentScaleDef = util_1.get(this.options.scales, [field]); var mergedScaleDef = tslib_1.__assign(tslib_1.__assign({}, currentScaleDef), scaleDef); // 2. 是否存在父 view,在则递归,否则创建 if (this.parent) { return this.parent.createScale(field, data, mergedScaleDef, key); } // 3. 在根节点 view 通过 scalePool 创建 return this.scalePool.createScale(field, data, mergedScaleDef, key); }; /** * 递归渲染中的数据处理 * @param isUpdate */ View.prototype.renderDataRecursive = function (isUpdate) { // 1. 处理数据 this.doFilterData(); // 2. 创建实例 this.createCoordinate(); // 3. 初始化 Geometry this.initGeometries(isUpdate); // 4. 处理分面逻辑,最终都是生成子 view 和 geometry this.renderFacet(isUpdate); // 同样递归处理子 views var views = this.views; for (var i = 0, len = views.length; i < len; i++) { var view = views[i]; view.renderDataRecursive(isUpdate); } }; /** * 计算 region,计算实际的像素范围坐标 * @private */ View.prototype.calculateViewBBox = function () { var x; var y; var width; var height; if (this.parent) { var bbox = this.parent.coordinateBBox; // 存在 parent, 那么就是通过父容器大小计算 x = bbox.x; y = bbox.y; width = bbox.width; height = bbox.height; } else { // 顶层容器,从 canvas 中取值 宽高 x = 0; y = 0; width = this.canvas.get('width'); height = this.canvas.get('height'); } var _a = this.region, start = _a.start, end = _a.end; // 根据 region 计算当前 view 的 bbox 大小。 var viewBBox = new bbox_1.BBox(x + width * start.x, y + height * start.y, width * (end.x - start.x), height * (end.y - start.y)); if (!this.viewBBox || !this.viewBBox.isEqual(viewBBox)) { // viewBBox 发生变化的时候进行更新 this.viewBBox = new bbox_1.BBox(x + width * start.x, y + height * start.y, width * (end.x - start.x), height * (end.y - start.y)); // 初始的 coordinate bbox 大小 this.coordinateBBox = this.viewBBox; } }; /** * 初始化事件机制:G 4.0 底层内置支持 name:event 的机制,那么只要所有组件都有自己的 name 即可。 * * G2 的事件只是获取事件委托,然后在 view 嵌套结构中,形成事件冒泡机制。 * 当前 view 只委托自己 view 中的 Component 和 Geometry 事件,并向上冒泡 * @private */ View.prototype.initEvents = function () { // 三层 group 中的 shape 事件都会通过 G 冒泡上来的 this.foregroundGroup.on('*', this.onDelegateEvents); this.middleGroup.on('*', this.onDelegateEvents); this.backgroundGroup.on('*', this.onDelegateEvents); this.canvas.on('*', this.onCanvasEvent); }; /** * 初始化插件 */ View.prototype.initComponentController = function () { var usedControllers = this.usedControllers; for (var i = 0, len = usedControllers.length; i < len; i++) { var controllerName = usedControllers[i]; var Ctor = controller_1.getComponentController(controllerName); if (Ctor) { this.controllers.push(new Ctor(this)); } } }; View.prototype.createViewEvent = function (evt) { var shape = evt.shape, name = evt.name; var data = shape ? shape.get('origin') : null; // 事件在 view 嵌套中冒泡(暂不提供阻止冒泡的机制) var e = new event_1.default(this, evt, data); e.type = name; return e; }; /** * 处理 PLOT_EVENTS * plot event 需要处理所有的基础事件,并判断是否在画布中,然后再决定是否要 emit。 * 对于 mouseenter、mouseleave 比较特殊,需要做一下数学比较。 * @param e */ View.prototype.doPlotEvent = function (e) { var type = e.type, x = e.x, y = e.y; var point = { x: x, y: y }; var ALL_EVENTS = [ 'mousedown', 'mouseup', 'mousemove', 'mouseleave', 'mousewheel', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'click', 'dblclick', 'contextmenu', ]; if (ALL_EVENTS.includes(type)) { var currentInPlot = this.isPointInPlot(point); if (currentInPlot) { var TYPE = "plot:" + type; // 组合 plot 事件 e.type = TYPE; this.emit(TYPE, e); if (type === 'mouseleave' || type === 'touchend') { // 在plot 内部却离开画布 this.isPreMouseInPlot = false; } } // 对于 mouseenter, mouseleave 的计算处理 if (type === 'mousemove' || type === 'touchmove') { if (this.isPreMouseInPlot && !currentInPlot) { if (type === 'mousemove') { e.type = constant_1.PLOT_EVENTS.MOUSE_LEAVE; this.emit(constant_1.PLOT_EVENTS.MOUSE_LEAVE, e); } e.type = constant_1.PLOT_EVENTS.LEAVE; this.emit(constant_1.PLOT_EVENTS.LEAVE, e); } else if (!this.isPreMouseInPlot && currentInPlot) { if (type === 'mousemove') { e.type = constant_1.PLOT_EVENTS.MOUSE_ENTER; this.emit(constant_1.PLOT_EVENTS.MOUSE_ENTER, e); } e.type = constant_1.PLOT_EVENTS.ENTER; this.emit(constant_1.PLOT_EVENTS.ENTER, e); } // 赋新的状态值 this.isPreMouseInPlot = currentInPlot; } else if (type === 'mouseleave' || type === 'touchend') { // 可能不在 currentInPlot 中 if (this.isPreMouseInPlot) { if (type === 'mouseleave') { e.type = constant_1.PLOT_EVENTS.MOUSE_LEAVE; this.emit(constant_1.PLOT_EVENTS.MOUSE_LEAVE, e); } e.type = constant_1.PLOT_EVENTS.LEAVE; this.emit(constant_1.PLOT_EVENTS.LEAVE, e); this.isPreMouseInPlot = false; } } } }; // view 生命周期 —— 渲染流程 /** * 处理筛选器,筛选数据 * @private */ View.prototype.doFilterData = function () { var data = this.options.data; this.filteredData = this.filterData(data); }; /** * 初始化 Geometries * @private */ View.prototype.initGeometries = function (isUpdate) { // 初始化图形的之前,先创建 / 更新 scales this.createOrUpdateScales(); // 实例化 Geometry,然后 view 将所有的 scale 管理起来 var coordinate = this.getCoordinate(); var scaleDefs = util_1.get(this.options, 'scales', {}); var geometries = this.geometries; for (var i = 0, len = geometries.length; i < len; i++) { var geometry = geometries[i]; // 保持 scales 引用不要变化 geometry.scales = this.getGeometryScales(); var cfg = { coordinate: coordinate, scaleDefs: scaleDefs, data: this.filteredData, theme: this.themeObject, isDataChanged: this.isDataChanged, isCoordinateChanged: this.isCoordinateChanged, }; if (isUpdate) { // 数据发生更新 geometry.update(cfg); } else { geometry.init(cfg); } } // Geometry 初始化之后,生成了 scale,然后进行调整 scale 配置 this.adjustScales(); }; /** * 根据 Geometry 的所有字段创建 scales * 如果存在,则更新,不存在则创建 */ View.prototype.createOrUpdateScales = function () { var fields = this.getScaleFields(); var groupedFields = this.getGroupedFields(); var _a = this.getOptions(), data = _a.data, _b = _a.scales, scales = _b === void 0 ? {} : _b; var filteredData = this.filteredData; for (var i = 0, len = fields.length; i < len; i++) { var field = fields[i]; var scaleDef = scales[field]; // 调用方法,递归去创建 var key = this.getScaleKey(field); this.createScale(field, // 分组字段的 scale 使用未过滤的数据创建 groupedFields.includes(field) ? data : filteredData, scaleDef, key); // 缓存从当前 view 创建的 scale key this.createdScaleKeys.set(key, true); } }; /** * 处理 scale 同步逻辑 */ View.prototype.syncScale = function () { // 最终调用 root view 的 this.getRootView().scalePool.sync(); }; /** * 获得 Geometry 中的 scale 对象 */ View.prototype.getGeometryScales = function () { var fields = this.getScaleFields(); var scales = {}; for (var i = 0; i < fields.length; i++) { var field = fields[i]; scales[field] = this.getScaleByField(field); } return scales; }; View.prototype.getScaleFields = function () { var fields = []; var tmpMap = {}; var geometries = this.geometries; for (var i = 0; i < geometries.length; i++) { var geometry = geometries[i]; var geometryScales = geometry.getScaleFields(); helper_1.uniq(geometryScales, fields, tmpMap); } return fields; }; View.prototype.getGroupedFields = function () { var fields = []; var tmpMap = {}; var geometries = this.geometries; for (var i = 0; i < geometries.length; i++) { var geometry = geometries[i]; var groupFields = geometry.getGroupFields(); helper_1.uniq(groupFields, fields, tmpMap); } return fields; }; /** * 调整 scale 配置 * @private */ View.prototype.adjustScales = function () { // 调整目前包括: // 分类 scale,调整 range 范围 this.adjustCategoryScaleRange(); }; /** * 调整分类 scale 的 range,防止超出坐标系外面 * @private */ View.prototype.adjustCategoryScaleRange = function () { var _this = this; var xyScales = tslib_1.__spreadArrays([this.getXScale()], this.getYScales()).filter(function (e) { return !!e; }); var coordinate = this.getCoordinate(); var scaleOptions = this.options.scales; util_1.each(xyScales, function (scale) { var field = scale.field, values = scale.values, isCategory = scale.isCategory, isIdentity = scale.isIdentity; // 分类或者 identity 的 scale 才进行处理 if (isCategory || isIdentity) { // 存在 value 值,且用户没有配置 range 配置 if (values && !util_1.get(scaleOptions, [field, 'range'])) { var count = values.length; var range = void 0; if (count === 1) { range = [0.5, 1]; // 只有一个分类时,防止计算出现 [0.5,0.5] 的状态 } else { var widthRatio = 1; var offset = 0; if (coordinate_1.isFullCircle(coordinate)) { if (!coordinate.isTransposed) { range = [0, 1 - 1 / count]; } else { widthRatio = util_1.get(_this.theme, 'widthRatio.multiplePie', 1 / 1.3); offset = (1 / count) * widthRatio; range = [offset / 2, 1 - offset / 2]; } } else { offset = 1 / count / 2; // 两边留下分类空间的一半 range = [offset, 1 - offset]; // 坐标轴最前面和最后面留下空白防止绘制柱状图时 } } // 更新 range scale.range = range; } } }); }; /** * 根据 options 配置、Geometry 字段配置,自动生成 components * @param isUpdate 是否是更新 * @private */ View.prototype.initComponents = function (isUpdate) { // 先全部清空,然后 render var controllers = this.controllers; for (var i = 0; i < controllers.length; i++) { var controller = controllers[i]; // 更新则走更新逻辑;否则清空载重绘 if (isUpdate) { controller.update(); } else { controller.clear(); controller.render(); } } }; View.prototype.doLayout = function () { this.layoutFunc(this); }; /** * 创建坐标系 * @private */ View.prototype.createCoordinate = function () { var start = this.coordinateBBox.bl; var end = this.coordinateBBox.tr; this.coordinateInstance = this.coordinateController.create(start, end); }; /** * 根据 options 配置自动渲染 geometry * @private */ View.prototype.paintGeometries = function (isUpdate) { var doAnimation = this.options.animate; // geometry 的 paint 阶段 var coordinate = this.getCoordinate(); var canvasRegion = { x: this.viewBBox.x, y: this.viewBBox.y, minX: this.viewBBox.minX, minY: this.viewBBox.minY, maxX: this.viewBBox.maxX, maxY: this.viewBBox.maxY, width: this.viewBBox.width, height: this.viewBBox.height, }; var geometries = this.geometries; for (var i = 0; i < geometries.length; i++) { var geometry = geometries[i]; geometry.coordinate = coordinate; geometry.canvasRegion = canvasRegion; if (!doAnimation) { // 如果 view 不执行动画,那么 view 下所有的 geometry 都不执行动画 geometry.animate(false); } geometry.paint(isUpdate); } }; /** * 最后的绘制组件 * @param isUpdate */ View.prototype.renderComponents = function (isUpdate) { // 先全部清空,然后 render for (var i = 0; i < this.getComponents().length; i++) { var co = this.getComponents()[i]; co.component.render(); } }; /** * 渲染分面,会在其中进行数据分面,然后进行子 view 创建 * @param isUpdate */ View.prototype.renderFacet = function (isUpdate) { if (this.facetInstance) { if (isUpdate) { this.facetInstance.update(); } else { this.facetInstance.clear(); // 计算分面数据 this.facetInstance.init(); // 渲染组件和 views this.facetInstance.render(); } } }; View.prototype.initOptions = function () { var _a = this.options, _b = _a.geometries, geometries = _b === void 0 ? [] : _b, _c = _a.interactions, interactions = _c === void 0 ? [] : _c, _d = _a.views, views = _d === void 0 ? [] : _d, _e = _a.annotations, annotations = _e === void 0 ? [] : _e; // 创建 geometry 实例 for (var i = 0; i < geometries.length; i++) { var geometryOption = geometries[i]; this.createGeometry(geometryOption); } // 创建 interactions 实例 for (var j = 0; j < interactions.length; j++) { var interactionOption = interactions[j]; var type = interactionOption.type, cfg = interactionOption.cfg; this.interaction(type, cfg); } // 创建 view 实例 for (var k = 0; k < views.length; k++) { var viewOption = views[k]; this.createView(viewOption); } // 设置 annotation var annotationComponent = this.getController('annotation'); for (var l = 0; l < annotations.length; l++) { var annotationOption = annotations[l]; annotationComponent.annotation(annotationOption); } }; View.prototype.createGeometry = function (geometryOption) { var type = geometryOption.type, _a = geometryOption.cfg, cfg = _a === void 0 ? {} : _a; if (this[type]) { var geometry_1 = this[type](cfg); util_1.each(geometryOption, function (v, k) { if (util_1.isFunction(geometry_1[k])) { geometry_1[k](v); } }); } }; /** * scale key 的创建方式 * @param field */ View.prototype.getScaleKey = function (field) { return this.id + "-" + field; }; return View; }(base_1.default)); exports.View = View; /** * 注册 geometry 组件 * @param name * @param Ctor * @returns Geometry */ function registerGeometry(name, Ctor) { // 语法糖,在 view API 上增加原型方法 View.prototype[name.toLowerCase()] = function (cfg) { if (cfg === void 0) { cfg = {}; } var props = tslib_1.__assign({ /** 图形容器 */ container: this.middleGroup.addGroup(), labelsContainer: this.foregroundGroup.addGroup() }, cfg); var geometry = new Ctor(props); this.geometries.push(geometry); return geometry; }; } exports.registerGeometry = registerGeometry; exports.default = View; },{"../base":218,"../constant":237,"../facet":243,"../interaction":362,"../theme":365,"../util/bbox":370,"../util/coordinate":371,"../util/helper":377,"../util/padding":380,"../util/tooltip":383,"./controller":225,"./controller/coordinate":223,"./event":229,"./layout":232,"./util/scale-pool":234,"@antv/util":803,"tslib":385}],236:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var animate_1 = require("../animate"); var label_1 = require("../geometry/label"); var graphics_1 = require("../util/graphics"); var transform_1 = require("../util/transform"); /** * Geometry labels 渲染组件 */ var Labels = /** @class */ (function () { function Labels(cfg) { /** 存储当前 shape 的映射表,键值为 shape id */ this.shapesMap = {}; this.lastShapesMap = {}; var layout = cfg.layout, container = cfg.container; this.layout = layout; this.container = container; } /** * 渲染文本 */ Labels.prototype.render = function (items, shapes, isUpdate) { var _this = this; if (isUpdate === void 0) { isUpdate = false; } this.shapesMap = {}; var container = this.container; var offscreenGroup = this.createOffscreenGroup(); // 创建虚拟分组 if (items.length) { // 如果 items 空的话就不进行绘制调整操作 // step 1: 在虚拟 group 中创建 shapes for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { var item = items_1[_i]; if (item) { this.renderLabel(item, offscreenGroup); } } // step 2: 根据布局,调整 labels this.doLayout(items, shapes); // step 3: 绘制 labelLine this.renderLabelLine(items); // step 4: 根据用户设置的偏移量调整 label this.adjustLabel(items); } // 进行添加、更新、销毁操作 var lastShapesMap = this.lastShapesMap; var shapesMap = this.shapesMap; util_1.each(shapesMap, function (shape, id) { if (shape.destroyed) { // label 在布局调整环节被删除了(doLayout) delete shapesMap[id]; } else { if (lastShapesMap[id]) { // 图形发生更新 var data_1 = shape.get('data'); var origin_1 = shape.get('origin'); var coordinate_1 = shape.get('coordinate'); var currentShape = lastShapesMap[id]; // 已经在渲染树上的 shape var currentAnimateCfg_1 = shape.get('animateCfg'); currentShape.set('data', data_1); currentShape.set('origin', origin_1); currentShape.set('animateCfg', currentAnimateCfg_1); currentShape.set('coordinate', coordinate_1); var updateAnimateCfg_1 = util_1.get(currentAnimateCfg_1, 'update'); var currentChildren_1 = currentShape.getChildren(); shape.getChildren().map(function (child, index) { var currentChild = currentChildren_1[index]; currentChild.set('data', data_1); currentChild.set('origin', origin_1); currentChild.set('animateCfg', currentAnimateCfg_1); currentChild.set('coordinate', coordinate_1); var newAttrs = graphics_1.getReplaceAttrs(currentChild, child); if (updateAnimateCfg_1) { animate_1.doAnimate(currentChild, updateAnimateCfg_1, { toAttrs: newAttrs, coordinate: coordinate_1, }); } else { currentChild.attr(newAttrs); } }); _this.shapesMap[id] = currentShape; // 保存引用 } else { // 新生成的 shape container.add(shape); var animateCfg = util_1.get(shape.get('animateCfg'), isUpdate ? 'enter' : 'appear'); if (animateCfg) { animate_1.doAnimate(shape, animateCfg, { toAttrs: tslib_1.__assign({}, shape.attr()), coordinate: shape.get('coordinate'), }); } } delete lastShapesMap[id]; } }); // 移除 util_1.each(lastShapesMap, function (deleteShape) { var animateCfg = util_1.get(deleteShape.get('animateCfg'), 'leave'); if (animateCfg) { animate_1.doAnimate(deleteShape, animateCfg, { toAttrs: null, coordinate: deleteShape.get('coordinate'), }); } else { deleteShape.remove(true); // 移除 } }); this.lastShapesMap = shapesMap; offscreenGroup.destroy(); }; /** 清楚当前 labels */ Labels.prototype.clear = function () { this.container.clear(); this.shapesMap = {}; this.lastShapesMap = {}; }; /** 销毁 */ Labels.prototype.destroy = function () { this.container.destroy(); this.shapesMap = null; this.lastShapesMap = null; }; Labels.prototype.renderLabel = function (cfg, container) { var id = cfg.id, data = cfg.data, mappingData = cfg.mappingData, coordinate = cfg.coordinate, animate = cfg.animate, content = cfg.content; var shapeAppendCfg = { id: id, data: data, origin: mappingData, coordinate: coordinate, }; var labelGroup = container.addGroup(tslib_1.__assign({ name: 'label', // 如果 this.animate === false 或者 cfg.animate === false/null 则不进行动画,否则进行动画配置的合并 animateCfg: this.animate === false || animate === null || animate === false ? false : util_1.deepMix({}, this.animate, animate) }, shapeAppendCfg)); var labelShape; if ((content.isGroup && content.isGroup()) || (content.isShape && content.isShape())) { // 如果 content 是 Group 或者 Shape,根据 textAlign 调整位置后,直接将其加入 labelGroup var _a = content.getCanvasBBox(), width = _a.width, height = _a.height; var textAlign = util_1.get(cfg, 'textAlign', 'left'); var x = cfg.x; var y = cfg.y - height / 2; if (textAlign === 'center') { x = x - width / 2; } else if (textAlign === 'right' || textAlign === 'end') { x = x - width; } transform_1.translate(content, x, y); // 将 label 平移至 x, y 指定的位置 labelShape = content; labelGroup.add(content); } else { labelShape = labelGroup.addShape('text', tslib_1.__assign({ attrs: tslib_1.__assign({ x: cfg.x, y: cfg.y, textAlign: cfg.textAlign, textBaseline: util_1.get(cfg, 'textBaseline', 'middle'), text: cfg.content }, cfg.style) }, shapeAppendCfg)); } if (cfg.rotate) { transform_1.rotate(labelShape, cfg.rotate); } this.shapesMap[id] = labelGroup; }; // 根据type对label布局 Labels.prototype.doLayout = function (items, shapes) { var _this = this; if (this.layout) { var layouts = util_1.isArray(this.layout) ? this.layout : [this.layout]; util_1.each(layouts, function (layout) { var layoutFn = label_1.getGeometryLabelLayout(util_1.get(layout, 'type', '')); if (layoutFn) { var labelShapes_1 = []; var geometryShapes_1 = []; util_1.each(_this.shapesMap, function (labelShape, id) { labelShapes_1.push(labelShape); geometryShapes_1.push(shapes[id]); }); layoutFn(items, labelShapes_1, geometryShapes_1, _this.region, layout.cfg); } }); } }; Labels.prototype.renderLabelLine = function (labelItems) { var _this = this; util_1.each(labelItems, function (labelItem) { var coordinate = util_1.get(labelItem, 'coordinate'); if (!labelItem || !coordinate) { return; } var center = coordinate.getCenter(); var radius = coordinate.getRadius(); if (!labelItem.labelLine) { // labelLine: null | false,关闭 label 对应的 labelLine return; } var labelLineCfg = util_1.get(labelItem, 'labelLine', {}); var id = labelItem.id; var path = labelLineCfg.path; if (!path) { var start = graphics_1.polarToCartesian(center.x, center.y, radius, labelItem.angle); path = [ ['M', start.x, start.y], ['L', labelItem.x, labelItem.y], ]; } var labelGroup = _this.shapesMap[id]; if (!labelGroup.destroyed) { labelGroup.addShape('path', { capture: false, attrs: tslib_1.__assign({ path: path, stroke: labelItem.color ? labelItem.color : util_1.get(labelItem, ['style', 'fill'], '#000'), fill: null }, labelLineCfg.style), id: id, origin: labelItem.mappingData, data: labelItem.data, coordinate: labelItem.coordinate, }); } }); }; Labels.prototype.createOffscreenGroup = function () { var container = this.container; var GroupClass = container.getGroupBase(); // 获取分组的构造函数 var newGroup = new GroupClass({}); return newGroup; }; Labels.prototype.adjustLabel = function (items) { var _this = this; util_1.each(items, function (item) { if (item) { var id = item.id; var labelGroup = _this.shapesMap[id]; if (!labelGroup.destroyed) { var labelShape = labelGroup.find(function (ele) { return ele.get('type') === 'text'; }); if (labelShape) { if (item.offsetX) { labelShape.attr('x', labelShape.attr('x') + item.offsetX); } if (item.offsetY) { labelShape.attr('y', labelShape.attr('y') + item.offsetY); } } } } }); }; return Labels; }()); exports.default = Labels; },{"../animate":217,"../geometry/label":256,"../util/graphics":375,"../util/transform":384,"@antv/util":803,"tslib":385}],237:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.COMPONENT_MAX_VIEW_PERCENTAGE = exports.MIN_CHART_HEIGHT = exports.MIN_CHART_WIDTH = exports.FIELD_ORIGIN = exports.GROUP_ATTRS = exports.ELEMENT_STATE = exports.PLOT_EVENTS = exports.VIEW_LIFE_CIRCLE = exports.GROUP_Z_INDEX = exports.COMPONENT_TYPE = exports.DIRECTION = exports.LAYER = void 0; /** * view 中三层 group 分层 key */ var LAYER; (function (LAYER) { /** 前景层 */ LAYER["FORE"] = "fore"; /** 中间层 */ LAYER["MID"] = "mid"; /** 背景层 */ LAYER["BG"] = "bg"; })(LAYER = exports.LAYER || (exports.LAYER = {})); /** * 组件在画布的布局方位 12 方位 */ var DIRECTION; (function (DIRECTION) { DIRECTION["TOP"] = "top"; DIRECTION["TOP_LEFT"] = "top-left"; DIRECTION["TOP_RIGHT"] = "top-right"; DIRECTION["RIGHT"] = "right"; DIRECTION["RIGHT_TOP"] = "right-top"; DIRECTION["RIGHT_BOTTOM"] = "right-bottom"; DIRECTION["LEFT"] = "left"; DIRECTION["LEFT_TOP"] = "left-top"; DIRECTION["LEFT_BOTTOM"] = "left-bottom"; DIRECTION["BOTTOM"] = "bottom"; DIRECTION["BOTTOM_LEFT"] = "bottom-left"; DIRECTION["BOTTOM_RIGHT"] = "bottom-right"; DIRECTION["RADIUS"] = "radius"; DIRECTION["CIRCLE"] = "circle"; // no direction information DIRECTION["NONE"] = "none"; })(DIRECTION = exports.DIRECTION || (exports.DIRECTION = {})); /** * 组件的类型,可能会影响到布局算法 */ var COMPONENT_TYPE; (function (COMPONENT_TYPE) { /** axis 组件 */ COMPONENT_TYPE["AXIS"] = "axis"; /** grid 组件 */ COMPONENT_TYPE["GRID"] = "grid"; /** legend 组件 */ COMPONENT_TYPE["LEGEND"] = "legend"; /** tooltip 组件 */ COMPONENT_TYPE["TOOLTIP"] = "tooltip"; /** annotation 组件 */ COMPONENT_TYPE["ANNOTATION"] = "annotation"; /** 其他组件,自定义组件 */ COMPONENT_TYPE["OTHER"] = "other"; })(COMPONENT_TYPE = exports.COMPONENT_TYPE || (exports.COMPONENT_TYPE = {})); /** * 三层 group 的 z index */ exports.GROUP_Z_INDEX = { FORE: 3, MID: 2, BG: 1, }; /** * View 的生命周期阶段(和 3.x 的生命周期略有不同) * 我们需要先确定在那写场景需要用到生命周期,如果只是为了在生命周期插入一下什么组件之类的,那么在现有架构就是不需要的 */ var VIEW_LIFE_CIRCLE; (function (VIEW_LIFE_CIRCLE) { VIEW_LIFE_CIRCLE["BEFORE_RENDER"] = "beforerender"; VIEW_LIFE_CIRCLE["AFTER_RENDER"] = "afterrender"; VIEW_LIFE_CIRCLE["BEFORE_PAINT"] = "beforepaint"; VIEW_LIFE_CIRCLE["AFTER_PAINT"] = "afterpaint"; VIEW_LIFE_CIRCLE["BEFORE_CHANGE_DATA"] = "beforechangedata"; VIEW_LIFE_CIRCLE["AFTER_CHANGE_DATA"] = "afterchangedata"; VIEW_LIFE_CIRCLE["BEFORE_CLEAR"] = "beforeclear"; VIEW_LIFE_CIRCLE["AFTER_CLEAR"] = "afterclear"; VIEW_LIFE_CIRCLE["BEFORE_DESTROY"] = "beforedestroy"; })(VIEW_LIFE_CIRCLE = exports.VIEW_LIFE_CIRCLE || (exports.VIEW_LIFE_CIRCLE = {})); /** * 绘图区的事件列表 */ var PLOT_EVENTS; (function (PLOT_EVENTS) { // mouse 事件 PLOT_EVENTS["MOUSE_ENTER"] = "plot:mouseenter"; PLOT_EVENTS["MOUSE_DOWN"] = "plot:mousedown"; PLOT_EVENTS["MOUSE_MOVE"] = "plot:mousemove"; PLOT_EVENTS["MOUSE_UP"] = "plot:mouseup"; PLOT_EVENTS["MOUSE_LEAVE"] = "plot:mouseleave"; // 移动端事件 PLOT_EVENTS["TOUCH_START"] = "plot:touchstart"; PLOT_EVENTS["TOUCH_MOVE"] = "plot:touchmove"; PLOT_EVENTS["TOUCH_END"] = "plot:touchend"; PLOT_EVENTS["TOUCH_CANCEL"] = "plot:touchcancel"; // click 事件 PLOT_EVENTS["CLICK"] = "plot:click"; PLOT_EVENTS["DBLCLICK"] = "plot:dblclick"; PLOT_EVENTS["CONTEXTMENU"] = "plot:contextmenu"; PLOT_EVENTS["LEAVE"] = "plot:leave"; PLOT_EVENTS["ENTER"] = "plot:enter"; })(PLOT_EVENTS = exports.PLOT_EVENTS || (exports.PLOT_EVENTS = {})); /** * Element 图形交互状态 */ var ELEMENT_STATE; (function (ELEMENT_STATE) { ELEMENT_STATE["ACTIVE"] = "active"; ELEMENT_STATE["INACTIVE"] = "inactive"; ELEMENT_STATE["SELECTED"] = "selected"; ELEMENT_STATE["DEFAULT"] = "default"; })(ELEMENT_STATE = exports.ELEMENT_STATE || (exports.ELEMENT_STATE = {})); /** 参与分组的图形属性名 */ exports.GROUP_ATTRS = ['color', 'shape', 'size']; /** 存储原始数据的字段名 */ exports.FIELD_ORIGIN = '_origin'; /** 最小的图表宽度 */ exports.MIN_CHART_WIDTH = 1; /** 最小的图表高度 */ exports.MIN_CHART_HEIGHT = 1; /** 辅助组件占图表的尺寸的最大比例:如图表上方的图例最多占图表高度的25% */ exports.COMPONENT_MAX_VIEW_PERCENTAGE = 0.25; },{}],238:[function(require,module,exports){ "use strict"; /* G2 的一个壳子,不包含 Geometry,由开发者自己定义和引入 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Types = exports.VERSION = void 0; var tslib_1 = require("tslib"); exports.VERSION = '4.0.15'; // 核心基类导出 var chart_1 = require("./chart"); // Chart, View 类 Object.defineProperty(exports, "Chart", { enumerable: true, get: function () { return chart_1.Chart; } }); Object.defineProperty(exports, "View", { enumerable: true, get: function () { return chart_1.View; } }); Object.defineProperty(exports, "Event", { enumerable: true, get: function () { return chart_1.Event; } }); var base_1 = require("./chart/controller/base"); // G2 组件基类 Object.defineProperty(exports, "ComponentController", { enumerable: true, get: function () { return base_1.Controller; } }); var base_2 = require("./geometry/base"); // Geometry 基类 Object.defineProperty(exports, "Geometry", { enumerable: true, get: function () { return base_2.default; } }); var base_3 = require("./geometry/label/base"); // Geometry Label 基类 Object.defineProperty(exports, "GeometryLabel", { enumerable: true, get: function () { return base_3.default; } }); var interaction_1 = require("./interaction"); // Interaction 基类 Object.defineProperty(exports, "Interaction", { enumerable: true, get: function () { return interaction_1.Interaction; } }); var facet_1 = require("./facet"); // Facet 基类 Object.defineProperty(exports, "Facet", { enumerable: true, get: function () { return facet_1.Facet; } }); var base_4 = require("./interaction/action/base"); // Interaction Action 基类 Object.defineProperty(exports, "InteractionAction", { enumerable: true, get: function () { return base_4.default; } }); // 注册 ComponentController var chart_2 = require("./chart"); Object.defineProperty(exports, "registerComponentController", { enumerable: true, get: function () { return chart_2.registerComponentController; } }); // 注册 Geometry var chart_3 = require("./chart"); Object.defineProperty(exports, "registerGeometry", { enumerable: true, get: function () { return chart_3.registerGeometry; } }); // 注册 Geometry Shape var base_5 = require("./geometry/shape/base"); Object.defineProperty(exports, "registerShape", { enumerable: true, get: function () { return base_5.registerShape; } }); Object.defineProperty(exports, "registerShapeFactory", { enumerable: true, get: function () { return base_5.registerShapeFactory; } }); Object.defineProperty(exports, "getShapeFactory", { enumerable: true, get: function () { return base_5.getShapeFactory; } }); // 注册 Geometry label 以及 Geometry Label 布局函数 var label_1 = require("./geometry/label"); Object.defineProperty(exports, "registerGeometryLabel", { enumerable: true, get: function () { return label_1.registerGeometryLabel; } }); Object.defineProperty(exports, "registerGeometryLabelLayout", { enumerable: true, get: function () { return label_1.registerGeometryLabelLayout; } }); Object.defineProperty(exports, "getGeometryLabel", { enumerable: true, get: function () { return label_1.getGeometryLabel; } }); Object.defineProperty(exports, "getGeometryLabelLayout", { enumerable: true, get: function () { return label_1.getGeometryLabelLayout; } }); // 注册 interaction var interaction_2 = require("./interaction"); Object.defineProperty(exports, "getInteraction", { enumerable: true, get: function () { return interaction_2.getInteraction; } }); Object.defineProperty(exports, "registerInteraction", { enumerable: true, get: function () { return interaction_2.registerInteraction; } }); Object.defineProperty(exports, "registerAction", { enumerable: true, get: function () { return interaction_2.registerAction; } }); Object.defineProperty(exports, "getActionClass", { enumerable: true, get: function () { return interaction_2.getActionClass; } }); // 注册 facet var facet_2 = require("./facet"); Object.defineProperty(exports, "getFacet", { enumerable: true, get: function () { return facet_2.getFacet; } }); Object.defineProperty(exports, "registerFacet", { enumerable: true, get: function () { return facet_2.registerFacet; } }); // 注册主题 var theme_1 = require("./theme"); Object.defineProperty(exports, "getTheme", { enumerable: true, get: function () { return theme_1.getTheme; } }); Object.defineProperty(exports, "registerTheme", { enumerable: true, get: function () { return theme_1.registerTheme; } }); // G engine 管理相关 var engine_1 = require("./engine"); Object.defineProperty(exports, "registerEngine", { enumerable: true, get: function () { return engine_1.registerEngine; } }); Object.defineProperty(exports, "getEngine", { enumerable: true, get: function () { return engine_1.getEngine; } }); // 注册动画函数 var animation_1 = require("./animate/animation"); Object.defineProperty(exports, "registerAnimation", { enumerable: true, get: function () { return animation_1.registerAnimation; } }); Object.defineProperty(exports, "getAnimation", { enumerable: true, get: function () { return animation_1.getAnimation; } }); var constant_1 = require("./constant"); Object.defineProperty(exports, "LAYER", { enumerable: true, get: function () { return constant_1.LAYER; } }); Object.defineProperty(exports, "DIRECTION", { enumerable: true, get: function () { return constant_1.DIRECTION; } }); // 因为 typescript 部分版本不支持 export * as 语法。 var Types = tslib_1.__importStar(require("./interface")); exports.Types = Types; },{"./animate/animation":209,"./chart":230,"./chart/controller/base":222,"./constant":237,"./engine":240,"./facet":243,"./geometry/base":250,"./geometry/label":256,"./geometry/label/base":255,"./geometry/shape/base":275,"./interaction":362,"./interaction/action/base":311,"./interface":364,"./theme":365,"tslib":385}],239:[function(require,module,exports){ "use strict"; /* 依赖的模块,在这里统一引入,方便打包优化 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Slider = exports.HtmlTooltip = exports.ContinuousLegend = exports.CategoryLegend = exports.CircleGrid = exports.LineGrid = exports.CircleAxis = exports.LineAxis = exports.Annotation = exports.Crosshair = exports.Component = exports.GroupComponent = exports.HtmlComponent = void 0; var g_base_1 = require("@antv/g-base"); Object.defineProperty(exports, "Event", { enumerable: true, get: function () { return g_base_1.Event; } }); Object.defineProperty(exports, "AbstractGroup", { enumerable: true, get: function () { return g_base_1.AbstractGroup; } }); Object.defineProperty(exports, "AbstractShape", { enumerable: true, get: function () { return g_base_1.AbstractShape; } }); // adjust var factory_1 = require("@antv/adjust/lib/factory"); Object.defineProperty(exports, "registerAdjust", { enumerable: true, get: function () { return factory_1.registerAdjust; } }); Object.defineProperty(exports, "getAdjust", { enumerable: true, get: function () { return factory_1.getAdjust; } }); Object.defineProperty(exports, "Adjust", { enumerable: true, get: function () { return factory_1.Adjust; } }); // attr var factory_2 = require("@antv/attr/lib/factory"); Object.defineProperty(exports, "getAttribute", { enumerable: true, get: function () { return factory_2.getAttribute; } }); Object.defineProperty(exports, "Attribute", { enumerable: true, get: function () { return factory_2.Attribute; } }); var attr_1 = require("@antv/attr"); Object.defineProperty(exports, "Color", { enumerable: true, get: function () { return attr_1.Color; } }); // coordinate var coord_1 = require("@antv/coord"); Object.defineProperty(exports, "getCoordinate", { enumerable: true, get: function () { return coord_1.getCoordinate; } }); Object.defineProperty(exports, "registerCoordinate", { enumerable: true, get: function () { return coord_1.registerCoordinate; } }); Object.defineProperty(exports, "Coordinate", { enumerable: true, get: function () { return coord_1.Coordinate; } }); // scale var scale_1 = require("@antv/scale"); Object.defineProperty(exports, "getScale", { enumerable: true, get: function () { return scale_1.getScale; } }); Object.defineProperty(exports, "registerScale", { enumerable: true, get: function () { return scale_1.registerScale; } }); Object.defineProperty(exports, "Scale", { enumerable: true, get: function () { return scale_1.Scale; } }); // component var component_1 = require("@antv/component"); Object.defineProperty(exports, "Annotation", { enumerable: true, get: function () { return component_1.Annotation; } }); Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return component_1.Component; } }); Object.defineProperty(exports, "Crosshair", { enumerable: true, get: function () { return component_1.Crosshair; } }); Object.defineProperty(exports, "GroupComponent", { enumerable: true, get: function () { return component_1.GroupComponent; } }); Object.defineProperty(exports, "HtmlComponent", { enumerable: true, get: function () { return component_1.HtmlComponent; } }); Object.defineProperty(exports, "Slider", { enumerable: true, get: function () { return component_1.Slider; } }); // axis var LineAxis = component_1.Axis.Line, CircleAxis = component_1.Axis.Circle; exports.LineAxis = LineAxis; exports.CircleAxis = CircleAxis; // grid var LineGrid = component_1.Grid.Line, CircleGrid = component_1.Grid.Circle; exports.LineGrid = LineGrid; exports.CircleGrid = CircleGrid; // legend var CategoryLegend = component_1.Legend.Category, ContinuousLegend = component_1.Legend.Continuous; exports.CategoryLegend = CategoryLegend; exports.ContinuousLegend = ContinuousLegend; // Tooltip var HtmlTooltip = component_1.Tooltip.Html; exports.HtmlTooltip = HtmlTooltip; },{"@antv/adjust/lib/factory":8,"@antv/attr":17,"@antv/attr/lib/factory":16,"@antv/component":51,"@antv/coord":83,"@antv/g-base":115,"@antv/scale":747}],240:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerEngine = exports.getEngine = void 0; var ENGINES = {}; /** * 通过名字获取渲染 engine * @param name 渲染引擎名字 * @returns G engine */ function getEngine(name) { var G = ENGINES[name]; if (!G) { throw new Error("G engine '" + name + "' is not exist, please register it at first."); } return G; } exports.getEngine = getEngine; /** * 注册渲染引擎 * @param name * @param engine */ function registerEngine(name, engine) { ENGINES[name] = engine; } exports.registerEngine = registerEngine; },{}],241:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var facet_1 = require("../util/facet"); var facet_2 = require("./facet"); /** * @ignore * 镜像分面 */ var Circle = /** @class */ (function (_super) { tslib_1.__extends(Circle, _super); function Circle() { return _super !== null && _super.apply(this, arguments) || this; } Circle.prototype.getDefaultCfg = function () { return util_1.deepMix({}, _super.prototype.getDefaultCfg.call(this), { type: 'circle', showTitle: true, title: _super.prototype.getDefaultTitleCfg.call(this), }); }; Circle.prototype.render = function () { _super.prototype.render.call(this); if (this.cfg.showTitle) { this.renderTitle(); } }; /** * 根据总数和当前索引,计算分面的 region * @param count * @param index */ Circle.prototype.getRegion = function (count, index) { var r = 1 / 2; // 画布半径 // 画布圆心 var center = { x: 0.5, y: 0.5 }; // 每隔分面间隔的弧度 var avgAngle = (Math.PI * 2) / count; // 当前分面所在的弧度 var angle = (-1 * Math.PI) / 2 + avgAngle * index; // TODO 没看懂 var facetR = r / (1 + 1 / Math.sin(avgAngle / 2)); // 分面的中心点 var middle = facet_1.getAnglePoint(center, r - facetR, angle); var startAngle = (Math.PI * 5) / 4; // 右上角 var endAngle = (Math.PI * 1) / 4; // 左下角 return { start: facet_1.getAnglePoint(middle, facetR, startAngle), end: facet_1.getAnglePoint(middle, facetR, endAngle), }; }; Circle.prototype.afterEachView = function (view, facet) { this.processAxis(view, facet); }; Circle.prototype.beforeEachView = function (view, facet) { }; Circle.prototype.generateFacets = function (data) { var _this = this; var _a = this.cfg, fields = _a.fields, type = _a.type; var field = fields[0]; if (!field) { throw new Error('No `fields` specified!'); } var values = this.getFieldValues(data, field); var count = values.length; var rst = []; values.forEach(function (value, index) { var conditions = [{ field: field, value: value, values: values }]; var facetData = util_1.filter(data, _this.getFacetDataFilter(conditions)); var facet = { type: type, data: facetData, region: _this.getRegion(count, index), columnValue: value, columnField: field, columnIndex: index, columnValuesLength: count, rowValue: null, rowField: null, rowIndex: 0, rowValuesLength: 1, }; rst.push(facet); }); return rst; }; Circle.prototype.getXAxisOption = function (x, axes, option, facet) { // 不做任何处理 return option; }; /** * 设置 y 坐标轴的文本、title 是否显示 * @param y * @param axes * @param option * @param facet */ Circle.prototype.getYAxisOption = function (y, axes, option, facet) { // 不做任何处理 return option; }; /** * facet title */ Circle.prototype.renderTitle = function () { var _this = this; util_1.each(this.facets, function (facet) { var columnValue = facet.columnValue, view = facet.view; var formatter = util_1.get(_this.cfg.title, 'formatter'); var config = util_1.deepMix({ position: ['50%', '0%'], content: formatter ? formatter(columnValue) : columnValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.TOP), _this.cfg.title); view.annotation().text(config); }); }; return Circle; }(facet_2.Facet)); exports.default = Circle; },{"../constant":237,"../util/facet":374,"./facet":242,"@antv/util":803,"tslib":385}],242:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Facet = void 0; var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var axis_1 = require("../util/axis"); /** * facet 基类 * - 定义生命周期,方便自定义 facet * - 提供基础的生命流程方法 * * 生命周期: * * 初始化 init * 1. 初始化容器 * 2. 数据分面,生成分面布局信息 * * 渲染阶段 render * 1. view 创建 * 2. title * 3. axis * * 清除阶段 clear * 1. 清除 view * * 销毁阶段 destroy * 1. clear * 2. 清除事件 * 3. 清除 group */ var Facet = /** @class */ (function () { function Facet(view, cfg) { /** 是否销毁 */ this.destroyed = false; /** 分面之后的所有分面数据结构 */ this.facets = []; this.view = view; this.cfg = util_1.deepMix({}, this.getDefaultCfg(), cfg); } /** * 初始化过程 */ Facet.prototype.init = function () { // 初始化容器 if (!this.container) { this.container = this.createContainer(); } // 生成分面布局信息 var data = this.view.getData(); this.facets = this.generateFacets(data); }; /** * 渲染分面,由上层 view 调用。包括: * - 分面 view * - 轴 * - title * * 子类可以复写,添加一些其他组件,比如滚动条等 */ Facet.prototype.render = function () { this.renderViews(); }; /** * 更新 facet */ Facet.prototype.update = function () { // 其实不用做任何事情,因为 facet 最终生成的 View 和 Geometry 都在父 view 的更新中处理了 }; /** * 清空,clear 之后如果还需要使用,需要重新调用 init 初始化过程 * 一般在数据有变更的时候调用,重新进行数据的分面逻辑 */ Facet.prototype.clear = function () { this.clearFacetViews(); }; /** * 销毁 */ Facet.prototype.destroy = function () { this.clear(); if (this.container) { this.container.remove(true); this.container = undefined; } this.destroyed = true; this.view = undefined; this.facets = []; }; /** * 根据 facet 生成 view,可以给上层自定义使用 * @param facet */ Facet.prototype.facetToView = function (facet) { var region = facet.region, data = facet.data, _a = facet.padding, padding = _a === void 0 ? this.cfg.padding : _a; var view = this.view.createView({ region: region, padding: padding, }); // 设置分面的数据 view.data(data || []); facet.view = view; // 前置钩子 this.beforeEachView(view, facet); var eachView = this.cfg.eachView; if (eachView) { eachView(view, facet); } // 后置钩子 this.afterEachView(view, facet); return view; }; // 创建容器 Facet.prototype.createContainer = function () { var foregroundGroup = this.view.getLayer(constant_1.LAYER.FORE); return foregroundGroup.addGroup(); }; /** * 初始化 view */ Facet.prototype.renderViews = function () { this.createFacetViews(); }; /** * 创建 分面 view */ Facet.prototype.createFacetViews = function () { var _this = this; // 使用分面数据 创建分面 view return this.facets.map(function (facet) { return _this.facetToView(facet); }); }; /** * 从 view 中清除 facetView */ Facet.prototype.clearFacetViews = function () { var _this = this; // 从 view 中移除分面 view util_1.each(this.facets, function (facet) { if (facet.view) { _this.view.removeView(facet.view); facet.view = undefined; } }); }; // 其他一些提供给子类使用的方法 /** * 获取这个字段对应的所有值,数组 * @protected * @param data 数据 * @param field 字段名 * @return 字段对应的值 */ Facet.prototype.getFieldValues = function (data, field) { var rst = []; var cache = {}; // 去重、去除 Nil 值 util_1.each(data, function (d) { var value = d[field]; if (!util_1.isNil(value) && !cache[value]) { rst.push(value); cache[value] = true; } }); return rst; }; /** * 获得每个分面的 region,平分区域 * @param rows row 总数 * @param cols col 总数 * @param xIndex x 方向 index * @param yIndex y 方向 index */ Facet.prototype.getRegion = function (rows, cols, xIndex, yIndex) { // x, y 方向均分 100% 宽高 var xRatio = 1 / (cols === 0 ? 1 : cols); var yRatio = 1 / (rows === 0 ? 1 : rows); var start = { x: xRatio * xIndex, y: yRatio * yIndex, }; var end = { x: xRatio * (xIndex + 1), y: yRatio * (yIndex + 1), }; return { start: start, end: end, }; }; Facet.prototype.getDefaultCfg = function () { return { eachView: undefined, showTitle: true, padding: 10, fields: [], }; }; /** * 默认的 title 样式,因为有的分面是 title,有的分面配置是 columnTitle、rowTitle */ Facet.prototype.getDefaultTitleCfg = function () { // @ts-ignore var fontFamily = this.view.getTheme().fontFamily; return { style: { fontSize: 14, fill: '#666', fontFamily: fontFamily, }, }; }; /** * 处理 axis 的默认配置 * @param view * @param facet */ Facet.prototype.processAxis = function (view, facet) { var options = view.getOptions(); var coordinateOption = options.coordinate; var geometries = view.geometries; var coordinateType = util_1.get(coordinateOption, 'type', 'rect'); if (coordinateType === 'rect' && geometries.length) { if (util_1.isNil(options.axes)) { // @ts-ignore options.axes = {}; } var axes = options.axes; var _a = geometries[0].getXYFields(), x = _a[0], y = _a[1]; var xOption = axis_1.getAxisOption(axes, x); var yOption = axis_1.getAxisOption(axes, y); if (xOption !== false) { options.axes[x] = this.getXAxisOption(x, axes, xOption, facet); } if (yOption !== false) { options.axes[y] = this.getYAxisOption(y, axes, yOption, facet); } } }; /** * 获取分面数据 * @param conditions */ Facet.prototype.getFacetDataFilter = function (conditions) { return function (datum) { // 过滤出全部满足条件的数据 return util_1.every(conditions, function (condition) { var field = condition.field, value = condition.value; if (!util_1.isNil(value) && field) { return datum[field] === value; } return true; }); }; }; return Facet; }()); exports.Facet = Facet; },{"../constant":237,"../util/axis":369,"@antv/util":803}],243:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerFacet = exports.getFacet = void 0; var util_1 = require("@antv/util"); var facet_1 = require("./facet"); Object.defineProperty(exports, "Facet", { enumerable: true, get: function () { return facet_1.Facet; } }); /** * 所有的 Facet 类 */ var Facets = {}; /** * 根据 type 获取 facet 类 * @param type 分面类型 */ exports.getFacet = function (type) { return Facets[util_1.lowerCase(type)]; }; /** * 注册一个 Facet 类 * @param type 分面类型 * @param ctor 分面类 */ exports.registerFacet = function (type, ctor) { Facets[util_1.lowerCase(type)] = ctor; }; },{"./facet":242,"@antv/util":803}],244:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var facet_1 = require("../util/facet"); var facet_2 = require("./facet"); /** * @ignore * 镜像分面 */ var List = /** @class */ (function (_super) { tslib_1.__extends(List, _super); function List() { return _super !== null && _super.apply(this, arguments) || this; } List.prototype.getDefaultCfg = function () { return util_1.deepMix({}, _super.prototype.getDefaultCfg.call(this), { type: 'list', cols: null, showTitle: true, title: _super.prototype.getDefaultTitleCfg.call(this), }); }; List.prototype.render = function () { _super.prototype.render.call(this); if (this.cfg.showTitle) { this.renderTitle(); } }; List.prototype.afterEachView = function (view, facet) { this.processAxis(view, facet); }; List.prototype.beforeEachView = function (view, facet) { }; List.prototype.generateFacets = function (data) { var _this = this; var fields = this.cfg.fields; var cols = this.cfg.cols; var columnField = fields[0]; if (!columnField) { throw new Error('No `fields` specified!'); } var colValues = this.getFieldValues(data, columnField); var count = colValues.length; cols = cols || count; // 每行有几列数据 // 总共有几行 var rows = this.getPageCount(count, cols); var rst = []; colValues.forEach(function (val, index) { // 当前 index 在那个行列 var _a = _this.getRowCol(index, cols), row = _a.row, col = _a.col; var conditions = [{ field: columnField, value: val, values: colValues }]; var facetData = util_1.filter(data, _this.getFacetDataFilter(conditions)); var facet = { type: _this.cfg.type, data: facetData, region: _this.getRegion(rows, cols, col, row), columnValue: val, rowValue: val, columnField: columnField, rowField: null, columnIndex: col, rowIndex: row, columnValuesLength: cols, rowValuesLength: rows, total: count, }; rst.push(facet); }); return rst; }; /** * 设置 x 坐标轴的文本、title 是否显示 * @param x * @param axes * @param option * @param facet */ List.prototype.getXAxisOption = function (x, axes, option, facet) { // 当是最后一行或者下面没有 view 时文本不显示 if (facet.rowIndex !== facet.rowValuesLength - 1 && facet.columnValuesLength * facet.rowIndex + facet.columnIndex + 1 + facet.columnValuesLength <= facet.total) { return tslib_1.__assign(tslib_1.__assign({}, option), { label: null, title: null }); } return option; }; /** * 设置 y 坐标轴的文本、title 是否显示 * @param y * @param axes * @param option * @param facet */ List.prototype.getYAxisOption = function (y, axes, option, facet) { if (facet.columnIndex !== 0) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null, label: null }); } return option; }; /** * facet title */ List.prototype.renderTitle = function () { var _this = this; util_1.each(this.facets, function (facet) { var columnValue = facet.columnValue, view = facet.view; var formatter = util_1.get(_this.cfg.title, 'formatter'); var config = util_1.deepMix({ position: ['50%', '0%'], content: formatter ? formatter(columnValue) : columnValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.TOP), _this.cfg.title); view.annotation().text(config); }); }; /** * 计算分页数 * @param total * @param pageSize */ List.prototype.getPageCount = function (total, pageSize) { return Math.floor((total + pageSize - 1) / pageSize); }; /** * 索引值在哪一页 * @param index * @param pageSize */ List.prototype.getRowCol = function (index, pageSize) { var row = Math.floor(index / pageSize); var col = index % pageSize; return { row: row, col: col }; }; return List; }(facet_2.Facet)); exports.default = List; },{"../constant":237,"../util/facet":374,"./facet":242,"@antv/util":803,"tslib":385}],245:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var facet_1 = require("../util/facet"); var facet_2 = require("./facet"); /** * @ignore * 镜像分面 */ var Matrix = /** @class */ (function (_super) { tslib_1.__extends(Matrix, _super); function Matrix() { return _super !== null && _super.apply(this, arguments) || this; } Matrix.prototype.getDefaultCfg = function () { return util_1.deepMix({}, _super.prototype.getDefaultCfg.call(this), { type: 'matrix', showTitle: false, columnTitle: tslib_1.__assign({}, _super.prototype.getDefaultTitleCfg.call(this)), rowTitle: tslib_1.__assign({}, _super.prototype.getDefaultTitleCfg.call(this)), }); }; Matrix.prototype.render = function () { _super.prototype.render.call(this); if (this.cfg.showTitle) { this.renderTitle(); } }; Matrix.prototype.afterEachView = function (view, facet) { this.processAxis(view, facet); }; Matrix.prototype.beforeEachView = function (view, facet) { }; Matrix.prototype.generateFacets = function (data) { var _a = this.cfg, fields = _a.fields, type = _a.type; // 矩阵中行列相等,等于指定的字段个数 var rowValuesLength = fields.length; var columnValuesLength = rowValuesLength; var rst = []; for (var i = 0; i < columnValuesLength; i++) { var columnField = fields[i]; for (var j = 0; j < rowValuesLength; j++) { var rowField = fields[j]; var facet = { type: type, data: data, region: this.getRegion(rowValuesLength, columnValuesLength, i, j), columnValue: columnField, rowValue: rowField, columnField: columnField, rowField: rowField, columnIndex: i, rowIndex: j, columnValuesLength: columnValuesLength, rowValuesLength: rowValuesLength, }; rst.push(facet); } } return rst; }; /** * 设置 x 坐标轴的文本、title 是否显示 * @param x * @param axes * @param option * @param facet */ Matrix.prototype.getXAxisOption = function (x, axes, option, facet) { // 最后一行显示 if (facet.rowIndex !== facet.rowValuesLength - 1) { return tslib_1.__assign(tslib_1.__assign({}, option), { label: null, title: null }); } return option; }; /** * 设置 y 坐标轴的文本、title 是否显示 * @param y * @param axes * @param option * @param facet */ Matrix.prototype.getYAxisOption = function (y, axes, option, facet) { // 第一列显示 if (facet.columnIndex !== 0) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null, label: null }); } return option; }; /** * facet title */ Matrix.prototype.renderTitle = function () { var _this = this; util_1.each(this.facets, function (facet, facetIndex) { var columnIndex = facet.columnIndex, rowIndex = facet.rowIndex, columnValuesLength = facet.columnValuesLength, rowValuesLength = facet.rowValuesLength, columnValue = facet.columnValue, rowValue = facet.rowValue, view = facet.view; // top if (rowIndex === 0) { var formatter = util_1.get(_this.cfg.columnTitle, 'formatter'); var config = util_1.deepMix({ position: ['50%', '0%'], content: formatter ? formatter(columnValue) : columnValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.TOP), _this.cfg.columnTitle); view.annotation().text(config); } // right if (columnIndex === columnValuesLength - 1) { var formatter = util_1.get(_this.cfg.rowTitle, 'formatter'); var config = util_1.deepMix({ position: ['100%', '50%'], content: formatter ? formatter(rowValue) : rowValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.RIGHT), _this.cfg.rowTitle); view.annotation().text(config); } }); }; return Matrix; }(facet_2.Facet)); exports.default = Matrix; },{"../constant":237,"../util/facet":374,"./facet":242,"@antv/util":803,"tslib":385}],246:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var facet_1 = require("../util/facet"); var facet_2 = require("./facet"); /** * @ignore * 镜像分面 */ var Mirror = /** @class */ (function (_super) { tslib_1.__extends(Mirror, _super); function Mirror() { return _super !== null && _super.apply(this, arguments) || this; } Mirror.prototype.getDefaultCfg = function () { return util_1.deepMix({}, _super.prototype.getDefaultCfg.call(this), { type: 'mirror', showTitle: true, title: _super.prototype.getDefaultTitleCfg.call(this), transpose: false, }); }; Mirror.prototype.render = function () { _super.prototype.render.call(this); if (this.cfg.showTitle) { this.renderTitle(); } }; Mirror.prototype.beforeEachView = function (view, facet) { // 做一下坐标系转化 if (this.cfg.transpose) { if (facet.columnIndex % 2 === 0) { view.coordinate().transpose().reflect('x'); } else { view.coordinate().transpose(); } } else { if (facet.rowIndex % 2 !== 0) { view.coordinate().reflect('y'); } } }; Mirror.prototype.afterEachView = function (view, facet) { this.processAxis(view, facet); }; Mirror.prototype.generateFacets = function (data) { var _this = this; var f = this.cfg.fields[0]; var rst = []; var columnValuesLength = 1; var rowValuesLength = 1; var columnValues = ['']; var rowValues = ['']; var columnField; var rowField; if (this.cfg.transpose) { columnField = f; columnValues = this.getFieldValues(data, columnField).slice(0, 2); // 镜像最多两个 columnValuesLength = columnValues.length; } else { rowField = f; rowValues = this.getFieldValues(data, rowField).slice(0, 2); // 镜像最多两个 rowValuesLength = rowValues.length; } // 获取每个维度对应的数据配置片段 columnValues.forEach(function (xVal, xIndex) { rowValues.forEach(function (yVal, yIndex) { var conditions = [ { field: columnField, value: xVal, values: columnValues }, { field: rowField, value: yVal, values: rowValues }, ]; var facetData = util_1.filter(data, _this.getFacetDataFilter(conditions)); var facet = { type: _this.cfg.type, data: facetData, region: _this.getRegion(rowValuesLength, columnValuesLength, xIndex, yIndex), columnValue: xVal, rowValue: yVal, columnField: columnField, rowField: rowField, columnIndex: xIndex, rowIndex: yIndex, columnValuesLength: columnValuesLength, rowValuesLength: rowValuesLength, }; rst.push(facet); }); }); return rst; }; /** * 设置 x 坐标轴的文本、title 是否显示 * @param x * @param axes * @param option * @param facet */ Mirror.prototype.getXAxisOption = function (x, axes, option, facet) { // 非最后一行 // 当是最后一行或者下面没有 view 时文本不显示 if (facet.columnIndex === 1 || facet.rowIndex === 1) { return tslib_1.__assign(tslib_1.__assign({}, option), { label: null, title: null }); } return option; }; /** * 设置 y 坐标轴的文本、title 是否显示 * @param y * @param axes * @param option * @param facet */ Mirror.prototype.getYAxisOption = function (y, axes, option, facet) { // do nothing return option; }; Mirror.prototype.renderTitle = function () { var _this = this; util_1.each(this.facets, function (facet, facetIndex) { var columnValue = facet.columnValue, rowValue = facet.rowValue, view = facet.view; var formatter = util_1.get(_this.cfg.title, 'formatter'); if (_this.cfg.transpose) { var config = util_1.deepMix({ position: ['50%', '0%'], content: formatter ? formatter(columnValue) : columnValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.TOP), _this.cfg.title); view.annotation().text(config); } else { var config = util_1.deepMix({ position: ['100%', '50%'], content: formatter ? formatter(rowValue) : rowValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.RIGHT), _this.cfg.title); view.annotation().text(config); } }); }; return Mirror; }(facet_2.Facet)); exports.default = Mirror; },{"../constant":237,"../util/facet":374,"./facet":242,"@antv/util":803,"tslib":385}],247:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var facet_1 = require("../util/facet"); var facet_2 = require("./facet"); /** * @ignore * 矩阵分面 */ var Rect = /** @class */ (function (_super) { tslib_1.__extends(Rect, _super); function Rect() { return _super !== null && _super.apply(this, arguments) || this; } Rect.prototype.afterEachView = function (view, facet) { this.processAxis(view, facet); }; Rect.prototype.beforeEachView = function (view, facet) { // do nothing }; Rect.prototype.getDefaultCfg = function () { return util_1.deepMix({}, _super.prototype.getDefaultCfg.call(this), { type: 'rect', columnTitle: tslib_1.__assign({}, _super.prototype.getDefaultTitleCfg.call(this)), rowTitle: tslib_1.__assign({}, _super.prototype.getDefaultTitleCfg.call(this)), }); }; Rect.prototype.render = function () { _super.prototype.render.call(this); if (this.cfg.showTitle) { this.renderTitle(); } }; /** * 生成矩阵分面的分面数据 * @param data */ Rect.prototype.generateFacets = function (data) { var _this = this; var _a = this.cfg.fields, columnField = _a[0], rowField = _a[1]; var rst = []; var columnValuesLength = 1; var rowValuesLength = 1; var columnValues = ['']; var rowValues = ['']; if (columnField) { columnValues = this.getFieldValues(data, columnField); columnValuesLength = columnValues.length; } if (rowField) { rowValues = this.getFieldValues(data, rowField); rowValuesLength = rowValues.length; } // 获取每个维度对应的数据配置片段 columnValues.forEach(function (xVal, xIndex) { rowValues.forEach(function (yVal, yIndex) { var conditions = [ { field: columnField, value: xVal, values: columnValues }, { field: rowField, value: yVal, values: rowValues }, ]; var facetData = util_1.filter(data, _this.getFacetDataFilter(conditions)); var facet = { type: _this.cfg.type, data: facetData, region: _this.getRegion(rowValuesLength, columnValuesLength, xIndex, yIndex), columnValue: xVal, rowValue: yVal, columnField: columnField, rowField: rowField, columnIndex: xIndex, rowIndex: yIndex, columnValuesLength: columnValuesLength, rowValuesLength: rowValuesLength, }; rst.push(facet); }); }); return rst; }; Rect.prototype.renderTitle = function () { var _this = this; util_1.each(this.facets, function (facet, facetIndex) { var columnIndex = facet.columnIndex, rowIndex = facet.rowIndex, columnValuesLength = facet.columnValuesLength, columnValue = facet.columnValue, rowValue = facet.rowValue, view = facet.view; // top if (rowIndex === 0) { var formatter = util_1.get(_this.cfg.columnTitle, 'formatter'); var config = util_1.deepMix({ position: ['50%', '0%'], content: formatter ? formatter(columnValue) : columnValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.TOP), _this.cfg.columnTitle); view.annotation().text(config); } // right if (columnIndex === columnValuesLength - 1) { var formatter = util_1.get(_this.cfg.rowTitle, 'formatter'); var config = util_1.deepMix({ position: ['100%', '50%'], content: formatter ? formatter(rowValue) : rowValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.RIGHT), _this.cfg.rowTitle); view.annotation().text(config); } }); }; /** * 设置 x 坐标轴的文本、title 是否显示 * @param x * @param axes * @param option * @param facet */ Rect.prototype.getXAxisOption = function (x, axes, option, facet) { // 非最后一行 if (facet.rowIndex !== facet.rowValuesLength - 1) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null, label: null }); } else if (facet.columnIndex !== Math.floor((facet.columnValuesLength - 1) / 2)) { // 不是中间列 return tslib_1.__assign(tslib_1.__assign({}, option), { title: null }); } return option; }; /** * 设置 y 坐标轴的文本、title 是否显示 * @param y * @param axes * @param option * @param facet */ Rect.prototype.getYAxisOption = function (y, axes, option, facet) { if (facet.columnIndex !== 0) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null, label: null }); } else if (facet.rowIndex !== Math.floor((facet.rowValuesLength - 1) / 2)) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null }); } return option; }; return Rect; }(facet_2.Facet)); exports.default = Rect; },{"../constant":237,"../util/facet":374,"./facet":242,"@antv/util":803,"tslib":385}],248:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-10 */ var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var facet_1 = require("../util/facet"); var facet_2 = require("./facet"); /** * @ignore * Tree Facet */ var Tree = /** @class */ (function (_super) { tslib_1.__extends(Tree, _super); function Tree() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.afterChartRender = function () { if (_this.facets && _this.cfg.line) { _this.container.clear(); _this.drawLines(_this.facets); } }; return _this; } Tree.prototype.afterEachView = function (view, facet) { this.processAxis(view, facet); }; Tree.prototype.beforeEachView = function (view, facet) { }; Tree.prototype.init = function () { _super.prototype.init.call(this); this.view.on(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, this.afterChartRender); }; Tree.prototype.getDefaultCfg = function () { return util_1.deepMix({}, _super.prototype.getDefaultCfg.call(this), { type: 'tree', line: { style: { lineWidth: 1, stroke: '#ddd', }, smooth: false, }, showTitle: true, title: _super.prototype.getDefaultTitleCfg.call(this), }); }; Tree.prototype.generateFacets = function (data) { var fields = this.cfg.fields; if (!fields.length) { throw new Error('Please specify for the fields for rootFacet!'); } var rst = []; var rootFacet = { type: this.cfg.type, data: data, region: null, rowValuesLength: this.getRows(), columnValuesLength: 1, rowIndex: 0, columnIndex: 0, rowField: '', columnField: '', rowValue: '', columnValue: '', }; rst.push(rootFacet); rootFacet.children = this.getChildFacets(data, 1, rst); this.setRegion(rst); return rst; }; Tree.prototype.setRegion = function (facets) { var _this = this; this.forceColIndex(facets); facets.forEach(function (facet) { // @ts-ignore 允许调整 facet.region = _this.getRegion(facet.rowValuesLength, facet.columnValuesLength, facet.columnIndex, facet.rowIndex); }); }; Tree.prototype.getRegion = function (rows, cols, xIndex, yIndex) { var xWidth = 1 / cols; // x轴方向的每个分面的偏移 var yWidth = 1 / rows; // y轴方向的每个分面的偏移 var start = { x: xWidth * xIndex, y: yWidth * yIndex, }; var end = { x: start.x + xWidth, y: start.y + (yWidth * 2) / 3, }; return { start: start, end: end, }; }; Tree.prototype.forceColIndex = function (facets) { var _this = this; var leafs = []; var index = 0; facets.forEach(function (facet) { if (_this.isLeaf(facet)) { leafs.push(facet); // @ts-ignore 允许调整 facet.columnIndex = index; index++; } }); leafs.forEach(function (facet) { // @ts-ignore facet.columnValuesLength = leafs.length; }); var maxLevel = this.cfg.fields.length; for (var i = maxLevel - 1; i >= 0; i--) { var levelFacets = this.getFacetsByLevel(facets, i); // var yIndex = maxLevel - i; for (var _i = 0, levelFacets_1 = levelFacets; _i < levelFacets_1.length; _i++) { var facet = levelFacets_1[_i]; if (!this.isLeaf(facet)) { facet.originColIndex = facet.columnIndex; // @ts-ignore facet.columnIndex = this.getRegionIndex(facet.children); // @ts-ignore facet.columnValuesLength = leafs.length; } } } }; // get facet use level Tree.prototype.getFacetsByLevel = function (facets, level) { var rst = []; facets.forEach(function (facet) { if (facet.rowIndex === level) { rst.push(facet); } }); return rst; }; // if the facet has children , make it's column index in the middle of it's children Tree.prototype.getRegionIndex = function (children) { var first = children[0]; var last = children[children.length - 1]; return (last.columnIndex - first.columnIndex) / 2 + first.columnIndex; }; // is a leaf without children Tree.prototype.isLeaf = function (facet) { return !facet.children || !facet.children.length; }; Tree.prototype.getRows = function () { return this.cfg.fields.length + 1; }; // get child Tree.prototype.getChildFacets = function (data, level, arr) { var _this = this; // [ 'grade', 'class' ] var fields = this.cfg.fields; var length = fields.length; if (length < level) { return; } var rst = []; // get fist level except root node var field = fields[level - 1]; // get field value var values = this.getFieldValues(data, field); values.forEach(function (value, index) { var conditions = [{ field: field, value: value, values: values }]; var subData = data.filter(_this.getFacetDataFilter(conditions)); if (subData.length) { var facet = { type: _this.cfg.type, data: subData, region: null, columnValue: value, rowValue: '', columnField: field, rowField: '', columnIndex: index, rowValuesLength: _this.getRows(), columnValuesLength: 1, rowIndex: level, children: _this.getChildFacets(subData, level + 1, arr), }; rst.push(facet); arr.push(facet); } }); return rst; }; Tree.prototype.render = function () { _super.prototype.render.call(this); if (this.cfg.showTitle) { this.renderTitle(); } }; Tree.prototype.renderTitle = function () { var _this = this; util_1.each(this.facets, function (facet) { var columnValue = facet.columnValue, view = facet.view; var formatter = util_1.get(_this.cfg.title, 'formatter'); var config = util_1.deepMix({ position: ['50%', '0%'], content: formatter ? formatter(columnValue) : columnValue, }, facet_1.getFactTitleConfig(constant_1.DIRECTION.TOP), _this.cfg.title); view.annotation().text(config); }); }; Tree.prototype.drawLines = function (facets) { var _this = this; facets.forEach(function (facet) { if (!_this.isLeaf(facet)) { var children = facet.children; _this.addFacetLines(facet, children); } }); }; // add lines with it's children Tree.prototype.addFacetLines = function (facet, children) { var _this = this; var view = facet.view; var region = view.coordinateBBox; // top, right, bottom, left var start = { x: region.x + region.width / 2, y: region.y + region.height, }; children.forEach(function (subFacet) { var subRegion = subFacet.view.coordinateBBox; var end = { x: subRegion.bl.x + (subRegion.tr.x - subRegion.bl.x) / 2, y: subRegion.tr.y, }; var middle1 = { x: start.x, y: start.y + (end.y - start.y) / 2, }; var middle2 = { x: end.x, y: middle1.y, }; _this.drawLine([start, middle1, middle2, end]); }); }; Tree.prototype.getPath = function (points) { var path = []; var smooth = this.cfg.line.smooth; if (smooth) { path.push(['M', points[0].x, points[0].y]); path.push(['C', points[1].x, points[1].y, points[2].x, points[2].y, points[3].x, points[3].y]); } else { points.forEach(function (point, index) { if (index === 0) { path.push(['M', point.x, point.y]); } else { path.push(['L', point.x, point.y]); } }); } return path; }; // draw line width points Tree.prototype.drawLine = function (points) { var path = this.getPath(points); var line = this.cfg.line.style; this.container.addShape('path', { attrs: util_1.assign({ // @ts-ignore path: path, }, line), }); }; Tree.prototype.getXAxisOption = function (x, axes, option, facet) { if (facet.rowIndex !== facet.rowValuesLength - 1) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null, label: null }); } return option; }; Tree.prototype.getYAxisOption = function (y, axes, option, facet) { if (facet.originColIndex !== 0 && facet.columnIndex !== 0) { return tslib_1.__assign(tslib_1.__assign({}, option), { title: null, label: null }); } return option; }; return Tree; }(facet_2.Facet)); exports.default = Tree; },{"../constant":237,"../util/facet":374,"./facet":242,"@antv/util":803,"tslib":385}],249:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var constant_1 = require("../constant"); var path_1 = tslib_1.__importDefault(require("./path")); require("./shape/area"); /** * Area 几何标记类。 * 常用于绘制面积图。 */ var Area = /** @class */ (function (_super) { tslib_1.__extends(Area, _super); function Area(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'area'; _this.shapeType = 'area'; /** 生成图形关键点 */ _this.generatePoints = true; /** * 面积图是否从 0 基准线开始填充。 * 1. 默认值为 `true`,表现如下: * ![image](https://gw.alipayobjects.com/zos/rmsportal/ZQqwUCczalrKqGgagOVp.png) * 2. 当值为 `false` 时,表现如下: * ![image](https://gw.alipayobjects.com/zos/rmsportal/yPswkaXvUpCYOdhocGwB.png) */ _this.startOnZero = true; var _a = cfg.startOnZero, startOnZero = _a === void 0 ? true : _a, _b = cfg.sortable, sortable = _b === void 0 ? true : _b, _c = cfg.showSinglePoint, showSinglePoint = _c === void 0 ? false : _c; _this.startOnZero = startOnZero; // 默认为 true _this.sortable = sortable; // Area 默认会对数据按照 x 轴字段进行正向排序 _this.showSinglePoint = showSinglePoint; return _this; } /** * 获取图形绘制的关键点以及数据 * @param mappingData 映射后的数据 */ Area.prototype.getPointsAndData = function (mappingData) { var points = []; var data = []; for (var i = 0, len = mappingData.length; i < len; i++) { var obj = mappingData[i]; points.push(obj.points); data.push(obj[constant_1.FIELD_ORIGIN]); } return { points: points, data: data, }; }; /** * 获取 Y 轴上的最小值 * @returns y 字段最小值 */ Area.prototype.getYMinValue = function () { if (this.startOnZero) { return _super.prototype.getYMinValue.call(this); } var yScale = this.getYScale(); return yScale.min; }; return Area; }(path_1.default)); exports.default = Area; },{"../constant":237,"./path":266,"./shape/area":270,"tslib":385}],250:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var adjust_1 = require("@antv/adjust"); var attr_1 = require("@antv/attr"); var util_1 = require("@antv/util"); var animate_1 = require("../animate"); var base_1 = tslib_1.__importDefault(require("../base")); var constant_1 = require("../constant"); var helper_1 = require("../util/helper"); var element_1 = tslib_1.__importDefault(require("./element")); var label_1 = require("./label"); var base_2 = require("./shape/base"); var group_data_1 = require("./util/group-data"); var is_model_change_1 = require("./util/is-model-change"); var parse_fields_1 = require("./util/parse-fields"); // 根据 elementId 查找对应的 label,因为有可能一个 element 对应多个 labels,所以在给 labels 打标识时做了处理 // 打标规则详见 ./label/base.ts#L263 function filterLabelsById(id, labelsMap) { var labels = []; util_1.each(labelsMap, function (label, labelId) { var elementId = labelId.split(' ')[0]; if (elementId === id) { labels.push(label); } }); return labels; } /** * Geometry 几何标记基类,主要负责数据到图形属性的映射以及绘制逻辑。 */ var Geometry = /** @class */ (function (_super) { tslib_1.__extends(Geometry, _super); /** * 创建 Geometry 实例。 * @param cfg */ function Geometry(cfg) { var _this = _super.call(this, cfg) || this; /** Geometry 几何标记类型。 */ _this.type = 'base'; // 内部产生的属性 /** Attribute map */ _this.attributes = {}; /** Element map */ _this.elements = []; /** 使用 key-value 结构存储 Element,key 为每个 Element 实例对应的唯一 ID */ _this.elementsMap = {}; /** animate 配置项 */ _this.animateOption = true; /** 图形属性映射配置 */ _this.attributeOption = {}; /** 存储上一次渲染时的 element 映射表,用于更新逻辑 */ _this.lastElementsMap = {}; /** 是否生成多个点来绘制图形。 */ _this.generatePoints = false; /** 存储发生图形属性映射前的数据 */ _this.beforeMappingData = null; _this.adjusts = {}; _this.idFields = []; _this.hasSorted = false; _this.isCoordinateChanged = false; var container = cfg.container, labelsContainer = cfg.labelsContainer, coordinate = cfg.coordinate, data = cfg.data, _a = cfg.sortable, sortable = _a === void 0 ? false : _a, _b = cfg.visible, visible = _b === void 0 ? true : _b, theme = cfg.theme, _c = cfg.scales, scales = _c === void 0 ? {} : _c, _d = cfg.scaleDefs, scaleDefs = _d === void 0 ? {} : _d; _this.container = container; _this.labelsContainer = labelsContainer; _this.coordinate = coordinate; _this.data = data; _this.sortable = sortable; _this.visible = visible; _this.userTheme = theme; _this.scales = scales; _this.scaleDefs = scaleDefs; return _this; } /** * 配置 position 通道映射规则。 * * @example * ```typescript * // 数据结构: [{ x: 'A', y: 10, color: 'red' }] * geometry.position('x*y'); * geometry.position([ 'x', 'y' ]); * geometry.position({ * fields: [ 'x', 'y' ], * }); * ``` * * @param cfg 映射规则 * @returns */ Geometry.prototype.position = function (cfg) { var positionCfg = cfg; if (!util_1.isPlainObject(cfg)) { // 字符串字段或者数组字段 positionCfg = { fields: parse_fields_1.parseFields(cfg), }; } var fields = util_1.get(positionCfg, 'fields'); if (fields.length === 1) { // 默认填充一维 1*xx fields.unshift('1'); util_1.set(positionCfg, 'fields', fields); } util_1.set(this.attributeOption, 'position', positionCfg); return this; }; Geometry.prototype.color = function (field, cfg) { this.createAttrOption('color', field, cfg); return this; }; Geometry.prototype.shape = function (field, cfg) { this.createAttrOption('shape', field, cfg); return this; }; Geometry.prototype.size = function (field, cfg) { this.createAttrOption('size', field, cfg); return this; }; /** * 设置数据调整方式。G2 目前内置了四种类型: * 1. dodge * 2. stack * 3. symmetric * 4. jitter * * * **Tip** * + 对于 'dodge' 类型,可以额外进行如下属性的配置: * ```typescript * geometry.adjust('dodge', { * marginRatio: 0, // 取 0 到 1 范围的值(相对于每个柱子宽度),用于控制一个分组中柱子之间的间距 * dodgeBy: 'x', // 该属性只对 'dodge' 类型生效,声明以哪个数据字段为分组依据 * }); * ``` * * + 对于 'stack' 类型,可以额外进行如下属性的配置: * ```typescript * geometry.adjust('stack', { * reverseOrder: false, // 用于控制是否对数据进行反序操作 * }); * ``` * * @example * ```typescript * geometry.adjust('stack'); * * geometry.adjust({ * type: 'stack', * reverseOrder: false, * }); * * // 组合使用 adjust * geometry.adjust([ 'stack', 'dodge' ]); * * geometry.adjust([ * { type: 'stack' }, * { type: 'dodge', dodgeBy: 'x' }, * ]); * ``` * * @param adjustCfg 数据调整配置 * @returns */ Geometry.prototype.adjust = function (adjustCfg) { var adjusts = adjustCfg; if (util_1.isString(adjustCfg) || util_1.isPlainObject(adjustCfg)) { adjusts = [adjustCfg]; } util_1.each(adjusts, function (adjust, index) { if (!util_1.isObject(adjust)) { adjusts[index] = { type: adjust }; } }); this.adjustOption = adjusts; return this; }; Geometry.prototype.style = function (field, styleFunc) { if (util_1.isString(field)) { var fields = parse_fields_1.parseFields(field); this.styleOption = { fields: fields, callback: styleFunc, }; } else { var _a = field, fields = _a.fields, callback = _a.callback, cfg = _a.cfg; if (fields || callback || cfg) { this.styleOption = field; } else { this.styleOption = { cfg: field, }; } } return this; }; Geometry.prototype.tooltip = function (field, cfg) { if (util_1.isString(field)) { var fields = parse_fields_1.parseFields(field); this.tooltipOption = { fields: fields, callback: cfg, }; } else { this.tooltipOption = field; } return this; }; /** * Geometry 动画配置。 * * + `animate(false)` 关闭动画 * + `animate(true)` 开启动画,默认开启。 * * 我们将动画分为四个场景: * 1. appear: 图表第一次加载时的入场动画; * 2. enter: 图表绘制完成,发生更新后,产生的新图形的进场动画; * 3. update: 图表绘制完成,数据发生变更后,有状态变更的图形的更新动画; * 4. leave: 图表绘制完成,数据发生变更后,被销毁图形的销毁动画。 * * @example * ```typescript * animate({ * enter: { * duration: 1000, // enter 动画执行时间 * }, * leave: false, // 关闭 leave 销毁动画 * }); * ``` * * @param cfg 动画配置 * @returns */ Geometry.prototype.animate = function (cfg) { this.animateOption = cfg; return this; }; Geometry.prototype.label = function (field, secondParam, thirdParam) { if (util_1.isString(field)) { var labelOption = {}; var fields = parse_fields_1.parseFields(field); labelOption.fields = fields; if (util_1.isFunction(secondParam)) { labelOption.callback = secondParam; } else if (util_1.isPlainObject(secondParam)) { labelOption.cfg = secondParam; } if (thirdParam) { labelOption.cfg = thirdParam; } this.labelOption = labelOption; } else { this.labelOption = field; } return this; }; /** * 设置状态对应的样式。 * * @example * ```ts * chart.interval().state({ * selected: { * animate: { duration: 100, easing: 'easeLinear' }, * style: { * lineWidth: 2, * stroke: '#000', * }, * }, * }); * ``` * * 如果图形 shape 是由多个 shape 组成,即为一个 G.Group 对象,那么针对 group 中的每个 shape,我们需要使用下列方式进行状态样式设置: * 如果我们为 group 中的每个 shape 设置了 'name' 属性(shape.set('name', 'xx')),则以 'name' 作为 key,否则默认以索引值(即 shape 的 添加顺序)为 key。 * * ```ts * chart.interval().shape('groupShape').state({ * selected: { * style: { * 0: { lineWidth: 2 }, * 1: { fillOpacity: 1 }, * } * } * }); * ``` * * @param cfg 状态样式 */ Geometry.prototype.state = function (cfg) { this.stateOption = cfg; return this; }; /** * 初始化 Geomtry 实例: * 创建 [[Attribute]] and [[Scale]] 实例,进行数据处理,包括分组、数值化以及数据调整。 */ Geometry.prototype.init = function (cfg) { if (cfg === void 0) { cfg = {}; } this.setCfg(cfg); this.initAttributes(); // 创建图形属性 // 数据加工:分组 -> 数字化 -> adjust this.processData(this.data); // 调整 scale this.adjustScale(); }; /** * Geometry 更新。 * @param [cfg] 更新的配置 */ Geometry.prototype.update = function (cfg) { if (cfg === void 0) { cfg = {}; } var data = cfg.data, isDataChanged = cfg.isDataChanged, isCoordinateChanged = cfg.isCoordinateChanged; var _a = this, attributeOption = _a.attributeOption, lastAttributeOption = _a.lastAttributeOption; if (!util_1.isEqual(attributeOption, lastAttributeOption)) { // 映射发生改变,则重新创建图形属性 this.init(cfg); } else if (data && (isDataChanged || !util_1.isEqual(data, this.data))) { // 数据发生变化 this.setCfg(cfg); this.processData(data); // 数据加工:分组 -> 数字化 -> adjust } else { // 有可能 coordinate 变化 this.setCfg(cfg); } // 调整 scale this.adjustScale(); this.isCoordinateChanged = isCoordinateChanged; }; /** * 将原始数据映射至图形空间,同时创建图形对象。 */ Geometry.prototype.paint = function (isUpdate) { var _this = this; if (isUpdate === void 0) { isUpdate = false; } if (this.animateOption) { this.animateOption = util_1.deepMix({}, animate_1.getDefaultAnimateCfg(this.type, this.coordinate), this.animateOption); } this.defaultSize = undefined; this.elements = []; this.elementsMap = {}; var offscreenGroup = this.getOffscreenGroup(); offscreenGroup.clear(); var beforeMappingData = this.beforeMappingData; var dataArray = this.beforeMapping(beforeMappingData); var mappingArray = []; for (var index = 0, length_1 = dataArray.length; index < length_1; index++) { var eachGroup = dataArray[index]; var mappingData = this.mapping(eachGroup); mappingArray.push(mappingData); this.createElements(mappingData, index, isUpdate); } if (this.canDoGroupAnimation(isUpdate)) { // 如果用户没有配置 appear.animation,就默认走整体动画 var container = this.container; var type = this.type; var coordinate = this.coordinate; var animateCfg = util_1.get(this.animateOption, 'appear'); var yScale = this.getYScale(); var yMinPoint = coordinate.convert({ x: 0, y: yScale.scale(this.getYMinValue()), }); animate_1.doGroupAppearAnimate(container, animateCfg, type, coordinate, yMinPoint); } // 添加 label if (this.labelOption) { this.renderLabels(util_1.flatten(mappingArray), isUpdate); } this.dataArray = mappingArray; // 销毁被删除的 elements util_1.each(this.lastElementsMap, function (deletedElement) { // 更新动画配置,用户有可能在更新之前有对动画进行配置操作 deletedElement.animate = _this.animateOption; deletedElement.destroy(); }); this.lastElementsMap = this.elementsMap; // 缓存,用于更新 this.lastAttributeOption = tslib_1.__assign({}, this.attributeOption); if (this.visible === false) { // 用户在初始化的时候声明 visible: false this.changeVisible(false); } }; /** * 清空当前 Geometry,配置项仍保留,但是内部创建的对象全部清空。 * @override */ Geometry.prototype.clear = function () { var _a = this, container = _a.container, geometryLabel = _a.geometryLabel, offscreenGroup = _a.offscreenGroup; if (container) { container.clear(); } if (geometryLabel) { geometryLabel.clear(); } if (offscreenGroup) { offscreenGroup.clear(); } // 属性恢复至出厂状态 this.scaleDefs = undefined; this.attributes = {}; this.scales = {}; this.elementsMap = {}; this.lastElementsMap = {}; this.elements = []; this.adjusts = {}; this.dataArray = null; this.beforeMappingData = null; this.lastAttributeOption = undefined; this.defaultSize = undefined; this.idFields = []; this.groupScales = undefined; this.hasSorted = false; this.isCoordinateChanged = false; }; /** * 销毁 Geometry 实例。 */ Geometry.prototype.destroy = function () { this.clear(); var container = this.container; container.remove(true); if (this.offscreenGroup) { this.offscreenGroup.remove(true); this.offscreenGroup = null; } if (this.geometryLabel) { this.geometryLabel.destroy(); this.geometryLabel = null; } this.theme = undefined; this.shapeFactory = undefined; _super.prototype.destroy.call(this); }; /** * 获取决定分组的图形属性对应的 scale 实例。 * @returns */ Geometry.prototype.getGroupScales = function () { return this.groupScales; }; /** * 根据名字获取图形属性实例。 */ Geometry.prototype.getAttribute = function (name) { return this.attributes[name]; }; /** 获取 x 轴对应的 scale 实例。 */ Geometry.prototype.getXScale = function () { return this.getAttribute('position').scales[0]; }; /** 获取 y 轴对应的 scale 实例。 */ Geometry.prototype.getYScale = function () { return this.getAttribute('position').scales[1]; }; /** * 获取决定分组的图形属性实例。 */ Geometry.prototype.getGroupAttributes = function () { var rst = []; util_1.each(this.attributes, function (attr) { if (constant_1.GROUP_ATTRS.includes(attr.type)) { rst.push(attr); } }); return rst; }; /** 获取图形属性默认的映射值。 */ Geometry.prototype.getDefaultValue = function (attrName) { var value; var attr = this.getAttribute(attrName); if (attr && util_1.isEmpty(attr.scales)) { // 获取映射至常量的值 value = attr.values[0]; } return value; }; /** * 获取该数据发生图形映射后对应的 Attribute 图形空间数据。 * @param attr Attribute 图形属性实例。 * @param obj 需要进行映射的原始数据。 * @returns */ Geometry.prototype.getAttributeValues = function (attr, obj) { var params = []; var scales = attr.scales; for (var index = 0, length_2 = scales.length; index < length_2; index++) { var scale = scales[index]; var field = scale.field; if (scale.isIdentity) { params.push(scale.values); } else { params.push(obj[field]); } } return attr.mapping.apply(attr, params); }; Geometry.prototype.getAdjust = function (adjustType) { return this.adjusts[adjustType]; }; /** * 获取 shape 对应的 marker 样式。 * @param shapeName shape 具体名字 * @param cfg marker 信息 * @returns */ Geometry.prototype.getShapeMarker = function (shapeName, cfg) { var shapeFactory = this.getShapeFactory(); return shapeFactory.getMarker(shapeName, cfg); }; /** * 根据一定的规则查找 Geometry 的 Elements。 * * ```typescript * getElementsBy((element) => { * const data = element.getData(); * * return data.a === 'a'; * }); * ``` * * @param condition 定义查找规则的回调函数。 * @returns */ Geometry.prototype.getElementsBy = function (condition) { return this.elements.filter(function (element) { return condition(element); }); }; /** * 获取数据对应的唯一 id。 * @param data Element 对应的绘制数据 * @returns */ Geometry.prototype.getElementId = function (data) { data = util_1.isArray(data) ? data[0] : data; var originData = data[constant_1.FIELD_ORIGIN]; // 如果用户声明了使用哪些字段作为 id 值 if (this.idFields.length) { var elementId = originData[this.idFields[0]]; for (var index = 1; index < this.idFields.length; index++) { elementId += '-' + originData[this.idFields[index]]; } return elementId; } var type = this.type; var xScale = this.getXScale(); var yScale = this.getYScale(); var xField = xScale.field || 'x'; var yField = yScale.field || 'y'; var yVal = originData[yField]; var xVal; if (xScale.type === 'identity') { xVal = xScale.values[0]; } else { xVal = originData[xField]; } var id; if (type === 'interval' || type === 'schema') { id = xVal; } else if (type === 'line' || type === 'area' || type === 'path') { id = type; } else { id = xVal + "-" + yVal; } var groupScales = this.groupScales; for (var index = 0, length_3 = groupScales.length; index < length_3; index++) { var groupScale = groupScales[index]; var field = groupScale.field; id = id + "-" + originData[field]; } // 用户在进行 dodge 类型的 adjust 调整的时候设置了 dodgeBy 属性 var dodgeAdjust = this.getAdjust('dodge'); if (dodgeAdjust) { var dodgeBy = dodgeAdjust.dodgeBy; if (dodgeBy) { id = id + "-" + originData[dodgeBy]; } } if (this.getAdjust('jitter')) { id = id + "-" + data.x + "-" + data.y; } return id; }; /** * 获取所有需要创建 scale 的字段名称。 */ Geometry.prototype.getScaleFields = function () { var fields = []; var tmpMap = {}; var _a = this, attributeOption = _a.attributeOption, labelOption = _a.labelOption, tooltipOption = _a.tooltipOption; // 获取图形属性上的 fields for (var attributeType in attributeOption) { if (attributeOption.hasOwnProperty(attributeType)) { var eachOpt = attributeOption[attributeType]; if (eachOpt.fields) { helper_1.uniq(eachOpt.fields, fields, tmpMap); } else if (eachOpt.values) { // 考虑 size(10), shape('circle') 等场景 helper_1.uniq(eachOpt.values, fields, tmpMap); } } } // 获取 label 上的字段 if (labelOption && labelOption.fields) { helper_1.uniq(labelOption.fields, fields, tmpMap); } // 获取 tooltip 上的字段 if (util_1.isObject(tooltipOption) && tooltipOption.fields) { helper_1.uniq(tooltipOption.fields, fields, tmpMap); } return fields; }; /** * 显示或者隐藏 geometry。 * @param visible */ Geometry.prototype.changeVisible = function (visible) { _super.prototype.changeVisible.call(this, visible); var elements = this.elements; for (var index = 0, length_4 = elements.length; index < length_4; index++) { var element = elements[index]; element.changeVisible(visible); } if (visible) { if (this.container) { this.container.show(); } if (this.labelsContainer) { this.labelsContainer.show(); } } else { if (this.container) { this.container.hide(); } if (this.labelsContainer) { this.labelsContainer.hide(); } } }; /** * 获取当前配置中的所有分组 & 分类的字段。 * @return fields string[] */ Geometry.prototype.getGroupFields = function () { var groupFields = []; var tmpMap = {}; // 用于去重过滤 for (var index = 0, length_5 = constant_1.GROUP_ATTRS.length; index < length_5; index++) { var attributeName = constant_1.GROUP_ATTRS[index]; var cfg = this.attributeOption[attributeName]; if (cfg && cfg.fields) { helper_1.uniq(cfg.fields, groupFields, tmpMap); } } return groupFields; }; /** * 获得图形的 x y 字段。 */ Geometry.prototype.getXYFields = function () { var _a = this.attributeOption.position.fields, x = _a[0], y = _a[1]; return [x, y]; }; /** * 获取该 Geometry 下所有生成的 shapes。 * @returns shapes */ Geometry.prototype.getShapes = function () { return this.elements.map(function (element) { return element.shape; }); }; /** * 获取虚拟 Group。 * @returns */ Geometry.prototype.getOffscreenGroup = function () { if (!this.offscreenGroup) { var GroupCtor = this.container.getGroupBase(); // 获取分组的构造函数 this.offscreenGroup = new GroupCtor({}); } return this.offscreenGroup; }; // 对数据进行排序 Geometry.prototype.sort = function (mappingArray) { if (!this.hasSorted) { // 未发生过排序 var xScale_1 = this.getXScale(); var xField_1 = xScale_1.field; for (var index = 0; index < mappingArray.length; index++) { var itemArr = mappingArray[index]; itemArr.sort(function (obj1, obj2) { return xScale_1.translate(obj1[constant_1.FIELD_ORIGIN][xField_1]) - xScale_1.translate(obj2[constant_1.FIELD_ORIGIN][xField_1]); }); } } this.hasSorted = true; }; /** * 调整度量范围。主要针对发生层叠以及一些特殊需求的 Geometry,比如 Interval 下的柱状图 Y 轴默认从 0 开始。 */ Geometry.prototype.adjustScale = function () { var yScale = this.getYScale(); // 如果数据发生过 stack adjust,需要调整下 yScale 的数据范围 if (yScale && this.getAdjust('stack')) { this.updateStackRange(yScale, this.beforeMappingData); } }; /** * 获取当前 Geometry 对应的 Shape 工厂实例。 */ Geometry.prototype.getShapeFactory = function () { var shapeType = this.shapeType; if (!base_2.getShapeFactory(shapeType)) { return; } if (!this.shapeFactory) { this.shapeFactory = util_1.clone(base_2.getShapeFactory(shapeType)); // 防止多个 view 共享一个 shapeFactory 实例,导致 coordinate 被篡改 } // 因为这里缓存了 shapeFactory,但是外部可能会变更 coordinate,导致无法重新设置到 shapeFactory 中 this.shapeFactory.coordinate = this.coordinate; // theme 原因同上 this.shapeFactory.theme = this.theme.geometries[shapeType] || {}; return this.shapeFactory; }; /** * 获取每个 Shape 对应的关键点数据。 * @param obj 经过分组 -> 数字化 -> adjust 调整后的数据记录 * @returns */ Geometry.prototype.createShapePointsCfg = function (obj) { var xScale = this.getXScale(); var yScale = this.getYScale(); var x = this.normalizeValues(obj[xScale.field], xScale); var y; // 存在没有 y 的情况 if (yScale) { y = this.normalizeValues(obj[yScale.field], yScale); } else { y = obj.y ? obj.y : 0.1; } return { x: x, y: y, y0: yScale ? yScale.scale(this.getYMinValue()) : undefined, }; }; /** * 创建 Element 实例。 * @param mappingDatum Element 对应的绘制数据 * @param [isUpdate] 是否处于更新阶段 * @returns element 返回创建的 Element 实例 */ Geometry.prototype.createElement = function (mappingDatum, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } var container = this.container; var shapeCfg = this.getDrawCfg(mappingDatum); // 获取绘制图形的配置信息 var shapeFactory = this.getShapeFactory(); var element = new element_1.default({ shapeFactory: shapeFactory, container: container, offscreenGroup: this.getOffscreenGroup(), }); element.animate = this.animateOption; element.geometry = this; element.draw(shapeCfg, isUpdate); // 绘制 return element; }; /** * 获取每条数据对应的图形绘制数据。 * @param mappingDatum 映射后的数据 * @returns draw cfg */ Geometry.prototype.getDrawCfg = function (mappingDatum) { var originData = mappingDatum[constant_1.FIELD_ORIGIN]; // 原始数据 var cfg = { mappingData: mappingDatum, data: originData, x: mappingDatum.x, y: mappingDatum.y, color: mappingDatum.color, size: mappingDatum.size, isInCircle: this.coordinate.isPolar, }; var shapeName = mappingDatum.shape; if (!shapeName && this.getShapeFactory()) { shapeName = this.getShapeFactory().defaultShapeType; } cfg.shape = shapeName; // 获取默认样式 var theme = this.theme.geometries[this.shapeType]; cfg.defaultStyle = util_1.get(theme, [shapeName, 'default'], {}).style; var styleOption = this.styleOption; if (styleOption) { cfg.style = this.getStyleCfg(styleOption, originData); } if (this.generatePoints) { cfg.points = mappingDatum.points; cfg.nextPoints = mappingDatum.nextPoints; } return cfg; }; /** * 创建所有的 Elements。 * @param mappingData * @param [isUpdate] * @returns elements */ Geometry.prototype.createElements = function (mappingData, index, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } var _a = this, lastElementsMap = _a.lastElementsMap, elementsMap = _a.elementsMap, elements = _a.elements; for (var subIndex = 0, length_6 = mappingData.length; subIndex < length_6; subIndex++) { var mappingDatum = mappingData[subIndex]; var id = this.getElementId(mappingDatum); if (elementsMap[id]) { // 存在重复数据,则根据再根据 index 进行区分 id = id + "-" + index + "-" + subIndex; } var result = lastElementsMap[id]; if (!result) { // 创建新的 element result = this.createElement(mappingDatum, isUpdate); } else { // element 已经创建 var currentShapeCfg = this.getDrawCfg(mappingDatum); var preShapeCfg = result.getModel(); if (this.isCoordinateChanged || is_model_change_1.isModelChange(currentShapeCfg, preShapeCfg)) { result.animate = this.animateOption; // 通过绘制数据的变更来判断是否需要更新,因为用户有可能会修改图形属性映射 result.update(currentShapeCfg); // 更新对应的 element } delete lastElementsMap[id]; } elements.push(result); elementsMap[id] = result; } return elements; }; /** * 获取渲染的 label 类型。 */ Geometry.prototype.getLabelType = function () { var _a = this, labelOption = _a.labelOption, coordinate = _a.coordinate, type = _a.type; var coordinateType = coordinate.type; var labelType = util_1.get(labelOption, ['cfg', 'type']); if (!labelType) { // 用户未定义,则进行默认的逻辑 if (coordinateType === 'polar') { // 极坐标下使用通用的极坐标文本 labelType = 'polar'; } else if (coordinateType === 'theta') { // theta 坐标系下使用饼图文本 labelType = 'pie'; } else if (type === 'interval' || type === 'polygon') { labelType = 'interval'; } else { labelType = 'base'; } } return labelType; }; /** * 获取 Y 轴上的最小值。 */ Geometry.prototype.getYMinValue = function () { var yScale = this.getYScale(); var min = yScale.min, max = yScale.max; var value; if (min >= 0) { value = min; } else if (max <= 0) { // 当值全位于负区间时,需要保证 ymin 在区域内,不可为 0 value = max; } else { value = 0; } return value; }; // 创建图形属性相关的配置项 Geometry.prototype.createAttrOption = function (attrName, field, cfg) { if (util_1.isNil(field) || util_1.isObject(field)) { if (util_1.isObject(field) && util_1.isEqual(Object.keys(field), ['values'])) { // shape({ values: [ 'funnel' ] }) util_1.set(this.attributeOption, attrName, { fields: field.values, }); } else { util_1.set(this.attributeOption, attrName, field); } } else { var attrCfg = {}; if (util_1.isNumber(field)) { // size(3) attrCfg.values = [field]; } else { attrCfg.fields = parse_fields_1.parseFields(field); } if (cfg) { if (util_1.isFunction(cfg)) { attrCfg.callback = cfg; } else { attrCfg.values = cfg; } } util_1.set(this.attributeOption, attrName, attrCfg); } }; Geometry.prototype.initAttributes = function () { var _this = this; var _a = this, attributes = _a.attributes, attributeOption = _a.attributeOption, theme = _a.theme, shapeType = _a.shapeType; this.groupScales = []; var tmpMap = {}; var _loop_1 = function (attrType) { if (attributeOption.hasOwnProperty(attrType)) { var option = attributeOption[attrType]; if (!option) { return { value: void 0 }; } var attrCfg = tslib_1.__assign({}, option); var callback = attrCfg.callback, values = attrCfg.values, _a = attrCfg.fields, fields = _a === void 0 ? [] : _a; // 获取每一个字段对应的 scale var scales = fields.map(function (field) { var scale = _this.scales[field]; if (scale.isCategory && !tmpMap[field] && constant_1.GROUP_ATTRS.includes(attrType)) { _this.groupScales.push(scale); tmpMap[field] = true; } return scale; }); attrCfg.scales = scales; if (attrType !== 'position' && scales.length === 1 && scales[0].type === 'identity') { // 用户在图形通道上声明了常量字段 color('red'), size(5) attrCfg.values = scales[0].values; } else if (!callback && !values) { // 用户没有指定任何规则,则使用默认的映射规则 if (attrType === 'size') { attrCfg.values = theme.sizes; } else if (attrType === 'shape') { attrCfg.values = theme.shapes[shapeType] || []; } else if (attrType === 'color') { if (scales.length) { // 根据数值个数使用对应的色板 attrCfg.values = scales[0].values.length <= 10 ? theme.colors10 : theme.colors20; } else { attrCfg.values = theme.colors10; } } } var AttributeCtor = attr_1.getAttribute(attrType); attributes[attrType] = new AttributeCtor(attrCfg); } }; // 遍历每一个 attrOption,各自创建 Attribute 实例 for (var attrType in attributeOption) { var state_1 = _loop_1(attrType); if (typeof state_1 === "object") return state_1.value; } }; // 处理数据:分组 -> 数字化 -> adjust 调整 Geometry.prototype.processData = function (data) { this.hasSorted = false; var scales = this.getAttribute('position').scales; var categoryScales = scales.filter(function (scale) { return scale.isCategory; }); var groupedArray = this.groupData(data); // 数据分组 var beforeAdjust = []; for (var i = 0, len = groupedArray.length; i < len; i++) { var subData = groupedArray[i]; var arr = []; for (var j = 0, subLen = subData.length; j < subLen; j++) { var originData = subData[j]; var item = {}; // tslint:disable-next-line: forin for (var k in originData) { item[k] = originData[k]; } item[constant_1.FIELD_ORIGIN] = originData; // 将分类数据翻译成数据, 仅对位置相关的度量进行数字化处理 for (var _i = 0, categoryScales_1 = categoryScales; _i < categoryScales_1.length; _i++) { var scale = categoryScales_1[_i]; var field = scale.field; item[field] = scale.translate(item[field]); } arr.push(item); } beforeAdjust.push(arr); } var dataArray = this.adjustData(beforeAdjust); // 进行 adjust 数据调整 this.beforeMappingData = dataArray; return dataArray; }; // 调整数据 Geometry.prototype.adjustData = function (dataArray) { var adjustOption = this.adjustOption; var result = dataArray; if (adjustOption) { var xScale = this.getXScale(); var yScale = this.getYScale(); var xField = xScale.field; var yField = yScale ? yScale.field : null; for (var i = 0, len = adjustOption.length; i < len; i++) { var adjust = adjustOption[i]; var adjustCfg = tslib_1.__assign({ xField: xField, yField: yField }, adjust); var type = adjust.type; if (type === 'dodge') { var adjustNames = []; if (xScale.isCategory || xScale.type === 'identity') { adjustNames.push('x'); } else if (!yScale) { adjustNames.push('y'); } else { throw new Error('dodge is not support linear attribute, please use category attribute!'); } adjustCfg.adjustNames = adjustNames; // 每个分组内每条柱子的宽度占比,用户不可指定,用户需要通过 columnWidthRatio 指定 adjustCfg.dodgeRatio = this.theme.columnWidthRatio; } else if (type === 'stack') { var coordinate = this.coordinate; if (!yScale) { // 一维的情况下获取高度和默认size adjustCfg.height = coordinate.getHeight(); var size = this.getDefaultValue('size') || 3; adjustCfg.size = size; } // 不进行 transpose 时,用户又没有设置这个参数时,默认从上向下 if (!coordinate.isTransposed && util_1.isNil(adjustCfg.reverseOrder)) { adjustCfg.reverseOrder = true; } } var adjustCtor = adjust_1.getAdjust(type); var adjustInstance = new adjustCtor(adjustCfg); result = adjustInstance.process(result); this.adjusts[type] = adjustInstance; } } return result; }; // 对数据进行分组 Geometry.prototype.groupData = function (data) { var groupScales = this.getGroupScales(); var scaleDefs = this.scaleDefs; var appendConditions = {}; var groupFields = []; for (var index = 0; index < groupScales.length; index++) { var scale = groupScales[index]; var field = scale.field; groupFields.push(field); if (util_1.get(scaleDefs, [field, 'values'])) { // 用户通过 view.scale() 接口指定了 values 属性 appendConditions[field] = scaleDefs[field].values; } } return group_data_1.group(data, groupFields, appendConditions); }; // 更新发生层叠后的数据对应的度量范围 Geometry.prototype.updateStackRange = function (scale, dataArray) { var mergeArray = util_1.flatten(dataArray); var field = scale.field; var min = scale.min; var max = scale.max; for (var index = 0; index < mergeArray.length; index++) { var obj = mergeArray[index]; var tmpMin = Math.min.apply(null, obj[field]); var tmpMax = Math.max.apply(null, obj[field]); if (tmpMin < min) { min = tmpMin; } if (tmpMax > max) { max = tmpMax; } } var scaleDefs = this.scaleDefs; var cfg = {}; if (min < scale.min && !util_1.get(scaleDefs, [field, 'min'])) { // 用户如果在列定义中定义了 min,则以用户定义的为准 cfg.min = min; } if (max > scale.max && !util_1.get(scaleDefs, [field, 'max'])) { // 用户如果在列定义中定义了 max cfg.max = max; } scale.change(cfg); }; // 将数据映射至图形空间前的操作:排序以及关键点的生成 Geometry.prototype.beforeMapping = function (beforeMappingData) { // 当初加 clone 是因为 points 的引用关系,导致更新失败,可是现在貌似复现不出来了,所以暂时不进行 clone // const source = clone(beforeMappingData); var source = beforeMappingData; if (this.sortable) { this.sort(source); } if (this.generatePoints) { // 需要生成关键点 for (var index = 0, length_7 = source.length; index < length_7; index++) { var currentData = source[index]; this.generateShapePoints(currentData); var nextData = source[index + 1]; if (nextData) { this.generateShapePoints(nextData); currentData[0].nextPoints = nextData[0].points; } } } return source; }; // 生成 shape 的关键点 Geometry.prototype.generateShapePoints = function (data) { var shapeFactory = this.getShapeFactory(); var shapeAttr = this.getAttribute('shape'); for (var index = 0; index < data.length; index++) { var obj = data[index]; var cfg = this.createShapePointsCfg(obj); var shape = shapeAttr ? this.getAttributeValues(shapeAttr, obj) : null; var points = shapeFactory.getShapePoints(shape, cfg); obj.points = points; } }; // 将数据归一化 Geometry.prototype.normalizeValues = function (values, scale) { var rst = []; if (util_1.isArray(values)) { for (var index = 0; index < values.length; index++) { var value = values[index]; rst.push(scale.scale(value)); } } else { rst = scale.scale(values); } return rst; }; // 将数据映射至图形空间 Geometry.prototype.mapping = function (data) { var attributes = this.attributes; var mappingData = []; for (var index = 0; index < data.length; index++) { var record = data[index]; var newRecord = { _origin: record[constant_1.FIELD_ORIGIN], points: record.points, nextPoints: record.nextPoints, }; for (var k in attributes) { if (attributes.hasOwnProperty(k)) { var attr = attributes[k]; var names = attr.names; var values = this.getAttributeValues(attr, record); if (names.length > 1) { // position 之类的生成多个字段的属性 for (var j = 0; j < values.length; j += 1) { var val = values[j]; var name_1 = names[j]; newRecord[name_1] = util_1.isArray(val) && val.length === 1 ? val[0] : val; // 只有一个值时返回第一个属性值 } } else { // values.length === 1 的判断是以下情况,获取用户设置的图形属性值 // shape('a', ['dot', 'dash']), color('a', ['red', 'yellow']) newRecord[names[0]] = values.length === 1 ? values[0] : values; } } } this.convertPoint(newRecord); // 将 x、y 转换成画布坐标 mappingData.push(newRecord); } return mappingData; }; // 将归一化的坐标值转换成画布坐标 Geometry.prototype.convertPoint = function (mappingRecord) { var x = mappingRecord.x, y = mappingRecord.y; var rstX; var rstY; var obj; var coordinate = this.coordinate; if (util_1.isArray(x) && util_1.isArray(y)) { rstX = []; rstY = []; for (var i = 0, j = 0, xLen = x.length, yLen = y.length; i < xLen && j < yLen; i += 1, j += 1) { obj = coordinate.convert({ x: x[i], y: y[j], }); rstX.push(obj.x); rstY.push(obj.y); } } else if (util_1.isArray(y)) { rstY = []; for (var index = 0; index < y.length; index++) { var yVal = y[index]; obj = coordinate.convert({ x: x, y: yVal, }); if (rstX && rstX !== obj.x) { if (!util_1.isArray(rstX)) { rstX = [rstX]; } rstX.push(obj.x); } else { rstX = obj.x; } rstY.push(obj.y); } } else if (util_1.isArray(x)) { rstX = []; for (var index = 0; index < x.length; index++) { var xVal = x[index]; obj = coordinate.convert({ x: xVal, y: y, }); if (rstY && rstY !== obj.y) { if (!util_1.isArray(rstY)) { rstY = [rstY]; } rstY.push(obj.y); } else { rstY = obj.y; } rstX.push(obj.x); } } else { var point = coordinate.convert({ x: x, y: y, }); rstX = point.x; rstY = point.y; } mappingRecord.x = rstX; mappingRecord.y = rstY; }; // 获取 style 配置 Geometry.prototype.getStyleCfg = function (styleOption, originData) { var _a = styleOption.fields, fields = _a === void 0 ? [] : _a, callback = styleOption.callback, cfg = styleOption.cfg; if (cfg) { // 用户直接配置样式属性 return cfg; } var params = fields.map(function (field) { return originData[field]; }); return callback.apply(void 0, params); }; Geometry.prototype.setCfg = function (cfg) { var _this = this; var coordinate = cfg.coordinate, data = cfg.data, theme = cfg.theme, scaleDefs = cfg.scaleDefs; if (coordinate) { this.coordinate = coordinate; } if (data) { this.data = data; } if (scaleDefs) { this.scaleDefs = scaleDefs; this.idFields = []; util_1.each(scaleDefs, function (scaleDef, field) { if (scaleDef && scaleDef.key) { _this.idFields.push(field); } }); } if (theme) { this.theme = this.userTheme ? util_1.deepMix({}, theme, this.userTheme) : theme; // 支持 geometry 层级的主题设置 } }; Geometry.prototype.renderLabels = function (mappingArray, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } var geometryLabel = this.geometryLabel; if (!geometryLabel) { // 初次创建 var labelType = this.getLabelType(); var GeometryLabelsCtor = label_1.getGeometryLabel(labelType); geometryLabel = new GeometryLabelsCtor(this); this.geometryLabel = geometryLabel; } geometryLabel.render(mappingArray, isUpdate); // 将 label 同 element 进行关联 var labelsMap = geometryLabel.labelsRenderer.shapesMap; util_1.each(this.elementsMap, function (element, id) { var labels = filterLabelsById(id, labelsMap); // element 实例同 label 进行绑定 if (labels.length) { element.labelShape = labels; for (var i = 0; i < labels.length; i++) { var label = labels[i]; var labelChildren = label.getChildren(); for (var j = 0; j < labelChildren.length; j++) { var child = labelChildren[j]; child.cfg.name = ['element', 'label']; child.cfg.element = element; } } } }); }; /** * 是否需要进行群组入场动画 * 规则: * 1. 如果发生更新,则不进行 * 2. 如果用户关闭 geometry 动画,则不进行 * 3. 如果用户关闭了 appear 动画,则不进行 * 4. 如果用户配置了 appear.animation,则不进行 */ Geometry.prototype.canDoGroupAnimation = function (isUpdate) { return (!isUpdate && this.animateOption && (util_1.get(this.animateOption, 'appear') === undefined || (util_1.get(this.animateOption, 'appear') && util_1.get(this.animateOption, ['appear', 'animation']) === undefined))); }; return Geometry; }(base_1.default)); exports.default = Geometry; },{"../animate":217,"../base":218,"../constant":237,"../util/helper":377,"./element":252,"./label":256,"./shape/base":275,"./util/group-data":305,"./util/is-model-change":306,"./util/parse-fields":307,"@antv/adjust":9,"@antv/attr":17,"@antv/util":803,"tslib":385}],251:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("./base")); require("./shape/edge"); /** * Edge 几何标记,用于绘制关系图中的**边**图形,如: * 1. 流程图 * 2. 树 * 3. 弧长连接图 * 4. 和弦图 * 5. 桑基图 */ var Edge = /** @class */ (function (_super) { tslib_1.__extends(Edge, _super); function Edge() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'edge'; _this.shapeType = 'edge'; _this.generatePoints = true; return _this; } return Edge; }(base_1.default)); exports.default = Edge; },{"./base":250,"./shape/edge":277,"tslib":385}],252:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var animate_1 = require("../../animate"); var base_1 = tslib_1.__importDefault(require("../../base")); var graphics_1 = require("../../util/graphics"); var event_1 = require("@antv/component/lib/util/event"); /** * Element 图形元素。 * 定义:在 G2 中,我们会将数据通过图形语法映射成不同的图形,比如点图,数据集中的每条数据会对应一个点,柱状图每条数据对应一个柱子,线图则是一组数据对应一条折线,Element 即一条/一组数据对应的图形元素,它代表一条数据或者一个数据集,在图形层面,它可以是单个 Shape 也可以是多个 Shape,我们称之为图形元素。 */ var Element = /** @class */ (function (_super) { tslib_1.__extends(Element, _super); function Element(cfg) { var _this = _super.call(this, cfg) || this; // 存储当前开启的状态 _this.states = []; var shapeFactory = cfg.shapeFactory, container = cfg.container, offscreenGroup = cfg.offscreenGroup, _a = cfg.visible, visible = _a === void 0 ? true : _a; _this.shapeFactory = shapeFactory; _this.container = container; _this.offscreenGroup = offscreenGroup; _this.visible = visible; return _this; } /** * 绘制图形。 * @param model 绘制数据。 * @param isUpdate 可选,是否是更新发生后的绘制。 */ Element.prototype.draw = function (model, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } this.model = model; this.data = model.data; // 存储原始数据 this.shapeType = this.getShapeType(model); // 绘制图形 this.drawShape(model, isUpdate); if (this.visible === false) { // 用户在初始化的时候声明 visible: false this.changeVisible(false); } }; /** * 更新图形。 * @param model 更新的绘制数据。 */ Element.prototype.update = function (model) { var _a = this, shapeFactory = _a.shapeFactory, shape = _a.shape; if (!shape) { return; } // 更新数据 this.model = model; this.data = model.data; this.shapeType = this.getShapeType(model); // step 1: 更新 shape 携带的信息 this.setShapeInfo(shape, model); // step 2: 使用虚拟 Group 重新绘制 shape,然后更新当前 shape var offscreenGroup = this.getOffscreenGroup(); var newShape = shapeFactory.drawShape(this.shapeType, model, offscreenGroup); // @ts-ignore newShape.cfg.data = this.data; // @ts-ignore newShape.cfg.origin = model; // step 3: 同步 shape 样式 this.syncShapeStyle(shape, newShape, '', this.getAnimateCfg('update')); }; /** * 销毁 element 实例。 */ Element.prototype.destroy = function () { var _a = this, shapeFactory = _a.shapeFactory, shape = _a.shape; if (shape) { var animateCfg = this.getAnimateCfg('leave'); if (animateCfg) { // 指定了动画配置则执行销毁动画 animate_1.doAnimate(shape, animateCfg, { coordinate: shapeFactory.coordinate, toAttrs: tslib_1.__assign({}, shape.attr()), }); } else { // 否则直接销毁 shape.remove(true); } } // reset this.states = []; this.shapeFactory = undefined; this.container = undefined; this.shape = undefined; this.animate = undefined; this.geometry = undefined; this.labelShape = undefined; this.model = undefined; this.data = undefined; this.offscreenGroup = undefined; this.statesStyle = undefined; _super.prototype.destroy.call(this); }; /** * 显示或者隐藏 element。 * @param visible 是否可见。 */ Element.prototype.changeVisible = function (visible) { _super.prototype.changeVisible.call(this, visible); if (visible) { if (this.shape) { this.shape.show(); } if (this.labelShape) { this.labelShape.forEach(function (label) { label.show(); }); } } else { if (this.shape) { this.shape.hide(); } if (this.labelShape) { this.labelShape.forEach(function (label) { label.hide(); }); } } }; /** * 设置 Element 的状态。 * * 目前 Element 开放三种状态: * 1. active * 2. selected * 3. inactive * * 这三种状态相互独立,可以进行叠加。 * * 这三种状态的样式可在 [[Theme]] 主题中或者通过 `geometry.state()` 接口进行配置。 * * ```ts * // 激活 active 状态 * setState('active', true); * ``` * * @param stateName 状态名 * @param stateStatus 是否开启状态 */ Element.prototype.setState = function (stateName, stateStatus) { var _this = this; var _a = this, states = _a.states, shapeFactory = _a.shapeFactory, model = _a.model, shape = _a.shape, shapeType = _a.shapeType; var index = states.indexOf(stateName); if (stateStatus) { // 开启状态 if (index > -1) { // 该状态已经开启,则返回 return; } states.push(stateName); if (stateName === 'active' || stateName === 'selected') { shape.toFront(); } } else { if (index === -1) { // 关闭状态,但是状态未设置过 return; } states.splice(index, 1); if (stateName === 'active' || stateName === 'selected') { shape.toBack(); } } // 使用虚拟 group 重新绘制 shape,然后对这个 shape 应用状态样式后,更新当前 shape。 var offscreenShape = shapeFactory.drawShape(shapeType, model, this.getOffscreenGroup()); if (states.length) { // 应用当前状态 states.forEach(function (state) { _this.syncShapeStyle(shape, offscreenShape, state, null); }); } else { // 如果没有状态,则需要恢复至原始状态 this.syncShapeStyle(shape, offscreenShape, 'reset', null); } offscreenShape.remove(true); // 销毁,减少内存占用 var eventObject = { state: stateName, stateStatus: stateStatus, element: this, target: this.container, }; this.container.emit('statechange', eventObject); // @ts-ignore event_1.propagationDelegate(this.shape, 'statechange', eventObject); }; /** * 清空状量态,恢复至初始状态。 */ Element.prototype.clearStates = function () { var _this = this; var states = this.states; util_1.each(states, function (state) { _this.setState(state, false); }); this.states = []; }; /** * 查询当前 Element 上是否已设置 `stateName` 对应的状态。 * @param stateName 状态名称。 * @returns true 表示存在,false 表示不存在。 */ Element.prototype.hasState = function (stateName) { return this.states.includes(stateName); }; /** * 获取当前 Element 上所有的状态。 * @returns 当前 Element 上所有的状态数组。 */ Element.prototype.getStates = function () { return this.states; }; /** * 获取 Element 对应的原始数据。 * @returns 原始数据。 */ Element.prototype.getData = function () { return this.data; }; /** * 获取 Element 对应的图形绘制数据。 * @returns 图形绘制数据。 */ Element.prototype.getModel = function () { return this.model; }; /** * 返回 Element 元素整体的 bbox,包含文本及文本连线(有的话)。 * @returns 整体包围盒。 */ Element.prototype.getBBox = function () { var _a = this, shape = _a.shape, labelShape = _a.labelShape; var bbox = { x: 0, y: 0, minX: 0, minY: 0, maxX: 0, maxY: 0, width: 0, height: 0, }; if (shape) { bbox = shape.getCanvasBBox(); } if (labelShape) { labelShape.forEach(function (label) { var labelBBox = label.getCanvasBBox(); bbox.x = Math.min(labelBBox.x, bbox.x); bbox.y = Math.min(labelBBox.y, bbox.y); bbox.minX = Math.min(labelBBox.minX, bbox.minX); bbox.minY = Math.min(labelBBox.minY, bbox.minY); bbox.maxX = Math.max(labelBBox.maxX, bbox.maxX); bbox.maxY = Math.max(labelBBox.maxY, bbox.maxY); }); } bbox.width = bbox.maxX - bbox.minX; bbox.height = bbox.maxY - bbox.minY; return bbox; }; Element.prototype.getStatesStyle = function () { if (!this.statesStyle) { var _a = this, shapeType = _a.shapeType, geometry = _a.geometry, shapeFactory = _a.shapeFactory; var stateOption = geometry.stateOption; var defaultShapeType = shapeFactory.defaultShapeType; var stateTheme = shapeFactory.theme[shapeType] || shapeFactory.theme[defaultShapeType]; this.statesStyle = util_1.deepMix({}, stateTheme, stateOption); } return this.statesStyle; }; // 从主题中获取对应状态量的样式 Element.prototype.getStateStyle = function (stateName, shapeKey) { var statesStyle = this.getStatesStyle(); var stateCfg = util_1.get(statesStyle, [stateName, 'style'], {}); var shapeStyle = stateCfg[shapeKey] || stateCfg; if (util_1.isFunction(shapeStyle)) { return shapeStyle(this); } return shapeStyle; }; // 获取动画配置 Element.prototype.getAnimateCfg = function (animateType) { var animate = this.animate; if (animate) { return animate[animateType]; } return null; }; // 绘制图形 Element.prototype.drawShape = function (model, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } var _a = this, shapeFactory = _a.shapeFactory, container = _a.container, shapeType = _a.shapeType; // 自定义 shape 有可能返回空 shape this.shape = shapeFactory.drawShape(shapeType, model, container); if (this.shape) { this.setShapeInfo(this.shape, model); // 存储绘图数据 // @ts-ignore var name_1 = this.shape.cfg.name; // 附加 element 的 name, name 现在支持数组了,很好用了 if (!name_1) { // 这个地方如果用户添加了 name, 则附加 name ,否则就添加自己的 name // @ts-ignore this.shape.cfg.name = ['element', this.shapeFactory.geometryType]; } else if (util_1.isString(name_1)) { // @ts-ignore this.shape.cfg.name = ['element', name_1]; } // 执行入场动画 var animateType = isUpdate ? 'enter' : 'appear'; var animateCfg = this.getAnimateCfg(animateType); if (animateCfg) { animate_1.doAnimate(this.shape, animateCfg, { coordinate: shapeFactory.coordinate, toAttrs: tslib_1.__assign({}, this.shape.attr()), }); } } }; // 获取虚拟 Group Element.prototype.getOffscreenGroup = function () { if (!this.offscreenGroup) { var GroupCtor = this.container.getGroupBase(); // 获取分组的构造函数 this.offscreenGroup = new GroupCtor({}); } return this.offscreenGroup; }; // 设置 shape 上需要携带的信息 Element.prototype.setShapeInfo = function (shape, data) { var _this = this; // @ts-ignore shape.cfg.origin = data; // @ts-ignore shape.cfg.element = this; if (shape.isGroup()) { var children = shape.get('children'); children.forEach(function (child) { _this.setShapeInfo(child, data); }); } }; // 更新当前 shape 的样式 Element.prototype.syncShapeStyle = function (sourceShape, targetShape, state, animateCfg, index) { if (state === void 0) { state = ''; } if (index === void 0) { index = 0; } if (sourceShape.isGroup()) { var children = sourceShape.get('children'); var newChildren = targetShape.get('children'); for (var i = 0; i < children.length; i++) { this.syncShapeStyle(children[i], newChildren[i], state, animateCfg, index + i); } } else { if (state && state !== 'reset') { var name_2 = sourceShape.get('name'); if (util_1.isArray(name_2)) { // 会附加 element 的 name name_2 = name_2[1]; } var style = this.getStateStyle(state, name_2 || index); // 如果用户没有设置 name,则默认根据索引值 targetShape.attr(style); } var newAttrs = graphics_1.getReplaceAttrs(sourceShape, targetShape); if (this.animate) { if (animateCfg) { // 需要进行动画 animate_1.doAnimate(sourceShape, animateCfg, { coordinate: this.shapeFactory.coordinate, toAttrs: newAttrs, shapeModel: this.model, }); } else if (state) { sourceShape.stopAnimate(); sourceShape.animate(newAttrs, { duration: 300, }); } else { sourceShape.attr(newAttrs); } } else { sourceShape.attr(newAttrs); } } }; Element.prototype.getShapeType = function (model) { var shape = util_1.get(model, 'shape'); return util_1.isArray(shape) ? shape[0] : shape; }; return Element; }(base_1.default)); exports.default = Element; },{"../../animate":217,"../../base":218,"../../util/graphics":375,"@antv/component/lib/util/event":70,"@antv/util":803,"tslib":385}],253:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var color_util_1 = tslib_1.__importDefault(require("@antv/color-util")); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var base_1 = tslib_1.__importDefault(require("./base")); /** * 用于绘制热力图。 */ var Heatmap = /** @class */ (function (_super) { tslib_1.__extends(Heatmap, _super); function Heatmap() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'heatmap'; _this.paletteCache = {}; return _this; } Heatmap.prototype.createElements = function (mappingData, index, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } var range = this.prepareRange(mappingData); var radius = this.prepareSize(); var blur = util_1.get(this.styleOption, ['style', 'shadowBlur']); if (!util_1.isNumber(blur)) { blur = radius / 2; } this.prepareGreyScaleBlurredCircle(radius, blur); this.drawWithRange(mappingData, range, radius, blur); return null; }; /** * clear */ Heatmap.prototype.clear = function () { _super.prototype.clear.call(this); this.clearShadowCanvasCtx(); this.paletteCache = {}; }; Heatmap.prototype.prepareRange = function (data) { var colorAttr = this.getAttribute('color'); var colorField = colorAttr.getFields()[0]; var min = Infinity; var max = -Infinity; data.forEach(function (row) { var value = row[constant_1.FIELD_ORIGIN][colorField]; if (value > max) { max = value; } if (value < min) { min = value; } }); if (min === max) { min = max - 1; } return [min, max]; }; Heatmap.prototype.prepareSize = function () { var radius = this.getDefaultValue('size'); if (!util_1.isNumber(radius)) { radius = this.getDefaultSize(); } return radius; }; Heatmap.prototype.prepareGreyScaleBlurredCircle = function (radius, blur) { var grayScaleBlurredCanvas = this.getGrayScaleBlurredCanvas(); var r2 = radius + blur; var ctx = grayScaleBlurredCanvas.getContext('2d'); grayScaleBlurredCanvas.width = grayScaleBlurredCanvas.height = r2 * 2; ctx.clearRect(0, 0, grayScaleBlurredCanvas.width, grayScaleBlurredCanvas.height); ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2; ctx.shadowBlur = blur; ctx.shadowColor = 'black'; ctx.beginPath(); ctx.arc(-r2, -r2, radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); }; Heatmap.prototype.drawWithRange = function (data, range, radius, blur) { // canvas size var _a = this.coordinate, start = _a.start, end = _a.end; var width = this.coordinate.getWidth(); var height = this.coordinate.getHeight(); // value, range, etc var colorAttr = this.getAttribute('color'); var valueField = colorAttr.getFields()[0]; // prepare shadow canvas context this.clearShadowCanvasCtx(); var ctx = this.getShadowCanvasCtx(); // filter data if (range) { data = data.filter(function (row) { return row[constant_1.FIELD_ORIGIN][valueField] <= range[1] && row[constant_1.FIELD_ORIGIN][valueField] >= range[0]; }); } // step1. draw points with shadow var scale = this.scales[valueField]; for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { var obj = data_1[_i]; var _b = this.getDrawCfg(obj), x = _b.x, y = _b.y; var alpha = scale.scale(obj[constant_1.FIELD_ORIGIN][valueField]); this.drawGrayScaleBlurredCircle(x - start.x, y - end.y, radius + blur, alpha, ctx); } // step2. convert pixels var colored = ctx.getImageData(0, 0, width, height); this.clearShadowCanvasCtx(); this.colorize(colored); ctx.putImageData(colored, 0, 0); var imageShape = this.getImageShape(); imageShape.attr('x', start.x); imageShape.attr('y', end.y); imageShape.attr('width', width); imageShape.attr('height', height); imageShape.attr('img', ctx.canvas); imageShape.set('origin', this.getShapeInfo(data)); // 存储绘图信息数据 }; Heatmap.prototype.getDefaultSize = function () { var position = this.getAttribute('position'); var coordinate = this.coordinate; return Math.min(coordinate.getWidth() / (position.scales[0].ticks.length * 4), coordinate.getHeight() / (position.scales[1].ticks.length * 4)); }; Heatmap.prototype.clearShadowCanvasCtx = function () { var ctx = this.getShadowCanvasCtx(); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); }; Heatmap.prototype.getShadowCanvasCtx = function () { var canvas = this.shadowCanvas; if (!canvas) { canvas = document.createElement('canvas'); this.shadowCanvas = canvas; } canvas.width = this.coordinate.getWidth(); canvas.height = this.coordinate.getHeight(); return canvas.getContext('2d'); }; Heatmap.prototype.getGrayScaleBlurredCanvas = function () { if (!this.grayScaleBlurredCanvas) { this.grayScaleBlurredCanvas = document.createElement('canvas'); } return this.grayScaleBlurredCanvas; }; Heatmap.prototype.drawGrayScaleBlurredCircle = function (x, y, r, alpha, ctx) { var grayScaleBlurredCanvas = this.getGrayScaleBlurredCanvas(); ctx.globalAlpha = alpha; ctx.drawImage(grayScaleBlurredCanvas, x - r, y - r); }; Heatmap.prototype.colorize = function (img) { var colorAttr = this.getAttribute('color'); var pixels = img.data; var paletteCache = this.paletteCache; for (var i = 3; i < pixels.length; i += 4) { var alpha = pixels[i]; // get gradient color from opacity value if (util_1.isNumber(alpha)) { var palette = paletteCache[alpha] ? paletteCache[alpha] : color_util_1.default.rgb2arr(colorAttr.gradient(alpha / 256)); pixels[i - 3] = palette[0]; pixels[i - 2] = palette[1]; pixels[i - 1] = palette[2]; pixels[i] = alpha; } } }; Heatmap.prototype.getImageShape = function () { var imageShape = this.imageShape; if (imageShape) { return imageShape; } var container = this.container; imageShape = container.addShape({ type: 'image', attrs: {}, }); this.imageShape = imageShape; return imageShape; }; Heatmap.prototype.getShapeInfo = function (mappingData) { var shapeCfg = this.getDrawCfg(mappingData[0]); return tslib_1.__assign(tslib_1.__assign({}, shapeCfg), { mappingData: mappingData, data: this.getData(mappingData) }); }; Heatmap.prototype.getData = function (mappingData) { return mappingData.map(function (obj) { return obj[constant_1.FIELD_ORIGIN]; }); }; return Heatmap; }(base_1.default)); exports.default = Heatmap; },{"../constant":237,"./base":250,"@antv/color-util":19,"@antv/util":803,"tslib":385}],254:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var coordinate_1 = require("../util/coordinate"); var base_1 = tslib_1.__importDefault(require("./base")); /** 引入对应的 ShapeFactory */ require("./shape/interval"); var shape_size_1 = require("./util/shape-size"); /** * Interval 几何标记。 * 用于绘制柱状图、饼图、条形图、玫瑰图等。 */ var Interval = /** @class */ (function (_super) { tslib_1.__extends(Interval, _super); function Interval() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'interval'; _this.shapeType = 'interval'; _this.generatePoints = true; return _this; } /** * 获取每条数据的 Shape 绘制信息 * @param obj 经过分组 -> 数字化 -> adjust 调整后的数据记录 * @returns */ Interval.prototype.createShapePointsCfg = function (obj) { var cfg = _super.prototype.createShapePointsCfg.call(this, obj); // 计算每个 shape 的 size var size; var sizeAttr = this.getAttribute('size'); if (sizeAttr) { size = this.getAttributeValues(sizeAttr, obj)[0]; // 归一化 var coordinate = this.coordinate; var coordinateWidth = coordinate_1.getXDimensionLength(coordinate); size = size / coordinateWidth; } else { if (!this.defaultSize) { this.defaultSize = shape_size_1.getDefaultSize(this); } size = this.defaultSize; } cfg.size = size; return cfg; }; /** * 调整 y 轴的 scale 范围。 * 对于 Y 轴为数值轴柱状图,默认从 0 开始 生长。 */ Interval.prototype.adjustScale = function () { _super.prototype.adjustScale.call(this); var yScale = this.getYScale(); // 特殊逻辑:饼图需要填充满整个空间 if (this.coordinate.type === 'theta') { yScale.change({ nice: false, min: 0, // 发生过 stack 调整,yScale 的 max 被调整过,this.updateStackRange() max: Math.max(Math.max.apply(null, yScale.values), yScale.max), }); } else { // 柱状图数值轴默认从 0 开始 var scaleDefs = this.scaleDefs; var field = yScale.field, min = yScale.min, max = yScale.max, type = yScale.type; if (type !== 'time') { // time 类型不做调整 // 柱状图的 Y 轴要从 0 开始生长,但是如果用户设置了则以用户的为准 if (min > 0 && !util_1.get(scaleDefs, [field, 'min'])) { yScale.change({ min: 0, }); } // 柱当柱状图全为负值时也需要从 0 开始生长,但是如果用户设置了则以用户的为准 if (max <= 0 && !util_1.get(scaleDefs, [field, 'max'])) { yScale.change({ max: 0, }); } } } }; return Interval; }(base_1.default)); exports.default = Interval; },{"../util/coordinate":371,"./base":250,"./shape/interval":283,"./util/shape-size":308,"@antv/util":803,"tslib":385}],255:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../../constant"); var animate_1 = require("../../animate"); var graphics_1 = require("../../util/graphics"); var labels_1 = tslib_1.__importDefault(require("../../component/labels")); function avg(arr) { var sum = 0; util_1.each(arr, function (value) { sum += value; }); return sum / arr.length; } /** * Geometry Label 基类,用于生成 Geometry 下所有 label 的配置项信息 */ var GeometryLabel = /** @class */ (function () { function GeometryLabel(geometry) { this.geometry = geometry; } GeometryLabel.prototype.getLabelItems = function (mapppingArray) { var _this = this; var items = []; var labelCfgs = this.getLabelCfgs(mapppingArray); // 获取 label 相关的 x,y 的值,获取具体的 x, y,防止存在数组 util_1.each(mapppingArray, function (mappingData, index) { var labelCfg = labelCfgs[index]; if (!labelCfg || util_1.isNil(mappingData.x) || util_1.isNil(mappingData.y)) { items.push(null); return; } var labelContent = !util_1.isArray(labelCfg.content) ? [labelCfg.content] : labelCfg.content; labelCfg.content = labelContent; var total = labelContent.length; util_1.each(labelContent, function (content, subIndex) { if (util_1.isNil(content) || content === '') { items.push(null); return; } var item = tslib_1.__assign(tslib_1.__assign({}, labelCfg), _this.getLabelPoint(labelCfg, mappingData, subIndex)); if (!item.textAlign) { item.textAlign = _this.getLabelAlign(item, subIndex, total); } if (item.offset <= 0) { item.labelLine = null; } items.push(item); }); }); return items; }; GeometryLabel.prototype.render = function (mapppingArray, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } var labelItems = this.getLabelItems(mapppingArray); var labelsRenderer = this.getLabelsRenderer(); var shapes = this.getGeometryShapes(); // 渲染文本 labelsRenderer.render(labelItems, shapes, isUpdate); }; GeometryLabel.prototype.clear = function () { var labelsRenderer = this.labelsRenderer; if (labelsRenderer) { labelsRenderer.clear(); } }; GeometryLabel.prototype.destroy = function () { var labelsRenderer = this.labelsRenderer; if (labelsRenderer) { labelsRenderer.destroy(); } this.labelsRenderer = null; }; // geometry 更新之后,对应的 Coordinate 也会更新,为了获取到最新鲜的 Coordinate,故使用方法获取 GeometryLabel.prototype.getCoordinate = function () { return this.geometry.coordinate; }; /** * 获取 label 的默认配置 */ GeometryLabel.prototype.getDefaultLabelCfg = function () { return util_1.get(this.geometry.theme, 'labels', {}); }; /** * 设置 label 位置 * @param labelPointCfg * @param mappingData * @param index * @param position */ GeometryLabel.prototype.setLabelPosition = function (labelPointCfg, mappingData, index, position) { }; /** * 获取文本默认偏移量 * @param offset * @returns */ GeometryLabel.prototype.getDefaultOffset = function (offset) { var coordinate = this.getCoordinate(); var vector = this.getOffsetVector(offset); return coordinate.isTransposed ? vector[0] : vector[1]; }; /** * 获取每个 label 的偏移量 * @param labelCfg * @param index * @param total * @returns */ GeometryLabel.prototype.getLabelOffset = function (labelCfg, index, total) { var offset = this.getDefaultOffset(labelCfg.offset); var coordinate = this.getCoordinate(); var transposed = coordinate.isTransposed; var dim = transposed ? 'x' : 'y'; var factor = transposed ? 1 : -1; // y 方向上越大,像素的坐标越小,所以transposed时将系数变成 var offsetPoint = { x: 0, y: 0, }; if (index > 0 || total === 1) { // 判断是否小于0 offsetPoint[dim] = offset * factor; } else { offsetPoint[dim] = offset * factor * -1; } return offsetPoint; }; /** * 获取每个 label 的位置 * @param labelCfg * @param mappingData * @param index * @returns label point */ GeometryLabel.prototype.getLabelPoint = function (labelCfg, mappingData, index) { var coordinate = this.getCoordinate(); var total = labelCfg.content.length; function getDimValue(value, idx) { var v = value; if (util_1.isArray(v)) { if (labelCfg.content.length === 1) { // 如果仅一个 label,多个 y, 取最后一个 y if (v.length <= 2) { v = v[value.length - 1]; } else { v = avg(v); } } else { v = v[idx]; } } return v; } var label = { content: labelCfg.content[index], x: 0, y: 0, start: { x: 0, y: 0 }, color: '#fff', }; // 多边形场景,多用于地图 if (mappingData && this.geometry.type === 'polygon') { var centroid = graphics_1.getPolygonCentroid(mappingData.x, mappingData.y); label.x = centroid[0]; label.y = centroid[1]; } else { label.x = getDimValue(mappingData.x, index); label.y = getDimValue(mappingData.y, index); } // 处理漏斗图文本位置 var shape = util_1.isArray(mappingData.shape) ? mappingData.shape[0] : mappingData.shape; if (shape === 'funnel' || shape === 'pyramid') { var nextPoints = util_1.get(mappingData, 'nextPoints'); var points = util_1.get(mappingData, 'points'); if (nextPoints) { // 非漏斗图底部 var point1 = coordinate.convert(points[1]); var point2 = coordinate.convert(nextPoints[1]); label.x = (point1.x + point2.x) / 2; label.y = (point1.y + point2.y) / 2; } else if (shape === 'pyramid') { var point1 = coordinate.convert(points[1]); var point2 = coordinate.convert(points[2]); label.x = (point1.x + point2.x) / 2; label.y = (point1.y + point2.y) / 2; } } if (labelCfg.position) { // 如果 label 支持 position 属性 this.setLabelPosition(label, mappingData, index, labelCfg.position); } var offsetPoint = this.getLabelOffset(labelCfg, index, total); label.start = { x: label.x, y: label.y }; label.x += offsetPoint.x; label.y += offsetPoint.y; label.color = mappingData.color; return label; }; /** * 获取文本的对齐方式 * @param item * @param index * @param total * @returns */ GeometryLabel.prototype.getLabelAlign = function (item, index, total) { var align = 'center'; var coordinate = this.getCoordinate(); if (coordinate.isTransposed) { var offset = this.getDefaultOffset(item.offset); if (offset < 0) { align = 'right'; } else if (offset === 0) { align = 'center'; } else { align = 'left'; } if (total > 1 && index === 0) { if (align === 'right') { align = 'left'; } else if (align === 'left') { align = 'right'; } } } return align; }; /** * 获取每一个 label 的唯一 id * @param mappingData label 对应的图形的绘制数据 */ GeometryLabel.prototype.getLabelId = function (mappingData) { var geometry = this.geometry; var type = geometry.type; var xScale = geometry.getXScale(); var yScale = geometry.getYScale(); var origin = mappingData[constant_1.FIELD_ORIGIN]; // 原始数据 var labelId = geometry.getElementId(mappingData); if (type === 'line' || type === 'area') { // 折线图以及区域图,一条线会对应一组数据,即多个 labels,为了区分这些 labels,需要在 line id 的前提下加上 x 字段值 labelId += " " + origin[xScale.field]; } else if (type === 'path') { // path 路径图,无序,有可能存在相同 x 不同 y 的情况,需要通过 x y 来确定唯一 id labelId += " " + origin[xScale.field] + "-" + origin[yScale.field]; } return labelId; }; // 获取 labels 组件 GeometryLabel.prototype.getLabelsRenderer = function () { var _a = this.geometry, labelsContainer = _a.labelsContainer, labelOption = _a.labelOption, canvasRegion = _a.canvasRegion, animateOption = _a.animateOption; var coordinate = this.geometry.coordinate; var labelsRenderer = this.labelsRenderer; if (!labelsRenderer) { labelsRenderer = new labels_1.default({ container: labelsContainer, layout: util_1.get(labelOption, ['cfg', 'layout'], { type: this.defaultLayout, }), }); this.labelsRenderer = labelsRenderer; } labelsRenderer.region = canvasRegion; // 设置动画配置,如果 geometry 的动画关闭了,那么 label 的动画也会关闭 labelsRenderer.animate = animateOption ? animate_1.getDefaultAnimateCfg('label', coordinate) : false; return labelsRenderer; }; GeometryLabel.prototype.getLabelCfgs = function (mapppingArray) { var _this = this; var geometry = this.geometry; var defaultLabelCfg = this.getDefaultLabelCfg(); var type = geometry.type, theme = geometry.theme, labelOption = geometry.labelOption, scales = geometry.scales, coordinate = geometry.coordinate; var _a = labelOption, fields = _a.fields, callback = _a.callback, cfg = _a.cfg; var labelScales = fields.map(function (field) { return scales[field]; }); var labelCfgs = []; util_1.each(mapppingArray, function (mappingData, index) { var origin = mappingData[constant_1.FIELD_ORIGIN]; // 原始数据 var originText = _this.getLabelText(origin, labelScales); var callbackCfg; if (callback) { // 当同时配置了 callback 和 cfg 时,以 callback 为准 var originValues = fields.map(function (field) { return origin[field]; }); callbackCfg = callback.apply(void 0, originValues); if (util_1.isNil(callbackCfg)) { labelCfgs.push(null); return; } } var labelCfg = tslib_1.__assign(tslib_1.__assign({ id: _this.getLabelId(mappingData), data: origin, // 存储原始数据 mappingData: mappingData, coordinate: coordinate }, cfg), callbackCfg); var content = labelCfg.content; if (util_1.isFunction(content)) { labelCfg.content = content(origin, mappingData, index); } else if (util_1.isUndefined(content)) { // 用户未配置 content,则默认为映射的第一个字段的值 labelCfg.content = originText[0]; } if (util_1.isFunction(labelCfg.position)) { labelCfg.position = labelCfg.position(origin, mappingData, index); } if (type === 'polygon' || (labelCfg.offset < 0 && !['line', 'point', 'path'].includes(type))) { // polygon 或者 offset 小于 0 时,文本展示在图形内部,将其颜色设置为 白色 labelCfg = util_1.deepMix({}, defaultLabelCfg, theme.innerLabels, labelCfg); } else { labelCfg = util_1.deepMix({}, defaultLabelCfg, theme.labels, labelCfg); } labelCfgs.push(labelCfg); }); return labelCfgs; }; GeometryLabel.prototype.getLabelText = function (origin, scales) { var labelTexts = []; util_1.each(scales, function (scale) { var value = origin[scale.field]; if (util_1.isArray(value)) { value = value.map(function (subVal) { return scale.getText(subVal); }); } else { value = scale.getText(value); } if (util_1.isNil(value) || value === '') { labelTexts.push(null); } else { labelTexts.push(value); } }); return labelTexts; }; GeometryLabel.prototype.getOffsetVector = function (offset) { if (offset === void 0) { offset = 0; } var coordinate = this.getCoordinate(); // 如果 x,y 翻转,则偏移 x,否则偏移 y return coordinate.isTransposed ? coordinate.applyMatrix(offset, 0) : coordinate.applyMatrix(0, offset); }; GeometryLabel.prototype.getGeometryShapes = function () { var geometry = this.geometry; var shapes = {}; util_1.each(geometry.elementsMap, function (element, id) { shapes[id] = element.shape; }); // 因为有可能 shape 还在进行动画,导致 shape.getBBox() 获取到的值不是最终态,所以需要从 offscreenGroup 获取 util_1.each(geometry.getOffscreenGroup().getChildren(), function (child) { var id = geometry.getElementId(child.get('origin').mappingData); shapes[id] = child; }); return shapes; }; return GeometryLabel; }()); exports.default = GeometryLabel; },{"../../animate":217,"../../component/labels":236,"../../constant":237,"../../util/graphics":375,"@antv/util":803,"tslib":385}],256:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerGeometryLabelLayout = exports.getGeometryLabelLayout = exports.registerGeometryLabel = exports.getGeometryLabel = void 0; var GEOMETRY_LABELS_MAP = {}; var GEOMETRY_LABELS_LAYOUT_MAP = {}; /** * 获取 `type` 对应的 [[GeometryLabel]] 类 * @param type * @returns */ function getGeometryLabel(type) { return GEOMETRY_LABELS_MAP[type.toLowerCase()]; } exports.getGeometryLabel = getGeometryLabel; /** * 注册定义的 GeometryLabel 类 * @param type GeometryLabel 类型名称 * @param ctor GeometryLabel 类 */ function registerGeometryLabel(type, ctor) { GEOMETRY_LABELS_MAP[type.toLowerCase()] = ctor; } exports.registerGeometryLabel = registerGeometryLabel; /** * 获取 `type` 对应的 [[GeometryLabelsLayoutFn]] label 布局函数 * @param type 布局函数名称 * @returns */ function getGeometryLabelLayout(type) { return GEOMETRY_LABELS_LAYOUT_MAP[type.toLowerCase()]; } exports.getGeometryLabelLayout = getGeometryLabelLayout; /** * 注册定义的 label 布局函数 * @param type label 布局函数名称 * @param layoutFn label 布局函数 */ function registerGeometryLabelLayout(type, layoutFn) { GEOMETRY_LABELS_LAYOUT_MAP[type.toLowerCase()] = layoutFn; } exports.registerGeometryLabelLayout = registerGeometryLabelLayout; },{}],257:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); /** * 柱状图 label */ var IntervalLabel = /** @class */ (function (_super) { tslib_1.__extends(IntervalLabel, _super); function IntervalLabel() { return _super !== null && _super.apply(this, arguments) || this; } IntervalLabel.prototype.setLabelPosition = function (labelPointCfg, mappingData, index, position) { var coordinate = this.getCoordinate(); var transposed = coordinate.isTransposed; var shapePoints = mappingData.points; var point0 = coordinate.convert(shapePoints[0]); var point1 = coordinate.convert(shapePoints[2]); var flag = transposed ? -1 : 1; var width = ((point0.x - point1.x) / 2) * flag; var height = ((point0.y - point1.y) / 2) * flag; switch (position) { case 'right': if (!transposed) { labelPointCfg.x -= width; labelPointCfg.y += height; } labelPointCfg.textAlign = util_1.get(labelPointCfg, 'textAlign', 'left'); break; case 'left': if (transposed) { labelPointCfg.x -= width * 2; } else { labelPointCfg.x += width; labelPointCfg.y += height; } labelPointCfg.textAlign = util_1.get(labelPointCfg, 'textAlign', 'right'); break; case 'bottom': if (transposed) { labelPointCfg.x -= width; labelPointCfg.y -= height; } else { labelPointCfg.y += height * 2; } labelPointCfg.textAlign = util_1.get(labelPointCfg, 'textAlign', 'center'); labelPointCfg.textBaseline = util_1.get(labelPointCfg, 'textBaseline', 'top'); break; case 'middle': if (transposed) { labelPointCfg.x -= width; } else { labelPointCfg.y += height; } labelPointCfg.textAlign = util_1.get(labelPointCfg, 'textAlign', 'center'); break; case 'top': if (transposed) { labelPointCfg.x -= width; labelPointCfg.y += height; } labelPointCfg.textAlign = util_1.get(labelPointCfg, 'textAlign', 'center'); labelPointCfg.textBaseline = util_1.get(labelPointCfg, 'textBaseline', 'bottom'); break; default: break; } }; return IntervalLabel; }(base_1.default)); exports.default = IntervalLabel; },{"./base":255,"@antv/util":803,"tslib":385}],258:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.limitInCanvas = void 0; var util_1 = require("@antv/util"); var transform_1 = require("../../../util/transform"); /** * @ignore * 将 label 限制在画布范围内,简单得将超出画布的 label 往画布内调整 * @param labels * @param cfg */ function limitInCanvas(items, labels, shapes, region) { util_1.each(labels, function (label) { var regionMinX = region.minX, regionMinY = region.minY, regionMaxX = region.maxX, regionMaxY = region.maxY; var _a = label.getCanvasBBox(), minX = _a.minX, minY = _a.minY, maxX = _a.maxX, maxY = _a.maxY, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var finalX = x; var finalY = y; if (minX < regionMinX || maxX < regionMinX) { // 超出左侧 finalX = regionMinX; } if (minY < regionMinY || maxY < regionMinY) { // 超出顶部 finalY = regionMinY; } if (minX > regionMaxX) { // 整体超出右侧 finalX = regionMaxX - width; } else if (maxX > regionMaxX) { // 超出右侧 finalX = finalX - (maxX - regionMaxX); } if (minY > regionMaxY) { // 整体超出顶部 finalY = regionMaxY - height; } else if (maxY > regionMaxY) { // 超出底部 finalY = finalY - (maxY - regionMaxY); } if (finalX !== x || finalY !== y) { transform_1.translate(label, finalX - x, finalY - y); } }); } exports.limitInCanvas = limitInCanvas; },{"../../../util/transform":384,"@antv/util":803}],259:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.limitInShape = void 0; var util_1 = require("@antv/util"); /** * @ignore * 根据图形元素以及 label 的 bbox 进行调整,如果 label 超出了 shape 的 bbox 则不展示 */ function limitInShape(items, labels, shapes, region) { util_1.each(labels, function (label, index) { var labelBBox = label.getCanvasBBox(); // 文本有可能发生旋转 var shapeBBox = shapes[index].getBBox(); if (labelBBox.minX < shapeBBox.minX || labelBBox.minY < shapeBBox.minY || labelBBox.maxX > shapeBBox.maxX || labelBBox.maxY > shapeBBox.maxY) { label.remove(true); // 超出则不展示 } }); } exports.limitInShape = limitInShape; },{"@antv/util":803}],260:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.overlap = exports.fixedOverlap = void 0; var util_1 = require("@antv/util"); var MAX_TIMES = 100; /** * @ignore * Greedy 贪婪算法 */ var Greedy = /** @class */ (function () { function Greedy(cfg) { if (cfg === void 0) { cfg = {}; } this.bitmap = {}; var _a = cfg.xGap, xGap = _a === void 0 ? 1 : _a, _b = cfg.yGap, yGap = _b === void 0 ? 8 : _b; this.xGap = xGap; this.yGap = yGap; } Greedy.prototype.hasGap = function (bbox) { var hasGap = true; var bitmap = this.bitmap; var minX = Math.round(bbox.minX); var maxX = Math.round(bbox.maxX); var minY = Math.round(bbox.minY); var maxY = Math.round(bbox.maxY); for (var i = minX; i <= maxX; i += 1) { if (!bitmap[i]) { bitmap[i] = {}; continue; } if (i === minX || i === maxX) { for (var j = minY; j <= maxY; j++) { if (bitmap[i][j]) { hasGap = false; break; } } } else { if (bitmap[i][minY] || bitmap[i][maxY]) { hasGap = false; break; } } } return hasGap; }; Greedy.prototype.fillGap = function (bbox) { var bitmap = this.bitmap; var minX = Math.round(bbox.minX); var maxX = Math.round(bbox.maxX); var minY = Math.round(bbox.minY); var maxY = Math.round(bbox.maxY); // filling grid for (var i = minX; i <= maxX; i += 1) { if (!bitmap[i]) { bitmap[i] = {}; } } for (var i = minX; i <= maxX; i += this.xGap) { for (var j = minY; j <= maxY; j += this.yGap) { bitmap[i][j] = true; } bitmap[i][maxY] = true; } // filling y edges if (this.yGap !== 1) { for (var i = minY; i <= maxY; i += 1) { bitmap[minX][i] = true; bitmap[maxX][i] = true; } } // filling x edges if (this.xGap !== 1) { for (var i = minX; i <= maxX; i += 1) { bitmap[i][minY] = true; bitmap[i][maxY] = true; } } }; Greedy.prototype.destroy = function () { this.bitmap = {}; }; return Greedy; }()); function spiralFill(label, greedy, maxTimes) { if (maxTimes === void 0) { maxTimes = MAX_TIMES; } var dt = -1; var _a = label.attr(), x = _a.x, y = _a.y; var bbox = label.getCanvasBBox(); var maxDelta = Math.sqrt(bbox.width * bbox.width + bbox.height * bbox.height); var dxdy; var t = -dt; var dx = 0; var dy = 0; var f = function (param) { var nt = param * 0.1; return [nt * Math.cos(nt), nt * Math.sin(nt)]; }; if (greedy.hasGap(bbox)) { greedy.fillGap(bbox); return true; } var canFill = false; var times = 0; var accessedCache = {}; while (Math.min(Math.abs(dx), Math.abs(dy)) < maxDelta && times < maxTimes) { dxdy = f((t += dt)); dx = ~~dxdy[0]; dy = ~~dxdy[1]; if ((!dx && !dy) || accessedCache[dx + "-" + dy]) { continue; } label.attr({ x: x + dx, y: y + dy }); if (dx + dy < 0) { label.attr('textAlign', 'right'); } times++; if (greedy.hasGap(label.getCanvasBBox())) { greedy.fillGap(label.getCanvasBBox()); canFill = true; accessedCache[dx + "-" + dy] = true; break; } } return canFill; } /* * 根据如下规则尝试放置label * 5 * ------------------ * | 1 | 0 | * 8 —————————4———————— 7 * | 2 | 3 | * —————————————————— * 6 */ function adjustLabelPosition(label, x, y, index) { var _a = label.getCanvasBBox(), width = _a.width, height = _a.height; var attrs = { x: x, y: y, textAlign: 'center', }; switch (index) { case 0: attrs.y -= height + 1; attrs.x += 1; attrs.textAlign = 'left'; break; case 1: attrs.y -= height + 1; attrs.x -= 1; attrs.textAlign = 'right'; break; case 2: attrs.y += height + 1; attrs.x -= 1; attrs.textAlign = 'right'; break; case 3: attrs.y += height + 1; attrs.x += 1; attrs.textAlign = 'left'; break; case 5: attrs.y -= height * 2 + 2; break; case 6: attrs.y += height * 2 + 2; break; case 7: attrs.x += width + 1; attrs.textAlign = 'left'; break; case 8: attrs.x -= width + 1; attrs.textAlign = 'right'; break; default: break; } label.attr(attrs); return label.getCanvasBBox(); } /** * @ignore * label 防遮挡布局:在不改变 label 位置的情况下对相互重叠的 label 进行调整。 * 不同于 'overlap' 类型的布局,该布局不会对 label 的位置进行偏移调整。 * @param labels 参与布局调整的 label 数组集合 */ function fixedOverlap(items, labels, shapes, region) { var greedy = new Greedy(); util_1.each(labels, function (label) { var labelShape = label.find(function (shape) { return shape.get('type') === 'text'; }); if (!spiralFill(labelShape, greedy)) { label.remove(true); } }); greedy.destroy(); } exports.fixedOverlap = fixedOverlap; /** * @ignore * label 防遮挡布局:为了防止 label 之间相互覆盖同时保证尽可能多 的 label 展示,通过尝试将 label 向**四周偏移**来剔除放不下的 label * @param labels 参与布局调整的 label 数组集合 */ function overlap(items, labels, shapes, region) { var greedy = new Greedy(); util_1.each(labels, function (label) { var labelShape = label.find(function (shape) { return shape.get('type') === 'text'; }); var _a = labelShape.attr(), x = _a.x, y = _a.y; var canFill = false; for (var i = 0; i <= 8; i++) { var bbox = adjustLabelPosition(labelShape, x, y, i); if (greedy.hasGap(bbox)) { greedy.fillGap(bbox); canFill = true; break; } } if (!canFill) { label.remove(true); } }); greedy.destroy(); } exports.overlap = overlap; },{"@antv/util":803}],261:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.distribute = void 0; var util_1 = require("@antv/util"); var graphics_1 = require("../../../../util/graphics"); /** label text和line距离 4px */ var MARGIN = 4; function antiCollision(labelShapes, labels, lineHeight, plotRange, center, isRight) { // adjust y position of labels to avoid overlapping var overlapping = true; var start = plotRange.start; var end = plotRange.end; var startY = Math.min(start.y, end.y); var totalHeight = Math.abs(start.y - end.y); var i; var maxY = 0; var minY = Number.MIN_VALUE; var boxes = labels.map(function (label) { if (label.y > maxY) { maxY = label.y; } if (label.y < minY) { minY = label.y; } return { size: lineHeight, targets: [label.y - startY], }; }); minY -= startY; if (maxY - startY > totalHeight) { totalHeight = maxY - startY; } while (overlapping) { /* eslint no-loop-func: 0 */ boxes.forEach(function (box) { var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2; box.pos = Math.min(Math.max(minY, target - box.size / 2), totalHeight - box.size); // box.pos = Math.max(0, target - box.size / 2); }); // detect overlapping and join boxes overlapping = false; i = boxes.length; while (i--) { if (i > 0) { var previousBox = boxes[i - 1]; var box = boxes[i]; if (previousBox.pos + previousBox.size > box.pos) { // overlapping previousBox.size += box.size; previousBox.targets = previousBox.targets.concat(box.targets); // overflow, shift up if (previousBox.pos + previousBox.size > totalHeight) { previousBox.pos = totalHeight - previousBox.size; } boxes.splice(i, 1); // removing box overlapping = true; } } } } i = 0; // step 4: normalize y and adjust x boxes.forEach(function (b) { var posInCompositeBox = startY + lineHeight / 2; // middle of the label b.targets.forEach(function () { labels[i].y = b.pos + posInCompositeBox; posInCompositeBox += lineHeight; i++; }); }); var labelsMap = {}; for (var _i = 0, labelShapes_1 = labelShapes; _i < labelShapes_1.length; _i++) { var labelShape = labelShapes_1[_i]; labelsMap[labelShape.get('id')] = labelShape; } // (x - cx)^2 + (y - cy)^2 = totalR^2 labels.forEach(function (label) { var rPow2 = label.r * label.r; var dyPow2 = Math.pow(Math.abs(label.y - center.y), 2); if (rPow2 < dyPow2) { label.x = center.x; } else { var dx = Math.sqrt(rPow2 - dyPow2); if (!isRight) { // left label.x = center.x - dx; } else { // right label.x = center.x + dx; } } // adjust labelShape var labelShape = labelsMap[label.id]; labelShape.attr('x', label.x); labelShape.attr('y', label.y); // because group could not effect text-shape, should set text-shape position manually var textShape = util_1.find(labelShape.getChildren(), function (ele) { return ele.get('type') === 'text'; }); // @ts-ignore if (textShape) { textShape.attr('y', label.y); textShape.attr('x', label.x); } }); } function distribute(items, labels, shapes, region) { var offset = items[0] ? items[0].offset : 0; var coordinate = labels[0].get('coordinate'); var radius = coordinate.getRadius(); var center = coordinate.getCenter(); if (offset > 0) { // const lineHeight = get(this.geometry.theme, ['pieLabels', 'labelHeight'], 14); var lineHeight_1 = 14; // TODO var totalR = radius + offset; var totalHeight_1 = totalR * 2 + lineHeight_1 * 2; var plotRange_1 = { start: coordinate.start, end: coordinate.end, }; // step 1: separate labels var halves_1 = [ [], [], ]; items.forEach(function (labelItem) { if (!labelItem) { return; } if (labelItem.textAlign === 'right') { // left halves_1[0].push(labelItem); } else { // right or center will be put on the right side halves_1[1].push(labelItem); } }); halves_1.forEach(function (half, index) { // step 2: reduce labels var maxLabelsCountForOneSide = totalHeight_1 / lineHeight_1; if (half.length > maxLabelsCountForOneSide) { half.sort(function (a, b) { // sort by percentage DESC return b['..percent'] - a['..percent']; }); half.splice(maxLabelsCountForOneSide, half.length - maxLabelsCountForOneSide); } // step 3: distribute position (x and y) half.sort(function (a, b) { // sort by y ASC return a.y - b.y; }); antiCollision(labels, half, lineHeight_1, plotRange_1, center, index); }); } // 配置 labelLine util_1.each(items, function (item) { if (item && item.labelLine) { var distance = item.offset; var angle = item.angle; // 贴近圆周 var startPoint = graphics_1.polarToCartesian(center.x, center.y, radius, angle); var innerPoint = graphics_1.polarToCartesian(center.x, center.y, radius + distance / 2, angle); var itemX = item.x + util_1.get(item, 'offsetX', 0); var itemY = item.y + util_1.get(item, 'offsetY', 0); var endPoint = { x: itemX - Math.cos(angle) * MARGIN, y: itemY - Math.sin(angle) * MARGIN, }; if (!util_1.isObject(item.labelLine)) { // labelLine: true item.labelLine = {}; } item.labelLine.path = [ "M " + startPoint.x, startPoint.y + " Q" + innerPoint.x, innerPoint.y + " " + endPoint.x, endPoint.y, ].join(','); } }); } exports.distribute = distribute; },{"../../../../util/graphics":375,"@antv/util":803}],262:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pieOuterLabelLayout = void 0; var util_1 = require("@antv/util"); var graphics_1 = require("../../../../util/graphics"); /** label text和line距离 4px */ var MARGIN = 4; function antiCollision(labelShapes, labels, labelHeight, plotRange, center, radius, isRight) { // sorted by y, mutable labels.sort(function (a, b) { return a.y - b.y; }); // adjust y position of labels to avoid overlapping var start = plotRange.start; var end = plotRange.end; var startY = Math.min(start.y, end.y); var endY = Math.max(start.y, end.y); var i; var boxes = labels.map(function (label) { return { content: label.content, size: labelHeight, pos: label.y, targets: [label.y], }; }); var maxPos = Math.max.apply(Math, boxes.map(function (b) { return b.pos; })); var minPos = Math.min.apply(Math, boxes.map(function (b) { return b.pos; })); /** * when in right, shift from up to down */ if (isRight) { var minY = Math.min(minPos, endY - (boxes.length - 1) * labelHeight); var maxY = Math.max(minY + boxes.length * labelHeight, maxPos + labelHeight); var overlapping = true; while (overlapping) { // detect overlapping and join boxes overlapping = false; i = boxes.length; while (i--) { if (i > 0) { var previousBox = boxes[i - 1]; var box = boxes[i]; // overlap if (previousBox.pos + previousBox.size > box.pos) { if (box.pos + i * labelHeight < maxY) { // join boxes previousBox.size += box.size; previousBox.targets = previousBox.targets.concat(box.targets); // removing box boxes.splice(i, 1); } else { previousBox.pos = box.pos - previousBox.size; } overlapping = true; } } } } } else { var maxY = Math.max(startY + (boxes.length - 1) * labelHeight, maxPos); var minY = Math.min(minPos, maxY - (boxes.length - 1) * labelHeight); var overlapping = true; while (overlapping) { // detect overlapping and join boxes overlapping = false; i = boxes.length; while (i--) { if (i > 0) { var previousBox = boxes[i - 1]; var box = boxes[i]; // overlap if (previousBox.pos + previousBox.size > box.pos) { if (previousBox.pos - minY > i * labelHeight) { previousBox.pos -= previousBox.size; } else { // join boxes previousBox.size += box.size; previousBox.targets = previousBox.targets.concat(box.targets); // removing box boxes.splice(i, 1); } overlapping = true; } } } } } // step 4: normalize y and adjust x i = 0; boxes.forEach(function (b) { var posInCompositeBox = b.pos; b.targets.forEach(function () { labels[i].y = posInCompositeBox; posInCompositeBox += labelHeight; i++; }); }); var labelsMap = {}; for (var _i = 0, labelShapes_1 = labelShapes; _i < labelShapes_1.length; _i++) { var labelShape = labelShapes_1[_i]; labelsMap[labelShape.get('id')] = labelShape; } // (x - cx)^2 + (y - cy)^2 = totalR^2 var totalR = (Math.max.apply(Math, labels.map(function (l) { return l.y; })) - Math.min.apply(Math, labels.map(function (l) { return l.y; }))) / 2; totalR = Math.max(totalR, radius); labels.forEach(function (label) { var labelShape = labelsMap[label.id]; // because group could not effect text-shape, should set text-shape position manually var textShape = labelShape.find(function (child) { return child.get('type') === 'text'; }); // textShape 发生过调整 if (textShape && textShape.attr('y') !== label.y) { var rPow2 = totalR * totalR; var dyPow2 = Math.pow(Math.abs(label.y - center.y), 2); if (rPow2 < dyPow2) { label.x = center.x; } else { var dx = Math.sqrt(rPow2 - dyPow2); if (!isRight) { // left label.x = center.x - dx; } else { // right label.x = center.x + dx; } } } // adjust labelShape labelShape.attr('x', label.x); labelShape.attr('y', label.y); // @ts-ignore if (textShape) { textShape.attr('y', label.y); textShape.attr('x', label.x); } }); } function pieOuterLabelLayout(items, labels, shapes, region) { var offset = items[0] ? items[0].offset : 0; var coordinate = labels[0].get('coordinate'); var radius = coordinate.getRadius(); var center = coordinate.getCenter(); if (offset > 0) { // note labelHeight 可以控制 label 的行高 var lineHeight_1 = util_1.get(items[0], 'labelHeight', 14); var totalR_1 = radius + offset; var totalHeight_1 = totalR_1 * 2 + lineHeight_1 * 2; var plotRange_1 = { start: coordinate.start, end: coordinate.end, }; // step 1: separate labels var halves_1 = [ [], [], ]; items.forEach(function (labelItem) { if (!labelItem) { return; } if (labelItem.x < center.x) { // left halves_1[0].push(labelItem); } else { // right or center will be put on the right side halves_1[1].push(labelItem); } }); halves_1.forEach(function (half, index) { // step 2: reduce labels var maxLabelsCountForOneSide = totalHeight_1 / lineHeight_1; if (half.length > maxLabelsCountForOneSide) { half.sort(function (a, b) { // sort by percentage DESC // fixme-xinming 目前还获取不到,需要使用 scale 去获取 percent return b['data.percent'] - a['data.percent']; }); var hidden = half.splice(maxLabelsCountForOneSide, half.length - maxLabelsCountForOneSide + 1); hidden.forEach(function (l) { var idx = labels.findIndex(function (item) { return item.get('id') === l.id; }); if (labels[idx]) { labels[idx].remove(true); // 同时移除 labels.splice(idx, 1); } }); } antiCollision(labels, half, lineHeight_1, plotRange_1, center, totalR_1, index === 1); }); } // 配置 labelLine util_1.each(items, function (item) { if (item && item.labelLine) { var angle = item.angle; // 贴近圆周 var startPoint = graphics_1.polarToCartesian(center.x, center.y, radius, angle); var itemX = item.x + util_1.get(item, 'offsetX', 0) * (Math.cos(angle) > 0 ? 1 : -1); var itemY = item.y + util_1.get(item, 'offsetY', 0) * (Math.sin(angle) > 0 ? 1 : -1); var endPoint = { x: itemX - Math.cos(angle) * MARGIN, y: itemY - Math.sin(angle) * MARGIN, }; var smoothConnector = item.labelLine.smooth; var path = []; var dx = endPoint.x - center.x; var dy = endPoint.y - center.y; var endAngle = Math.atan(dy / dx); // 第三象限 & 第四象限 if (dx < 0) { endAngle += Math.PI; } // 默认 smooth, undefined 也为 smooth if (smoothConnector === false) { if (!util_1.isObject(item.labelLine)) { // labelLine: true item.labelLine = {}; } // 表示弧线的方向,0 表示从起点到终点沿逆时针画弧, 1 表示顺时针 var sweepFlag = 0; // 第一象限 if ((angle < 0 && angle > -Math.PI / 2) || angle > Math.PI * 1.5) { if (endPoint.y > startPoint.y) { sweepFlag = 1; } } // 第二象限 if (angle >= 0 && angle < Math.PI / 2) { if (endPoint.y > startPoint.y) { sweepFlag = 1; } } // 第三象限 if (angle >= Math.PI / 2 && angle < Math.PI) { if (startPoint.y > endPoint.y) { sweepFlag = 1; } } // 第四象限 if (angle < -Math.PI / 2 || (angle >= Math.PI && angle < Math.PI * 1.5)) { if (startPoint.y > endPoint.y) { sweepFlag = 1; } } var distance = offset / 2 > 4 ? 4 : Math.max(offset / 2 - 1, 0); var breakPoint = graphics_1.polarToCartesian(center.x, center.y, radius + distance, angle); // 圆弧的结束点 var breakPoint3 = graphics_1.polarToCartesian(center.x, center.y, radius + offset / 2, endAngle); /** * @example * M 100 100 L100 90 A 50 50 0 0 0 150 50 * 移动至 (100, 100), 连接到 (100, 90), 以 (50, 50) 为圆心,绘制圆弧至 (150, 50); * A 命令的第 4 个参数 large-arc-flag, 决定弧线是大于还是小于 180 度: 0 表示小角度弧,1 表示大角 * 第 5 个参数: 是否顺时针绘制 */ // 默认小弧 var largeArcFlag = 0; // step1: 移动至起点 path.push("M " + startPoint.x + " " + startPoint.y); // step2: 连接拐点 path.push("L " + breakPoint.x + " " + breakPoint.y); // step3: 绘制圆弧 至 结束点 path.push("A " + center.x + " " + center.y + " 0 " + largeArcFlag + " " + sweepFlag + " " + breakPoint3.x + " " + breakPoint3.y); // step4: 连接结束点 path.push("L " + endPoint.x + " " + endPoint.y); } else { var breakPoint = graphics_1.polarToCartesian(center.x, center.y, radius + (offset / 2 > 4 ? 4 : Math.max(offset / 2 - 1, 0)), angle); // G2 旧的拉线 // path.push('Q', `${breakPoint.x}`, `${breakPoint.y}`, `${endPoint.x}`, `${endPoint.y}`); var xSign = startPoint.x < center.x ? 1 : -1; // step1: 连接结束点 path.push("M " + endPoint.x + " " + endPoint.y); var slope1 = (startPoint.y - center.y) / (startPoint.x - center.x); var slope2 = (endPoint.y - center.y) / (endPoint.x - center.x); if (Math.abs(slope1 - slope2) > Math.pow(Math.E, -16)) { // step2: 绘制 curve line (起点 & 结合点与圆心的斜率不等时, 由于存在误差, 使用近似处理) path.push.apply(path, [ 'C', endPoint.x + xSign * 4, endPoint.y, 2 * breakPoint.x - startPoint.x, 2 * breakPoint.y - startPoint.y, startPoint.x, startPoint.y, ]); } // step3: 连接至起点 path.push("L " + startPoint.x + " " + startPoint.y); } item.labelLine.path = path.join(' '); } }); } exports.pieOuterLabelLayout = pieOuterLabelLayout; },{"../../../../util/graphics":375,"@antv/util":803}],263:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var coordinate_1 = require("../../util/coordinate"); var graphics_1 = require("../../util/graphics"); var polar_1 = tslib_1.__importDefault(require("./polar")); /** * 饼图 label */ var PieLabel = /** @class */ (function (_super) { tslib_1.__extends(PieLabel, _super); function PieLabel(geometry) { var _this = _super.call(this, geometry) || this; _this.defaultLayout = 'distribute'; return _this; } PieLabel.prototype.getDefaultLabelCfg = function () { return util_1.get(this.geometry.theme, 'pieLabels', {}); }; PieLabel.prototype.getDefaultOffset = function (offset) { return offset || 0; }; PieLabel.prototype.getLabelRotate = function (angle, offset, isLabelLimit) { var rotate; if (offset < 0) { rotate = angle; if (rotate > Math.PI / 2) { rotate = rotate - Math.PI; } if (rotate < -Math.PI / 2) { rotate = rotate + Math.PI; } } return rotate; }; PieLabel.prototype.getLabelAlign = function (point) { var coordinate = this.getCoordinate(); var center = coordinate.getCenter(); var align; if (point.angle <= Math.PI / 2 && point.x >= center.x) { align = 'left'; } else { align = 'right'; } var offset = this.getDefaultOffset(point.offset); if (offset <= 0) { if (align === 'right') { align = 'left'; } else { align = 'right'; } } return align; }; PieLabel.prototype.getArcPoint = function (point) { return point; }; PieLabel.prototype.getPointAngle = function (point) { var coordinate = this.getCoordinate(); var startPoint = { x: util_1.isArray(point.x) ? point.x[0] : point.x, y: point.y[0], }; var endPoint = { x: util_1.isArray(point.x) ? point.x[1] : point.x, y: point.y[1], }; var angle; var startAngle = coordinate_1.getAngleByPoint(coordinate, startPoint); if (point.points && point.points[0].y === point.points[1].y) { angle = startAngle; } else { var endAngle = coordinate_1.getAngleByPoint(coordinate, endPoint); if (startAngle >= endAngle) { // 100% pie slice endAngle = endAngle + Math.PI * 2; } angle = startAngle + (endAngle - startAngle) / 2; } return angle; }; PieLabel.prototype.getCirclePoint = function (angle, offset, p) { var coordinate = this.getCoordinate(); var center = coordinate.getCenter(); var r = coordinate.getRadius() + offset; return tslib_1.__assign(tslib_1.__assign({}, graphics_1.polarToCartesian(center.x, center.y, r, angle)), { angle: angle, r: r }); }; return PieLabel; }(polar_1.default)); exports.default = PieLabel; },{"../../util/coordinate":371,"../../util/graphics":375,"./polar":264,"@antv/util":803,"tslib":385}],264:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var coordinate_1 = require("../../util/coordinate"); var coordinate_2 = require("../../util/coordinate"); var base_1 = tslib_1.__importDefault(require("./base")); var HALF_PI = Math.PI / 2; /** * 极坐标下的图形 label */ var PolarLabel = /** @class */ (function (_super) { tslib_1.__extends(PolarLabel, _super); function PolarLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** * @override * 获取文本的对齐方式 * @param point */ PolarLabel.prototype.getLabelAlign = function (point) { var coordinate = this.getCoordinate(); var align; if (point.labelEmit) { align = point.angle <= Math.PI / 2 && point.angle >= -Math.PI / 2 ? 'left' : 'right'; } else if (!coordinate.isTransposed) { align = 'center'; } else { var center = coordinate.getCenter(); var offset = this.getDefaultOffset(point.offset); if (Math.abs(point.x - center.x) < 1) { align = 'center'; } else if (point.angle > Math.PI || point.angle <= 0) { align = offset > 0 ? 'left' : 'right'; } else { align = offset > 0 ? 'right' : 'left'; } } return align; }; /** * @override * 获取 label 的位置 * @param labelCfg * @param mappingData * @param index */ PolarLabel.prototype.getLabelPoint = function (labelCfg, mappingData, index) { var factor = 1; var arcPoint; var content = labelCfg.content[index]; if (this.isToMiddle(mappingData)) { arcPoint = this.getMiddlePoint(mappingData.points); } else { if (labelCfg.content.length === 1 && index === 0) { index = 1; } else if (index === 0) { factor = -1; } arcPoint = this.getArcPoint(mappingData, index); } var offset = this.getDefaultOffset(labelCfg.offset) * factor; var middleAngle = this.getPointAngle(arcPoint); var isLabelEmit = labelCfg.labelEmit; var labelPositionCfg = this.getCirclePoint(middleAngle, offset, arcPoint, isLabelEmit); if (labelPositionCfg.r === 0) { // 如果文本位置位于圆心,则不展示 labelPositionCfg.content = ''; } else { labelPositionCfg.content = content; labelPositionCfg.angle = middleAngle; labelPositionCfg.color = mappingData.color; } labelPositionCfg.rotate = labelCfg.autoRotate ? this.getLabelRotate(middleAngle, offset, isLabelEmit) : labelCfg.rotate; labelPositionCfg.start = { x: arcPoint.x, y: arcPoint.y, }; return labelPositionCfg; }; /** * 获取圆弧的位置 */ PolarLabel.prototype.getArcPoint = function (mappingData, index) { if (index === void 0) { index = 0; } if (!util_1.isArray(mappingData.x) && !util_1.isArray(mappingData.y)) { return { x: mappingData.x, y: mappingData.y, }; } return { x: util_1.isArray(mappingData.x) ? mappingData.x[index] : mappingData.x, y: util_1.isArray(mappingData.y) ? mappingData.y[index] : mappingData.y, }; }; /** * 计算坐标线点在极坐标系下角度 * @param point */ PolarLabel.prototype.getPointAngle = function (point) { return coordinate_2.getAngleByPoint(this.getCoordinate(), point); }; /** * 获取坐标点与圆心形成的圆的位置信息 * @param angle * @param offset * @param point * @param isLabelEmit */ PolarLabel.prototype.getCirclePoint = function (angle, offset, point, isLabelEmit) { var coordinate = this.getCoordinate(); var center = coordinate.getCenter(); var r = coordinate_1.getDistanceToCenter(coordinate, point); if (r === 0) { return tslib_1.__assign(tslib_1.__assign({}, center), { r: r }); } var labelAngle = angle; if (coordinate.isTransposed && r > offset && !isLabelEmit) { var appendAngle = Math.asin(offset / (2 * r)); labelAngle = angle + appendAngle * 2; } else { r = r + offset; } return { x: center.x + r * Math.cos(labelAngle), y: center.y + r * Math.sin(labelAngle), r: r, }; }; /** * 获取 label 的旋转角度 * @param angle * @param offset * @param isLabelEmit */ PolarLabel.prototype.getLabelRotate = function (angle, offset, isLabelEmit) { var rotate = angle + HALF_PI; if (isLabelEmit) { rotate -= HALF_PI; } if (rotate) { if (rotate > HALF_PI) { rotate = rotate - Math.PI; } else if (rotate < -HALF_PI) { rotate = rotate + Math.PI; } } return rotate; }; // 获取中心的位置 PolarLabel.prototype.getMiddlePoint = function (points) { var coordinate = this.getCoordinate(); var count = points.length; var middlePoint = { x: 0, y: 0, }; util_1.each(points, function (point) { middlePoint.x += point.x; middlePoint.y += point.y; }); middlePoint.x /= count; middlePoint.y /= count; middlePoint = coordinate.convert(middlePoint); return middlePoint; }; // 是否居中 PolarLabel.prototype.isToMiddle = function (mappingData) { return mappingData.x.length > 2; }; return PolarLabel; }(base_1.default)); exports.default = PolarLabel; },{"../../util/coordinate":371,"./base":255,"@antv/util":803,"tslib":385}],265:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var path_1 = tslib_1.__importDefault(require("./path")); /** 引入 Path 对应的 ShapeFactory */ require("./shape/line"); /** * Line 几何标记。 * 常用于折线图的绘制。 */ var Line = /** @class */ (function (_super) { tslib_1.__extends(Line, _super); function Line(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'line'; var _a = cfg.sortable, sortable = _a === void 0 ? true : _a; // Line 默认会对数据按照 x 轴字段进行排序 _this.sortable = sortable; return _this; } return Line; }(path_1.default)); exports.default = Line; },{"./path":266,"./shape/line":288,"tslib":385}],266:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var constant_1 = require("../constant"); var base_1 = tslib_1.__importDefault(require("./base")); var element_1 = tslib_1.__importDefault(require("./element")); /** 引入对应的 ShapeFactory */ require("./shape/line"); var is_model_change_1 = require("./util/is-model-change"); /** * Path 几何标记。 * 用于绘制路径图等。 */ var Path = /** @class */ (function (_super) { tslib_1.__extends(Path, _super); function Path(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'path'; _this.shapeType = 'line'; var _a = cfg.connectNulls, connectNulls = _a === void 0 ? false : _a, _b = cfg.showSinglePoint, showSinglePoint = _b === void 0 ? true : _b; _this.connectNulls = connectNulls; _this.showSinglePoint = showSinglePoint; return _this; } /** * 创建所有的 Element 实例,对于 Path、Line、Area,一组数据对应一个 Element。 * @param mappingData * @param [isUpdate] * @returns elements */ Path.prototype.createElements = function (mappingData, index, isUpdate) { if (isUpdate === void 0) { isUpdate = false; } // Path 的每个 element 对应一组数据 var _a = this, lastElementsMap = _a.lastElementsMap, elementsMap = _a.elementsMap, elements = _a.elements, container = _a.container; var elementId = this.getElementId(mappingData); var shapeCfg = this.getShapeInfo(mappingData); var result = lastElementsMap[elementId]; if (!result) { var shapeFactory = this.getShapeFactory(); result = new element_1.default({ shapeFactory: shapeFactory, container: container, offscreenGroup: this.getOffscreenGroup(), }); result.geometry = this; result.animate = this.animateOption; result.draw(shapeCfg, isUpdate); // 绘制 shape } else { // element 已经创建 var preShapeCfg = result.getModel(); if (this.isCoordinateChanged || is_model_change_1.isModelChange(preShapeCfg, shapeCfg)) { result.animate = this.animateOption; // 通过绘制数据的变更来判断是否需要更新,因为用户有可能会修改图形属性映射 result.update(shapeCfg); // 更新对应的 element } delete lastElementsMap[elementId]; } elements.push(result); elementsMap[elementId] = result; return elements; }; /** * 获取组成一条线(一组数据)的所有点以及数据 * @param mappingData 映射后的数组 */ Path.prototype.getPointsAndData = function (mappingData) { var points = []; var data = []; for (var i = 0, len = mappingData.length; i < len; i++) { var obj = mappingData[i]; points.push({ x: obj.x, y: obj.y, }); data.push(obj[constant_1.FIELD_ORIGIN]); } return { points: points, data: data, }; }; Path.prototype.getShapeInfo = function (mappingData) { var shapeCfg = this.getDrawCfg(mappingData[0]); var _a = this.getPointsAndData(mappingData), points = _a.points, data = _a.data; shapeCfg.mappingData = mappingData; shapeCfg.data = data; shapeCfg.isStack = !!this.getAdjust('stack'); shapeCfg.points = points; shapeCfg.connectNulls = this.connectNulls; shapeCfg.showSinglePoint = this.showSinglePoint; return shapeCfg; }; return Path; }(base_1.default)); exports.default = Path; },{"../constant":237,"./base":250,"./element":252,"./shape/line":288,"./util/is-model-change":306,"tslib":385}],267:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("./base")); /** 引入 Point 对应的 ShapeFactory */ require("./shape/point"); /** * Point 几何标记。 * 常用于绘制点图。 */ var Point = /** @class */ (function (_super) { tslib_1.__extends(Point, _super); function Point() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'point'; _this.shapeType = 'point'; _this.generatePoints = true; return _this; } /** * 获取一个点的绘制信息。 * @param mappingDatum * @returns draw cfg */ Point.prototype.getDrawCfg = function (mappingDatum) { var shapeCfg = _super.prototype.getDrawCfg.call(this, mappingDatum); return tslib_1.__assign(tslib_1.__assign({}, shapeCfg), { isStack: !!this.getAdjust('stack') }); }; return Point; }(base_1.default)); exports.default = Point; },{"./base":250,"./shape/point":293,"tslib":385}],268:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); /** 引入 Path 对应的 ShapeFactory */ require("./shape/polygon"); /** * Polygon 几何标记。 * 常用于绘制色块图、日历图等。 */ var Polygon = /** @class */ (function (_super) { tslib_1.__extends(Polygon, _super); function Polygon() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'polygon'; _this.shapeType = 'polygon'; _this.generatePoints = true; return _this; } /** * 获取 Shape 的关键点数据。 * @param obj * @returns */ Polygon.prototype.createShapePointsCfg = function (obj) { var cfg = _super.prototype.createShapePointsCfg.call(this, obj); var x = cfg.x; var y = cfg.y; var temp; // x y 都是数组时,不做处理 if (!(util_1.isArray(x) && util_1.isArray(y))) { var xScale = this.getXScale(); var yScale = this.getYScale(); var xCount = xScale.values.length; var yCount = yScale.values.length; var xOffset = (0.5 * 1) / xCount; var yOffset = (0.5 * 1) / yCount; if (xScale.isCategory && yScale.isCategory) { // 如果x,y都是分类 x = [x - xOffset, x - xOffset, x + xOffset, x + xOffset]; y = [y - yOffset, y + yOffset, y + yOffset, y - yOffset]; } else if (util_1.isArray(x)) { // x 是数组 temp = x; x = [temp[0], temp[0], temp[1], temp[1]]; y = [y - yOffset / 2, y + yOffset / 2, y + yOffset / 2, y - yOffset / 2]; } else if (util_1.isArray(y)) { // y 是数组 temp = y; y = [temp[0], temp[1], temp[1], temp[0]]; x = [x - xOffset / 2, x - xOffset / 2, x + xOffset / 2, x + xOffset / 2]; } cfg.x = x; cfg.y = y; } return cfg; }; return Polygon; }(base_1.default)); exports.default = Polygon; },{"./base":250,"./shape/polygon":296,"@antv/util":803,"tslib":385}],269:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var coordinate_1 = require("../util/coordinate"); var base_1 = tslib_1.__importDefault(require("./base")); /** 引入对应的 ShapeFactory */ require("./shape/schema"); var shape_size_1 = require("./util/shape-size"); /** * Schema 几何标记,用于一些自定义图形的绘制,比如箱型图、股票图等。 */ var Schema = /** @class */ (function (_super) { tslib_1.__extends(Schema, _super); function Schema() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'schema'; _this.shapeType = 'schema'; _this.generatePoints = true; return _this; } /** * 获取 Shape 的关键点数据。 * @param record * @returns */ Schema.prototype.createShapePointsCfg = function (record) { var cfg = _super.prototype.createShapePointsCfg.call(this, record); // 计算每个 shape 的 size var size; var sizeAttr = this.getAttribute('size'); if (sizeAttr) { size = this.getAttributeValues(sizeAttr, record)[0]; // 归一化 var coordinate = this.coordinate; var coordinateWidth = coordinate_1.getXDimensionLength(coordinate); size = size / coordinateWidth; } else { if (!this.defaultSize) { this.defaultSize = shape_size_1.getDefaultSize(this); } size = this.defaultSize; } cfg.size = size; return cfg; }; return Schema; }(base_1.default)); exports.default = Schema; },{"../util/coordinate":371,"./base":250,"./shape/schema":300,"./util/shape-size":308,"tslib":385}],270:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var base_1 = require("../base"); var util_2 = require("./util"); var AreaShapeFactory = base_1.registerShapeFactory('area', { defaultShapeType: 'area', getDefaultPoints: function (pointInfo) { // area 基本标记的绘制需要获取上下两边的顶点 var x = pointInfo.x, y0 = pointInfo.y0; var y = util_1.isArray(pointInfo.y) ? pointInfo.y : [y0, pointInfo.y]; return y.map(function (yItem) { return { x: x, y: yItem, }; }); }, }); // Area 几何标记默认的 shape:填充的区域图 base_1.registerShape('area', 'area', { draw: function (cfg, container) { var attrs = util_2.getShapeAttrs(cfg, false, false, this); var shape = container.addShape({ type: 'path', attrs: attrs, name: 'area', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { if (r === void 0) { r = 5.5; } return [['M', x - r, y - 4], ['L', x + r, y - 4], ['L', x + r, y + 4], ['L', x - r, y + 4], ['Z']]; }, style: { r: 5, fill: color, }, }; }, }); exports.default = AreaShapeFactory; },{"../base":275,"./util":274,"@antv/util":803}],271:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("../base"); var util_1 = require("./util"); /** * 描边但不填充的区域图 */ base_1.registerShape('area', 'line', { draw: function (cfg, container) { var attrs = util_1.getShapeAttrs(cfg, true, false, this); var shape = container.addShape({ type: 'path', attrs: attrs, name: 'area', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { if (r === void 0) { r = 5.5; } return [['M', x - r, y - 4], ['L', x + r, y - 4], ['L', x + r, y + 4], ['L', x - r, y + 4], ['Z']]; }, style: { r: 5, stroke: color, fill: null, }, }; }, }); },{"../base":275,"./util":274}],272:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("../base"); var util_1 = require("./util"); /** 描边的平滑曲面图 */ base_1.registerShape('area', 'smooth-line', { draw: function (cfg, container) { var coordinate = this.coordinate; var attrs = util_1.getShapeAttrs(cfg, true, true, this, util_1.getConstraint(coordinate)); var shape = container.addShape({ type: 'path', attrs: attrs, name: 'area', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { if (r === void 0) { r = 5.5; } return [['M', x - r, y - 4], ['L', x + r, y - 4], ['L', x + r, y + 4], ['L', x - r, y + 4], ['Z']]; }, style: { r: 5, stroke: color, fill: null, }, }; }, }); },{"../base":275,"./util":274}],273:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("../base"); var util_1 = require("./util"); /** * 填充的平滑曲面图 */ base_1.registerShape('area', 'smooth', { draw: function (cfg, container) { var coordinate = this.coordinate; var attrs = util_1.getShapeAttrs(cfg, false, true, this, util_1.getConstraint(coordinate)); var shape = container.addShape({ type: 'path', attrs: attrs, name: 'area', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { if (r === void 0) { r = 5.5; } return [['M', x - r, y - 4], ['L', x + r, y - 4], ['L', x + r, y + 4], ['L', x - r, y + 4], ['Z']]; }, style: { r: 5, fill: color, }, }; }, }); },{"../base":275,"./util":274}],274:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getConstraint = exports.getShapeAttrs = void 0; var util_1 = require("@antv/util"); var get_path_points_1 = require("../util/get-path-points"); var get_style_1 = require("../util/get-style"); var path_1 = require("../util/path"); function getPath(points, isInCircle, smooth, registeredShape, constraint) { var path = []; if (points.length) { var topLinePoints_1 = []; // area 区域上部分 var bottomLinePoints_1 = []; // area 区域下部分 for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; topLinePoints_1.push(point[1]); bottomLinePoints_1.push(point[0]); } bottomLinePoints_1 = bottomLinePoints_1.reverse(); util_1.each([topLinePoints_1, bottomLinePoints_1], function (pointsData, index) { var subPath = []; var parsedPoints = registeredShape.parsePoints(pointsData); var p1 = parsedPoints[0]; if (topLinePoints_1.length === 1 && bottomLinePoints_1.length === 1) { // 都只有一个点,绘制一条竖线 subPath = index === 0 ? [ ['M', p1.x - 0.5, p1.y], ['L', p1.x + 0.5, p1.y], ] : [ ['L', p1.x + 0.5, p1.y], ['L', p1.x - 0.5, p1.y], ]; } else { if (isInCircle) { parsedPoints.push({ x: p1.x, y: p1.y }); } if (smooth) { subPath = path_1.getSplinePath(parsedPoints, false, constraint); } else { subPath = path_1.getLinePath(parsedPoints, false); } if (index > 0) { subPath[0][0] = 'L'; } } path = path.concat(subPath); }); path.push(['Z']); } return path; } /** * @ignore * Gets shape attrs * @param cfg * @param isStroke * @param smooth * @param registeredShape * @param [constraint] * @returns */ function getShapeAttrs(cfg, isStroke, smooth, registeredShape, constraint) { var attrs = get_style_1.getStyle(cfg, isStroke, !isStroke, 'lineWidth'); var connectNulls = cfg.connectNulls, isInCircle = cfg.isInCircle, points = cfg.points, showSinglePoint = cfg.showSinglePoint; var pathPoints = get_path_points_1.getPathPoints(points, connectNulls, showSinglePoint); // 根据 connectNulls 配置获取图形关键点 var path = []; for (var i = 0, len = pathPoints.length; i < len; i++) { var eachPoints = pathPoints[i]; path = path.concat(getPath(eachPoints, isInCircle, smooth, registeredShape, constraint)); } attrs.path = path; return attrs; } exports.getShapeAttrs = getShapeAttrs; /** * @ignore * Gets constraint * @param coordinate * @returns constraint */ function getConstraint(coordinate) { var start = coordinate.start, end = coordinate.end; return [ [start.x, end.y], [end.x, start.y], ]; } exports.getConstraint = getConstraint; },{"../util/get-path-points":301,"../util/get-style":302,"../util/path":303,"@antv/util":803}],275:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getShapeFactory = exports.registerShape = exports.registerShapeFactory = void 0; var tslib_1 = require("tslib"); var path_util_1 = require("@antv/path-util"); var util_1 = require("@antv/util"); var path_1 = require("./util/path"); /** ShapeFactory 基类 */ var ShapeFactoryBase = { /** 坐标系对象 */ coordinate: null, /** 默认绘制的 Shape 类型 */ defaultShapeType: null, /** 主题样式 */ theme: null, /** * 获取 shape 绘制需要的关键点 * @param shapeType shape 类型 * @param shapePoint 每条数据映射后的坐标点以及 size 数值 * @returns 图形关键点信息 */ getShapePoints: function (shapeType, shapePoint) { var shape = this.getShape(shapeType); if (shape.getPoints) { return shape.getPoints(shapePoint); } return this.getDefaultPoints(shapePoint); }, /** * 根据 shape 类型获取具体的 shape 实例 * @param shapeType string shape 的类型 * @returns */ getShape: function (shapeType) { var shape = this[shapeType] || this[this.defaultShapeType]; shape.coordinate = this.coordinate; return shape; }, /** * 获取 shape 的默认关键点 * @override */ getDefaultPoints: function () { return []; }, /** * 获取 shape 对应的缩略图配置信息。 * @param shapeType shape 类型 * @param color 颜色 * @param isInPolar 是否在极坐标系下 * @returns 返回缩略图 marker 配置。 */ getMarker: function (shapeType, markerCfg) { var shape = this.getShape(shapeType); if (!shape.getMarker) { var defaultShapeType = this.defaultShapeType; shape = this.getShape(defaultShapeType); } var theme = this.theme; var shapeStyle = util_1.get(theme, [shapeType, 'default'], {}); var markerStyle = shape.getMarker(markerCfg); return util_1.deepMix({}, shapeStyle, markerStyle); }, /** * 绘制 shape * @override * @param shapeType 绘制的 shape 类型 * @param cfg 绘制 shape 需要的信息 * @param element Element 实例 * @returns */ drawShape: function (shapeType, cfg, container) { var shape = this.getShape(shapeType); return shape.draw(cfg, container); }, }; /** Shape 基类 */ var ShapeBase = { /** 坐标系对象 */ coordinate: null, /** * 将归一化的 path 转换成坐标系下的 path * @param path 归一化的路径 * @returns */ parsePath: function (path) { var coordinate = this.coordinate; var parsedPath = path_util_1.parsePathString(path); if (coordinate.isPolar) { parsedPath = path_1.convertPolarPath(coordinate, parsedPath); } else { parsedPath = path_1.convertNormalPath(coordinate, parsedPath); } return parsedPath; }, /** * 将归一化的坐标转换成画布坐标 * @param point 归一化的坐标点数据 * @returns */ parsePoint: function (point) { var coordinate = this.coordinate; return coordinate.convert(point); }, /** * 0~1 points 转 画布 points * @param points 节点集合 * @returns */ parsePoints: function (points) { var coordinate = this.coordinate; return points.map(function (point) { return coordinate.convert(point); }); }, /** * 绘制 shape * @override */ draw: function (cfg, container) { }, }; var ShapeFactoryMap = {}; /** * 注册 ShapeFactory。 * @param factoryName ShapeFactory 名称,对应 Geometry 几何标记名称。 * @param cfg 注册 ShapeFactory 需要覆写定义的属性。 * @returns 返回 ShapeFactory 对象。 */ function registerShapeFactory(factoryName, cfg) { var className = util_1.upperFirst(factoryName); var geomObj = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, ShapeFactoryBase), cfg), { geometryType: factoryName }); ShapeFactoryMap[className] = geomObj; return geomObj; } exports.registerShapeFactory = registerShapeFactory; /** * 注册 Shape。 * @param factoryName 对应的 ShapeFactory 名称。 * @param shapeType 注册的 shape 名称。 * @param cfg 注册 Shape 需要覆写定义的属性。 * @returns shape 返回注册的 shape 对象。 */ function registerShape(factoryName, shapeType, cfg) { var className = util_1.upperFirst(factoryName); var factory = ShapeFactoryMap[className]; var shapeObj = tslib_1.__assign(tslib_1.__assign({}, ShapeBase), cfg); factory[shapeType] = shapeObj; return shapeObj; } exports.registerShape = registerShape; /** * 获取 factoryName 对应的 shapeFactory * @param factoryName * @returns shape factory */ function getShapeFactory(factoryName) { var className = util_1.upperFirst(factoryName); return ShapeFactoryMap[className]; } exports.getShapeFactory = getShapeFactory; },{"./util/path":303,"@antv/path-util":724,"@antv/util":803,"tslib":385}],276:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var graphics_1 = require("../../../util/graphics"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_1 = require("./util"); function getArcShapePath(from, to, center) { var sub = util_1.getQPath(to, center); var path = [['M', from.x, from.y]]; path.push(sub); return path; } function getArcShapeWeightPath(points, center) { var arc1 = util_1.getQPath(points[1], center); var arc2 = util_1.getQPath(points[3], center); var path = [['M', points[0].x, points[0].y]]; path.push(arc2); path.push(['L', points[3].x, points[3].y]); path.push(['L', points[2].x, points[2].y]); path.push(arc1); path.push(['L', points[1].x, points[1].y]); path.push(['L', points[0].x, points[0].y]); path.push(['Z']); return path; } // 弧线包括笛卡尔坐标系下的半圆弧线、极坐标系下以圆心为控制点的二阶曲线、笛卡尔坐标系下带权重的三阶曲线、极坐标系下带权重的以圆心为控制点的二阶曲线 base_1.registerShape('edge', 'arc', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false, 'lineWidth'); var points = cfg.points; var type = points.length > 2 ? 'weight' : 'normal'; var path; if (cfg.isInCircle) { var center = { x: 0, y: 1 }; if (type === 'normal') { path = getArcShapePath(points[0], points[1], center); } else { style.fill = style.stroke; path = getArcShapeWeightPath(points, center); } path = this.parsePath(path); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); } else { if (type === 'normal') { points = this.parsePoints(points); path = graphics_1.getArcPath((points[1].x + points[0].x) / 2, points[0].y, Math.abs(points[1].x - points[0].x) / 2, Math.PI, Math.PI * 2); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); } else { var c1 = util_1.getCPath(points[1], points[3]); var c2 = util_1.getCPath(points[2], points[0]); path = [ ['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], c1, ['L', points[3].x, points[3].y], ['L', points[2].x, points[2].y], c2, ['Z'], ]; path = this.parsePath(path); style.fill = style.stroke; return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); } } }, getMarker: function (markerCfg) { return { symbol: 'circle', style: { r: 4.5, fill: markerCfg.color, }, }; }, }); },{"../../../util/graphics":375,"../base":275,"../util/get-style":302,"./util":279,"tslib":385}],277:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var path_1 = require("../util/path"); var split_points_1 = require("../util/split-points"); var EdgeShapeFactory = base_1.registerShapeFactory('edge', { defaultShapeType: 'line', getDefaultPoints: function (pointInfo) { return split_points_1.splitPoints(pointInfo); }, }); base_1.registerShape('edge', 'line', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false, 'lineWidth'); var path = path_1.getLinePath(this.parsePoints(cfg.points), this.coordinate.isPolar); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); }, getMarker: function (markerCfg) { return { symbol: 'circle', style: { r: 4.5, fill: markerCfg.color, }, }; }, }); exports.default = EdgeShapeFactory; },{"../base":275,"../util/get-style":302,"../util/path":303,"../util/split-points":304,"tslib":385}],278:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_1 = require("./util"); function getSmoothPath(from, to) { var sub = util_1.getCPath(from, to); var path = [['M', from.x, from.y]]; path.push(sub); return path; } base_1.registerShape('edge', 'smooth', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false, 'lineWidth'); var points = cfg.points; var path = this.parsePath(getSmoothPath(points[0], points[1])); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); }, getMarker: function (markerCfg) { return { symbol: 'circle', style: { r: 4.5, fill: markerCfg.color, }, }; }, }); },{"../base":275,"../util/get-style":302,"./util":279,"tslib":385}],279:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getQPath = exports.getCPath = void 0; var util_1 = require("@antv/util"); /** * @ignore * Gets cpath * @param from * @param to * @returns */ function getCPath(from, to) { var points = []; points.push({ x: from.x, y: (from.y * 1) / 2 + (to.y * 1) / 2, }); points.push({ x: to.x, y: (from.y * 1) / 2 + (to.y * 1) / 2, }); points.push(to); var sub = ['C']; util_1.each(points, function (point) { sub.push(point.x, point.y); }); return sub; } exports.getCPath = getCPath; /** * @ignore * Gets qpath * @param to * @param center * @returns */ function getQPath(to, center) { var points = []; points.push({ x: center.x, y: center.y, }); points.push(to); var sub = ['Q']; util_1.each(points, function (point) { sub.push(point.x, point.y); }); return sub; } exports.getQPath = getQPath; },{"@antv/util":803}],280:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var CORNER_PERCENT = 1 / 3; function getVHVPath(from, to) { var points = []; points.push({ x: from.x, y: from.y * (1 - CORNER_PERCENT) + to.y * CORNER_PERCENT, }); points.push({ x: to.x, y: from.y * (1 - CORNER_PERCENT) + to.y * CORNER_PERCENT, }); points.push(to); var path = [['M', from.x, from.y]]; util_1.each(points, function (point) { path.push(['L', point.x, point.y]); }); return path; } base_1.registerShape('edge', 'vhv', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false, 'lineWidth'); var points = cfg.points; var path = this.parsePath(getVHVPath(points[0], points[1])); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); }, getMarker: function (markerCfg) { return { symbol: 'circle', style: { r: 4.5, fill: markerCfg.color, }, }; }, }); },{"../base":275,"../util/get-style":302,"@antv/util":803,"tslib":385}],281:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_1 = require("./util"); /** 漏斗图 */ base_1.registerShape('interval', 'funnel', { getPoints: function (shapePoint) { shapePoint.size = shapePoint.size * 2; // 漏斗图的 size 是柱状图的两倍 return util_1.getRectPoints(shapePoint); }, draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, false, true); var path = this.parsePath(util_1.getFunnelPath(cfg.points, cfg.nextPoints, false)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'square', style: { r: 4, fill: color, }, }; }, }); },{"../base":275,"../util/get-style":302,"./util":287,"tslib":385}],282:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_1 = require("./util"); /** 描边柱状图 */ base_1.registerShape('interval', 'hollow-rect', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false); var path = this.parsePath(util_1.getRectPath(cfg.points)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color, isInPolar = markerCfg.isInPolar; if (isInPolar) { return { symbol: 'circle', style: { r: 4.5, stroke: color, fill: null, }, }; } return { symbol: 'square', style: { r: 4, stroke: color, fill: null, }, }; }, }); },{"../base":275,"../util/get-style":302,"./util":287,"tslib":385}],283:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_1 = require("./util"); /** Interval 的 shape 工厂 */ var IntervalShapeFactory = base_1.registerShapeFactory('interval', { defaultShapeType: 'rect', getDefaultPoints: function (pointInfo) { return util_1.getRectPoints(pointInfo); }, }); /** Inerval 默认 shape,填充的矩形 */ base_1.registerShape('interval', 'rect', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, false, true); var path = this.parsePath(util_1.getRectPath(cfg.points)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color, isInPolar = markerCfg.isInPolar; if (isInPolar) { return { symbol: 'circle', style: { r: 4.5, fill: color, }, }; } return { symbol: 'square', style: { r: 4, fill: color, }, }; }, }); exports.default = IntervalShapeFactory; },{"../base":275,"../util/get-style":302,"./util":287,"tslib":385}],284:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_2 = require("./util"); // 根据数据点生成 Line 的两个关键点 function getLinePoints(pointInfo) { var x = pointInfo.x, y = pointInfo.y, y0 = pointInfo.y0; if (util_1.isArray(y)) { return y.map(function (yItem, idx) { return { x: util_1.isArray(x) ? x[idx] : x, y: yItem, }; }); } // 起始点从 y0 开始 return [ { x: x, y: y0 }, { x: x, y: y }, ]; } base_1.registerShape('interval', 'line', { getPoints: function (shapePoint) { return getLinePoints(shapePoint); }, draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false, 'lineWidth'); var path = this.parsePath(util_2.getRectPath(cfg.points, false)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { return [ ['M', x, y - r], ['L', x, y + r], ]; }, style: { r: 5, stroke: color, }, }; }, }); },{"../base":275,"../util/get-style":302,"./util":287,"@antv/util":803,"tslib":385}],285:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); var util_1 = require("./util"); /** 金字塔图,尖底漏斗图 */ base_1.registerShape('interval', 'pyramid', { getPoints: function (shapePoint) { shapePoint.size = shapePoint.size * 2; // 漏斗图的 size 是柱状图的两倍 return util_1.getRectPoints(shapePoint, true); }, draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, false, true); var path = this.parsePath(util_1.getFunnelPath(cfg.points, cfg.nextPoints, true)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'square', style: { r: 4, fill: color, }, }; }, }); },{"../base":275,"../util/get-style":302,"./util":287,"tslib":385}],286:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); // 根据数据点生成 tick shape 的 6 个关键点 function getTickPoints(pointInfo) { var x = pointInfo.x, y = pointInfo.y, y0 = pointInfo.y0, size = pointInfo.size; var yMin; var yMax; if (util_1.isArray(y)) { yMin = y[0], yMax = y[1]; } else { yMin = y0; yMax = y; } var xMax = x + size / 2; var xMin = x - size / 2; // tick 关键点顺序 // 4 - 1 - 5 // | // 2 - 0 - 3 return [ { x: x, y: yMin }, { x: x, y: yMax }, { x: xMin, y: yMin }, { x: xMax, y: yMin }, { x: xMin, y: yMax }, { x: xMax, y: yMax }, ]; } // 根据 tick 关键点绘制 path function getTickPath(points) { return [ ['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['M', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['M', points[4].x, points[4].y], ['L', points[5].x, points[5].y], ]; } /** I 形状柱状图,常用于 error bar chart */ base_1.registerShape('interval', 'tick', { getPoints: function (shapePoint) { return getTickPoints(shapePoint); }, draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false); var path = this.parsePath(getTickPath(cfg.points)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { return [ ['M', x - r / 2, y - r], ['L', x + r / 2, y - r], ['M', x, y - r], ['L', x, y + r], ['M', x - r / 2, y + r], ['L', x + r / 2, y + r], ]; }, style: { r: 5, stroke: color, }, }; }, }); },{"../base":275,"../util/get-style":302,"@antv/util":803,"tslib":385}],287:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFunnelPath = exports.getRectPath = exports.getRectPoints = void 0; var util_1 = require("@antv/util"); /** * @ignore * 根据数据点生成矩形的四个关键点 * @param pointInfo 数据点信息 * @param [isPyramid] 是否为尖底漏斗图 * @returns rect points 返回矩形四个顶点信息 */ function getRectPoints(pointInfo, isPyramid) { if (isPyramid === void 0) { isPyramid = false; } var x = pointInfo.x, y = pointInfo.y, y0 = pointInfo.y0, size = pointInfo.size; // 有 4 种情况, // 1. x, y 都不是数组 // 2. y是数组,x不是 // 3. x是数组,y不是 // 4. x, y 都是数组 var yMin; var yMax; if (util_1.isArray(y)) { yMin = y[0], yMax = y[1]; } else { yMin = y0; yMax = y; } var xMin; var xMax; if (util_1.isArray(x)) { xMin = x[0], xMax = x[1]; } else { xMin = x - size / 2; xMax = x + size / 2; } var points = [ { x: xMin, y: yMin }, { x: xMin, y: yMax }, ]; if (isPyramid) { // 绘制尖底漏斗图 // 金字塔漏斗图的关键点 // 1 // | 2 // 0 points.push({ x: xMax, y: (yMax + yMin) / 2, }); } else { // 矩形的四个关键点,结构如下(左下角顺时针连接) // 1 ---- 2 // | | // 0 ---- 3 points.push({ x: xMax, y: yMax }, { x: xMax, y: yMin }); } return points; } exports.getRectPoints = getRectPoints; /** * @ignore * 根据矩形关键点绘制 path * @param points 关键点数组 * @param isClosed path 是否需要闭合 * @returns 返回矩形的 path */ function getRectPath(points, isClosed) { if (isClosed === void 0) { isClosed = true; } var path = []; var firstPoint = points[0]; path.push(['M', firstPoint.x, firstPoint.y]); for (var i = 1, len = points.length; i < len; i++) { path.push(['L', points[i].x, points[i].y]); } // 对于 shape="line" path 不应该闭合,否则会造成 lineCap 绘图属性失效 if (isClosed) { path.push(['L', firstPoint.x, firstPoint.y]); // 需要闭合 path.push(['z']); } return path; } exports.getRectPath = getRectPath; /** * @ignore * 根据 funnel 关键点绘制漏斗图的 path * @param points 图形关键点信息 * @param nextPoints 下一个数据的图形关键点信息 * @param isPyramid 是否为尖底漏斗图 * @returns 返回漏斗图的图形 path */ function getFunnelPath(points, nextPoints, isPyramid) { var path = []; if (!util_1.isNil(nextPoints)) { path.push(['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['L', nextPoints[1].x, nextPoints[1].y], ['L', nextPoints[0].x, nextPoints[0].y], ['Z']); } else if (isPyramid) { // 金字塔最底部 path.push(['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['L', points[2].x, points[2].y], ['L', points[2].x, points[2].y], ['Z']); } else { // 漏斗图最底部 path.push(['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['L', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['Z']); } return path; } exports.getFunnelPath = getFunnelPath; },{"@antv/util":803}],288:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_path_points_1 = require("../util/get-path-points"); var get_style_1 = require("../util/get-style"); var path_1 = require("../util/path"); var split_points_1 = require("../util/split-points"); var util_2 = require("./util"); function getShapeAttrs(cfg, smooth, constraint) { var isStack = cfg.isStack, connectNulls = cfg.connectNulls, isInCircle = cfg.isInCircle, showSinglePoint = cfg.showSinglePoint; var shapeAttrs = get_style_1.getStyle(cfg, true, false, 'lineWidth'); var points = get_path_points_1.getPathPoints(cfg.points, connectNulls, showSinglePoint); // 根据 connectNulls 值处理 points var path = []; for (var i = 0, len = points.length; i < len; i++) { var eachLinePoints = points[i]; path = path.concat(getPath(eachLinePoints, isInCircle, isStack, smooth, constraint, shapeAttrs)); } shapeAttrs.path = path; return shapeAttrs; } // 单条 path function getSinglePath(points, isInCircle, smooth, constraint, style) { if (points.length === 1) { // 只有一个点时 return [ ['M', points[0].x, points[0].y - style.lineWidth / 2], ['L', points[0].x, points[0].y], ['L', points[0].x, points[0].y + style.lineWidth / 2], ]; } var path; if (!smooth) { path = path_1.getLinePath(points, false); if (isInCircle) { path.push(['Z']); } } else { // 直角坐标系下绘制曲线时限制最大值、最小值 if (isInCircle && points.length) { points.push({ x: points[0].x, y: points[0].y }); } path = path_1.getSplinePath(points, false, constraint); } return path; } function getRangePath(points, isInCircle, isStack, smooth, constraint, style) { var topPoints = []; var bottomPoints = []; util_1.each(points, function (point) { var result = split_points_1.splitPoints(point); topPoints.push(result[1]); // 上边 bottomPoints.push(result[0]); // 底边 }); var topPath = getSinglePath(topPoints, isInCircle, smooth, constraint, style); var bottomPath = getSinglePath(bottomPoints, isInCircle, smooth, constraint, style); if (isStack) { return topPath; } return topPath.concat(bottomPath); } function getPath(points, isInCircle, isStack, smooth, constraint, style) { if (points.length) { var first = points[0]; return util_1.isArray(first.y) ? getRangePath(points, isInCircle, isStack, smooth, constraint, style) : getSinglePath(points, isInCircle, smooth, constraint, style); } return []; } var LineShapeFactory = base_1.registerShapeFactory('line', { defaultShapeType: 'line', }); // 这里因为代码公用,所以直接全部注册 // 'line' 默认折线;'dot' 点线 ···;'dash' 断线 - - - util_1.each(['line', 'dot', 'dash', 'smooth'], function (shapeType) { base_1.registerShape('line', shapeType, { draw: function (cfg, container) { var smooth = shapeType === 'smooth'; var constraint; if (smooth) { var _a = this.coordinate, start = _a.start, end = _a.end; constraint = [ [start.x, end.y], [end.x, start.y], ]; } var attrs = getShapeAttrs(cfg, smooth, constraint); var shape = container.addShape({ type: 'path', attrs: attrs, name: 'line', }); return shape; }, getMarker: function (markerCfg) { return util_2.getLineMarker(markerCfg, shapeType); }, }); }); exports.default = LineShapeFactory; },{"../base":275,"../util/get-path-points":301,"../util/get-style":302,"../util/path":303,"../util/split-points":304,"./util":290,"@antv/util":803}],289:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_path_points_1 = require("../util/get-path-points"); var get_style_1 = require("../util/get-style"); var util_2 = require("./util"); var interpolateCallback = function (point, nextPoint, shapeType) { var x = point.x; var y = point.y; var nextX = nextPoint.x; var nextY = nextPoint.y; var result; switch (shapeType) { case 'hv': result = [{ x: nextX, y: y }]; break; case 'vh': result = [{ x: x, y: nextY }]; break; case 'hvh': var middleX = (nextX + x) / 2; result = [ { x: middleX, y: y }, { x: middleX, y: nextY }, ]; break; case 'vhv': var middleY = (y + nextY) / 2; result = [ { x: x, y: middleY }, { x: nextX, y: middleY }, ]; break; default: break; } return result; }; function getInterpolatePoints(points, shapeType) { var result = []; util_1.each(points, function (point, index) { var nextPoint = points[index + 1]; result.push(point); if (nextPoint) { var interpolatePoint = interpolateCallback(point, nextPoint, shapeType); result = result.concat(interpolatePoint); } }); return result; } // 插值的图形path,不考虑null function getInterpolatePath(points) { return points.map(function (point, index) { return index === 0 ? ['M', point.x, point.y] : ['L', point.x, point.y]; }); } // 插值的图形 function getInterpolateShapeAttrs(cfg, shapeType) { var points = get_path_points_1.getPathPoints(cfg.points, cfg.connectNulls, cfg.showSinglePoint); // 根据 connectNulls 值处理 points var path = []; util_1.each(points, function (eachLinePoints) { var interpolatePoints = getInterpolatePoints(eachLinePoints, shapeType); path = path.concat(getInterpolatePath(interpolatePoints)); }); return tslib_1.__assign(tslib_1.__assign({}, get_style_1.getStyle(cfg, true, false, 'lineWidth')), { path: path }); } // step line util_1.each(['hv', 'vh', 'hvh', 'vhv'], function (shapeType) { base_1.registerShape('line', shapeType, { draw: function (cfg, container) { var attrs = getInterpolateShapeAttrs(cfg, shapeType); var shape = container.addShape({ type: 'path', attrs: attrs, name: 'line', }); return shape; }, getMarker: function (markerCfg) { return util_2.getLineMarker(markerCfg, shapeType); }, }); }); },{"../base":275,"../util/get-path-points":301,"../util/get-style":302,"./util":290,"@antv/util":803,"tslib":385}],290:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLineMarker = void 0; var LineSymbols = { line: function (x, y, r) { return [ ['M', x - r, y], ['L', x + r, y], ]; }, dot: function (x, y, r) { return [ ['M', x - r, y], ['L', x + r, y], ]; }, dash: function (x, y, r) { return [ ['M', x - r, y], ['L', x + r, y], ]; }, smooth: function (x, y, r) { return [ ['M', x - r, y], ['A', r / 2, r / 2, 0, 1, 1, x, y], ['A', r / 2, r / 2, 0, 1, 0, x + r, y], ]; }, hv: function (x, y, r) { return [ ['M', x - r - 1, y - 2.5], ['L', x, y - 2.5], ['L', x, y + 2.5], ['L', x + r + 1, y + 2.5], ]; }, vh: function (x, y, r) { return [ ['M', x - r - 1, y + 2.5], ['L', x, y + 2.5], ['L', x, y - 2.5], ['L', x + r + 1, y - 2.5], ]; }, hvh: function (x, y, r) { return [ ['M', x - (r + 1), y + 2.5], ['L', x - r / 2, y + 2.5], ['L', x - r / 2, y - 2.5], ['L', x + r / 2, y - 2.5], ['L', x + r / 2, y + 2.5], ['L', x + r + 1, y + 2.5], ]; }, vhv: function (x, y) { // 宽 13px,高 8px return [ ['M', x - 5, y + 2.5], ['L', x - 5, y], ['L', x, y], ['L', x, y - 3], ['L', x, y + 3], ['L', x + 6.5, y + 3], ]; }, }; /** * Gets line marker * @ignore * @param markerCfg * @param shapeType * @returns 返回 Line 的 marker 配置 */ function getLineMarker(markerCfg, shapeType) { var color = markerCfg.color; return { symbol: LineSymbols[shapeType], style: { lineWidth: 2, r: 6, stroke: color, }, }; } exports.getLineMarker = getLineMarker; },{}],291:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var marker_1 = require("../../../util/marker"); var base_1 = require("../base"); var util_2 = require("./util"); // 添加 hollowShape util_1.each(util_2.HOLLOW_SHAPES, function (shapeName) { base_1.registerShape('point', shapeName, { draw: function (cfg, container) { return util_2.drawPoints(this, cfg, container, shapeName, true); }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: marker_1.MarkerSymbols[shapeName], style: { r: 4.5, stroke: color, fill: null, }, }; }, }); }); },{"../../../util/marker":379,"../base":275,"./util":295,"@antv/util":803}],292:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); base_1.registerShape('point', 'image', { draw: function (cfg, container) { var size = get_style_1.getStyle(cfg, false, false, 'r').r; var points = this.parsePoints(cfg.points); var pointPosition = points[0]; if (cfg.isStack) { pointPosition = points[1]; } else if (points.length > 1) { var group = container.addGroup(); for (var _i = 0, points_1 = points; _i < points_1.length; _i++) { var point = points_1[_i]; group.addShape('image', { attrs: { x: point.x - size / 2, y: point.y - size, width: size, height: size, img: cfg.shape[1], }, }); } return group; } return container.addShape('image', { attrs: { x: pointPosition.x - size / 2, y: pointPosition.y - size, width: size, height: size, img: cfg.shape[1], }, }); }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'circle', style: { r: 4.5, fill: color, }, }; }, }); },{"../base":275,"../util/get-style":302}],293:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var marker_1 = require("../../../util/marker"); var base_1 = require("../base"); var split_points_1 = require("../util/split-points"); var util_2 = require("./util"); var PointShapeFactory = base_1.registerShapeFactory('point', { defaultShapeType: 'hollow-circle', getDefaultPoints: function (pointInfo) { return split_points_1.splitPoints(pointInfo); }, }); util_1.each(util_2.SHAPES, function (shapeName) { // 添加该 shape 对应的 hollow-shape base_1.registerShape('point', "hollow-" + shapeName, { draw: function (cfg, container) { return util_2.drawPoints(this, cfg, container, shapeName, true); }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: marker_1.MarkerSymbols[shapeName] || shapeName, style: { r: 4.5, stroke: color, fill: null, }, }; }, }); }); exports.default = PointShapeFactory; },{"../../../util/marker":379,"../base":275,"../util/split-points":304,"./util":295,"@antv/util":803}],294:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var marker_1 = require("../../../util/marker"); var base_1 = require("../base"); var util_2 = require("./util"); // 所有的 SHAPES 都注册一下 util_1.each(util_2.SHAPES, function (shapeName) { base_1.registerShape('point', shapeName, { draw: function (cfg, container) { return util_2.drawPoints(this, cfg, container, shapeName, false); }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: marker_1.MarkerSymbols[shapeName] || shapeName, style: { r: 4.5, fill: color, }, }; }, }); }); },{"../../../util/marker":379,"../base":275,"./util":295,"@antv/util":803}],295:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.drawPoints = exports.HOLLOW_SHAPES = exports.SHAPES = void 0; var tslib_1 = require("tslib"); var marker_1 = require("../../../util/marker"); var get_style_1 = require("../util/get-style"); exports.SHAPES = ['circle', 'square', 'bowtie', 'diamond', 'hexagon', 'triangle', 'triangle-down']; exports.HOLLOW_SHAPES = ['cross', 'tick', 'plus', 'hyphen', 'line']; /** * @ignore * Draws points * @param shape * @param cfg * @param container * @param shapeName * @param isStroke * @returns points */ function drawPoints(shape, cfg, container, shapeName, isStroke) { var style = get_style_1.getStyle(cfg, isStroke, !isStroke, 'r'); var points = shape.parsePoints(cfg.points); var pointPosition = points[0]; if (cfg.isStack) { pointPosition = points[1]; } else if (points.length > 1) { var group = container.addGroup(); for (var _i = 0, points_1 = points; _i < points_1.length; _i++) { var point = points_1[_i]; group.addShape({ type: 'marker', attrs: tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, style), { symbol: marker_1.MarkerSymbols[shapeName] || shapeName }), point), }); } return group; } return container.addShape({ type: 'marker', attrs: tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, style), { symbol: marker_1.MarkerSymbols[shapeName] || shapeName }), pointPosition), }); } exports.drawPoints = drawPoints; },{"../../../util/marker":379,"../util/get-style":302,"tslib":385}],296:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); function getPath(points) { var flag = points[0]; var i = 1; var path = [['M', flag.x, flag.y]]; while (i < points.length) { var c = points[i]; if (c.x !== points[i - 1].x || c.y !== points[i - 1].y) { path.push(['L', c.x, c.y]); if (c.x === flag.x && c.y === flag.y && i < points.length - 1) { flag = points[i + 1]; path.push(['Z']); path.push(['M', flag.x, flag.y]); i++; } } i++; } if (!util_1.isEqual(util_1.last(path), flag)) { path.push(['L', flag.x, flag.y]); } path.push(['Z']); return path; } var PolygonShapeFactory = base_1.registerShapeFactory('polygon', { defaultShapeType: 'polygon', getDefaultPoints: function (pointInfo) { var points = []; util_1.each(pointInfo.x, function (subX, index) { var subY = pointInfo.y[index]; points.push({ x: subX, y: subY, }); }); return points; }, }); base_1.registerShape('polygon', 'polygon', { draw: function (cfg, container) { if (!util_1.isEmpty(cfg.points)) { var shapeAttrs = get_style_1.getStyle(cfg, true, true); var path = this.parsePath(getPath(cfg.points)); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, shapeAttrs), { path: path }), name: 'polygon', }); } }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'square', style: { r: 4, fill: color, }, }; }, }); exports.default = PolygonShapeFactory; },{"../base":275,"../util/get-style":302,"@antv/util":803,"tslib":385}],297:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); function getRectAttrs(points, size) { var width = Math.abs(points[0].x - points[2].x); var height = Math.abs(points[0].y - points[2].y); var len = Math.min(width, height); if (size) { len = util_1.clamp(size, 0, Math.min(width, height)); } len = len / 2; var centerX = (points[0].x + points[2].x) / 2; var centerY = (points[0].y + points[2].y) / 2; return { x: centerX - len, y: centerY - len, width: len * 2, height: len * 2, }; } base_1.registerShape('polygon', 'square', { draw: function (cfg, container) { if (!util_1.isEmpty(cfg.points)) { var shapeAttrs = get_style_1.getStyle(cfg, true, true); var points = this.parsePoints(cfg.points); // 转换为画布坐标 return container.addShape('rect', { attrs: tslib_1.__assign(tslib_1.__assign({}, shapeAttrs), getRectAttrs(points, cfg.size)), name: 'polygon', }); } }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'square', style: { r: 4, fill: color, }, }; }, }); },{"../base":275,"../util/get-style":302,"@antv/util":803,"tslib":385}],298:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); function parseValue(value) { var array = !util_1.isArray(value) ? [value] : value; var min = array[0]; // 最小值 var max = array[array.length - 1]; // 最大值 var min1 = array.length > 1 ? array[1] : min; var max1 = array.length > 3 ? array[3] : max; var median = array.length > 2 ? array[2] : min1; return { min: min, max: max, min1: min1, max1: max1, median: median, }; } function getBoxPoints(x, y, size) { var halfSize = size / 2; var pointsArray; if (util_1.isArray(y)) { // 2维 var _a = parseValue(y), min = _a.min, max = _a.max, median = _a.median, min1 = _a.min1, max1 = _a.max1; var minX = x - halfSize; var maxX = x + halfSize; pointsArray = [ [minX, max], [maxX, max], [x, max], [x, max1], [minX, min1], [minX, max1], [maxX, max1], [maxX, min1], [x, min1], [x, min], [minX, min], [maxX, min], [minX, median], [maxX, median], ]; } else { // 只有一个维度 y = util_1.isNil(y) ? 0.5 : y; var _b = parseValue(x), min = _b.min, max = _b.max, median = _b.median, min1 = _b.min1, max1 = _b.max1; var minY = y - halfSize; var maxY = y + halfSize; pointsArray = [ [min, minY], [min, maxY], [min, y], [min1, y], [min1, minY], [min1, maxY], [max1, maxY], [max1, minY], [max1, y], [max, y], [max, minY], [max, maxY], [median, minY], [median, maxY], ]; } return pointsArray.map(function (arr) { return { x: arr[0], y: arr[1], }; }); } function getBoxPath(points) { return [ ['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['M', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['M', points[4].x, points[4].y], ['L', points[5].x, points[5].y], ['L', points[6].x, points[6].y], ['L', points[7].x, points[7].y], ['L', points[4].x, points[4].y], ['Z'], ['M', points[8].x, points[8].y], ['L', points[9].x, points[9].y], ['M', points[10].x, points[10].y], ['L', points[11].x, points[11].y], ['M', points[12].x, points[12].y], ['L', points[13].x, points[13].y], ]; } // box shape base_1.registerShape('schema', 'box', { getPoints: function (shapePoint) { var x = shapePoint.x, y = shapePoint.y, size = shapePoint.size; return getBoxPoints(x, y, size); }, draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, false); var path = this.parsePath(getBoxPath(cfg.points)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path, name: 'schema' }), }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { var yValues = [y - 6, y - 3, y, y + 3, y + 6]; var points = getBoxPoints(x, yValues, r); return [ ['M', points[0].x + 1, points[0].y], ['L', points[1].x - 1, points[1].y], ['M', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['M', points[4].x, points[4].y], ['L', points[5].x, points[5].y], ['L', points[6].x, points[6].y], ['L', points[7].x, points[7].y], ['L', points[4].x, points[4].y], ['Z'], ['M', points[8].x, points[8].y], ['L', points[9].x, points[9].y], ['M', points[10].x + 1, points[10].y], ['L', points[11].x - 1, points[11].y], ['M', points[12].x, points[12].y], ['L', points[13].x, points[13].y], ]; }, style: { r: 6, lineWidth: 1, stroke: color, }, }; }, }); },{"../base":275,"../util/get-style":302,"@antv/util":803,"tslib":385}],299:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var helper_1 = require("../../../util/helper"); var base_1 = require("../base"); var get_style_1 = require("../util/get-style"); function getCandleYValues(value) { var array = !util_1.isArray(value) ? [value] : value; // 从大到小排序 var sorted = array.sort(function (a, b) { return b - a; }); return helper_1.padEnd(sorted, 4, sorted[sorted.length - 1]); } // get candle shape's key points function getCandlePoints(x, y, size) { var yValues = getCandleYValues(y); return [ { x: x, y: yValues[0] }, { x: x, y: yValues[1] }, { x: x - size / 2, y: yValues[2] }, { x: x - size / 2, y: yValues[1] }, { x: x + size / 2, y: yValues[1] }, { x: x + size / 2, y: yValues[2] }, { x: x, y: yValues[2] }, { x: x, y: yValues[3] }, ]; } function getCandlePath(points) { return [ ['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['M', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['L', points[4].x, points[4].y], ['L', points[5].x, points[5].y], ['Z'], ['M', points[6].x, points[6].y], ['L', points[7].x, points[7].y], ]; } // k line shape base_1.registerShape('schema', 'candle', { getPoints: function (shapePoint) { var x = shapePoint.x, y = shapePoint.y, size = shapePoint.size; return getCandlePoints(x, y, size); }, draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, true, true); var path = this.parsePath(getCandlePath(cfg.points)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path, name: 'schema' }), }); return shape; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: function (x, y, r) { var yValues = [y + 7.5, y + 3, y - 3, y - 7.5]; var points = getCandlePoints(x, yValues, r); return [ ['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['M', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['L', points[4].x, points[4].y], ['L', points[5].x, points[5].y], ['Z'], ['M', points[6].x, points[6].y], ['L', points[7].x, points[7].y], ]; }, style: { lineWidth: 1, stroke: color, fill: color, r: 6, }, }; }, }); },{"../../../util/helper":377,"../base":275,"../util/get-style":302,"@antv/util":803,"tslib":385}],300:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("../base"); var SchemaShapeFactory = base_1.registerShapeFactory('schema', { defaultShapeType: '', }); exports.default = SchemaShapeFactory; },{"../base":275}],301:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPathPoints = void 0; var util_1 = require("@antv/util"); function isValueEmpty(value) { if (value) { return false; } return value === null || value === undefined || isNaN(value); } function isYNil(point) { if (util_1.isArray(point)) { // 特殊处理 area 的关键点数据,其关键点结构为 [{x: 0, y: 1}, {x: 0, y: 2}] return isValueEmpty(point[1].y); } var value = point.y; return util_1.isArray(value) ? isValueEmpty(value[0]) : isValueEmpty(value); } /** * @ignore * 分割数据,用于处理在一组点数据中,y 对应的数值存在 null/undefined/NaN 的情况 * 应用于折线图、区域图以及路径图 * * ```typescript * // return [[{x: 1, y: 2}, {x: 3, y: 3}]] * getPathPoints([{x: 1, y: 2}, {x: 2, y: null}, {x: 3, y: 3}], true); * // return [[{x: 1, y: 2}], [{x: 3, y: 3}]] * getPathPoints([{x: 1, y: 2}, {x: 2, y: null}, {x: 3, y: 3}], false); * // return [[[{ x: 1, y: 10 }, { x: 2, y: 2 }], [{ x: 9, y: 34 }, { x: 1, y: 1 }]]] * getPathPoints([ * [{ x: 1, y: 10 }, { x: 2, y: 2 }], * [{ x: 4, y: 2 }, { x: 8, y: NaN }], * [{ x: 9, y: 34 }, { x: 1, y: 1 }], * ], true); * ``` * * @param points 要进行处理点集合 * @param connectNulls 是否连接空值数据 * @param showSinglePoint 是否展示孤立点 * @returns 返回处理后的点集合 */ function getPathPoints(points, connectNulls, showSinglePoint) { if (connectNulls === void 0) { connectNulls = false; } if (showSinglePoint === void 0) { showSinglePoint = true; } if (!points.length || (points.length === 1 && !showSinglePoint)) { // 空或者只有一个点并配置不展示时 return []; } if (connectNulls) { // 即 y 值为空的场景 var filtered = []; for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; if (!isYNil(point)) { filtered.push(point); } } return [filtered]; } var result = []; var tmp = []; for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; if (isYNil(point)) { if (tmp.length) { if (!(tmp.length === 1 && !showSinglePoint)) { // 如果前段数据只有一个字段并且不需要展示时则不加入 result.push(tmp); } tmp = []; } } else { tmp.push(point); } } if (tmp.length) { result.push(tmp); } return result; } exports.getPathPoints = getPathPoints; },{"@antv/util":803}],302:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStyle = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); /** * @ignore * 获取 Shape 的图形属性 * @param cfg * @param isStroke 是否需要描边 * @param isFill 是否需要填充 * @param [sizeName] 可选,表示图形大小的属性,lineWidth 或者 r * @returns */ function getStyle(cfg, isStroke, isFill, sizeName) { if (sizeName === void 0) { sizeName = ''; } var _a = cfg.style, style = _a === void 0 ? {} : _a, defaultStyle = cfg.defaultStyle, color = cfg.color, size = cfg.size; var attrs = tslib_1.__assign(tslib_1.__assign({}, defaultStyle), style); if (color) { if (isStroke) { if (!style.stroke) { // 如果用户在 style() 中配置了 stroke,则以用户配置的为准 attrs.stroke = color; } } if (isFill) { if (!style.fill) { // 如果用户在 style() 中配置了 fill attrs.fill = color; } } } if (sizeName && util_1.isNil(style[sizeName]) && !util_1.isNil(size)) { // 如果用户在 style() 中配置了 lineWidth 或者 r 属性 attrs[sizeName] = size; } return attrs; } exports.getStyle = getStyle; },{"@antv/util":803,"tslib":385}],303:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertPolarPath = exports.convertNormalPath = exports.getSplinePath = exports.getLinePath = exports.catmullRom2bezier = exports.smoothBezier = void 0; var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var coordinate_1 = require("../../../util/coordinate"); function _points2path(points, isInCircle) { var path = []; if (points.length) { path.push(['M', points[0].x, points[0].y]); for (var i = 1, length_1 = points.length; i < length_1; i += 1) { var item = points[i]; path.push(['L', item.x, item.y]); } if (isInCircle) { path.push(['Z']); } } return path; } function _convertArr(arr, coord) { var tmp = [arr[0]]; for (var i = 1, len = arr.length; i < len; i = i + 2) { var point = coord.convert({ x: arr[i], y: arr[i + 1], }); tmp.push(point.x, point.y); } return tmp; } function _convertPolarPath(pre, cur, coord) { var isTransposed = coord.isTransposed, startAngle = coord.startAngle, endAngle = coord.endAngle; var prePoint = { x: pre[1], y: pre[2], }; var curPoint = { x: cur[1], y: cur[2], }; var rst = []; var xDim = isTransposed ? 'y' : 'x'; var angleRange = Math.abs(curPoint[xDim] - prePoint[xDim]) * (endAngle - startAngle); var direction = curPoint[xDim] >= prePoint[xDim] ? 1 : 0; // 圆弧的方向 var flag = angleRange > Math.PI ? 1 : 0; // 大弧还是小弧标志位 var convertPoint = coord.convert(curPoint); var r = coordinate_1.getDistanceToCenter(coord, convertPoint); if (r >= 0.5) { // 小于1像素的圆在图像上无法识别 if (angleRange === Math.PI * 2) { var middlePoint = { x: (curPoint.x + prePoint.x) / 2, y: (curPoint.y + prePoint.y) / 2, }; var middleConvertPoint = coord.convert(middlePoint); rst.push(['A', r, r, 0, flag, direction, middleConvertPoint.x, middleConvertPoint.y]); rst.push(['A', r, r, 0, flag, direction, convertPoint.x, convertPoint.y]); } else { rst.push(['A', r, r, 0, flag, direction, convertPoint.x, convertPoint.y]); } } return rst; } // 当存在整体的圆时,去除圆前面和后面的线,防止出现直线穿过整个圆的情形 function _filterFullCirleLine(path) { util_1.each(path, function (subPath, index) { var cur = subPath; if (cur[0].toLowerCase() === 'a') { var pre = path[index - 1]; var next = path[index + 1]; if (next && next[0].toLowerCase() === 'a') { if (pre && pre[0].toLowerCase() === 'l') { pre[0] = 'M'; } } else if (pre && pre[0].toLowerCase() === 'a') { if (next && next[0].toLowerCase() === 'l') { next[0] = 'M'; } } } }); } /** * @ignore * 计算光滑的贝塞尔曲线 */ exports.smoothBezier = function (points, smooth, isLoop, constraint) { var cps = []; var prevPoint; var nextPoint; var hasConstraint = !!constraint; var min; var max; if (hasConstraint) { min = [Infinity, Infinity]; max = [-Infinity, -Infinity]; for (var i = 0, l = points.length; i < l; i++) { var point = points[i]; min = matrix_util_1.vec2.min([0, 0], min, point); max = matrix_util_1.vec2.max([0, 0], max, point); } min = matrix_util_1.vec2.min([0, 0], min, constraint[0]); max = matrix_util_1.vec2.max([0, 0], max, constraint[1]); } for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; if (isLoop) { prevPoint = points[i ? i - 1 : len - 1]; nextPoint = points[(i + 1) % len]; } else { if (i === 0 || i === len - 1) { cps.push(point); continue; } else { prevPoint = points[i - 1]; nextPoint = points[i + 1]; } } var v = [0, 0]; v = matrix_util_1.vec2.sub(v, nextPoint, prevPoint); v = matrix_util_1.vec2.scale(v, v, smooth); var d0 = matrix_util_1.vec2.distance(point, prevPoint); var d1 = matrix_util_1.vec2.distance(point, nextPoint); var sum = d0 + d1; if (sum !== 0) { d0 /= sum; d1 /= sum; } var v1 = matrix_util_1.vec2.scale([0, 0], v, -d0); var v2 = matrix_util_1.vec2.scale([0, 0], v, d1); var cp0 = matrix_util_1.vec2.add([0, 0], point, v1); var cp1 = matrix_util_1.vec2.add([0, 0], point, v2); if (hasConstraint) { cp0 = matrix_util_1.vec2.max([0, 0], cp0, min); cp0 = matrix_util_1.vec2.min([0, 0], cp0, max); cp1 = matrix_util_1.vec2.max([0, 0], cp1, min); cp1 = matrix_util_1.vec2.min([0, 0], cp1, max); } cps.push(cp0); cps.push(cp1); } if (isLoop) { cps.push(cps.shift()); } return cps; }; /** * @ignore * 贝塞尔曲线 */ function catmullRom2bezier(crp, z, constraint) { var isLoop = !!z; var pointList = []; for (var i = 0, l = crp.length; i < l; i += 2) { pointList.push([crp[i], crp[i + 1]]); } var controlPointList = exports.smoothBezier(pointList, 0.4, isLoop, constraint); var len = pointList.length; var d1 = []; var cp1; var cp2; var p; for (var i = 0; i < len - 1; i++) { cp1 = controlPointList[i * 2]; cp2 = controlPointList[i * 2 + 1]; p = pointList[i + 1]; d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]); } if (isLoop) { cp1 = controlPointList[len]; cp2 = controlPointList[len + 1]; p = pointList[0]; d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]); } return d1; } exports.catmullRom2bezier = catmullRom2bezier; /** * @ignore * 将点连接成路径 path */ function getLinePath(points, isInCircle) { return _points2path(points, isInCircle); } exports.getLinePath = getLinePath; /** * @ignore * 根据关键点获取限定了范围的平滑线 */ function getSplinePath(points, isInCircle, constaint) { var data = []; var first = points[0]; var prePoint = null; if (points.length <= 2) { // 两点以内直接绘制成路径 return getLinePath(points, isInCircle); } for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; if (!prePoint || !(prePoint.x === point.x && prePoint.y === point.y)) { data.push(point.x); data.push(point.y); prePoint = point; } } var constraint = constaint || [ // 范围 [0, 0], [1, 1], ]; var splinePath = catmullRom2bezier(data, isInCircle, constraint); splinePath.unshift(['M', first.x, first.y]); return splinePath; } exports.getSplinePath = getSplinePath; /** * @ignore * 将归一化后的路径数据转换成坐标 */ function convertNormalPath(coord, path) { var tmp = []; util_1.each(path, function (subPath) { var action = subPath[0]; switch (action.toLowerCase()) { case 'm': case 'l': case 'c': tmp.push(_convertArr(subPath, coord)); break; case 'z': default: tmp.push(subPath); break; } }); return tmp; } exports.convertNormalPath = convertNormalPath; /** * @ignore * 将路径转换为极坐标下的真实路径 */ function convertPolarPath(coord, path) { var tmp = []; var pre; var cur; var transposed; var equals; util_1.each(path, function (subPath, index) { var action = subPath[0]; switch (action.toLowerCase()) { case 'm': case 'c': case 'q': tmp.push(_convertArr(subPath, coord)); break; case 'l': pre = path[index - 1]; cur = subPath; transposed = coord.isTransposed; // 是否半径相同,转换成圆弧 equals = transposed ? pre[pre.length - 2] === cur[1] : pre[pre.length - 1] === cur[2]; if (equals) { tmp = tmp.concat(_convertPolarPath(pre, cur, coord)); } else { // y 不相等,所以直接转换 tmp.push(_convertArr(subPath, coord)); } break; case 'z': default: tmp.push(subPath); break; } }); _filterFullCirleLine(tmp); // 过滤多余的直线 return tmp; } exports.convertPolarPath = convertPolarPath; },{"../../../util/coordinate":371,"@antv/matrix-util":717,"@antv/util":803}],304:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.splitPoints = void 0; var util_1 = require("@antv/util"); /** * @ignore * 拆分点数据 * @example * // result: [{x: 20, y: 20}, {x: 20, y: 30}] * splitPoints({x: 20,y: [20, 30]}); * @example * // result: [{x: 20, y: 20}, {x: 30, y: 30}] * splitPoints({x: [20, 30],y: [20, 30]}); * @param obj */ function splitPoints(obj) { // y 有可能是数组,对应原始数据中 y 为一个区间数据,如 [19, 30],为了统一也将 x 转换为数组 var x = obj.x; var y = util_1.isArray(obj.y) ? obj.y : [obj.y]; return y.map(function (eachY, index) { return { x: util_1.isArray(x) ? x[index] : x, y: eachY, }; }); } exports.splitPoints = splitPoints; },{"@antv/util":803}],305:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.group = void 0; var util_1 = require("@antv/util"); /** @ignore */ function group(data, fields, appendConditions) { if (appendConditions === void 0) { appendConditions = {}; } if (!fields) { return [data]; } var groups = util_1.groupToMap(data, fields); var array = []; if (fields.length === 1 && appendConditions[fields[0]]) { var values = appendConditions[fields[0]]; for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { var value = values_1[_i]; var arr = groups["_" + value]; if (arr) { // 可能存在用户设置 values ,但是数据中没有对应的字段,则这时候 arr 就为 null array.push(arr); } } } else { for (var k in groups) { if (groups.hasOwnProperty(k)) { var eachGroup = groups[k]; array.push(eachGroup); } } } return array; } exports.group = group; },{"@antv/util":803}],306:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isModelChange = void 0; var util_1 = require("@antv/util"); /** * @ignore * Determines whether model is change * @param currentModel * @param preModel * @returns */ function isModelChange(currentModel, preModel) { return util_1.some(['color', 'shape', 'size', 'x', 'y', 'isInCircle', 'data', 'style', 'defaultStyle', 'points', 'mappingData'], function (key) { return !util_1.isEqual(currentModel[key], preModel[key]); }); } exports.isModelChange = isModelChange; },{"@antv/util":803}],307:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseFields = void 0; var util_1 = require("@antv/util"); /** @ignore */ function parseFields(field) { if (util_1.isArray(field)) { return field; } return field.split('*'); } exports.parseFields = parseFields; },{"@antv/util":803}],308:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDefaultSize = void 0; var util_1 = require("@antv/util"); var coordinate_1 = require("../../util/coordinate"); // 已经排序后的数据查找距离最小的 function findMinDistance(arr, scale) { var count = arr.length; var sourceArr = arr; if (util_1.isString(sourceArr[0])) { // 日期类型的 values 经常上文本类型,所以需要转换一下 sourceArr = arr.map(function (v) { return scale.translate(v); }); } var distance = sourceArr[1] - sourceArr[0]; for (var i = 2; i < count; i++) { var tmp = sourceArr[i] - sourceArr[i - 1]; if (distance > tmp) { distance = tmp; } } return distance; } function getDodgeCount(dataArray, dodgeBy) { if (dodgeBy) { var mergeData = util_1.flatten(dataArray); var values = util_1.valuesOfKey(mergeData, dodgeBy); return values.length; } return dataArray.length; } /** @ignore */ function getDefaultSize(geometry) { var theme = geometry.theme; var coordinate = geometry.coordinate; var xScale = geometry.getXScale(); var xValues = xScale.values; var dataArray = geometry.beforeMappingData; var count = xValues.length; if (xScale.isLinear && xValues.length > 1) { // Linear 类型用户有可能设置了 min, max 范围所以需要根据数据最小区间计算 count xValues.sort(); var interval = findMinDistance(xValues, xScale); count = (xScale.max - xScale.min) / interval; if (xValues.length > count) { count = xValues.length; } } var range = xScale.range; var normalizedSize = 1 / count; var wr = 1; if (coordinate.isPolar) { if (coordinate.isTransposed && count > 1) { // 极坐标下多层环图 wr = theme.multiplePieWidthRatio; } else { wr = theme.roseWidthRatio; } } else { if (xScale.isLinear) { normalizedSize *= range[1] - range[0]; } wr = theme.columnWidthRatio; } normalizedSize *= wr; if (geometry.getAdjust('dodge')) { var dodgeAdjust = geometry.getAdjust('dodge'); var dodgeBy = dodgeAdjust.dodgeBy; var dodgeCount = getDodgeCount(dataArray, dodgeBy); normalizedSize = normalizedSize / dodgeCount; } // 最大和最小限制 var maxColumnWidth = theme.maxColumnWidth, minColumnWidth = theme.minColumnWidth; var xDimensionLength = coordinate_1.getXDimensionLength(geometry.coordinate); if (maxColumnWidth) { var normalizedMaxColumnWidth = maxColumnWidth / xDimensionLength; if (normalizedSize > normalizedMaxColumnWidth) { normalizedSize = normalizedMaxColumnWidth; } } if (minColumnWidth) { var normalizedMinColumnWidth = minColumnWidth / xDimensionLength; if (normalizedSize < normalizedMinColumnWidth) { normalizedSize = normalizedMinColumnWidth; } } return normalizedSize; } exports.getDefaultSize = getDefaultSize; },{"../../util/coordinate":371,"@antv/util":803}],309:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Util = void 0; var tslib_1 = require("tslib"); // 注册黑暗主题 var core_1 = require("./core"); var dark_1 = require("./theme/style-sheet/dark"); var theme_1 = require("./util/theme"); core_1.registerTheme('dark', theme_1.createThemeByStylesheet(dark_1.antvDark)); // 注册 G 渲染引擎 var CanvasEngine = tslib_1.__importStar(require("@antv/g-canvas")); var SVGEngine = tslib_1.__importStar(require("@antv/g-svg")); var core_2 = require("./core"); core_2.registerEngine('canvas', CanvasEngine); core_2.registerEngine('svg', SVGEngine); // 注册 G2 内置的 geometry var core_3 = require("./core"); var area_1 = tslib_1.__importDefault(require("./geometry/area")); var edge_1 = tslib_1.__importDefault(require("./geometry/edge")); var heatmap_1 = tslib_1.__importDefault(require("./geometry/heatmap")); var interval_1 = tslib_1.__importDefault(require("./geometry/interval")); var line_1 = tslib_1.__importDefault(require("./geometry/line")); var path_1 = tslib_1.__importDefault(require("./geometry/path")); var point_1 = tslib_1.__importDefault(require("./geometry/point")); var polygon_1 = tslib_1.__importDefault(require("./geometry/polygon")); var schema_1 = tslib_1.__importDefault(require("./geometry/schema")); core_3.registerGeometry('Polygon', polygon_1.default); core_3.registerGeometry('Interval', interval_1.default); core_3.registerGeometry('Schema', schema_1.default); core_3.registerGeometry('Path', path_1.default); core_3.registerGeometry('Point', point_1.default); core_3.registerGeometry('Line', line_1.default); core_3.registerGeometry('Area', area_1.default); core_3.registerGeometry('Edge', edge_1.default); core_3.registerGeometry('Heatmap', heatmap_1.default); // 引入所有内置的 shapes require("./geometry/shape/area/line"); require("./geometry/shape/area/smooth"); require("./geometry/shape/area/smooth-line"); require("./geometry/shape/edge/arc"); require("./geometry/shape/edge/smooth"); require("./geometry/shape/edge/vhv"); require("./geometry/shape/interval/funnel"); require("./geometry/shape/interval/hollow-rect"); require("./geometry/shape/interval/line"); require("./geometry/shape/interval/pyramid"); require("./geometry/shape/interval/tick"); require("./geometry/shape/line/step"); require("./geometry/shape/point/hollow"); require("./geometry/shape/point/image"); require("./geometry/shape/point/solid"); require("./geometry/shape/schema/box"); require("./geometry/shape/schema/candle"); require("./geometry/shape/polygon/square"); // 注册 Geometry 内置的 label var core_4 = require("./core"); var base_1 = tslib_1.__importDefault(require("./geometry/label/base")); var interval_2 = tslib_1.__importDefault(require("./geometry/label/interval")); var pie_1 = tslib_1.__importDefault(require("./geometry/label/pie")); var polar_1 = tslib_1.__importDefault(require("./geometry/label/polar")); core_4.registerGeometryLabel('base', base_1.default); core_4.registerGeometryLabel('interval', interval_2.default); core_4.registerGeometryLabel('pie', pie_1.default); core_4.registerGeometryLabel('polar', polar_1.default); // 注册 Geometry label 内置的布局函数 var core_5 = require("./core"); var distribute_1 = require("./geometry/label/layout/pie/distribute"); var outer_1 = require("./geometry/label/layout/pie/outer"); var limit_in_canvas_1 = require("./geometry/label/layout/limit-in-canvas"); var limit_in_shape_1 = require("./geometry/label/layout/limit-in-shape"); var overlap_1 = require("./geometry/label/layout/overlap"); core_5.registerGeometryLabelLayout('overlap', overlap_1.overlap); core_5.registerGeometryLabelLayout('distribute', distribute_1.distribute); core_5.registerGeometryLabelLayout('fixed-overlap', overlap_1.fixedOverlap); core_5.registerGeometryLabelLayout('limit-in-shape', limit_in_shape_1.limitInShape); core_5.registerGeometryLabelLayout('limit-in-canvas', limit_in_canvas_1.limitInCanvas); core_5.registerGeometryLabelLayout('pie-outer', outer_1.pieOuterLabelLayout); // 注册需要的动画执行函数 var fade_1 = require("./animate/animation/fade"); var grow_in_1 = require("./animate/animation/grow-in"); var path_in_1 = require("./animate/animation/path-in"); var position_update_1 = require("./animate/animation/position-update"); var scale_in_1 = require("./animate/animation/scale-in"); var sector_path_update_1 = require("./animate/animation/sector-path-update"); var wave_in_1 = require("./animate/animation/wave-in"); var zoom_1 = require("./animate/animation/zoom"); var core_6 = require("./core"); core_6.registerAnimation('fade-in', fade_1.fadeIn); core_6.registerAnimation('fade-out', fade_1.fadeOut); core_6.registerAnimation('grow-in-x', grow_in_1.growInX); core_6.registerAnimation('grow-in-xy', grow_in_1.growInXY); core_6.registerAnimation('grow-in-y', grow_in_1.growInY); core_6.registerAnimation('scale-in-x', scale_in_1.scaleInX); core_6.registerAnimation('scale-in-y', scale_in_1.scaleInY); core_6.registerAnimation('wave-in', wave_in_1.waveIn); core_6.registerAnimation('zoom-in', zoom_1.zoomIn); core_6.registerAnimation('zoom-out', zoom_1.zoomOut); core_6.registerAnimation('position-update', position_update_1.positionUpdate); core_6.registerAnimation('sector-path-update', sector_path_update_1.sectorPathUpdate); core_6.registerAnimation('path-in', path_in_1.pathIn); // 注册内置的 Facet var core_7 = require("./core"); var circle_1 = tslib_1.__importDefault(require("./facet/circle")); var list_1 = tslib_1.__importDefault(require("./facet/list")); var matrix_1 = tslib_1.__importDefault(require("./facet/matrix")); var mirror_1 = tslib_1.__importDefault(require("./facet/mirror")); var rect_1 = tslib_1.__importDefault(require("./facet/rect")); var tree_1 = tslib_1.__importDefault(require("./facet/tree")); core_7.registerFacet('rect', rect_1.default); core_7.registerFacet('mirror', mirror_1.default); core_7.registerFacet('list', list_1.default); core_7.registerFacet('matrix', matrix_1.default); core_7.registerFacet('circle', circle_1.default); core_7.registerFacet('tree', tree_1.default); // 注册内置的 Component var core_8 = require("./core"); var annotation_1 = tslib_1.__importDefault(require("./chart/controller/annotation")); var axis_1 = tslib_1.__importDefault(require("./chart/controller/axis")); var legend_1 = tslib_1.__importDefault(require("./chart/controller/legend")); var slider_1 = tslib_1.__importDefault(require("./chart/controller/slider")); var tooltip_1 = tslib_1.__importDefault(require("./chart/controller/tooltip")); // register build-in components core_8.registerComponentController('axis', axis_1.default); core_8.registerComponentController('legend', legend_1.default); core_8.registerComponentController('tooltip', tooltip_1.default); core_8.registerComponentController('annotation', annotation_1.default); core_8.registerComponentController('slider', slider_1.default); // 注册 Interaction Action var core_9 = require("./core"); var active_region_1 = tslib_1.__importDefault(require("./interaction/action/active-region")); var sibling_1 = tslib_1.__importDefault(require("./interaction/action/component/tooltip/sibling")); var geometry_1 = tslib_1.__importDefault(require("./interaction/action/component/tooltip/geometry")); var ellipsis_text_1 = tslib_1.__importDefault(require("./interaction/action/component/tooltip/ellipsis-text")); var active_1 = tslib_1.__importDefault(require("./interaction/action/element/active")); var link_by_color_1 = tslib_1.__importDefault(require("./interaction/action/element/link-by-color")); var range_active_1 = tslib_1.__importDefault(require("./interaction/action/element/range-active")); var single_active_1 = tslib_1.__importDefault(require("./interaction/action/element/single-active")); var highlight_1 = tslib_1.__importDefault(require("./interaction/action/element/highlight")); var highlight_by_color_1 = tslib_1.__importDefault(require("./interaction/action/element/highlight-by-color")); var highlight_by_x_1 = tslib_1.__importDefault(require("./interaction/action/element/highlight-by-x")); var range_highlight_1 = tslib_1.__importDefault(require("./interaction/action/element/range-highlight")); var single_highlight_1 = tslib_1.__importDefault(require("./interaction/action/element/single-highlight")); var range_selected_1 = tslib_1.__importDefault(require("./interaction/action/element/range-selected")); var selected_1 = tslib_1.__importDefault(require("./interaction/action/element/selected")); var single_selected_1 = tslib_1.__importDefault(require("./interaction/action/element/single-selected")); var list_active_1 = tslib_1.__importDefault(require("./interaction/action/component/list-active")); var list_highlight_1 = tslib_1.__importDefault(require("./interaction/action/component/list-highlight")); var list_selected_1 = tslib_1.__importDefault(require("./interaction/action/component/list-selected")); var list_unchecked_1 = tslib_1.__importDefault(require("./interaction/action/component/list-unchecked")); var circle_2 = tslib_1.__importDefault(require("./interaction/action/mask/circle")); var dim_rect_1 = tslib_1.__importDefault(require("./interaction/action/mask/dim-rect")); var path_2 = tslib_1.__importDefault(require("./interaction/action/mask/path")); var rect_2 = tslib_1.__importDefault(require("./interaction/action/mask/rect")); var smooth_path_1 = tslib_1.__importDefault(require("./interaction/action/mask/smooth-path")); var cursor_1 = tslib_1.__importDefault(require("./interaction/action/cursor")); var filter_1 = tslib_1.__importDefault(require("./interaction/action/data/filter")); var range_filter_1 = tslib_1.__importDefault(require("./interaction/action/data/range-filter")); var sibling_filter_1 = tslib_1.__importDefault(require("./interaction/action/data/sibling-filter")); var filter_2 = tslib_1.__importDefault(require("./interaction/action/element/filter")); var sibling_filter_2 = tslib_1.__importDefault(require("./interaction/action/element/sibling-filter")); var button_1 = tslib_1.__importDefault(require("./interaction/action/view/button")); var drag_1 = tslib_1.__importDefault(require("./interaction/action/view/drag")); var move_1 = tslib_1.__importDefault(require("./interaction/action/view/move")); var scale_translate_1 = tslib_1.__importDefault(require("./interaction/action/view/scale-translate")); var scale_zoom_1 = tslib_1.__importDefault(require("./interaction/action/view/scale-zoom")); core_9.registerAction('tooltip', geometry_1.default); core_9.registerAction('sibling-tooltip', sibling_1.default); core_9.registerAction('ellipsis-text', ellipsis_text_1.default); core_9.registerAction('element-active', active_1.default); core_9.registerAction('element-single-active', single_active_1.default); core_9.registerAction('element-range-active', range_active_1.default); core_9.registerAction('element-highlight', highlight_1.default); core_9.registerAction('element-highlight-by-x', highlight_by_x_1.default); core_9.registerAction('element-highlight-by-color', highlight_by_color_1.default); core_9.registerAction('element-single-highlight', single_highlight_1.default); core_9.registerAction('element-range-highlight', range_highlight_1.default); core_9.registerAction('element-sibling-highlight', range_highlight_1.default, { effectSiblings: true, effectByRecord: true, }); core_9.registerAction('element-selected', selected_1.default); core_9.registerAction('element-single-selected', single_selected_1.default); core_9.registerAction('element-range-selected', range_selected_1.default); core_9.registerAction('element-link-by-color', link_by_color_1.default); core_9.registerAction('active-region', active_region_1.default); core_9.registerAction('list-active', list_active_1.default); core_9.registerAction('list-selected', list_selected_1.default); core_9.registerAction('list-highlight', list_highlight_1.default); core_9.registerAction('list-unchecked', list_unchecked_1.default); core_9.registerAction('legend-item-highlight', list_highlight_1.default, { componentNames: ['legend'], }); core_9.registerAction('axis-label-highlight', list_highlight_1.default, { componentNames: ['axis'], }); core_9.registerAction('rect-mask', rect_2.default); core_9.registerAction('x-rect-mask', dim_rect_1.default, { dim: 'x' }); core_9.registerAction('y-rect-mask', dim_rect_1.default, { dim: 'y' }); core_9.registerAction('circle-mask', circle_2.default); core_9.registerAction('path-mask', path_2.default); core_9.registerAction('smooth-path-mask', smooth_path_1.default); core_9.registerAction('cursor', cursor_1.default); core_9.registerAction('data-filter', filter_1.default); core_9.registerAction('brush', range_filter_1.default); core_9.registerAction('brush-x', range_filter_1.default, { dims: ['x'] }); core_9.registerAction('brush-y', range_filter_1.default, { dims: ['y'] }); core_9.registerAction('sibling-filter', sibling_filter_1.default); core_9.registerAction('sibling-x-filter', sibling_filter_1.default); core_9.registerAction('sibling-y-filter', sibling_filter_1.default); core_9.registerAction('element-filter', filter_2.default); core_9.registerAction('element-sibling-filter', sibling_filter_2.default); core_9.registerAction('element-sibling-filter-record', sibling_filter_2.default, { byRecord: true }); core_9.registerAction('view-drag', drag_1.default); core_9.registerAction('view-move', move_1.default); core_9.registerAction('scale-translate', scale_translate_1.default); core_9.registerAction('scale-zoom', scale_zoom_1.default); core_9.registerAction('reset-button', button_1.default, { name: 'reset-button', text: 'reset', }); // 注册默认的 Interaction 交互行为 var core_10 = require("./core"); function isPointInView(context) { return context.isInPlot(); } // 注册 tooltip 的 interaction core_10.registerInteraction('tooltip', { start: [ { trigger: 'plot:mousemove', action: 'tooltip:show', throttle: { wait: 50, leading: true, trailing: false } }, { trigger: 'plot:touchmove', action: 'tooltip:show', throttle: { wait: 50, leading: true, trailing: false } }, ], end: [ { trigger: 'plot:mouseleave', action: 'tooltip:hide' }, { trigger: 'plot:leave', action: 'tooltip:hide' }, { trigger: 'plot:touchend', action: 'tooltip:hide' }, ], }); core_10.registerInteraction('ellipsis-text', { start: [ { trigger: 'legend-item-name:mousemove', action: 'ellipsis-text:show', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'legend-item-name:touchstart', action: 'ellipsis-text:show', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'axis-label:mousemove', action: 'ellipsis-text:show', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'axis-label:touchstart', action: 'ellipsis-text:show', throttle: { wait: 50, leading: true, trailing: false }, }, ], end: [ { trigger: 'legend-item-name:mouseleave', action: 'ellipsis-text:hide' }, { trigger: 'legend-item-name:touchend', action: 'ellipsis-text:hide' }, { trigger: 'axis-label:mouseleave', action: 'ellipsis-text:hide' }, { trigger: 'axis-label:touchend', action: 'ellipsis-text:hide' }, ], }); // 移动到 elment 上 active core_10.registerInteraction('element-active', { start: [{ trigger: 'element:mouseenter', action: 'element-active:active' }], end: [{ trigger: 'element:mouseleave', action: 'element-active:reset' }], }); // 点击选中,允许取消 core_10.registerInteraction('element-selected', { start: [{ trigger: 'element:click', action: 'element-selected:toggle' }], }); // hover highlight,允许取消 core_10.registerInteraction('element-highlight', { start: [{ trigger: 'element:mouseenter', action: 'element-highlight:highlight' }], end: [{ trigger: 'element:mouseleave', action: 'element-highlight:reset' }], }); // hover highlight by x,允许取消 core_10.registerInteraction('element-highlight-by-x', { start: [{ trigger: 'element:mouseenter', action: 'element-highlight-by-x:highlight' }], end: [{ trigger: 'element:mouseleave', action: 'element-highlight-by-x:reset' }], }); // hover highlight by y,允许取消 core_10.registerInteraction('element-highlight-by-color', { start: [{ trigger: 'element:mouseenter', action: 'element-highlight-by-color:highlight' }], end: [{ trigger: 'element:mouseleave', action: 'element-highlight-by-color:reset' }], }); // legend hover,element active core_10.registerInteraction('legend-active', { start: [{ trigger: 'legend-item:mouseenter', action: ['list-active:active', 'element-active:active'] }], end: [{ trigger: 'legend-item:mouseleave', action: ['list-active:reset', 'element-active:reset'] }], }); // legend hover,element active core_10.registerInteraction('legend-highlight', { start: [ { trigger: 'legend-item:mouseenter', action: ['legend-item-highlight:highlight', 'element-highlight:highlight'] }, ], end: [{ trigger: 'legend-item:mouseleave', action: ['legend-item-highlight:reset', 'element-highlight:reset'] }], }); // legend hover,element active core_10.registerInteraction('axis-label-highlight', { start: [ { trigger: 'axis-label:mouseenter', action: ['axis-label-highlight:highlight', 'element-highlight:highlight'] }, ], end: [{ trigger: 'axis-label:mouseleave', action: ['axis-label-highlight:reset', 'element-highlight:reset'] }], }); // legend hover,element active core_10.registerInteraction('element-list-highlight', { start: [{ trigger: 'element:mouseenter', action: ['list-highlight:highlight', 'element-highlight:highlight'] }], end: [{ trigger: 'element:mouseleave', action: ['list-highlight:reset', 'element-highlight:reset'] }], }); // 框选 core_10.registerInteraction('element-range-highlight', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'mask:mouseenter', action: 'cursor:move' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, { trigger: 'mask:mouseleave', action: 'cursor:crosshair' }, ], start: [ { trigger: 'plot:mousedown', isEnable: function (context) { // 不要点击在 mask 上重新开始 return !context.isInShape('mask'); }, action: ['rect-mask:start', 'rect-mask:show'], }, { trigger: 'mask:dragstart', action: ['rect-mask:moveStart'], }, ], processing: [ { trigger: 'plot:mousemove', action: ['rect-mask:resize'], }, { trigger: 'mask:drag', action: ['rect-mask:move'], }, { trigger: 'mask:change', action: ['element-range-highlight:highlight'], }, ], end: [ { trigger: 'plot:mouseup', action: ['rect-mask:end'] }, { trigger: 'mask:dragend', action: ['rect-mask:moveEnd'] }, { trigger: 'document:mouseup', isEnable: function (context) { return !context.isInPlot(); }, action: ['element-range-highlight:clear', 'rect-mask:end', 'rect-mask:hide'], }, ], rollback: [{ trigger: 'dblclick', action: ['element-range-highlight:clear', 'rect-mask:hide'] }], }); core_10.registerInteraction('brush', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, ], start: [ { trigger: 'mousedown', isEnable: isPointInView, action: ['brush:start', 'rect-mask:start', 'rect-mask:show'], }, ], processing: [ { trigger: 'mousemove', isEnable: isPointInView, action: ['rect-mask:resize'], }, ], end: [ { trigger: 'mouseup', isEnable: isPointInView, action: ['brush:filter', 'brush:end', 'rect-mask:end', 'rect-mask:hide', 'reset-button:show'], }, ], rollback: [{ trigger: 'reset-button:click', action: ['brush:reset', 'reset-button:hide', 'cursor:crosshair'] }], }); core_10.registerInteraction('brush-visible', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, ], start: [ { trigger: 'plot:mousedown', action: ['rect-mask:start', 'rect-mask:show'], }, ], processing: [ { trigger: 'plot:mousemove', action: ['rect-mask:resize'], }, { trigger: 'mask:change', action: ['element-range-highlight:highlight'] }, ], end: [ { trigger: 'plot:mouseup', action: ['rect-mask:end', 'rect-mask:hide', 'element-filter:filter', 'element-range-highlight:clear'], }, ], rollback: [ { trigger: 'dblclick', action: ['element-filter:clear'], }, ], }); core_10.registerInteraction('brush-x', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, ], start: [ { trigger: 'mousedown', isEnable: isPointInView, action: ['brush-x:start', 'x-rect-mask:start', 'x-rect-mask:show'], }, ], processing: [ { trigger: 'mousemove', isEnable: isPointInView, action: ['x-rect-mask:resize'], }, ], end: [ { trigger: 'mouseup', isEnable: isPointInView, action: ['brush-x:filter', 'brush-x:end', 'x-rect-mask:end', 'x-rect-mask:hide'], }, ], rollback: [{ trigger: 'dblclick', action: ['brush-x:reset'] }], }); core_10.registerInteraction('element-path-highlight', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, ], start: [ { trigger: 'mousedown', isEnable: isPointInView, action: 'path-mask:start' }, { trigger: 'mousedown', isEnable: isPointInView, action: 'path-mask:show' }, ], processing: [{ trigger: 'mousemove', action: 'path-mask:addPoint' }], end: [{ trigger: 'mouseup', action: 'path-mask:end' }], rollback: [{ trigger: 'dblclick', action: 'path-mask:hide' }], }); // 点击选中,允许取消 core_10.registerInteraction('element-single-selected', { start: [{ trigger: 'element:click', action: 'element-single-selected:toggle' }], }); // 筛选数据 core_10.registerInteraction('legend-filter', { showEnable: [ { trigger: 'legend-item:mouseenter', action: 'cursor:pointer' }, { trigger: 'legend-item:mouseleave', action: 'cursor:default' }, ], start: [{ trigger: 'legend-item:click', action: ['list-unchecked:toggle', 'data-filter:filter'] }], }); // 筛选数据 core_10.registerInteraction('continuous-filter', { start: [{ trigger: 'legend:valuechanged', action: 'data-filter:filter' }], }); // 筛选数据 core_10.registerInteraction('continuous-visible-filter', { start: [{ trigger: 'legend:valuechanged', action: 'element-filter:filter' }], }); // 筛选图形 core_10.registerInteraction('legend-visible-filter', { showEnable: [ { trigger: 'legend-item:mouseenter', action: 'cursor:pointer' }, { trigger: 'legend-item:mouseleave', action: 'cursor:default' }, ], start: [{ trigger: 'legend-item:click', action: ['list-unchecked:toggle', 'element-filter:filter'] }], }); // 出现背景框 core_10.registerInteraction('active-region', { start: [{ trigger: 'plot:mousemove', action: 'active-region:show' }], end: [{ trigger: 'plot:mouseleave', action: 'active-region:hide' }], }); function isWheelDown(event) { event.gEvent.preventDefault(); return event.gEvent.originalEvent.deltaY > 0; } core_10.registerInteraction('view-zoom', { start: [ { trigger: 'plot:mousewheel', isEnable: function (context) { return isWheelDown(context.event); }, action: 'scale-zoom:zoomOut', throttle: { wait: 100, leading: true, trailing: false }, }, { trigger: 'plot:mousewheel', isEnable: function (context) { return !isWheelDown(context.event); }, action: 'scale-zoom:zoomIn', throttle: { wait: 100, leading: true, trailing: false }, }, ], }); core_10.registerInteraction('sibling-tooltip', { start: [{ trigger: 'plot:mousemove', action: 'sibling-tooltip:show' }], end: [{ trigger: 'plot:mouseleave', action: 'sibling-tooltip:hide' }], }); tslib_1.__exportStar(require("./core"), exports); // 一些工具方法导出 var graphics_1 = require("./util/graphics"); var transform_1 = require("./util/transform"); exports.Util = { translate: transform_1.translate, rotate: transform_1.rotate, zoom: transform_1.zoom, transform: transform_1.transform, getAngle: graphics_1.getAngle, polarToCartesian: graphics_1.polarToCartesian, }; },{"./animate/animation/fade":207,"./animate/animation/grow-in":208,"./animate/animation/path-in":210,"./animate/animation/position-update":211,"./animate/animation/scale-in":212,"./animate/animation/sector-path-update":213,"./animate/animation/wave-in":215,"./animate/animation/zoom":216,"./chart/controller/annotation":220,"./chart/controller/axis":221,"./chart/controller/legend":226,"./chart/controller/slider":227,"./chart/controller/tooltip":228,"./core":238,"./facet/circle":241,"./facet/list":244,"./facet/matrix":245,"./facet/mirror":246,"./facet/rect":247,"./facet/tree":248,"./geometry/area":249,"./geometry/edge":251,"./geometry/heatmap":253,"./geometry/interval":254,"./geometry/label/base":255,"./geometry/label/interval":257,"./geometry/label/layout/limit-in-canvas":258,"./geometry/label/layout/limit-in-shape":259,"./geometry/label/layout/overlap":260,"./geometry/label/layout/pie/distribute":261,"./geometry/label/layout/pie/outer":262,"./geometry/label/pie":263,"./geometry/label/polar":264,"./geometry/line":265,"./geometry/path":266,"./geometry/point":267,"./geometry/polygon":268,"./geometry/schema":269,"./geometry/shape/area/line":271,"./geometry/shape/area/smooth":273,"./geometry/shape/area/smooth-line":272,"./geometry/shape/edge/arc":276,"./geometry/shape/edge/smooth":278,"./geometry/shape/edge/vhv":280,"./geometry/shape/interval/funnel":281,"./geometry/shape/interval/hollow-rect":282,"./geometry/shape/interval/line":284,"./geometry/shape/interval/pyramid":285,"./geometry/shape/interval/tick":286,"./geometry/shape/line/step":289,"./geometry/shape/point/hollow":291,"./geometry/shape/point/image":292,"./geometry/shape/point/solid":294,"./geometry/shape/polygon/square":297,"./geometry/shape/schema/box":298,"./geometry/shape/schema/candle":299,"./interaction/action/active-region":310,"./interaction/action/component/list-active":313,"./interaction/action/component/list-highlight":315,"./interaction/action/component/list-selected":316,"./interaction/action/component/list-unchecked":318,"./interaction/action/component/tooltip/ellipsis-text":319,"./interaction/action/component/tooltip/geometry":320,"./interaction/action/component/tooltip/sibling":321,"./interaction/action/cursor":322,"./interaction/action/data/filter":323,"./interaction/action/data/range-filter":324,"./interaction/action/data/sibling-filter":325,"./interaction/action/element/active":326,"./interaction/action/element/filter":327,"./interaction/action/element/highlight":331,"./interaction/action/element/highlight-by-color":328,"./interaction/action/element/highlight-by-x":329,"./interaction/action/element/link-by-color":332,"./interaction/action/element/range-active":333,"./interaction/action/element/range-highlight":334,"./interaction/action/element/range-selected":335,"./interaction/action/element/selected":337,"./interaction/action/element/sibling-filter":338,"./interaction/action/element/single-active":339,"./interaction/action/element/single-highlight":340,"./interaction/action/element/single-selected":341,"./interaction/action/mask/circle":347,"./interaction/action/mask/dim-rect":348,"./interaction/action/mask/path":349,"./interaction/action/mask/rect":350,"./interaction/action/mask/smooth-path":351,"./interaction/action/view/button":354,"./interaction/action/view/drag":355,"./interaction/action/view/move":356,"./interaction/action/view/scale-translate":358,"./interaction/action/view/scale-zoom":359,"./theme/style-sheet/dark":366,"./util/graphics":375,"./util/theme":382,"./util/transform":384,"@antv/g-canvas":127,"@antv/g-svg":186,"tslib":385}],310:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var graphics_1 = require("../../util/graphics"); var base_1 = tslib_1.__importDefault(require("./base")); /** * 背景框的 Action * @ignore */ var ActiveRegion = /** @class */ (function (_super) { tslib_1.__extends(ActiveRegion, _super); function ActiveRegion() { return _super !== null && _super.apply(this, arguments) || this; } /** * 显示 */ ActiveRegion.prototype.show = function () { var view = this.context.view; var ev = this.context.event; var tooltipItems = view.getTooltipItems({ x: ev.x, y: ev.y, }); if (util_1.isEqual(tooltipItems, this.items)) { // 如果拾取数据同上次相同,则不重复绘制 return; } this.items = tooltipItems; if (tooltipItems.length) { var xField_1 = view.getXScale().field; var xValue_1 = tooltipItems[0].data[xField_1]; // 根据 x 对应的值查找 elements var elements_1 = []; var geometries = view.geometries; util_1.each(geometries, function (geometry) { if (geometry.type === 'interval' || geometry.type === 'schema') { var result = geometry.getElementsBy(function (ele) { var eleData = ele.getData(); return eleData[xField_1] === xValue_1; }); elements_1 = elements_1.concat(result); } }); // 根据 bbox 计算背景框的面积区域 if (elements_1.length) { var coordinate_1 = view.getCoordinate(); var firstBBox_1 = elements_1[0].shape.getCanvasBBox(); var lastBBox_1 = elements_1[0].shape.getCanvasBBox(); var groupBBox_1 = firstBBox_1; util_1.each(elements_1, function (ele) { var bbox = ele.shape.getCanvasBBox(); if (coordinate_1.isTransposed) { if (bbox.minY < firstBBox_1.minY) { firstBBox_1 = bbox; } if (bbox.maxY > lastBBox_1.maxY) { lastBBox_1 = bbox; } } else { if (bbox.minX < firstBBox_1.minX) { firstBBox_1 = bbox; } if (bbox.maxX > lastBBox_1.maxX) { lastBBox_1 = bbox; } } groupBBox_1.x = Math.min(bbox.minX, groupBBox_1.minX); groupBBox_1.y = Math.min(bbox.minY, groupBBox_1.minY); groupBBox_1.width = Math.max(bbox.maxX, groupBBox_1.maxX) - groupBBox_1.x; groupBBox_1.height = Math.max(bbox.maxY, groupBBox_1.maxY) - groupBBox_1.y; }); var backgroundGroup = view.backgroundGroup, coordinateBBox = view.coordinateBBox; var path = void 0; if (coordinate_1.isRect) { var xScale = view.getXScale(); var appendRatio = xScale.isLinear ? 0 : 0.25; // 如果 x 轴是数值类型,如直方图,不需要家额外的宽度 var minX = void 0; var minY = void 0; var width = void 0; var height = void 0; if (coordinate_1.isTransposed) { minX = coordinateBBox.minX; minY = Math.min(lastBBox_1.minY, firstBBox_1.minY) - appendRatio * lastBBox_1.height; width = coordinateBBox.width; height = groupBBox_1.height + appendRatio * 2 * lastBBox_1.height; } else { minX = Math.min(firstBBox_1.minX, lastBBox_1.minX) - appendRatio * firstBBox_1.width; minY = Math.min(coordinateBBox.minY, firstBBox_1.minY); width = groupBBox_1.width + appendRatio * 2 * firstBBox_1.width; height = coordinateBBox.height; } path = [ ['M', minX, minY], ['L', minX + width, minY], ['L', minX + width, minY + height], ['L', minX, minY + height], ['Z'], ]; } else { var firstElement = util_1.head(elements_1); var lastElement = util_1.last(elements_1); var startAngle = graphics_1.getAngle(firstElement.getModel(), coordinate_1).startAngle; var endAngle = graphics_1.getAngle(lastElement.getModel(), coordinate_1).endAngle; var center = coordinate_1.getCenter(); var radius = coordinate_1.getRadius(); var innterRadius = coordinate_1.innerRadius * radius; path = graphics_1.getSectorPath(center.x, center.y, radius, startAngle, endAngle, innterRadius); } if (this.regionPath) { this.regionPath.attr('path', path); this.regionPath.show(); } else { this.regionPath = backgroundGroup.addShape({ type: 'path', name: 'active-region', capture: false, attrs: { path: path, fill: '#CCD6EC', opacity: 0.3, }, }); } } } }; /** * 隐藏 */ ActiveRegion.prototype.hide = function () { if (this.regionPath) { this.regionPath.hide(); } // this.regionPath = null; this.items = null; }; /** * 销毁 */ ActiveRegion.prototype.destroy = function () { this.hide(); if (this.regionPath) { this.regionPath.remove(true); } _super.prototype.destroy.call(this); }; return ActiveRegion; }(base_1.default)); exports.default = ActiveRegion; },{"../../util/graphics":375,"./base":311,"@antv/util":803,"tslib":385}],311:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); /** * Action 的基类 */ var Action = /** @class */ (function () { function Action(context, cfg) { this.context = context; this.cfg = cfg; context.addAction(this); } /** * 设置配置项传入的值 * @param cfg */ Action.prototype.applyCfg = function (cfg) { util_1.assign(this, cfg); }; /** * Inits action,提供给子类用于继承 */ Action.prototype.init = function () { this.applyCfg(this.cfg); }; /** * Destroys action */ Action.prototype.destroy = function () { // 移除 action this.context.removeAction(this); // 清空 this.context = null; }; return Action; }()); exports.default = Action; },{"@antv/util":803}],312:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("./base")); /** 回调函数构建的 Action */ var CallbackAction = /** @class */ (function (_super) { tslib_1.__extends(CallbackAction, _super); function CallbackAction() { return _super !== null && _super.apply(this, arguments) || this; } /** * 执行 */ CallbackAction.prototype.execute = function () { if (this.callback) { this.callback(this.context); } }; /** * 销毁 */ CallbackAction.prototype.destroy = function () { _super.prototype.destroy.call(this); this.callback = null; }; return CallbackAction; }(base_1.default)); exports.default = CallbackAction; },{"./base":311,"tslib":385}],313:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var list_state_1 = tslib_1.__importDefault(require("./list-state")); /** * 列表项(图例项、坐标轴文本)激活的 Action * @class * @ignore */ var ListActive = /** @class */ (function (_super) { tslib_1.__extends(ListActive, _super); function ListActive() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'active'; return _this; } /** * 激活选项 */ ListActive.prototype.active = function () { this.setState(); }; return ListActive; }(list_state_1.default)); exports.default = ListActive; },{"./list-state":317,"tslib":385}],314:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clearList = void 0; var util_1 = require("@antv/util"); var STATUS_UNACTIVE = 'inactive'; var STATUS_ACTIVE = 'active'; /** * 清理图例的 Highlight 效果 * @param list 列表组件,图例或者坐标轴 * @ignore */ function clearList(list) { var items = list.getItems(); util_1.each(items, function (item) { if (list.hasState(item, STATUS_ACTIVE)) { list.setItemState(item, STATUS_ACTIVE, false); } if (list.hasState(item, STATUS_UNACTIVE)) { list.setItemState(item, STATUS_UNACTIVE, false); } }); } exports.clearList = clearList; },{"@antv/util":803}],315:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var list_highlight_util_1 = require("./list-highlight-util"); var list_state_1 = tslib_1.__importDefault(require("./list-state")); var STATUS_UNACTIVE = 'inactive'; var STATUS_ACTIVE = 'active'; /** * highlight Action 的效果是 active 和 inactive 两个状态的组合 * @class * @ignore */ var ListHighlight = /** @class */ (function (_super) { tslib_1.__extends(ListHighlight, _super); function ListHighlight() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = STATUS_ACTIVE; _this.ignoreItemStates = ['unchecked']; // 当存在 unchecked 状态时不触发 return _this; } // 如果 item.name 匹配,则设置 highlight 以及取消 ListHighlight.prototype.setItemsState = function (list, name, enable) { this.setHighlightBy(list, function (item) { return item.name === name; }, enable); }; // 单个 item 设置状态 ListHighlight.prototype.setItemState = function (list, item, enable) { var items = list.getItems(); this.setHighlightBy(list, function (el) { return el === item; }, enable); }; // 根据条件设置 highlight ListHighlight.prototype.setHighlightBy = function (list, callback, enable) { var items = list.getItems(); if (enable) { // 设置 highlight 时,保留之前已经 Highlight 的项 util_1.each(items, function (item) { if (callback(item)) { if (list.hasState(item, STATUS_UNACTIVE)) { list.setItemState(item, STATUS_UNACTIVE, false); } list.setItemState(item, STATUS_ACTIVE, true); } else if (!list.hasState(item, STATUS_ACTIVE)) { list.setItemState(item, STATUS_UNACTIVE, true); } }); } else { var activeItems = list.getItemsByState(STATUS_ACTIVE); var allCancel_1 = true; // 检测 activeItems 是否要全部取消 util_1.each(activeItems, function (item) { if (!callback(item)) { allCancel_1 = false; return false; } }); if (allCancel_1) { this.clear(); } else { // 如果不是都要取消 highlight, 则设置匹配的 element 的状态为 unactive // 其他 element 状态不变 util_1.each(items, function (item) { if (callback(item)) { if (list.hasState(item, STATUS_ACTIVE)) { list.setItemState(item, STATUS_ACTIVE, false); } list.setItemState(item, STATUS_UNACTIVE, true); } }); } } }; /** * highlight 图例项(坐标轴文本) */ ListHighlight.prototype.highlight = function () { this.setState(); }; // 需要全部清理 active 和 unactive ListHighlight.prototype.clear = function () { var triggerInfo = this.getTriggerListInfo(); if (triggerInfo) { list_highlight_util_1.clearList(triggerInfo.list); } else { // 如果不是 component 的事件触发,则所有满足触发条件的组件都清除该状态 var components = this.getAllowComponents(); util_1.each(components, function (component) { component.clearItemsState(STATUS_ACTIVE); component.clearItemsState(STATUS_UNACTIVE); }); } }; return ListHighlight; }(list_state_1.default)); exports.default = ListHighlight; },{"./list-highlight-util":314,"./list-state":317,"@antv/util":803,"tslib":385}],316:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var list_state_1 = tslib_1.__importDefault(require("./list-state")); /** * 图例项和坐标轴文本选中的 Action * @ignore */ var ListSelected = /** @class */ (function (_super) { tslib_1.__extends(ListSelected, _super); function ListSelected() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'selected'; return _this; } ListSelected.prototype.selected = function () { this.setState(); }; return ListSelected; }(list_state_1.default)); exports.default = ListSelected; },{"./list-state":317,"tslib":385}],317:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var util_2 = require("../util"); var util_3 = require("../util"); /** * 列表项状态 Action 的基础类 * @class * @ignore */ var ListState = /** @class */ (function (_super) { tslib_1.__extends(ListState, _super); function ListState() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = ''; _this.ignoreItemStates = []; return _this; } /** 获取触发的列表组件 */ ListState.prototype.getTriggerListInfo = function () { var delegateObject = util_3.getDelegationObject(this.context); var info = null; if (util_3.isList(delegateObject)) { info = { item: delegateObject.item, list: delegateObject.component, }; } return info; }; // 获取所有允许执行 Action 的组件 ListState.prototype.getAllowComponents = function () { var _this = this; var view = this.context.view; var components = util_2.getComponents(view); var rst = []; util_1.each(components, function (component) { if (component.isList() && _this.allowSetStateByElement(component)) { rst.push(component); } }); return rst; }; /** 是否存在指定的状态 */ ListState.prototype.hasState = function (list, item) { return list.hasState(item, this.stateName); }; /** 清理组件的状态 */ ListState.prototype.clearAllComponentsState = function () { var _this = this; var components = this.getAllowComponents(); util_1.each(components, function (component) { component.clearItemsState(_this.stateName); }); }; // 不是所有的 component 都能进行 active,目前仅支持分类 scale 对应的组件 ListState.prototype.allowSetStateByElement = function (component) { var field = component.get('field'); if (!field) { return false; } if (this.cfg && this.cfg.componentNames) { var name_1 = component.get('name'); // 如果配置了限制的 component name,则要进行检测 if (this.cfg.componentNames.indexOf(name_1) === -1) { return false; } } var view = this.context.view; var scale = util_3.getScaleByField(view, field); return scale && scale.isCategory; }; // 检测是否允许触发对应的状态改变事件 ListState.prototype.allowSetStateByItem = function (item, list) { var ignoreStates = this.ignoreItemStates; if (ignoreStates.length) { var filterStates = ignoreStates.filter(function (state) { return list.hasState(item, state); }); return filterStates.length === 0; } return true; // 没有定义忽略的状态时,允许 }; // 设置组件的 item active ListState.prototype.setStateByElement = function (component, element, enable) { var field = component.get('field'); var view = this.context.view; var scale = util_3.getScaleByField(view, field); var value = util_3.getElementValue(element, field); var text = scale.getText(value); this.setItemsState(component, text, enable); }; // 设置状态 ListState.prototype.setStateEnable = function (enable) { var _this = this; var element = util_3.getCurrentElement(this.context); if (element) { // trigger by element var components = this.getAllowComponents(); util_1.each(components, function (component) { _this.setStateByElement(component, element, enable); }); } else { // 被组件触发 var delegateObject = util_3.getDelegationObject(this.context); if (util_3.isList(delegateObject)) { var item = delegateObject.item, component = delegateObject.component; if (this.allowSetStateByElement(component) && this.allowSetStateByItem(item, component)) { this.setItemState(component, item, enable); } } } }; // 多个 item 设置状态 ListState.prototype.setItemsState = function (list, name, enable) { var _this = this; var items = list.getItems(); util_1.each(items, function (item) { if (item.name === name) { _this.setItemState(list, item, enable); } }); }; // 单个 item 设置状态 ListState.prototype.setItemState = function (list, item, enable) { list.setItemState(item, this.stateName, enable); }; /** * 设置状态 */ ListState.prototype.setState = function () { this.setStateEnable(true); }; /** * 取消状态 */ ListState.prototype.reset = function () { this.setStateEnable(false); }; /** * 切换状态 */ ListState.prototype.toggle = function () { var triggerInfo = this.getTriggerListInfo(); if (triggerInfo && triggerInfo.item) { var list = triggerInfo.list, item = triggerInfo.item; var enable = this.hasState(list, item); this.setItemState(list, item, !enable); } }; /** * 取消状态 */ ListState.prototype.clear = function () { var triggerInfo = this.getTriggerListInfo(); if (triggerInfo) { triggerInfo.list.clearItemsState(this.stateName); } else { this.clearAllComponentsState(); } }; return ListState; }(base_1.default)); exports.default = ListState; },{"../base":311,"../util":353,"@antv/util":803,"tslib":385}],318:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var list_state_1 = tslib_1.__importDefault(require("./list-state")); /** * 图例项取消勾选的 Action * @ignore */ var ListUnchecked = /** @class */ (function (_super) { tslib_1.__extends(ListUnchecked, _super); function ListUnchecked() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'unchecked'; return _this; } /** * 取消勾选 */ ListUnchecked.prototype.unchecked = function () { this.setState(); }; return ListUnchecked; }(list_state_1.default)); exports.default = ListUnchecked; },{"./list-state":317,"tslib":385}],319:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../../base")); var dependents_1 = require("../../../../dependents"); /** * 用于组件文本省略后需要展示完整信息的 Tooltip Action * @ignore */ var EllipsisText = /** @class */ (function (_super) { tslib_1.__extends(EllipsisText, _super); function EllipsisText() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.timeStamp = 0; return _this; } EllipsisText.prototype.destroy = function () { _super.prototype.destroy.call(this); this.tooltip && this.tooltip.destroy(); }; /** * 显示 Tooltip * @returns */ EllipsisText.prototype.show = function () { var context = this.context; var ev = context.event; var lastTimeStamp = this.timeStamp; var timeStamp = +new Date(); if (timeStamp - lastTimeStamp > 16) { var preLoc = this.location; var curLoc = { x: ev.x, y: ev.y }; if (!preLoc || !util_1.isEqual(preLoc, curLoc)) { this.showTooltip(curLoc); } this.timeStamp = timeStamp; this.location = curLoc; } }; /** * 隐藏 Tooltip。 * @returns */ EllipsisText.prototype.hide = function () { this.hideTooltip(); this.location = null; }; EllipsisText.prototype.showTooltip = function (curLoc) { var context = this.context; var ev = context.event; var target = ev.target; if (target && target.get('tip')) { if (!this.tooltip) { this.renderTooltip(); // 延迟生成 } var tipContent = target.get('tip'); // 展示 tooltip this.tooltip.update(tslib_1.__assign({ title: tipContent }, curLoc)); this.tooltip.show(); } }; EllipsisText.prototype.hideTooltip = function () { this.tooltip && this.tooltip.hide(); }; EllipsisText.prototype.renderTooltip = function () { var view = this.context.view; var canvas = view.canvas; var region = { start: { x: 0, y: 0 }, end: { x: canvas.get('width'), y: canvas.get('height') }, }; var theme = view.getTheme(); var tooltipStyles = util_1.get(theme, ['components', 'tooltip', 'domStyles'], {}); // 获取 tooltip 样式 var tooltip = new dependents_1.HtmlTooltip({ parent: canvas.get('el').parentNode, region: region, visible: false, crosshairs: null, domStyles: tooltipStyles, }); tooltip.init(); tooltip.setCapture(false); // 不允许捕获事件 this.tooltip = tooltip; }; return EllipsisText; }(base_1.default)); exports.default = EllipsisText; },{"../../../../dependents":239,"../../base":311,"@antv/util":803,"tslib":385}],320:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../../base")); /** * Tooltip 展示隐藏的 Action * @ignore */ var TooltipAction = /** @class */ (function (_super) { tslib_1.__extends(TooltipAction, _super); function TooltipAction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.timeStamp = 0; return _this; } /** * 显示 Tooltip * @returns */ TooltipAction.prototype.show = function () { var context = this.context; var ev = context.event; var view = context.view; var isTooltipLocked = view.isTooltipLocked(); if (isTooltipLocked) { // 锁定时不移动 tooltip return; } var lastTimeStamp = this.timeStamp; var timeStamp = +new Date(); if (timeStamp - lastTimeStamp > 16) { var preLoc = this.location; var curLoc = { x: ev.x, y: ev.y }; if (!preLoc || !util_1.isEqual(preLoc, curLoc)) { this.showTooltip(view, curLoc); } this.timeStamp = timeStamp; this.location = curLoc; } }; /** * 隐藏 Tooltip。 * @returns */ TooltipAction.prototype.hide = function () { var view = this.context.view; var isTooltipLocked = view.isTooltipLocked(); if (isTooltipLocked) { // 锁定 tooltip 时不隐藏 return; } this.hideTooltip(view); this.location = null; }; TooltipAction.prototype.showTooltip = function (view, point) { // 相同位置不重复展示 view.showTooltip(point); }; TooltipAction.prototype.hideTooltip = function (view) { view.hideTooltip(); }; return TooltipAction; }(base_1.default)); exports.default = TooltipAction; },{"../../base":311,"@antv/util":803,"tslib":385}],321:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var util_2 = require("../../util"); var geometry_1 = tslib_1.__importDefault(require("./geometry")); /** * 存在多个 view 时,控制其他 view 上的 tooltip 显示 * @ignore */ var SiblingTooltip = /** @class */ (function (_super) { tslib_1.__extends(SiblingTooltip, _super); function SiblingTooltip() { return _super !== null && _super.apply(this, arguments) || this; } /** * 所有同一层级的 tooltip 显示 * @param view * @param point */ SiblingTooltip.prototype.showTooltip = function (view, point) { var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { var siblingPoint = util_2.getSiblingPoint(view, sibling, point); sibling.showTooltip(siblingPoint); }); }; /** * 隐藏同一层级的 tooltip * @param view */ SiblingTooltip.prototype.hideTooltip = function (view) { var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { sibling.hideTooltip(); }); }; return SiblingTooltip; }(geometry_1.default)); exports.default = SiblingTooltip; },{"../../util":353,"./geometry":320,"@antv/util":803,"tslib":385}],322:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * @fileoverview 设置画布的箭头,参看:https://www.w3school.com.cn/jsref/prop_style_cursor.asp * @author dxq613 */ var base_1 = tslib_1.__importDefault(require("./base")); /** * 鼠标形状的 Action * @ignore */ var CursorAction = /** @class */ (function (_super) { tslib_1.__extends(CursorAction, _super); function CursorAction() { return _super !== null && _super.apply(this, arguments) || this; } CursorAction.prototype.setCursor = function (cursor) { var view = this.context.view; view.getCanvas().setCursor(cursor); }; /** * 默认光标(通常是一个箭头) */ CursorAction.prototype.default = function () { this.setCursor('default'); }; /** 光标呈现为指示链接的指针(一只手) */ CursorAction.prototype.pointer = function () { this.setCursor('pointer'); }; /** 此光标指示某对象可被移动。 */ CursorAction.prototype.move = function () { this.setCursor('move'); }; /** 光标呈现为十字线。 */ CursorAction.prototype.crosshair = function () { this.setCursor('crosshair'); }; /** 此光标指示程序正忙(通常是一只表或沙漏)。 */ CursorAction.prototype.wait = function () { this.setCursor('wait'); }; /** 此光标指示可用的帮助(通常是一个问号或一个气球)。 */ CursorAction.prototype.help = function () { this.setCursor('help'); }; /** 此光标指示文本。 */ CursorAction.prototype.text = function () { this.setCursor('text'); }; /** * 此光标指示矩形框的边缘可被向右(东)移动。 */ CursorAction.prototype.eResize = function () { this.setCursor('e-resize'); }; /** * 此光标指示矩形框的边缘可被向左(西)移动。 */ CursorAction.prototype.wResize = function () { this.setCursor('w-resize'); }; /** * 此光标指示矩形框的边缘可被向上(北)移动。 */ CursorAction.prototype.nResize = function () { this.setCursor('n-resize'); }; /** * 此光标指示矩形框的边缘可被向下(南)移动。 */ CursorAction.prototype.sResize = function () { this.setCursor('s-resize'); }; /** * 光标指示可移动的方向 右上方(东北) */ CursorAction.prototype.neResize = function () { this.setCursor('ne-resize'); }; /** * 光标指示可移动的方向 左上方(西北) */ CursorAction.prototype.nwResize = function () { this.setCursor('nw-resize'); }; /** * 光标指示可移动的方向右下方(东南) */ CursorAction.prototype.seResize = function () { this.setCursor('se-resize'); }; /** * 光标指示可移动的方向左下方(西南) */ CursorAction.prototype.swResize = function () { this.setCursor('sw-resize'); }; /** * 光标指示可以在上下方向移动 */ CursorAction.prototype.nsResize = function () { this.setCursor('ns-resize'); }; /** * 光标指示可以在左右方向移动 */ CursorAction.prototype.ewResize = function () { this.setCursor('ew-resize'); }; return CursorAction; }(base_1.default)); exports.default = CursorAction; },{"./base":311,"tslib":385}],323:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var util_2 = require("../util"); /** * 数据过滤。 * @ignore */ var DataFilter = /** @class */ (function (_super) { tslib_1.__extends(DataFilter, _super); function DataFilter() { return _super !== null && _super.apply(this, arguments) || this; } DataFilter.prototype.filterView = function (view, field, filter) { var _this = this; // 只有存在这个 scale 时才生效 if (view.getScaleByField(field)) { view.filter(field, filter); } if (view.views && view.views.length) { util_1.each(view.views, function (subView) { _this.filterView(subView, field, filter); }); } }; /** * 过滤数据 */ DataFilter.prototype.filter = function () { var delegateObject = util_2.getDelegationObject(this.context); if (delegateObject) { var view = this.context.view; var component = delegateObject.component; var field = component.get('field'); // 列表类的组件能够触发 if (util_2.isList(delegateObject)) { if (field) { var unCheckedItems = component.getItemsByState('unchecked'); var scale_1 = util_2.getScaleByField(view, field); var names_1 = unCheckedItems.map(function (item) { return item.name; }); if (names_1.length) { this.filterView(view, field, function (value) { var text = scale_1.getText(value); return !names_1.includes(text); }); } else { this.filterView(view, field, null); } view.render(true); } } else if (util_2.isSlider(delegateObject)) { var range = component.getValue(); var min_1 = range[0], max_1 = range[1]; this.filterView(view, field, function (value) { return value >= min_1 && value <= max_1; }); view.render(true); } } }; return DataFilter; }(base_1.default)); exports.default = DataFilter; },{"../base":311,"../util":353,"@antv/util":803,"tslib":385}],324:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("../base")); var util_1 = require("../util"); // 获取对应的 scale function getFilter(scale, dim, point1, point2) { var min = Math.min(point1[dim], point2[dim]); var max = Math.max(point1[dim], point2[dim]); var _a = scale.range, rangeMin = _a[0], rangeMax = _a[1]; // 约束值在 scale 的 range 之间 if (min < rangeMin) { min = rangeMin; } if (max > rangeMax) { max = rangeMax; } // 范围大于整个 view 的范围,则返回 null if (min === rangeMax && max === rangeMax) { return null; } var minValue = scale.invert(min); var maxValue = scale.invert(max); if (scale.isCategory) { var minIndex = scale.values.indexOf(minValue); var maxIndex = scale.values.indexOf(maxValue); var arr_1 = scale.values.slice(minIndex, maxIndex + 1); return function (value) { return arr_1.includes(value); }; } else { return function (value) { return value >= minValue && value <= maxValue; }; } } /** * 范围过滤的 Action * @ignore */ var RangeFilter = /** @class */ (function (_super) { tslib_1.__extends(RangeFilter, _super); function RangeFilter() { var _this = _super !== null && _super.apply(this, arguments) || this; /** * 范围过滤生效的字段/维度,可以是 x, y */ _this.dims = ['x', 'y']; /** 起始点 */ _this.startPoint = null; _this.isStarted = false; return _this; } // x,y 是否生效 RangeFilter.prototype.hasDim = function (dim) { return this.dims.includes(dim); }; /** * 开始范围过滤,记录范围过滤的起点 */ RangeFilter.prototype.start = function () { var context = this.context; this.isStarted = true; this.startPoint = context.getCurrentPoint(); }; /** * 过滤,以开始的点和当前点对数据进行过滤 */ RangeFilter.prototype.filter = function () { var startPoint; var currentPoint; if (util_1.isMask(this.context)) { var maskShape = this.context.event.target; var bbox = maskShape.getCanvasBBox(); startPoint = { x: bbox.x, y: bbox.y }; currentPoint = { x: bbox.maxX, y: bbox.maxY }; } else { if (!this.isStarted) { // 如果没有开始,则不执行过滤 return; } startPoint = this.startPoint; currentPoint = this.context.getCurrentPoint(); } if (Math.abs(startPoint.x - currentPoint.x) < 5 || Math.abs(startPoint.x - currentPoint.y) < 5) { // 距离过小也不生效 return; } var view = this.context.view; var coord = view.getCoordinate(); var normalCurrent = coord.invert(currentPoint); var normalStart = coord.invert(startPoint); // 设置 x 方向的 filter if (this.hasDim('x')) { var xScale = view.getXScale(); var filter = getFilter(xScale, 'x', normalCurrent, normalStart); this.filterView(view, xScale.field, filter); } // 设置 y 方向的 filter if (this.hasDim('y')) { var yScale = view.getYScales()[0]; var filter = getFilter(yScale, 'y', normalCurrent, normalStart); this.filterView(view, yScale.field, filter); } this.reRender(view); }; /** * 结束 */ RangeFilter.prototype.end = function () { this.isStarted = false; }; /** * 取消同当前 Action 相关的过滤,指定的 x,y */ RangeFilter.prototype.reset = function () { var view = this.context.view; this.isStarted = false; if (this.hasDim('x')) { var xScale = view.getXScale(); this.filterView(view, xScale.field, null); // 取消过滤 } if (this.hasDim('y')) { // y 轴过滤仅取第一个 yScale var yScale = view.getYScales()[0]; this.filterView(view, yScale.field, null); // 取消过滤 } this.reRender(view); }; /** * 对 view 进行过滤 */ RangeFilter.prototype.filterView = function (view, field, filter) { view.filter(field, filter); }; /** * 重新渲染 * @param view */ RangeFilter.prototype.reRender = function (view) { view.render(true); }; return RangeFilter; }(base_1.default)); exports.default = RangeFilter; },{"../base":311,"../util":353,"tslib":385}],325:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var range_filter_1 = tslib_1.__importDefault(require("./range-filter")); var util_2 = require("../util"); /** * 数据范围过滤,但不在当前的 view 上生效,而在当前的 view 同一层级的其他 views 上生效,用于实现联动过滤。 * @ignore */ var SiblingFilter = /** @class */ (function (_super) { tslib_1.__extends(SiblingFilter, _super); function SiblingFilter() { return _super !== null && _super.apply(this, arguments) || this; } /** * 对 view 进行过滤 * @param view * @param field * @param filter */ SiblingFilter.prototype.filterView = function (view, field, filter) { var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { sibling.filter(field, filter); }); }; /** * 重新渲染 * @param view */ SiblingFilter.prototype.reRender = function (view) { var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { sibling.render(true); }); }; return SiblingFilter; }(range_filter_1.default)); exports.default = SiblingFilter; },{"../util":353,"./range-filter":324,"@antv/util":803,"tslib":385}],326:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var state_1 = tslib_1.__importDefault(require("./state")); /** * 元素 active 的 Action,允许多个元素同时 active * @class * @ignore */ var ElementActive = /** @class */ (function (_super) { tslib_1.__extends(ElementActive, _super); function ElementActive() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'active'; return _this; } /** * Active Element */ ElementActive.prototype.active = function () { this.setState(); }; return ElementActive; }(state_1.default)); exports.default = ElementActive; },{"./state":344,"tslib":385}],327:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var util_2 = require("../util"); /** * 元素过滤的 Action,控制元素的显示隐藏 * @ignore */ var ElementFilter = /** @class */ (function (_super) { tslib_1.__extends(ElementFilter, _super); function ElementFilter() { return _super !== null && _super.apply(this, arguments) || this; } /** * 过滤 */ ElementFilter.prototype.filter = function () { var delegateObject = util_2.getDelegationObject(this.context); var view = this.context.view; var elements = util_2.getElements(view); if (util_2.isMask(this.context)) { var maskElements_1 = util_2.getMaskedElements(this.context, 10); if (maskElements_1) { util_1.each(elements, function (el) { if (maskElements_1.includes(el)) { el.show(); } else { el.hide(); } }); } } else if (delegateObject) { var component = delegateObject.component; var field_1 = component.get('field'); // 列表类的组件能够触发 if (util_2.isList(delegateObject)) { if (field_1) { var unCheckedItems = component.getItemsByState('unchecked'); var scale_1 = util_2.getScaleByField(view, field_1); var names_1 = unCheckedItems.map(function (item) { return item.name; }); // 直接控制显示、隐藏 util_1.each(elements, function (el) { var value = util_2.getElementValue(el, field_1); var text = scale_1.getText(value); if (names_1.indexOf(text) >= 0) { el.hide(); } else { el.show(); } }); } } else if (util_2.isSlider(delegateObject)) { var range = component.getValue(); var min_1 = range[0], max_1 = range[1]; util_1.each(elements, function (el) { var value = util_2.getElementValue(el, field_1); if (value >= min_1 && value <= max_1) { el.show(); } else { el.hide(); } }); } } }; /** * 清除过滤 */ ElementFilter.prototype.clear = function () { var elements = util_2.getElements(this.context.view); util_1.each(elements, function (el) { el.show(); }); }; /** * 恢复发生的过滤,保持同 data-filter 命名的一致 */ ElementFilter.prototype.reset = function () { this.clear(); }; return ElementFilter; }(base_1.default)); exports.default = ElementFilter; },{"../base":311,"../util":353,"@antv/util":803,"tslib":385}],328:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util"); var highlight_1 = tslib_1.__importDefault(require("./highlight")); /** * Highlight color * @ignore */ var HighlightColor = /** @class */ (function (_super) { tslib_1.__extends(HighlightColor, _super); function HighlightColor() { return _super !== null && _super.apply(this, arguments) || this; } HighlightColor.prototype.setStateByElement = function (element, enable) { var view = this.context.view; var colorAttr = element.geometry.getAttribute('color'); if (!colorAttr) { return; } var scale = view.getScaleByField(colorAttr.getFields()[0]); var value = util_1.getElementValue(element, scale.field); var elements = util_1.getElements(view); var highlightElements = elements.filter(function (el) { return util_1.getElementValue(el, scale.field) === value; }); this.setHighlightBy(elements, function (el) { return highlightElements.includes(el); }, enable); }; return HighlightColor; }(highlight_1.default)); exports.default = HighlightColor; },{"../util":353,"./highlight":331,"tslib":385}],329:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util"); var highlight_1 = tslib_1.__importStar(require("./highlight")); /** * Highlight x * @ignore */ var HighlightX = /** @class */ (function (_super) { tslib_1.__extends(HighlightX, _super); function HighlightX() { return _super !== null && _super.apply(this, arguments) || this; } // 不允许多选 HighlightX.prototype.setElementHighlight = function (el, callback) { if (callback(el)) { if (el.hasState(highlight_1.STATUS_UNACTIVE)) { el.setState(highlight_1.STATUS_UNACTIVE, false); } el.setState(highlight_1.STATUS_ACTIVE, true); } else { el.setState(highlight_1.STATUS_UNACTIVE, true); if (el.hasState(highlight_1.STATUS_ACTIVE)) { el.setState(highlight_1.STATUS_ACTIVE, false); } } }; HighlightX.prototype.setStateByElement = function (element, enable) { var view = this.context.view; var scale = view.getXScale(); var value = util_1.getElementValue(element, scale.field); var elements = util_1.getElements(view); var highlightElements = elements.filter(function (el) { return util_1.getElementValue(el, scale.field) === value; }); this.setHighlightBy(elements, function (el) { return highlightElements.includes(el); }, enable); }; /** * 切换状态 */ HighlightX.prototype.toggle = function () { var element = util_1.getCurrentElement(this.context); if (element) { var hasState = element.hasState(this.stateName); this.setStateByElement(element, !hasState); } }; return HighlightX; }(highlight_1.default)); exports.default = HighlightX; },{"../util":353,"./highlight":331,"tslib":385}],330:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setHighlightBy = exports.clearHighlight = void 0; var util_1 = require("@antv/util"); var util_2 = require("../util"); var STATUS_UNACTIVE = 'inactive'; var STATUS_ACTIVE = 'active'; /** * @ignore * 清理 highlight 效果 * @param view View 或者 Chart */ function clearHighlight(view) { var elements = util_2.getElements(view); util_1.each(elements, function (el) { if (el.hasState(STATUS_ACTIVE)) { el.setState(STATUS_ACTIVE, false); } if (el.hasState(STATUS_UNACTIVE)) { el.setState(STATUS_UNACTIVE, false); } }); } exports.clearHighlight = clearHighlight; /** * @ignore * 设置多个元素的 highlight * @param elements 元素集合 * @param callback 设置回调函数 * @param enable 设置或者取消 */ function setHighlightBy(elements, callback, enable) { util_1.each(elements, function (el) { // 需要处理 active 和 unactive 的互斥 if (callback(el)) { if (el.hasState(STATUS_UNACTIVE)) { el.setState(STATUS_UNACTIVE, false); } el.setState(STATUS_ACTIVE, enable); } else { if (el.hasState(STATUS_ACTIVE)) { el.setState(STATUS_ACTIVE, false); } el.setState(STATUS_UNACTIVE, enable); } }); } exports.setHighlightBy = setHighlightBy; },{"../util":353,"@antv/util":803}],331:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.STATUS_ACTIVE = exports.STATUS_UNACTIVE = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var util_2 = require("../util"); var highlight_util_1 = require("./highlight-util"); var state_1 = tslib_1.__importDefault(require("./state")); var constant_1 = require("../../../constant"); exports.STATUS_UNACTIVE = constant_1.ELEMENT_STATE.INACTIVE; exports.STATUS_ACTIVE = constant_1.ELEMENT_STATE.ACTIVE; /** * @ignore * highlight,指定图形高亮,其他图形变暗 */ var ElementHighlight = /** @class */ (function (_super) { tslib_1.__extends(ElementHighlight, _super); function ElementHighlight() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = exports.STATUS_ACTIVE; return _this; } // 多个元素设置、取消 highlight ElementHighlight.prototype.setElementsStateByItem = function (elements, field, item, enable) { var _this = this; var callback = function (el) { return _this.isMathItem(el, field, item); }; this.setHighlightBy(elements, callback, enable); }; // 设置元素的 highlight ElementHighlight.prototype.setElementHighlight = function (el, callback) { if (callback(el)) { if (el.hasState(exports.STATUS_UNACTIVE)) { el.setState(exports.STATUS_UNACTIVE, false); } el.setState(exports.STATUS_ACTIVE, true); } else if (!el.hasState(exports.STATUS_ACTIVE)) { el.setState(exports.STATUS_UNACTIVE, true); } }; ElementHighlight.prototype.setHighlightBy = function (elements, callback, enable) { var _this = this; if (enable) { // 如果是设置 highlight ,则将匹配的 element 设置成 active, // 其他如果不是 active,则设置成 unactive util_1.each(elements, function (el) { _this.setElementHighlight(el, callback); }); } else { // 如果取消 highlight,则要检测是否全部取消 highlight var activeElements = util_2.getElementsByState(this.context.view, exports.STATUS_ACTIVE); var allCancel_1 = true; // 检测所有 activeElements 都要取消 highlight util_1.each(activeElements, function (el) { if (!callback(el)) { allCancel_1 = false; return false; } }); if (allCancel_1) { // 都要取消,则取消所有的 active,unactive 状态 this.clear(); } else { // 如果不是都要取消 highlight, 则设置匹配的 element 的状态为 unactive // 其他 element 状态不变 util_1.each(elements, function (el) { if (callback(el)) { if (el.hasState(exports.STATUS_ACTIVE)) { el.setState(exports.STATUS_ACTIVE, false); } el.setState(exports.STATUS_UNACTIVE, true); } }); } } }; // 单个元素设置和取消 highlight ElementHighlight.prototype.setElementState = function (element, enable) { var view = this.context.view; var elements = util_2.getElements(view); this.setHighlightBy(elements, function (el) { return element === el; }, enable); }; ElementHighlight.prototype.highlight = function () { this.setState(); }; // 清理掉所有的 active, unactive 状态 ElementHighlight.prototype.clear = function () { var view = this.context.view; highlight_util_1.clearHighlight(view); }; return ElementHighlight; }(state_1.default)); exports.default = ElementHighlight; },{"../../../constant":237,"../util":353,"./highlight-util":330,"./state":344,"@antv/util":803,"tslib":385}],332:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("../base")); var util_1 = require("../util"); var util_2 = require("@antv/util"); /** * Link Elements by color * @ignore */ var LinkByColor = /** @class */ (function (_super) { tslib_1.__extends(LinkByColor, _super); function LinkByColor() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.cache = {}; return _this; } // 获取颜色对应的 scale LinkByColor.prototype.getColorScale = function (view, element) { var colorAttr = element.geometry.getAttribute('color'); if (!colorAttr) { return null; } var scale = view.getScaleByField(colorAttr.getFields()[0]); return scale; }; // 获取连接的 path LinkByColor.prototype.getLinkPath = function (element, nextElement) { var bbox = element.shape.getCanvasBBox(); var nextBBox = nextElement.shape.getCanvasBBox(); var path = [ ['M', bbox.maxX, bbox.minY], ['L', nextBBox.minX, nextBBox.minY], ['L', nextBBox.minX, nextBBox.maxY], ['L', bbox.maxX, bbox.maxY], ['Z'], ]; return path; }; // 添加连接的图形 LinkByColor.prototype.addLinkShape = function (group, element, nextElement) { group.addShape({ type: 'path', attrs: { opacity: 0.4, fill: element.shape.attr('fill'), path: this.getLinkPath(element, nextElement), }, }); }; // 使用图形连接 LinkByColor.prototype.linkByElement = function (element) { var _this = this; var view = this.context.view; var scale = this.getColorScale(view, element); if (!scale) { return; } var value = util_1.getElementValue(element, scale.field); if (!this.cache[value]) { var elements_1 = util_1.getElementsByField(view, scale.field, value); var linkGroup = this.linkGroup; var group_1 = linkGroup.addGroup(); this.cache[value] = group_1; // 缓存 var count_1 = elements_1.length; util_2.each(elements_1, function (el, index) { if (index < count_1 - 1) { var nextEl = elements_1[index + 1]; _this.addLinkShape(group_1, el, nextEl); } }); } }; // 移除连接 LinkByColor.prototype.removeLink = function (element) { var scale = this.getColorScale(this.context.view, element); if (!scale) { return; } var value = util_1.getElementValue(element, scale.field); if (this.cache[value]) { this.cache[value].remove(); this.cache[value] = null; } }; /** * 连接 elements */ LinkByColor.prototype.link = function () { var context = this.context; if (!this.linkGroup) { // 不允许被拾取 this.linkGroup = context.view.foregroundGroup.addGroup({ capture: false, }); } var element = util_1.getCurrentElement(context); if (element) { this.linkByElement(element); } }; /** * 取消连接 elements */ LinkByColor.prototype.unlink = function () { var element = util_1.getCurrentElement(this.context); if (element) { this.removeLink(element); } }; /** * 清除所有连接 */ LinkByColor.prototype.clear = function () { if (this.linkGroup) { this.linkGroup.clear(); } }; /** * 销毁 */ LinkByColor.prototype.destroy = function () { _super.prototype.destroy.call(this); if (this.linkGroup) { this.linkGroup.remove(); } }; return LinkByColor; }(base_1.default)); exports.default = LinkByColor; },{"../base":311,"../util":353,"@antv/util":803,"tslib":385}],333:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var range_state_1 = tslib_1.__importDefault(require("./range-state")); /** * @ignore * 图表元素区域 Active 的 Action */ var ElementRangeActive = /** @class */ (function (_super) { tslib_1.__extends(ElementRangeActive, _super); function ElementRangeActive() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'active'; return _this; } /** * 图表元素 Active */ ElementRangeActive.prototype.active = function () { this.setState(); }; return ElementRangeActive; }(range_state_1.default)); exports.default = ElementRangeActive; },{"./range-state":336,"tslib":385}],334:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var highlight_util_1 = require("./highlight-util"); var range_state_1 = tslib_1.__importDefault(require("./range-state")); /** * @ignore * 区域 highlight 的 Action */ var ElementRangeHighlight = /** @class */ (function (_super) { tslib_1.__extends(ElementRangeHighlight, _super); function ElementRangeHighlight() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'active'; return _this; } // 清理掉所有的 active, unactive 状态 ElementRangeHighlight.prototype.clearViewState = function (view) { highlight_util_1.clearHighlight(view); }; /** * 设置 highlight */ ElementRangeHighlight.prototype.highlight = function () { this.setState(); }; ElementRangeHighlight.prototype.setElementsState = function (elements, enable, allElements) { highlight_util_1.setHighlightBy(allElements, function (el) { return elements.indexOf(el) >= 0; }, enable); }; return ElementRangeHighlight; }(range_state_1.default)); exports.default = ElementRangeHighlight; },{"./highlight-util":330,"./range-state":336,"tslib":385}],335:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var range_state_1 = tslib_1.__importDefault(require("./range-state")); /** * @ignore * 区域选中的 Action */ var ElementRangeSelected = /** @class */ (function (_super) { tslib_1.__extends(ElementRangeSelected, _super); function ElementRangeSelected() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'selected'; return _this; } /** * 选中 */ ElementRangeSelected.prototype.selected = function () { this.setState(); }; return ElementRangeSelected; }(range_state_1.default)); exports.default = ElementRangeSelected; },{"./range-state":336,"tslib":385}],336:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var util_2 = require("../util"); var state_base_1 = tslib_1.__importDefault(require("./state-base")); /** * @ignore * 区域设置状态的基础 Action */ var ElementRangeState = /** @class */ (function (_super) { tslib_1.__extends(ElementRangeState, _super); function ElementRangeState() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.startPoint = null; _this.endPoint = null; _this.isStarted = false; /** * 是否作用于当前 view 的 siblings,默认是 false 仅作用于自己 */ _this.effectSiblings = false; /** * 是否受 element 的数据影响,还是受包围盒的影响 */ _this.effectByRecord = false; return _this; } // 获取当前的位置 ElementRangeState.prototype.getCurrentPoint = function () { var event = this.context.event; return { x: event.x, y: event.y, }; }; /** * 开始,记录开始选中的位置 */ ElementRangeState.prototype.start = function () { this.clear(); // 开始的时候清理之前的状态 this.startPoint = this.getCurrentPoint(); this.isStarted = true; }; ElementRangeState.prototype.getIntersectElements = function () { var elements = null; if (util_2.isMask(this.context)) { elements = util_2.getMaskedElements(this.context, 10); } else { var startPoint = this.startPoint; var endPoint = this.isStarted ? this.getCurrentPoint() : this.endPoint; // 如果没有开始,则不允许范围设置状态,保护性质 if (!startPoint || !endPoint) { return; } // 计算框选区域 var box = { minX: Math.min(startPoint.x, endPoint.x), minY: Math.min(startPoint.y, endPoint.y), maxX: Math.max(startPoint.x, endPoint.x), maxY: Math.max(startPoint.y, endPoint.y), }; // this.clear(); // 不全部清理,会导致闪烁 var view = this.context.view; elements = util_2.getIntersectElements(view, box); } return elements; }; /** * 选中 */ ElementRangeState.prototype.setStateEnable = function (enable) { if (this.effectSiblings && !this.effectByRecord) { this.setSiblingsState(enable); } else { var allElements = util_2.getElements(this.context.view); var elements = this.getIntersectElements(); if (elements && elements.length) { if (this.effectByRecord) { this.setSiblingsStateByRecord(elements, enable); } else { this.setElementsState(elements, enable, allElements); } } else { this.clear(); } } }; // 根据选中的 element 的数据进行设置状态 ElementRangeState.prototype.setSiblingsStateByRecord = function (elements, enable) { var _this = this; var view = this.context.view; var siblings = util_2.getSilbings(view); var records = elements.map(function (el) { return el.getModel().data; }); var xFiled = view.getXScale().field; var yField = view.getYScales()[0].field; util_1.each(siblings, function (sibling) { var allElements = util_2.getElements(sibling); var effectElements = allElements.filter(function (el) { var record = el.getModel().data; return util_2.isInRecords(records, record, xFiled, yField); }); _this.setElementsState(effectElements, enable, allElements); }); }; // 设置兄弟 view 的状态 ElementRangeState.prototype.setSiblingsState = function (enable) { var _this = this; var view = this.context.view; var siblings = util_2.getSilbings(view); if (util_2.isMask(this.context)) { // 受 mask 影响 util_1.each(siblings, function (sibling) { var allElements = util_2.getElements(sibling); var effectElements = util_2.getSiblingMaskElements(_this.context, sibling, 10); if (effectElements && effectElements.length) { _this.setElementsState(effectElements, enable, allElements); } else { _this.clearViewState(sibling); } }); } }; ElementRangeState.prototype.setElementsState = function (elements, enable, allElements) { var _this = this; util_1.each(allElements, function (el) { if (!elements.includes(el)) { _this.setElementState(el, false); } else { _this.setElementState(el, enable); } }); }; /** * 结束 */ ElementRangeState.prototype.end = function () { this.isStarted = false; this.endPoint = this.getCurrentPoint(); }; // 复写 clear ElementRangeState.prototype.clear = function () { var _this = this; var view = this.context.view; // 判断是否影响 siblings if (this.effectSiblings) { var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { _this.clearViewState(sibling); }); } else { this.clearViewState(view); } }; return ElementRangeState; }(state_base_1.default)); exports.default = ElementRangeState; },{"../util":353,"./state-base":343,"@antv/util":803,"tslib":385}],337:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var state_1 = tslib_1.__importDefault(require("./state")); /** * @ignore * 允许多选的 Action * @class */ var ElementMultipleSelected = /** @class */ (function (_super) { tslib_1.__extends(ElementMultipleSelected, _super); function ElementMultipleSelected() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'selected'; return _this; } /** * 选中节点,允许多选 */ ElementMultipleSelected.prototype.selected = function () { this.setState(); }; return ElementMultipleSelected; }(state_1.default)); exports.default = ElementMultipleSelected; },{"./state":344,"tslib":385}],338:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var util_2 = require("../util"); /** * Sibling filter * @ignore */ var SiblingFilter = /** @class */ (function (_super) { tslib_1.__extends(SiblingFilter, _super); function SiblingFilter() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.byRecord = false; return _this; } /** * 过滤隐藏图形 */ SiblingFilter.prototype.filter = function () { // 仅考虑 mask 导致的过滤 if (util_2.isMask(this.context)) { if (this.byRecord) { this.filterByRecord(); } else { this.filterByBBox(); } } }; // 根据框选的记录来做过滤 SiblingFilter.prototype.filterByRecord = function () { var view = this.context.view; var maskElements = util_2.getMaskedElements(this.context, 10); if (!maskElements) { return; } var xFiled = view.getXScale().field; var yField = view.getYScales()[0].field; var records = maskElements.map(function (el) { return el.getModel().data; }); var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { var elements = util_2.getElements(sibling); util_1.each(elements, function (el) { var record = el.getModel().data; // records.includes(record) 不生效,应该是数据的引用被改了 if (util_2.isInRecords(records, record, xFiled, yField)) { el.show(); } else { el.hide(); } }); }); }; // 根据被框选的包围盒做过滤 SiblingFilter.prototype.filterByBBox = function () { var _this = this; var view = this.context.view; var siblings = util_2.getSilbings(view); util_1.each(siblings, function (sibling) { var maskElements = util_2.getSiblingMaskElements(_this.context, sibling, 10); var elements = util_2.getElements(sibling); if (maskElements) { // mask 过小时返回为 null,不能是空数组,否则同未框选到混淆 util_1.each(elements, function (el) { if (maskElements.includes(el)) { el.show(); } else { el.hide(); } }); } }); }; /** * 清理所有隐藏的图形 */ SiblingFilter.prototype.reset = function () { var siblings = util_2.getSilbings(this.context.view); util_1.each(siblings, function (sibling) { var elements = util_2.getElements(sibling); util_1.each(elements, function (el) { el.show(); }); }); }; return SiblingFilter; }(base_1.default)); exports.default = SiblingFilter; },{"../base":311,"../util":353,"@antv/util":803,"tslib":385}],339:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var single_state_1 = tslib_1.__importDefault(require("./single-state")); /** * @ignore * 仅允许单个 Element Active 的 Action */ var ElementSingleActive = /** @class */ (function (_super) { tslib_1.__extends(ElementSingleActive, _super); function ElementSingleActive() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'active'; return _this; } /** * 当前事件相关的 Element Active */ ElementSingleActive.prototype.active = function () { this.setState(); }; return ElementSingleActive; }(single_state_1.default)); exports.default = ElementSingleActive; },{"./single-state":342,"tslib":385}],340:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util"); var highlight_util_1 = require("./highlight-util"); var single_state_1 = tslib_1.__importDefault(require("./single-state")); /** * @ignore * 单个 Element Highlight 的 Action */ var ElementSingleHighlight = /** @class */ (function (_super) { tslib_1.__extends(ElementSingleHighlight, _super); function ElementSingleHighlight() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'active'; return _this; } /** * Element Highlight */ ElementSingleHighlight.prototype.highlight = function () { this.setState(); }; ElementSingleHighlight.prototype.setElementState = function (element, enable) { var view = this.context.view; var elements = util_1.getElements(view); highlight_util_1.setHighlightBy(elements, function (el) { return element === el; }, enable); }; // 清理掉所有的 active, unactive 状态 ElementSingleHighlight.prototype.clear = function () { var view = this.context.view; highlight_util_1.clearHighlight(view); }; return ElementSingleHighlight; }(single_state_1.default)); exports.default = ElementSingleHighlight; },{"../util":353,"./highlight-util":330,"./single-state":342,"tslib":385}],341:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var single_state_1 = tslib_1.__importDefault(require("./single-state")); /** * @ignore * 单选的 Action */ var ElementSingleSelected = /** @class */ (function (_super) { tslib_1.__extends(ElementSingleSelected, _super); function ElementSingleSelected() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.stateName = 'selected'; return _this; } /** * 选中 */ ElementSingleSelected.prototype.selected = function () { this.setState(); }; return ElementSingleSelected; }(single_state_1.default)); exports.default = ElementSingleSelected; },{"./single-state":342,"tslib":385}],342:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util"); var state_base_1 = tslib_1.__importDefault(require("./state-base")); /** * 单状态量的 Action 基类 * @class * @ignore */ var ElementSingleState = /** @class */ (function (_super) { tslib_1.__extends(ElementSingleState, _super); function ElementSingleState() { return _super !== null && _super.apply(this, arguments) || this; } ElementSingleState.prototype.setStateEnable = function (enable) { var element = util_1.getCurrentElement(this.context); if (element) { // 在同一个 element 内部移动,忽视 label 和 shape 之间 if (!util_1.isElementChange(this.context)) { return; } // 仅支持单个状态量的元素,只能由 element 触发 if (enable) { this.clear(); this.setElementState(element, true); } else if (this.hasState(element)) { this.setElementState(element, false); } } }; /** * 切换选中,只允许选中一个 */ ElementSingleState.prototype.toggle = function () { var element = util_1.getCurrentElement(this.context); if (element) { var hasState = this.hasState(element); // 提前获取状态 if (!hasState) { this.clear(); } this.setElementState(element, !hasState); } }; /** * 取消当前时间影响的状态 */ ElementSingleState.prototype.reset = function () { this.setStateEnable(false); }; return ElementSingleState; }(state_base_1.default)); exports.default = ElementSingleState; },{"../util":353,"./state-base":343,"tslib":385}],343:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var util_2 = require("../util"); /** * 状态量 Action 的基类 * @abstract * @class * @ignore */ var StateBase = /** @class */ (function (_super) { tslib_1.__extends(StateBase, _super); function StateBase() { var _this = _super !== null && _super.apply(this, arguments) || this; /** * 状态名称 */ _this.stateName = ''; return _this; } /** * 是否具有某个状态 * @param element 图表 Element 元素 */ StateBase.prototype.hasState = function (element) { return element.hasState(this.stateName); }; /** * 设置状态激活 * @param enable 状态值 */ StateBase.prototype.setElementState = function (element, enable) { // 防止闪烁 element.setState(this.stateName, enable); }; /** * 设置状态 */ StateBase.prototype.setState = function () { this.setStateEnable(true); }; /** * 清除所有 Element 的状态 */ StateBase.prototype.clear = function () { var view = this.context.view; this.clearViewState(view); }; StateBase.prototype.clearViewState = function (view) { var _this = this; var elements = util_2.getElementsByState(view, this.stateName); util_1.each(elements, function (el) { _this.setElementState(el, false); }); }; return StateBase; }(base_1.default)); exports.default = StateBase; },{"../base":311,"../util":353,"@antv/util":803,"tslib":385}],344:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var util_2 = require("../util"); var state_base_1 = tslib_1.__importDefault(require("./state-base")); function getItem(shape) { return util_1.get(shape.get('delegateObject'), 'item'); } /** * 状态量 Action 的基类,允许多个 Element 同时拥有某个状态 * @class * @ignore */ var ElementState = /** @class */ (function (_super) { tslib_1.__extends(ElementState, _super); function ElementState() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.ignoreListItemStates = ['unchecked']; return _this; } // 是否忽略触发的列表项 ElementState.prototype.isItemIgnore = function (item, list) { var states = this.ignoreListItemStates; var filtered = states.filter(function (state) { return list.hasState(item, state); }); return !!filtered.length; }; // 设置由组件选项导致的状态变化 ElementState.prototype.setStateByComponent = function (component, item, enable) { var view = this.context.view; var field = component.get('field'); var elements = util_2.getElements(view); this.setElementsStateByItem(elements, field, item, enable); }; // 处理触发源由 element 导致的状态变化 ElementState.prototype.setStateByElement = function (element, enable) { this.setElementState(element, enable); }; /** 组件的选项是否同 element 匹配 */ ElementState.prototype.isMathItem = function (element, field, item) { var view = this.context.view; var scale = util_2.getScaleByField(view, field); var value = util_2.getElementValue(element, field); return !util_1.isNil(value) && item.name === scale.getText(value); }; ElementState.prototype.setElementsStateByItem = function (elements, field, item, enable) { var _this = this; util_1.each(elements, function (el) { if (_this.isMathItem(el, field, item)) { el.setState(_this.stateName, enable); } }); }; /** 设置状态是否激活 */ ElementState.prototype.setStateEnable = function (enable) { var element = util_2.getCurrentElement(this.context); if (element) { // 触发源由于 element 导致 if (util_2.isElementChange(this.context)) { this.setStateByElement(element, enable); } } else { // 触发源由组件导致 var delegateObject = util_2.getDelegationObject(this.context); // 如果触发源时列表,图例、坐标轴 if (util_2.isList(delegateObject)) { var item = delegateObject.item, component = delegateObject.component; if (item && component && !this.isItemIgnore(item, component)) { var event_1 = this.context.event.gEvent; // 防止闪烁 if (event_1 && event_1.fromShape && event_1.toShape && getItem(event_1.fromShape) === getItem(event_1.toShape)) { return; } this.setStateByComponent(component, item, enable); } } } }; /** * 切换状态 */ ElementState.prototype.toggle = function () { var element = util_2.getCurrentElement(this.context); if (element) { var hasState = element.hasState(this.stateName); this.setElementState(element, !hasState); } }; /** * 取消当前时间影响的状态 */ ElementState.prototype.reset = function () { this.setStateEnable(false); }; return ElementState; }(state_base_1.default)); exports.default = ElementState; },{"../util":353,"./state-base":343,"@antv/util":803,"tslib":385}],345:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var base_1 = require("./base"); // 导出 Action 基类 Object.defineProperty(exports, "Action", { enumerable: true, get: function () { return base_1.default; } }); var register_1 = require("./register"); Object.defineProperty(exports, "createAction", { enumerable: true, get: function () { return register_1.createAction; } }); Object.defineProperty(exports, "registerAction", { enumerable: true, get: function () { return register_1.registerAction; } }); Object.defineProperty(exports, "getActionClass", { enumerable: true, get: function () { return register_1.getActionClass; } }); },{"./base":311,"./register":352}],346:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); /** * @ignore * 辅助框 Action 的基类 */ var MaskBase = /** @class */ (function (_super) { tslib_1.__extends(MaskBase, _super); function MaskBase() { var _this = _super !== null && _super.apply(this, arguments) || this; // mask 图形 _this.maskShape = null; // 组成 mask 的各个点 _this.points = []; // 开始 mask 的标记 _this.starting = false; // 开始移动的标记 _this.moving = false; _this.preMovePoint = null; _this.shapeType = 'path'; return _this; } // 获取当前的位置 MaskBase.prototype.getCurrentPoint = function () { var event = this.context.event; return { x: event.x, y: event.y, }; }; // 触发 mask 的事件 MaskBase.prototype.emitEvent = function (type) { var eventName = "mask:" + type; var view = this.context.view; var event = this.context.event; view.emit(eventName, { target: this.maskShape, shape: this.maskShape, points: this.points, x: event.x, y: event.y, }); }; // 创建 mask MaskBase.prototype.createMask = function () { var view = this.context.view; var maskAttrs = this.getMaskAttrs(); var maskShape = view.foregroundGroup.addShape({ type: this.shapeType, name: 'mask', draggable: true, attrs: tslib_1.__assign({ fill: '#C5D4EB', opacity: 0.3 }, maskAttrs), }); return maskShape; }; // 生成 mask 的路径 MaskBase.prototype.getMaskPath = function () { return []; }; /** * 显示 */ MaskBase.prototype.show = function () { if (this.maskShape) { this.maskShape.show(); this.emitEvent('show'); } }; /** * 开始 */ MaskBase.prototype.start = function () { this.starting = true; // 开始时,保证移动结束 this.moving = false; this.points = [this.getCurrentPoint()]; if (!this.maskShape) { this.maskShape = this.createMask(); // 开始时设置 capture: false,可以避免创建、resize 时触发事件 this.maskShape.set('capture', false); } this.updateMask(); this.emitEvent('start'); }; /** * 开始移动 */ MaskBase.prototype.moveStart = function () { this.moving = true; this.preMovePoint = this.getCurrentPoint(); }; /** * 移动 mask */ MaskBase.prototype.move = function () { if (!this.moving || !this.maskShape) { return; } var currentPoint = this.getCurrentPoint(); var preMovePoint = this.preMovePoint; var dx = currentPoint.x - preMovePoint.x; var dy = currentPoint.y - preMovePoint.y; var points = this.points; util_1.each(points, function (point) { point.x += dx; point.y += dy; }); this.updateMask(); this.emitEvent('change'); this.preMovePoint = currentPoint; }; MaskBase.prototype.updateMask = function () { var attrs = this.getMaskAttrs(); this.maskShape.attr(attrs); }; /** * 结束移动 */ MaskBase.prototype.moveEnd = function () { this.moving = false; this.preMovePoint = null; }; /** * 结束 */ MaskBase.prototype.end = function () { this.starting = false; this.emitEvent('end'); if (this.maskShape) { this.maskShape.set('capture', true); } }; /** * 隐藏 */ MaskBase.prototype.hide = function () { if (this.maskShape) { this.maskShape.hide(); this.emitEvent('hide'); } }; /** * 大小变化 */ MaskBase.prototype.resize = function () { // 只有进行中,才会允许大小变化 if (this.starting && this.maskShape) { this.points.push(this.getCurrentPoint()); this.updateMask(); this.emitEvent('change'); } }; /** * 销毁 */ MaskBase.prototype.destroy = function () { this.points = []; if (this.maskShape) { this.maskShape.remove(); } this.maskShape = null; this.preMovePoint = null; _super.prototype.destroy.call(this); }; return MaskBase; }(base_1.default)); exports.default = MaskBase; },{"../base":311,"@antv/util":803,"tslib":385}],347:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var util_2 = require("../util"); var base_1 = tslib_1.__importDefault(require("./base")); /** * @ignore * 圆形辅助框 Action */ var CircleMask = /** @class */ (function (_super) { tslib_1.__extends(CircleMask, _super); function CircleMask() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.shapeType = 'circle'; return _this; } CircleMask.prototype.getMaskAttrs = function () { var points = this.points; var currentPoint = util_1.last(this.points); var r = 0; var x = 0; var y = 0; if (points.length) { var first = points[0]; r = util_2.distance(first, currentPoint) / 2; x = (currentPoint.x + first.x) / 2; y = (currentPoint.y + first.y) / 2; } return { x: x, y: y, r: r, }; }; return CircleMask; }(base_1.default)); exports.default = CircleMask; },{"../util":353,"./base":346,"@antv/util":803,"tslib":385}],348:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var rect_1 = tslib_1.__importDefault(require("./rect")); function clampPoint(point) { point.x = util_1.clamp(point.x, 0, 1); point.y = util_1.clamp(point.y, 0, 1); } /** * @ignore */ var DimRect = /** @class */ (function (_super) { tslib_1.__extends(DimRect, _super); function DimRect() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.dim = 'x'; _this.inPlot = true; return _this; } DimRect.prototype.getRegion = function () { var start = null; var end = null; var points = this.points; var dim = this.dim; var coord = this.context.view.getCoordinate(); var normalStart = coord.invert(util_1.head(points)); var normalEnd = coord.invert(util_1.last(points)); if (this.inPlot) { // 约束到 0 - 1 范围内 clampPoint(normalStart); clampPoint(normalEnd); } if (dim === 'x') { // x 轴方向扩展, y 轴方向占满全部 start = coord.convert({ x: normalStart.x, y: 0, }); end = coord.convert({ x: normalEnd.x, y: 1, }); } else { // y 轴方向扩展, x 轴方向占满全部 start = coord.convert({ x: 0, y: normalStart.y, }); end = coord.convert({ x: 1, y: normalEnd.y, }); } return { start: start, end: end, }; }; return DimRect; }(rect_1.default)); exports.default = DimRect; },{"./rect":350,"@antv/util":803,"tslib":385}],349:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); /** * @ignore * 多个点构成的 Path 辅助框 Action */ var PathMask = /** @class */ (function (_super) { tslib_1.__extends(PathMask, _super); function PathMask() { return _super !== null && _super.apply(this, arguments) || this; } // 生成 mask 的路径 PathMask.prototype.getMaskPath = function () { var points = this.points; var path = []; if (points.length) { util_1.each(points, function (point, index) { if (index === 0) { path.push(['M', point.x, point.y]); } else { path.push(['L', point.x, point.y]); } }); path.push(['L', points[0].x, points[0].y]); } return path; }; PathMask.prototype.getMaskAttrs = function () { return { path: this.getMaskPath(), }; }; /** * 添加一个点 */ PathMask.prototype.addPoint = function () { this.resize(); }; return PathMask; }(base_1.default)); exports.default = PathMask; },{"./base":346,"@antv/util":803,"tslib":385}],350:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); /** * @ignore * 矩形的辅助框 Action */ var RectMask = /** @class */ (function (_super) { tslib_1.__extends(RectMask, _super); function RectMask() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.shapeType = 'rect'; return _this; } RectMask.prototype.getRegion = function () { var points = this.points; return { start: util_1.head(points), end: util_1.last(points), }; }; // 添加图形 RectMask.prototype.getMaskAttrs = function () { var _a = this.getRegion(), start = _a.start, end = _a.end; var x = Math.min(start.x, end.x); var y = Math.min(start.y, end.y); var width = Math.abs(end.x - start.x); var height = Math.abs(end.y - start.y); return { x: x, y: y, width: width, height: height, }; }; return RectMask; }(base_1.default)); exports.default = RectMask; },{"./base":346,"@antv/util":803,"tslib":385}],351:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("../util"); var path_1 = tslib_1.__importDefault(require("./path")); /** * Smooth path mask * @ignore */ var SmoothPathMask = /** @class */ (function (_super) { tslib_1.__extends(SmoothPathMask, _super); function SmoothPathMask() { return _super !== null && _super.apply(this, arguments) || this; } // 生成 mask 的路径 SmoothPathMask.prototype.getMaskPath = function () { var points = this.points; return util_1.getSpline(points, true); }; return SmoothPathMask; }(path_1.default)); exports.default = SmoothPathMask; },{"../util":353,"./path":349,"tslib":385}],352:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCallbackAction = exports.unregisterAction = exports.registerAction = exports.getActionClass = exports.createAction = void 0; var tslib_1 = require("tslib"); var callback_1 = tslib_1.__importDefault(require("./callback")); var util_1 = require("@antv/util"); // Action 类的缓存 var ActionCache = {}; /** * 根据名称获取 Action 实例 * @param actionName - action 的名称 * @param context 上下文 * @returns Action 实例 */ function createAction(actionName, context) { var actionOption = ActionCache[actionName]; var action = null; if (actionOption) { var ActionClass = actionOption.ActionClass, cfg = actionOption.cfg; action = new ActionClass(context, cfg); action.name = actionName; action.init(); } return action; } exports.createAction = createAction; /** * 根据 action 的 name 获取定义的类 * @param actionName action 的 name */ function getActionClass(actionName) { var actionOption = ActionCache[actionName]; return util_1.get(actionOption, 'ActionClass'); } exports.getActionClass = getActionClass; /** * 注册 Action * @param actionName - action 的名称 * @param ActionClass - 继承自 action 的类 */ function registerAction(actionName, ActionClass, cfg) { ActionCache[actionName] = { ActionClass: ActionClass, cfg: cfg, }; } exports.registerAction = registerAction; /** * 取消注册 Action * @param actionName action 名称 */ function unregisterAction(actionName) { delete ActionCache[actionName]; } exports.unregisterAction = unregisterAction; /** * 根据回调函数获取 Action 实例 * @param callback - action 的回调函数 * @param context 上下文 * @returns Action 实例 */ function createCallbackAction(callback, context) { var action = new callback_1.default(context); action.callback = callback; action.name = 'callback'; return action; } exports.createCallbackAction = createCallbackAction; },{"./callback":312,"@antv/util":803,"tslib":385}],353:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getScaleByField = exports.isInRecords = exports.getSiblingPoint = exports.getSilbings = exports.isInBox = exports.getSpline = exports.distance = exports.getComponents = exports.getElementsByPath = exports.getIntersectElements = exports.intersectRect = exports.getElementValue = exports.getElementsByState = exports.getElementsByField = exports.getElements = exports.getSiblingMaskElements = exports.getMaskedElements = exports.isMask = exports.isSlider = exports.isList = exports.isElementChange = exports.getDelegationObject = exports.getCurrentElement = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var path_1 = require("../../geometry/shape/util/path"); var bbox_1 = require("../../util/bbox"); var is_polygons_intersect_1 = tslib_1.__importDefault(require("@antv/path-util/lib/is-polygons-intersect")); function getMaskBBox(context, tolerance) { var event = context.event; var maskShape = event.target; var maskBBox = maskShape.getCanvasBBox(); // 如果 bbox 过小则不返回 if (!(maskBBox.width >= tolerance || maskBBox.height >= tolerance)) { return null; } return maskBBox; } function getMaskPath(context, tolerance) { var event = context.event; var maskShape = event.target; var maskBBox = maskShape.getCanvasBBox(); // 如果 bbox 过小则不返回 if (!(maskBBox.width >= tolerance || maskBBox.height >= tolerance)) { return null; } return maskShape.attr('path'); } /** * 获取当前事件相关的图表元素 * @param context 交互的上下文 * @ignore */ function getCurrentElement(context) { var event = context.event; var element; var target = event.target; if (target) { element = target.get('element'); } return element; } exports.getCurrentElement = getCurrentElement; /** * 获取委托对象 * @param context 上下文 * @ignore */ function getDelegationObject(context) { var event = context.event; var target = event.target; var delegateObject; if (target) { delegateObject = target.get('delegateObject'); } return delegateObject; } exports.getDelegationObject = getDelegationObject; function isElementChange(context) { var event = context.event.gEvent; // 在同一个 element 内部移动,label 和 shape 之间 if (event && event.fromShape && event.toShape && event.fromShape.get('element') === event.toShape.get('element')) { return false; } return true; } exports.isElementChange = isElementChange; /** * 是否是列表组件 * @param delegateObject 委托对象 * @ignore */ function isList(delegateObject) { return delegateObject && delegateObject.component && delegateObject.component.isList(); } exports.isList = isList; /** * 是否是滑块组件 * @param delegateObject 委托对象 * @ignore */ function isSlider(delegateObject) { return delegateObject && delegateObject.component && delegateObject.component.isSlider(); } exports.isSlider = isSlider; /** * 是否由 mask 触发 * @param context 上下文 * @ignore */ function isMask(context) { var event = context.event; var target = event.target; return target && target.get('name') === 'mask'; } exports.isMask = isMask; /** * 获取被遮挡的 elements * @param context 上下文 * @ignore */ function getMaskedElements(context, tolerance) { var target = context.event.target; if (target.get('type') === 'path') { var maskPath = getMaskPath(context, tolerance); if (!maskPath) { return; } return getElementsByPath(context.view, maskPath); } var maskBBox = getMaskBBox(context, tolerance); // 如果 bbox 过小则不返回 if (!maskBBox) { return null; } return getIntersectElements(context.view, maskBBox); } exports.getMaskedElements = getMaskedElements; /** * @ignore */ function getSiblingMaskElements(context, sibling, tolerance) { var maskBBox = getMaskBBox(context, tolerance); // 如果 bbox 过小则不返回 if (!maskBBox) { return null; } var view = context.view; var start = getSiblingPoint(view, sibling, { x: maskBBox.x, y: maskBBox.y }); var end = getSiblingPoint(view, sibling, { x: maskBBox.maxX, y: maskBBox.maxY }); var box = { minX: start.x, minY: start.y, maxX: end.x, maxY: end.y, }; return getIntersectElements(sibling, box); } exports.getSiblingMaskElements = getSiblingMaskElements; /** * 获取所有的图表元素 * @param view View/Chart * @ignore */ function getElements(view) { var geometries = view.geometries; var rst = []; util_1.each(geometries, function (geom) { var elements = geom.elements; rst = rst.concat(elements); }); if (view.views && view.views.length) { util_1.each(view.views, function (subView) { rst = rst.concat(getElements(subView)); }); } return rst; } exports.getElements = getElements; /** * 获取所有的图表元素 * @param view View/Chart * @param field 字段名 * @param value 字段值 * @ignore */ function getElementsByField(view, field, value) { var elements = getElements(view); return elements.filter(function (el) { return getElementValue(el, field) === value; }); } exports.getElementsByField = getElementsByField; /** * 根据状态名获取图表元素 * @param view View/Chart * @param stateName 状态名 * @ignore */ function getElementsByState(view, stateName) { var geometries = view.geometries; var rst = []; util_1.each(geometries, function (geom) { var elements = geom.getElementsBy(function (el) { return el.hasState(stateName); }); rst = rst.concat(elements); }); return rst; } exports.getElementsByState = getElementsByState; /** * 获取图表元素对应字段的值 * @param element 图表元素 * @param field 字段名 * @ignore */ function getElementValue(element, field) { var model = element.getModel(); var record = model.data; var value; if (util_1.isArray(record)) { value = record[0][field]; } else { value = record[field]; } return value; } exports.getElementValue = getElementValue; /** * 两个包围盒是否相交 * @param box1 包围盒1 * @param box2 包围盒2 * @ignore */ function intersectRect(box1, box2) { return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY); } exports.intersectRect = intersectRect; /** * 获取包围盒内的图表元素 * @param view View/Chart * @param box 包围盒 * @ignore */ function getIntersectElements(view, box) { var elements = getElements(view); var rst = []; util_1.each(elements, function (el) { var shape = el.shape; var shapeBBox = shape.getCanvasBBox(); if (intersectRect(box, shapeBBox)) { rst.push(el); } }); return rst; } exports.getIntersectElements = getIntersectElements; function pathToPoints(path) { var points = []; util_1.each(path, function (seg) { var command = seg[0]; if (command !== 'A') { for (var i = 1; i < seg.length; i = i + 2) { points.push([seg[i], seg[i + 1]]); } } else { var length_1 = seg.length; points.push([seg[length_1 - 2], seg[length_1 - 1]]); } }); return points; } /** * 获取包围盒内的图表元素 * @param view View/Chart * @param path 路径 * @ignore */ function getElementsByPath(view, path) { var elements = getElements(view); var points = pathToPoints(path); var rst = elements.filter(function (el) { var shape = el.shape; var shapePoints; if (shape.get('type') === 'path') { shapePoints = pathToPoints(shape.attr('path')); } else { var shapeBBox = shape.getCanvasBBox(); shapePoints = bbox_1.toPoints(shapeBBox); } return is_polygons_intersect_1.default(points, shapePoints); }); return rst; } exports.getElementsByPath = getElementsByPath; /** * 获取当前 View 的所有组件 * @param view View/Chart * @ignore */ function getComponents(view) { return view.getComponents().map(function (co) { return co.component; }); } exports.getComponents = getComponents; /** @ignore */ function distance(p1, p2) { var dx = p2.x - p1.x; var dy = p2.y - p1.y; return Math.sqrt(dx * dx + dy * dy); } exports.distance = distance; /** @ignore */ function getSpline(points, z) { if (points.length <= 2) { return path_1.getLinePath(points, false); } var first = points[0]; var arr = []; util_1.each(points, function (point) { arr.push(point.x); arr.push(point.y); }); var path = path_1.catmullRom2bezier(arr, z, null); path.unshift(['M', first.x, first.y]); return path; } exports.getSpline = getSpline; /** * 检测点是否在包围盒内 * @param box 包围盒 * @param point 点 * @ignore */ function isInBox(box, point) { return box.x <= point.x && box.maxX >= point.x && box.y <= point.y && box.maxY > point.y; } exports.isInBox = isInBox; /** * 获取同 view 同一级的 views * @param view 当前 view * @returns 同一级的 views * @ignore */ function getSilbings(view) { var parent = view.parent; var siblings = null; if (parent) { siblings = parent.views.filter(function (sub) { return sub !== view; }); } return siblings; } exports.getSilbings = getSilbings; function point2Normalize(view, point) { var coord = view.getCoordinate(); return coord.invert(point); } /** * 将 view 上的一点转换成另一个 view 的点 * @param view 当前的 view * @param sibling 同一层级的 view * @param point 指定点 * @ignore */ function getSiblingPoint(view, sibling, point) { var normalPoint = point2Normalize(view, point); return sibling.getCoordinate().convert(normalPoint); } exports.getSiblingPoint = getSiblingPoint; /** * 是否在记录中,临时因为所有的 view 中的数据不是引用,而使用的方法 * 不同 view 上对数据的引用不相等,导致无法直接用 includes * 假设 x, y 值相等时是同一条数据,这个假设不完全正确,而改成 isEqual 则成本太高 * 后面改成同一个引用时可以修改回来 * @param records * @param record * @param xFiled * @param yField * @returns * @ignore */ function isInRecords(records, record, xFiled, yField) { var isIn = false; util_1.each(records, function (r) { if (r[xFiled] === record[xFiled] && r[yField] === record[yField]) { isIn = true; return false; } }); return isIn; } exports.isInRecords = isInRecords; // 级联获取 field 对应的 scale,如果 view 上没有,遍历子 view function getScaleByField(view, field) { var scale = view.getScaleByField(field); if (!scale && view.views) { util_1.each(view.views, function (subView) { scale = getScaleByField(subView, field); if (scale) { return false; // 终止循环 } }); } return scale; } exports.getScaleByField = getScaleByField; },{"../../geometry/shape/util/path":303,"../../util/bbox":370,"@antv/path-util/lib/is-polygons-intersect":725,"@antv/util":803,"tslib":385}],354:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var padding_1 = require("../../../util/padding"); var base_1 = tslib_1.__importDefault(require("../base")); var PADDING_RIGHT = 10; var PADDING_TOP = 5; /** * Button action * @ignore */ var ButtonAction = /** @class */ (function (_super) { tslib_1.__extends(ButtonAction, _super); function ButtonAction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.buttonGroup = null; _this.buttonCfg = { name: 'button', text: 'button', textStyle: { x: 0, y: 0, fontSize: 12, fill: '#333333', cursor: 'pointer', }, padding: [8, 10], style: { fill: '#f7f7f7', stroke: '#cccccc', cursor: 'pointer', }, activeStyle: { fill: '#e6e6e6', }, }; return _this; } // mix 默认的配置和用户配置 ButtonAction.prototype.getButtonCfg = function () { return util_1.deepMix(this.buttonCfg, this.cfg); }; // 绘制 Button 和 文本 ButtonAction.prototype.drawButton = function () { var config = this.getButtonCfg(); var group = this.context.view.foregroundGroup.addGroup({ name: config.name, }); // 添加文本 var textShape = group.addShape({ type: 'text', name: 'button-text', attrs: tslib_1.__assign({ text: config.text }, config.textStyle), }); var textBBox = textShape.getBBox(); var padding = padding_1.parsePadding(config.padding); // 添加背景按钮 var buttonShape = group.addShape({ type: 'rect', name: 'button-rect', attrs: tslib_1.__assign({ x: textBBox.x - padding[3], y: textBBox.y - padding[0], width: textBBox.width + padding[1] + padding[3], height: textBBox.height + padding[0] + padding[2] }, config.style), }); buttonShape.toBack(); // 在后面 // active 效果内置 group.on('mouseenter', function () { buttonShape.attr(config.activeStyle); }); group.on('mouseleave', function () { buttonShape.attr(config.style); }); this.buttonGroup = group; }; // 重置位置 ButtonAction.prototype.resetPosition = function () { var view = this.context.view; var coord = view.getCoordinate(); var point = coord.convert({ x: 1, y: 1 }); // 后面直接改成左上角 var buttonGroup = this.buttonGroup; var bbox = buttonGroup.getBBox(); var matrix = matrix_util_1.ext.transform(null, [ ['t', point.x - bbox.width - PADDING_RIGHT, point.y + bbox.height + PADDING_TOP], ]); buttonGroup.setMatrix(matrix); }; /** * 显示 */ ButtonAction.prototype.show = function () { if (!this.buttonGroup) { this.drawButton(); } this.resetPosition(); this.buttonGroup.show(); }; /** * 隐藏 */ ButtonAction.prototype.hide = function () { if (this.buttonGroup) { this.buttonGroup.hide(); } }; /** * 销毁 */ ButtonAction.prototype.destroy = function () { var buttonGroup = this.buttonGroup; if (buttonGroup) { buttonGroup.remove(); } _super.prototype.destroy.call(this); }; return ButtonAction; }(base_1.default)); exports.default = ButtonAction; },{"../../../util/padding":380,"../base":311,"@antv/matrix-util":717,"@antv/util":803,"tslib":385}],355:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("../base")); var util_1 = require("../util"); var DISTANCE = 4; // 移动的最小距离 /** * @ignore * View 支持 Drag 的 Action */ var Drag = /** @class */ (function (_super) { tslib_1.__extends(Drag, _super); function Drag() { var _this = _super !== null && _super.apply(this, arguments) || this; // Action 开始,不等同于 拖拽开始,需要判定移动的范围 _this.starting = false; // 拖拽开始 _this.dragStart = false; return _this; } /** * 开始 */ Drag.prototype.start = function () { this.starting = true; this.startPoint = this.context.getCurrentPoint(); }; /** * 拖拽 */ Drag.prototype.drag = function () { if (!this.startPoint) { return; } var current = this.context.getCurrentPoint(); var view = this.context.view; var event = this.context.event; if (!this.dragStart) { if (util_1.distance(current, this.startPoint) > DISTANCE) { view.emit('dragstart', { target: event.target, x: event.x, y: event.y, }); this.dragStart = true; } } else { view.emit('drag', { target: event.target, x: event.x, y: event.y, }); } }; /** * 结束 */ Drag.prototype.end = function () { if (this.dragStart) { var view = this.context.view; var event_1 = this.context.event; view.emit('dragend', { target: event_1.target, x: event_1.x, y: event_1.y, }); } this.starting = false; this.dragStart = false; }; return Drag; }(base_1.default)); exports.default = Drag; },{"../base":311,"../util":353,"tslib":385}],356:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var __1 = require(".."); var util_1 = require("../util"); var MIN_DISTANCE = 5; /** * @ignore * View 移动的 Action */ var Move = /** @class */ (function (_super) { tslib_1.__extends(Move, _super); function Move() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.starting = false; _this.isMoving = false; // private cacheRange = null; _this.startPoint = null; _this.startMatrix = null; return _this; } /** * 开始移动 */ Move.prototype.start = function () { this.starting = true; this.startPoint = this.context.getCurrentPoint(); // 缓存开始时的矩阵,防止反复拖拽 this.startMatrix = this.context.view.middleGroup.getMatrix(); }; /** * 移动 */ Move.prototype.move = function () { if (!this.starting) { return; } var startPoint = this.startPoint; var currentPoint = this.context.getCurrentPoint(); var d = util_1.distance(startPoint, currentPoint); if (d > MIN_DISTANCE && !this.isMoving) { this.isMoving = true; } if (this.isMoving) { var view = this.context.view; var matrix = matrix_util_1.ext.transform(this.startMatrix, [ ['t', currentPoint.x - startPoint.x, currentPoint.y - startPoint.y], ]); view.backgroundGroup.setMatrix(matrix); view.foregroundGroup.setMatrix(matrix); view.middleGroup.setMatrix(matrix); } }; /** * 结束移动 */ Move.prototype.end = function () { if (this.isMoving) { this.isMoving = false; } this.startMatrix = null; this.starting = false; this.startPoint = null; }; /** * 回滚 */ Move.prototype.reset = function () { this.starting = false; this.startPoint = null; this.isMoving = false; var view = this.context.view; view.backgroundGroup.resetMatrix(); view.foregroundGroup.resetMatrix(); view.middleGroup.resetMatrix(); this.isMoving = false; }; return Move; }(__1.Action)); exports.default = Move; },{"..":345,"../util":353,"@antv/matrix-util":717,"tslib":385}],357:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var __1 = require(".."); var DIM_X = 'x'; var DIM_Y = 'y'; /** * Scale translate * @ignore */ var ScaleTranslate = /** @class */ (function (_super) { tslib_1.__extends(ScaleTranslate, _super); function ScaleTranslate() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.dims = [DIM_X, DIM_Y]; _this.cfgFields = ['dims']; _this.cacheScaleDefs = {}; return _this; } // 是否支持对应字段的平移 ScaleTranslate.prototype.hasDim = function (dim) { return this.dims.includes(dim); }; ScaleTranslate.prototype.getScale = function (dim) { var view = this.context.view; if (dim === 'x') { return view.getXScale(); } else { return view.getYScales()[0]; } }; ScaleTranslate.prototype.resetDim = function (dim) { var view = this.context.view; if (this.hasDim(dim) && this.cacheScaleDefs[dim]) { var scale = this.getScale(dim); view.scale(scale.field, this.cacheScaleDefs[dim]); this.cacheScaleDefs[dim] = null; } }; /** * 回滚 */ ScaleTranslate.prototype.reset = function () { this.resetDim(DIM_X); this.resetDim(DIM_Y); var view = this.context.view; view.render(true); }; return ScaleTranslate; }(__1.Action)); exports.default = ScaleTranslate; },{"..":345,"tslib":385}],358:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var scale_transform_1 = tslib_1.__importDefault(require("./scale-transform")); /** * 拖拽 Scale 的 Action * @ignore */ var ScaleTranslate = /** @class */ (function (_super) { tslib_1.__extends(ScaleTranslate, _super); function ScaleTranslate() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.startPoint = null; _this.starting = false; _this.startCache = {}; return _this; } /** * 开始 */ ScaleTranslate.prototype.start = function () { var _this = this; this.startPoint = this.context.getCurrentPoint(); this.starting = true; var dims = this.dims; util_1.each(dims, function (dim) { var scale = _this.getScale(dim); var min = scale.min, max = scale.max, values = scale.values; _this.startCache[dim] = { min: min, max: max, values: values }; }); }; // 平移分类的度量 // private translateCategory(dim, scale, normalPoint) { // } /** * 结束 */ ScaleTranslate.prototype.end = function () { this.startPoint = null; this.starting = false; this.startCache = {}; }; /** * 平移 */ ScaleTranslate.prototype.translate = function () { var _this = this; if (!this.starting) { return; } var startPoint = this.startPoint; var coord = this.context.view.getCoordinate(); var currentPoint = this.context.getCurrentPoint(); var normalStart = coord.invert(startPoint); var noramlCurrent = coord.invert(currentPoint); var dx = noramlCurrent.x - normalStart.x; var dy = noramlCurrent.y - normalStart.y; var view = this.context.view; var dims = this.dims; util_1.each(dims, function (dim) { _this.translateDim(dim, { x: dx * -1, y: dy * -1 }); }); view.render(true); }; // 平移度量 ScaleTranslate.prototype.translateDim = function (dim, normalPoint) { if (this.hasDim(dim)) { var scale = this.getScale(dim); if (scale.isLinear) { this.translateLinear(dim, scale, normalPoint); } // else { // 暂时仅处理连续字段 // this.translateCategory(dim, scale, normalPoint); // } } }; // linear 度量平移 ScaleTranslate.prototype.translateLinear = function (dim, scale, normalPoint) { var view = this.context.view; var _a = this.startCache[dim], min = _a.min, max = _a.max; var range = max - min; var d = normalPoint[dim] * range; // 只有第一次缓存,否则无法回滚 if (!this.cacheScaleDefs[dim]) { this.cacheScaleDefs[dim] = { // @ts-ignore nice: scale.nice, min: min, max: max, }; } view.scale(scale.field, { // @ts-ignore nice: false, min: min + d, max: max + d, }); }; // 平移分类的度量 // private translateCategory(dim, scale, normalPoint) { // } /** * 回滚 */ ScaleTranslate.prototype.reset = function () { _super.prototype.reset.call(this); this.startPoint = null; this.starting = false; }; return ScaleTranslate; }(scale_transform_1.default)); exports.default = ScaleTranslate; },{"./scale-transform":357,"@antv/util":803,"tslib":385}],359:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var scale_transform_1 = tslib_1.__importDefault(require("./scale-transform")); /** * 缩放 Scale 的 Action * @ignore */ var ScaleTranslate = /** @class */ (function (_super) { tslib_1.__extends(ScaleTranslate, _super); function ScaleTranslate() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.zoomRatio = 0.05; return _this; // 平移分类的度量 // private translateCategory(dim, scale, normalPoint) { // } } /** * 缩小 */ ScaleTranslate.prototype.zoomIn = function () { this.zoom(this.zoomRatio); }; ScaleTranslate.prototype.zoom = function (scale) { var _this = this; var dims = this.dims; util_1.each(dims, function (dim) { _this.zoomDim(dim, scale); }); this.context.view.render(true); }; /** * 放大 */ ScaleTranslate.prototype.zoomOut = function () { this.zoom(-1 * this.zoomRatio); }; // 缩放度量 ScaleTranslate.prototype.zoomDim = function (dim, dRatio) { if (this.hasDim(dim)) { var scale = this.getScale(dim); if (scale.isLinear) { this.zoomLinear(dim, scale, dRatio); } // else { // 暂时仅处理连续字段 // this.zoomCategory(dim, scale, normalPoint); // } } }; // linear 度量平移 ScaleTranslate.prototype.zoomLinear = function (dim, scale, dRatio) { var view = this.context.view; // 只有第一次缓存,否则无法回滚 if (!this.cacheScaleDefs[dim]) { this.cacheScaleDefs[dim] = { // @ts-ignore nice: scale.nice, min: scale.min, max: scale.max, }; } // 使用使用原始度量作为缩放标准 var scaleDef = this.cacheScaleDefs[dim]; var range = scaleDef.max - scaleDef.min; var min = scale.min, max = scale.max; var d = dRatio * range; var toMin = min - d; var toMax = max + d; var curRange = toMax - toMin; var scaled = curRange / range; if (toMax > toMin && scaled < 100 && scaled > 0.01) { view.scale(scale.field, { // @ts-ignore nice: false, min: min - d, max: max + d, }); } }; return ScaleTranslate; }(scale_transform_1.default)); exports.default = ScaleTranslate; },{"./scale-transform":357,"@antv/util":803,"tslib":385}],360:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var util_2 = require("./action/util"); /** * 交互的上下文 */ var Context = /** @class */ (function () { function Context(view) { /** 当前所有的 Action */ this.actions = []; /** 当前事件对象 */ this.event = null; this.cacheMap = {}; this.view = view; } /** * 缓存信息 * @param params 缓存的字段 * - 如果一个字段则获取缓存 * - 两个字段则设置缓存 */ Context.prototype.cache = function () { var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } if (params.length === 1) { return this.cacheMap[params[0]]; } else if (params.length === 2) { this.cacheMap[params[0]] = params[1]; } }; /** * 获取 Action * @param name Action 的名称 */ Context.prototype.getAction = function (name) { return this.actions.find(function (action) { return action.name === name; }); }; /** * 获取 Action * @param action Action 对象 */ Context.prototype.addAction = function (action) { this.actions.push(action); }; /** * 移除 Action * @param action Action 对象 */ Context.prototype.removeAction = function (action) { var actions = this.actions; var index = this.actions.indexOf(action); if (index >= 0) { actions.splice(index, 1); } }; /** * 获取当前的点 */ Context.prototype.getCurrentPoint = function () { var event = this.event; if (event) { if (event.target instanceof HTMLElement) { var canvas = this.view.getCanvas(); var point = canvas.getPointByClient(event.clientX, event.clientY); return point; } else { return { x: event.x, y: event.y, }; } } return null; }; /** * 获取当前 shape * @returns current shape */ Context.prototype.getCurrentShape = function () { return util_1.get(this.event, ['gEvent', 'shape']); }; /** * 当前的触发是否在 View 内 */ Context.prototype.isInPlot = function () { var point = this.getCurrentPoint(); if (point) { return this.view.isPointInPlot(point); } return false; }; /** * 是否在指定的图形内 * @param name shape 的 name */ Context.prototype.isInShape = function (name) { var shape = this.getCurrentShape(); // 不再考虑在 shape 的 parent 内的情况 if (shape) { return shape.get('name') === name; } return false; }; /** * 当前的触发是组件内部 * @param name 组件名,可以为空 */ Context.prototype.isInComponent = function (name) { var components = util_2.getComponents(this.view); var point = this.getCurrentPoint(); if (point) { return !!components.find(function (component) { var bbox = component.getBBox(); if (name) { return component.get('name') === name && util_2.isInBox(bbox, point); } else { return util_2.isInBox(bbox, point); } }); } return false; }; /** * 销毁 */ Context.prototype.destroy = function () { this.view = null; this.event = null; // 先销毁 action 再清空,一边遍历,一边删除,所以数组需要更新引用 util_1.each(this.actions.slice(), function (action) { action.destroy(); }); this.actions = null; this.cacheMap = null; }; return Context; }()); exports.default = Context; },{"./action/util":353,"@antv/util":803}],361:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var register_1 = require("./action/register"); var context_1 = tslib_1.__importDefault(require("./context")); var interaction_1 = tslib_1.__importDefault(require("./interaction")); // 将字符串转换成 action function parseAction(actionStr, context) { var arr = actionStr.split(':'); var actionName = arr[0]; // 如果已经初始化过 action ,则直接引用之前的 action var action = context.getAction(actionName) || register_1.createAction(actionName, context); if (!action) { throw new Error("There is no action named " + actionName); } var methodName = arr[1]; return { action: action, methodName: methodName, }; } // 执行 Action function executeAction(actionObject) { var action = actionObject.action, methodName = actionObject.methodName; if (action[methodName]) { action[methodName](); } else { throw new Error("Action(" + action.name + ") doesn't have a method called " + methodName); } } var STEP_NAMES = { START: 'start', SHOW_ENABLE: 'showEnable', END: 'end', ROLLBACK: 'rollback', PROCESSING: 'processing', }; /** * 支持语法的交互类 */ var GrammarInteraction = /** @class */ (function (_super) { tslib_1.__extends(GrammarInteraction, _super); function GrammarInteraction(view, steps) { var _this = _super.call(this, view, steps) || this; _this.callbackCaches = {}; // 某个触发和反馈在本环节是否执行或 _this.emitCaches = {}; _this.steps = steps; return _this; } /** * 初始化 */ GrammarInteraction.prototype.init = function () { this.initContext(); _super.prototype.init.call(this); }; /** * 清理资源 */ GrammarInteraction.prototype.destroy = function () { _super.prototype.destroy.call(this); // 先清理事件 this.steps = null; if (this.context) { this.context.destroy(); this.context = null; } this.callbackCaches = null; this.view = null; }; /** * 绑定事件 */ GrammarInteraction.prototype.initEvents = function () { var _this = this; util_1.each(this.steps, function (stepArr, stepName) { util_1.each(stepArr, function (step) { var callback = _this.getActionCallback(stepName, step); if (callback) { // 如果存在 callback,才绑定,有时候会出现无 callback 的情况 _this.bindEvent(step.trigger, callback); } }); }); }; /** * 清理绑定的事件 */ GrammarInteraction.prototype.clearEvents = function () { var _this = this; util_1.each(this.steps, function (stepArr, stepName) { util_1.each(stepArr, function (step) { var callback = _this.getActionCallback(stepName, step); if (callback) { _this.offEvent(step.trigger, callback); } }); }); }; // 初始化上下文,并初始化 action GrammarInteraction.prototype.initContext = function () { var view = this.view; var context = new context_1.default(view); this.context = context; var steps = this.steps; // 生成具体的 Action util_1.each(steps, function (subSteps) { util_1.each(subSteps, function (step) { if (util_1.isFunction(step.action)) { // 如果传入回调函数,则直接生成 CallbackAction step.actionObject = { action: register_1.createCallbackAction(step.action, context), methodName: 'execute', }; } else if (util_1.isString(step.action)) { // 如果是字符串 step.actionObject = parseAction(step.action, context); } else if (util_1.isArray(step.action)) { // 如果是数组 var actionArr = step.action; step.actionObject = []; util_1.each(actionArr, function (actionStr) { step.actionObject.push(parseAction(actionStr, context)); }); } // 如果 action 既不是字符串,也不是函数,则不会生成 actionObject }); }); }; // 是否允许指定阶段名称执行 GrammarInteraction.prototype.isAllowStep = function (stepName) { var currentStepName = this.currentStepName; var steps = this.steps; // 相同的阶段允许同时执行 if (currentStepName === stepName) { return true; } if (stepName === STEP_NAMES.SHOW_ENABLE) { // 示能在整个过程中都可用 return true; } if (stepName === STEP_NAMES.PROCESSING) { // 只有当前是 start 时,才允许 processing return currentStepName === STEP_NAMES.START; } if (stepName === STEP_NAMES.START) { // 如果当前是 processing,则无法 start,必须等待 end 后才能执行 return currentStepName !== STEP_NAMES.PROCESSING; } if (stepName === STEP_NAMES.END) { return currentStepName === STEP_NAMES.PROCESSING || currentStepName === STEP_NAMES.START; } if (stepName === STEP_NAMES.ROLLBACK) { if (steps[STEP_NAMES.END]) { // 如果定义了 end, 只有 end 时才允许回滚 return currentStepName === STEP_NAMES.END; } else if (currentStepName === STEP_NAMES.START) { // 如果未定义 end, 则判断是否是开始 return true; } } return false; }; // 具体的指定阶段是否允许执行 GrammarInteraction.prototype.isAllowExcute = function (stepName, step) { if (this.isAllowStep(stepName)) { var key = this.getKey(stepName, step); // 如果是在本环节内仅允许触发一次,同时已经触发过,则不允许再触发 if (step.once && this.emitCaches[key]) { return false; } // 如果是允许的阶段,则验证 isEnable 方法 if (step.isEnable) { return step.isEnable(this.context); } return true; // 如果没有 isEnable 则允许执行 } return false; }; GrammarInteraction.prototype.enterStep = function (stepName) { this.currentStepName = stepName; this.emitCaches = {}; // 清除所有本环节触发的缓存 }; // 执行完某个触发和反馈(子环节) GrammarInteraction.prototype.afterExecute = function (stepName, step) { // show enable 不计入正常的流程,其他情况则设置当前的 step if (stepName !== STEP_NAMES.SHOW_ENABLE && this.currentStepName !== stepName) { this.enterStep(stepName); } var key = this.getKey(stepName, step); // 一旦执行,则缓存标记为,一直保持到跳出改环节 this.emitCaches[key] = true; }; // 获取某个环节的唯一的键值 GrammarInteraction.prototype.getKey = function (stepName, step) { return stepName + step.trigger + step.action; }; // 获取 step 的回调函数,如果已经生成,则直接返回,如果未生成,则创建 GrammarInteraction.prototype.getActionCallback = function (stepName, step) { var _this = this; var context = this.context; var callbackCaches = this.callbackCaches; var actionObject = step.actionObject; if (step.action && actionObject) { var key = this.getKey(stepName, step); if (!callbackCaches[key]) { // 动态生成执行的方法,执行对应 action 的名称 var actionCallback = function (event) { context.event = event; // 保证检测时的 event if (_this.isAllowExcute(stepName, step)) { // 如果是数组时,则依次执行 if (util_1.isArray(actionObject)) { util_1.each(actionObject, function (obj) { context.event = event; // 可能触发新的事件,保证执行前的 context.event 是正确的 executeAction(obj); }); } else { context.event = event; // 保证执行前的 context.event 是正确的 executeAction(actionObject); } _this.afterExecute(stepName, step); if (step.callback) { context.event = event; // 保证执行前的 context.event 是正确的 step.callback(context); } } else { // 如果未通过验证,则事件不要绑定在上面 context.event = null; } }; // 如果设置了 debounce if (step.debounce) { callbackCaches[key] = util_1.debounce(actionCallback, step.debounce.wait, step.debounce.immediate); } else if (step.throttle) { // 设置 throttle callbackCaches[key] = util_1.throttle(actionCallback, step.throttle.wait, { leading: step.throttle.leading, trailing: step.throttle.trailing, }); } else { // 直接设置 callbackCaches[key] = actionCallback; } } return callbackCaches[key]; } return null; }; GrammarInteraction.prototype.bindEvent = function (eventName, callback) { var nameArr = eventName.split(':'); if (nameArr[0] === 'window') { window.addEventListener(nameArr[1], callback); } else if (nameArr[0] === 'document') { document.addEventListener(nameArr[1], callback); } else { this.view.on(eventName, callback); } }; GrammarInteraction.prototype.offEvent = function (eventName, callback) { var nameArr = eventName.split(':'); if (nameArr[0] === 'window') { window.removeEventListener(nameArr[1], callback); } else if (nameArr[0] === 'document') { document.removeEventListener(nameArr[1], callback); } else { this.view.off(eventName, callback); } }; return GrammarInteraction; }(interaction_1.default)); exports.default = GrammarInteraction; },{"./action/register":352,"./context":360,"./interaction":363,"@antv/util":803,"tslib":385}],362:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createInteraction = exports.registerInteraction = exports.getInteraction = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var grammar_interaction_1 = tslib_1.__importDefault(require("./grammar-interaction")); var Interactions = {}; /** * 根据交互行为名字获取对应的交互类 * @param name 交互名字 * @returns 交互类 */ function getInteraction(name) { return Interactions[util_1.lowerCase(name)]; } exports.getInteraction = getInteraction; /** * 注册交互行为 * @param name 交互行为名字 * @param interaction 交互类 */ function registerInteraction(name, interaction) { Interactions[util_1.lowerCase(name)] = interaction; } exports.registerInteraction = registerInteraction; /** * 创建交互实例 * @param name 交互名 * @param view 交互应用的 View 实例 * @param cfg 交互行为配置 */ function createInteraction(name, view, cfg) { var interaciton = getInteraction(name); if (!interaciton) { return null; } if (util_1.isPlainObject(interaciton)) { // 如果不 clone 则会多个 interaction 实例共享 step 的定义 var steps = util_1.mix(util_1.clone(interaciton), cfg); return new grammar_interaction_1.default(view, steps); } else { var cls = interaciton; return new cls(view, cfg); } } exports.createInteraction = createInteraction; var interaction_1 = require("./interaction"); Object.defineProperty(exports, "Interaction", { enumerable: true, get: function () { return interaction_1.default; } }); var action_1 = require("./action"); Object.defineProperty(exports, "Action", { enumerable: true, get: function () { return action_1.Action; } }); Object.defineProperty(exports, "registerAction", { enumerable: true, get: function () { return action_1.registerAction; } }); Object.defineProperty(exports, "getActionClass", { enumerable: true, get: function () { return action_1.getActionClass; } }); },{"./action":345,"./grammar-interaction":361,"./interaction":363,"@antv/util":803,"tslib":385}],363:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 交互的基类。 */ var Interaction = /** @class */ (function () { function Interaction(view, cfg) { this.view = view; this.cfg = cfg; } /** * 初始化。 */ Interaction.prototype.init = function () { this.initEvents(); }; /** * 绑定事件 */ Interaction.prototype.initEvents = function () { }; /** * 销毁事件 */ Interaction.prototype.clearEvents = function () { }; /** * 销毁。 */ Interaction.prototype.destroy = function () { this.clearEvents(); }; return Interaction; }()); exports.default = Interaction; },{}],364:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); },{}],365:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerTheme = exports.getTheme = void 0; var util_1 = require("@antv/util"); var theme_1 = require("../util/theme"); var light_1 = require("./style-sheet/light"); var defaultTheme = theme_1.createThemeByStylesheet(light_1.antvLight); // 所有已经存在的主题 var Themes = { default: defaultTheme, }; /** * 获取主题配置信息。 * @param theme 主题名 */ function getTheme(theme) { return util_1.get(Themes, util_1.lowerCase(theme), Themes.default); } exports.getTheme = getTheme; /** * 注册新的主题配置信息。 * @param theme 主题名。 * @param value 具体的主题配置。 */ function registerTheme(theme, value) { Themes[util_1.lowerCase(theme)] = util_1.deepMix({}, Themes.default, value); } exports.registerTheme = registerTheme; },{"../util/theme":382,"./style-sheet/light":367,"@antv/util":803}],366:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.antvDark = void 0; var WHITE_COLORS = { 100: '#000', 95: '#0D0D0D', 85: '#262626', 65: '#595959', 45: '#8C8C8C', 25: '#BFBFBF', 15: '#D9D9D9', 6: '#F0F0F0', }; var BLACK_COLORS = { 100: '#FFFFFF', 95: '#F2F2F2', 85: '#D9D9D9', 65: '#A6A6A6', 45: '#737373', 25: '#404040', 15: '#262626', 6: '#0F0F0F', }; var QUALITATIVE_10 = [ '#5B8FF9', '#5AD8A6', '#5D7092', '#F6BD16', '#E86452', '#6DC8EC', '#945FB9', '#FF9845', '#1E9493', '#FF99C3', ]; var QUALITATIVE_20 = [ '#5B8FF9', '#CDDDFD', '#5AD8A6', '#CDF3E4', '#5D7092', '#CED4DE', '#F6BD16', '#FCEBB9', '#E86452', '#F8D0CB', '#6DC8EC', '#D3EEF9', '#945FB9', '#DECFEA', '#FF9845', '#FFE0C7', '#1E9493', '#BBDEDE', '#FF99C3', '#FFE0ED', ]; exports.antvDark = { backgroundColor: '#141414', /** 主题色 */ brandColor: QUALITATIVE_10[0], /** 分类色板 1,在数据量小于等于 10 时使用 */ paletteQualitative10: QUALITATIVE_10, /** 分类色板 2,在数据量大于 10 时使用 */ paletteQualitative20: QUALITATIVE_20, /** 语义色 */ paletteSemanticRed: '#F4664A', /** 语义色 */ paletteSemanticGreen: '#30BF78', /** 语义色 */ paletteSemanticYellow: '#FAAD14', /** 字体 */ fontFamily: "\"-apple-system\", \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial,\n \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n \"Noto Color Emoji\"", // -------------------- 坐标轴 -------------------- /** 坐标轴线颜色 */ axisLineBorderColor: BLACK_COLORS[25], /** 坐标轴线粗细 */ axisLineBorder: 0.5, /** 坐标轴线 lineDash 设置 */ axisLineDash: null, /** 坐标轴标题颜色 */ axisTitleTextFillColor: BLACK_COLORS[65], /** 坐标轴标题文本字体大小 */ axisTitleTextFontSize: 12, /** 坐标轴标题文本行高 */ axisTitleTextLineHeight: 12, /** 坐标轴标题文本字体粗细 */ axisTitleTextFontWeight: 'normal', /** 坐标轴刻度线颜色 */ axisTickLineBorderColor: BLACK_COLORS[25], /** 坐标轴刻度线长度 */ axisTickLineLength: 4, /** 坐标轴刻度线粗细 */ axisTickLineBorder: 0.5, /** 坐标轴次刻度线颜色 */ axisSubTickLineBorderColor: BLACK_COLORS[15], /** 坐标轴次刻度线长度 */ axisSubTickLineLength: 2, /** 坐标轴次刻度线粗细 */ axisSubTickLineBorder: 0.5, /** 坐标轴刻度文本颜色 */ axisLabelFillColor: BLACK_COLORS[45], /** 坐标轴刻度文本字体大小 */ axisLabelFontSize: 12, /** 坐标轴刻度文本行高 */ axisLabelLineHeight: 12, /** 坐标轴刻度文本字体粗细 */ axisLabelFontWeight: 'normal', /** 坐标轴网格线颜色 */ axisGridBorderColor: BLACK_COLORS[15], /** 坐标轴网格线粗细 */ axisGridBorder: 0.5, /** 坐标轴网格线虚线设置 */ axisGridLineDash: null, // -------------------- 图例 -------------------- /** 图例标题颜色 */ legendTitleTextFillColor: BLACK_COLORS[45], /** 图例标题文本字体大小 */ legendTitleTextFontSize: 12, /** 图例标题文本行高 */ legendTitleTextLineHeight: 21, /** 图例标题文本字体粗细 */ legendTitleTextFontWeight: 'normal', /** 图例 marker 颜色 */ legendMarkerColor: QUALITATIVE_10[0], /** 图例 marker 默认半径大小 */ legendMarkerSize: 4, /** 图例 'circle' marker 半径 */ legendCircleMarkerSize: 4, /** 图例 'square' marker 半径 */ legendSquareMarkerSize: 4, /** 图例 'line' marker 半径 */ legendLineMarkerSize: 5, /** 图例项文本颜色 */ legendItemNameFillColor: BLACK_COLORS[65], /** 图例项文本字体大小 */ legendItemNameFontSize: 12, /** 图例项文本行高 */ legendItemNameLineHeight: 12, /** 图例项粗细 */ legendItemNameFontWeight: 'normal', /** 连续图例滑块填充色 */ sliderRailFillColor: BLACK_COLORS[15], /** 连续图例滑块边框粗细 */ sliderRailBorder: 0, /** 连续图例滑块边框颜色 */ sliderRailBorderColor: null, /** 连续图例滑块宽度 */ sliderRailWidth: 100, /** 连续图例滑块高度 */ sliderRailHeight: 12, /** 连续图例文本颜色 */ sliderLabelTextFillColor: BLACK_COLORS[45], /** 连续图例文本字体大小 */ sliderLabelTextFontSize: 12, /** 连续图例文本行高 */ sliderLabelTextLineHeight: 12, /** 连续图例文本字体粗细 */ sliderLabelTextFontWeight: 'normal', /** 连续图例滑块颜色 */ sliderHandlerFillColor: WHITE_COLORS[6], /** 连续图例滑块宽度 */ sliderHandlerWidth: 10, /** 连续图例滑块高度 */ sliderHandlerHeight: 14, /** 连续图例滑块边框粗细 */ sliderHandlerBorder: 1, /** 连续图例滑块边框颜色 */ sliderHandlerBorderColor: WHITE_COLORS[25], // -------------------- Annotation,图形标注 -------------------- /** arc 图形标注描边颜色 */ annotationArcBorderColor: BLACK_COLORS[15], /** arc 图形标注粗细 */ annotationArcBorder: 0.5, /** line 图形标注颜色 */ annotationLineBorderColor: BLACK_COLORS[25], /** line 图形标注粗细 */ annotationLineBorder: 0.5, /** lube 图形标注的虚线间隔 */ annotationLineDash: null, /** text 图形标注文本颜色 */ annotationTextFillColor: BLACK_COLORS[65], /** text 图形标注文本字体大小 */ annotationTextFontSize: 12, /** text 图形标注文本行高 */ annotationTextLineHeight: 12, /** text 图形标注文本字体粗细 */ annotationTextFontWeight: 'normal', /** text 图形标注文本边框颜色 */ annotationTextBorderColor: WHITE_COLORS[95], /** text 图形标注文本边框粗细 */ annotationTextBorder: 1.5, /** region 图形标注填充颜色 */ annotationRegionFillColor: BLACK_COLORS[100], /** region 图形标注填充颜色透明色 */ annotationRegionFillOpacity: 0.06, /** region 图形标注描边粗细 */ annotationRegionBorder: 0, /** region 图形标注描边颜色 */ annotationRegionBorderColor: null, /** dataMarker 图形标注线的长度 */ annotationDataMarkerLineLength: 16, // -------------------- Tooltip -------------------- /** tooltip crosshairs 辅助线颜色 */ tooltipCrosshairsBorderColor: BLACK_COLORS[25], /** tooltip crosshairs 辅助线粗细 */ tooltipCrosshairsBorder: 0.5, /** tooltip crosshairs 辅助线虚线间隔 */ tooltipCrosshairsLineDash: null, /** tooltip 内容框背景色 */ tooltipContainerFillColor: '#1f1f1f', tooltipContainerFillOpacity: 0.95, /** tooltip 内容框阴影 */ tooltipContainerShadow: '0px 2px 4px rgba(0,0,0,.5)', /** tooltip 内容框圆角 */ tooltipContainerBorderRadius: 3, /** tooltip 文本颜色 */ tooltipTextFillColor: BLACK_COLORS[65], /** tooltip 文本字体大小 */ tooltipTextFontSize: 12, /** tooltip 文本行高 */ tooltipTextLineHeight: 12, /** tooltip 文本字体粗细 */ tooltipTextFontWeight: 'bold', // -------------------- Geometry labels -------------------- /** Geometry label 文本颜色 */ labelFillColor: BLACK_COLORS[65], /** Geometry label 文本字体大小 */ labelFontSize: 12, /** Geometry label 文本行高 */ labelLineHeight: 12, /** Geometry label 文本字体粗细 */ labelFontWeight: 'normal', /** Geometry label 文本描边颜色 */ labelBorderColor: null, /** Geometry label 文本描边粗细 */ labelBorder: 0, /** Geometry innerLabel 文本颜色 */ innerLabelFillColor: WHITE_COLORS[100], /** Geometry innerLabel 文本字体大小 */ innerLabelFontSize: 12, /** Geometry innerLabel 文本行高 */ innerLabelLineHeight: 12, /** Geometry innerLabel 文本字体粗细 */ innerLabelFontWeight: 'normal', /** Geometry innerLabel 文本描边颜色 */ innerLabelBorderColor: null, /** Geometry innerLabel 文本描边粗细 */ innerLabelBorder: 0, /** Geometry label 文本连接线粗细 */ labelLineBorder: 0.5, /** Geometry label 文本连接线颜色 */ labelLineBorderColor: BLACK_COLORS[25], // -------------------- Geometry 图形样式-------------------- /** 点图填充颜色 */ pointFillColor: QUALITATIVE_10[0], /** 点图填充颜色透明度 */ pointFillOpacity: 0.95, /** 点图大小 */ pointSize: 4, /** 点图描边粗细 */ pointBorder: 1, /** 点图描边颜色 */ pointBorderColor: WHITE_COLORS[100], /** 点图描边透明度 */ pointBorderOpacity: 1, /** 点图 active 状态下描边颜色 */ pointActiveBorderColor: BLACK_COLORS[100], /** 点图 selected 状态下描边粗细 */ pointSelectedBorder: 2, /** 点图 selected 状态下描边颜色 */ pointSelectedBorderColor: BLACK_COLORS[100], /** 点图 inactive 状态下填充颜色透明度 */ pointInactiveFillOpacity: 0.3, /** 点图 inactive 状态下描边透明度 */ pointInactiveBorderOpacity: 0.3, /** 空心点图大小 */ hollowPointSize: 4, /** 空心点图描边粗细 */ hollowPointBorder: 1, /** 空心点图描边颜色 */ hollowPointBorderColor: QUALITATIVE_10[0], /** 空心点图描边透明度 */ hollowPointBorderOpacity: 0.95, hollowPointFillColor: WHITE_COLORS[100], /** 空心点图 active 状态下描边粗细 */ hollowPointActiveBorder: 1, /** 空心点图 active 状态下描边颜色 */ hollowPointActiveBorderColor: BLACK_COLORS[100], /** 空心点图 active 状态下描边透明度 */ hollowPointActiveBorderOpacity: 1, /** 空心点图 selected 状态下描边粗细 */ hollowPointSelectedBorder: 2, /** 空心点图 selected 状态下描边颜色 */ hollowPointSelectedBorderColor: BLACK_COLORS[100], /** 空心点图 selected 状态下描边透明度 */ hollowPointSelectedBorderOpacity: 1, /** 空心点图 inactive 状态下描边透明度 */ hollowPointInactiveBorderOpacity: 0.3, /** 线图粗细 */ lineBorder: 2, /** 线图颜色 */ lineBorderColor: QUALITATIVE_10[0], /** 线图透明度 */ lineBorderOpacity: 1, /** 线图 Active 状态下粗细 */ lineActiveBorder: 3, /** 线图 selected 状态下粗细 */ lineSelectedBorder: 3, /** 线图 inactive 状态下透明度 */ lineInactiveBorderOpacity: 0.3, /** area 填充颜色 */ areaFillColor: QUALITATIVE_10[0], /** area 填充透明度 */ areaFillOpacity: 0.25, /** area 在 active 状态下的填充透明度 */ areaActiveFillColor: QUALITATIVE_10[0], areaActiveFillOpacity: 0.5, /** area 在 selected 状态下的填充透明度 */ areaSelectedFillColor: QUALITATIVE_10[0], areaSelectedFillOpacity: 0.5, /** area inactive 状态下填充透明度 */ areaInactiveFillOpacity: 0.3, /** hollowArea 颜色 */ hollowAreaBorderColor: QUALITATIVE_10[0], /** hollowArea 边框粗细 */ hollowAreaBorder: 2, /** hollowArea 边框透明度 */ hollowAreaBorderOpacity: 1, /** hollowArea active 状态下的边框粗细 */ hollowAreaActiveBorder: 3, hollowAreaActiveBorderColor: BLACK_COLORS[100], /** hollowArea selected 状态下的边框粗细 */ hollowAreaSelectedBorder: 3, hollowAreaSelectedBorderColor: BLACK_COLORS[100], /** hollowArea inactive 状态下的边框透明度 */ hollowAreaInactiveBorderOpacity: 0.3, /** interval 填充颜色 */ intervalFillColor: QUALITATIVE_10[0], /** interval 填充透明度 */ intervalFillOpacity: 0.95, /** interval active 状态下边框粗细 */ intervalActiveBorder: 1, /** interval active 状态下边框颜色 */ intervalActiveBorderColor: BLACK_COLORS[100], intervalActiveBorderOpacity: 1, /** interval selected 状态下边框粗细 */ intervalSelectedBorder: 2, /** interval selected 状态下边框颜色 */ intervalSelectedBorderColor: BLACK_COLORS[100], /** interval selected 状态下边框透明度 */ intervalSelectedBorderOpacity: 1, /** interval inactive 状态下边框透明度 */ intervalInactiveBorderOpacity: 0.3, /** interval inactive 状态下填充透明度 */ intervalInactiveFillOpacity: 0.3, /** interval 边框粗细 */ hollowIntervalBorder: 2, /** hollowInterval 边框颜色 */ hollowIntervalBorderColor: QUALITATIVE_10[0], /** hollowInterval 边框透明度 */ hollowIntervalBorderOpacity: 1, hollowIntervalFillColor: WHITE_COLORS[100], /** hollowInterval active 状态下边框粗细 */ hollowIntervalActiveBorder: 2, /** hollowInterval active 状态下边框颜色 */ hollowIntervalActiveBorderColor: BLACK_COLORS[100], /** hollowInterval selected 状态下边框粗细 */ hollowIntervalSelectedBorder: 3, /** hollowInterval selected 状态下边框颜色 */ hollowIntervalSelectedBorderColor: BLACK_COLORS[100], /** hollowInterval selected 状态下边框透明度 */ hollowIntervalSelectedBorderOpacity: 1, /** hollowInterval inactive 状态下边框透明度 */ hollowIntervalInactiveBorderOpacity: 0.3, }; },{}],367:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.antvLight = void 0; var BLACK_COLORS = { 100: '#000', 95: '#0D0D0D', 85: '#262626', 65: '#595959', 45: '#8C8C8C', 25: '#BFBFBF', 15: '#D9D9D9', 6: '#F0F0F0', }; var WHITE_COLORS = { 100: '#FFFFFF', 95: '#F2F2F2', 85: '#D9D9D9', 65: '#A6A6A6', 45: '#737373', 25: '#404040', 15: '#262626', 6: '#0F0F0F', }; var QUALITATIVE_10 = [ '#5B8FF9', '#5AD8A6', '#5D7092', '#F6BD16', '#E86452', '#6DC8EC', '#945FB9', '#FF9845', '#1E9493', '#FF99C3', ]; var QUALITATIVE_20 = [ '#5B8FF9', '#CDDDFD', '#5AD8A6', '#CDF3E4', '#5D7092', '#CED4DE', '#F6BD16', '#FCEBB9', '#E86452', '#F8D0CB', '#6DC8EC', '#D3EEF9', '#945FB9', '#DECFEA', '#FF9845', '#FFE0C7', '#1E9493', '#BBDEDE', '#FF99C3', '#FFE0ED', ]; exports.antvLight = { backgroundColor: 'transparent', /** 主题色 */ brandColor: QUALITATIVE_10[0], /** 分类色板 1,在数据量小于等于 10 时使用 */ paletteQualitative10: QUALITATIVE_10, /** 分类色板 2,在数据量大于 10 时使用 */ paletteQualitative20: QUALITATIVE_20, /** 语义色 */ paletteSemanticRed: '#F4664A', /** 语义色 */ paletteSemanticGreen: '#30BF78', /** 语义色 */ paletteSemanticYellow: '#FAAD14', /** 字体 */ fontFamily: "\"-apple-system\", \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial,\n \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n \"Noto Color Emoji\"", // -------------------- 坐标轴 -------------------- /** 坐标轴线颜色 */ axisLineBorderColor: BLACK_COLORS[25], /** 坐标轴线粗细 */ axisLineBorder: 0.5, /** 坐标轴线 lineDash 设置 */ axisLineDash: null, /** 坐标轴标题颜色 */ axisTitleTextFillColor: BLACK_COLORS[65], /** 坐标轴标题文本字体大小 */ axisTitleTextFontSize: 12, /** 坐标轴标题文本行高 */ axisTitleTextLineHeight: 12, /** 坐标轴标题文本字体粗细 */ axisTitleTextFontWeight: 'normal', /** 坐标轴刻度线颜色 */ axisTickLineBorderColor: BLACK_COLORS[25], /** 坐标轴刻度线长度 */ axisTickLineLength: 4, /** 坐标轴刻度线粗细 */ axisTickLineBorder: 0.5, /** 坐标轴次刻度线颜色 */ axisSubTickLineBorderColor: BLACK_COLORS[15], /** 坐标轴次刻度线长度 */ axisSubTickLineLength: 2, /** 坐标轴次刻度线粗细 */ axisSubTickLineBorder: 0.5, /** 坐标轴刻度文本颜色 */ axisLabelFillColor: BLACK_COLORS[45], /** 坐标轴刻度文本字体大小 */ axisLabelFontSize: 12, /** 坐标轴刻度文本行高 */ axisLabelLineHeight: 12, /** 坐标轴刻度文本字体粗细 */ axisLabelFontWeight: 'normal', /** 坐标轴网格线颜色 */ axisGridBorderColor: BLACK_COLORS[15], /** 坐标轴网格线粗细 */ axisGridBorder: 0.5, /** 坐标轴网格线虚线设置 */ axisGridLineDash: null, // -------------------- 图例 -------------------- /** 图例标题颜色 */ legendTitleTextFillColor: BLACK_COLORS[45], /** 图例标题文本字体大小 */ legendTitleTextFontSize: 12, /** 图例标题文本行高 */ legendTitleTextLineHeight: 21, /** 图例标题文本字体粗细 */ legendTitleTextFontWeight: 'normal', /** 图例 marker 颜色 */ legendMarkerColor: QUALITATIVE_10[0], /** 图例 marker 默认半径大小 */ legendMarkerSize: 4, /** 图例 'circle' marker 半径 */ legendCircleMarkerSize: 4, /** 图例 'square' marker 半径 */ legendSquareMarkerSize: 4, /** 图例 'line' marker 半径 */ legendLineMarkerSize: 5, /** 图例项文本颜色 */ legendItemNameFillColor: BLACK_COLORS[65], /** 图例项文本字体大小 */ legendItemNameFontSize: 12, /** 图例项文本行高 */ legendItemNameLineHeight: 12, /** 图例项粗细 */ legendItemNameFontWeight: 'normal', /** 连续图例滑块填充色 */ sliderRailFillColor: BLACK_COLORS[15], /** 连续图例滑块边框粗细 */ sliderRailBorder: 0, /** 连续图例滑块边框颜色 */ sliderRailBorderColor: null, /** 连续图例滑块宽度 */ sliderRailWidth: 100, /** 连续图例滑块高度 */ sliderRailHeight: 12, /** 连续图例文本颜色 */ sliderLabelTextFillColor: BLACK_COLORS[45], /** 连续图例文本字体大小 */ sliderLabelTextFontSize: 12, /** 连续图例文本行高 */ sliderLabelTextLineHeight: 12, /** 连续图例文本字体粗细 */ sliderLabelTextFontWeight: 'normal', /** 连续图例滑块颜色 */ sliderHandlerFillColor: BLACK_COLORS[6], /** 连续图例滑块宽度 */ sliderHandlerWidth: 10, /** 连续图例滑块高度 */ sliderHandlerHeight: 14, /** 连续图例滑块边框粗细 */ sliderHandlerBorder: 1, /** 连续图例滑块边框颜色 */ sliderHandlerBorderColor: BLACK_COLORS[25], // -------------------- Annotation,图形标注 -------------------- /** arc 图形标注描边颜色 */ annotationArcBorderColor: BLACK_COLORS[15], /** arc 图形标注粗细 */ annotationArcBorder: 0.5, /** line 图形标注颜色 */ annotationLineBorderColor: BLACK_COLORS[25], /** line 图形标注粗细 */ annotationLineBorder: 0.5, /** lube 图形标注的虚线间隔 */ annotationLineDash: null, /** text 图形标注文本颜色 */ annotationTextFillColor: BLACK_COLORS[65], /** text 图形标注文本字体大小 */ annotationTextFontSize: 12, /** text 图形标注文本行高 */ annotationTextLineHeight: 12, /** text 图形标注文本字体粗细 */ annotationTextFontWeight: 'normal', /** text 图形标注文本边框颜色 */ annotationTextBorderColor: WHITE_COLORS[95], /** text 图形标注文本边框粗细 */ annotationTextBorder: 1.5, /** region 图形标注填充颜色 */ annotationRegionFillColor: BLACK_COLORS[100], /** region 图形标注填充颜色透明色 */ annotationRegionFillOpacity: 0.06, /** region 图形标注描边粗细 */ annotationRegionBorder: 0, /** region 图形标注描边颜色 */ annotationRegionBorderColor: null, /** dataMarker 图形标注线的长度 */ annotationDataMarkerLineLength: 16, // -------------------- Tooltip -------------------- /** tooltip crosshairs 辅助线颜色 */ tooltipCrosshairsBorderColor: BLACK_COLORS[25], /** tooltip crosshairs 辅助线粗细 */ tooltipCrosshairsBorder: 0.5, /** tooltip crosshairs 辅助线虚线间隔 */ tooltipCrosshairsLineDash: null, /** tooltip 内容框背景色 */ tooltipContainerFillColor: 'rgb(255, 255, 255)', tooltipContainerFillOpacity: 0.95, /** tooltip 内容框阴影 */ tooltipContainerShadow: '0px 0px 10px #aeaeae', /** tooltip 内容框圆角 */ tooltipContainerBorderRadius: 3, /** tooltip 文本颜色 */ tooltipTextFillColor: BLACK_COLORS[65], /** tooltip 文本字体大小 */ tooltipTextFontSize: 12, /** tooltip 文本行高 */ tooltipTextLineHeight: 12, /** tooltip 文本字体粗细 */ tooltipTextFontWeight: 'bold', // -------------------- Geometry labels -------------------- /** Geometry label 文本颜色 */ labelFillColor: BLACK_COLORS[65], /** Geometry label 文本字体大小 */ labelFontSize: 12, /** Geometry label 文本行高 */ labelLineHeight: 12, /** Geometry label 文本字体粗细 */ labelFontWeight: 'normal', /** Geometry label 文本描边颜色 */ labelBorderColor: null, /** Geometry label 文本描边粗细 */ labelBorder: 0, /** Geometry innerLabel 文本颜色 */ innerLabelFillColor: WHITE_COLORS[100], /** Geometry innerLabel 文本字体大小 */ innerLabelFontSize: 12, /** Geometry innerLabel 文本行高 */ innerLabelLineHeight: 12, /** Geometry innerLabel 文本字体粗细 */ innerLabelFontWeight: 'normal', /** Geometry innerLabel 文本描边颜色 */ innerLabelBorderColor: null, /** Geometry innerLabel 文本描边粗细 */ innerLabelBorder: 0, /** Geometry label 文本连接线粗细 */ labelLineBorder: 0.5, /** Geometry label 文本连接线颜色 */ labelLineBorderColor: BLACK_COLORS[25], // -------------------- Geometry 图形样式-------------------- /** 点图填充颜色 */ pointFillColor: QUALITATIVE_10[0], /** 点图填充颜色透明度 */ pointFillOpacity: 0.95, /** 点图大小 */ pointSize: 4, /** 点图描边粗细 */ pointBorder: 1, /** 点图描边颜色 */ pointBorderColor: WHITE_COLORS[100], /** 点图描边透明度 */ pointBorderOpacity: 1, /** 点图 active 状态下描边颜色 */ pointActiveBorderColor: BLACK_COLORS[100], /** 点图 selected 状态下描边粗细 */ pointSelectedBorder: 2, /** 点图 selected 状态下描边颜色 */ pointSelectedBorderColor: BLACK_COLORS[100], /** 点图 inactive 状态下填充颜色透明度 */ pointInactiveFillOpacity: 0.3, /** 点图 inactive 状态下描边透明度 */ pointInactiveBorderOpacity: 0.3, /** 空心点图大小 */ hollowPointSize: 4, /** 空心点图描边粗细 */ hollowPointBorder: 1, /** 空心点图描边颜色 */ hollowPointBorderColor: QUALITATIVE_10[0], /** 空心点图描边透明度 */ hollowPointBorderOpacity: 0.95, hollowPointFillColor: WHITE_COLORS[100], /** 空心点图 active 状态下描边粗细 */ hollowPointActiveBorder: 1, /** 空心点图 active 状态下描边颜色 */ hollowPointActiveBorderColor: BLACK_COLORS[100], /** 空心点图 active 状态下描边透明度 */ hollowPointActiveBorderOpacity: 1, /** 空心点图 selected 状态下描边粗细 */ hollowPointSelectedBorder: 2, /** 空心点图 selected 状态下描边颜色 */ hollowPointSelectedBorderColor: BLACK_COLORS[100], /** 空心点图 selected 状态下描边透明度 */ hollowPointSelectedBorderOpacity: 1, /** 空心点图 inactive 状态下描边透明度 */ hollowPointInactiveBorderOpacity: 0.3, /** 线图粗细 */ lineBorder: 2, /** 线图颜色 */ lineBorderColor: QUALITATIVE_10[0], /** 线图透明度 */ lineBorderOpacity: 1, /** 线图 Active 状态下粗细 */ lineActiveBorder: 3, /** 线图 selected 状态下粗细 */ lineSelectedBorder: 3, /** 线图 inactive 状态下透明度 */ lineInactiveBorderOpacity: 0.3, /** area 填充颜色 */ areaFillColor: QUALITATIVE_10[0], /** area 填充透明度 */ areaFillOpacity: 0.25, /** area 在 active 状态下的填充透明度 */ areaActiveFillColor: QUALITATIVE_10[0], areaActiveFillOpacity: 0.5, /** area 在 selected 状态下的填充透明度 */ areaSelectedFillColor: QUALITATIVE_10[0], areaSelectedFillOpacity: 0.5, /** area inactive 状态下填充透明度 */ areaInactiveFillOpacity: 0.3, /** hollowArea 颜色 */ hollowAreaBorderColor: QUALITATIVE_10[0], /** hollowArea 边框粗细 */ hollowAreaBorder: 2, /** hollowArea 边框透明度 */ hollowAreaBorderOpacity: 1, /** hollowArea active 状态下的边框粗细 */ hollowAreaActiveBorder: 3, hollowAreaActiveBorderColor: BLACK_COLORS[100], /** hollowArea selected 状态下的边框粗细 */ hollowAreaSelectedBorder: 3, hollowAreaSelectedBorderColor: BLACK_COLORS[100], /** hollowArea inactive 状态下的边框透明度 */ hollowAreaInactiveBorderOpacity: 0.3, /** interval 填充颜色 */ intervalFillColor: QUALITATIVE_10[0], /** interval 填充透明度 */ intervalFillOpacity: 0.95, /** interval active 状态下边框粗细 */ intervalActiveBorder: 1, /** interval active 状态下边框颜色 */ intervalActiveBorderColor: BLACK_COLORS[100], intervalActiveBorderOpacity: 1, /** interval selected 状态下边框粗细 */ intervalSelectedBorder: 2, /** interval selected 状态下边框颜色 */ intervalSelectedBorderColor: BLACK_COLORS[100], /** interval selected 状态下边框透明度 */ intervalSelectedBorderOpacity: 1, /** interval inactive 状态下边框透明度 */ intervalInactiveBorderOpacity: 0.3, /** interval inactive 状态下填充透明度 */ intervalInactiveFillOpacity: 0.3, /** interval 边框粗细 */ hollowIntervalBorder: 2, /** hollowInterval 边框颜色 */ hollowIntervalBorderColor: QUALITATIVE_10[0], /** hollowInterval 边框透明度 */ hollowIntervalBorderOpacity: 1, hollowIntervalFillColor: WHITE_COLORS[100], /** hollowInterval active 状态下边框粗细 */ hollowIntervalActiveBorder: 2, /** hollowInterval active 状态下边框颜色 */ hollowIntervalActiveBorderColor: BLACK_COLORS[100], /** hollowInterval selected 状态下边框粗细 */ hollowIntervalSelectedBorder: 3, /** hollowInterval selected 状态下边框颜色 */ hollowIntervalSelectedBorderColor: BLACK_COLORS[100], /** hollowInterval selected 状态下边框透明度 */ hollowIntervalSelectedBorderOpacity: 1, /** hollowInterval inactive 状态下边框透明度 */ hollowIntervalInactiveBorderOpacity: 0.3, }; },{}],368:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMappingValue = void 0; var tslib_1 = require("tslib"); /** * @ignore * get the mapping value by attribute, if mapping value is nil, return def * @param attr * @param value * @param def * @returns get mapping value */ function getMappingValue(attr, value, def) { if (!attr) { return def; } var r; // 多参数映射,阻止程序报错 if (attr.callback && attr.callback.length > 1) { var restArgs = Array(attr.callback.length - 1).fill(''); r = attr.mapping.apply(attr, tslib_1.__spreadArrays([value], restArgs)).join(''); } else { r = attr.mapping(value).join(''); } return r || def; } exports.getMappingValue = getMappingValue; },{"tslib":385}],369:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAxisTitleText = exports.getAxisDirection = exports.getAxisOption = exports.getCircleAxisCenterRadius = exports.getAxisThemeCfg = exports.getAxisFactorByRegion = exports.isVertical = exports.getAxisFactor = exports.getAxisRegion = exports.getCircleAxisRelativeRegion = exports.getLineAxisRelativeRegion = void 0; var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var scale_1 = require("./scale"); var matrix_util_1 = require("@antv/matrix-util"); /** * @ignore * get axis relative region ( 0 ~ 1) by direction when coordinate is rect * @param direction * @returns axis coordinate region */ function getLineAxisRelativeRegion(direction) { var start; var end; switch (direction) { case constant_1.DIRECTION.TOP: start = { x: 0, y: 1 }; end = { x: 1, y: 1 }; break; case constant_1.DIRECTION.RIGHT: start = { x: 1, y: 0 }; end = { x: 1, y: 1 }; break; case constant_1.DIRECTION.BOTTOM: start = { x: 0, y: 0 }; end = { x: 1, y: 0 }; break; case constant_1.DIRECTION.LEFT: start = { x: 0, y: 0 }; end = { x: 0, y: 1 }; break; default: start = end = { x: 0, y: 0 }; } return { start: start, end: end }; } exports.getLineAxisRelativeRegion = getLineAxisRelativeRegion; /** * @ignore * get axis relative region ( 0 ~ 1) by direction when coordinate is polar * @param coordinate * @returns axis coordinate region */ function getCircleAxisRelativeRegion(coordinate) { var start; var end; if (coordinate.isTransposed) { start = { x: 0, y: 0, }; end = { x: 1, y: 0, }; } else { start = { x: 0, y: 0, }; end = { x: 0, y: 1, }; } return { start: start, end: end }; } exports.getCircleAxisRelativeRegion = getCircleAxisRelativeRegion; /** * @ignore * get the axis region from coordinate * @param coordinate * @param direction * @returns the axis region (start point, end point) */ function getAxisRegion(coordinate, direction) { var region = { start: { x: 0, y: 0 }, end: { x: 0, y: 0 } }; if (coordinate.isRect) { region = getLineAxisRelativeRegion(direction); } else if (coordinate.isPolar) { region = getCircleAxisRelativeRegion(coordinate); } var start = region.start, end = region.end; return { start: coordinate.convert(start), end: coordinate.convert(end), }; } exports.getAxisRegion = getAxisRegion; /** * @ignore * get axis factor * @param coordinate * @param direction * @returns factor */ function getAxisFactor(coordinate, direction) { // rect coordinate, by direction if (coordinate.isRect) { return coordinate.isTransposed ? [constant_1.DIRECTION.RIGHT, constant_1.DIRECTION.BOTTOM].includes(direction) ? 1 : -1 : [constant_1.DIRECTION.BOTTOM, constant_1.DIRECTION.RIGHT].includes(direction) ? -1 : 1; } // polar y axis, by angle if (coordinate.isPolar) { var startAngle = coordinate.x.start; return startAngle < 0 ? -1 : 1; } return 1; } exports.getAxisFactor = getAxisFactor; /** * @ignore * whether the axis isVertical * @param region * @returns isVertical */ function isVertical(region) { var start = region.start, end = region.end; return start.x === end.x; } exports.isVertical = isVertical; /** * @ignore * get factor by region (real position) * @param region * @param center * @returns factor */ function getAxisFactorByRegion(region, center) { var start = region.start, end = region.end; var isAxisVertical = isVertical(region); // 垂直 if (isAxisVertical) { // 左方,从下到上、右方,从上到下 if ((start.y - end.y) * (center.x - start.x) > 0) { return 1; } else { return -1; } } else { // 下方,从左到右、上方,从右到做 if ((end.x - start.x) * (start.y - center.y) > 0) { return -1; } else { return 1; } } } exports.getAxisFactorByRegion = getAxisFactorByRegion; /** * @ignore * get the axis cfg from theme * @param theme view theme object * @param direction axis direction * @returns axis theme cfg */ function getAxisThemeCfg(theme, direction) { return util_1.get(theme, ['components', 'axis', direction], {}); } exports.getAxisThemeCfg = getAxisThemeCfg; /** * @ignore * get circle axis center and radius * @param coordinate */ function getCircleAxisCenterRadius(coordinate) { // @ts-ignore var x = coordinate.x, y = coordinate.y, center = coordinate.circleCenter; var isReflectY = y.start > y.end; var start = coordinate.isTransposed ? coordinate.convert({ x: isReflectY ? 0 : 1, y: 0, }) : coordinate.convert({ x: 0, y: isReflectY ? 0 : 1, }); var startVector = [start.x - center.x, start.y - center.y]; var normalVector = [1, 0]; var startAngle = start.y > center.y ? matrix_util_1.vec2.angle(startVector, normalVector) : matrix_util_1.vec2.angle(startVector, normalVector) * -1; var endAngle = startAngle + (x.end - x.start); var radius = Math.sqrt(Math.pow((start.x - center.x), 2) + Math.pow((start.y - center.y), 2)); return { center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, }; } exports.getCircleAxisCenterRadius = getCircleAxisCenterRadius; /** * @ignore * 从配置中获取单个字段的 axis 配置 * @param axes * @param field * @returns the axis option of field */ function getAxisOption(axes, field) { if (util_1.isBoolean(axes)) { return axes === false ? false : {}; } return util_1.get(axes, [field]); } exports.getAxisOption = getAxisOption; /** * @ignore * 如果配置了 position,则使用配置 * @param axisOption * @param def */ function getAxisDirection(axisOption, def) { return util_1.get(axisOption, 'position', def); } exports.getAxisDirection = getAxisDirection; /** * 获取 axis 的 title 文本 * @param scale * @param axisOption */ function getAxisTitleText(scale, axisOption) { return util_1.get(axisOption, ['title', 'text'], scale_1.getName(scale)); } exports.getAxisTitleText = getAxisTitleText; },{"../constant":237,"./scale":381,"@antv/matrix-util":717,"@antv/util":803}],370:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toPoints = exports.getRegionBBox = exports.BBox = void 0; var util_1 = require("@antv/util"); var constant_1 = require("../constant"); /** * 用于包围盒计算。 */ var BBox = /** @class */ (function () { function BBox(x, y, width, height) { if (x === void 0) { x = 0; } if (y === void 0) { y = 0; } if (width === void 0) { width = 0; } if (height === void 0) { height = 0; } this.x = x; this.y = y; this.height = height; this.width = width; } BBox.fromRange = function (minX, minY, maxX, maxY) { return new BBox(minX, minY, maxX - minX, maxY - minY); }; Object.defineProperty(BBox.prototype, "minX", { get: function () { return this.x; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "maxX", { get: function () { return this.x + this.width; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "minY", { get: function () { return this.y; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "maxY", { get: function () { return this.y + this.height; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "tl", { get: function () { return { x: this.x, y: this.y }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "tr", { get: function () { return { x: this.maxX, y: this.y }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "bl", { get: function () { return { x: this.x, y: this.maxY }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "br", { get: function () { return { x: this.maxX, y: this.maxY }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "top", { get: function () { return { x: this.x + this.width / 2, y: this.minY, }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "right", { get: function () { return { x: this.maxX, y: this.y + this.height / 2, }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "bottom", { get: function () { return { x: this.x + this.width / 2, y: this.maxY, }; }, enumerable: false, configurable: true }); Object.defineProperty(BBox.prototype, "left", { get: function () { return { x: this.minX, y: this.y + this.height / 2, }; }, enumerable: false, configurable: true }); // end 计算属性 /** * 包围盒是否相等 * @param {BBox} bbox 包围盒 * @returns 包围盒是否相等 */ BBox.prototype.isEqual = function (bbox) { return this.x === bbox.x && this.y === bbox.y && this.width === bbox.width && this.height === bbox.height; }; /** * 克隆包围盒 * @returns 包围盒 */ BBox.prototype.clone = function () { return new BBox(this.x, this.y, this.width, this.height); }; /** * 取并集 * @param subBBox */ BBox.prototype.add = function () { var subBBox = []; for (var _i = 0; _i < arguments.length; _i++) { subBBox[_i] = arguments[_i]; } var bbox = this.clone(); util_1.each(subBBox, function (b) { bbox.x = Math.min(b.x, bbox.x); bbox.y = Math.min(b.y, bbox.y); bbox.width = Math.max(b.maxX, bbox.maxX) - bbox.x; bbox.height = Math.max(b.maxY, bbox.maxY) - bbox.y; }); return bbox; }; /** * 取交集 * @param subBBox */ BBox.prototype.merge = function () { var subBBox = []; for (var _i = 0; _i < arguments.length; _i++) { subBBox[_i] = arguments[_i]; } var bbox = this.clone(); util_1.each(subBBox, function (b) { bbox.x = Math.max(b.x, bbox.x); bbox.y = Math.max(b.y, bbox.y); bbox.width = Math.min(b.maxX, bbox.maxX) - bbox.x; bbox.height = Math.min(b.maxY, bbox.maxY) - bbox.y; }); return bbox; }; /** * bbox 剪裁 * @param subBBox * @param direction */ BBox.prototype.cut = function (subBBox, direction) { var width = subBBox.width; var height = subBBox.height; switch (direction) { case constant_1.DIRECTION.TOP: case constant_1.DIRECTION.TOP_LEFT: case constant_1.DIRECTION.TOP_RIGHT: return BBox.fromRange(this.minX, this.minY + height, this.maxX, this.maxY); case constant_1.DIRECTION.RIGHT: case constant_1.DIRECTION.RIGHT_TOP: case constant_1.DIRECTION.RIGHT_BOTTOM: return BBox.fromRange(this.minX, this.minY, this.maxX - width, this.maxY); case constant_1.DIRECTION.BOTTOM: case constant_1.DIRECTION.BOTTOM_LEFT: case constant_1.DIRECTION.BOTTOM_RIGHT: return BBox.fromRange(this.minX, this.minY, this.maxX, this.maxY - height); case constant_1.DIRECTION.LEFT: case constant_1.DIRECTION.LEFT_TOP: case constant_1.DIRECTION.LEFT_BOTTOM: return BBox.fromRange(this.minX + width, this.minY, this.maxX, this.maxY); default: // 其他情况不裁剪,原样返回 return this; } }; /** * 收缩形成新的 * @param gap */ BBox.prototype.shrink = function (gap) { var top = gap[0], right = gap[1], bottom = gap[2], left = gap[3]; return new BBox(this.x + left, this.y + top, this.width - left - right, this.height - top - bottom); }; /** * get the gap of two bbox, if not exceed, then 0 * @param bbox * @returns [top, right, bottom, left] */ BBox.prototype.exceed = function (bbox) { return [ Math.max(-this.minY + bbox.minY, 0), Math.max(this.maxX - bbox.maxX, 0), Math.max(this.maxY - bbox.maxY, 0), Math.max(-this.minX + bbox.minX, 0), ]; }; /** * 获取包围盒大小 * @returns 包围盒大小 */ BBox.prototype.size = function () { return this.width * this.height; }; return BBox; }()); exports.BBox = BBox; /** * 从一个 bbox 的 region 获取 bbox * @param bbox * @param region */ exports.getRegionBBox = function (bbox, region) { var start = region.start, end = region.end; return new BBox(bbox.x + bbox.width * start.x, bbox.y + bbox.height * start.y, bbox.width * Math.abs(end.x - start.x), bbox.height * Math.abs(end.y - start.y)); }; /** * 将 bbox 转换成 points * @param bbox */ function toPoints(bbox) { return [ [bbox.minX, bbox.minY], [bbox.maxX, bbox.minY], [bbox.maxX, bbox.maxY], [bbox.minX, bbox.maxY], ]; } exports.toPoints = toPoints; },{"../constant":237,"@antv/util":803}],371:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCoordinateClipCfg = exports.getAngleByPoint = exports.isPointInCoordinate = exports.getDistanceToCenter = exports.isFullCircle = exports.getXDimensionLength = void 0; var graphics_1 = require("./graphics"); var helper_1 = require("./helper"); /** * @ignore * Gets x dimension length * @param coordinate * @returns x dimension length */ function getXDimensionLength(coordinate) { if (coordinate.isPolar && !coordinate.isTransposed) { // 极坐标系下 width 为弧长 return (coordinate.endAngle - coordinate.startAngle) * coordinate.getRadius(); } // 直角坐标系 var start = coordinate.convert({ x: 0, y: 0 }); var end = coordinate.convert({ x: 1, y: 0 }); // 坐标系有可能发生 transpose 等变换,所有通过两点之间的距离进行计算 return Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2)); } exports.getXDimensionLength = getXDimensionLength; /** * @ignore * Determines whether full circle is * @param coordinate * @returns true if full circle */ function isFullCircle(coordinate) { if (coordinate.isPolar) { var startAngle = coordinate.startAngle, endAngle = coordinate.endAngle; return endAngle - startAngle === Math.PI * 2; } return false; } exports.isFullCircle = isFullCircle; /** * @ignore * 获取当前点到坐标系圆心的距离 * @param coordinate 坐标系 * @param point 当前点 * @returns distance to center */ function getDistanceToCenter(coordinate, point) { var center = coordinate.getCenter(); return Math.sqrt(Math.pow((point.x - center.x), 2) + Math.pow((point.y - center.y), 2)); } exports.getDistanceToCenter = getDistanceToCenter; /** * @ignore * 坐标点是否在坐标系中 * @param coordinate * @param point */ function isPointInCoordinate(coordinate, point) { var result = false; if (coordinate) { if (coordinate.type === 'theta') { var start = coordinate.start, end = coordinate.end; result = helper_1.isBetween(point.x, start.x, end.x) && helper_1.isBetween(point.y, start.y, end.y); } else { var invertPoint = coordinate.invert(point); result = helper_1.isBetween(invertPoint.x, 0, 1) && helper_1.isBetween(invertPoint.y, 0, 1); } } return result; } exports.isPointInCoordinate = isPointInCoordinate; /** * @ignore * 获取点到圆心的连线与水平方向的夹角 */ function getAngleByPoint(coordinate, point) { var center = coordinate.getCenter(); return Math.atan2(point.y - center.y, point.x - center.x); } exports.getAngleByPoint = getAngleByPoint; /** * @ignore * 获取同坐标系范围相同的剪切区域 * @param coordinate * @returns */ function getCoordinateClipCfg(coordinate, margin) { if (margin === void 0) { margin = 0; } var start = coordinate.start, end = coordinate.end; var width = coordinate.getWidth(); var height = coordinate.getHeight(); if (coordinate.isPolar) { var startAngle_1 = coordinate.startAngle, endAngle_1 = coordinate.endAngle; var center_1 = coordinate.getCenter(); var radius_1 = coordinate.getRadius(); return { type: 'path', startState: { path: graphics_1.getSectorPath(center_1.x, center_1.y, radius_1 + margin, startAngle_1, startAngle_1), }, endState: function (ratio) { var diff = (endAngle_1 - startAngle_1) * ratio + startAngle_1; var path = graphics_1.getSectorPath(center_1.x, center_1.y, radius_1 + margin, startAngle_1, diff); return { path: path, }; }, attrs: { path: graphics_1.getSectorPath(center_1.x, center_1.y, radius_1 + margin, startAngle_1, endAngle_1), }, }; } var endState; if (coordinate.isTransposed) { endState = { height: height + margin * 2, }; } else { endState = { width: width + margin * 2, }; } return { type: 'rect', startState: { x: start.x - margin, y: end.y - margin, width: coordinate.isTransposed ? width + margin * 2 : 0, height: coordinate.isTransposed ? 0 : height + margin * 2, }, endState: endState, attrs: { x: start.x - margin, y: end.y - margin, width: width + margin * 2, height: height + margin * 2, }, }; } exports.getCoordinateClipCfg = getCoordinateClipCfg; },{"./graphics":375,"./helper":377}],372:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTranslateDirection = exports.directionToPosition = void 0; var constant_1 = require("../constant"); /** * @ignore * 方位常量转实际的 bbox 位置大小 * @param parentBBox * @param bbox * @param direction */ function directionToPosition(parentBBox, bbox, direction) { if (direction === constant_1.DIRECTION.TOP) { return [parentBBox.minX + parentBBox.width / 2 - bbox.width / 2, parentBBox.minY]; } if (direction === constant_1.DIRECTION.BOTTOM) { return [parentBBox.minX + parentBBox.width / 2 - bbox.width / 2, parentBBox.maxY - bbox.height]; } if (direction === constant_1.DIRECTION.LEFT) { return [parentBBox.minX, parentBBox.minY + parentBBox.height / 2 - bbox.height / 2]; } if (direction === constant_1.DIRECTION.RIGHT) { return [parentBBox.maxX - bbox.width, parentBBox.minY + parentBBox.height / 2 - bbox.height / 2]; } if (direction === constant_1.DIRECTION.TOP_LEFT || direction === constant_1.DIRECTION.LEFT_TOP) { return [parentBBox.tl.x, parentBBox.tl.y]; } if (direction === constant_1.DIRECTION.TOP_RIGHT || direction === constant_1.DIRECTION.RIGHT_TOP) { return [parentBBox.tr.x - bbox.width, parentBBox.tr.y]; } if (direction === constant_1.DIRECTION.BOTTOM_LEFT || direction === constant_1.DIRECTION.LEFT_BOTTOM) { return [parentBBox.bl.x, parentBBox.bl.y - bbox.height]; } if (direction === constant_1.DIRECTION.BOTTOM_RIGHT || direction === constant_1.DIRECTION.RIGHT_BOTTOM) { return [parentBBox.br.x - bbox.width, parentBBox.br.y - bbox.height]; } return [0, 0]; } exports.directionToPosition = directionToPosition; /** * get direction after coordinate transpose * @param direction * @param coordinate * @returns direction after transpose or not */ function getTransposedDirection(direction, coordinate) { if (coordinate.isTransposed) { switch (direction) { case constant_1.DIRECTION.BOTTOM: return constant_1.DIRECTION.LEFT; case constant_1.DIRECTION.LEFT: return constant_1.DIRECTION.BOTTOM; case constant_1.DIRECTION.RIGHT: return constant_1.DIRECTION.TOP; case constant_1.DIRECTION.TOP: return constant_1.DIRECTION.RIGHT; } } return direction; } function reflectX(direct) { if (direct === constant_1.DIRECTION.LEFT) { return constant_1.DIRECTION.RIGHT; } if (direct === constant_1.DIRECTION.RIGHT) { return constant_1.DIRECTION.LEFT; } return direct; } function reflectY(direct) { if (direct === constant_1.DIRECTION.TOP) { return constant_1.DIRECTION.BOTTOM; } if (direct === constant_1.DIRECTION.BOTTOM) { return constant_1.DIRECTION.TOP; } return direct; } /** * get direction after coordinate.scale * @param direction * @param coordinate */ function getScaleDirection(direction, coordinate) { var x = coordinate.matrix[0]; var y = coordinate.matrix[4]; var d = direction; if (x < 0) { d = reflectX(d); } if (y < 0) { d = reflectY(d); } return d; } /** * * @param direction * @param coordinate */ function getReflectDirection(direction, coordinate) { var d = direction; if (coordinate.isReflect('x')) { d = reflectX(d); } if (coordinate.isReflect('y')) { d = reflectY(d); } return d; } /** * @ignore * get direction after coordinate translate * @param direction * @param coordinate */ function getTranslateDirection(direction, coordinate) { var d = direction; d = getTransposedDirection(d, coordinate); d = getScaleDirection(d, coordinate); d = getReflectDirection(d, coordinate); return d; } exports.getTranslateDirection = getTranslateDirection; },{"../constant":237}],373:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.removeDom = exports.getChartSize = void 0; var constant_1 = require("../constant"); /** * get the element's bounding size * @param ele dom element * @returns the element width and height */ function getElementSize(ele) { var style = getComputedStyle(ele); return { width: (ele.clientWidth || parseInt(style.width, 10)) - parseInt(style.paddingLeft, 10) - parseInt(style.paddingRight, 10), height: (ele.clientHeight || parseInt(style.height, 10)) - parseInt(style.paddingTop, 10) - parseInt(style.paddingBottom, 10), }; } /** * is value a valid number * @param v the input value * @returns whether it is a number */ function isNumber(v) { return typeof v === 'number' && !isNaN(v); } /** * @ignore * calculate the chart size * @param ele DOM element * @param autoFit should auto fit * @param width chart width which is set by user * @param height chart height which is set by user * @returns the chart width and height */ function getChartSize(ele, autoFit, width, height) { var w = width; var h = height; if (autoFit) { var size = getElementSize(ele); w = size.width ? size.width : w; h = size.height ? size.height : h; } return { width: Math.max(isNumber(w) ? w : constant_1.MIN_CHART_WIDTH, constant_1.MIN_CHART_WIDTH), height: Math.max(isNumber(h) ? h : constant_1.MIN_CHART_HEIGHT, constant_1.MIN_CHART_HEIGHT), }; } exports.getChartSize = getChartSize; /** * @ignore * remove html element from its parent * @param dom */ function removeDom(dom) { var parent = dom.parentNode; if (parent) { parent.removeChild(dom); } } exports.removeDom = removeDom; /** @ignore */ var dom_util_1 = require("@antv/dom-util"); Object.defineProperty(exports, "createDom", { enumerable: true, get: function () { return dom_util_1.createDom; } }); Object.defineProperty(exports, "modifyCSS", { enumerable: true, get: function () { return dom_util_1.modifyCSS; } }); },{"../constant":237,"@antv/dom-util":92}],374:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAnglePoint = exports.getFactTitleConfig = void 0; var constant_1 = require("../constant"); /** * @ignore * 获取 facet title 的最佳默认配置,防止 */ function getFactTitleConfig(direction) { if ([constant_1.DIRECTION.TOP, constant_1.DIRECTION.BOTTOM].includes(direction)) { return { offsetX: 0, offsetY: direction === constant_1.DIRECTION.TOP ? -8 : 8, style: { textAlign: 'center', textBaseline: direction === constant_1.DIRECTION.TOP ? 'bottom' : 'top', }, }; } if ([constant_1.DIRECTION.LEFT, constant_1.DIRECTION.RIGHT].includes(direction)) { return { offsetX: direction === constant_1.DIRECTION.LEFT ? -8 : 8, offsetY: 0, style: { textAlign: direction === constant_1.DIRECTION.LEFT ? 'right' : 'left', textBaseline: 'middle', rotate: Math.PI / 2, }, }; } return {}; } exports.getFactTitleConfig = getFactTitleConfig; /** * @ignore * 根据角度,获取 ○ 上的点 * @param center * @param r * @param angle */ function getAnglePoint(center, r, angle) { return { x: center.x + r * Math.cos(angle), y: center.y + r * Math.sin(angle), }; } exports.getAnglePoint = getAnglePoint; },{"../constant":237}],375:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getReplaceAttrs = exports.getPolygonCentroid = exports.getAngle = exports.getArcPath = exports.getSectorPath = exports.polarToCartesian = void 0; var util_1 = require("@antv/util"); // 获取图形的包围盒 function getPointsBox(points) { if (util_1.isEmpty(points)) { return null; } var minX = points[0].x; var maxX = points[0].x; var minY = points[0].y; var maxY = points[0].y; util_1.each(points, function (point) { minX = minX > point.x ? point.x : minX; maxX = maxX < point.x ? point.x : maxX; minY = minY > point.y ? point.y : minY; maxY = maxY < point.y ? point.y : maxY; }); return { minX: minX, maxX: maxX, minY: minY, maxY: maxY, centerX: (minX + maxX) / 2, centerY: (minY + maxY) / 2, }; } /** * @ignore * 根据弧度计算极坐标系下的坐标点 * @param centerX * @param centerY * @param radius * @param angleInRadian * @returns */ function polarToCartesian(centerX, centerY, radius, angleInRadian) { return { x: centerX + radius * Math.cos(angleInRadian), y: centerY + radius * Math.sin(angleInRadian), }; } exports.polarToCartesian = polarToCartesian; /** * @ignore * 根据起始角度计算绘制扇形的 path * @param centerX * @param centerY * @param radius * @param startAngleInRadian * @param endAngleInRadian * @returns */ function getSectorPath(centerX, centerY, radius, startAngleInRadian, endAngleInRadian, innerRadius) { if (innerRadius === void 0) { innerRadius = 0; } var start = polarToCartesian(centerX, centerY, radius, startAngleInRadian); var end = polarToCartesian(centerX, centerY, radius, endAngleInRadian); var innerStart = polarToCartesian(centerX, centerY, innerRadius, startAngleInRadian); var innerEnd = polarToCartesian(centerX, centerY, innerRadius, endAngleInRadian); if (endAngleInRadian - startAngleInRadian === Math.PI * 2) { // 整个圆是分割成两个圆 var middlePoint = polarToCartesian(centerX, centerY, radius, startAngleInRadian + Math.PI); var innerMiddlePoint = polarToCartesian(centerX, centerY, innerRadius, startAngleInRadian + Math.PI); var circlePathCommands = [ ['M', start.x, start.y], ['A', radius, radius, 0, 1, 1, middlePoint.x, middlePoint.y], ['A', radius, radius, 0, 1, 1, end.x, end.y], ['M', innerStart.x, innerStart.y], ]; if (innerRadius) { circlePathCommands.push(['A', innerRadius, innerRadius, 0, 1, 0, innerMiddlePoint.x, innerMiddlePoint.y]); circlePathCommands.push(['A', innerRadius, innerRadius, 0, 1, 0, innerEnd.x, innerEnd.y]); } circlePathCommands.push(['M', start.x, start.y]); circlePathCommands.push(['Z']); return circlePathCommands; } var arcSweep = endAngleInRadian - startAngleInRadian <= Math.PI ? 0 : 1; var sectorPathCommands = [ ['M', start.x, start.y], ['A', radius, radius, 0, arcSweep, 1, end.x, end.y], ['L', innerEnd.x, innerEnd.y], ]; if (innerRadius) { sectorPathCommands.push(['A', innerRadius, innerRadius, 0, arcSweep, 0, innerStart.x, innerStart.y]); } sectorPathCommands.push(['L', start.x, start.y]); sectorPathCommands.push(['Z']); return sectorPathCommands; } exports.getSectorPath = getSectorPath; /** * @ignore * Gets arc path * @param centerX * @param centerY * @param radius * @param startAngleInRadian * @param endAngleInRadian * @returns */ function getArcPath(centerX, centerY, radius, startAngleInRadian, endAngleInRadian) { var start = polarToCartesian(centerX, centerY, radius, startAngleInRadian); var end = polarToCartesian(centerX, centerY, radius, endAngleInRadian); if (util_1.isNumberEqual(endAngleInRadian - startAngleInRadian, Math.PI * 2)) { var middlePoint = polarToCartesian(centerX, centerY, radius, startAngleInRadian + Math.PI); return [ ['M', start.x, start.y], ['A', radius, radius, 0, 1, 1, middlePoint.x, middlePoint.y], ['A', radius, radius, 0, 1, 1, start.x, start.y], ['A', radius, radius, 0, 1, 0, middlePoint.x, middlePoint.y], ['A', radius, radius, 0, 1, 0, start.x, start.y], ['Z'], ]; } var arcSweep = endAngleInRadian - startAngleInRadian <= Math.PI ? 0 : 1; return [ ['M', start.x, start.y], ['A', radius, radius, 0, arcSweep, 1, end.x, end.y], ]; } exports.getArcPath = getArcPath; /** * @ignore * 从数据模型中的 points 换算角度 * @param shapeModel * @param coordinate * @returns */ function getAngle(shapeModel, coordinate) { var points = shapeModel.points; var box = getPointsBox(points); var endAngle; var startAngle; var coordStartAngle = coordinate.startAngle, coordEndAngle = coordinate.endAngle; var diffAngle = coordEndAngle - coordStartAngle; if (coordinate.isTransposed) { endAngle = box.maxY * diffAngle; startAngle = box.minY * diffAngle; } else { endAngle = box.maxX * diffAngle; startAngle = box.minX * diffAngle; } endAngle += coordStartAngle; startAngle += coordStartAngle; return { startAngle: startAngle, endAngle: endAngle, }; } exports.getAngle = getAngle; /** * @ignore * 计算多边形重心: https://en.wikipedia.org/wiki/Centroid#Of_a_polygon */ function getPolygonCentroid(xs, ys) { if (util_1.isNumber(xs) && util_1.isNumber(ys)) { // 普通色块图,xs 和 ys 是数值 return [xs, ys]; } var i = -1; var x = 0; var y = 0; var former; var current = xs.length - 1; var diff; var k = 0; while (++i < xs.length) { former = current; current = i; k += diff = xs[former] * ys[current] - xs[current] * ys[former]; x += (xs[former] + xs[current]) * diff; y += (ys[former] + ys[current]) * diff; } k *= 3; return [x / k, y / k]; } exports.getPolygonCentroid = getPolygonCentroid; /** * @ignore * 获取需要替换的属性,如果原先图形元素存在,而新图形不存在,则设置 undefined */ function getReplaceAttrs(sourceShape, targetShape) { var originAttrs = sourceShape.attr(); var newAttrs = targetShape.attr(); util_1.each(originAttrs, function (v, k) { if (newAttrs[k] === undefined) { newAttrs[k] = undefined; } }); return newAttrs; } exports.getReplaceAttrs = getReplaceAttrs; },{"@antv/util":803}],376:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.showGrid = exports.getCircleGridItems = exports.getLineGridItems = exports.getGridThemeCfg = void 0; var util_1 = require("@antv/util"); /** * @ignore * get the grid theme by type * @param theme * @param direction * @returns theme object */ function getGridThemeCfg(theme, direction) { return util_1.get(theme, ['components', 'axis', direction, 'grid'], {}); } exports.getGridThemeCfg = getGridThemeCfg; /** * @ignore * get axis grid items * @param coordinate * @param scale * @param dim * @return items */ function getLineGridItems(coordinate, scale, dim, alignTick) { var items = []; var ticks = scale.getTicks(); if (coordinate.isPolar) { // 补全 ticks ticks.push({ value: 1, text: '', tickValue: '', }); } ticks.reduce(function (preTick, currentTick, currentIndex) { var currentValue = currentTick.value; if (alignTick) { items.push({ points: [ coordinate.convert(dim === 'y' ? { x: 0, y: currentValue } : { x: currentValue, y: 0 }), coordinate.convert(dim === 'y' ? { x: 1, y: currentValue } : { x: currentValue, y: 1 }), ], }); } else { if (currentIndex) { var preValue = preTick.value; var middleValue = (preValue + currentValue) / 2; items.push({ points: [ coordinate.convert(dim === 'y' ? { x: 0, y: middleValue } : { x: middleValue, y: 0 }), coordinate.convert(dim === 'y' ? { x: 1, y: middleValue } : { x: middleValue, y: 1 }), ], }); } } return currentTick; }, ticks[0]); return items; } exports.getLineGridItems = getLineGridItems; /** * @ignore * get * @param coordinate * @param xScale * @param yScale * @param dim * @returns items */ function getCircleGridItems(coordinate, xScale, yScale, alignTick, dim) { var count = xScale.values.length; var items = []; var ticks = yScale.getTicks(); ticks.reduce(function (preTick, currentTick) { var preValue = preTick ? preTick.value : currentTick.value; // 只有一项数据时取当前值 var currentValue = currentTick.value; var middleValue = (preValue + currentValue) / 2; if (dim === 'x') { // 如果是 x 轴作为半径轴,那么只需要取圆弧收尾两个即可 items.push({ points: [ coordinate.convert({ x: alignTick ? currentValue : middleValue, y: 0, }), coordinate.convert({ x: alignTick ? currentValue : middleValue, y: 1, }), ], }); } else { items.push({ points: util_1.map(Array(count + 1), function (__, idx) { return coordinate.convert({ x: idx / count, y: alignTick ? currentValue : middleValue, }); }), }); } return currentTick; }, ticks[0]); return items; } exports.getCircleGridItems = getCircleGridItems; /** * @ignore * show grid or not * @param axisTheme * @param axisOption */ function showGrid(axisTheme, axisOption) { var userGrid = util_1.get(axisOption, 'grid'); if (userGrid === null) { return false; } var themeGrid = util_1.get(axisTheme, 'grid'); return !(userGrid === undefined && themeGrid === null); } exports.showGrid = showGrid; },{"@antv/util":803}],377:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.uniq = exports.omit = exports.padEnd = exports.isBetween = void 0; var util_1 = require("@antv/util"); /** * @ignore * Determines whether between is * @param value * @param start * @param end * @returns true if between */ function isBetween(value, start, end) { var min = Math.min(start, end); var max = Math.max(start, end); return value >= min && value <= max; } exports.isBetween = isBetween; /** * @ignore * pads the current string/array with a given value (repeated, if needed) so that the resulting reaches a given length. * The padding is applied from the end of the current value. * * @param source * @param targetLength * @param padValue * @returns */ function padEnd(source, targetLength, padValue) { if (util_1.isString(source)) { return source.padEnd(targetLength, padValue); } else if (util_1.isArray(source)) { var sourceLength = source.length; if (sourceLength < targetLength) { var diff = targetLength - sourceLength; for (var i = 0; i < diff; i++) { source.push(padValue); } } } return source; } exports.padEnd = padEnd; /** * @ignore * omit keys of an object. * @param obj * @param keys */ function omit(obj, keys) { keys.forEach(function (key) { delete obj[key]; }); return obj; } exports.omit = omit; /** * @ignore * @param sourceArray * @param targetArray * @param map */ function uniq(sourceArray, targetArray, map) { if (targetArray === void 0) { targetArray = []; } if (map === void 0) { map = {}; } for (var _i = 0, sourceArray_1 = sourceArray; _i < sourceArray_1.length; _i++) { var source = sourceArray_1[_i]; if (!map[source]) { targetArray.push(source); map[source] = true; } } return targetArray; } exports.uniq = uniq; },{"@antv/util":803}],378:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCustomLegendItems = exports.getLegendItems = exports.getLegendLayout = void 0; var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var attr_1 = require("./attr"); var marker_1 = require("./marker"); function setMarkerSymbol(marker) { var symbol = marker.symbol; if (util_1.isString(symbol) && marker_1.MarkerSymbols[symbol]) { marker.symbol = marker_1.MarkerSymbols[symbol]; } } /** * @ignore * get the legend layout from direction * @param direction * @returns layout 'horizontal' | 'vertical' */ function getLegendLayout(direction) { return direction.startsWith(constant_1.DIRECTION.LEFT) || direction.startsWith(constant_1.DIRECTION.RIGHT) ? 'vertical' : 'horizontal'; } exports.getLegendLayout = getLegendLayout; /** * @ignore * get the legend items * @param view * @param geometry * @param attr * @param themeMarker * @param userMarker * @returns legend items */ function getLegendItems(view, geometry, attr, themeMarker, userMarker) { var scale = attr.getScale(attr.type); if (scale.isCategory) { var field_1 = scale.field; var colorAttr_1 = geometry.getAttribute('color'); var shapeAttr_1 = geometry.getAttribute('shape'); var defaultColor_1 = view.getTheme().defaultColor; var isInPolar_1 = geometry.coordinate.isPolar; return scale.getTicks().map(function (tick) { var _a; var text = tick.text, scaleValue = tick.value; var name = text; var value = scale.invert(scaleValue); // 通过过滤图例项的数据,来看是否 unchecked var unchecked = view.filterFieldData(field_1, [(_a = {}, _a[field_1] = value, _a)]).length === 0; // @ts-ignore var color = attr_1.getMappingValue(colorAttr_1, value, defaultColor_1); var shape = attr_1.getMappingValue(shapeAttr_1, value, 'point'); var marker = geometry.getShapeMarker(shape, { color: color, isInPolar: isInPolar_1, }); // the marker configure order should be ensure marker = util_1.deepMix({}, themeMarker, marker, userMarker); setMarkerSymbol(marker); return { id: value, name: name, value: value, marker: marker, unchecked: unchecked }; }); } return []; } exports.getLegendItems = getLegendItems; /** * @ignore * custom legend 的 items 获取 * @param themeMarker * @param userMarker * @param customItems */ function getCustomLegendItems(themeMarker, userMarker, customItems) { // 如果有自定义的 item,那么就直接使用,并合并主题的 marker 配置 return customItems.map(function (item) { var marker = util_1.deepMix({}, themeMarker, userMarker, item.marker); setMarkerSymbol(marker); item.marker = marker; return item; }); } exports.getCustomLegendItems = getCustomLegendItems; },{"../constant":237,"./attr":368,"./marker":379,"@antv/util":803}],379:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MarkerSymbols = void 0; /** @ignore */ exports.MarkerSymbols = { hexagon: function (x, y, r) { var diffX = (r / 2) * Math.sqrt(3); return [ ['M', x, y - r], ['L', x + diffX, y - r / 2], ['L', x + diffX, y + r / 2], ['L', x, y + r], ['L', x - diffX, y + r / 2], ['L', x - diffX, y - r / 2], ['Z'], ]; }, bowtie: function (x, y, r) { var diffY = r - 1.5; return [['M', x - r, y - diffY], ['L', x + r, y + diffY], ['L', x + r, y - diffY], ['L', x - r, y + diffY], ['Z']]; }, cross: function (x, y, r) { return [ ['M', x - r, y - r], ['L', x + r, y + r], ['M', x + r, y - r], ['L', x - r, y + r], ]; }, tick: function (x, y, r) { return [ ['M', x - r / 2, y - r], ['L', x + r / 2, y - r], ['M', x, y - r], ['L', x, y + r], ['M', x - r / 2, y + r], ['L', x + r / 2, y + r], ]; }, plus: function (x, y, r) { return [ ['M', x - r, y], ['L', x + r, y], ['M', x, y - r], ['L', x, y + r], ]; }, hyphen: function (x, y, r) { return [ ['M', x - r, y], ['L', x + r, y], ]; }, line: function (x, y, r) { return [ ['M', x, y - r], ['L', x, y + r], ]; }, }; },{}],380:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parsePadding = exports.isAutoPadding = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); /** * @ignore * 是否是自动 padding * @param padding */ function isAutoPadding(padding) { return !util_1.isNumber(padding) && !util_1.isArray(padding); } exports.isAutoPadding = isAutoPadding; /** * @ignore * padding 的解析逻辑 * @param padding * @return [ top, right, bottom, left ] */ function parsePadding(padding) { if (padding === void 0) { padding = 0; } var paddingArray = util_1.isArray(padding) ? padding : [padding]; switch (paddingArray.length) { case 0: paddingArray = [0, 0, 0, 0]; break; case 1: paddingArray = new Array(4).fill(paddingArray[0]); break; case 2: paddingArray = tslib_1.__spreadArrays(paddingArray, paddingArray); break; case 3: paddingArray = tslib_1.__spreadArrays(paddingArray, [paddingArray[1]]); break; default: // 其他情况,只去四个 paddingArray = paddingArray.slice(0, 4); break; } return paddingArray; } exports.parsePadding = parsePadding; },{"@antv/util":803,"tslib":385}],381:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getName = exports.syncScale = exports.createScaleByField = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../dependents"); var dateRegex = /^(?:(?!0000)[0-9]{4}([-/.]+)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]+)0?2\2(?:29))(\s+([01]|([01][0-9]|2[0-3])):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9]))?$/; /** * 获取字段对应数据的类型 * @param field 数据字段名 * @param data 数据源 * @returns default type 返回对应的数据类型 */ function getDefaultType(value) { var type = 'linear'; if (dateRegex.test(value)) { type = 'time'; } else if (util_1.isString(value)) { type = 'cat'; } return type; } /** * @ignore * 为指定的 `field` 字段数据创建 scale * @param field 字段名 * @param [data] 数据集,可为空 * @param [scaleDef] 列定义,可为空 * @returns scale 返回创建的 Scale 实例 */ function createScaleByField(field, data, scaleDef) { var validData = data || []; if (util_1.isNumber(field) || (util_1.isNil(util_1.firstValue(validData, field)) && util_1.isEmpty(scaleDef))) { var Identity = dependents_1.getScale('identity'); return new Identity({ field: field.toString(), values: [field], }); } var values = util_1.valuesOfKey(validData, field); // 如果已经定义过这个度量 var type = util_1.get(scaleDef, 'type', getDefaultType(values[0])); var ScaleCtor = dependents_1.getScale(type); return new ScaleCtor(tslib_1.__assign({ field: field, values: values }, scaleDef)); } exports.createScaleByField = createScaleByField; /** * @ignore * 同步 scale * @todo 是否可以通过 scale.update() 方法进行更新 * @param scale 需要同步的 scale 实例 * @param newScale 同步源 Scale */ function syncScale(scale, newScale) { if (scale.type !== 'identity' && newScale.type !== 'identity') { var obj = {}; for (var k in newScale) { if (Object.prototype.hasOwnProperty.call(newScale, k)) { obj[k] = newScale[k]; } } scale.change(obj); } } exports.syncScale = syncScale; /** * @ignore * get the scale name, if alias exist, return alias, or else field * @param scale * @returns the name of field */ function getName(scale) { return scale.alias || scale.field; } exports.getName = getName; },{"../dependents":239,"@antv/util":803,"tslib":385}],382:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createThemeByStylesheet = void 0; var tslib_1 = require("tslib"); var TOOLTIP_CSS_CONST = tslib_1.__importStar(require("@antv/component/lib/tooltip/css-const")); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var graphics_1 = require("../util/graphics"); /** * 根据主题样式表生成主题结构 * @param styleSheet 主题样式表 */ function createThemeByStylesheet(styleSheet) { var _a; var shapeStyles = { point: { default: { fill: styleSheet.pointFillColor, r: styleSheet.pointSize, stroke: styleSheet.pointBorderColor, lineWidth: styleSheet.pointBorder, fillOpacity: styleSheet.pointFillOpacity, }, active: { stroke: styleSheet.pointActiveBorderColor, lineWidth: styleSheet.pointActiveBorder, }, selected: { stroke: styleSheet.pointSelectedBorderColor, lineWidth: styleSheet.pointSelectedBorder, }, inactive: { fillOpacity: styleSheet.pointInactiveFillOpacity, strokeOpacity: styleSheet.pointInactiveBorderOpacity, }, }, hollowPoint: { default: { fill: styleSheet.hollowPointFillColor, lineWidth: styleSheet.hollowPointBorder, stroke: styleSheet.hollowPointBorderColor, strokeOpacity: styleSheet.hollowPointBorderOpacity, r: styleSheet.hollowPointSize, }, active: { stroke: styleSheet.hollowPointActiveBorderColor, strokeOpacity: styleSheet.hollowPointActiveBorderOpacity, }, selected: { lineWidth: styleSheet.hollowPointSelectedBorder, stroke: styleSheet.hollowPointSelectedBorderColor, strokeOpacity: styleSheet.hollowPointSelectedBorderOpacity, }, inactive: { strokeOpacity: styleSheet.hollowPointInactiveBorderOpacity, }, }, area: { default: { fill: styleSheet.areaFillColor, fillOpacity: styleSheet.areaFillOpacity, stroke: null, }, active: { fillOpacity: styleSheet.areaActiveFillOpacity, }, selected: { fillOpacity: styleSheet.areaSelectedFillOpacity, }, inactive: { fillOpacity: styleSheet.areaInactiveFillOpacity, }, }, hollowArea: { default: { fill: null, stroke: styleSheet.hollowAreaBorderColor, lineWidth: styleSheet.hollowAreaBorder, strokeOpacity: styleSheet.hollowAreaBorderOpacity, }, active: { fill: null, lineWidth: styleSheet.hollowAreaActiveBorder, }, selected: { fill: null, lineWidth: styleSheet.hollowAreaSelectedBorder, }, inactive: { strokeOpacity: styleSheet.hollowAreaInactiveBorderOpacity, }, }, interval: { default: { fill: styleSheet.intervalFillColor, fillOpacity: styleSheet.intervalFillOpacity, }, active: { stroke: styleSheet.intervalActiveBorderColor, lineWidth: styleSheet.intervalActiveBorder, }, selected: { stroke: styleSheet.intervalSelectedBorderColor, lineWidth: styleSheet.intervalSelectedBorder, }, inactive: { fillOpacity: styleSheet.intervalInactiveFillOpacity, strokeOpacity: styleSheet.intervalInactiveBorderOpacity, }, }, hollowInterval: { default: { fill: styleSheet.hollowIntervalFillColor, stroke: styleSheet.hollowIntervalBorderColor, lineWidth: styleSheet.hollowIntervalBorder, strokeOpacity: styleSheet.hollowIntervalBorderOpacity, }, active: { stroke: styleSheet.hollowIntervalActiveBorderColor, lineWidth: styleSheet.hollowIntervalActiveBorder, strokeOpacity: styleSheet.hollowIntervalActiveBorderOpacity, }, selected: { stroke: styleSheet.hollowIntervalSelectedBorderColor, lineWidth: styleSheet.hollowIntervalSelectedBorder, strokeOpacity: styleSheet.hollowIntervalSelectedBorderOpacity, }, inactive: { stroke: styleSheet.hollowIntervalInactiveBorderColor, lineWidth: styleSheet.hollowIntervalInactiveBorder, strokeOpacity: styleSheet.hollowIntervalInactiveBorderOpacity, }, }, line: { default: { stroke: styleSheet.lineBorderColor, lineWidth: styleSheet.lineBorder, strokeOpacity: styleSheet.lineBorderOpacity, fill: null, lineAppendWidth: 10, }, active: { lineWidth: styleSheet.lineActiveBorder, }, selected: { lineWidth: styleSheet.lineSelectedBorder, }, inactive: { strokeOpacity: styleSheet.lineInactiveBorderOpacity, }, }, }; var axisStyles = { title: { autoRotate: true, position: 'center', style: { fill: styleSheet.axisTitleTextFillColor, fontSize: styleSheet.axisTitleTextFontSize, lineHeight: styleSheet.axisTitleTextLineHeight, textBaseline: 'middle', fontFamily: styleSheet.fontFamily, }, }, label: { autoRotate: true, autoEllipsis: true, autoHide: true, offset: 16, style: { fill: styleSheet.axisLabelFillColor, fontSize: styleSheet.axisLabelFontSize, lineHeight: styleSheet.axisLabelLineHeight, textBaseline: 'middle', fontFamily: styleSheet.fontFamily, }, }, line: { style: { lineWidth: styleSheet.axisLineBorder, stroke: styleSheet.axisLineBorderColor, }, }, tickLine: { style: { lineWidth: styleSheet.axisTickLineBorder, stroke: styleSheet.axisTickLineBorderColor, }, alignTick: true, length: styleSheet.axisTickLineLength, }, subTickLine: null, animate: true, }; var axisGridStyles = { line: { type: 'line', style: { stroke: styleSheet.axisGridBorderColor, lineWidth: styleSheet.axisGridBorder, lineDash: styleSheet.axisGridLineDash, }, }, alignTick: true, animate: true, }; var legendStyles = { title: null, marker: { symbol: 'circle', style: { r: styleSheet.legendCircleMarkerSize, fill: styleSheet.legendMarkerColor, }, }, itemName: { spacing: 5, style: { fill: styleSheet.legendItemNameFillColor, fontFamily: styleSheet.fontFamily, fontSize: styleSheet.legendItemNameFontSize, lineHeight: styleSheet.legendItemNameLineHeight, fontWeight: styleSheet.legendItemNameFontWeight, textAlign: 'start', textBaseline: 'middle', }, }, flipPage: true, animate: false, maxItemWidth: 0.2, }; return { background: styleSheet.backgroundColor, defaultColor: styleSheet.brandColor, padding: 'auto', fontFamily: styleSheet.fontFamily, /** 一般柱状图宽度占比 */ columnWidthRatio: 1 / 2, /** 柱状图最大宽度 */ maxColumnWidth: null, /** 柱状图最小宽度 */ minColumnWidth: null, /** 玫瑰图占比 */ roseWidthRatio: 0.9999999, /** 多层饼图/环图占比 */ multiplePieWidthRatio: 1 / 1.3, colors10: styleSheet.paletteQualitative10, colors20: styleSheet.paletteQualitative20, shapes: { point: [ 'hollow-circle', 'hollow-square', 'hollow-bowtie', 'hollow-diamond', 'hollow-hexagon', 'hollow-triangle', 'hollow-triangle-down', 'circle', 'square', 'bowtie', 'diamond', 'hexagon', 'triangle', 'triangle-down', 'cross', 'tick', 'plus', 'hyphen', 'line', ], line: ['line', 'dash', 'dot', 'smooth'], area: ['area', 'smooth', 'line', 'smooth-line'], interval: ['rect', 'hollow-rect', 'line', 'tick'], }, sizes: [1, 10], geometries: { interval: { rect: { default: { style: shapeStyles.interval.default, }, active: { style: shapeStyles.interval.active, }, inactive: { style: shapeStyles.interval.inactive, }, selected: { style: function (element) { var coordinate = element.geometry.coordinate; if (coordinate.isPolar && coordinate.isTransposed) { var _a = graphics_1.getAngle(element.getModel(), coordinate), startAngle = _a.startAngle, endAngle = _a.endAngle; var middleAngle = (startAngle + endAngle) / 2; var r = 7.5; var x = r * Math.cos(middleAngle); var y = r * Math.sin(middleAngle); return { matrix: matrix_util_1.ext.transform(null, [['t', x, y]]), }; } return shapeStyles.interval.selected; }, }, }, 'hollow-rect': { default: { style: shapeStyles.hollowInterval.default, }, active: { style: shapeStyles.hollowInterval.active, }, inactive: { style: shapeStyles.hollowInterval.inactive, }, selected: { style: shapeStyles.hollowInterval.selected, }, }, line: { default: { style: shapeStyles.hollowInterval.default, }, active: { style: shapeStyles.hollowInterval.active, }, inactive: { style: shapeStyles.hollowInterval.inactive, }, selected: { style: shapeStyles.hollowInterval.selected, }, }, tick: { default: { style: shapeStyles.hollowInterval.default, }, active: { style: shapeStyles.hollowInterval.active, }, inactive: { style: shapeStyles.hollowInterval.inactive, }, selected: { style: shapeStyles.hollowInterval.selected, }, }, funnel: { default: { style: shapeStyles.interval.default, }, active: { style: shapeStyles.interval.active, }, inactive: { style: shapeStyles.interval.inactive, }, selected: { style: shapeStyles.interval.selected, }, }, pyramid: { default: { style: shapeStyles.interval.default, }, active: { style: shapeStyles.interval.active, }, inactive: { style: shapeStyles.interval.inactive, }, selected: { style: shapeStyles.interval.selected, }, }, }, line: { line: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, dot: { default: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.default), { lineDash: [1, 1] }), }, active: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.active), { lineDash: [1, 1] }), }, inactive: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.inactive), { lineDash: [1, 1] }), }, selected: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.selected), { lineDash: [1, 1] }), }, }, dash: { default: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.default), { lineDash: [5.5, 1] }), }, active: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.active), { lineDash: [5.5, 1] }), }, inactive: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.inactive), { lineDash: [5.5, 1] }), }, selected: { style: tslib_1.__assign(tslib_1.__assign({}, shapeStyles.line.selected), { lineDash: [5.5, 1] }), }, }, smooth: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, hv: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, vh: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, hvh: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, vhv: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, }, polygon: { polygon: { default: { style: shapeStyles.interval.default, }, active: { style: shapeStyles.interval.active, }, inactive: { style: shapeStyles.interval.inactive, }, selected: { style: shapeStyles.interval.selected, }, }, }, point: { circle: { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, square: { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, bowtie: { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, diamond: { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, hexagon: { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, triangle: { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, 'triangle-down': { default: { style: shapeStyles.point.default, }, active: { style: shapeStyles.point.active, }, inactive: { style: shapeStyles.point.inactive, }, selected: { style: shapeStyles.point.selected, }, }, 'hollow-circle': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, 'hollow-square': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, 'hollow-bowtie': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, 'hollow-diamond': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, 'hollow-hexagon': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, 'hollow-triangle': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, 'hollow-triangle-down': { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, cross: { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, tick: { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, plus: { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, hyphen: { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, line: { default: { style: shapeStyles.hollowPoint.default, }, active: { style: shapeStyles.hollowPoint.active, }, inactive: { style: shapeStyles.hollowPoint.inactive, }, selected: { style: shapeStyles.hollowPoint.selected, }, }, }, area: { area: { default: { style: shapeStyles.area.default, }, active: { style: shapeStyles.area.active, }, inactive: { style: shapeStyles.area.inactive, }, selected: { style: shapeStyles.area.selected, }, }, smooth: { default: { style: shapeStyles.area.default, }, active: { style: shapeStyles.area.active, }, inactive: { style: shapeStyles.area.inactive, }, selected: { style: shapeStyles.area.selected, }, }, line: { default: { style: shapeStyles.hollowArea.default, }, active: { style: shapeStyles.hollowArea.active, }, inactive: { style: shapeStyles.hollowArea.inactive, }, selected: { style: shapeStyles.hollowArea.selected, }, }, 'smooth-line': { default: { style: shapeStyles.hollowArea.default, }, active: { style: shapeStyles.hollowArea.active, }, inactive: { style: shapeStyles.hollowArea.inactive, }, selected: { style: shapeStyles.hollowArea.selected, }, }, }, schema: { candle: { default: { style: shapeStyles.hollowInterval.default, }, active: { style: shapeStyles.hollowInterval.active, }, inactive: { style: shapeStyles.hollowInterval.inactive, }, selected: { style: shapeStyles.hollowInterval.selected, }, }, box: { default: { style: shapeStyles.hollowInterval.default, }, active: { style: shapeStyles.hollowInterval.active, }, inactive: { style: shapeStyles.hollowInterval.inactive, }, selected: { style: shapeStyles.hollowInterval.selected, }, }, }, edge: { line: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, vhv: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, smooth: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, arc: { default: { style: shapeStyles.line.default, }, active: { style: shapeStyles.line.active, }, inactive: { style: shapeStyles.line.inactive, }, selected: { style: shapeStyles.line.selected, }, }, }, }, components: { axis: { top: util_1.deepMix({}, axisStyles, { position: 'top', grid: null, title: null, verticalLimitLength: 1 / 2, }), bottom: util_1.deepMix({}, axisStyles, { position: 'bottom', grid: null, title: null, verticalLimitLength: 1 / 2, }), left: util_1.deepMix({}, axisStyles, { position: 'left', label: { offset: 8, }, title: null, line: null, tickLine: null, grid: axisGridStyles, verticalLimitLength: 1 / 3, }), right: util_1.deepMix({}, axisStyles, { position: 'right', label: { offset: 8, }, title: null, line: null, tickLine: null, grid: axisGridStyles, verticalLimitLength: 1 / 3, }), circle: util_1.deepMix({}, axisStyles, { title: null, label: { offset: 8, }, grid: util_1.deepMix({}, axisGridStyles, { line: { type: 'line' } }), }), radius: util_1.deepMix({}, axisStyles, { title: null, label: { offset: 8, }, grid: util_1.deepMix({}, axisGridStyles, { line: { type: 'circle' } }), }), }, legend: { right: util_1.deepMix({}, legendStyles, { layout: 'vertical', }), left: util_1.deepMix({}, legendStyles, { layout: 'vertical', }), top: util_1.deepMix({}, legendStyles, { layout: 'horizontal', }), bottom: util_1.deepMix({}, legendStyles, { layout: 'horizontal', }), continuous: { title: null, background: null, track: {}, rail: { type: 'color', size: styleSheet.sliderRailHeight, defaultLength: styleSheet.sliderRailWidth, style: { fill: styleSheet.sliderRailFillColor, stroke: styleSheet.sliderRailBorderColor, lineWidth: styleSheet.sliderRailBorder, }, }, label: { align: 'rail', spacing: 4, formatter: null, style: { fill: styleSheet.sliderLabelTextFillColor, fontSize: styleSheet.sliderLabelTextFontSize, lineHeight: styleSheet.sliderLabelTextLineHeight, textBaseline: 'middle', fontFamily: styleSheet.fontFamily, }, }, handler: { size: styleSheet.sliderHandlerWidth, style: { fill: styleSheet.sliderHandlerFillColor, stroke: styleSheet.sliderHandlerBorderColor, }, }, slidable: true, }, // 图例与四条边之间的间距 margin: [0, 0, 0, 0], }, tooltip: { showContent: true, follow: true, showCrosshairs: false, showMarkers: true, shared: false, enterable: false, position: 'auto', marker: { symbol: 'circle', stroke: '#fff', shadowBlur: 10, shadowOffsetX: 0, shadowOffSetY: 0, shadowColor: 'rgba(0,0,0,0.09)', lineWidth: 2, r: 4, }, crosshairs: { line: { style: { stroke: styleSheet.tooltipCrosshairsBorderColor, lineWidth: styleSheet.tooltipCrosshairsBorder, }, }, text: null, textBackground: { padding: 2, style: { fill: 'rgba(0, 0, 0, 0.25)', lineWidth: 0, stroke: null, }, }, follow: false, }, // tooltip dom 样式 domStyles: (_a = {}, _a["" + TOOLTIP_CSS_CONST.CONTAINER_CLASS] = { position: 'absolute', visibility: 'hidden', zIndex: 8, transition: 'left 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s, top 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s', backgroundColor: styleSheet.tooltipContainerFillColor, opacity: styleSheet.tooltipContainerFillOpacity, boxShadow: styleSheet.tooltipContainerShadow, borderRadius: styleSheet.tooltipContainerBorderRadius + "px", color: styleSheet.tooltipTextFillColor, fontSize: styleSheet.tooltipTextFontSize + "px", fontFamily: styleSheet.fontFamily, lineHeight: styleSheet.tooltipTextLineHeight + "px", padding: '0 12px 0 12px', }, _a["" + TOOLTIP_CSS_CONST.TITLE_CLASS] = { marginBottom: '12px', marginTop: '12px', }, _a["" + TOOLTIP_CSS_CONST.LIST_CLASS] = { margin: 0, listStyleType: 'none', padding: 0, }, _a["" + TOOLTIP_CSS_CONST.LIST_ITEM_CLASS] = { listStyleType: 'none', padding: 0, marginBottom: '12px', marginTop: '12px', marginLeft: 0, marginRight: 0, }, _a["" + TOOLTIP_CSS_CONST.MARKER_CLASS] = { width: '8px', height: '8px', borderRadius: '50%', display: 'inline-block', marginRight: '8px', }, _a["" + TOOLTIP_CSS_CONST.VALUE_CLASS] = { display: 'inline-block', float: 'right', marginLeft: '30px', }, _a), }, annotation: { arc: { style: { stroke: styleSheet.annotationArcBorderColor, lineWidth: styleSheet.annotationArcBorder, }, animate: true, }, line: { style: { stroke: styleSheet.annotationLineBorderColor, lineDash: styleSheet.annotationLineDash, lineWidth: styleSheet.annotationLineBorder, }, text: { position: 'start', autoRotate: true, style: { fill: styleSheet.annotationTextFillColor, stroke: styleSheet.annotationTextBorderColor, lineWidth: styleSheet.annotationTextBorder, fontSize: styleSheet.annotationTextFontSize, textAlign: 'start', fontFamily: styleSheet.fontFamily, textBaseline: 'bottom', }, }, animate: true, }, text: { style: { fill: styleSheet.annotationTextFillColor, stroke: styleSheet.annotationTextBorderColor, lineWidth: styleSheet.annotationTextBorder, fontSize: styleSheet.annotationTextFontSize, textBaseline: 'middle', textAlign: 'start', fontFamily: styleSheet.fontFamily, }, animate: true, }, region: { top: false, style: { lineWidth: styleSheet.annotationRegionBorder, stroke: styleSheet.annotationRegionBorderColor, fill: styleSheet.annotationRegionFillColor, fillOpacity: styleSheet.annotationRegionFillOpacity, }, animate: true, }, image: { top: false, animate: true, }, dataMarker: { top: true, point: { style: { r: 3, stroke: styleSheet.brandColor, lineWidth: 2, }, }, line: { style: { stroke: styleSheet.annotationLineBorderColor, lineWidth: styleSheet.annotationLineBorder, }, length: styleSheet.annotationDataMarkerLineLength, }, text: { style: { textAlign: 'start', fill: styleSheet.annotationTextFillColor, stroke: styleSheet.annotationTextBorderColor, lineWidth: styleSheet.annotationTextBorder, fontSize: styleSheet.annotationTextFontSize, fontFamily: styleSheet.fontFamily, }, }, direction: 'upward', autoAdjust: true, animate: true, }, dataRegion: { style: { region: { fill: styleSheet.annotationRegionFillColor, fillOpacity: styleSheet.annotationRegionFillOpacity, }, text: { textAlign: 'center', textBaseline: 'bottom', fill: styleSheet.annotationTextFillColor, stroke: styleSheet.annotationTextBorderColor, lineWidth: styleSheet.annotationTextBorder, fontSize: styleSheet.annotationTextFontSize, fontFamily: styleSheet.fontFamily, }, }, animate: true, }, }, }, labels: { offset: 12, style: { fill: styleSheet.labelFillColor, fontSize: styleSheet.labelFontSize, fontFamily: styleSheet.fontFamily, stroke: styleSheet.labelBorderColor, lineWidth: styleSheet.labelBorder, }, autoRotate: true, }, innerLabels: { style: { fill: styleSheet.innerLabelFillColor, fontSize: styleSheet.innerLabelFontSize, fontFamily: styleSheet.fontFamily, stroke: styleSheet.innerLabelBorderColor, lineWidth: styleSheet.innerLabelBorder, }, autoRotate: true, }, pieLabels: { labelHeight: 14, offset: 30, labelLine: { style: { lineWidth: styleSheet.labelLineBorder, }, }, autoRotate: true, }, }; } exports.createThemeByStylesheet = createThemeByStylesheet; },{"../util/graphics":375,"@antv/component/lib/tooltip/css-const":62,"@antv/matrix-util":717,"@antv/util":803,"tslib":385}],383:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTooltipItems = exports.findDataByPoint = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var constant_1 = require("../constant"); var scale_1 = require("./scale"); function snapEqual(v1, v2, scale) { var value1 = scale.translate(v1); var value2 = scale.translate(v2); return util_1.isNumberEqual(value1, value2); } function getXValueByPoint(point, geometry) { var coordinate = geometry.coordinate; var xScale = geometry.getXScale(); var range = xScale.range; var rangeMax = range[range.length - 1]; var rangeMin = range[0]; var invertPoint = coordinate.invert(point); var xValue = invertPoint.x; if (coordinate.isPolar && xValue > (1 + rangeMax) / 2) { xValue = rangeMin; // 极坐标下,scale 的 range 被做过特殊处理 } return xScale.translate(xScale.invert(xValue)); } function filterYValue(data, point, geometry) { var coordinate = geometry.coordinate; var yScale = geometry.getYScale(); var yField = yScale.field; var invertPoint = coordinate.invert(point); var yValue = yScale.invert(invertPoint.y); var result = util_1.find(data, function (obj) { var originData = obj[constant_1.FIELD_ORIGIN]; return originData[yField][0] <= yValue && originData[yField][1] >= yValue; }); return result || data[data.length - 1]; } var getXDistance = util_1.memoize(function (scale) { if (scale.isCategory) { return 1; } var scaleValues = scale.values; // values 是无序的 var length = scaleValues.length; var min = scale.translate(scaleValues[0]); var max = min; for (var index = 0; index < length; index++) { var value = scaleValues[index]; // 时间类型需要 translate var numericValue = scale.translate(value); if (numericValue < min) { min = numericValue; } if (numericValue > max) { max = numericValue; } } return (max - min) / (length - 1); }); function getTooltipTitle(originData, geometry, title) { var titleField = title; if (!title) { var positionAttr = geometry.getAttribute('position'); var fields = positionAttr.getFields(); titleField = fields[0]; } var scales = geometry.scales; if (scales[titleField]) { // 如果创建了该字段对应的 scale,则通过 scale.getText() 方式取值,因为用户可能对数据进行了格式化 return scales[titleField].getText(originData[titleField]); } // 如果没有对应的 scale,则从原始数据中取值,如果原始数据中仍不存在,则直接放回 title 值 return util_1.hasKey(originData, titleField) ? originData[titleField] : titleField; } function getAttributesForLegend(geometry) { var attributes = util_1.values(geometry.attributes); return util_1.filter(attributes, function (attribute) { return util_1.contains(constant_1.GROUP_ATTRS, attribute.type); }); } function getTooltipValueScale(geometry) { var attributes = getAttributesForLegend(geometry); var scale; for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) { var attribute = attributes_1[_i]; var tmpScale = attribute.getScale(attribute.type); if (tmpScale && tmpScale.isLinear) { // 如果指定字段是非 position 的,同时是连续的 scale = tmpScale; break; } } var xScale = geometry.getXScale(); var yScale = geometry.getYScale(); return scale || yScale || xScale; } function getTooltipValue(originData, valueScale) { var field = valueScale.field; var value = originData[field]; if (util_1.isArray(value)) { var texts = value.map(function (eachValue) { return valueScale.getText(eachValue); }); return texts.join('-'); } return valueScale.getText(value); } // 根据原始数据获取 tooltip item 中 name 值 function getTooltipName(originData, geometry) { var nameScale; var groupScales = geometry.getGroupScales(); if (groupScales.length) { // 如果存在分组类型,取第一个分组类型 nameScale = groupScales[0]; } if (nameScale) { var field = nameScale.field; return nameScale.getText(originData[field]); } var valueScale = getTooltipValueScale(geometry); return scale_1.getName(valueScale); } /** * @ignore * Finds data from geometry by point * @param point canvas point * @param data an item of geometry.dataArray * @param geometry * @returns */ function findDataByPoint(point, data, geometry) { if (data.length === 0) { return null; } var geometryType = geometry.type; var xScale = geometry.getXScale(); var yScale = geometry.getYScale(); var xField = xScale.field; var yField = yScale.field; var rst = null; // 热力图采用最小逼近策略查找 point 击中的数据 if (geometryType === 'heatmap' || geometryType === 'point') { // 将 point 画布坐标转换为原始数据值 var coordinate = geometry.coordinate; var invertPoint = coordinate.invert(point); // 转换成归一化的数据 var x = xScale.invert(invertPoint.x); // 转换为原始值 var y = yScale.invert(invertPoint.y); // 转换为原始值 var min = Infinity; for (var index = 0; index < data.length; index++) { var obj = data[index]; var originData = obj[constant_1.FIELD_ORIGIN]; var range = Math.pow((originData[xField] - x), 2) + Math.pow((originData[yField] - y), 2); if (range < min) { min = range; rst = obj; } } return rst; } // 其他 Geometry 类型按照 x 字段数据进行查找 var first = data[0]; var last = data[data.length - 1]; var xValue = getXValueByPoint(point, geometry); var firstXValue = first[constant_1.FIELD_ORIGIN][xField]; var firstYValue = first[constant_1.FIELD_ORIGIN][yField]; var lastXValue = last[constant_1.FIELD_ORIGIN][xField]; var isYArray = yScale.isLinear && util_1.isArray(firstYValue); // 考虑 x 维度相同,y 是数组区间的情况 // 如果 x 的值是数组 if (util_1.isArray(firstXValue)) { for (var index = 0; index < data.length; index++) { var record = data[index]; var originData = record[constant_1.FIELD_ORIGIN]; // xValue 在 originData[xField] 的数值区间内 if (xScale.translate(originData[xField][0]) <= xValue && xScale.translate(originData[xField][1]) >= xValue) { if (isYArray) { // 层叠直方图场景,x 和 y 都是数组区间 if (!util_1.isArray(rst)) { rst = []; } rst.push(record); } else { rst = record; break; } } } if (util_1.isArray(rst)) { rst = filterYValue(rst, point, geometry); } } else { var next = void 0; if (!xScale.isLinear && xScale.type !== 'timeCat') { // x 轴对应的数据为非线性以及非时间类型的数据采用遍历查找 for (var index = 0; index < data.length; index++) { var record = data[index]; var originData = record[constant_1.FIELD_ORIGIN]; if (snapEqual(originData[xField], xValue, xScale)) { if (isYArray) { if (!util_1.isArray(rst)) { rst = []; } rst.push(record); } else { rst = record; break; } } else if (xScale.translate(originData[xField]) <= xValue) { last = record; next = data[index + 1]; } } if (util_1.isArray(rst)) { rst = filterYValue(rst, point, geometry); } } else { // x 轴对应的数据为线性以及时间类型,进行二分查找,性能更好 if ((xValue > xScale.translate(lastXValue) || xValue < xScale.translate(firstXValue)) && (xValue > xScale.max || xValue < xScale.min)) { // 不在数据范围内 return null; } var firstIdx = 0; var lastIdx = data.length - 1; var middleIdx = void 0; while (firstIdx <= lastIdx) { middleIdx = Math.floor((firstIdx + lastIdx) / 2); var item = data[middleIdx][constant_1.FIELD_ORIGIN][xField]; if (snapEqual(item, xValue, xScale)) { return data[middleIdx]; } if (xScale.translate(item) <= xScale.translate(xValue)) { firstIdx = middleIdx + 1; last = data[middleIdx]; next = data[middleIdx + 1]; } else { if (lastIdx === 0) { last = data[0]; } lastIdx = middleIdx - 1; } } } if (last && next) { // 计算最逼近的 if (Math.abs(xScale.translate(last[constant_1.FIELD_ORIGIN][xField]) - xValue) > Math.abs(xScale.translate(next[constant_1.FIELD_ORIGIN][xField]) - xValue)) { last = next; } } } var distance = getXDistance(geometry.getXScale()); // 每个分类间的平均间距 if (!rst && Math.abs(xScale.translate(last[constant_1.FIELD_ORIGIN][xField]) - xValue) <= distance / 2) { rst = last; } return rst; } exports.findDataByPoint = findDataByPoint; /** * @ignore * Gets tooltip items * @param data * @param geometry * @param [title] * @returns */ function getTooltipItems(data, geometry, title) { if (title === void 0) { title = ''; } var originData = data[constant_1.FIELD_ORIGIN]; var tooltipTitle = getTooltipTitle(originData, geometry, title); var tooltipOption = geometry.tooltipOption; var defaultColor = geometry.theme.defaultColor; var items = []; var name; var value; function addItem(itemName, itemValue) { if (!util_1.isNil(itemValue) && itemValue !== '') { // 值为 null的时候,忽视 var item = { title: tooltipTitle, data: originData, mappingData: data, name: itemName, value: itemValue, color: data.color || defaultColor, marker: true, }; items.push(item); } } if (util_1.isObject(tooltipOption)) { var fields = tooltipOption.fields, callback = tooltipOption.callback; if (callback) { // 用户定义了回调函数 var callbackParams = fields.map(function (field) { return data[constant_1.FIELD_ORIGIN][field]; }); var cfg = callback.apply(void 0, callbackParams); var itemCfg = tslib_1.__assign({ data: data[constant_1.FIELD_ORIGIN], mappingData: data, title: tooltipTitle, color: data.color || defaultColor, marker: true }, cfg); items.push(itemCfg); } else { var scales = geometry.scales; for (var _i = 0, fields_1 = fields; _i < fields_1.length; _i++) { var field = fields_1[_i]; if (!util_1.isNil(originData[field])) { // 字段数据为null, undefined 时不显示 var scale = scales[field]; name = scale_1.getName(scale); value = scale.getText(originData[field]); addItem(name, value); } } } } else { var valueScale = getTooltipValueScale(geometry); if (!util_1.isNil(originData[valueScale.field])) { // 字段数据为null ,undefined时不显示 value = getTooltipValue(originData, valueScale); name = getTooltipName(originData, geometry); addItem(name, value); } } return items; } exports.getTooltipItems = getTooltipItems; },{"../constant":237,"./scale":381,"@antv/util":803,"tslib":385}],384:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.zoom = exports.getIdentityMatrix = exports.rotate = exports.translate = exports.transform = void 0; var matrix_util_1 = require("@antv/matrix-util"); var transform = matrix_util_1.ext.transform; exports.transform = transform; /** * 对元素进行平移操作。 * @param element 进行变换的元素 * @param x x 方向位移 * @param y y 方向位移 */ function translate(element, x, y) { var matrix = transform(element.getMatrix(), [['t', x, y]]); element.setMatrix(matrix); } exports.translate = translate; /** * 对元素进行旋转操作。 * @param element 进行变换的元素 * @param rotateRadian 旋转弧度 */ function rotate(element, rotateRadian) { var _a = element.attr(), x = _a.x, y = _a.y; var matrix = transform(element.getMatrix(), [ ['t', -x, -y], ['r', rotateRadian], ['t', x, y], ]); element.setMatrix(matrix); } exports.rotate = rotate; /** * 获取元矩阵。 * @returns identity matrix */ function getIdentityMatrix() { return [1, 0, 0, 0, 1, 0, 0, 0, 1]; } exports.getIdentityMatrix = getIdentityMatrix; /** * 围绕图形中心点进行缩放 * @param element 进行缩放的图形元素 * @param ratio 缩放比例 */ function zoom(element, ratio) { var bbox = element.getBBox(); var x = (bbox.minX + bbox.maxX) / 2; var y = (bbox.minY + bbox.maxY) / 2; element.applyToMatrix([x, y, 1]); var matrix = transform(element.getMatrix(), [ ['t', -x, -y], ['s', ratio, ratio], ['t', x, y], ]); element.setMatrix(matrix); } exports.zoom = zoom; },{"@antv/matrix-util":717}],385:[function(require,module,exports){ (function (global){ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global global, define, System, Reflect, Promise */ var __extends; var __assign; var __rest; var __decorate; var __param; var __metadata; var __awaiter; var __generator; var __exportStar; var __values; var __read; var __spread; var __spreadArrays; var __await; var __asyncGenerator; var __asyncDelegator; var __asyncValues; var __makeTemplateObject; var __importStar; var __importDefault; var __classPrivateFieldGet; var __classPrivateFieldSet; var __createBinding; (function (factory) { var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; if (typeof define === "function" && define.amd) { define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); } else if (typeof module === "object" && typeof module.exports === "object") { factory(createExporter(root, createExporter(module.exports))); } else { factory(createExporter(root)); } function createExporter(exports, previous) { if (exports !== root) { if (typeof Object.create === "function") { Object.defineProperty(exports, "__esModule", { value: true }); } else { exports.__esModule = true; } } return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; } }) (function (exporter) { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; __extends = function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; __assign = Object.assign || function (t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; __rest = function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; __decorate = function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; __param = function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; __metadata = function (metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); }; __awaiter = function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; __generator = function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; __exportStar = function(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); }; __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); __values = function (o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; __read = function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; __spread = function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; __spreadArrays = function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; __await = function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }; __asyncGenerator = function (thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; __asyncDelegator = function (o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; __asyncValues = function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; __makeTemplateObject = function (cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; __importStar = function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; __importDefault = function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; __classPrivateFieldGet = function (receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); }; __classPrivateFieldSet = function (receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; }; exporter("__extends", __extends); exporter("__assign", __assign); exporter("__rest", __rest); exporter("__decorate", __decorate); exporter("__param", __param); exporter("__metadata", __metadata); exporter("__awaiter", __awaiter); exporter("__generator", __generator); exporter("__exportStar", __exportStar); exporter("__createBinding", __createBinding); exporter("__values", __values); exporter("__read", __read); exporter("__spread", __spread); exporter("__spreadArrays", __spreadArrays); exporter("__await", __await); exporter("__asyncGenerator", __asyncGenerator); exporter("__asyncDelegator", __asyncDelegator); exporter("__asyncValues", __asyncValues); exporter("__makeTemplateObject", __makeTemplateObject); exporter("__importStar", __importStar); exporter("__importDefault", __importDefault); exporter("__classPrivateFieldGet", __classPrivateFieldGet); exporter("__classPrivateFieldSet", __classPrivateFieldSet); }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],386:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VIEW_LAYER_LIFE_CYCLE = void 0; var VIEW_LAYER_LIFE_CYCLE; (function (VIEW_LAYER_LIFE_CYCLE) { VIEW_LAYER_LIFE_CYCLE["BEFORE_INIT"] = "beforeinit"; VIEW_LAYER_LIFE_CYCLE["AFTER_INIT"] = "afterinit"; VIEW_LAYER_LIFE_CYCLE["BEFORE_RENDER"] = "beforerender"; VIEW_LAYER_LIFE_CYCLE["AFTER_RENDER"] = "afterrender"; VIEW_LAYER_LIFE_CYCLE["BEFORE_CHANGE_DATA"] = "beforechangedata"; VIEW_LAYER_LIFE_CYCLE["AFTER_CHANGE_DATA"] = "afterchangedata"; })(VIEW_LAYER_LIFE_CYCLE = exports.VIEW_LAYER_LIFE_CYCLE || (exports.VIEW_LAYER_LIFE_CYCLE = {})); },{}],387:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dom_util_1 = require("@antv/dom-util"); var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); var resize_observer_polyfill_1 = tslib_1.__importDefault(require("resize-observer-polyfill")); var global_1 = require("../../theme/global"); var theme_1 = tslib_1.__importDefault(require("./theme")); /** * Canvas controller * 1. create G.Canvas, destroy G.Canvas * 2. process auto fit container * 3. API for G.Canvas */ var CanvasController = /** @class */ (function () { function CanvasController(cfg) { var _this = this; /** * when the container size changed, trigger it after 300ms. */ this.onResize = util_1.debounce(function () { if (_this.plot.destroyed) { return; } var _a = _this.getCanvasSize(), width = _a.width, height = _a.height; /** height measure不准导致重复 forceFit */ if (_this.width === width && _this.height === height) { return; } // got new width, height, re-render the plot _this.width = width; _this.height = height; _this.plot.updateConfig({ width: width, height: height }); _this.plot.render(); }, 300); var containerDOM = cfg.containerDOM, plot = cfg.plot; this.containerDOM = containerDOM; this.plot = plot; this.init(); } /** * get canvas size from props. * @returns the width, height of canvas */ CanvasController.prototype.getCanvasSize = function () { var theme = global_1.getGlobalTheme(); var width = this.plot.width ? this.plot.width : theme.width; var height = this.plot.height ? this.plot.height : theme.height; // if forceFit = true, then use the container's size as default. if (this.plot.forceFit) { width = this.containerDOM.offsetWidth ? this.containerDOM.offsetWidth : width; height = this.containerDOM.offsetHeight ? this.containerDOM.offsetHeight : height; } return { width: width, height: height }; }; /** * get the canvas dom * @returns Canvas DOM */ CanvasController.prototype.getCanvasDOM = function () { return this.canvas.get('container'); }; /** * update the plot size */ CanvasController.prototype.updateCanvasSize = function () { var _a = this.getCanvasSize(), width = _a.width, height = _a.height; this.width = width; this.height = height; this.canvas.changeSize(width, height); // this.plot.updateRange(); }; /** * 根据主题调整canvas样式 */ CanvasController.prototype.updateCanvasTheme = function () { var theme = this.plot.theme; var globalTheme = theme_1.default.getGlobalTheme(theme); var fill = util_1.get(globalTheme, 'backgroundStyle.fill'); if (fill) { this.updateCanvasStyle({ backgroundColor: fill, }); } }; /** * update the canvas dom styles * @param styles */ CanvasController.prototype.updateCanvasStyle = function (styles) { // 修改容器的样式 dom_util_1.modifyCSS(this.getCanvasDOM(), styles); // 修改 canvas 的样式 dom_util_1.modifyCSS(this.canvas.get('el'), { display: 'inline-block', verticalAlign: 'middle', }); }; /** * destroy the plot, remove resize event. */ CanvasController.prototype.destroy = function () { // remove event if (this.resizeObserver) { this.resizeObserver.unobserve(this.containerDOM); this.resizeObserver.disconnect(); this.containerDOM = null; } // remove G.Canvas this.canvas.destroy(); }; /** * when forceFit = true, then bind the event to listen the container size change */ CanvasController.prototype.bindForceFit = function () { var forceFit = this.plot.forceFit; // use ResizeObserver to listen the container size change. if (forceFit) { this.resizeObserver = new resize_observer_polyfill_1.default(this.onResize); this.resizeObserver.observe(this.containerDOM); } }; /** * init life circle */ CanvasController.prototype.init = function () { this.initGCanvas(); this.bindForceFit(); // 追加容器的 css 样式,防止 tooltip 的位置参考点不正确 this.updateCanvasStyle({ position: 'relative' }); }; /** * init G.Canvas instance */ CanvasController.prototype.initGCanvas = function () { /** 创建canvas */ var _a = this.plot, _b = _a.renderer, renderer = _b === void 0 ? 'canvas' : _b, pixelRatio = _a.pixelRatio, _c = _a.localRefresh, localRefresh = _c === void 0 ? false : _c; var _d = this.getCanvasSize(), width = _d.width, height = _d.height; var G = renderer === 'canvas' ? dependents_1.Canvas : dependents_1.SVG; this.canvas = new G({ localRefresh: localRefresh, container: this.containerDOM, width: width, height: height, pixelRatio: pixelRatio, }); this.width = width; this.height = height; this.updateCanvasTheme(); }; return CanvasController; }()); exports.default = CanvasController; },{"../../dependents":425,"../../theme/global":668,"./theme":391,"@antv/dom-util":92,"@antv/util":803,"resize-observer-polyfill":893,"tslib":894}],388:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); function isSameShape(shape1, shape2) { if (shape1 && shape2 && shape1 === shape2) { return true; } return false; } function isPointInBBox(point, bbox) { if (point.x >= bbox.minX && point.x <= bbox.maxX && point.y >= bbox.minY && point.y <= bbox.maxY) { return true; } return false; } var EventController = /** @class */ (function () { function EventController(cfg) { this.plot = cfg.plot; this.canvas = cfg.canvas; this.eventHandlers = []; } EventController.prototype.bindEvents = function () { this.addEvent(this.canvas, 'mousedown', util_1.wrapBehavior(this, 'onEvents')); this.addEvent(this.canvas, 'mousemove', util_1.wrapBehavior(this, 'onMove')); this.addEvent(this.canvas, 'mouseup', util_1.wrapBehavior(this, 'onEvents')); this.addEvent(this.canvas, 'click', util_1.wrapBehavior(this, 'onEvents')); this.addEvent(this.canvas, 'dblclick', util_1.wrapBehavior(this, 'onEvents')); this.addEvent(this.canvas, 'contextmenu', util_1.wrapBehavior(this, 'onEvents')); this.addEvent(this.canvas, 'wheel', util_1.wrapBehavior(this, 'onEvents')); }; EventController.prototype.clearEvents = function () { var eventHandlers = this.eventHandlers; util_1.each(eventHandlers, function (eh) { eh.target.off(eh.type, eh.handler); }); }; EventController.prototype.addEvent = function (target, eventType, handler) { target.on(eventType, handler); this.eventHandlers.push({ target: target, type: eventType, handler: handler }); }; EventController.prototype.onEvents = function (ev) { var eventObj = this.getEventObj(ev); var target = ev.target; // 判断是否拾取到view以外的shape if (!this.isShapeInView(target) && target.name) { this.plot.emit(target.name + ":" + ev.type, ev); } this.plot.emit("" + ev.type, eventObj); // layer事件 var layers = this.plot.getLayers(); if (layers.length > 0) { this.onLayerEvent(layers, eventObj, ev.type); } }; EventController.prototype.onMove = function (ev) { var target = ev.target; var eventObj = this.getEventObj(ev); // shape的mouseenter, mouseleave和mousemove事件 if (!this.isShapeInView(target) && target.name) { this.plot.emit(target.name + ":" + ev.type, eventObj); // mouseleave & mouseenter if (this.lastShape && !isSameShape(target, this.lastShape)) { if (this.lastShape) { this.plot.emit(this.lastShape.name + ":mouseleave", eventObj); } this.plot.emit(target.name + ":mouseenter", eventObj); } this.lastShape = target; } this.plot.emit('mousemove', eventObj); // layer事件 var layers = this.plot.getLayers(); if (layers.length > 0) { this.onLayerEvent(layers, eventObj, 'mousemove'); } }; EventController.prototype.isShapeInView = function (shape) { var groupName = ['frontgroundGroup', 'backgroundGroup', 'panelGroup']; var parent = shape.get('parent'); while (parent) { var parentName = parent.get('name'); if (parentName && util_1.contains(groupName, parentName)) { return true; } parent = parent.get('parent'); } return false; }; EventController.prototype.getEventObj = function (ev) { var obj = { clientX: ev.clientX, clientY: ev.clientY, x: ev.x, y: ev.y, plot: this.plot, data: ev.data ? ev.data.data : null, canvas: this.canvas, target: ev.target, gEvent: ev, }; return obj; }; EventController.prototype.onLayerEvent = function (layers, eventObj, eventName) { var _this = this; util_1.each(layers, function (layer) { var bbox = layer.getGlobalBBox(); if (isPointInBBox({ x: eventObj.x, y: eventObj.y }, bbox)) { layer.emit("" + eventName, eventObj); var subLayers = layer.layers; if (subLayers.length > 0) { _this.onLayerEvent(subLayers, eventObj, eventName); } } }); }; return EventController; }()); exports.default = EventController; },{"@antv/util":803}],389:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var bbox_1 = tslib_1.__importDefault(require("../../util/bbox")); var common_1 = require("../../util/common"); /** * 处理图表padding的逻辑: * 注册参与padding的自定义组件 */ var PaddingController = /** @class */ (function () { function PaddingController(cfg) { this.innerPaddingComponents = []; this.outerPaddingComponents = []; this.plot = cfg.plot; } PaddingController.prototype.registerPadding = function (component, type, checkIfExist) { if (type === void 0) { type = 'outer'; } if (checkIfExist === void 0) { checkIfExist = false; } if (type === 'inner') { if (checkIfExist) { if (!this.innerPaddingComponents.find(function (c) { return c == component; })) { this.innerPaddingComponents.push(component); } } else { this.innerPaddingComponents.push(component); } } else { if (checkIfExist) { if (!this.outerPaddingComponents.find(function (c) { return c == component; })) { this.outerPaddingComponents.push(component); } } else { this.outerPaddingComponents.push(component); } } }; PaddingController.prototype.getPaddingComponents = function (type) { if (type === void 0) { type = 'outer'; } return (type === 'outer' ? this.outerPaddingComponents : this.innerPaddingComponents) || []; }; /** * 清除已经注册的元素 */ PaddingController.prototype.clear = function () { this.innerPaddingComponents = []; // 一些组件是在view渲染完成之后渲染初始化的 // TODO: afterRender的什么时候清除 this.outerPaddingComponents = util_1.filter(this.outerPaddingComponents, function (component) { return component.afterRender; }); }; PaddingController.prototype.clearOuterComponents = function () { util_1.each(this.outerPaddingComponents, function (component) { if (component.afterRender) { component.destroy(); } }); this.outerPaddingComponents = []; }; PaddingController.prototype.getPadding = function () { var props = this.plot.options; var padding = props.padding ? props.padding : this.plot.config.theme.padding; if (padding === 'auto') { return [0, 0, 0, 1]; } return padding; }; /** view层的padding计算 */ PaddingController.prototype.processAutoPadding = function () { var padding = this._getInnerAutoPadding(); this.plot.updateConfig({ padding: padding, }); this.plot.render(); }; PaddingController.prototype.processOuterPadding = function () { if (!this.plot.layerBBox) { this.plot.layerBBox = new bbox_1.default(this.plot.x, this.plot.y, this.plot.width, this.plot.height); } var viewMinX = this.plot.layerBBox.minX; var viewMaxX = this.plot.layerBBox.maxX; var viewMinY = this.plot.layerBBox.minY; var viewMaxY = this.plot.layerBBox.maxY; util_1.each(this.outerPaddingComponents, function (component) { var position = component.position; if (component.destroyed) { return; } var _a = component.getBBox(), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY; if (maxY >= viewMinY && maxY <= viewMaxY && position === 'top') { viewMinY = maxY; } if (minY >= viewMinY && minY <= viewMaxY && position === 'bottom') { viewMaxY = minY; } if (maxX > viewMinX && maxX <= viewMaxX && position === 'left') { viewMinX = maxX; } if (minX >= viewMinX && maxX <= viewMaxX && position === 'right') { viewMaxX = minX; } }); return new bbox_1.default(viewMinX, viewMinY, viewMaxX - viewMinX, viewMaxY - viewMinY); }; PaddingController.prototype._getInnerAutoPadding = function () { var _a; var props = this.plot.options; var view = this.plot.view; var viewRange = view.coordinateBBox; var maxX = viewRange.maxX, maxY = viewRange.maxY, minY = viewRange.minY, minX = viewRange.minX; var bleeding = this.plot.config.theme.bleeding; if (util_1.isArray(bleeding)) { util_1.each(bleeding, function (it, index) { if (typeof bleeding[index] === 'function') { bleeding[index] = bleeding[index](props); } }); } this.bleeding = util_1.clone(bleeding); // 参与auto padding的components: axis legend label annotation var components_bbox = [new bbox_1.default(viewRange.minX, viewRange.minY, viewRange.width, viewRange.height)]; if (((_a = this.plot.config.coordinate) === null || _a === void 0 ? void 0 : _a.type) === 'cartesian') { this._getCartesianAxis(view, components_bbox[0], components_bbox); } var box = this._mergeBBox(components_bbox); this._getLegend(view, box, components_bbox); box = this._mergeBBox(components_bbox); // 参与auto padding的自定义组件 var components = this.innerPaddingComponents; util_1.each(components, function (obj) { var component = obj; var bbox = component.getBBox(); components_bbox.push(bbox); }); box = this._mergeBBox(components_bbox); var padding = [ minY - box.minY + this.bleeding[0], box.maxX - maxX + this.bleeding[1], box.maxY - maxY + this.bleeding[2], minX - box.minX + this.bleeding[3], ]; // label、annotation等 var panelPadding = this._getPanel(view); padding[0] += panelPadding[0]; padding[1] += panelPadding[1]; padding[2] += panelPadding[2]; padding[3] += panelPadding[3]; return padding; }; PaddingController.prototype._getCartesianAxis = function (view, globalBBox, bboxes) { var axes = common_1.getAxisComponents(view); var isTransposed = view.getCoordinate().isTransposed; util_1.each(axes, function (axis) { if (axis.get('group').get('children').length === 0) { return; } var position = axis.get('position'); var _a = axis.getLayoutBBox(), minX = _a.minX, minY = _a.minY, width = _a.width, height = _a.height; if (!isTransposed) { if (position === 'left') { bboxes.push(new bbox_1.default(globalBBox.minX - width, minY, width, height)); } else if (position === 'bottom') { bboxes.push(new bbox_1.default(minX, globalBBox.maxY, width, height)); } else if (position === 'right') { bboxes.push(new bbox_1.default(globalBBox.maxX, minY, width, height)); } } else { if (position === 'bottom') { bboxes.push(new bbox_1.default(globalBBox.minX - width, minY, width, height)); } else if (position === 'left') { bboxes.push(new bbox_1.default(minX, globalBBox.maxY, width, height)); } else if (position === 'top') { bboxes.push(new bbox_1.default(globalBBox.maxX, minY, width, height)); } } }); }; PaddingController.prototype._getLegend = function (view, globalBBox, bboxes) { var legends = common_1.getLegendComponents(view); util_1.each(legends, function (legend) { var position = legend.get('position').split('-')[0]; var _a = legend.getLayoutBBox(), minX = _a.minX, minY = _a.minY, width = _a.width, height = _a.height; if (position === 'top') { bboxes.push(new bbox_1.default(minX, globalBBox.minY - height, width, height)); } else if (position === 'bottom') { bboxes.push(new bbox_1.default(minX, globalBBox.maxY, width, height)); } else if (position === 'left') { bboxes.push(new bbox_1.default(globalBBox.minX - width, minY, width, height)); } else { bboxes.push(new bbox_1.default(globalBBox.maxX, minY, width, height)); } }); }; PaddingController.prototype._getPanel = function (view) { var groups = []; var geoms = view.geometries; util_1.each(geoms, function (geom) { if (geom.labelsContainer) { groups.push(geom.labelsContainer); } }); var minX = Infinity; var maxX = -Infinity; var minY = Infinity; var maxY = -Infinity; util_1.each(groups, function (group) { var children = group.get('children'); children.forEach(function (child) { if (child.type === 'group' && child.get('children').length === 0) { return; } var bbox = child.getBBox(); if (bbox.minX < minX) { minX = bbox.minX; } if (bbox.maxX > maxX) { maxX = bbox.maxX; } if (bbox.minY < minY) { minY = bbox.minY; } if (bbox.maxY > maxY) { maxY = bbox.maxY; } }); }); var panelRange = view.coordinateBBox; //right var rightDist = Math.max(maxX - parseFloat(panelRange.maxX), 0); if (rightDist > 0) { var ratio = panelRange.width / (panelRange.width + rightDist); rightDist *= ratio; } //left var leftDist = Math.max(parseFloat(panelRange.minX) - minX, 0); if (leftDist > 0) { var ratio = panelRange.width / (panelRange.width + leftDist); leftDist *= ratio; } //top var topDist = Math.max(parseFloat(panelRange.minY) - minY, 0); if (topDist > 0) { var ratio = panelRange.height / (panelRange.height + topDist); topDist *= ratio; } //bottom var bottomDist = Math.max(maxY - parseFloat(panelRange.maxY), 0); if (bottomDist > 0) { var ratio = panelRange.height / (panelRange.height + bottomDist); bottomDist *= ratio; } return [topDist, rightDist, bottomDist, leftDist]; }; PaddingController.prototype._mergeBBox = function (bboxes) { var minX = Infinity; var maxX = -Infinity; var minY = Infinity; var maxY = -Infinity; util_1.each(bboxes, function (bbox) { var box = bbox; minX = Math.min(box.minX, minX); maxX = Math.max(box.maxX, maxX); minY = Math.min(box.minY, minY); maxY = Math.max(box.maxY, maxY); }); return { minX: minX, maxX: maxX, minY: minY, maxY: maxY }; }; return PaddingController; }()); exports.default = PaddingController; },{"../../util/bbox":672,"../../util/common":674,"@antv/util":803,"tslib":894}],390:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.compare = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var factory_1 = require("../../components/factory"); var event_1 = require("../../util/event"); var state_manager_1 = tslib_1.__importDefault(require("../../util/state-manager")); function compare(origin, condition) { if (!util_1.isFunction(condition)) { var name_1 = condition.name, exp = condition.exp; if (util_1.isFunction(exp)) { return exp(origin[name_1]); } return origin[name_1] === exp; } return condition(origin); } exports.compare = compare; var StateController = /** @class */ (function () { function StateController(cfg) { this.shapeContainers = []; util_1.assign(this, cfg); } StateController.prototype.createStateManager = function () { this.stateManager = new state_manager_1.default(); }; StateController.prototype.bindStateManager = function (manager, cfg) { this.stateManager = manager; if (cfg.setState) { this._updateStateProcess(cfg.setState); } if (cfg.onStateChange) { this._stateChangeProcess(cfg.onStateChange); } }; StateController.prototype.defaultStates = function (states) { var _this = this; util_1.each(states, function (state, type) { var condition = state.condition, related = state.related; _this.setState({ type: type, condition: condition, related: related }); }); }; StateController.prototype.setState = function (cfg) { var _this = this; var type = cfg.type, condition = cfg.condition, related = cfg.related; this.shapes = this._getShapes(); this.originAttrs = this._getOriginAttrs(); // this.resetZIndex(); util_1.each(this.shapes, function (shape, index) { var shapeOrigin = shape.get('origin').data; var origin = util_1.isArray(shapeOrigin) ? shapeOrigin[0] : shapeOrigin; if (compare(origin, condition)) { var stateStyle = cfg.style ? cfg.style : _this._getDefaultStateStyle(type, shape); var originAttr = _this.originAttrs[index]; var attrs = void 0; if (util_1.isFunction(stateStyle)) { attrs = stateStyle(originAttr); } else { attrs = util_1.mix({}, originAttr, stateStyle); } shape.attr(attrs); _this.setZIndex(type, shape); // const canvas = this.plot.canvas; // canvas.draw(); } }); // 组件与图形对状态量的响应不一定同步 if (related) { this._parserRelated(type, related, condition); } this.plot.canvas.draw(); }; StateController.prototype._updateStateProcess = function (setStateCfg) { var _this = this; util_1.each(setStateCfg, function (cfg) { var state = cfg.state; var handler; if (util_1.isFunction(state)) { handler = function (e) { var s = state(e); _this.stateManager.setState(s.name, s.exp); }; } else { handler = function () { _this.stateManager.setState(state.name, state.exp); }; } if (cfg.event) { event_1.onEvent(_this.plot, _this._eventParser(cfg.event), handler); } else { handler(); } }); }; StateController.prototype._stateChangeProcess = function (onChangeCfg) { var _this = this; util_1.each(onChangeCfg, function (cfg) { _this.stateManager.on(cfg.name + ":change", function (props) { cfg.callback(props, _this.plot); }); }); }; StateController.prototype._getShapes = function () { var _this = this; var shapes = []; var geoms = this.plot.view.geometries; util_1.each(geoms, function (geom) { var shapeContainer = geom.container; _this.shapeContainers.push(shapeContainer); if (!geom.destroyed) { shapes.push.apply(shapes, geom.getShapes()); } }); return shapes; }; StateController.prototype._getOriginAttrs = function () { var attrs = []; util_1.each(this.shapes, function (shape) { attrs.push(util_1.clone(shape.attr())); }); return attrs; }; // 将g2 geomtry转为plot层geometry StateController.prototype._eventParser = function (event) { var eventCfg = event.split(':'); var eventTarget = this.plot.geometryParser('g2', eventCfg[0]); var eventName = eventCfg[1]; return eventTarget + ":" + eventName; }; StateController.prototype._getDefaultStateStyle = function (type, shape) { var theme = this.plot.theme; var plotGeomType = this.plot.geometryParser('plot', shape.name); var styleField = plotGeomType + "Style"; if (theme[styleField]) { var style = theme[styleField][type]; if (util_1.isFunction(style)) { style = style(shape.attr()); } return style; } return {}; }; StateController.prototype._parserRelated = function (type, related, condition) { var _this = this; util_1.each(related, function (r) { if (_this.plot[r]) { // fixme: 自定义组件 // this.plot[r].setState(type, condition); var method = factory_1.getComponentStateMethod(r, type); method(_this.plot, condition); } }); }; // private set StateController.prototype.setZIndex = function (stateType, shape) { if (stateType === 'active' || stateType === 'selected') { // shape.setZIndex(1); var children = shape.get('parent').get('children'); children[children.length - 1].setZIndex(0); shape.setZIndex(1); } }; StateController.prototype.resetZIndex = function () { util_1.each(this.shapeContainers, function (container) { var children = container.get('children'); children.sort(function (obj1, obj2) { return obj1._INDEX - obj2._INDEX; }); }); }; return StateController; }()); exports.default = StateController; },{"../../components/factory":412,"../../util/event":677,"../../util/state-manager":713,"@antv/util":803,"tslib":894}],391:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); var theme_1 = require("../../theme"); var theme_2 = require("../../util/responsive/theme"); var theme_3 = require("../../theme/theme"); /** * 负责图表theme的管理 */ var G2DefaultTheme = dependents_1.getTheme(); var ThemeController = /** @class */ (function () { function ThemeController() { } /** * 获取指定的全局theme * @param theme */ ThemeController.getGlobalTheme = function (theme) { if (util_1.isString(theme)) { return theme_1.getGlobalTheme(theme); } return util_1.deepMix({}, theme_1.getGlobalTheme(), theme); }; /** * 通过 theme 和图表类型,获取当前 plot 对应的主题 * @param props * @param type */ ThemeController.prototype.getPlotTheme = function (props, type) { var theme = props.theme; if (util_1.isString(theme)) { return util_1.deepMix({}, theme_1.getGlobalTheme(theme), theme_1.getTheme(type)); } return util_1.deepMix({}, theme_1.getGlobalTheme(), theme_1.getTheme(type), theme_3.convertThemeToG2Theme(type, theme)); }; /** * 获取转化成 G2 的结构主题 * @param props * @param type */ ThemeController.prototype.getTheme = function (props, type) { var plotG2Theme = theme_1.convertToG2Theme(this.getPlotTheme(props, type)); var g2Theme = util_1.deepMix({}, G2DefaultTheme, plotG2Theme); return g2Theme; }; ThemeController.prototype.getResponsiveTheme = function (type) { return theme_2.getResponsiveTheme(type) || theme_2.getResponsiveTheme('default'); }; return ThemeController; }()); exports.default = ThemeController; },{"../../dependents":425,"../../theme":669,"../../theme/theme":670,"../../util/responsive/theme":711,"@antv/util":803}],392:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlotType = exports.registerPlotType = void 0; /** 所有统计图形 */ var GLOBAL_PLOT_MAP = {}; function registerPlotType(name, ctr) { GLOBAL_PLOT_MAP[name.toLowerCase()] = ctr; } exports.registerPlotType = registerPlotType; function getPlotType(name) { return GLOBAL_PLOT_MAP[name.toLowerCase()]; } exports.getPlotType = getPlotType; },{}],393:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); var util_1 = require("@antv/util"); var event_1 = require("../util/event"); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var Layer = /** @class */ (function (_super) { tslib_1.__extends(Layer, _super); /** * layer base for g2plot */ function Layer(props) { var _this = _super.call(this) || this; _this.layers = []; _this.destroyed = false; _this.visibility = true; _this.rendered = false; _this.eventHandlers = []; _this.options = _this.getOptions(props); _this.processOptions(_this.options); return _this; } Layer.prototype.processOptions = function (options) { this.id = options.id; this.x = options.x || 0; this.y = options.y || 0; this.width = options.width; this.height = options.height; this.canvas = options.canvas; this.parent = options.parent; }; Layer.prototype.updateConfig = function (cfg) { this.options = util_1.deepMix({}, this.options, cfg); this.processOptions(this.options); }; Layer.prototype.beforeInit = function () { return null; }; /** * init life cycle */ Layer.prototype.init = function () { this.layerBBox = this.getLayerBBox(); this.layerRegion = this.getLayerRegion(); this.eachLayer(function (layer) { layer.init(); }); }; Layer.prototype.afterInit = function () { return null; }; /** * render layer recursively */ Layer.prototype.render = function () { // fixme: 等plot不再继承layer,这个就可以挪到构造函数里去,不需要再加是否render过的判断了 if (!this.rendered) { this.container = this.parent ? this.parent.container.addGroup() : this.canvas.addGroup(); } this.rendered = true; this.beforeInit(); this.init(); this.afterInit(); //(this.container, [['t', this.x, this.y]]); this.eachLayer(function (layer) { layer.render(); }); this.canvas.draw(); }; /** * clear layer content */ Layer.prototype.clear = function () { this.eachLayer(function (layer) { layer.destroy(); }); this.layers = []; this.container.clear(); }; /** * destroy layer recursively, remove the container of layer */ Layer.prototype.destroy = function () { var _this = this; this.eachLayer(function (layer) { layer.destroy(); }); util_1.each(this.eventHandlers, function (h) { _this.off(h.eventName, h.handler); }); this.container.remove(true); this.destroyed = true; }; /** * display layer */ Layer.prototype.show = function () { this.container.attr('visible', true); this.container.set('visible', true); this.visibility = true; this.canvas.draw(); }; /** * hide layer */ Layer.prototype.hide = function () { this.container.attr('visible', false); this.container.set('visible', false); this.visibility = false; this.canvas.draw(); }; /** * add children layer * @param layer */ Layer.prototype.addLayer = function (layer) { var idx = util_1.findIndex(this.layers, function (item) { return item === layer; }); if (idx < 0) { if (layer.parent !== this) { layer.parent = this; layer.init(); } this.layers.push(layer); } }; /** * remove children layer * @param layer */ Layer.prototype.removeLayer = function (layer) { var idx = util_1.findIndex(this.layers, function (item) { return item === layer; }); if (idx >= 0) { this.layers.splice(idx, 1); } }; /** * update layer's display range * @param props * @param recursive whether update children layers or not */ Layer.prototype.updateBBox = function (props, recursive) { if (recursive === void 0) { recursive = false; } var originRange = { x: this.x, y: this.y, width: this.width, height: this.height, }; var newRange = util_1.deepMix({}, originRange, props); this.x = newRange.x; this.y = newRange.y; this.width = newRange.width; this.height = newRange.height; this.layerBBox = this.getLayerBBox(); this.layerRegion = this.getLayerRegion(); this.render(); if (recursive) { this.eachLayer(function (layer) { layer.updateBBoxByParent(); layer.render(); }); } this.canvas.draw(); }; /** * update display range according to parent layer's range */ Layer.prototype.updateBBoxByParent = function () { var region = this.layerRegion; this.x = this.parent.x + this.parent.width * region.start.x; this.y = this.parent.y + this.parent.height * region.start.y; this.width = this.parent.width * (region.end.x - region.start.x); this.height = this.parent.height * (region.end.y - region.start.y); this.layerBBox = this.getLayerBBox(); }; /** * get global position of layer */ Layer.prototype.getGlobalPosition = function () { var globalX = this.x; var globalY = this.y; var parent = this.parent; while (parent) { globalX += parent.x; globalY += parent.y; parent = parent.parent; } return { x: globalX, y: globalY }; }; Layer.prototype.getGlobalBBox = function () { var globalPosition = this.getGlobalPosition(); return new bbox_1.default(globalPosition.x, globalPosition.y, this.width, this.height); }; Layer.prototype.getOptions = function (props) { var parentWidth = 0; var parentHeight = 0; if (props.parent) { parentWidth = props.parent.width; parentHeight = props.parent.height; } var defaultOptions = { x: 0, y: 0, width: parentWidth, height: parentHeight, }; return util_1.deepMix({}, defaultOptions, props); }; Layer.prototype.eachLayer = function (cb) { util_1.each(this.layers, cb); }; Layer.prototype.parseEvents = function (eventParser) { var _this = this; var eventsName = util_1.keys(event_1.LAYER_EVENT_MAP); util_1.each(eventParser, function (e, k) { if (util_1.contains(eventsName, k) && util_1.isFunction(e)) { var eventName = event_1.LAYER_EVENT_MAP[k] || k; var handler = e; _this.on(eventName, handler); _this.eventHandlers.push({ name: eventName, handler: handler }); } }); }; Layer.prototype.getLayerBBox = function () { return new bbox_1.default(this.x, this.y, this.width, this.height); }; Layer.prototype.getLayerRegion = function () { if (this.parent) { var parentWidth = this.parent.width; var parentHeight = this.parent.height; var parentX = this.parent.x; var parentY = this.parent.y; var startX = (this.x - parentX) / parentWidth; var startY = (this.y - parentY) / parentHeight; var endX = (this.x + this.width - parentX) / parentWidth; var endY = (this.y + this.height - parentY) / parentHeight; return { start: { x: startX, y: startY }, end: { x: endX, y: endY } }; } return { start: { x: 0, y: 0 }, end: { x: 1, y: 1 } }; }; return Layer; }(event_emitter_1.default)); exports.default = Layer; },{"../util/bbox":672,"../util/event":677,"@antv/event-emitter":94,"@antv/util":803,"tslib":894}],394:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); var util_1 = require("@antv/util"); var canvas_1 = tslib_1.__importDefault(require("./controller/canvas")); var event_1 = tslib_1.__importDefault(require("./controller/event")); var global_1 = require("./global"); var layer_1 = tslib_1.__importDefault(require("./layer")); var view_layer_1 = tslib_1.__importDefault(require("./view-layer")); var event_2 = require("../util/event"); var BasePlot = /** @class */ (function (_super) { tslib_1.__extends(BasePlot, _super); function BasePlot(container, props) { var _this = _super.call(this) || this; _this.containerDOM = typeof container === 'string' ? document.getElementById(container) : container; _this.forceFit = !util_1.isNil(props.forceFit) ? props.forceFit : util_1.isNil(props.width) && util_1.isNil(props.height); _this.renderer = props.renderer || 'canvas'; _this.pixelRatio = props.pixelRatio || null; _this.width = props.width; _this.height = props.height; _this.theme = props.theme; _this.localRefresh = props.localRefresh; _this.canvasController = new canvas_1.default({ containerDOM: _this.containerDOM, plot: _this, }); /** update layer properties */ _this.width = _this.canvasController.width; _this.height = _this.canvasController.height; _this.canvas = _this.canvasController.canvas; _this.layers = []; _this.destroyed = false; _this.createLayers(props); /** bind events */ _this.eventController = new event_1.default({ plot: _this, canvas: _this.canvasController.canvas, }); _this.eventController.bindEvents(); _this.parseEvents(props); return _this; } /** 生命周期 */ BasePlot.prototype.destroy = function () { this.eachLayer(function (layer) { layer.destroy(); }); this.canvasController.destroy(); this.eventController.clearEvents(); this.layers = []; this.destroyed = true; }; /** * 重新绘制图形 */ BasePlot.prototype.repaint = function () { this.canvasController.canvas.draw(); }; BasePlot.prototype.updateConfig = function (config, all) { if (all === void 0) { all = false; } if (all) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.updateConfig(config); } }); } else { var layer = this.layers[0]; if (layer instanceof layer_1.default) { layer.updateConfig(config); } } if (config.width) { this.width = config.width; } if (config.height) { this.height = config.height; } if (config.theme) { this.theme = config.theme; } this.canvasController.updateCanvasSize(); this.canvasController.updateCanvasTheme(); }; BasePlot.prototype.changeData = function (data, all) { if (all === void 0) { all = false; } if (all) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.changeData(data); } }); } else { var layer = this.layers[0]; if (layer instanceof view_layer_1.default) { layer.changeData(data); } } }; BasePlot.prototype.getScaleByField = function (field) { return this.layers[0].getScaleByField(field); }; BasePlot.prototype.getXScale = function () { return this.layers[0].getXScale(); }; BasePlot.prototype.getYScale = function () { return this.layers[0].getYScale(); }; BasePlot.prototype.getColorScale = function () { return this.layers[0].getColorScale(); }; BasePlot.prototype.getPlotTheme = function () { var layer = this.layers[0]; return layer.getPlotTheme(); }; BasePlot.prototype.getData = function () { var layer = this.layers[0]; return layer.getData(); }; /** * 绑定一个外部的stateManager * 先直接传递给各个子 Layer * * @param stateManager * @param cfg */ BasePlot.prototype.bindStateManager = function (stateManager, cfg) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.bindStateManager(stateManager, cfg); } }); }; /** * 响应状态量更新的快捷方法 * * @param condition * @param style */ BasePlot.prototype.setActive = function (condition, style) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.setActive(condition, style); } }); }; BasePlot.prototype.setSelected = function (condition, style) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.setSelected(condition, style); } }); }; BasePlot.prototype.setDisable = function (condition, style) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.setDisable(condition, style); } }); }; BasePlot.prototype.setDefault = function (condition, style) { this.eachLayer(function (layer) { if (layer instanceof view_layer_1.default) { layer.setDefault(condition, style); } }); }; /** * 获取 Plot 的 View */ BasePlot.prototype.getView = function () { // 临时:避免 getLayer 的类型转换问题 return this.layers[0].view; }; /** * 获取图形下的图层 Layer,默认第一个 Layer * @param idx */ BasePlot.prototype.getLayer = function (idx) { if (idx === void 0) { idx = 0; } return this.layers[idx]; }; BasePlot.prototype.getCanvas = function () { return this.canvasController.canvas; }; BasePlot.prototype.getLayers = function () { return this.layers; }; BasePlot.prototype.render = function () { this.eachLayer(function (layer) { return layer.render(); }); }; BasePlot.prototype.eachLayer = function (cb) { util_1.each(this.layers, cb); }; /** * add children layer * @param layer */ BasePlot.prototype.addLayer = function (layer) { var idx = util_1.findIndex(this.layers, function (item) { return item === layer; }); if (idx < 0) { this.layers.push(layer); } }; BasePlot.prototype.createLayers = function (props) { if (props.layers) { // TODO: combo plot } else if (props.type) { var viewLayerCtr = global_1.getPlotType(props.type); var viewLayerProps = util_1.deepMix({}, props, { canvas: this.canvasController.canvas, x: 0, y: 0, width: this.width, height: this.height, }); var viewLayer = new viewLayerCtr(viewLayerProps); this.addLayer(viewLayer); } }; BasePlot.prototype.parseEvents = function (props) { var _this = this; var eventsName = util_1.keys(event_2.CANVAS_EVENT_MAP); if (props.events) { util_1.each(props.events, function (e, k) { if (util_1.contains(eventsName, k) && util_1.isFunction(e)) { var eventName = event_2.CANVAS_EVENT_MAP[k] || k; var handler = e; _this.on(eventName, handler); } }); } }; return BasePlot; }(event_emitter_1.default)); exports.default = BasePlot; },{"../util/event":677,"./controller/canvas":387,"./controller/event":388,"./global":392,"./layer":393,"./view-layer":395,"@antv/event-emitter":94,"@antv/util":803,"tslib":894}],395:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../dependents"); var description_1 = tslib_1.__importDefault(require("../components/description")); var base_1 = require("../components/label/base"); var factory_1 = require("../components/factory"); var index_1 = tslib_1.__importDefault(require("../interaction/index")); var event_1 = require("../util/event"); var padding_1 = tslib_1.__importDefault(require("./controller/padding")); var state_1 = tslib_1.__importDefault(require("./controller/state")); var theme_1 = tslib_1.__importDefault(require("./controller/theme")); var layer_1 = tslib_1.__importDefault(require("./layer")); var common_1 = require("../util/common"); var bbox_1 = tslib_1.__importStar(require("../util/bbox")); var constants_1 = require("./constants"); var ViewLayer = /** @class */ (function (_super) { tslib_1.__extends(ViewLayer, _super); function ViewLayer(props) { var _this = _super.call(this, props) || this; _this.interactions = []; _this.labels = []; _this.options = _this.getOptions(props); _this.initialOptions = util_1.deepMix({}, _this.options); _this.paddingController = new padding_1.default({ plot: _this, }); _this.stateController = new state_1.default({ plot: _this, }); _this.themeController = new theme_1.default(); return _this; } ViewLayer.getDefaultOptions = function () { return { renderer: 'canvas', title: { visible: false, alignTo: 'left', text: '', }, description: { visible: false, text: '', alignTo: 'left', }, padding: 'auto', legend: { visible: true, position: 'bottom-center', }, tooltip: { visible: true, shared: true, showCrosshairs: true, crosshairs: { type: 'x', }, offset: 20, }, xAxis: { visible: true, grid: { visible: false, }, line: { visible: true, }, tickLine: { visible: true, }, label: { visible: true, autoRotate: true, autoHide: true, }, title: { visible: false, spacing: 12, }, }, yAxis: { visible: true, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { autoRotate: true, visible: false, spacing: 12, }, }, label: { visible: false, }, interactions: [{ type: 'tooltip' }, { type: 'legend-active' }, { type: 'legend-filter' }], animation: true, }; }; ViewLayer.prototype.getOptions = function (props) { var curOptions = this.options || {}; var options = _super.prototype.getOptions.call(this, props); // @ts-ignore var defaultOptions = this.constructor.getDefaultOptions(props); // interactions 需要合并去重下,如果有更新 interactions,需要去掉当前的 interactions 配置 var interactions = util_1.reduce(util_1.flatten(util_1.map([options, defaultOptions, util_1.hasKey(props, 'interactions') ? props : curOptions], function (src) { return util_1.get(src, 'interactions', []); })), function (result, cur) { var idx = util_1.findIndex(result, function (item) { return item.type === cur.type; }); if (idx >= 0) { result.splice(idx, 1); } return tslib_1.__spreadArrays(result, [cur]); }, []); return util_1.deepMix({}, options, defaultOptions, curOptions, props, { interactions: interactions }); }; ViewLayer.prototype.beforeInit = function () { this.emit(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_INIT); _super.prototype.beforeInit.call(this); }; ViewLayer.prototype.init = function () { var _this = this; _super.prototype.init.call(this); this.theme = this.themeController.getTheme(this.options, this.type); this.config = { data: this.processData(this.options.data), scales: {}, legends: {}, tooltip: { showTitle: true, }, axes: {}, coordinate: { type: 'cartesian' }, geometries: [], annotations: [], interactions: [], theme: this.theme, panelRange: {}, animate: {}, views: [], }; this.paddingController.clear(); this.drawTitle(); this.drawDescription(); // 有些interaction要调整配置项,所以顺序提前 this.interaction(); this.coord(); this.scale(); this.axis(); this.tooltip(); this.legend(); this.addGeometry(); this.annotation(); this.animation(); this.viewRange = this.getViewRange(); var region = this.viewRangeToRegion(this.viewRange); this.view = new dependents_1.View({ parent: null, canvas: this.canvas, backgroundGroup: this.container.addGroup(), middleGroup: this.container.addGroup(), foregroundGroup: this.container.addGroup(), padding: this.paddingController.getPadding(), theme: this.theme, options: this.config, limitInPlot: this.isLimitInPlot(), region: region, }); this.applyInteractions(); this.view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, function () { _this.afterRender(); }); }; ViewLayer.prototype.afterInit = function () { _super.prototype.afterInit.call(this); if (!this.view || this.view.destroyed) { return; } if (this.options.padding !== 'auto') { this.parseEvents(); } this.emit(constants_1.VIEW_LAYER_LIFE_CYCLE.AFTER_INIT); }; ViewLayer.prototype.afterRender = function () { var _a, _b; if (!this.view || this.view.destroyed) { return; } var options = this.options; var padding = options.padding ? options.padding : this.config.theme.padding; /** defaultState */ if (options.defaultState && padding !== 'auto') { this.stateController.defaultStates(options.defaultState); } /** autopadding */ if (padding === 'auto') { this.paddingController.processAutoPadding(); } if (((_b = (_a = options.tooltip) === null || _a === void 0 ? void 0 : _a.custom) === null || _b === void 0 ? void 0 : _b.onChange) && options.padding !== 'auto') { this.customTooltip(); } }; /** 完整生命周期渲染 */ ViewLayer.prototype.render = function () { this.emit(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_RENDER); _super.prototype.render.call(this); var data = this.options.data; if (!util_1.isEmpty(data)) { this.view.render(); } this.emit(constants_1.VIEW_LAYER_LIFE_CYCLE.AFTER_RENDER); }; /** 画布重绘 */ ViewLayer.prototype.repaint = function () { if (this.canvas) { this.canvas.draw(); } }; ViewLayer.prototype.getScaleByField = function (field) { return this.view.getScaleByField(field); }; ViewLayer.prototype.getXScale = function () { var xField = this.options.xField; if (xField) { return this.view.getScaleByField(xField); } }; ViewLayer.prototype.getYScale = function () { var yField = this.options.yField; if (yField) { return this.view.getScaleByField(yField); } }; ViewLayer.prototype.getColorScale = function () { var options = this.options; if (util_1.contains(options, 'colorField')) { return this.view.getScaleByField(options); } }; ViewLayer.prototype.getShapes = function () { var geometries = this.view.geometries; var shapes = {}; // todo: geometry 类型转译 util_1.each(geometries, function (geom) { var type = geom.type; shapes[type] = geom.getShapes(); }); return shapes; }; /** 销毁 */ ViewLayer.prototype.destroy = function () { this.doDestroy(); _super.prototype.destroy.call(this); }; /** 更新配置项 */ ViewLayer.prototype.updateConfig = function (cfg) { this.doDestroy(); if (!cfg.padding && this.initialOptions.padding && this.initialOptions.padding === 'auto') { cfg.padding = 'auto'; } this.options = this.getOptions(cfg); this.processOptions(this.options); }; ViewLayer.prototype.changeData = function (data) { this.emit(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_CHANGE_DATA); var isEmptyBefore = util_1.isEmpty(this.options.data); this.options.data = this.processData(data); // 如果之前没有 data if (isEmptyBefore) { this.options.padding = this.initialOptions.padding || 'auto'; this.view.data(this.options.data); this.view.render(); } else { this.view.changeData(this.options.data); } this.emit(constants_1.VIEW_LAYER_LIFE_CYCLE.AFTER_CHANGE_DATA); }; // plot 不断销毁重建,需要一个api获取最新的plot ViewLayer.prototype.getPlot = function () { return this.view; }; /** * 获取已渲染的数据标签组件 */ ViewLayer.prototype.getLabels = function () { return this.labels; }; // 获取对应的G2 Theme ViewLayer.prototype.getTheme = function () { if (!this.theme) { return this.themeController.getTheme(this.options, this.type); } return this.theme; }; ViewLayer.prototype.getResponsiveTheme = function () { return this.themeController.getResponsiveTheme(this.type); }; // 获取对应的Plot Theme ViewLayer.prototype.getPlotTheme = function () { return this.themeController.getPlotTheme(this.options, this.type); }; ViewLayer.prototype.getInteractions = function () { return this.interactions; }; // 绑定一个外部的stateManager ViewLayer.prototype.bindStateManager = function (stateManager, cfg) { this.stateController.bindStateManager(stateManager, cfg); }; // 响应状态量更新的快捷方法 ViewLayer.prototype.setActive = function (condition, style) { this.stateController.setState({ type: 'active', condition: condition, style: style }); }; ViewLayer.prototype.setSelected = function (condition, style) { this.stateController.setState({ type: 'selected', condition: condition, style: style }); }; ViewLayer.prototype.setDisable = function (condition, style) { this.stateController.setState({ type: 'disable', condition: condition, style: style }); }; ViewLayer.prototype.setDefault = function (condition, style) { this.stateController.setState({ type: 'default', condition: condition, style: style }); }; // 获取 ViewLayer 的数据项 ViewLayer.prototype.getData = function (start, end) { return this.processData((this.options.data || []).slice(start, end)); }; ViewLayer.prototype.processData = function (data) { return data; }; ViewLayer.prototype.scale = function () { /** scale meta配置 */ // 1. this.config.scales中已有子图形在处理xAxis/yAxis是写入的xField/yField对应的scale信息,这里再检查用户设置的meta,将meta信息合并到默认的scale中 // 2. 同时xAxis/yAxis中的type优先级更高,覆盖meta中的type配置 var scaleTypes = util_1.mapValues(this.config.scales, function (scaleConfig) { var type = scaleConfig.type; return type ? { type: type } : {}; }); var scales = util_1.deepMix({}, this.config.scales, this.options.meta || {}, scaleTypes); this.setConfig('scales', scales); }; ViewLayer.prototype.axis = function () { var xAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'x', }); var yAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'y', }); var axesConfig = {}; axesConfig[this.options.xField] = xAxis_parser; axesConfig[this.options.yField] = yAxis_parser; /** 存储坐标轴配置项到config */ this.setConfig('axes', axesConfig); }; ViewLayer.prototype.tooltip = function () { var _a, _b; if (this.options.tooltip.visible === false) { this.setConfig('tooltip', false); return; } var tooltipOptions = util_1.get(this.options, 'tooltip'); if ((_a = tooltipOptions.custom) === null || _a === void 0 ? void 0 : _a.container) { tooltipOptions.container = tooltipOptions.custom.container; } if ((_b = tooltipOptions.custom) === null || _b === void 0 ? void 0 : _b.customContent) { tooltipOptions.customContent = tooltipOptions.custom.customContent; } this.setConfig('tooltip', util_1.deepMix({}, tooltipOptions)); util_1.deepMix(this.config.theme.tooltip, this.options.tooltip.domStyles); }; ViewLayer.prototype.createTooltipContainer = function () { var container = document.createElement('div'); container.className = 'g2-tooltip'; return container; }; ViewLayer.prototype.customTooltip = function () { var customContentCfg = this.options.tooltip.custom; var container; if (customContentCfg.container) { container = util_1.isString(customContentCfg.container) ? document.getElementById(customContentCfg.container) : customContentCfg.container; } if (!container) { container = this.createTooltipContainer(); } this.view.on('tooltip:show', function (ev) { if (customContentCfg === null || customContentCfg === void 0 ? void 0 : customContentCfg.onChange) { customContentCfg.onChange(container, ev); } }); this.view.hideTooltip(); this.view.on('tooltip:change', function (ev) { customContentCfg.onChange(container, ev); }); }; ViewLayer.prototype.getLegendPosition = function (position) { var positionList = position.split('-'); // G2 4.0 兼容 XXX-center 到 XXX 的场景 if (positionList && positionList.length > 1 && positionList[1] === 'center') { return positionList[0]; } return position; }; ViewLayer.prototype.legend = function () { var _a; if (this.options.legend.visible === false) { this.setConfig('legends', false); return; } var options = util_1.deepMix({}, this.theme.legend, this.options.legend); var legendConfig = { position: this.getLegendPosition(util_1.get(options, 'position')), offsetX: util_1.get(options, 'offsetX'), offsetY: util_1.get(options, 'offsetY'), flipPage: util_1.get(options, 'flipPage'), marker: util_1.get(options, 'marker'), title: ((_a = options.title) === null || _a === void 0 ? void 0 : _a.visible) ? util_1.get(options, 'title') : null, itemName: util_1.get(options, 'text'), }; this.setConfig('legends', legendConfig); }; ViewLayer.prototype.annotation = function () { var _this = this; var config = []; if (this.config.coordinate.type === 'cartesian' && this.options.guideLine) { util_1.each(this.options.guideLine, function (line) { var guideLine = factory_1.getComponent('guideLine', { plot: _this, cfg: line, }); config.push(guideLine); }); } this.setConfig('annotations', config); }; ViewLayer.prototype.interaction = function () { var _this = this; var _a = this.options.interactions, interactions = _a === void 0 ? [] : _a; util_1.each(interactions, function (interaction) { var type = interaction.type; if (type === 'slider' || type === 'scrollbar') { var axisConfig = { label: { autoHide: true, autoRotate: false, }, }; _this.options.xAxis = util_1.deepMix({}, _this.options.xAxis, axisConfig); } _this.setConfig('interaction', interaction); }); }; ViewLayer.prototype.animation = function () { if (this.options.animation === false) { this.setConfig('animate', false); } }; ViewLayer.prototype.applyInteractions = function () { var _this = this; var range = bbox_1.default.fromBBoxObject(this.layerBBox); // 临时去掉 title/description 的占用 var titleOrDesc = this.title || this.description; var extraBBox = new bbox_1.default(range.minX, range.minY, range.width, titleOrDesc ? titleOrDesc.getBBox().maxY : 0); range = range.cut(extraBBox, bbox_1.DIRECTION.TOP); var _a = this.options.interactions, interactions = _a === void 0 ? [] : _a; if (this.interactions) { this.interactions.forEach(function (inst) { inst.destroy(); }); } this.interactions = []; interactions.forEach(function (interaction) { var Ctor = index_1.default.getInteraction(interaction.type, _this.type); if (Ctor) { var inst = new Ctor({ view: _this.view }, _this, Ctor.getInteractionRange(range, interaction.cfg), interaction.cfg); inst.render(); _this.interactions.push(inst); } }); }; /** 设置G2 config,带有类型推导 */ ViewLayer.prototype.setConfig = function (key, config) { if (key === 'geometry') { this.config.geometries.push(config); return; } if (key === 'interaction') { this.config.interactions.push(config); return; } if (config === false) { this.config[key] = false; return; } util_1.assign(this.config[key], config); }; ViewLayer.prototype.parseEvents = function (eventParser) { var _this = this; var options = this.options; if (options.events) { _super.prototype.parseEvents.call(this, options.events); var eventmap_1 = eventParser ? eventParser.EVENT_MAP : event_1.EVENT_MAP; util_1.each(options.events, function (e, k) { if (util_1.isFunction(e)) { var eventName = eventmap_1[k] || k; var handler = e; event_1.onEvent(_this, eventName, handler); } }); } }; ViewLayer.prototype.drawTitle = function () { var props = this.options; var range = this.layerBBox; if (this.title) { this.title.destroy(); this.title = null; } if (common_1.isTextUsable(props.title)) { var width = this.width; var theme = this.config.theme; var title = new description_1.default({ leftMargin: range.minX + theme.title.padding[3], rightMargin: range.maxX - theme.title.padding[1], topMargin: range.minY + theme.title.padding[0], text: props.title.text, style: util_1.mix(theme.title, props.title.style), wrapperWidth: width - theme.title.padding[3] - theme.title.padding[1], container: this.container.addGroup(), theme: theme, index: common_1.isTextUsable(props.description) ? 0 : 1, plot: this, alignTo: props.title.alignTo, name: 'title', }); this.title = title; this.paddingController.registerPadding(title, 'outer'); } }; ViewLayer.prototype.drawDescription = function () { var props = this.options; var range = this.layerBBox; if (this.description) { this.description.destroy(); this.description = null; } if (common_1.isTextUsable(props.description)) { var width = this.width; var theme = this.config.theme; var topMargin = 0; if (this.title) { var titleBBox = this.title.getBBox(); topMargin += titleBBox.minY + titleBBox.height; topMargin += theme.description.padding[0]; } else { // 无title的情况下使用title的上padding topMargin += range.minY + theme.title.padding[0]; } var description = new description_1.default({ leftMargin: range.minX + theme.description.padding[3], topMargin: topMargin, rightMargin: range.maxX - theme.title.padding[1], text: props.description.text, style: util_1.mix(theme.description, props.description.style), wrapperWidth: width - theme.description.padding[3] - theme.description.padding[1], container: this.container.addGroup(), theme: theme, index: 1, plot: this, alignTo: props.description.alignTo, name: 'description', }); this.description = description; this.paddingController.registerPadding(description, 'outer'); } }; ViewLayer.prototype.doRenderLabel = function (geometry, label) { util_1.each(this.labels, function (item) { item.destroy(); }); this.labels = []; var config = { layer: this, container: geometry.labelsContainer, geometry: geometry, label: label, }; var Ctor = base_1.getLabelComponent(label.type); if (Ctor) { var label_1 = new Ctor(config); label_1.init(); label_1.render(); this.labels.push(label_1); } }; /** 抽取destroy和updateConfig共有代码为_destroy方法 */ ViewLayer.prototype.doDestroy = function () { this.doDestroyInteractions(); this.doDestroyLabels(); /** 销毁g2.view实例 */ if (!this.view.destroyed) { this.view.destroy(); } }; ViewLayer.prototype.doDestroyInteractions = function () { // 移除注册的 interactions if (this.interactions) { this.interactions.forEach(function (inst) { inst.destroy(); }); } this.interactions = []; }; ViewLayer.prototype.doDestroyLabels = function () { // 移除各 geometry 的 label util_1.each(this.labels, function (label) { label.destroy(); }); this.labels = []; }; ViewLayer.prototype.getViewRange = function () { var _this = this; // 有 Range 的 Interaction 参与 ViewMargin 计算 var _a = this.options.interactions, interactions = _a === void 0 ? [] : _a; // const layerBBox = this.layerBBox; var layerBBox = this.paddingController.processOuterPadding(); interactions.forEach(function (interaction) { var Ctor = index_1.default.getInteraction(interaction.type, _this.type); var range = Ctor && Ctor.getInteractionRange(layerBBox, interaction.cfg); var position = ''; if (range) { // 先只考虑 Range 靠边的情况 if (range.maxY === layerBBox.maxY && range.minY > layerBBox.minY) { // margin[2] += range.height; position = 'bottom'; } else if (range.maxX === layerBBox.maxX && range.minX > layerBBox.minX) { // margin[1] += range.width; position = 'right'; } else if (range.minX === layerBBox.minX && range.maxX > layerBBox.maxX) { // margin[3] += range.width; position = 'left'; } else if (range.minY === layerBBox.minY && range.maxY < layerBBox.maxY) { // margin[0] += range.height; position = 'top'; } _this.paddingController.registerPadding({ interaction: interaction.type, name: interaction.type, getBBox: function () { return range; }, position: position, }, 'outer'); } }); var viewRange = this.paddingController.processOuterPadding(); return viewRange; }; ViewLayer.prototype.isLimitInPlot = function () { var yAxisOptions = this.options.yAxis; if (util_1.hasKey(yAxisOptions, 'max') || util_1.hasKey(yAxisOptions, 'min') || util_1.hasKey(yAxisOptions, 'maxLimit') || util_1.hasKey(yAxisOptions, 'minLimit')) { return true; } return false; }; ViewLayer.prototype.viewRangeToRegion = function (viewRange) { var _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var start = { x: 0, y: 0 }, end = { x: 1, y: 1 }; start.x = viewRange.minX / (x + width); start.y = viewRange.minY / (y + height); end.x = viewRange.maxX / (x + width); end.y = viewRange.maxY / (y + height); return { start: start, end: end, }; }; return ViewLayer; }(layer_1.default)); exports.default = ViewLayer; },{"../components/description":411,"../components/factory":412,"../components/label/base":414,"../dependents":425,"../interaction/index":444,"../util/bbox":672,"../util/common":674,"../util/event":677,"./constants":386,"./controller/padding":389,"./controller/state":390,"./controller/theme":391,"./layer":393,"@antv/util":803,"tslib":894}],396:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var scale_1 = require("@antv/scale"); var description_1 = tslib_1.__importDefault(require("../components/description")); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var layer_1 = tslib_1.__importDefault(require("../base/layer")); var common_1 = require("../util/common"); var theme_1 = tslib_1.__importDefault(require("../base/controller/theme")); var theme_2 = require("../theme"); var LEGEND_MARGIN = 5; var ComboViewLayer = /** @class */ (function (_super) { tslib_1.__extends(ComboViewLayer, _super); function ComboViewLayer(props) { var _this = _super.call(this, props) || this; _this.geomLayers = []; _this.legends = []; _this.requiredField = ['xField', 'yField']; _this.options = _this.getOptions(props); _this.initialOptions = util_1.deepMix({}, props); _this.themeController = new theme_1.default(); return _this; } ComboViewLayer.getDefaultOptions = function () { return { title: { visible: false, alignTo: 'left', text: '', }, description: { visible: false, text: '', alignTo: 'left', }, }; }; ComboViewLayer.prototype.getOptions = function (props) { var curOptions = this.options || {}; var options = _super.prototype.getOptions.call(this, props); // @ts-ignore var defaultOptions = this.constructor.getDefaultOptions(props); return util_1.deepMix({}, options, defaultOptions, curOptions, props); }; ComboViewLayer.prototype.checkData = function () { var _this = this; var _a, _b; var _c = this.options, data = _c.data, xField = _c.xField, yField = _c.yField; // 判断1: 没有配置必选字段时不绘制 for (var i = 0; i < this.requiredField.length; i++) { var field = this.requiredField[i]; if (!util_1.hasKey(this.options, field)) { return false; } } // 判断2: yField不是数组或只设置了一个字段时不绘制 if (!util_1.isArray(yField) || yField.length < 2) { return false; } // 判断3:data为空时不绘制 data:[] if (!util_1.isArray(data) || data.length === 0) { return false; } // 判断4: 内嵌两层空数据时不绘制 data:[[],[]] if (((_a = data[0]) === null || _a === void 0 ? void 0 : _a.length) === 0 && ((_b = data[1]) === null || _b === void 0 ? void 0 : _b.length) === 0) { return false; } // 判断5:一层数据为空时,利用相关映射字段补齐数据 data:[[],[{type:'a',value:10}] util_1.each(data, function (d, index) { if (!util_1.isArray(d) || d.length === 0) { var mockData = _this.getMockData(index); data[index] = mockData; } }); // 判断6: 两份数据xField或值不一致时不绘制 if (!data[0][0][xField] || !data[1][0][xField]) { return false; } return true; }; ComboViewLayer.prototype.init = function () { _super.prototype.init.call(this); this.theme = this.themeController.getTheme(this.options, this.type); this.drawTitle(); this.drawDescription(); }; ComboViewLayer.prototype.updateConfig = function (cfg) { this.doDestroy(); this.options = this.getOptions(cfg); this.processOptions(this.options); }; ComboViewLayer.prototype.changeData = function (data) { if ((data && data.length < 2) || !util_1.isArray(data[0])) { return; } util_1.each(this.geomLayers, function (layer, index) { layer.changeData(data[index]); }); }; ComboViewLayer.prototype.changeDataByIndex = function (data, index) { if (util_1.isArray(data[0])) { return; } var geomLayer = this.geomLayers[index]; geomLayer.changeData(data); }; ComboViewLayer.prototype.doDestroy = function () { util_1.each(this.geomLayers, function (layer) { layer.doDestroy(); }); this.geomLayers = []; util_1.each(this.legends, function (legend) { legend.destroy(); }); this.legends = []; }; ComboViewLayer.prototype.createLayer = function (LayerCtr, data, config) { var viewRange = this.getViewRange(); var layer = new LayerCtr(tslib_1.__assign({ canvas: this.canvas, container: this.container, x: viewRange.minX, y: viewRange.minY, width: viewRange.width, height: viewRange.height, data: data }, config)); this.geomLayers.push(layer); return layer; }; // 临时修复 v1 双轴图在左侧数据为0的时候右侧scale处理错误的问题 ComboViewLayer.prototype.getLeftYAxisMax = function () { var leftScaleData = this.getScaleData(0); var rightScaleData = this.getScaleData(1); return leftScaleData.min == 0 && leftScaleData.max === 0 ? Math.max(rightScaleData.max, 0) : leftScaleData.max; }; ComboViewLayer.prototype.yAxis = function (index) { var leftScaleData = this.getScaleData(0); var yAxis = this.options.yAxis; var config = index === 0 ? yAxis.leftConfig : yAxis.rightConfig; var colorValue = this.colors[index]; var yAxisConfig = util_1.clone(config); var styleMap = { title: 'stroke', line: 'stroke', label: 'fill', tickLine: 'stroke', }; if (config.visible && config.colorMapping) { util_1.each(yAxisConfig, function (config, name) { if (!util_1.isString(config) && util_1.hasKey(styleMap, name)) { var styleKey = styleMap[name]; if (!config.style) { config.style = {}; } config.style[styleKey] = colorValue; } }); } if (!config.visible) { yAxisConfig.title.visible = false; yAxisConfig.tickLine.visible = false; yAxisConfig.label.visible = false; yAxisConfig.line.visible = false; yAxisConfig.visible = true; } var yAxisGlobalConfig = this.getYAxisGlobalConfig(); if (index === 0 && leftScaleData.max === 0 && leftScaleData.min === 0) { yAxisConfig.max = this.getLeftYAxisMax(); } return util_1.deepMix({}, yAxisGlobalConfig, yAxisConfig); }; ComboViewLayer.prototype.getTicks = function () { var yAxis = this.options.yAxis; var leftScaleData = this.getScaleData(0); // 取到左轴ticks数量 var Scale = scale_1.getScale('linear'); var linearScale = new Scale(util_1.deepMix({}, { min: 0, max: this.getLeftYAxisMax(), nice: true, values: leftScaleData.values, }, { tickCount: yAxis.tickCount, })); var tickCount = linearScale.ticks.length; // 生成右轴ticks var max = yAxis.max ? linearScale.max : this.getScaleData(1).max; var tickInterval = max / (tickCount - 1); var ticks = []; for (var i = 0; i < tickCount; i++) { var tickValue = i * tickInterval; if (!Number.isInteger(tickValue)) { tickValue = parseFloat(tickValue.toFixed(1)); } ticks.push(tickValue); } return ticks; }; ComboViewLayer.prototype.getScaleData = function (index) { var _a = this.options, data = _a.data, yField = _a.yField, yAxis = _a.yAxis; var values = []; util_1.each(data[index], function (d) { values.push(d[yField[index]]); }); values.sort(function (a, b) { return a - b; }); var min = values[0]; var max = yAxis.max ? yAxis.max : values[values.length - 1]; return { min: min, max: max, values: values }; }; ComboViewLayer.prototype.getDataByXField = function (value, index) { var _a = this.options, data = _a.data, xField = _a.xField; var dataSource = data[index]; return dataSource.filter(function (d) { return d[xField] === value; }); }; ComboViewLayer.prototype.getYAxisGlobalConfig = function () { var _a = this.options.yAxis, min = _a.min, max = _a.max, tickCount = _a.tickCount; return { min: min, max: max, tickCount: tickCount }; }; ComboViewLayer.prototype.adjustLayout = function () { var _this = this; var _a, _b; var bleeding = theme_2.getGlobalTheme().bleeding; if (util_1.isArray(bleeding)) { util_1.each(bleeding, function (it, index) { if (typeof bleeding[index] === 'function') { bleeding[index] = bleeding[index](_this.options); } }); } var viewRange = this.getViewRange(); var leftPadding = this.transfromPadding(this.geomLayers[0].options.padding); var rightPadding = this.transfromPadding(this.geomLayers[1].options.padding); // 获取legendHeight并加入上部padding var legendHeight = 0; var legendABBox; var legendBBBox; if ((_a = this.options.legend) === null || _a === void 0 ? void 0 : _a.visible) { legendABBox = this.legends[0].getLayoutBBox(); legendBBBox = this.legends[1].getLayoutBBox(); legendHeight = legendABBox.height + LEGEND_MARGIN * 2; } // 同步左右padding // const uniquePadding = [leftPadding[0] + legendHeight, rightPadding[1], rightPadding[2], leftPadding[3]]; var uniquePadding = leftPadding.map(function (item, index) { // 兼容老版本 if (index === 0) { return Math.max.apply(null, [item + legendHeight, rightPadding[index]]); } return Math.max.apply(null, [item, rightPadding[index]]); }); this.geomLayers[0].updateConfig({ padding: uniquePadding, }); this.geomLayers[0].render(); this.geomLayers[1].updateConfig({ padding: uniquePadding, }); this.geomLayers[1].render(); // 更新legend的位置 if ((_b = this.options.legend) === null || _b === void 0 ? void 0 : _b.visible) { this.legends[0].setLocation({ x: bleeding[3], y: viewRange.minY + LEGEND_MARGIN, }); this.legends[1].setLocation({ x: viewRange.maxX - bleeding[1] - legendBBBox.width, y: viewRange.minY + LEGEND_MARGIN, }); } }; /** * padding 预处理 * @param {string | number | number[]} padding */ ComboViewLayer.prototype.transfromPadding = function (padding) { if (typeof padding === 'string' || typeof padding === 'number') { return [Number(padding)]; } return padding; }; ComboViewLayer.prototype.legendFilter = function (index) { var _this = this; var legend = this.legends[index]; var legend_group = legend.get('group'); legend_group.on('click', function () { var item = legend.get('items')[0]; if (!item.unchecked) { legend.setItemState(item, 'unchecked', true); _this.hideLayer(index); } else { legend.setItemState(item, 'unchecked', false); _this.showLayer(index); } }); }; ComboViewLayer.prototype.hideLayer = function (index) { var layer = this.geomLayers[index]; var field = this.options.yField[index]; // 隐藏layer时只隐藏yAxis和geometry var view = layer.view; var axisContainer = this.getYAxisContainer(view, field); if (axisContainer) { axisContainer.set('visible', false); } this.setGeometryVisibility(view, false); this.canvas.draw(); }; ComboViewLayer.prototype.showLayer = function (index) { var layer = this.geomLayers[index]; var field = this.options.yField[index]; var view = layer.view; var axisContainer = this.getYAxisContainer(view, field); if (axisContainer) { axisContainer.set('visible', true); } this.setGeometryVisibility(view, true); this.canvas.draw(); }; ComboViewLayer.prototype.setGeometryVisibility = function (view, show) { util_1.each(view.geometries, function (geom) { var container = geom.container, labelsContainer = geom.labelsContainer; if (container) { container.set('visible', show); } if (labelsContainer) { labelsContainer.set('visible', show); } }); }; ComboViewLayer.prototype.getYAxisContainer = function (view, field) { var container; var axisCtr = view.controllers.filter(function (ctr) { return util_1.hasKey(ctr, 'axisContainer'); })[0]; if (axisCtr) { var ctr = axisCtr; var axisGroups = ctr.axisContainer.get('children'); util_1.each(axisGroups, function (g) { var axisField = g.get('component').get('field'); if (axisField === field) { container = g; } }); } return container; }; ComboViewLayer.prototype.getUnCheckedValue = function () { var value = []; util_1.each(this.legends, function (legend) { var uncheckedItems = legend.getItemsByState('unchecked'); util_1.each(uncheckedItems, function (item) { value.push(item.name); }); }); return value; }; ComboViewLayer.prototype.drawTitle = function () { var props = this.options; var range = this.layerBBox; if (this.title) { this.title.destroy(); this.title = null; } if (common_1.isTextUsable(props.title)) { var width = this.width; var theme = this.theme; var title = new description_1.default({ leftMargin: range.minX + theme.title.padding[3], rightMargin: range.maxX - theme.title.padding[1], topMargin: range.minY + theme.title.padding[0], text: props.title.text, style: util_1.mix(theme.title, props.title.style), wrapperWidth: width - theme.title.padding[3] - theme.title.padding[1], container: this.container.addGroup(), theme: theme, index: common_1.isTextUsable(props.description) ? 0 : 1, plot: this, alignTo: props.title.alignTo, name: 'title', }); this.title = title; } }; ComboViewLayer.prototype.drawDescription = function () { var props = this.options; var range = this.layerBBox; if (this.description) { this.description.destroy(); this.description = null; } if (common_1.isTextUsable(props.description)) { var width = this.width; var theme = this.theme; var topMargin = 0; if (this.title) { var titleBBox = this.title.getBBox(); topMargin += titleBBox.minY + titleBBox.height; topMargin += theme.description.padding[0]; } else { // 无title的情况下使用title的上padding topMargin += range.minY + theme.title.padding[0]; } var description = new description_1.default({ leftMargin: range.minX + theme.description.padding[3], topMargin: topMargin, rightMargin: range.maxX - theme.title.padding[1], text: props.description.text, style: util_1.mix(theme.description, props.description.style), wrapperWidth: width - theme.description.padding[3] - theme.description.padding[1], container: this.container.addGroup(), theme: theme, index: 1, plot: this, alignTo: props.description.alignTo, name: 'description', }); this.description = description; } }; ComboViewLayer.prototype.getViewRange = function () { if (!this.layerBBox) { this.layerBBox = new bbox_1.default(this.x, this.y, this.width, this.height); } var viewMinX = this.layerBBox.minX; var viewMaxX = this.layerBBox.maxX; var viewMinY = this.layerBBox.minY; var viewMaxY = this.layerBBox.maxY; var components = [this.title, this.description]; util_1.each(components, function (component) { if (component) { var position = component.position; var _a = component.getBBox(), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY; if (maxY >= viewMinY && maxY <= viewMaxY && position === 'top') { viewMinY = maxY; } if (minY >= viewMinY && minY <= viewMaxY && position === 'bottom') { viewMaxY = minY; } if (maxX > viewMinX && maxX <= viewMaxX && position === 'left') { viewMinX = maxX; } if (minX >= viewMinX && maxX <= viewMaxX && position === 'right') { viewMaxX = minX; } } }); return new bbox_1.default(viewMinX, viewMinY, viewMaxX - viewMinX, viewMaxY - viewMinY); }; ComboViewLayer.prototype.getMockData = function (index) { var _a = this.options, xField = _a.xField, yField = _a.yField; var mock = {}; mock[xField] = 'null'; mock[yField[index]] = 0; return [mock]; }; return ComboViewLayer; }(layer_1.default)); exports.default = ComboViewLayer; },{"../base/controller/theme":391,"../base/layer":393,"../components/description":411,"../theme":669,"../util/bbox":672,"../util/common":674,"@antv/scale":747,"@antv/util":803,"tslib":894}],397:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var ColumnLine = /** @class */ (function (_super) { tslib_1.__extends(ColumnLine, _super); function ColumnLine() { return _super !== null && _super.apply(this, arguments) || this; } ColumnLine.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'columnLine'; _super.prototype.createLayers.call(this, layerProps); }; ColumnLine.getDefaultOptions = layer_1.default.getDefaultOptions; return ColumnLine; }(plot_1.default)); exports.default = ColumnLine; },{"../../base/plot":394,"./layer":398,"@antv/util":803,"tslib":894}],398:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var component_1 = require("@antv/component"); var global_1 = require("../../base/global"); var base_1 = tslib_1.__importDefault(require("../base")); var layer_1 = tslib_1.__importDefault(require("../../plots/line/layer")); var layer_2 = tslib_1.__importDefault(require("../../plots/column/layer")); var util_1 = require("@antv/util"); var theme_1 = require("../../theme"); var defaultLineConfig = { color: '#f5bc32', lineSize: 4, connectNull: true, point: { visible: false, size: 3, shape: 'circle', style: { stroke: '#fff', }, }, label: { visible: false, }, }; var defaultColumnConfig = { color: '#5B8FF9', }; var defaultYAxisConfig = { visible: true, colorMapping: true, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { autoRotate: true, visible: false, spacing: 12, }, }; var ColumnLineLayer = /** @class */ (function (_super) { tslib_1.__extends(ColumnLineLayer, _super); function ColumnLineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'columnLine'; _this.legends = []; return _this; } ColumnLineLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { yAxis: { leftConfig: defaultYAxisConfig, rightConfig: defaultYAxisConfig, }, lineConfig: defaultLineConfig, columnConfig: defaultColumnConfig, legend: { visible: true, }, }); }; ColumnLineLayer.prototype.beforeInit = function () { var _a, _b; var _c = this, options = _c.options, initialOptions = _c.initialOptions; if (options.lineSeriesField) { options.yAxis.rightConfig.colorMapping = false; if (!((_a = initialOptions.lineConfig) === null || _a === void 0 ? void 0 : _a.lineSize)) { options.lineConfig.lineSize = 3; } if (!((_b = initialOptions.lineConfig) === null || _b === void 0 ? void 0 : _b.color)) { var _d = theme_1.getGlobalTheme(), colors = _d.colors, colors_20 = _d.colors_20; var seriesValue = this.getValueBySeriesField(); var colorSeries_1 = seriesValue.length > colors.length ? colors_20 : colors; var colorPlates_1 = []; util_1.each(seriesValue, function (v, index) { colorPlates_1.push(colorSeries_1[index + 1]); }); options.lineConfig.color = colorPlates_1; } } }; ColumnLineLayer.prototype.init = function () { _super.prototype.init.call(this); if (!this.checkData()) { return; } var _a = this.options, data = _a.data, meta = _a.meta, xField = _a.xField, yField = _a.yField, lineSeriesField = _a.lineSeriesField, legend = _a.legend, lineConfig = _a.lineConfig, columnConfig = _a.columnConfig, events = _a.events, customMeta = _a.customMeta; this.colors = [columnConfig.color, lineConfig.color]; // draw column this.drawColumn(); //draw line var metaInfo = {}; metaInfo[yField[1]] = { ticks: this.getTicks() }; var line = this.createLayer(layer_1.default, data[1], tslib_1.__assign({ xField: xField, yField: yField[1], seriesField: lineSeriesField, meta: !customMeta ? util_1.deepMix({}, meta, metaInfo) : meta, xAxis: { visible: false, }, yAxis: util_1.deepMix({}, { position: 'right', grid: { visible: false, }, nice: true, }, this.yAxis(1)), tooltip: { visible: false, }, legend: { visible: false, }, events: events }, lineConfig)); line.render(); if (legend.visible) { this.customLegend(); } this.adjustLayout(); }; ColumnLineLayer.prototype.drawColumn = function () { var _this = this; var _a = this.options, data = _a.data, xField = _a.xField, yField = _a.yField, xAxis = _a.xAxis, tooltip = _a.tooltip, columnConfig = _a.columnConfig, meta = _a.meta, events = _a.events; var column = this.createLayer(layer_2.default, data[0], tslib_1.__assign({ xField: xField, yField: yField[0], meta: meta, xAxis: xAxis, yAxis: util_1.deepMix({}, { grid: { visible: true, }, nice: true, }, this.yAxis(0)), tooltip: util_1.deepMix({}, { showMarkers: false, custom: { onChange: function (containerDom, ev) { _this.tooltip(containerDom, ev); }, }, }, tooltip), events: events }, columnConfig)); column.render(); }; ColumnLineLayer.prototype.tooltip = function (dom, ev) { var _this = this; var _a = this.options, xField = _a.xField, yField = _a.yField, tooltip = _a.tooltip; var originItem = util_1.clone(ev.items[0]); var dataItemsA = this.getDataByXField(ev.title, 1); var formatter = util_1.get(tooltip, 'formatter'); if (dataItemsA) { util_1.each(dataItemsA, function (d, index) { var seriesField = _this.geomLayers[1].options.seriesField; var name = seriesField ? d[seriesField] : yField[1]; // 如果有 formatter 就执行 formatter,否则不处理 var item = formatter ? formatter(d[xField], d[yField[1]], d[seriesField]) : { name: name, value: d[yField[1]], }; ev.items.push(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, originItem), { mappingData: util_1.deepMix({}, originItem.mappingData, { _origin: dataItemsA }), data: d }), item), { color: util_1.isArray(_this.colors[1]) ? _this.colors[1][index] : _this.colors[1] })); }); } if (this.options.legend.visible) { var unCheckedValue_1 = this.getUnCheckedValue(); var totalItems = this.legends[0].get('items').length + this.legends[1].get('items').length; // 如果legend全部是unchecked的状态,tooltip不显示 if (unCheckedValue_1.length === totalItems) { dom.style.display = 'none'; return; } else { dom.style.display = 'block'; } // legend部分checked的时候,根据checked状态filter items var uniqKeys_1 = []; var uniqItems_1 = []; util_1.each(ev.items, function (item) { var name = item.name; if (!util_1.contains(uniqKeys_1, name) && !util_1.contains(unCheckedValue_1, name)) { uniqKeys_1.push(name); uniqItems_1.push(item); } }); util_1.each(ev.items, function (item, index) { if (index < uniqItems_1.length) { ev.items[index] = uniqItems_1[index]; } else { ev.items.pop(); } }); } }; ColumnLineLayer.prototype.customLegend = function () { var _this = this; var _a = this.options, yField = _a.yField, legend = _a.legend; var colors = this.colors; var container = this.container.addGroup(); var legendCfg = legend; var symbols = ['square', 'circle']; util_1.each(this.geomLayers, function (geom, index) { var legend; if (geom.options.seriesField) { var values = _this.getValueBySeriesField(); legend = _this.createNormalLegend(values, symbols[index], colors[index], legendCfg, container); } else { legend = _this.createSingleLegend(yField[index], symbols[index], colors[index], legendCfg, container); } _this.legends.push(legend); }); // 使用legend做图层筛选 util_1.each(this.geomLayers, function (geom, index) { if (geom.options.seriesField) { _this.multipleLegendFilter(index, geom.options.seriesField); } else { _this.legendFilter(index); } }); }; ColumnLineLayer.prototype.createSingleLegend = function (name, symbol, color, cfg, container) { var markerCfg = util_1.deepMix({}, { symbol: symbol, style: { r: 4, fill: color, }, }, cfg.marker); var items = [ { name: name, unchecked: false, marker: markerCfg, }, ]; var legend = new component_1.Legend.Category({ id: this.type, container: container, x: 0, y: 0, items: items, updateAutoRender: true, itemBackground: null, itemName: cfg.text, }); legend.init(); legend.render(); return legend; }; ColumnLineLayer.prototype.createNormalLegend = function (values, symbol, color, cfg, container) { var legendItems = []; util_1.each(values, function (v, index) { legendItems.push({ name: v, unchecked: false, marker: { symbol: symbol, style: { r: 4, fill: color[index], }, }, }); }); var legend = new component_1.Legend.Category({ id: this.type, container: container, x: 0, y: 0, items: legendItems, updateAutoRender: true, itemBackground: null, itemName: cfg.text, offsetX: 0, }); legend.init(); legend.render(); return legend; }; ColumnLineLayer.prototype.multipleLegendFilter = function (index, field) { var _this = this; var legend = this.legends[index]; var filteredValue = []; var legend_group = legend.get('group'); var layerHide = false; legend_group.on('click', function (ev) { var view = _this.geomLayers[index].view; var item = ev.target.get('delegateObject').item; if (item.unchecked) { if (layerHide === true) { _this.showLayer(index); layerHide = false; } util_1.pull(filteredValue, item.name); view.filter(item.value, function (f) { return !util_1.contains(filteredValue, f); }); view.render(); legend.setItemState(item, 'unchecked', false); } else { legend.setItemState(item, 'unchecked', true); filteredValue.push(item.name); if (filteredValue.length === _this.legends[index].get('items').length) { // 如果分组分类全部被uncheck了,直接隐藏图层,这样仍然可以trigger tooltip _this.hideLayer(index); layerHide = true; } else { view.filter(field, function (f) { return !util_1.contains(filteredValue, f); }); view.render(); } } _this.canvas.draw(); }); }; ColumnLineLayer.prototype.getValueBySeriesField = function () { var _a = this.options, lineSeriesField = _a.lineSeriesField, data = _a.data; var lineData = data[1]; var values = []; util_1.each(lineData, function (d) { var v = d[lineSeriesField]; if (!util_1.contains(values, v)) { values.push(v); } }); return values; }; return ColumnLineLayer; }(base_1.default)); exports.default = ColumnLineLayer; global_1.registerPlotType('columnLine', ColumnLineLayer); },{"../../base/global":392,"../../plots/column/layer":490,"../../plots/line/layer":558,"../../theme":669,"../base":396,"@antv/component":51,"@antv/util":803,"tslib":894}],399:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var DualLine = /** @class */ (function (_super) { tslib_1.__extends(DualLine, _super); function DualLine() { return _super !== null && _super.apply(this, arguments) || this; } DualLine.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'dualLine'; _super.prototype.createLayers.call(this, layerProps); }; DualLine.getDefaultOptions = layer_1.default.getDefaultOptions; return DualLine; }(plot_1.default)); exports.default = DualLine; },{"../../base/plot":394,"./layer":400,"@antv/util":803,"tslib":894}],400:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var component_1 = require("@antv/component"); var global_1 = require("../../base/global"); var base_1 = tslib_1.__importDefault(require("../base")); var layer_1 = tslib_1.__importDefault(require("../../plots/line/layer")); var util_1 = require("@antv/util"); var defaultLineConfig = { lineSize: 2, connectNull: true, point: { visible: false, size: 3, shape: 'circle', style: { stroke: '#fff', }, }, label: { visible: false, }, }; var defaultYAxisConfig = { visible: true, colorMapping: true, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { autoRotate: true, visible: false, offset: 12, }, }; var DualLineLayer = /** @class */ (function (_super) { tslib_1.__extends(DualLineLayer, _super); function DualLineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'dualLine'; return _this; } DualLineLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { legend: { visible: true, }, yAxis: { leftConfig: defaultYAxisConfig, rightConfig: defaultYAxisConfig, }, // 自古红蓝出cp.... lineConfigs: [ util_1.deepMix({}, defaultLineConfig, { color: '#5B8FF9' }), util_1.deepMix({}, defaultLineConfig, { color: '#e76c5e' }), ], }); }; DualLineLayer.prototype.init = function () { var _this = this; _super.prototype.init.call(this); if (!this.checkData()) { return; } var _a = this.options, data = _a.data, meta = _a.meta, xField = _a.xField, yField = _a.yField, xAxis = _a.xAxis, tooltip = _a.tooltip, lineConfigs = _a.lineConfigs, legend = _a.legend, events = _a.events, customMeta = _a.customMeta; this.colors = [lineConfigs[0].color, lineConfigs[1].color]; var yAxisGlobalConfig = this.getYAxisGlobalConfig(); //draw first line var leftLine = this.createLayer(layer_1.default, data[0], tslib_1.__assign({ meta: meta, xField: xField, yField: yField[0], xAxis: { visible: false, }, yAxis: util_1.deepMix({}, yAxisGlobalConfig, { grid: { visible: false, }, nice: true, }, this.yAxis(0)), tooltip: { visible: false, }, events: events }, lineConfigs[0])); leftLine.render(); //draw second line var metaInfo = {}; metaInfo[yField[1]] = { ticks: this.getTicks() }; var rightLine = this.createLayer(layer_1.default, data[1], tslib_1.__assign({ xField: xField, yField: yField[1], meta: !customMeta ? util_1.deepMix({}, meta, metaInfo) : meta, serieField: yField[1], xAxis: xAxis, yAxis: util_1.deepMix({}, yAxisGlobalConfig, { position: 'right', nice: false, }, this.yAxis(1)), tooltip: util_1.deepMix({}, { showMarkers: false, custom: { onChange: function (containerDom, ev) { _this.tooltip(containerDom, ev); }, }, }, tooltip), events: events }, lineConfigs[1])); rightLine.render(); if (legend.visible) { this.customLegend(); } this.adjustLayout(); }; DualLineLayer.prototype.tooltip = function (dom, ev) { var unCheckedValue = this.getUnCheckedValue(); // 如果legend全部是unchecked的状态,tooltip不显示 if (unCheckedValue.length === this.colors.length) { dom.style.display = 'none'; return; } else { dom.style.display = 'block'; } var _a = this.options, yField = _a.yField, legend = _a.legend; var originItem = util_1.clone(ev.items[0]); var dataItemsA = this.getDataByXField(ev.title, 0)[0]; if (dataItemsA) { if (util_1.findIndex(ev.items, function (item) { return item.name === yField[0]; }) < 0) { ev.items.push(tslib_1.__assign(tslib_1.__assign({}, originItem), { mappingData: util_1.deepMix({}, originItem.mappingData, { _origin: dataItemsA }), data: dataItemsA, name: yField[0], value: dataItemsA[yField[0]], color: this.colors[0] })); } } if (legend.visible) { util_1.each(this.legends, function (legend, index) { var item = legend.get('items')[0]; if (item.unchecked) { var spliceIndex = index === 0 ? 1 : 0; ev.items.splice(spliceIndex, 1); } }); } }; DualLineLayer.prototype.customLegend = function () { var _this = this; var _a = this.options, yField = _a.yField, legend = _a.legend; var colors = this.colors; var container = this.container.addGroup(); var legendCfg = legend; util_1.each(this.geomLayers, function (line, index) { var markerCfg = util_1.deepMix({}, { symbol: 'circle', style: { r: 4, fill: colors[index], }, }, legendCfg.marker); var items = [ { name: yField[index], unchecked: false, marker: markerCfg, }, ]; var legend = new component_1.Legend.Category({ id: _this.type, container: container, x: 0, y: 0, items: items, updateAutoRender: true, itemBackground: null, itemName: legendCfg.text, }); legend.init(); legend.render(); _this.legends.push(legend); }); // 使用legend做图层筛选 util_1.each(this.geomLayers, function (line, index) { _this.legendFilter(index); }); }; return DualLineLayer; }(base_1.default)); exports.default = DualLineLayer; global_1.registerPlotType('dualLine', DualLineLayer); },{"../../base/global":392,"../../plots/line/layer":558,"../base":396,"@antv/component":51,"@antv/util":803,"tslib":894}],401:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var GroupedColumnLine = /** @class */ (function (_super) { tslib_1.__extends(GroupedColumnLine, _super); function GroupedColumnLine() { return _super !== null && _super.apply(this, arguments) || this; } GroupedColumnLine.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'groupedColumnLine'; _super.prototype.createLayers.call(this, layerProps); }; GroupedColumnLine.getDefaultOptions = layer_1.default.getDefaultOptions; return GroupedColumnLine; }(plot_1.default)); exports.default = GroupedColumnLine; },{"../../base/plot":394,"./layer":402,"@antv/util":803,"tslib":894}],402:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var global_1 = require("../../base/global"); var util_1 = require("@antv/util"); var layer_1 = tslib_1.__importDefault(require("../column-line/layer")); var layer_2 = tslib_1.__importDefault(require("../../plots/grouped-column/layer")); var theme_1 = require("../../theme"); var defaultLineConfig = { color: '#f5bc32', lineSize: 4, connectNull: true, point: { visible: false, size: 3, shape: 'circle', style: { stroke: '#fff', }, }, label: { visible: false, }, }; var defaultColumnConfig = { color: ['#5B8FF9', '#5AD8A6', '#5D7092', '#F6BD16', '#E8684A', '#6DC8EC', '#9270CA', '#FF9D4D', '#269A99', '#FF99C3'], }; var defaultYAxisConfig = { visible: true, colorMapping: true, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { autoRotate: true, visible: false, spacing: 12, }, }; var GroupedColumnLineLayer = /** @class */ (function (_super) { tslib_1.__extends(GroupedColumnLineLayer, _super); function GroupedColumnLineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'groupedColumnLine'; _this.requiredField = ['xField', 'yField', 'columnGroupField']; return _this; } GroupedColumnLineLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { yAxis: { leftConfig: util_1.deepMix({}, defaultYAxisConfig, { colorMapping: false }), rightConfig: defaultYAxisConfig, }, lineConfig: defaultLineConfig, columnConfig: defaultColumnConfig, legend: { visible: true, }, }); }; GroupedColumnLineLayer.prototype.beforeInit = function () { var _a, _b; var _c = this, options = _c.options, initialOptions = _c.initialOptions; var groupedValue = this.getValueByGroupField(); if (options.lineSeriesField) { options.yAxis.rightConfig.colorMapping = false; if (!((_a = initialOptions.lineConfig) === null || _a === void 0 ? void 0 : _a.lineSize)) { options.lineConfig.lineSize = 3; } if (!((_b = initialOptions.lineConfig) === null || _b === void 0 ? void 0 : _b.color)) { var _d = theme_1.getGlobalTheme(), colors = _d.colors, colors_20 = _d.colors_20; var seriesValue = this.getValueBySeriesField(); var colorSeries_1 = seriesValue.length > colors.length ? colors_20 : colors; var colorPlates_1 = []; var startIndex_1 = groupedValue.length; util_1.each(seriesValue, function (v, index) { colorPlates_1.push(colorSeries_1[index + startIndex_1]); }); options.lineConfig.color = colorPlates_1; } } var color = this.options.columnConfig.color; this.options.columnConfig.color = color.slice(0, groupedValue.length); }; GroupedColumnLineLayer.prototype.drawColumn = function () { var _this = this; var _a = this.options, data = _a.data, xField = _a.xField, yField = _a.yField, columnGroupField = _a.columnGroupField, xAxis = _a.xAxis, tooltip = _a.tooltip, columnConfig = _a.columnConfig, events = _a.events; var column = this.createLayer(layer_2.default, data[0], tslib_1.__assign({ xField: xField, yField: yField[0], groupField: columnGroupField, xAxis: xAxis, yAxis: util_1.deepMix({}, this.yAxis(0), { grid: { visible: true, }, nice: true, }), legend: { visible: false, }, tooltip: util_1.deepMix({}, tooltip, { showMarkers: false, custom: { onChange: function (containerDom, ev) { _this.tooltip(containerDom, ev); }, }, }), events: events }, columnConfig)); column.render(); }; GroupedColumnLineLayer.prototype.customLegend = function () { var _this = this; var _a = this.options, yField = _a.yField, legend = _a.legend; var colors = this.colors; var container = this.container.addGroup(); var legendCfg = legend; var symbols = ['square', 'circle']; util_1.each(this.geomLayers, function (geom, index) { var legend; if (geom.options.seriesField) { var values = _this.getValueBySeriesField(); legend = _this.createNormalLegend(values, symbols[index], colors[index], legendCfg, container); } else if (geom.options.groupField) { var values = _this.getValueByGroupField(); legend = _this.createNormalLegend(values, symbols[index], colors[index], legendCfg, container); } else { legend = _this.createSingleLegend(yField[index], symbols[index], colors[index], legendCfg, container); } _this.legends.push(legend); }); // 使用legend做图层筛选 util_1.each(this.geomLayers, function (geom, index) { if (geom.options.seriesField) { _this.multipleLegendFilter(index, geom.options.seriesField); } else if (geom.options.groupField) { _this.multipleLegendFilter(index, geom.options.groupField); } else { _this.legendFilter(index); } }); }; GroupedColumnLineLayer.prototype.getValueByGroupField = function () { var _a = this.options, columnGroupField = _a.columnGroupField, data = _a.data; var columnData = data[0]; var values = []; util_1.each(columnData, function (d) { var v = d[columnGroupField]; if (!util_1.contains(values, v)) { values.push(v); } }); return values; }; GroupedColumnLineLayer.prototype.getMockData = function (index) { var _a = this.options, xField = _a.xField, yField = _a.yField, columnGroupField = _a.columnGroupField; var mockA = {}; mockA[xField] = 'null_1'; mockA[yField[index]] = 0; mockA[columnGroupField] = 'null_a'; var mockB = {}; mockB[xField] = 'null_1'; mockB[yField[index]] = 1; mockB[columnGroupField] = 'null_a'; return [mockA, mockB]; }; return GroupedColumnLineLayer; }(layer_1.default)); exports.default = GroupedColumnLineLayer; global_1.registerPlotType('groupedColumnLine', GroupedColumnLineLayer); },{"../../base/global":392,"../../plots/grouped-column/layer":532,"../../theme":669,"../column-line/layer":398,"@antv/util":803,"tslib":894}],403:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var StackedColumnLine = /** @class */ (function (_super) { tslib_1.__extends(StackedColumnLine, _super); function StackedColumnLine() { return _super !== null && _super.apply(this, arguments) || this; } StackedColumnLine.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedColumnLine'; _super.prototype.createLayers.call(this, layerProps); }; StackedColumnLine.getDefaultOptions = layer_1.default.getDefaultOptions; return StackedColumnLine; }(plot_1.default)); exports.default = StackedColumnLine; },{"../../base/plot":394,"./layer":404,"@antv/util":803,"tslib":894}],404:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var global_1 = require("../../base/global"); var util_1 = require("@antv/util"); var layer_1 = tslib_1.__importDefault(require("../column-line/layer")); var layer_2 = tslib_1.__importDefault(require("../../plots/stacked-column/layer")); var theme_1 = require("../../theme"); var defaultLineConfig = { color: '#f5bc32', lineSize: 4, connectNull: true, point: { visible: false, size: 3, shape: 'circle', style: { stroke: '#fff', }, }, label: { visible: false, }, }; var defaultColumnConfig = { color: ['#5B8FF9', '#5AD8A6', '#5D7092', '#F6BD16', '#E8684A', '#6DC8EC', '#9270CA', '#FF9D4D', '#269A99', '#FF99C3'], }; var defaultYAxisConfig = { visible: true, colorMapping: true, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { autoRotate: true, visible: false, spacing: 12, }, }; var StackedColumnLineLayer = /** @class */ (function (_super) { tslib_1.__extends(StackedColumnLineLayer, _super); function StackedColumnLineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'groupedColumnLine'; _this.requiredField = ['xField', 'yField', 'columnStackField']; return _this; } StackedColumnLineLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { yAxis: { leftConfig: util_1.deepMix({}, defaultYAxisConfig, { colorMapping: false }), rightConfig: defaultYAxisConfig, }, lineConfig: defaultLineConfig, columnConfig: defaultColumnConfig, legend: { visible: true, }, }); }; StackedColumnLineLayer.prototype.beforeInit = function () { var _a, _b; var stackedValue = this.getValueByStackField(); var _c = this, options = _c.options, initialOptions = _c.initialOptions; if (options.lineSeriesField) { options.yAxis.rightConfig.colorMapping = false; if (!((_a = initialOptions.lineConfig) === null || _a === void 0 ? void 0 : _a.lineSize)) { options.lineConfig.lineSize = 3; } if (!((_b = initialOptions.lineConfig) === null || _b === void 0 ? void 0 : _b.color)) { var _d = theme_1.getGlobalTheme(), colors = _d.colors, colors_20 = _d.colors_20; var seriesValue = this.getValueBySeriesField(); var colorSeries_1 = seriesValue.length > colors.length ? colors_20 : colors; var colorPlates_1 = []; var startIndex_1 = stackedValue.length; util_1.each(seriesValue, function (v, index) { colorPlates_1.push(colorSeries_1[index + startIndex_1]); }); options.lineConfig.color = colorPlates_1; } } var color = this.options.columnConfig.color; this.options.columnConfig.color = color.slice(0, stackedValue.length); }; StackedColumnLineLayer.prototype.drawColumn = function () { var _this = this; var _a = this.options, data = _a.data, xField = _a.xField, yField = _a.yField, columnStackField = _a.columnStackField, xAxis = _a.xAxis, tooltip = _a.tooltip, columnConfig = _a.columnConfig, events = _a.events; var column = this.createLayer(layer_2.default, data[0], tslib_1.__assign({ xField: xField, yField: yField[0], stackField: columnStackField, xAxis: xAxis, yAxis: util_1.deepMix({}, this.yAxis(0), { grid: { visible: true, }, nice: true, }), legend: { visible: false, }, tooltip: util_1.deepMix({}, tooltip, { showMarkers: false, custom: { onChange: function (containerDom, ev) { _this.tooltip(containerDom, ev); }, }, }), events: events }, columnConfig)); column.render(); }; StackedColumnLineLayer.prototype.customLegend = function () { var _this = this; var _a = this.options, yField = _a.yField, legend = _a.legend; var colors = this.colors; var container = this.container.addGroup(); var legendCfg = legend; var symbols = ['square', 'circle']; util_1.each(this.geomLayers, function (geom, index) { var legend; if (geom.options.seriesField) { var values = _this.getValueBySeriesField(); legend = _this.createNormalLegend(values, symbols[index], colors[index], legendCfg, container); } else if (geom.options.stackField) { var values = _this.getValueByStackField(); legend = _this.createNormalLegend(values, symbols[index], colors[index], legendCfg, container); } else { legend = _this.createSingleLegend(yField[index], symbols[index], colors[index], legendCfg, container); } _this.legends.push(legend); }); // 使用legend做图层筛选 util_1.each(this.geomLayers, function (geom, index) { if (geom.options.seriesField) { _this.multipleLegendFilter(index, geom.options.seriesField); } else if (geom.options.stackField) { _this.multipleLegendFilter(index, geom.options.stackField); } else { _this.legendFilter(index); } }); }; StackedColumnLineLayer.prototype.getValueByStackField = function () { var _a = this.options, columnStackField = _a.columnStackField, data = _a.data; var columnData = data[0]; var values = []; util_1.each(columnData, function (d) { var v = d[columnStackField]; if (!util_1.contains(values, v)) { values.push(v); } }); return values; }; StackedColumnLineLayer.prototype.getUnCheckedValue = function () { var value = []; util_1.each(this.legends, function (legend) { var uncheckedItems = legend.getItemsByState('unchecked'); util_1.each(uncheckedItems, function (item) { value.push(item.name); }); }); return value; }; StackedColumnLineLayer.prototype.getMockData = function (index) { var _a = this.options, xField = _a.xField, yField = _a.yField, columnStackField = _a.columnStackField; var mockA = {}; mockA[xField] = 'null_1'; mockA[yField[index]] = 0; mockA[columnStackField] = 'null_a'; var mockB = {}; mockB[xField] = 'null_1'; mockB[yField[index]] = 1; mockB[columnStackField] = 'null_a'; return [mockA, mockB]; }; return StackedColumnLineLayer; }(layer_1.default)); exports.default = StackedColumnLineLayer; global_1.registerPlotType('stackedColumnLine', StackedColumnLineLayer); },{"../../base/global":392,"../../plots/stacked-column/layer":623,"../../theme":669,"../column-line/layer":398,"@antv/util":803,"tslib":894}],405:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var formatter_1 = require("../../util/formatter"); function propertyMapping(source, target, field) { if (source[field]) { target[field] = source[field]; } } var AxisParser = /** @class */ (function () { function AxisParser(cfg) { this.config = false; this.plot = cfg.plot; this.dim = cfg.dim; this.init(); } AxisParser.prototype.init = function () { this.config = false; var theme = this.plot.getPlotTheme(); this.themeConfig = theme && theme.axis && theme.axis[this.dim]; if (this._needDraw()) { this._styleParser(); } }; AxisParser.prototype._styleParser = function () { this.config = tslib_1.__assign({}, this.localProps); this._isVisible('line') ? this._lineParser() : (this.config.line = null); this._isVisible('grid') ? this._gridParser() : (this.config.grid = null); this._isVisible('tickLine') ? this._tickLineParser() : (this.config.tickLine = null); this._isVisible('label') ? this._labelParser() : (this.config.label = null); this._isVisible('title') ? this._titleParser() : (this.config.title = null); propertyMapping(this.localProps, this.config, 'autoHideLabel'); propertyMapping(this.localProps, this.config, 'autoRotateLabel'); propertyMapping(this.localProps, this.config, 'autoRotateTitle'); }; AxisParser.prototype._needDraw = function () { /** 如果在图表配置项里没有设置坐标轴整体的visibility则去对应的theme取 */ var propos = this.plot.options; var propsConfig = propos[this.dim + "Axis"] ? propos[this.dim + "Axis"] : {}; var config = util_1.deepMix({}, this.themeConfig, propsConfig); this.localProps = config; if (config.visible) { return true; } return false; }; AxisParser.prototype._lineParser = function () { this.config.line = this.localProps.line; if (this.localProps.line.style) { this.config.line = { style: this.localProps.line.style }; } this.applyThemeConfig('line'); }; AxisParser.prototype._gridParser = function () { var _this = this; var _a, _b, _c, _d, _e; var style = (_b = (_a = this.localProps.grid) === null || _a === void 0 ? void 0 : _a.line) === null || _b === void 0 ? void 0 : _b.style; var type = (_d = (_c = this.localProps.grid) === null || _c === void 0 ? void 0 : _c.line) === null || _d === void 0 ? void 0 : _d.type; var alternateColor = (_e = this.localProps.grid) === null || _e === void 0 ? void 0 : _e.alternateColor; if (util_1.isFunction(style)) { this.config.grid = function (text, index, count) { var cfg = style(text, index, count); return { line: { type: type, style: util_1.deepMix({}, util_1.get(_this.themeConfig, "grid.line.style"), cfg), }, alternateColor: alternateColor, }; }; } else if (style) { this.config.grid = { line: { type: type, style: style, }, alternateColor: alternateColor, }; this.applyThemeConfig('grid'); } }; AxisParser.prototype._tickLineParser = function () { this.config.tickLine = this.localProps.tickLine; if (this.localProps.tickLine.style) { this.config.tickLine = { style: this.localProps.tickLine.style }; } this.applyThemeConfig('tickLine'); }; AxisParser.prototype._labelParser = function () { var _a = this.localProps.label, style = _a.style, restLabelProps = tslib_1.__rest(_a, ["style"]); var labelConfig = tslib_1.__assign({}, restLabelProps); if (style) { labelConfig.style = tslib_1.__assign({}, this.localProps.label.style); } labelConfig.style = util_1.deepMix({}, util_1.get(this.themeConfig, 'label.style'), labelConfig.style); var formatter = this.parseFormatter(labelConfig); labelConfig.formatter = formatter; this.config.label = labelConfig; }; AxisParser.prototype._titleParser = function () { var titleConfig = tslib_1.__assign({}, this.localProps.title); var _a = this.localProps.title, visible = _a.visible, style = _a.style, text = _a.text; if (!visible) { this.config.showTitle = false; } else { this.config.showTitle = true; if (style) { titleConfig.style = style; } titleConfig.style = util_1.deepMix({}, util_1.get(this.config, 'title.style'), titleConfig.textStyle); if (text) { titleConfig.text = text; } } this.config.title = titleConfig; }; AxisParser.prototype._isVisible = function (name) { if (this.localProps[name] && this.localProps[name].visible) { return true; } return false; }; AxisParser.prototype.applyThemeConfig = function (type) { this.config[type] = util_1.deepMix({}, util_1.get(this.themeConfig, type + ".style"), this.config[type]); }; AxisParser.prototype.parseFormatter = function (labelConfig) { var formatter = formatter_1.combineFormatter(formatter_1.getNoopFormatter(), formatter_1.getPrecisionFormatter(labelConfig.precision), formatter_1.getSuffixFormatter(labelConfig.suffix)); if (labelConfig.formatter) { formatter = formatter_1.combineFormatter(formatter, labelConfig.formatter); } return formatter; }; return AxisParser; }()); exports.default = AxisParser; },{"../../util/formatter":678,"@antv/util":803,"tslib":894}],406:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); // import { compare } from '../../base/controller/state'; // 对axis label和label样式进行缓存 var labels; var originAttrs; function onActive(plot, condition) { if (!labels) { getAllAxisLabels(plot); } util_1.each(labels, function (label) { var _a = beforeCompare(label, condition), labelData = _a.labelData, con = _a.con; if (compare(labelData, con)) { var disableStyle = labelActiveStyle(); label.shape.attr(disableStyle); } }); } function onDisable(plot, condition) { if (!labels) { getAllAxisLabels(plot); } util_1.each(labels, function (label, index) { var _a = beforeCompare(label, condition), labelData = _a.labelData, con = _a.con; if (compare(labelData, con)) { var originAttr = originAttrs[index]; var disableStyle = labelDisableStyle(originAttr); label.shape.attr(disableStyle); } }); } function getAllAxisLabels(plot) { var _a; labels = []; originAttrs = []; var axes = (_a = plot.view.getController('axis')) === null || _a === void 0 ? void 0 : _a.getComponents(); util_1.each(axes, function (axisComponentOption) { var axis = axisComponentOption.component; var labelArr = []; var scale = getScale(plot, axis); var labelShapes = axis.get('labelRenderer').get('group').get('children'); util_1.each(labelShapes, function (shape) { if (shape.type === 'text') { labelArr.push({ shape: shape }); originAttrs.push(shape.attr()); } }); if (scale) { // 取到scale values作为原始数据,避免被label format的影响 var ticks_1 = scale.ticks, field_1 = scale.field; util_1.each(labelArr, function (label, index) { label.value = ticks_1[index]; label.scaleField = field_1; label.type = scale.type; }); } labels.push.apply(labels, labelArr); }); } // 获取坐标轴对应的scale function getScale(plot, axis) { var props = plot.options; var dim = 'y'; var position = axis.get('position'); if (position === 'bottom' || position === 'top') { dim = 'x'; } var scaleField = props[dim + "Field"]; return plot.view.get('scales')[scaleField]; } function beforeCompare(label, condition) { var _a; var labelData = (_a = {}, _a[label.scaleField] = label.value, _a); var con = util_1.clone(condition); if (label.type === 'time' && util_1.isObject(condition) && !util_1.isFunction(con.exp)) { con.exp = new Date(con.exp).getTime(); } return { labelData: labelData, con: con }; } function labelDisableStyle(style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.2 }; } function labelActiveStyle() { return { opacity: 1, fontWeight: 600, fill: 'red' }; } function compare(origin, condition) { if (!util_1.isFunction(condition)) { var name_1 = condition.name, exp = condition.exp; if (!origin[name_1]) { return false; } if (util_1.isFunction(exp)) { return exp(origin[name_1]); } return origin[name_1] === exp; } return condition(origin); } exports.default = { active: onActive, selected: onActive, disable: onDisable, }; },{"@antv/util":803}],407:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); var util_1 = require("@antv/util"); /** * 组件基类 * * 创建和渲染 * - 1. new Component() * - 2. init() * - 2. render() * 更新 * - 1. update() * - 2. render() * */ var BaseComponent = /** @class */ (function (_super) { tslib_1.__extends(BaseComponent, _super); function BaseComponent(config) { var _this = _super.call(this) || this; _this.container = config.container; _this.destroyed = false; _this.config = config; _this.disposables = []; return _this; } BaseComponent.prototype.init = function () { if (!this.group) { this.initGroup(); } this.initConfig(this.config); }; BaseComponent.prototype.getGroup = function () { return this.group; }; BaseComponent.prototype.getConfig = function () { return this.config; }; BaseComponent.prototype.getBBox = function () { return this.getGroup().getBBox(); }; BaseComponent.prototype.clear = function () { this.group.clear(); }; BaseComponent.prototype.render = function () { this.group.clear(); this.renderInner(this.group); this.getCanvas().draw(); }; BaseComponent.prototype.update = function (config) { this.config = tslib_1.__assign(tslib_1.__assign({}, this.config), config); this.initConfig(this.config); }; BaseComponent.prototype.destroy = function () { util_1.each(this.disposables, function (fn) { fn(); }); this.disposables = []; this.group.remove(true); this.destroyed = true; }; BaseComponent.prototype.initGroup = function () { this.group = this.container.addGroup(); }; BaseComponent.prototype.getCanvas = function () { return this.container.get('canvas'); }; BaseComponent.prototype.addDisposable = function (fn) { this.disposables.push(fn); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars BaseComponent.prototype.initConfig = function (config) { return; }; return BaseComponent; }(event_emitter_1.default)); exports.default = BaseComponent; },{"@antv/event-emitter":94,"@antv/util":803,"tslib":894}],408:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("./base")); var g_util_1 = require("../util/g-util"); var Breadcrumb = /** @class */ (function (_super) { tslib_1.__extends(Breadcrumb, _super); function Breadcrumb() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.listeners = []; _this.onItemGroupToggleActive = function (itemGroup, active) { return function () { var rectShape = itemGroup.get('children').find(function (item) { return item.get('class') === 'item-background'; }); if (rectShape) { rectShape.attr(active ? _this.itemActiveBackgroundStyle : _this.itemBackgroundStyle); } _this.getCanvas().draw(); }; }; return _this; } Breadcrumb.prototype.destroy = function () { this.offEvents(); _super.prototype.destroy.call(this); }; Breadcrumb.prototype.initConfig = function (config) { this.x = config.x; this.y = config.y; this.items = config.items || []; this.itemPadding = config.itemPadding || [2, 8, 2, 8]; this.backgroundStyle = tslib_1.__assign({ lineWidth: 1, stroke: '#ffffff' }, (config.backgroundStyle || {})); this.itemBackgroundStyle = tslib_1.__assign({ fill: '#fff' }, (config.itemBackgroundStyle || {})); this.itemActiveBackgroundStyle = tslib_1.__assign({ fill: '#ccc', opacity: 0.2 }, (config.itemActiveBackgroundStyle || {})); this.separator = config.separator || '/'; this.separatorStyle = tslib_1.__assign({ textBaseline: 'top', fill: '#000000', opacity: 0.45 }, (config.separatorStyle || {})); this.itemWidth = config.itemWidth; this.itemHeight = config.itemHeight; this.maxItemWidth = config.maxItemWidth; this.textStyle = tslib_1.__assign({ textBaseline: 'top', fill: '#000000', opacity: 0.45 }, (config.textStyle || {})); }; Breadcrumb.prototype.renderInner = function (group) { var startX = 0; var startY = 0; this.offEvents(); this.renderItems(group, startX, startY); //this.bindEvents(group); g_util_1.move(this.group, this.x, this.y); }; Breadcrumb.prototype.renderItems = function (group, startX, startY) { var _this = this; var _a = this.itemPadding, topPadding = _a[0], rightPadding = _a[1], bottomPadding = _a[2], leftPadding = _a[3]; var itemHeight; // background var backgroundRect = group.addShape('rect', { class: 'breadcrumb-background', attrs: tslib_1.__assign({ x: startX, y: startY, width: 1, height: 1 }, this.backgroundStyle), }); this.items.forEach(function (item, idx) { // item group var itemGroup = group.addGroup({ id: "item-group-" + item.key, // data: item.key, data: item, class: 'item-group', attrs: { cursor: 'pointer', }, }); // background rect var rectShape = itemGroup.addShape('rect', { id: "item-background-" + item.key, class: 'item-background', attrs: tslib_1.__assign(tslib_1.__assign({ x: startX, y: startY, width: leftPadding + rightPadding, height: topPadding + bottomPadding }, _this.itemBackgroundStyle), { cursor: 'pointer' }), }); rectShape.name = 'breadcrumb'; // text shape var textShape = itemGroup.addShape('text', { id: "item-text-" + item.key, class: 'item-text', attrs: tslib_1.__assign(tslib_1.__assign({ x: startX + leftPadding, y: startY + topPadding, text: item.text }, _this.textStyle), { cursor: 'pointer' }), }); textShape.name = 'breadcrumb'; var textShapeBBox = textShape.getBBox(); itemHeight = _this.itemHeight || textShapeBBox.height; var itemWidth = _this.itemWidth || textShapeBBox.width; if (_this.maxItemWidth) { itemWidth = Math.min(itemWidth, _this.maxItemWidth); } // update background rect var backgroundRectAttr = { x: startX, y: startY, width: itemWidth + leftPadding + rightPadding, height: itemHeight + topPadding + bottomPadding, }; rectShape.attr('width', backgroundRectAttr.width); rectShape.attr('height', backgroundRectAttr.height); // clip itemGroup.setClip({ type: 'rect', attrs: backgroundRectAttr, }); startX += backgroundRectAttr.width; // separator if (idx !== _this.items.length - 1) { var sepShape = group.addShape('text', { attrs: tslib_1.__assign({ x: startX, y: startY + topPadding, text: _this.separator }, _this.separatorStyle), class: 'separator', }); startX += sepShape.getBBox().width; } }); // update background backgroundRect.attr({ width: startX, height: itemHeight + topPadding + bottomPadding, }); }; Breadcrumb.prototype.bindEvents = function (group) { var _this = this; var items = this.items; var itemGroups = group.get('children').filter(function (item) { return item.get('class') === 'item-group'; }); var callback = function (event, itemGroup, emitEventName) { return function () { var key = itemGroup.get('data'); var item = items.find(function (val) { return val.key === key; }); _this.emit(emitEventName, { item: item, }); }; }; itemGroups.forEach(function (itemGroup) { var clickCallback = callback('click', itemGroup, 'onItemClick'); var dblclickCallback = callback('dblclick', itemGroup, 'onItemDblclick'); var mouseEnterCallback = _this.onItemGroupToggleActive(itemGroup, true); var mouseLeaveCallback = _this.onItemGroupToggleActive(itemGroup, false); itemGroup.on('click', clickCallback); itemGroup.on('dblclick', dblclickCallback); itemGroup.on('mouseenter', mouseEnterCallback); itemGroup.on('mouseleave', mouseLeaveCallback); _this.listeners.push({ target: itemGroup, event: 'click', callback: clickCallback }); _this.listeners.push({ target: itemGroup, event: 'dblclick', callback: dblclickCallback }); _this.listeners.push({ target: itemGroup, event: 'mouseenter', callback: mouseEnterCallback }); _this.listeners.push({ target: itemGroup, event: 'mouseleave', callback: mouseLeaveCallback }); }); }; Breadcrumb.prototype.offEvents = function () { if (this.listeners) { this.listeners.forEach(function (_a) { var target = _a.target, event = _a.event, callback = _a.callback; target.off(event, callback); }); } this.listeners = []; }; return Breadcrumb; }(base_1.default)); exports.default = Breadcrumb; },{"../util/g-util":679,"./base":407,"tslib":894}],409:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 区域连接组件,用于堆叠柱状图和堆叠条形图 */ var util_1 = require("@antv/util"); var state_1 = require("../base/controller/state"); function parsePoints(shape, coord) { var parsedPoints = []; var points = shape.get('origin').points; util_1.each(points, function (p) { parsedPoints.push(coord.convertPoint(p)); }); return parsedPoints; } function getDefaultStyle() { return { areaStyle: { opacity: 0.2, }, lineStyle: { lineWidth: 2, opacity: 0.1, }, }; } var ConnectedArea = /** @class */ (function () { function ConnectedArea(cfg) { this.areas = []; this.lines = []; this._areaStyle = {}; this._lineStyle = {}; util_1.assign(this, cfg); this._init(); } ConnectedArea.prototype.draw = function () { var _this = this; var groupedShapes = this._getGroupedShapes(); util_1.each(groupedShapes, function (shapes, name) { if (shapes.length > 0) { _this._drawConnection(shapes, name); } }); if (this.triggerOn) { this._addInteraction(); } else if (this.animation) { // 如果定义了triggerOn的方式,则组件是响应交互的,初始化为不可见状态,因此无需动画 this._initialAnimation(); } }; ConnectedArea.prototype.clear = function () { if (this.container) { this.container.clear(); } this.areas = []; this.lines = []; }; ConnectedArea.prototype.destroy = function () { if (this.container) { this.container.remove(); } }; ConnectedArea.prototype.setState = function (state, condition) { if (state === 'active') { this._onActive(condition); } if (state === 'disabled') { this._onDisabled(condition); } if (state === 'selected') { this._onSelected(condition); } }; ConnectedArea.prototype._init = function () { var _this = this; var layer = this.view.backgroundGroup; this.container = layer.addGroup(); this.draw(); this.view.on('beforerender', function () { _this.clear(); }); }; ConnectedArea.prototype._getGroupedShapes = function () { var _this = this; // 根据堆叠字段对shape进行分组 var values = this.view.getScaleByField(this.field).values; var geometry = this.view.geometries[0]; var shapes = geometry.getShapes(); // 创建分组 var groups = {}; util_1.each(values, function (v) { groups[v] = []; }); // 执行分组 util_1.each(shapes, function (shape) { var origin = shape.get('origin').data; var key = origin[_this.field]; groups[key].push(shape); }); return groups; }; ConnectedArea.prototype._drawConnection = function (shapes, name) { // tslint:disable-next-line: prefer-for-of var originColor = shapes[0].attr('fill'); this._areaStyle[name] = this._getShapeStyle(originColor, 'area'); this._lineStyle[name] = this._getShapeStyle(originColor, 'line'); var coord = this.view.geometries[0].coordinate; for (var i = 0; i < shapes.length - 1; i++) { var current = parsePoints(shapes[i], coord); var next = parsePoints(shapes[i + 1], coord); var areaStyle = util_1.mix({}, this._areaStyle[name]); var lineStyle = util_1.mix({}, this._lineStyle[name]); if (this.triggerOn) { areaStyle.opacity = 0; lineStyle.opacity = 0; } var area = this.container.addShape('path', { attrs: util_1.mix({}, areaStyle, { path: [ ['M', current[2].x, current[2].y], ['L', next[1].x, next[1].y], ['L', next[0].x, next[0].y], ['L', current[3].x, current[3].y], ], }), name: 'connectedArea', }); var line = this.container.addShape('path', { attrs: util_1.mix({}, lineStyle, { path: [ ['M', current[2].x, current[2].y], ['L', next[1].x, next[1].y], ], }), name: 'connectedArea', }); // 在辅助图形上记录数据,用以交互和响应状态量 var originData = shapes[i].get('origin').data; area.set('data', originData); line.set('data', originData); this.areas.push(area); this.lines.push(line); } }; ConnectedArea.prototype._getShapeStyle = function (originColor, shapeType) { var styleName = shapeType + "Style"; // 如果用户自己指定了样式,则不采用默认颜色映射 if (this[styleName]) { return this[styleName]; } var defaultStyle = getDefaultStyle()[styleName]; var mappedStyle = { fill: originColor }; if (shapeType === 'line') { mappedStyle = { stroke: originColor }; } return util_1.mix(defaultStyle, mappedStyle); }; ConnectedArea.prototype._addInteraction = function () { var _this = this; var eventName = this.triggerOn; this.view.on("interval:" + eventName, function (e) { var origin = e.target.get('origin').data[_this.field]; _this.setState('active', { name: _this.field, exp: origin, }); _this.setState('disabled', { name: _this.field, exp: function (d) { return d !== origin; }, }); _this.view.canvas.draw(); }); // 当鼠标移动到其他区域时取消显示 this.view.on('mousemove', function (e) { if (e.gEvent.target.get('name') !== 'interval') { _this.setState('disabled', { name: _this.field, exp: function () { return true; }, }); } }); }; ConnectedArea.prototype._initialAnimation = function () { // clipIn动画 var _a = this.view.coordinateBBox, x = _a.x, y = _a.y, width = _a.width, height = _a.height; this.container.setClip({ type: 'rect', attrs: { x: x, y: y, width: 0, height: height, }, }); this.container.set('animating', true); this.container.getClip().animate({ width: width, }, 600, 'easeQuadOut', function () { }, // eslint-disable-line @typescript-eslint/no-empty-function 400); }; ConnectedArea.prototype._onActive = function (condition) { var _this = this; util_1.each(this.areas, function (area) { var shapeData = area.get('data'); var styleField = shapeData[_this.field]; if (state_1.compare(shapeData, condition)) { var opacity = _this._areaStyle[styleField].opacity || 1; // area.attr('opacity',this._areaStyle[styleField].opacity || 1); area.stopAnimate(); area.animate({ opacity: opacity }, 400, 'easeQuadOut'); } }); util_1.each(this.lines, function (line) { var shapeData = line.get('data'); var styleField = shapeData[_this.field]; if (state_1.compare(shapeData, condition)) { var opacity = _this._lineStyle[styleField].opacity || 1; // line.attr('opacity',this._lineStyle[styleField].opacity || 1); line.stopAnimate(); line.animate({ opacity: opacity }, 400, 'easeQuadOut'); } }); }; ConnectedArea.prototype._onDisabled = function (condition) { util_1.each(this.areas, function (area) { var shapeData = area.get('data'); if (state_1.compare(shapeData, condition)) { // area.attr('opacity',0); area.stopAnimate(); area.animate({ opacity: 0, }, 400, 'easeQuadOut'); } }); util_1.each(this.lines, function (line) { var shapeData = line.get('data'); if (state_1.compare(shapeData, condition)) { // line.attr('opacity',0); line.stopAnimate(); line.animate({ opacity: 0, }, 400, 'easeQuadOut'); } }); }; ConnectedArea.prototype._onSelected = function (condition) { this._onActive(condition); }; ConnectedArea.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geom) { return geom.type === 'interval'; }); }; return ConnectedArea; }()); exports.default = ConnectedArea; },{"../base/controller/state":390,"@antv/util":803}],410:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var animate_1 = require("@antv/g2/lib/animate"); var util_1 = require("@antv/util"); function parsePoints(shape, coord) { var parsedPoints = []; var points = shape.get('origin').points; util_1.each(points, function (p) { parsedPoints.push(coord.convertPoint(p)); }); return parsedPoints; } var ConversionTag = /** @class */ (function () { function ConversionTag(cfg) { // @ts-ignore util_1.deepMix(this, this.constructor.getDefaultOptions(cfg), cfg); this._init(); } ConversionTag.getDefaultOptions = function (_a) { var transpose = _a.transpose; return { visible: true, size: transpose ? 32 : 80, spacing: transpose ? 8 : 12, offset: transpose ? 32 : 0, arrow: { visible: true, headSize: 12, style: { fill: 'rgba(0, 0, 0, 0.05)', }, }, value: { visible: true, style: { fontSize: 12, fill: 'rgba(0, 0, 0, 0.85)', }, formatter: function (valueUpper, valueLower) { return ((100 * valueLower) / valueUpper).toFixed(2) + "%"; }, }, animation: util_1.deepMix({}, animate_1.DEFAULT_ANIMATE_CFG), }; }; ConversionTag.prototype._init = function () { var _this = this; var layer = this.view.backgroundGroup; this.container = layer.addGroup(); this.draw(); this.view.on('beforerender', function () { _this.clear(); }); }; ConversionTag.prototype.draw = function () { var _this = this; var transpose = this.transpose; var values = this.view.getScaleByField(this.field).values; var geometry = this.view.geometries[0]; var shapes = geometry.getShapes(); var shapeLower, valueLower, shapeUpper, valueUpper; if (transpose) { shapes.forEach(function (shapeLower, i) { valueLower = values[i]; if (i++ > 0) { _this._drawTag(shapeUpper, valueUpper, shapeLower, valueLower); } valueUpper = valueLower; shapeUpper = shapeLower; }); } else { shapes.forEach(function (shapeUpper, i) { valueUpper = values[i]; if (i++ > 0) { _this._drawTag(shapeUpper, valueUpper, shapeLower, valueLower); } valueLower = valueUpper; shapeLower = shapeUpper; }); } }; ConversionTag.prototype.clear = function () { if (this.container) { this.container.clear(); } }; ConversionTag.prototype.destroy = function () { if (this.container) { this.container.remove(); } }; ConversionTag.prototype._drawTag = function (shapeUpper, valueUpper, shapeLower, valueLower) { var transpose = this.transpose; var coord = this.view.geometries[0].coordinate; var pointUpper = parsePoints(shapeUpper, coord)[transpose ? 3 : 0]; var pointLower = parsePoints(shapeLower, coord)[transpose ? 0 : 3]; this._drawTagArrow(pointUpper, pointLower); this._drawTagValue(pointUpper, valueUpper, pointLower, valueLower); }; ConversionTag.prototype._drawTagArrow = function (pointUpper, pointLower) { var spacing = this.spacing; var _a = this, size = _a.size, offset = _a.offset, animation = _a.animation, transpose = _a.transpose; var headSize = this.arrow.headSize; var totalHeight = pointLower.y - pointUpper.y; var totalWidth = pointLower.x - pointUpper.x; var points; if (transpose) { if ((totalWidth - headSize) / 2 < spacing) { // 当柱间距不足容纳箭头尖与间隔时,画三角并挤占间隔 spacing = Math.max(1, (totalWidth - headSize) / 2); points = [ [pointUpper.x + spacing, pointUpper.y - offset], [pointUpper.x + spacing, pointUpper.y - offset - size], [pointLower.x - spacing, pointLower.y - offset - size / 2], ]; } else { // 当柱间距足够时,画完整图形并留出间隔。 points = [ [pointUpper.x + spacing, pointUpper.y - offset], [pointUpper.x + spacing, pointUpper.y - offset - size], [pointLower.x - spacing - headSize, pointLower.y - offset - size], [pointLower.x - spacing, pointLower.y - offset - size / 2], [pointLower.x - spacing - headSize, pointLower.y - offset], ]; } } else { if ((totalHeight - headSize) / 2 < spacing) { // 当柱间距不足容纳箭头尖与间隔时,画三角并挤占间隔 spacing = Math.max(1, (totalHeight - headSize) / 2); points = [ [pointUpper.x + offset, pointUpper.y + spacing], [pointUpper.x + offset + size, pointUpper.y + spacing], [pointLower.x + offset + size / 2, pointLower.y - spacing], ]; } else { // 当柱间距足够时,画完整图形并留出间隔。 points = [ [pointUpper.x + offset, pointUpper.y + spacing], [pointUpper.x + offset + size, pointUpper.y + spacing], [pointLower.x + offset + size, pointLower.y - spacing - headSize], [pointLower.x + offset + size / 2, pointLower.y - spacing], [pointLower.x + offset, pointLower.y - spacing - headSize], ]; } } var tagArrow = this.container.addShape('polygon', { name: 'arrow', attrs: tslib_1.__assign(tslib_1.__assign({}, this.arrow.style), { points: points }), }); if (animation !== false) { this._fadeInTagShape(tagArrow); } }; ConversionTag.prototype._drawTagValue = function (pointUpper, valueUpper, pointLower, valueLower) { var _a = this, size = _a.size, offset = _a.offset, animation = _a.animation, transpose = _a.transpose; var text = this.value.formatter(valueUpper, valueLower); var tagValue = this.container.addShape('text', { name: 'value', attrs: tslib_1.__assign(tslib_1.__assign({}, this.value.style), { text: text, x: transpose ? (pointUpper.x + pointLower.x) / 2 : pointUpper.x + offset + size / 2, y: transpose ? pointUpper.y - offset - size / 2 : (pointUpper.y + pointLower.y) / 2, textAlign: 'center', textBaseline: 'middle' }), }); if (transpose) { var totalWidth = pointLower.x - pointUpper.x; var textWidth = tagValue.getBBox().width; if (textWidth > totalWidth) { var cWidth = textWidth / text.length; var cEnd = Math.max(1, Math.ceil(totalWidth / cWidth) - 1); var textAdjusted = text.slice(0, cEnd) + "..."; tagValue.attr('text', textAdjusted); } } if (animation !== false) { this._fadeInTagShape(tagValue); } }; ConversionTag.prototype._fadeInTagShape = function (shape) { var animation = this.animation; var opacity = shape.attr('opacity'); shape.attr('opacity', 0); var duration = util_1.get(animation, 'appear', animate_1.DEFAULT_ANIMATE_CFG.appear).duration; shape.animate({ opacity: opacity }, duration); }; return ConversionTag; }()); exports.default = ConversionTag; },{"@antv/g2/lib/animate":217,"@antv/util":803,"tslib":894}],411:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var common_1 = require("../util/common"); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); /** * 图表的文字描述,一般用于生成图表的标题和副标题 */ var TextDescription = /** @class */ (function () { function TextDescription(cfg) { this.position = 'top'; this.destroyed = false; util_1.assign(this, cfg); this.init(); } TextDescription.prototype.getBBox = function () { var _this = this; if (this.shape) { // @ts-ignore var bbox = this.shape.getBBox(); if (this.index === 0) { return bbox_1.default.fromBBoxObject(bbox); } var padding_1 = this.plot.theme.description.padding; if (util_1.isArray(padding_1)) { util_1.each(padding_1, function (it, index) { if (typeof padding_1[index] === 'function') { padding_1[index] = padding_1[index](_this.plot.options.legend.position); } }); } return new bbox_1.default(bbox.maxX, bbox.minY, bbox.width, bbox.height); } return null; }; TextDescription.prototype.clear = function () { if (this.shape) { // @ts-ignore this.shape.attr('text', ''); } }; TextDescription.prototype.destroy = function () { if (this.shape) { this.shape.remove(); } this.destroyed = true; }; TextDescription.prototype.init = function () { var content = this.textWrapper(); var _a = this.getPosition(), x = _a.x, y = _a.y; this.shape = this.container.addShape('text', { attrs: util_1.mix({ x: x, y: y, text: content, }, this.style, { textAlign: this.getTextAlign(), }), }); // @ts-ignore this.shape.name = this.name; }; TextDescription.prototype.getPosition = function () { if (this.alignTo === 'left') { return { x: this.leftMargin, y: this.topMargin }; } else if (this.alignTo === 'middle') { return { x: this.leftMargin + this.wrapperWidth / 2, y: this.topMargin }; } else { return { x: this.rightMargin, y: this.topMargin }; } }; TextDescription.prototype.getTextAlign = function () { if (this.alignTo === 'left') { return 'left'; } else if (this.alignTo === 'middle') { return 'center'; } else { return 'right'; } }; /** * 当text过长时,默认换行 * 1. 注意初始text带换行符的场景 */ TextDescription.prototype.textWrapper = function () { var width = this.wrapperWidth; var style = this.style; var textContent = this.text; var tShape = this.container.addShape('text', { attrs: tslib_1.__assign({ text: '', x: 0, y: 0 }, style), }); var textArr = textContent.split('\n'); var wrappedTextArr = textArr.map(function (wrappedText) { var text = ''; var chars = wrappedText.split(''); var breakIndex = []; for (var i = 0; i < chars.length; i++) { var item = chars[i]; tShape.attr('text', (text += item)); var currentWidth = tShape.getBBox().width - 1; if (currentWidth > width) { // 如果是第一个字符就大于宽度不做任何换行处理 if (i === 0) { break; } breakIndex.push(i); text = ''; } } return common_1.breakText(chars, breakIndex); }); tShape.remove(); return wrappedTextArr.join('\n'); }; return TextDescription; }()); exports.default = TextDescription; },{"../util/bbox":672,"../util/common":674,"@antv/util":803,"tslib":894}],412:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getComponentStateMethod = exports.getComponent = void 0; var tslib_1 = require("tslib"); // components parser var parser_1 = tslib_1.__importDefault(require("./axis/parser")); var guide_line_1 = tslib_1.__importDefault(require("./guide-line")); var parser_2 = tslib_1.__importDefault(require("./label/parser")); // components state methods var state_1 = tslib_1.__importDefault(require("./axis/state")); var state_2 = tslib_1.__importDefault(require("./label/state")); var state_3 = tslib_1.__importDefault(require("./tooltip/state")); var COMPONENT_MAPPER = { axis: parser_1.default, label: parser_2.default, guideLine: guide_line_1.default, }; var STATE_MAPPER = { tooltip: state_3.default, label: state_2.default, axis: state_1.default, }; function getComponent(name, cfg) { var Components = COMPONENT_MAPPER[name]; return new Components(cfg).config; } exports.getComponent = getComponent; function getComponentStateMethod(name, type) { return STATE_MAPPER[name][type]; } exports.getComponentStateMethod = getComponentStateMethod; },{"./axis/parser":405,"./axis/state":406,"./guide-line":413,"./label/parser":415,"./label/state":418,"./tooltip/state":424,"tslib":894}],413:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var scale_1 = require("@antv/scale"); var util_1 = require("@antv/util"); var math_1 = require("../util/math"); var GuideLine = /** @class */ (function () { function GuideLine(cfg) { util_1.assign(this, cfg); this._init(); } GuideLine.prototype._init = function () { var _a = this.plot.options, yField = _a.yField, data = _a.data; var plotData = this.plot.processData(data); if (util_1.isEmpty(plotData) || !util_1.isNumber(plotData[0][yField])) { return; } var defaultStyle = this.getDefaultStyle(); var baseConfig = { type: 'line', top: true, start: this.cfg.start, end: this.cfg.end, }; baseConfig.style = util_1.deepMix({}, defaultStyle.line.style, this.cfg.lineStyle); baseConfig.text = util_1.deepMix({}, defaultStyle.text, this.cfg.text); if (this.cfg.type) { var stateValue = this._getState(this.cfg.type); var scale = this.getYScale(); var percent = (1.0 - scale.scale(stateValue)) * 100 + "%"; var start = ['0%', percent]; var end = ['100%', percent]; this.config = util_1.mix({ start: start, end: end, }, baseConfig); } else { var _b = this.cfg, start_1 = _b.start, end_1 = _b.end; this.config = util_1.clone(baseConfig); var xScale_1 = this.getXScale(); var yScale_1 = this.getYScale(); var startData_1 = util_1.clone(start_1); var endData_1 = util_1.clone(end_1); util_1.each(start_1, function (value, index) { if (!util_1.contains(util_1.toArray(start_1[index]), '%') || util_1.isNumber(start_1[index])) { if (index === 0) { startData_1[index] = xScale_1.scale(start_1[0]) * 100 + "%"; } else { startData_1[index] = (1.0 - yScale_1.scale(start_1[1])) * 100 + "%"; } } }); util_1.each(end_1, function (value, index) { if (!util_1.contains(util_1.toArray(end_1[index]), '%') || util_1.isNumber(end_1[index])) { if (index === 0) { endData_1[index] = xScale_1.scale(end_1[0]) * 100 + "%"; } else { endData_1[index] = (1.0 - yScale_1.scale(end_1[1])) * 100 + "%"; } } }); this.config.start = startData_1; this.config.end = endData_1; } }; GuideLine.prototype.getYScale = function () { var minValue = this._getState('min'); var maxValue = this._getState('max'); var Scale = scale_1.getScale('linear'); // 重新组织scale并使用scale的min和max来计算guide point的百分比位置,以避免受nice的影响 var scale = new Scale(util_1.mix({}, { min: this.plot.type === 'column' ? 0 : minValue, max: maxValue, nice: true, values: this.values, }, this.plot.config.scales[this.plot.options.yField])); return scale; }; GuideLine.prototype.getXScale = function () { var values = this.extractXValue(); if (util_1.isString(values[0])) { var Scale = scale_1.getScale('cat'); var scale = new Scale(util_1.mix({}, { values: values, }, this.plot.config.scales[this.plot.options.xField])); return scale; } else { var min = Math.min.apply(Math, values); var max = Math.max.apply(Math, values); var Scale = scale_1.getScale('linear'); var scale = new Scale(util_1.mix({}, { min: min, max: max, nice: true, values: values, }, this.plot.config.scales[this.plot.options.xField])); return scale; } }; GuideLine.prototype._getState = function (type) { this.values = this._extractValues(); if (type === 'median') { return math_1.getMedian(this.values); } if (type === 'mean') { return math_1.getMean(this.values); } if (type === 'max') { return Math.max.apply(Math, this.values); } if (type === 'min') { return Math.min.apply(Math, this.values); } }; GuideLine.prototype._extractValues = function () { var props = this.plot.options; var field = props.yField; var values = []; var data = this.plot.processData(props.data); util_1.each(data, function (d) { if (util_1.isArray(d[field])) { values.push.apply(values, d[field]); } else { values.push(d[field]); } }); return values; }; GuideLine.prototype.extractXValue = function () { var props = this.plot.options; var field = props.xField; var values = []; var data = this.plot.processData(props.data); util_1.each(data, function (d) { if (util_1.isArray(d[field])) { values.push.apply(values, d[field]); } else { values.push(d[field]); } }); return values; }; GuideLine.prototype.getDefaultStyle = function () { this.getDefaultTextAlign(); return { line: { style: { lineWidth: 2, stroke: '#333333', opacity: 0.7, lineDash: [0, 0], }, }, text: { content: '', offsetY: -5, style: { fontSize: 14, stroke: 'white', lineWidth: 2, textAlign: this.getDefaultTextAlign(), }, }, }; }; GuideLine.prototype.getDefaultTextAlign = function () { var textConfig = this.cfg.text; if (textConfig) { if (!textConfig.position || textConfig.position === 'start') { return 'left'; } if (textConfig.position === 'center') { return 'center'; } if (textConfig.position === 'end') { return 'right'; } } }; return GuideLine; }()); exports.default = GuideLine; },{"../util/math":680,"@antv/scale":747,"@antv/util":803}],414:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLabelComponent = exports.registerLabelComponent = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var dependents_1 = require("../../dependents"); var bbox_1 = tslib_1.__importDefault(require("../../util/bbox")); var LabelComponent = /** @class */ (function (_super) { tslib_1.__extends(LabelComponent, _super); function LabelComponent() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.labelsCfgMap = {}; _this.lastLabelsCfgMap = {}; return _this; } LabelComponent.prototype.getGeometry = function () { return this.geometry; }; LabelComponent.prototype.getLabels = function () { return this.labels; }; LabelComponent.prototype.show = function () { this.container.show(); }; LabelComponent.prototype.hide = function () { this.container.hide(); }; LabelComponent.prototype.initConfig = function (config) { var _this = this; this.layer = config.layer; var view = this.layer.view; this.view = view; this.geometry = config.geometry; this.coord = view.getCoordinate(); this.options = util_1.deepMix(this.getDefaultOptions(), config.label); var callback = function () { _this.clear(); _this.labelsCfgMap = {}; _this.lastLabelsCfgMap = {}; _this.render(); }; view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); this.addDisposable(function () { view.off(dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); }); }; LabelComponent.prototype.renderInner = function (group) { var _this = this; this.labels = []; this.labelsCfgMap = {}; // 绘制 Label 图形 util_1.each(this.geometry.elements, function (element, elementIdx) { var labels = [].concat(_this.drawLabelItem(group, element, elementIdx)); util_1.each(labels, function (label, idx) { _this.adjustLabel(label, element, idx); if (!label.destroyed) { _this.labels.push(label); _this.labelsCfgMap[label.get('id')] = util_1.clone(label.attrs); } }); }); // 执行布局 this.layoutLabels(this.geometry, this.labels); // 执行动画:参照 G2 Label 动画 var lastLabelsCfgMap = this.lastLabelsCfgMap; var labelsCfgMap = this.labelsCfgMap; var animateCfg = this.geometry.animateOption ? dependents_1.getDefaultAnimateCfg('label', this.coord) : false; util_1.each(labelsCfgMap, function (attrs, id) { var shape = group.findById(id); if (shape) { if (lastLabelsCfgMap[id]) { var oldAttrs = lastLabelsCfgMap[id]; // 图形发生更新 var updateAnimateCfg = util_1.get(animateCfg, 'update'); if (updateAnimateCfg) { shape.stopAnimate(); shape.attr(oldAttrs); dependents_1.doAnimate(shape, updateAnimateCfg, { toAttrs: tslib_1.__assign({}, attrs), coordinate: _this.coord, }); } } else { // 新生成的 shape var appearAnimateCfg = util_1.get(animateCfg, 'appear'); if (appearAnimateCfg) { shape.stopAnimate(); dependents_1.doAnimate(shape, appearAnimateCfg, { toAttrs: tslib_1.__assign({}, shape.attr()), coordinate: _this.coord, }); } } } delete lastLabelsCfgMap[id]; }); util_1.each(lastLabelsCfgMap, function (attrs, id) { // 移除 var leaveAnimateCfg = util_1.get(animateCfg, 'leave'); if (leaveAnimateCfg) { var tempShape = group.addShape('text', { attrs: attrs, id: id, name: 'label', }); tempShape.stopAnimate(); dependents_1.doAnimate(tempShape, leaveAnimateCfg, { toAttrs: null, coordinate: _this.coord, }); } }); this.lastLabelsCfgMap = this.labelsCfgMap; }; LabelComponent.prototype.drawLabelText = function (group, attrs, extraCfgs) { if (extraCfgs === void 0) { extraCfgs = {}; } return group.addShape('text', tslib_1.__assign({ attrs: attrs }, extraCfgs)); }; LabelComponent.prototype.drawLabelItem = function (group, element, elementIndex) { var _this = this; var model = element.getModel(); var items = [].concat(this.getLabelItemAttrs(element, elementIndex)); var offset = this.getDefaultOffset(); var offsetPoint = this.getLabelOffset(); return util_1.map(items, function (attrs, index) { var _a; var position = { x: attrs.x + offsetPoint.x, y: attrs.y + offsetPoint.y, }; var dataItem = util_1.isArray(model.mappingData) ? model.mappingData[index] : model.mappingData; var id = _this.getLabelId(dataItem); return _this.drawLabelText(group, tslib_1.__assign(tslib_1.__assign({}, attrs), position), (_a = { id: id, name: 'label', offset: offset, element: element }, _a[dependents_1.ORIGIN] = dataItem, _a)); }); }; /** 获取当前 Label 的 offset */ LabelComponent.prototype.getDefaultOffset = function () { return Number(this.options.offset); }; /** 默认实现:获取当前 Label 的 offset 点:包括 offset、offsetX、offsetY */ LabelComponent.prototype.getLabelOffset = function () { var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY; return { x: util_1.isNumber(offsetX) ? offsetX : 0, y: util_1.isNumber(offsetY) ? offsetY : 0, }; }; /** 通过指定方向和系数获取整体 offset 点 */ LabelComponent.prototype.getLabelOffsetByDimAndFactor = function (dim, factor) { var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY; var offset = this.getDefaultOffset(); var offsetPoint = { x: 0, y: 0, }; offsetPoint[dim] = offset * factor; if (util_1.isNumber(offsetX)) { offsetPoint.x += offsetX; } if (util_1.isNumber(offsetY)) { offsetPoint.y += offsetY; } return offsetPoint; }; /** 初始化默认全局配置 */ LabelComponent.prototype.getDefaultOptions = function () { return {}; }; /** 整理对所有 Labels 的布局调整 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars LabelComponent.prototype.layoutLabels = function (geometry, labels) { // empty }; LabelComponent.prototype.getLabelId = function (data) { var origin = data._origin; var type = this.geometry.type; var xScale = this.geometry.getXScale(); var yScale = this.geometry.getYScale(); var labelId = this.geometry.getElementId(data); if (type === 'line' || type === 'area') { // 折线图以及区域图,一条线会对应一组数据,即多个 labels,为了区分这些 labels,需要在 line id 的前提下加上 x 字段值 labelId += " " + origin[xScale.field]; } else if (type === 'path') { // path 路径图,无序,有可能存在相同 x 不同 y 的情况,需要通过 x y 来确定唯一 id labelId += " " + origin[xScale.field] + "-" + origin[yScale.field]; } return labelId; }; LabelComponent.prototype.getCoordinateBBox = function () { var coord = this.coord; var start = coord.start, end = coord.end; return new bbox_1.default(Math.min(start.x, end.x), Math.min(start.y, end.y), coord.getWidth(), coord.getHeight()); }; return LabelComponent; }(base_1.default)); exports.default = LabelComponent; // Label 组件注册 var LABEL_CONFIG_MAP = {}; function registerLabelComponent(type, component) { LABEL_CONFIG_MAP[type] = component; } exports.registerLabelComponent = registerLabelComponent; function getLabelComponent(type) { return LABEL_CONFIG_MAP[type]; } exports.getLabelComponent = getLabelComponent; },{"../../dependents":425,"../../util/bbox":672,"../base":407,"@antv/util":803,"tslib":894}],415:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var formatter_1 = require("../../util/formatter"); var LabelParser = /** @class */ (function () { function LabelParser(cfg) { this.config = {}; var plot = cfg.plot, rest = tslib_1.__rest(cfg, ["plot"]); this.plot = plot; this.originConfig = rest; this.init(cfg); } LabelParser.prototype.getConfig = function () { return this.config; }; LabelParser.prototype.init = function (cfg) { var _this = this; util_1.assign(this.config, cfg); this.config.callback = function (val) { return _this.parseCallBack(val); }; }; LabelParser.prototype.parseCallBack = function (val) { var labelProps = this.originConfig; var theme = this.plot.getPlotTheme(); var config = tslib_1.__assign({}, labelProps); this.parseOffset(labelProps, config); if (labelProps.position) { if (util_1.isFunction(labelProps.position)) { config.position = labelProps.position(val); } else { config.position = labelProps.position; } } this.parseFormatter(config); if (labelProps.style) { if (util_1.isFunction(labelProps.style)) { config.textStyle = labelProps.style(val); } else { config.textStyle = labelProps.style; } } config.textStyle = util_1.deepMix({}, util_1.get(theme, 'label.style'), config.textStyle); if (labelProps.autoRotate) { config.autoRotate = labelProps.autoRotate; } return config; }; LabelParser.prototype.parseOffset = function (props, config) { var mapper = ['offset', 'offsetX', 'offsetY']; var count = 0; util_1.each(mapper, function (m) { if (util_1.has(props, m)) { config[m] = props[m]; count++; } }); // 如用户没有设置offset,而label position又为middle时,则默认设置offset为0 if (count === 0 && util_1.get(props, 'position') === 'middle') { config.offset = 0; } }; LabelParser.prototype.parseFormatter = function (config) { var labelProps = this.originConfig; config.content = function (data, index) { // @ts-ignore var text = data[labelProps.fields[0]]; return formatter_1.combineFormatter(formatter_1.getNoopFormatter(), formatter_1.getPrecisionFormatter(labelProps.precision), formatter_1.getSuffixFormatter(labelProps.suffix), labelProps.formatter ? labelProps.formatter : formatter_1.getNoopFormatter())(text, data, index); }; }; return LabelParser; }()); exports.default = LabelParser; },{"../../util/formatter":678,"@antv/util":803,"tslib":894}],416:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("./base"); var point_1 = tslib_1.__importDefault(require("./point")); var dependents_1 = require("../../dependents"); var view_1 = require("../../util/view"); var bbox_1 = tslib_1.__importDefault(require("../../util/bbox")); var PointAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(PointAutoLabel, _super); function PointAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } PointAutoLabel.prototype.layoutLabels = function (geometry, labels) { var _this = this; var _a; var dones = []; var panel = bbox_1.default.fromBBoxObject(this.getCoordinateBBox()); var _b = geometry.getXYFields(), xField = _b[0], yField = _b[1]; var groupedMap = util_1.groupBy(labels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; }); var offset = (_a = labels[0]) === null || _a === void 0 ? void 0 : _a.get('offset'); util_1.each(util_1.keys(groupedMap).reverse(), function (xValue) { var group = _this.sortLabels(geometry, groupedMap[xValue]); while (group.length) { var label = group.shift(); if (view_1.checkOriginEqual(label, dones, function (datumLeft, datumRight) { return datumLeft._origin[xField] === datumRight._origin[xField] && datumLeft._origin[yField] === datumRight._origin[yField]; })) { label.set('visible', false); continue; } view_1.moveInPanel(label, panel); var upFail = view_1.checkShapeOverlap(label, dones); var downFail = void 0; if (upFail) { label.attr('y', label.attr('y') + 2 * offset); view_1.moveInPanel(label, panel); downFail = view_1.checkShapeOverlap(label, dones); } if (downFail) { label.set('visible', false); continue; } dones.push(label); } }); }; /** 对 Labels 排序,排序顺序决定自动布局优先级 */ PointAutoLabel.prototype.sortLabels = function (geometry, labels) { var yField = geometry.getXYFields()[1]; var sorted = []; // 顺序:第一个、最后一个、再其他 labels.sort(function (a, b) { return b.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][yField] - a.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][yField]; }); if (labels.length > 0) { sorted.push(labels.shift()); } if (labels.length > 0) { sorted.push(labels.pop()); } sorted.push.apply(sorted, labels); return sorted; }; return PointAutoLabel; }(point_1.default)); exports.default = PointAutoLabel; base_1.registerLabelComponent('point-auto', PointAutoLabel); },{"../../dependents":425,"../../util/bbox":672,"../../util/view":715,"./base":414,"./point":417,"@antv/util":803,"tslib":894}],417:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../dependents"); var base_1 = tslib_1.__importStar(require("../../components/label/base")); var common_1 = require("../../util/common"); /** * 说明: * 适用于展示面积图和折线图上数据点的label * */ var PointLabel = /** @class */ (function (_super) { tslib_1.__extends(PointLabel, _super); function PointLabel() { return _super !== null && _super.apply(this, arguments) || this; } PointLabel.prototype.getDefaultOptions = function () { var theme = this.layer.theme; var _a = theme.label, label = _a === void 0 ? {} : _a; return tslib_1.__assign({ offsetX: 0, offsetY: 0 }, label); }; PointLabel.prototype.getLabelOffset = function () { return this.getLabelOffsetByDimAndFactor('y', -1); }; PointLabel.prototype.getLabelItemAttrs = function (element, index) { var _this = this; var _a = this.options, style = _a.style, formatter = _a.formatter; var mappingData = util_1.get(element, 'model.mappingData', []); return util_1.map(mappingData, function (datum, datumIndex) { var _a; var value = _this.getValue(datum); return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, _this.getPosition(datum)), { text: formatter ? formatter(value, (_a = {}, _a[dependents_1._ORIGIN] = datum._origin, _a.mappingDatum = datum, _a.mappingDatumIndex = datumIndex, _a.element = element, _a.elementIndex = index, _a), index) : value, textAlign: 'center', textBaseline: 'middle' }), style); }); }; PointLabel.prototype.getValue = function (datum) { return util_1.get(datum._origin, this.layer.options.yField); }; PointLabel.prototype.getPosition = function (datum) { var pos = { x: util_1.isArray(datum.x) ? util_1.last(datum.x) : datum.x, y: util_1.isArray(datum.y) ? util_1.last(datum.y) : datum.y, }; return pos; }; PointLabel.prototype.layoutLabels = function (geometry, labels) { var _this = this; if (!this.options.adjustPosition) { return; } var overlap = this.isOverlapped(labels); // 规则1:先横向,优先显示横向上变化趋势大的label if (overlap) { var tolerance_1 = this.getGlobalTolerance(labels); util_1.each(labels, function (label, index) { if (index > 1) { _this.labelResamplingByChange(label, labels, index, tolerance_1); } }); } overlap = this.isOverlapped(labels); // 规则2: 后纵向,优先保留纵向最高点label if (overlap) { util_1.each(labels, function (label, index) { if (label.get('visible')) { _this.clearOverlapping(label, labels, index); } }); } }; PointLabel.prototype.adjustLabel = function () { return; }; /** 根据变化进行抽样,保留变化较大的点,类似于点简化算法 */ PointLabel.prototype.labelResamplingByChange = function (label, labels, index, tolerance) { var previous = this.findPrevious(index, labels); var currentCenter = this.getCenter(label); var previousCenter = this.getCenter(previous); var distX = previousCenter.x - currentCenter.x; var distY = previousCenter.y - currentCenter.y; var dist = Math.sqrt(distX * distX + distY * distY); if (dist < tolerance) { label.set('visible', false); } }; PointLabel.prototype.clearOverlapping = function (label, labels, index) { // 找到所有与当前点overlap的node var overlapped = []; for (var i = 0; i < labels.length; i++) { var current = labels[i]; if (i !== index && current.get('visible')) { var isOverlap = common_1.isBBoxIntersect(label.getBBox(), current.getBBox()); if (isOverlap) { overlapped.push(current); } } } // 对overapped label进行处理 if (overlapped.length > 0) { overlapped.push(label); overlapped.sort(function (a, b) { return b.minY - a.minY; }); // 隐藏除最高点以外的label util_1.each(overlapped, function (label, index) { if (index > 0) { label.set('visible', false); } }); } }; /** 检测一组label中是否存在重叠 **/ PointLabel.prototype.isOverlapped = function (labels) { for (var i = 0; i < labels.length; i++) { if (labels[i].get('visible')) { var labelABBox = labels[i].getBBox(); for (var j = 0; j < labels.length; j++) { if (j !== i && labels[j].get('visible')) { var labelBBBox = labels[j].getBBox(); var intersection = common_1.isBBoxIntersect(labelABBox, labelBBBox); if (intersection) { return true; } } } } } return false; }; PointLabel.prototype.getGlobalTolerance = function (labels) { var labelsClone = labels.slice(); labelsClone.sort(function (a, b) { return b.getBBox().width - a.getBBox().width; }); return Math.round(labelsClone[0].getBBox().width); }; PointLabel.prototype.findPrevious = function (index, labels) { for (var i = index - 1; i > 0; i--) { if (labels[i].get('visible')) { return labels[i]; } } }; PointLabel.prototype.getCenter = function (label) { var _a = label.getBBox(), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY; return { x: minX + (maxX - minX) / 2, y: minY + (maxY - minY) / 2 }; }; return PointLabel; }(base_1.default)); exports.default = PointLabel; base_1.registerLabelComponent('point', PointLabel); },{"../../components/label/base":414,"../../dependents":425,"../../util/common":674,"@antv/util":803,"tslib":894}],418:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var state_1 = require("../../base/controller/state"); // 对label和label样式进行缓存 var labels; var originAttrs; function onActive(plot, condition) { if (!labels) { getAllLabels(plot); } util_1.each(labels, function (label, index) { var origin = label.get('origin'); if (state_1.compare(origin, condition)) { var originAttr = originAttrs[index]; var style = util_1.mix({}, originAttr, { opacity: 1 }); label.attr(style); } }); } function onDisable(plot, condition) { if (!labels) { getAllLabels(plot); } util_1.each(labels, function (label, index) { var origin = label.get('origin'); if (state_1.compare(origin, condition)) { var originAttr = originAttrs[index]; var disableStyle = labelDisableStyle(originAttr); label.attr(disableStyle); } }); } function getAllLabels(plot) { labels = []; originAttrs = []; var geoms = plot.view.get('elements'); util_1.each(geoms, function (geom) { var geomLabels = geom.get('labels'); if (geomLabels) { util_1.each(geomLabels, function (label) { labels.push(label); originAttrs.push(label.attr()); }); } }); } function labelDisableStyle(style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.2 }; } exports.default = { active: onActive, selected: onActive, disable: onDisable, }; },{"../../base/controller/state":390,"@antv/util":803}],419:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dependents_1 = require("../dependents"); var util_1 = require("@antv/util"); var animate_1 = require("@antv/g2/lib/animate"); var DEFAULT_STYLE = { stroke: 'transparent', fill: '#FCC509', lineWidth: 0, }; var ACTIVE_STYLE = { stroke: '#FFF', fill: '#FCC509', lineWidth: 1, }; var SELECTED_STYLE = { stroke: 'rgba(0,0,0,0.85)', fill: '#FCC509', lineWidth: 1, }; /** * 标注点 绘制在最顶层 */ var MarkerPoint = /** @class */ (function () { function MarkerPoint(cfg) { this.points = []; this.labels = []; this.name = 'markerPoints'; this.defaultCfg = { offsetX: 0, offsetY: 0, style: { normal: DEFAULT_STYLE, selected: SELECTED_STYLE, active: ACTIVE_STYLE }, label: { visible: false, offsetY: -8, position: 'top', style: { fill: 'rgba(0, 0, 0, 0.85)', }, }, animation: false, }; this.view = cfg.view; this.size = cfg.size || 6; this.config = util_1.deepMix({}, this.defaultCfg, cfg); this._init(); } MarkerPoint.prototype.render = function () { var dataArray = this.getDataArray(); this._renderPoints(dataArray); this.view.canvas.draw(); this._addInteraction(); }; MarkerPoint.prototype.clear = function () { if (this.container) { this.container.clear(); } }; MarkerPoint.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.points = []; this.labels = []; }; MarkerPoint.prototype.getDataArray = function () { var geometry = this.view.geometries[0]; return geometry.dataArray; }; MarkerPoint.prototype._init = function () { var _this = this; var layer = this.view.foregroundGroup; this.container = layer.addGroup(); this.render(); this.view.on('beforerender', function () { _this.clear(); }); }; MarkerPoint.prototype._renderPoints = function (dataArray) { var _this = this; util_1.each(this.config.data, function (dataItem, dataItemIdx) { util_1.each(dataArray, function (dataum) { var origin = util_1.find(dataum, function (d) { return util_1.isMatch(d._origin, dataItem); }); if (origin) { var pointAttrs = _this.config.style.normal; var group = _this.container.addGroup({ name: _this.name }); var x = origin.x, y = origin.y; if (util_1.isArray(x)) { x = x[0]; } if (util_1.isArray(y)) { y = y[0]; } var symbol = _this.config.symbol; var _a = _this.config, offsetX = _a.offsetX, offsetY = _a.offsetY; var point = void 0; if (util_1.isString(symbol) && symbol.startsWith('image://')) { var imageUrl = symbol.substr(8); point = group.addShape('image', { attrs: { x: x - _this.size / 2 + offsetX, y: y - _this.size / 2 + offsetY, img: imageUrl, width: _this.size, height: _this.size, }, }); } else { symbol = util_1.isString(symbol) ? dependents_1.MarkerSymbols[symbol] : symbol; point = group.addShape({ type: 'marker', name: 'marker-point', id: "point-" + dataItemIdx, attrs: tslib_1.__assign(tslib_1.__assign({ x: x + offsetX, y: y + offsetY, r: _this.size / 2 }, pointAttrs), { symbol: symbol }), }); } _this.points.push(point); _this._animatePoint(point); _this._renderLabel(group, origin, dataItemIdx); group.set('data', dataItem); group.set('origin', origin); } }); }); }; MarkerPoint.prototype._renderLabel = function (container, origin, index) { var labelCfg = this.config.label; if (labelCfg && labelCfg.visible) { var _a = labelCfg.offsetX, offsetX = _a === void 0 ? 0 : _a, _b = labelCfg.offsetY, offsetY = _b === void 0 ? 0 : _b, formatter = labelCfg.formatter, position = labelCfg.position, field = labelCfg.field; var text = origin._origin[field]; if (formatter) { text = formatter(text, { _origin: origin._origin }, index); } var x = util_1.isArray(origin.x) ? origin.x[0] : origin.x; var y = util_1.isArray(origin.y) ? origin.y[0] : origin.y; var label = container.addShape('text', { name: 'marker-label', id: "label-" + index, attrs: tslib_1.__assign(tslib_1.__assign({ x: x + offsetX, y: y + offsetY, text: text || '' }, labelCfg.style), { textAlign: 'center', textBaseline: position === 'top' ? 'bottom' : 'top' }), }); this.labels.push(label); } }; MarkerPoint.prototype._addInteraction = function () { var _this = this; var events = this.config.events; util_1.each(events, function (cb, eventName) { _this.container.on(_this.name + ":" + eventName, function (e) { cb(e); var target = e.target.get('parent'); var pointShape = target.get('children')[0]; if (pointShape) { var data = pointShape.get('data'); var id = pointShape.get('id'); var condition = { id: id, data: data }; if (eventName === 'click') { if (_this.selectedPoint && _this.selectedPoint.get('id') === id) { _this.selectedPoint = null; _this.setState('inactive', condition); } else { _this.selectedPoint = pointShape; _this.setState('selected', condition); } } else if (eventName === 'mouseenter') { _this.setState('active', condition); } else if (eventName === 'mouseleave') { _this.setState('inactive', condition); } } _this.view.canvas.draw(); }); _this.view.on('click', function (e) { var target = e.target.get('parent'); if (!target || (target.get('name') !== _this.name && _this.selectedPoint)) { _this.selectedPoint = null; _this.setState('inactive'); } }); }); }; MarkerPoint.prototype.setState = function (state, condition) { var _this = this; if (state === 'active') { if (!this.selectedPoint || condition.id !== this.selectedPoint.get('id')) { this._onActive(condition); } } else if (state === 'inactive') { this.points.forEach(function (p) { return _this._onInactive(p); }); } else if (state === 'selected') { this._onSelected(condition); } }; MarkerPoint.prototype._onActive = function (condition) { var _this = this; var active = this.config.style.active; util_1.each(this.points, function (point) { if (point.get('id') === condition.id) { util_1.each(active, function (v, k) { point.attr(k, v); }); } else { _this._onInactive(point); } }); }; MarkerPoint.prototype._onInactive = function (point) { var normal = this.config.style.normal; if (!this.selectedPoint || point.get('id') !== this.selectedPoint.get('id')) { util_1.each(normal, function (v, k) { point.attr(k, v); }); } }; MarkerPoint.prototype._onSelected = function (condition) { var _this = this; var selected = this.config.style.selected; util_1.each(this.points, function (point) { if (point.get('id') === condition.id) { util_1.each(selected, function (v, k) { point.attr(k, v); }); } else { _this._onInactive(point); } }); }; /** point animation, not for label */ MarkerPoint.prototype._animatePoint = function (shape) { var _a = this.config, animation = _a.animation, size = _a.size; if (animation !== false) { var _b = animation, _c = _b.endState, endState = _c === void 0 ? {} : _c, _d = _b.animateCfg, animateCfg = _d === void 0 ? animate_1.DEFAULT_ANIMATE_CFG.appear : _d; shape.animate(tslib_1.__assign({ r: Number.isNaN(endState.size / 2) ? size / 2 : endState.size / 2 }, endState), animateCfg); } }; return MarkerPoint; }()); exports.default = MarkerPoint; },{"../dependents":425,"@antv/g2/lib/animate":217,"@antv/util":803,"tslib":894}],420:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var dom_util_1 = require("@antv/dom-util"); var StatisticHtml = /** @class */ (function () { function StatisticHtml(cfg) { var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); this.x = this.options.x; this.y = this.options.y; this.html = this.options.html; this.container = this.options.container; } StatisticHtml.prototype.render = function () { if (util_1.isElement(this.container)) { this.wrapperNode = dom_util_1.createDom('
    '); this.container.appendChild(this.wrapperNode); dom_util_1.modifyCSS(this.wrapperNode, { position: 'absolute', pointerEvents: 'none', }); var htmlNode = this.html; this.wrapperNode.appendChild(htmlNode); this.setDomPosition(this.x, this.y); } }; StatisticHtml.prototype.updateHtml = function (content) { if (util_1.isType(content, 'HTMLDivElement')) { this.wrapperNode.innerHTML = ''; this.wrapperNode.appendChild(content); } else { this.wrapperNode.innerHTML = content; } this.setDomPosition(this.x, this.y); }; StatisticHtml.prototype.updatePosition = function (x, y) { this.x = x; this.y = y; this.setDomPosition(x, y); }; StatisticHtml.prototype.destroy = function () { this.container.removeChild(this.wrapperNode); }; StatisticHtml.prototype.getDefaultOptions = function () { return { x: 0, y: 0, width: 0, height: 0, html: '', container: null, alignX: 'middle', alignY: 'middle', }; }; StatisticHtml.prototype.setDomPosition = function (x, y) { var xPosition = x; var yPosition = y; var width = dom_util_1.getOuterWidth(this.wrapperNode); var height = dom_util_1.getOuterHeight(this.wrapperNode); if (this.options.alignX === 'middle') { xPosition = x - width / 2; } if (this.options.alignY === 'middle') { yPosition = y - height / 2; } dom_util_1.modifyCSS(this.wrapperNode, { top: Math.round(yPosition) + "px", left: Math.round(xPosition) + "px", /** * 支持Ant Design Charts * render是异步的操作,获取到的 width 为 0 */ transform: width > 0 ? 'none' : 'translate(-50%, -50%)', }); }; return StatisticHtml; }()); exports.default = StatisticHtml; },{"@antv/dom-util":92,"@antv/util":803}],421:[function(require,module,exports){ "use strict"; /** * @file 播放轴组件按钮 * @author blackganglion */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var Button = /** @class */ (function (_super) { tslib_1.__extends(Button, _super); function Button(cfg) { return _super.call(this, util_1.deepMix({}, cfg)) || this; } Button.prototype.renderInner = function (group) { var _this = this; this.initElement(group); this.updateElement(); this.renderMarker(); group.off('click'); group.on('click', function () { _this.emit('click'); }); }; Button.prototype.destroy = function () { this.group.off(); _super.prototype.destroy.call(this); }; Button.prototype.initElement = function (group) { this.circle = group.addShape('circle', { attrs: { x: this.config.x, y: this.config.y, r: this.config.r, fill: '#607889', }, }); this.startMarker = group.addShape('path', { attrs: { path: this.getStartMarkerPath(), fill: '#ffffff', }, }); this.pauseGroupMarker = group.addGroup(); var width = (1 / 4) * this.config.r; var height = 0.5 * this.config.r * Math.sqrt(3); this.pauseLeftMarker = this.pauseGroupMarker.addShape('rect', { attrs: { x: this.config.x - (1 / 4 + 1 / 8) * this.config.r, y: this.config.y - height / 2, width: width, height: height, fill: '#ffffff', }, }); this.pauseRightMarker = this.pauseGroupMarker.addShape('rect', { attrs: { x: this.config.x + (1 / 8) * this.config.r, y: this.config.y - height / 2, width: width, height: height, fill: '#ffffff', }, }); }; Button.prototype.updateElement = function () { this.circle.attr('x', this.config.x); this.circle.attr('y', this.config.y); this.circle.attr('r', this.config.r); this.startMarker.attr('path', this.getStartMarkerPath()); var width = (1 / 4) * this.config.r; var height = 0.5 * this.config.r * Math.sqrt(3); this.pauseLeftMarker.attr('x', this.config.x - (1 / 4 + 1 / 8) * this.config.r); this.pauseLeftMarker.attr('y', this.config.y - height / 2); this.pauseLeftMarker.attr('width', width); this.pauseLeftMarker.attr('height', height); this.pauseRightMarker.attr('x', this.config.x + (1 / 8) * this.config.r); this.pauseRightMarker.attr('y', this.config.y - height / 2); this.pauseRightMarker.attr('width', width); this.pauseRightMarker.attr('height', height); }; Button.prototype.renderMarker = function () { if (this.config.isPlay) { this.startMarker.hide(); this.pauseGroupMarker.show(); } else { this.startMarker.show(); this.pauseGroupMarker.hide(); } }; /** 获取播放键 marker path */ Button.prototype.getStartMarkerPath = function () { var sideLength = 0.5 * this.config.r * Math.sqrt(3); return [ ['M', this.config.x - sideLength / Math.sqrt(3) / 2, this.config.y - sideLength / 2], ['L', this.config.x + sideLength / Math.sqrt(3), this.config.y], ['L', this.config.x - sideLength / Math.sqrt(3) / 2, this.config.y + sideLength / 2], ]; }; return Button; }(base_1.default)); exports.default = Button; },{"../base":407,"@antv/util":803,"tslib":894}],422:[function(require,module,exports){ "use strict"; /** * @file 基于 G 的播放轴组件 * @author blackganglion */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var button_1 = tslib_1.__importDefault(require("./button")); var base_1 = tslib_1.__importDefault(require("../base")); var TIMELINE_START = 'timelinestart'; var TIMELINE_CHANGE = 'timelinechange'; var TIMELINE_END = 'timelineend'; var TIMELINE_UPDATE = 'timelineupdate'; var PADDING_LEFT = 20; var PADDING_RIGHT = 20; /** * 参考示例 * https://www.gapminder.org/tools/#$state$time$value=1870&delay:100;;&chart-type=bubbles */ var TimeLine = /** @class */ (function (_super) { tslib_1.__extends(TimeLine, _super); function TimeLine(cfg) { var _this = _super.call(this, util_1.deepMix({}, { speed: 1, loop: false, }, cfg)) || this; _this.onTimeSelectMouseMove = function (e) { e.stopPropagation(); e.preventDefault(); var x = util_1.get(e, 'touches.0.pageX', e.pageX); var offsetX = x - _this.prevX; _this.setTimeSelectX(offsetX); _this.prevX = x; }; _this.onTimeSelectMouseUp = function () { _this.syncCurrnentTick(); _this.emit(TIMELINE_END, null); // 取消事件 var containerDOM = _this.getCanvas().get('container'); if (containerDOM) { containerDOM.removeEventListener('mousemove', _this.onTimeSelectMouseMove); containerDOM.removeEventListener('mouseup', _this.onTimeSelectMouseUp); // 防止滑动到 canvas 外部之后,状态丢失 containerDOM.removeEventListener('mouseleave', _this.onTimeSelectMouseUp); // 移动端事件 containerDOM.removeEventListener('touchmove', _this.onTimeSelectMouseMove); containerDOM.removeEventListener('touchend', _this.onTimeSelectMouseUp); containerDOM.removeEventListener('touchcancel', _this.onTimeSelectMouseUp); } }; _this.onTimeSelectMouseDown = function (e) { // 取出原生事件 var event = e.originalEvent; event.stopPropagation(); event.preventDefault(); if (_this.isPlay === false) { _this.emit(TIMELINE_START, null); } else { // 取消播放状态 _this.isPlay = false; // 拖动过程中的播放暂停不需要调整 tick 位置,防止偏移 _this.changePlayStatus(false); } _this.prevX = util_1.get(event, 'touches.0.pageX', event.pageX); // 开始滑动的时候,绑定 move 和 up 事件 var containerDOM = _this.getCanvas().get('container'); containerDOM.addEventListener('mousemove', _this.onTimeSelectMouseMove); containerDOM.addEventListener('mouseup', _this.onTimeSelectMouseUp); containerDOM.addEventListener('mouseleave', _this.onTimeSelectMouseUp); // 移动端事件 containerDOM.addEventListener('touchmove', _this.onTimeSelectMouseMove); containerDOM.addEventListener('touchend', _this.onTimeSelectMouseUp); containerDOM.addEventListener('touchcancel', _this.onTimeSelectMouseUp); }; return _this; } TimeLine.prototype.renderInner = function (group) { var _a = this.config, ticks = _a.ticks, defaultCurrentTick = _a.defaultCurrentTick; if (ticks && ticks.length) { this.currentTick = this.config.ticks.includes(defaultCurrentTick) ? defaultCurrentTick : ticks[0]; this.renderPlayButton(group); this.renderTimeLine(group); this.renderTimeSelect(group, this.currentTick); this.initEvent(); } }; // 更新配置 TimeLine.prototype.update = function (cfg) { _super.prototype.update.call(this, cfg); // 更新时需要触发一次,来过滤数据 this.emit(TIMELINE_UPDATE, this.currentTick); }; TimeLine.prototype.destroy = function () { _super.prototype.destroy.call(this); this.timeLineButton.destroy(); this.timeLineButton.off(); this.timeSelect.off(); if (this.playHandler) { window.cancelAnimationFrame(this.playHandler); } }; TimeLine.prototype.renderPlayButton = function (group) { var _a = this.config, height = _a.height, x = _a.x, y = _a.y; var ratio = 0.8; var r = (height / 2) * ratio; if (this.timeLineButton) { this.timeLineButton.update({ x: x + r, y: y + r + (height * (1 - ratio)) / 2, r: r, }); } else { this.timeLineButton = new button_1.default({ container: group, x: x + r, y: y + r + (height * (1 - ratio)) / 2, r: r, isPlay: this.isPlay, }); this.timeLineButton.init(); } this.timeLineButton.render(); }; TimeLine.prototype.getTimeLinePath = function () { var _a = this.timeLine, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var r = height / 2; if (width > 0) { return ("M" + x + ", " + y + ("A" + r + "," + r + " 90 0,0 " + x + "," + (y + height)) + ("L" + (x + width) + ", " + (y + height)) + ("A" + r + "," + r + " 90 0,0 " + (x + width) + "," + y) + ("L" + x + ", " + y)); } return []; }; TimeLine.prototype.renderTimeLine = function (group) { var _this = this; var _a = this.config, width = _a.width, height = _a.height, ticks = _a.ticks, x = _a.x, y = _a.y; if (!this.timeLine) { this.timeLine = {}; } /** 默认高度是真实高度 15% */ this.timeLine.height = height * 0.15; this.timeLine.x = x + height + PADDING_LEFT; this.timeLine.y = y + (height / 2 - this.timeLine.height / 2); this.timeLine.width = width - this.timeLine.x - PADDING_RIGHT; if (this.timeLine && this.timeLine.shape) { this.timeLine.shape.attr('path', this.getTimeLinePath()); } else { this.timeLine.shape = group.addShape('path', { attrs: { path: this.getTimeLinePath(), fill: '#607889', opacity: 0.2, }, }); } var interval = this.timeLine.width / (ticks.length - 1); this.tickPosList = []; if (this.timeLine.textList && this.timeLine.textList.length) { this.timeLine.textList.forEach(function (text) { text.destroy(); }); } var lastX = -Infinity; this.timeLine.textList = ticks.map(function (tick, index) { _this.tickPosList.push(_this.timeLine.x + index * interval); var text = group.addShape('text', { attrs: { x: _this.timeLine.x + index * interval, y: _this.timeLine.y + _this.timeLine.height + 5, text: tick, textAlign: 'center', textBaseline: 'top', fill: '#607889', opacity: 0.35, }, }); var bbox = text.getBBox(); // 抽样,标签与标签间距不小于 10 if (bbox.minX > lastX) { text.show(); lastX = bbox.minX + bbox.width + 10; } else { text.hide(); } return text; }); }; TimeLine.prototype.renderTimeSelect = function (group, tickValue) { var _a = this.config, ticks = _a.ticks, height = _a.height; var interval = this.timeLine.width / (ticks.length - 1); var index = util_1.findIndex(ticks, function (tick) { return tick === tickValue; }); var x = this.timeLine.x + index * interval; var y = this.config.y + height / 2; var r = height * 0.15; if (this.timeSelect) { this.timeSelect.attr('x', x); this.timeSelect.attr('y', y); this.timeSelect.attr('r', r); } else { this.timeSelect = group.addShape('circle', { attrs: { x: x, y: y, r: r, fill: '#607889', }, }); } if (this.timeSelectText) { this.timeSelectText.attr('x', x); this.timeSelectText.attr('y', y - height * 0.15 - 14); this.timeSelectText.attr('text', this.currentTick); } else { this.timeSelectText = group.addShape('text', { attrs: { x: x, y: y - height * 0.15 - 14, text: this.currentTick, textAlign: 'center', textBaseline: 'top', fill: '#607889', }, }); } }; /** 输入当前圆点位置,输出离哪个 tick 的位置最近 */ TimeLine.prototype.adjustTickIndex = function (timeSelectX) { for (var i = 0; i < this.tickPosList.length - 1; i++) { if (this.tickPosList[i] <= timeSelectX && timeSelectX <= this.tickPosList[i + 1]) { return Math.abs(this.tickPosList[i] - timeSelectX) < Math.abs(timeSelectX - this.tickPosList[i + 1]) ? i : i + 1; } } }; /** 拖动或自动播放过程中,设置 TimeSelect 的位置 */ TimeLine.prototype.setTimeSelectX = function (offsetX) { var timeSelectX = this.timeSelect.attr('x') + offsetX; // 防止左右溢出 if (timeSelectX < this.timeLine.x) { timeSelectX = this.timeLine.x; } if (timeSelectX > this.timeLine.x + this.timeLine.width) { timeSelectX = this.timeLine.x + this.timeLine.width; // 正在播放场景 if (this.isPlay) { // 如果是循环 if (this.config.loop) { // 当前滑动点已经处于最后一个 tick 上,才能重置回去,继续循环 if (this.timeSelect.attr('x') === this.timeLine.x + this.timeLine.width) { timeSelectX = this.timeLine.x; } } else { this.isPlay = false; this.changePlayStatus(); } } } this.timeSelect.attr('x', timeSelectX); this.timeSelectText.attr('x', timeSelectX); var index = this.adjustTickIndex(timeSelectX); if (this.currentTick !== this.config.ticks[index]) { this.currentTick = this.config.ticks[index]; this.timeSelectText.attr('text', this.currentTick); this.emit(TIMELINE_CHANGE, this.currentTick); } this.getCanvas().draw(); }; /** 同步圆点到 currnentTick */ TimeLine.prototype.syncCurrnentTick = function () { var _this = this; var ticks = this.config.ticks; var interval = this.timeLine.width / (ticks.length - 1); var index = util_1.findIndex(ticks, function (tick) { return tick === _this.currentTick; }); var x = this.timeLine.x + index * interval; this.timeSelect.attr('x', x); this.timeSelectText.attr('x', x); this.getCanvas().draw(); }; TimeLine.prototype.startPlay = function () { var _this = this; return window.requestAnimationFrame(function () { var _a = _this.config, speed = _a.speed, ticks = _a.ticks; var width = _this.timeLine.width; var tickInterval = width / ticks.length; var offsetX = tickInterval / ((speed * 1000) / 60); _this.setTimeSelectX(offsetX); if (_this.isPlay) { _this.playHandler = _this.startPlay(); } }); }; TimeLine.prototype.changePlayStatus = function (isSync) { if (isSync === void 0) { isSync = true; } this.timeLineButton.update({ isPlay: this.isPlay, }); if (this.isPlay) { // 开始播放 this.playHandler = this.startPlay(); this.emit(TIMELINE_START, null); } else { // 结束播放 if (this.playHandler) { window.cancelAnimationFrame(this.playHandler); if (isSync) { this.syncCurrnentTick(); this.emit(TIMELINE_END, null); } } } this.getCanvas().draw(); }; TimeLine.prototype.initEvent = function () { var _this = this; /** 播放/暂停事件 */ this.timeLineButton.off('click'); this.timeLineButton.on('click', function () { _this.isPlay = !_this.isPlay; _this.changePlayStatus(); }); /** 播放轴上圆点滑动事件 */ this.timeSelect.off('mousedown'); this.timeSelect.on('mousedown', function (event) { _this.onTimeSelectMouseDown(event); }); }; return TimeLine; }(base_1.default)); exports.default = TimeLine; },{"../base":407,"./button":421,"@antv/util":803,"tslib":894}],423:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EVENTS = exports.ELEMENT_NAMES = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); var dependents_1 = require("../dependents"); var g_util_1 = require("../util/g-util"); var text_1 = require("../util/text"); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var ELEMENT_NAMES; (function (ELEMENT_NAMES) { ELEMENT_NAMES["TOOLTIP_INDICATOR_INNER"] = "tooltip_indicator-inner"; ELEMENT_NAMES["TOOLTIP_INDICATOR_TITLE"] = "tooltip_indicator-title"; ELEMENT_NAMES["TOOLTIP_INDICATOR_BODY"] = "tooltip_indicator-body"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_GROUP"] = "tooltip_indicator-item-group"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_BACKGROUND"] = "tooltip_indicator-item-background"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_LINE"] = "tooltip_indicator-item-line"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_TITLE"] = "tooltip_indicator-item-title"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_BODY"] = "tooltip_indicator-item-body"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_VALUE_GROUP"] = "tooltip_indicator-item-value-group"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_NAME"] = "tooltip_indicator-item-name"; ELEMENT_NAMES["TOOLTIP_INDICATOR_ITEM_VALUE"] = "tooltip_indicator-item-value"; })(ELEMENT_NAMES = exports.ELEMENT_NAMES || (exports.ELEMENT_NAMES = {})); var EVENTS; (function (EVENTS) { EVENTS["ON_SELECT_ITEM"] = "onSelectItem"; })(EVENTS = exports.EVENTS || (exports.EVENTS = {})); var PADDING; (function (PADDING) { PADDING[PADDING["LARGE"] = 12] = "LARGE"; PADDING[PADDING["NORMAL"] = 8] = "NORMAL"; PADDING[PADDING["SMALL"] = 4] = "SMALL"; })(PADDING || (PADDING = {})); var MAX_ITEM_TITLE_WIDTH = 160; /** 指标卡图例组件 */ var TooltipIndicator = /** @class */ (function (_super) { tslib_1.__extends(TooltipIndicator, _super); function TooltipIndicator() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.curX = 0; _this.curY = 0; _this.offsetX = 0; _this.scrollWidth = 0; _this.onBodyGroupMousemove = function (evt) { var itemGroup = findTargetAncestor(evt.target, function (target) { return target.get('name') === ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_GROUP; }); if (itemGroup) { var itemData = itemGroup.get('delegateObject'); _this.doSelectItem(itemData.item.id); } }; _this.onWheel = function (evt) { var _a = _this.config.width, width = _a === void 0 ? 0 : _a; var deltaX = evt.deltaX; var offsetMin = Math.min(_this.scrollWidth - width, 0) - (_this.scrollWidth / 2 + Math.max(0, (_this.scrollWidth - width) / 2)); var offsetMax = Math.max(_this.scrollWidth - width, 0) + _this.scrollWidth / 2 + Math.max(0, (_this.scrollWidth - width) / 2); var newOffsetX = util_1.clamp(_this.offsetX + deltaX, offsetMin, offsetMax); if (newOffsetX !== _this.offsetX) { g_util_1.translate(_this.bodyGroup, _this.offsetX - newOffsetX, 0); _this.offsetX = newOffsetX; } }; return _this; } TooltipIndicator.prototype.destroy = function () { this.offEvents(); _super.prototype.destroy.call(this); }; /** 选中某一项 */ TooltipIndicator.prototype.selectItem = function (id) { this.doSelectItem(id); }; /** 重置选中状态 */ TooltipIndicator.prototype.resetSelect = function () { this.doSelectItem(this.selectedItemId); }; TooltipIndicator.prototype.initConfig = function (config) { var _a; var _b = config.theme, theme = _b === void 0 ? {} : _b; var defaultCfg = { x: 0, y: 0, title: { text: '', spacingY: PADDING.NORMAL, style: {}, }, line: { spacingX: PADDING.SMALL, width: 2, style: {}, }, itemTitle: { spacingX: 0, spacingY: PADDING.SMALL, style: {}, }, itemName: { spacingX: PADDING.NORMAL, spacingY: PADDING.SMALL, style: {}, }, itemValue: { style: {}, }, itemBackground: { style: { opacity: 0, fill: '#000', }, }, itemSpacing: PADDING.LARGE, }; this.config = util_1.deepMix({}, (_a = theme === null || theme === void 0 ? void 0 : theme.components) === null || _a === void 0 ? void 0 : _a.tooltipIndicator, defaultCfg, config); this.selectedItemId = this.config.selectedItem; }; TooltipIndicator.prototype.renderInner = function (group) { var _this = this; this.resetRender(); var _a = this.config, items = _a.items, x = _a.x, y = _a.y; var itemGroups = []; var innerGroup = group.addGroup({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_INNER, }); this.renderTitle(innerGroup); this.bodyGroup = innerGroup.addGroup({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_BODY, }); items === null || items === void 0 ? void 0 : items.forEach(function (item, index) { itemGroups.push(_this.renderItem(_this.bodyGroup, item, index)); }); this.layoutItems(innerGroup); g_util_1.move(innerGroup, x, y); this.applyClip(group); this.bindEvents(innerGroup); }; TooltipIndicator.prototype.renderTitle = function (group) { var title = this.config.title; if (title === null || title === void 0 ? void 0 : title.text) { var shape = group.addShape({ type: 'text', name: ELEMENT_NAMES.TOOLTIP_INDICATOR_TITLE, attrs: tslib_1.__assign({ text: title === null || title === void 0 ? void 0 : title.text, textAlign: 'left', textBaseline: 'top' }, ((title === null || title === void 0 ? void 0 : title.style) || {})), }); var bbox = shape.getBBox(); this.curY += bbox.height; this.curY += title.spacingY || 0; return shape; } }; TooltipIndicator.prototype.renderItem = function (group, item, index) { var itemBackground = this.config.itemBackground; var itemGroup = group.addGroup({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_GROUP, delegateObject: { item: item, index: index, }, }); var oldX = this.curX; var oldY = this.curY; var background = itemGroup.addShape({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_BACKGROUND, type: 'rect', attrs: tslib_1.__assign({ x: this.curX, y: this.curY, width: 1, height: 1 }, (itemBackground.style || {})), }); var line = this.renderLine(itemGroup, item); this.renderItemTitle(itemGroup, item); this.renderItemValues(itemGroup, item); var itemGroupBBox = itemGroup.getBBox(); // update line height line.attr({ y2: line.attr('y1') + itemGroupBBox.height, }); // spacing this.curX = oldX + itemGroupBBox.width; this.curX += this.config.itemSpacing || 0; // update background background.attr({ width: this.curX - oldX - background.attr('lineWidth') * 2, height: this.curY - oldY - background.attr('lineWidth') * 2, }); // reset Y this.curY = oldY; return itemGroup; }; TooltipIndicator.prototype.renderLine = function (group, item) { var line = this.config.line; var width = line.width || 2; var attrs = tslib_1.__assign({ x1: this.curX + width / 2, y1: this.curY, x2: this.curX + width / 2, y2: this.curY, lineWidth: width, stroke: item.color }, ((line === null || line === void 0 ? void 0 : line.style) || {})); var shape = group.addShape({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_LINE, type: 'line', attrs: attrs, }); var bbox = shape.getBBox(); this.curX += bbox.width; this.curX += line.spacingX || 0; return shape; }; TooltipIndicator.prototype.renderItemTitle = function (group, item) { var itemTitle = this.config.itemTitle; var text = text_1.getEllipsisText(item.title, MAX_ITEM_TITLE_WIDTH, itemTitle.style || {}); var shape = group.addShape({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_TITLE, type: 'text', attrs: tslib_1.__assign({ x: this.curX, y: this.curY, textAlign: 'left', textBaseline: 'top', text: text }, (itemTitle.style || {})), }); var bbox = shape.getBBox(); this.curY += bbox.height; this.curY += itemTitle.spacingY || 0; return shape; }; TooltipIndicator.prototype.renderItemValues = function (group, item) { var _this = this; var _a; var itemBodyGroup = group.addGroup({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_BODY, }); var oldX = this.curX; (_a = item.values) === null || _a === void 0 ? void 0 : _a.forEach(function (value, valueIndex) { var valueGroup = itemBodyGroup.addGroup({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_VALUE_GROUP, delegateObject: { item: item, valueIndex: valueIndex, }, }); // reset x _this.curX = oldX; _this.renderItemValueName(valueGroup, value); _this.renderItemValueValue(valueGroup, value); }); this.layoutItemValues(itemBodyGroup); return itemBodyGroup; }; TooltipIndicator.prototype.renderItemValueName = function (group, value) { var itemName = this.config.itemName; if (value.name) { var shape = group.addShape({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_NAME, type: 'text', attrs: tslib_1.__assign({ x: this.curX, y: this.curY, textAlign: 'left', textBaseline: 'top', text: value.name }, (itemName.style || {})), }); var bbox = shape.getBBox(); if (value.wrapLine) { this.curY += bbox.height; this.curY += itemName.spacingY || 0; } else { this.curX += bbox.width; this.curX += itemName.spacingX || 0; } return shape; } }; TooltipIndicator.prototype.renderItemValueValue = function (group, value) { var _a = this.config, itemName = _a.itemName, itemValue = _a.itemValue; var shape = group.addShape({ name: ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_VALUE, type: 'text', attrs: tslib_1.__assign({ x: this.curX, y: this.curY, textAlign: 'left', textBaseline: 'top', text: value.value }, (itemValue.style || {})), }); var bbox = shape.getBBox(); this.curY += bbox.height; this.curY += itemName.spacingY || 0; return shape; }; TooltipIndicator.prototype.layoutItems = function (group) { var bodyGroup = group.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_BODY)[0]; var itemGroups = group.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_GROUP); if (!bodyGroup || itemGroups.length === 0) { return; } var bodyGroupBBox = bodyGroup.getBBox(); this.scrollWidth = bodyGroupBBox.width; }; TooltipIndicator.prototype.layoutItemValues = function (group) { var valueGroups = group.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_VALUE_GROUP); var valueGroupBBoxes = valueGroups.map(function (item) { return bbox_1.default.fromBBoxObject(item.getBBox()); }); var valueShapes = group.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_VALUE); var valueShapeBBoxes = valueShapes.map(function (shape) { return bbox_1.default.fromBBoxObject(shape.getBBox()); }); var maxX = Math.max.apply(Math, valueShapeBBoxes.map(function (bbox) { return bbox.maxX; })); valueGroups.forEach(function (valueGroup, index) { var bbox = valueGroupBBoxes[index]; var nameShape = valueGroup.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_NAME)[0]; var valueShape = valueGroup.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_VALUE)[0]; if (nameShape && valueShape) { var nameShapeBBox = bbox_1.default.fromBBoxObject(nameShape.getBBox()); var valueShapeBBox = bbox_1.default.fromBBoxObject(valueShape.getBBox()); // horizontal align: name & value if (nameShapeBBox.height < bbox.height) { nameShape.attr('y', nameShape.attr('y') + (bbox.height - nameShapeBBox.height) / 2); } if (valueShapeBBox.height < bbox.height) { valueShape.attr('y', valueShape.attr('y') + (bbox.height - valueShapeBBox.height) / 2); } // vertical align values if (valueShapeBBox.maxX < maxX) { valueShape.attr('x', valueShape.attr('x') + maxX - valueShapeBBox.maxX); } } }); }; TooltipIndicator.prototype.applyClip = function (group) { var _a = this.config, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var bbox = group.getBBox(); if (width || height) { group.setClip({ type: 'rect', attrs: { x: x, y: y, width: width || bbox.width, height: height || bbox.height, }, }); } }; TooltipIndicator.prototype.doSelectItem = function (id) { var _this = this; var group = this.getGroup(); var itemGroups = group.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_GROUP); if (id !== this.selectedItemId) { itemGroups.forEach(function (itemGroup) { var curItemData = itemGroup.get('delegateObject'); if (curItemData) { _this.applyItemStyle(itemGroup, curItemData.item.id === id ? 'selected' : 'inactive'); } }); this.selectedItemId = id; } else { // 取消选中 itemGroups.forEach(function (itemGroup) { _this.applyItemStyle(itemGroup); }); this.selectedItemId = undefined; } this.emit(EVENTS.ON_SELECT_ITEM, this.selectedItemId); }; TooltipIndicator.prototype.applyItemStyle = function (itemGroup, state) { var _a = this.config, line = _a.line, itemTitle = _a.itemTitle, itemName = _a.itemName, itemValue = _a.itemValue; var lineShape = itemGroup.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_LINE)[0]; var titleShape = itemGroup.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_TITLE)[0]; var itemNameShapes = itemGroup.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_NAME); var itemValueShapes = itemGroup.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_ITEM_VALUE); var styleName = state && state + "Style"; if (lineShape) { lineShape.attr(line.style); lineShape.attr(line[styleName] || {}); } if (titleShape) { titleShape.attr(itemTitle.style); titleShape.attr(itemTitle[styleName] || {}); } itemNameShapes.forEach(function (itemNameShape) { itemNameShape.attr(itemName.style); itemNameShape.attr(itemName[styleName] || {}); }); itemValueShapes.forEach(function (itemValueShape) { itemValueShape.attr(itemValue.style); itemValueShape.attr(itemValue[styleName] || {}); }); }; TooltipIndicator.prototype.bindEvents = function (group) { var _this = this; this.offEvents(); var bodyGroup = group.findAllByName(ELEMENT_NAMES.TOOLTIP_INDICATOR_BODY)[0]; bodyGroup.on('mousemove', this.onBodyGroupMousemove); this.addDisposable(function () { bodyGroup.off('mousemove', _this.onBodyGroupMousemove); }); this.gm = new dependents_1.GM(bodyGroup); this.wheel = new dependents_1.Wheel(bodyGroup); this.wheel.on('wheel', this.onWheel); }; TooltipIndicator.prototype.offEvents = function () { if (this.gm) { this.gm.destroy(); } if (this.wheel) { this.wheel.destroy(); } }; TooltipIndicator.prototype.resetRender = function () { this.curX = 0; this.curY = 0; this.offsetX = 0; }; return TooltipIndicator; }(base_1.default)); exports.default = TooltipIndicator; function findTargetAncestor(element, predicate) { var cur = element; while (cur) { if (predicate(cur)) { return cur; } cur = cur.getParent(); } } },{"../dependents":425,"../util/bbox":672,"../util/g-util":679,"../util/text":714,"./base":407,"@antv/util":803,"tslib":894}],424:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var state_1 = require("../../base/controller/state"); var POSITION_MAPPER = ['xField', 'yField', 'angleField']; function onActive(plot, condition) { var props = plot.options; // 获取state condition对应在画布的位置,只有在state condition对应字段为位置映射字段时,tooltip才会对齐进行响应 if (shouldActive(props, condition)) { var data = props.data; util_1.each(data, function (d) { if (state_1.compare(d, condition)) { var point = plot.view.getXY(d); // 调用showTooltip方法 plot.view.on('tooltip:create', function (e) { processState(condition, e, false); }); plot.view.showTooltip(point); } }); } } function onDisable(plot, condition) { plot.view.on('tooltip:change', function (e) { processState(condition, e, true); }); } function processState(condition, e, inverse) { var expected = inverse ? false : true; var originItems = util_1.clone(e.items); e.items.splice(0); util_1.each(originItems, function (item) { var origin = item.point._origin; if (state_1.compare(origin, condition) === expected) { e.items.push(item); } }); } function shouldActive(props, condition) { var fields = getPositionField(props); return !util_1.isFunction(condition) && fields.indexOf(condition.name); } function getPositionField(props) { var fields = []; util_1.each(POSITION_MAPPER, function (v) { if (util_1.has(props, v)) { fields.push(v); } }); return fields; } exports.default = { active: onActive, selected: onActive, disable: onDisable, }; },{"../../base/controller/state":390,"@antv/util":803}],425:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports._ORIGIN = exports.ORIGIN = exports.TooltipCssConst = exports.HtmlTooltipTheme = exports.HtmlTooltip = exports.InteractionUtils = exports.GrammarInteraction = exports.GestureController = void 0; var tslib_1 = require("tslib"); // dependents是基础依赖,以便按需使用plot var gesture_1 = tslib_1.__importDefault(require("@antv/g2/lib/chart/controller/gesture")); exports.GestureController = gesture_1.default; var g2_1 = require("@antv/g2"); g2_1.registerComponentController('gesture', gesture_1.default); // G var g_base_1 = require("@antv/g-base"); Object.defineProperty(exports, "GraphicEvent", { enumerable: true, get: function () { return g_base_1.Event; } }); var g_canvas_1 = require("@antv/g-canvas"); Object.defineProperty(exports, "Canvas", { enumerable: true, get: function () { return g_canvas_1.Canvas; } }); var g_svg_1 = require("@antv/g-svg"); Object.defineProperty(exports, "SVG", { enumerable: true, get: function () { return g_svg_1.Canvas; } }); // G-Gesture var g_gesture_1 = require("@antv/g-gesture"); Object.defineProperty(exports, "GM", { enumerable: true, get: function () { return g_gesture_1.GM; } }); Object.defineProperty(exports, "Wheel", { enumerable: true, get: function () { return g_gesture_1.Wheel; } }); // G2 var g2_2 = require("@antv/g2"); Object.defineProperty(exports, "View", { enumerable: true, get: function () { return g2_2.View; } }); Object.defineProperty(exports, "registerAnimation", { enumerable: true, get: function () { return g2_2.registerAnimation; } }); Object.defineProperty(exports, "registerGeometry", { enumerable: true, get: function () { return g2_2.registerGeometry; } }); Object.defineProperty(exports, "Geometry", { enumerable: true, get: function () { return g2_2.Geometry; } }); Object.defineProperty(exports, "Interaction", { enumerable: true, get: function () { return g2_2.Interaction; } }); Object.defineProperty(exports, "InteractionAction", { enumerable: true, get: function () { return g2_2.InteractionAction; } }); Object.defineProperty(exports, "registerInteraction", { enumerable: true, get: function () { return g2_2.registerInteraction; } }); Object.defineProperty(exports, "registerAction", { enumerable: true, get: function () { return g2_2.registerAction; } }); Object.defineProperty(exports, "registerShape", { enumerable: true, get: function () { return g2_2.registerShape; } }); Object.defineProperty(exports, "getTheme", { enumerable: true, get: function () { return g2_2.getTheme; } }); Object.defineProperty(exports, "Util", { enumerable: true, get: function () { return g2_2.Util; } }); Object.defineProperty(exports, "getShapeFactory", { enumerable: true, get: function () { return g2_2.getShapeFactory; } }); Object.defineProperty(exports, "ComponentController", { enumerable: true, get: function () { return g2_2.ComponentController; } }); Object.defineProperty(exports, "registerComponentController", { enumerable: true, get: function () { return g2_2.registerComponentController; } }); var constant_1 = require("@antv/g2/lib/constant"); Object.defineProperty(exports, "VIEW_LIFE_CIRCLE", { enumerable: true, get: function () { return constant_1.VIEW_LIFE_CIRCLE; } }); Object.defineProperty(exports, "COMPONENT_TYPE", { enumerable: true, get: function () { return constant_1.COMPONENT_TYPE; } }); Object.defineProperty(exports, "FIELD_ORIGIN", { enumerable: true, get: function () { return constant_1.FIELD_ORIGIN; } }); var tooltip_1 = require("@antv/g2/lib/chart/controller/tooltip"); Object.defineProperty(exports, "TooltipController", { enumerable: true, get: function () { return tooltip_1.default; } }); var marker_1 = require("@antv/g2/lib/util/marker"); Object.defineProperty(exports, "MarkerSymbols", { enumerable: true, get: function () { return marker_1.MarkerSymbols; } }); var grammar_interaction_1 = tslib_1.__importDefault(require("@antv/g2/lib/interaction/grammar-interaction")); exports.GrammarInteraction = grammar_interaction_1.default; var InteractionUtils = tslib_1.__importStar(require("@antv/g2/lib/interaction/action/util")); exports.InteractionUtils = InteractionUtils; var animate_1 = require("@antv/g2/lib/animate"); Object.defineProperty(exports, "DEFAULT_ANIMATE_CFG", { enumerable: true, get: function () { return animate_1.DEFAULT_ANIMATE_CFG; } }); Object.defineProperty(exports, "getDefaultAnimateCfg", { enumerable: true, get: function () { return animate_1.getDefaultAnimateCfg; } }); Object.defineProperty(exports, "doAnimate", { enumerable: true, get: function () { return animate_1.doAnimate; } }); var element_1 = require("@antv/g2/lib/geometry/element"); Object.defineProperty(exports, "Element", { enumerable: true, get: function () { return element_1.default; } }); // Component var html_1 = tslib_1.__importDefault(require("@antv/component/lib/tooltip/html")); exports.HtmlTooltip = html_1.default; var html_theme_1 = tslib_1.__importDefault(require("@antv/component/lib/tooltip/html-theme")); exports.HtmlTooltipTheme = html_theme_1.default; var TooltipCssConst = tslib_1.__importStar(require("@antv/component/lib/tooltip/css-const")); exports.TooltipCssConst = TooltipCssConst; var component_1 = require("@antv/component"); Object.defineProperty(exports, "GroupComponent", { enumerable: true, get: function () { return component_1.GroupComponent; } }); Object.defineProperty(exports, "Axis", { enumerable: true, get: function () { return component_1.Axis; } }); Object.defineProperty(exports, "Legend", { enumerable: true, get: function () { return component_1.Legend; } }); Object.defineProperty(exports, "Tooltip", { enumerable: true, get: function () { return component_1.Tooltip; } }); Object.defineProperty(exports, "Slider", { enumerable: true, get: function () { return component_1.Slider; } }); Object.defineProperty(exports, "Scrollbar", { enumerable: true, get: function () { return component_1.Scrollbar; } }); // Coordinate var coord_1 = require("@antv/coord"); Object.defineProperty(exports, "Coordinate", { enumerable: true, get: function () { return coord_1.Coordinate; } }); // Common exports.ORIGIN = 'origin'; exports._ORIGIN = '_origin'; },{"@antv/component":51,"@antv/component/lib/tooltip/css-const":62,"@antv/component/lib/tooltip/html":64,"@antv/component/lib/tooltip/html-theme":63,"@antv/coord":83,"@antv/g-base":115,"@antv/g-canvas":127,"@antv/g-gesture":166,"@antv/g-svg":186,"@antv/g2":309,"@antv/g2/lib/animate":217,"@antv/g2/lib/chart/controller/gesture":224,"@antv/g2/lib/chart/controller/tooltip":228,"@antv/g2/lib/constant":237,"@antv/g2/lib/geometry/element":252,"@antv/g2/lib/interaction/action/util":353,"@antv/g2/lib/interaction/grammar-interaction":361,"@antv/g2/lib/util/marker":379,"tslib":894}],426:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var main_1 = tslib_1.__importDefault(require("./main")); var mini_1 = tslib_1.__importDefault(require("./mini")); exports.default = { main: main_1.default, mini: mini_1.default, }; },{"./main":427,"./mini":428,"tslib":894}],427:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var AreaParser = /** @class */ (function (_super) { tslib_1.__extends(AreaParser, _super); function AreaParser() { return _super !== null && _super.apply(this, arguments) || this; } AreaParser.prototype.init = function () { var props = this.plot.options; this.config = { type: 'area', position: { fields: [props.xField, props.yField], }, connectNulls: props.connectNulls || false, }; if (props.smooth) { this.config.shape = { values: ['smooth'] }; } if (this._getColorMappingField() || props.color) { this.parseColor(); } if (props.areaStyle || (props.area && props.area.style)) { this.parseStyle(); } }; AreaParser.prototype.parseColor = function () { var props = this.plot.options; var config = {}; var colorMappingField = this._getColorMappingField(); if (colorMappingField) { config.fields = colorMappingField; } if (util_1.has(props, 'color')) { var color = props.color; if (util_1.isString(color)) { config.values = [color]; } else if (util_1.isFunction(color)) { config.callback = color; } else if (util_1.isArray(color)) { if (colorMappingField) { config.values = color; } else { if (color.length > 0) { config.values = [color[0]]; } } } } this.config.color = config; }; AreaParser.prototype.parseStyle = function () { var props = this.plot.options; var styleProps = props.areaStyle ? props.areaStyle : props.area.style; var config = {}; if (util_1.isFunction(styleProps) && props.seriesField) { config.fields = [props.seriesField]; config.callback = styleProps; } else { config.cfg = styleProps; } this.config.style = config; }; AreaParser.prototype._getColorMappingField = function () { var props = this.plot.options; var colorMapper = ['stackField', 'seriesField']; for (var _i = 0, colorMapper_1 = colorMapper; _i < colorMapper_1.length; _i++) { var m = colorMapper_1[_i]; if (util_1.get(props, m)) { return [props[m]]; } } }; return AreaParser; }(base_1.default)); exports.default = AreaParser; },{"../base":429,"@antv/util":803,"tslib":894}],428:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** 简化折线点 */ var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); var math_1 = require("../../util/math"); var path_1 = require("../../util/path"); var main_1 = tslib_1.__importDefault(require("./main")); var theme_1 = require("../../theme"); dependents_1.registerShape('area', 'miniArea', { draw: function (cfg, container) { var opacity = cfg.style ? cfg.style.opacity : null; var path = getPath(cfg, this, false); var style = util_1.deepMix({}, { lineJoin: 'round', lineCap: 'round', }, cfg.style); var shape = container.addShape('path', { attrs: { path: path, fill: parseGradient(cfg.color || theme_1.getGlobalTheme().defaultColor), opacity: opacity || 0.4, }, style: style, }); return shape; }, }); dependents_1.registerShape('area', 'miniAreaSmooth', { draw: function (cfg, container) { var opacity = cfg.style ? cfg.style.opacity : null; var path = getPath(cfg, this, true); var shape = container.addShape('path', { attrs: { path: path, fill: parseGradient(cfg.color || theme_1.getGlobalTheme().defaultColor), opacity: opacity || 0.5, }, }); return shape; }, }); function getPath(cfg, shape, isSmooth) { var constraint = [ [0, 0], [1, 1], ]; var topLinePoints = []; var bottomLinePoints = []; util_1.each(cfg.points, function (point) { topLinePoints.push(point[1]); bottomLinePoints.push(point[0]); }); bottomLinePoints = shape.parsePoints(bottomLinePoints.reverse()); topLinePoints = math_1.lineSimplification(shape.parsePoints(topLinePoints)); var topPath = isSmooth ? path_1.getSplinePath(topLinePoints, false, constraint) : getStraightPath(topLinePoints); var bottomPath = getStraightPath(bottomLinePoints); bottomPath[0][0] = 'L'; var path = topPath.concat(bottomPath); return path; } function getStraightPath(points) { var path = []; for (var i = 0; i < points.length; i++) { var p = points[i]; var flag = i === 0 ? 'M' : 'L'; path.push([flag, p.x, p.y]); } return path; } function parseGradient(color) { return "l(90) 0:" + color + " 1:#ffffff"; } var MiniAreaParser = /** @class */ (function (_super) { tslib_1.__extends(MiniAreaParser, _super); function MiniAreaParser() { return _super !== null && _super.apply(this, arguments) || this; } MiniAreaParser.prototype.init = function () { _super.prototype.init.call(this); this.parseShape(); }; MiniAreaParser.prototype.parseShape = function () { var props = this.plot.options; if (props.smooth) { this.config.shape = { values: ['miniAreaSmooth'] }; } else { this.config.shape = { values: ['miniArea'] }; } }; return MiniAreaParser; }(main_1.default)); exports.default = MiniAreaParser; },{"../../dependents":425,"../../theme":669,"../../util/math":680,"../../util/path":681,"./main":427,"@antv/util":803,"tslib":894}],429:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var ElementParser = /** @class */ (function () { function ElementParser(cfg) { util_1.assign(this, cfg); this.init(); } ElementParser.prototype.init = function () { this.config = { type: this.type, position: { fields: this.positionFields, }, }; }; return ElementParser; }()); exports.default = ElementParser; },{"@antv/util":803}],430:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getGeom = void 0; var tslib_1 = require("tslib"); var index_1 = tslib_1.__importDefault(require("./area/index")); var index_2 = tslib_1.__importDefault(require("./interval/index")); var index_3 = tslib_1.__importDefault(require("./line/index")); var index_4 = tslib_1.__importDefault(require("./point/index")); /** * 将element的配置逻辑拆离出来,并将每类element细分为主体图形、辅助图形、mini图形三种 * 这样也方便未来更灵活的调用和组装g2的element模块 */ var GEOMETRY_MAP = { area: index_1.default, line: index_3.default, point: index_4.default, interval: index_2.default, }; function getGeom(name, type, cfg) { var Geom = GEOMETRY_MAP[name][type]; return new Geom(cfg).config; } exports.getGeom = getGeom; },{"./area/index":426,"./interval/index":432,"./line/index":435,"./point/index":440,"tslib":894}],431:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); var colorUtil = tslib_1.__importStar(require("../../util/color")); var GAUSS_COEF = 0.3989422804014327; var ZERO = 1.0 / 255.0 / 16.0; var ORIGIN_FIELD = '_origin'; var LinearHeatmap = /** @class */ (function (_super) { tslib_1.__extends(LinearHeatmap, _super); function LinearHeatmap(cfg) { var _this = _super.call(this, cfg) || this; _this.type = 'heatmap'; _this.paletteCache = {}; _this.intensity = cfg.intensity; _this.radius = cfg.radius; return _this; } LinearHeatmap.prototype.createElements = function (mappingData /*index: number, isUpdate: boolean = false*/) { var range = this.prepareRange(mappingData); this.prepareSize(); this.prepareBlur(); this.prepareGreyScaleBlurredCircle(this.radius); this.drawWithRange(mappingData, range); return null; }; LinearHeatmap.prototype.clear = function () { this.clearShadowCanvasCtx(); _super.prototype.clear.call(this); }; LinearHeatmap.prototype.prepareRange = function (data) { var colorAttr = this.getAttribute('color'); var colorField = colorAttr.getFields()[0]; var min = Infinity; var max = -Infinity; data.forEach(function (row) { var value = row[ORIGIN_FIELD][colorField]; if (value > max) { max = value; } if (value < min) { min = value; } }); if (min === max) { min = max - 1; } return [min, max]; }; LinearHeatmap.prototype.prepareSize = function () { var radius = this.radius; if (!this.radius) { radius = this.getDefaultValue('size'); if (!util_1.isNumber(radius)) { radius = this.getDefaultSize(); } this.radius = radius; } }; LinearHeatmap.prototype.prepareBlur = function () { var blur = util_1.get(this.styleOption, ['style', 'shadowBlur']); if (!util_1.isNumber(blur)) { blur = this.radius / 2; } this.blur = blur; }; LinearHeatmap.prototype.getDefaultSize = function () { var position = this.getAttribute('position'); var coord = this.coordinate; var radius = Math.min(coord.getWidth() / (position.scales[0].ticks.length * 4), coord.getHeight() / (position.scales[1].ticks.length * 4)); return radius; }; LinearHeatmap.prototype.colorize = function (img) { var colorAttr = this.getAttribute('color'); var pixels = img.data; var paletteCache = this.paletteCache; for (var i = 3; i < pixels.length; i += 4) { var alpha = pixels[i]; // get gradient color from opacity value if (alpha) { var palette = void 0; if (paletteCache[alpha]) { palette = paletteCache[alpha]; } else { palette = colorUtil.rgb2arr(colorAttr.gradient(alpha / 256)); paletteCache[alpha] = palette; } // const palette = colorUtil.rgb2arr(colorAttr.gradient(alpha / 256)); pixels[i - 3] = palette[0]; pixels[i - 2] = palette[1]; pixels[i - 1] = palette[2]; pixels[i] = alpha; } } }; LinearHeatmap.prototype.prepareGreyScaleBlurredCircle = function (r) { var circleCanvas = this.grayScaleCanvas; if (!circleCanvas) { circleCanvas = document.createElement('canvas'); this.grayScaleCanvas = circleCanvas; } var intensity = this.intensity ? this.intensity : 2; var circleRadius = (Math.sqrt(-2.0 * Math.log(ZERO / r / intensity / GAUSS_COEF)) / 3.0) * r; var blur = circleRadius - r; var r2 = circleRadius + blur; var ctx = circleCanvas.getContext('2d'); circleCanvas.width = circleCanvas.height = r2 * 2; ctx.clearRect(0, 0, circleCanvas.width, circleCanvas.height); ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2; ctx.shadowBlur = blur; ctx.shadowColor = 'black'; ctx.beginPath(); ctx.arc(-r2, -r2, r, 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); }; LinearHeatmap.prototype.drawGrayScaleBlurredCircle = function (x, y, r, alpha, ctx) { var circleCanvas = this.grayScaleCanvas; ctx.globalAlpha = alpha; ctx.drawImage(circleCanvas, x - r, y - r); }; LinearHeatmap.prototype.getShadowCanvasCtx = function () { var canvas = this.shadowCanvas; if (!canvas) { canvas = document.createElement('canvas'); this.shadowCanvas = canvas; } canvas.width = this.coordinate.getWidth(); canvas.height = this.coordinate.getHeight(); var context = canvas.getContext('2d'); context.globalCompositeOperation = 'lighter'; return context; }; LinearHeatmap.prototype.clearShadowCanvasCtx = function () { var ctx = this.getShadowCanvasCtx(); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); }; LinearHeatmap.prototype.getImageShape = function () { var imageShape = this.imageShape; if (imageShape) { return imageShape; } var container = this.container; imageShape = container.addShape({ type: 'image', attrs: {}, }); this.imageShape = imageShape; }; LinearHeatmap.prototype.drawWithRange = function (data, range) { // canvas size var _a = this.coordinate, start = _a.start, end = _a.end; var width = this.coordinate.getWidth(); var height = this.coordinate.getHeight(); // value, range, etc var colorAttr = this.getAttribute('color'); var valueField = colorAttr.getFields()[0]; // prepare shadow canvas context this.clearShadowCanvasCtx(); var ctx = this.getShadowCanvasCtx(); // filter data if (range) { data = data.filter(function (row) { return row[ORIGIN_FIELD][valueField] <= range[1] && row[ORIGIN_FIELD][valueField] >= range[0]; }); } // step1. draw points with shadow var scale = this.scales[valueField]; for (var i = 0; i < data.length; i++) { var obj = data[i]; var cfg = this.getDrawCfg(obj); var alpha = scale.scale(obj[ORIGIN_FIELD][valueField]); // @ts-ignore this.drawGrayScaleBlurredCircle(cfg.x - start.x, cfg.y - end.y, this.radius + this.blur, alpha, ctx); } // step2. convert pixels var colored = ctx.getImageData(0, 0, width, height); this.clearShadowCanvasCtx(); this.colorize(colored); ctx.putImageData(colored, 0, 0); var image = new Image(); image.src = ctx.canvas.toDataURL('image/png'); this.getImageShape(); this.imageShape.attr('x', start.x); this.imageShape.attr('y', end.y); this.imageShape.attr('width', width); this.imageShape.attr('height', height); this.imageShape.attr('img', ctx.canvas); this.imageShape.set('origin', this.getShapeInfo(data)); // 存储绘图信息数据 }; LinearHeatmap.prototype.getShapeInfo = function (mappingData) { var shapeCfg = this.getDrawCfg(mappingData[0]); return tslib_1.__assign(tslib_1.__assign({}, shapeCfg), { mappingData: mappingData, data: this.getData(mappingData) }); }; LinearHeatmap.prototype.getData = function (mappingData) { return mappingData.map(function (obj) { return obj[ORIGIN_FIELD]; }); }; return LinearHeatmap; }(dependents_1.Geometry)); dependents_1.registerGeometry('linearHeatmap', LinearHeatmap); },{"../../dependents":425,"../../util/color":673,"@antv/util":803,"tslib":894}],432:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var main_1 = tslib_1.__importDefault(require("./main")); exports.default = { main: main_1.default, }; },{"./main":433,"tslib":894}],433:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var COLOR_MAPPER = ['colorField', 'stackField', 'groupField']; var IntervalParser = /** @class */ (function (_super) { tslib_1.__extends(IntervalParser, _super); function IntervalParser() { return _super !== null && _super.apply(this, arguments) || this; } IntervalParser.prototype.init = function () { this.type = 'interval'; _super.prototype.init.call(this); var props = this.plot.options; if (this._needParserColor()) { this.parseColor(); } if (!this.config.color) { this.config.color = { values: ['#5b8ff9'] }; } var sizeProps = this._getSizeProps(props); if (sizeProps) { this.parseSize(sizeProps); } var styleProps = this._getStyleProps(props); if (styleProps) { this.parseStyle(styleProps); } }; IntervalParser.prototype.parseColor = function () { var props = this.plot.options; var colorField = this._getColorMappingField(props); var config = {}; if (colorField) { config.fields = colorField; } if (props.color) { if (util_1.isString(props.color)) { config.values = [props.color]; } else if (util_1.isFunction(props.color)) { config.callback = props.color; } else if (util_1.isArray(props.color)) { if (colorField) { config.values = props.color; } else { if (props.color.length > 0) { config.values = [props.color[0]]; } } } else if (util_1.isObject(props.color)) { config.fields = colorField; config.callback = function (d) { return props.color[d]; }; } } this.config.color = config; }; IntervalParser.prototype.parseSize = function (sizeProps) { var props = this.plot.options; var config = {}; if (util_1.isFunction(props[sizeProps])) { config.fields = [this.config.position.fields]; config.callback = props[sizeProps]; } else { config.values = [props[sizeProps]]; } this.config.size = config; }; IntervalParser.prototype.parseStyle = function (styleProps) { var props = this.plot.options; var color = this.config.color; var style = this.plot.options[styleProps]; var config = {}; if (util_1.isFunction(style)) { config.fields = (color === null || color === void 0 ? void 0 : color.fields) || [props.xField, props.yField]; config.callback = style; } else { config.cfg = style; } this.config.style = config; }; IntervalParser.prototype._getSizeProps = function (props) { var sizeMapper = ['columnSize', 'barSize']; for (var _i = 0, sizeMapper_1 = sizeMapper; _i < sizeMapper_1.length; _i++) { var m = sizeMapper_1[_i]; if (util_1.get(props, m)) { return m; } } }; IntervalParser.prototype._getStyleProps = function (props) { var sizeMapper = ['columnStyle', 'barStyle', 'pieStyle', 'ringStyle']; for (var _i = 0, sizeMapper_2 = sizeMapper; _i < sizeMapper_2.length; _i++) { var m = sizeMapper_2[_i]; if (util_1.get(props, m)) { return m; } } }; IntervalParser.prototype._getColorMappingField = function (props) { /**如果有colorFiled或stackField配置项(后者为堆叠interval),则参与colorMapping的字段为对应值 * 如没有特别设定,则一般是callback中的传参,传入位置映射的字段 */ for (var _i = 0, COLOR_MAPPER_1 = COLOR_MAPPER; _i < COLOR_MAPPER_1.length; _i++) { var m = COLOR_MAPPER_1[_i]; if (util_1.get(props, m)) { return [props[m]]; } } }; IntervalParser.prototype._needParserColor = function () { var props = this.plot.options; if (props.color) { return true; } for (var _i = 0, COLOR_MAPPER_2 = COLOR_MAPPER; _i < COLOR_MAPPER_2.length; _i++) { var m = COLOR_MAPPER_2[_i]; if (props[m]) { return true; } } return false; }; return IntervalParser; }(base_1.default)); exports.default = IntervalParser; },{"../base":429,"@antv/util":803,"tslib":894}],434:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var main_1 = tslib_1.__importDefault(require("./main")); var GuideLineParser = /** @class */ (function (_super) { tslib_1.__extends(GuideLineParser, _super); function GuideLineParser() { return _super !== null && _super.apply(this, arguments) || this; } GuideLineParser.prototype.init = function () { var props = this.plot.options; if (!props.xField || !props.yField) { return; } this.config = { type: 'line', position: { fields: [props.xField, props.yField], }, tooltip: false, }; if (this._getColorMappingField() || this._needParseAttribute('color')) { this.parseColor(); } if (this._needParseAttribute('size')) { this.parseSize(); } if (props.line.style) { this.parseStyle(); } if (props.smooth) { this.config.shape = { values: ['smooth'] }; } }; GuideLineParser.prototype.parseSize = function () { var props = this.plot.options; var config = {}; if (props.line.size) { config.values = [props.line.size]; } else { // line作为辅助图形没有在style里指定size属性的情况下,设置默认值 config.values = [2]; } this.config.size = config; }; GuideLineParser.prototype.parseColor = function () { var props = this.plot.options; var config = {}; var colorField = this._getColorMappingField(); if (colorField) { config.fields = colorField; } if (props.line.color) { config.values = [props.line.color]; } else { // line作为辅助图形没有在style里指定color属性的情况下,默认接受主体图形的透传 if (util_1.isString(props.color)) { config.values = [props.color]; } else if (util_1.isFunction(props.color)) { config.fields = colorField; config.callback = props.color; } else if (util_1.isArray(props.color)) { if (colorField) { config.values = props.color; } else { if (props.color.length > 0) { config.values = [props.color[0]]; } } } } this.config.color = config; }; GuideLineParser.prototype.parseStyle = function () { var props = this.plot.options; var styleProps = props.line.style; var config = {}; if (util_1.isFunction(styleProps)) { config.fields = this.config.position.fields; config.callback = styleProps; } else { config.cfg = styleProps; } this.config.style = config; }; GuideLineParser.prototype._needParseAttribute = function (attr) { var props = this.plot.options; if (props[attr]) { return true; } else if (props.line[attr]) { return true; } return false; }; GuideLineParser.prototype._getColorMappingField = function () { var props = this.plot.options; var colorMapper = ['stackField', 'seriesField']; for (var _i = 0, colorMapper_1 = colorMapper; _i < colorMapper_1.length; _i++) { var m = colorMapper_1[_i]; if (util_1.get(props, m)) { return [props[m]]; } } }; return GuideLineParser; }(main_1.default)); exports.default = GuideLineParser; },{"./main":436,"@antv/util":803,"tslib":894}],435:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var guide_1 = tslib_1.__importDefault(require("./guide")); var main_1 = tslib_1.__importDefault(require("./main")); var mini_1 = tslib_1.__importDefault(require("./mini")); exports.default = { main: main_1.default, guide: guide_1.default, mini: mini_1.default, }; },{"./guide":434,"./main":436,"./mini":437,"tslib":894}],436:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var LineParser = /** @class */ (function (_super) { tslib_1.__extends(LineParser, _super); function LineParser() { return _super !== null && _super.apply(this, arguments) || this; } LineParser.prototype.init = function () { var props = this.plot.options; this.config = { type: 'line', position: { fields: [props.xField, props.yField], }, connectNulls: props.connectNulls, }; if (props.lineSize) { this.parseSize(); } if (props.smooth) { this.config.shape = { values: ['smooth'] }; } if (props.step) { this.config.shape = { values: [props.step] }; } if (props.seriesField || props.color) { this.parseColor(); } if (props.lineStyle || util_1.get(props, ['line', 'style'])) { this.parseStyle(); } }; LineParser.prototype.parseSize = function () { var sizeProps = this.plot.options.lineSize; var config = {}; if (util_1.isFunction(sizeProps)) { config.callback = sizeProps; } else { config.values = [sizeProps]; } this.config.size = config; }; LineParser.prototype.parseColor = function () { var props = this.plot.options; var config = {}; if (props.seriesField) { config.fields = [props.seriesField]; } if (util_1.has(props, 'color')) { var color = props.color; if (util_1.isString(color)) { config.values = [color]; } else if (util_1.isFunction(color)) { config.callback = color; } else if (util_1.isArray(color)) { if (props.seriesField) { config.values = color; } else { if (color.length > 0) { config.values = [color[0]]; } } } } this.config.color = config; }; LineParser.prototype.parseStyle = function () { var props = this.plot.options; var styleProps = props.lineStyle || util_1.get(props, ['line', 'style']); var config = { fields: null, callback: null, cfg: null, }; if (util_1.isFunction(styleProps) && props.seriesField) { config.fields = [props.seriesField]; config.callback = styleProps; } else { config.cfg = styleProps; } this.config.style = config; }; return LineParser; }(base_1.default)); exports.default = LineParser; },{"../base":429,"@antv/util":803,"tslib":894}],437:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** 简化折线点 */ var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); var math_1 = require("../../util/math"); var path_1 = require("../../util/path"); var main_1 = tslib_1.__importDefault(require("./main")); var theme_1 = require("../../theme"); dependents_1.registerShape('line', 'miniLine', { draw: function (cfg, container) { var points = math_1.lineSimplification(cfg.points); var path = []; for (var i = 0; i < points.length; i++) { var p = points[i]; var flag = i === 0 ? 'M' : 'L'; path.push([flag, p.x, p.y]); } var style = util_1.deepMix({}, { lineJoin: 'round', lineCap: 'round', }, cfg.style); var shape = container.addShape('path', { attrs: util_1.mix({ path: path, stroke: cfg.color || theme_1.getGlobalTheme().defaultColor, lineWidth: cfg.size || 2, }, style), }); return shape; }, }); dependents_1.registerShape('line', 'miniLineSmooth', { draw: function (cfg, container) { var points = math_1.lineSimplification(cfg.points); var constraint = [ [0, 0], [1, 1], ]; var path = path_1.getSplinePath(points, false, constraint); var shape = container.addShape('path', { attrs: util_1.mix({ path: path, stroke: cfg.color || theme_1.getGlobalTheme().defaultColor, lineWidth: cfg.size || 2, }, cfg.style), }); return shape; }, }); var MiniLineParser = /** @class */ (function (_super) { tslib_1.__extends(MiniLineParser, _super); function MiniLineParser() { return _super !== null && _super.apply(this, arguments) || this; } MiniLineParser.prototype.init = function () { _super.prototype.init.call(this); this.parseShape(); }; MiniLineParser.prototype.parseShape = function () { var props = this.plot.options; if (props.smooth) { this.config.shape = { values: ['miniLineSmooth'] }; } else { this.config.shape = { values: ['miniLine'] }; } }; return MiniLineParser; }(main_1.default)); exports.default = MiniLineParser; },{"../../dependents":425,"../../theme":669,"../../util/math":680,"../../util/path":681,"./main":436,"@antv/util":803,"tslib":894}],438:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); var CircleParser = /** @class */ (function (_super) { tslib_1.__extends(CircleParser, _super); function CircleParser() { return _super !== null && _super.apply(this, arguments) || this; } CircleParser.prototype.init = function () { var props = this.plot.options; this.style = props.pointStyle; if (!props.xField || !props.yField) { return; } this.config = { type: 'point', position: { fields: [props.xField, props.yField], }, }; this.parseColor(); this.parseSize(); if (props.shape) { this.parseShape(props.shape); } if (props.pointStyle) { this.parseStyle(); } }; CircleParser.prototype.parseColor = function () { var props = this.plot.options; var config = {}; var colorField = props.colorField; if (colorField) { config.fields = util_1.isArray(colorField) ? colorField : [colorField]; } if (props.color) { this._parseColor(props, config); } if (!util_1.isEmpty(config)) { this.config.color = config; } }; CircleParser.prototype.parseSize = function () { var props = this.plot.options; var config = {}; if (props.sizeField) { config.fields = [props.sizeField]; } if (props.pointSize) { config.values = util_1.isArray(props.pointSize) ? props.pointSize : [props.pointSize]; } this.config.size = config; }; CircleParser.prototype.parseShape = function (shapeName) { this.config.shape = shapeName; }; CircleParser.prototype.parseStyle = function () { var props = this.plot.options; var styleProps = props.pointStyle; var config = { fields: null, callback: null, cfg: null, }; var xField = props.xField, yField = props.yField, colorField = props.colorField; if (util_1.isFunction(styleProps)) { if (colorField) { config.fields = util_1.isArray(colorField) ? [xField, yField, colorField].concat(colorField) : [xField, yField, colorField]; } else { config.fields = [xField, yField]; } config.callback = styleProps; } else { config.cfg = styleProps; // opacity 与 fillOpacity 兼容 if (!util_1.isNil(styleProps.opacity)) { config.cfg.fillOpacity = styleProps.opacity; } } this.config.style = config; }; CircleParser.prototype._parseColor = function (props, config) { if (util_1.isString(props.color)) { config.values = [props.color]; } else if (util_1.isFunction(props.color)) { config.callback = props.color; } else if (util_1.isArray(props.color)) { config.values = props.color; } }; return CircleParser; }(base_1.default)); exports.default = CircleParser; },{"../base":429,"@antv/util":803,"tslib":894}],439:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("../base")); function getValuesByField(field, data) { var values = []; util_1.each(data, function (d) { var v = d[field]; values.push(v); }); return util_1.uniq(values); } var COLOR_MAPPER = ['seriesField', 'stackField']; var GuidePointParser = /** @class */ (function (_super) { tslib_1.__extends(GuidePointParser, _super); function GuidePointParser() { return _super !== null && _super.apply(this, arguments) || this; } GuidePointParser.prototype.init = function () { var props = this.plot.options; this.style = props.point.style; if (!props.xField || !props.yField) { return; } this.config = { type: 'point', position: { fields: [props.xField, props.yField], }, tooltip: false, }; // if (this._needParseAttribute('color')) { this.parseColor(); // } if (this._needParseAttribute('size')) { this.parseSize(); } if (props.point.shape) { this.parseShape(props.point.shape); } if (props.point.style) { this.parseStyle(); } }; GuidePointParser.prototype.parseColor = function () { var props = this.plot.options; var config = {}; var mappingField = this._getColorMappingField(props); if (mappingField) { this._parseColorByField(props, config, mappingField); } else { if (props.point && props.point.color) { config.values = [props.point.color]; } else if (props.color) { this._parseColor(props, config); } else { var theme = this.plot.getTheme(); config.values = [theme.defaultColor]; } } if (util_1.keys(config).length > 0) { this.config.color = config; } }; GuidePointParser.prototype.parseSize = function () { var props = this.plot.options; var config = {}; config.values = [props.point.size]; this.config.size = config; }; GuidePointParser.prototype.parseShape = function (shapeCfg) { var config = {}; if (util_1.isString(shapeCfg)) { config.values = [shapeCfg]; } else if (util_1.isObject(shapeCfg)) { config.fields = shapeCfg.fields; config.callback = shapeCfg.callback; } this.config.shape = config; }; GuidePointParser.prototype.parseStyle = function () { var props = this.plot.options; var styleProps = props.point && props.point.style; var config = { fields: null, callback: null, cfg: null, }; var field = this._getColorMappingField(props); if (util_1.isFunction(styleProps)) { config.fields = [props.xField, props.yField]; config.callback = styleProps; if (field) { config.fields.unshift(field); } } else { config.cfg = styleProps; } this.config.style = config; }; GuidePointParser.prototype._parseColorByField = function (props, config, field) { config.fields = [field]; if (props.point.color) { var count = getValuesByField(field, props.data).length; var values = []; for (var i = 0; i < count; i++) { values.push(props.point.color); } config.values = values; } else if (props.color) { this._parseColor(props, config); } }; GuidePointParser.prototype._parseColor = function (props, config) { var field = this._getColorMappingField(props); if (util_1.isString(props.color)) { config.values = [props.color]; } else if (util_1.isFunction(props.color)) { config.callback = props.color; } else if (util_1.isArray(props.color)) { if (field) { config.values = props.color; } else { if (props.color.length > 0) { config.values = [props.color[0]]; } } } }; GuidePointParser.prototype._needParseAttribute = function (attr) { var props = this.plot.options; var condition = props.point && util_1.has(props.point, attr); return condition; // const condition = !this.style || this.style[attr]; // return condition; }; GuidePointParser.prototype._getColorMappingField = function (props) { for (var _i = 0, COLOR_MAPPER_1 = COLOR_MAPPER; _i < COLOR_MAPPER_1.length; _i++) { var m = COLOR_MAPPER_1[_i]; if (util_1.get(props, m)) { return [props[m]]; } } }; return GuidePointParser; }(base_1.default)); exports.default = GuidePointParser; },{"../base":429,"@antv/util":803,"tslib":894}],440:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var circle_1 = tslib_1.__importDefault(require("./circle")); var guide_1 = tslib_1.__importDefault(require("./guide")); exports.default = { guide: guide_1.default, circle: circle_1.default, }; },{"./circle":438,"./guide":439,"tslib":894}],441:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var core_1 = tslib_1.__importDefault(require("./core")); var BaseInteraction = /** @class */ (function (_super) { tslib_1.__extends(BaseInteraction, _super); function BaseInteraction(cfg, viewLayer, interactionRange, interaction) { var _this = _super.call(this, cfg) || this; _this.viewLayer = viewLayer; _this.interactionRange = interactionRange; _this.interactionConfig = interaction; _this.disposables = []; return _this; } BaseInteraction.registerInteraction = function (type, ctor) { BaseInteraction.GLOBAL_INTERACTION_MAP[type] = ctor; }; BaseInteraction.registerPlotInteraction = function (plotType, type, ctor) { if (!BaseInteraction.PLOT_INTERACTION_MAP[plotType]) { BaseInteraction.PLOT_INTERACTION_MAP[plotType] = {}; } BaseInteraction.PLOT_INTERACTION_MAP[plotType][type] = ctor; }; BaseInteraction.getInteraction = function (type, plotType) { if (plotType && BaseInteraction.PLOT_INTERACTION_MAP[plotType] && BaseInteraction[plotType][type]) { return BaseInteraction.PLOT_INTERACTION_MAP[plotType][type]; } return BaseInteraction.GLOBAL_INTERACTION_MAP[type]; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars BaseInteraction.getInteractionRange = function (layerRange, interaction) { return undefined; }; BaseInteraction.prototype.destroy = function () { util_1.each(this.disposables, function (fn) { fn(); }); this.disposables = []; this.clear(); _super.prototype.destroy.call(this); }; BaseInteraction.prototype.getViewLayer = function () { return this.viewLayer; }; BaseInteraction.prototype.getRange = function () { return this.interactionRange; }; BaseInteraction.prototype.getInteractionConfig = function () { return this.interactionConfig; }; BaseInteraction.prototype.addDisposable = function (fn) { this.disposables.push(fn); }; BaseInteraction.prototype.render = function () { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars BaseInteraction.prototype.start = function (ev) { return; }; BaseInteraction.GLOBAL_INTERACTION_MAP = {}; BaseInteraction.PLOT_INTERACTION_MAP = {}; return BaseInteraction; }(core_1.default)); exports.default = BaseInteraction; },{"./core":442,"@antv/util":803,"tslib":894}],442:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var EVENT_TYPES = ['start', 'process', 'end', 'reset']; var Interaction = /** @class */ (function () { function Interaction(cfg) { var defaultCfg = this.getDefaultCfg(); util_1.assign(this, defaultCfg, cfg); this.canvas = this.view.canvas; this._eventHandlers = []; this._bindEvents(); } Interaction.prototype.getDefaultCfg = function () { return { startEvent: 'mousedown', processEvent: 'mousemove', endEvent: 'mouseup', resetEvent: 'dblclick', }; }; Interaction.prototype._start = function (ev) { this.preStart(ev); this.start(ev); this.afterStart(ev); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.preStart = function (ev) { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.afterStart = function (ev) { return; }; Interaction.prototype._process = function (ev) { this.preProcess(ev); this.process(ev); this.afterProcess(ev); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.preProcess = function (ev) { return; }; //eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.process = function (ev) { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.afterProcess = function (ev) { return; }; Interaction.prototype._end = function (ev) { this.preEnd(ev); this.end(ev); this.afterEnd(ev); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.preEnd = function (ev) { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.end = function (ev) { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.afterEnd = function (ev) { return; }; Interaction.prototype._reset = function (ev) { this.preReset(ev); this.reset(ev); this.afterReset(ev); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.preReset = function (ev) { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.reset = function (ev) { return; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars Interaction.prototype.afterReset = function (ev) { return; }; Interaction.prototype._bindEvents = function () { var _this = this; util_1.each(EVENT_TYPES, function (type) { var eventName = _this[type + "Event"]; var handler = util_1.wrapBehavior(_this, "_" + type); _this.view.on(eventName, handler); _this._eventHandlers.push({ type: eventName, handler: handler }); }); }; Interaction.prototype._unbindEvents = function () { var _this = this; var eventHandlers = this._eventHandlers; util_1.each(eventHandlers, function (eh) { _this.view.off(eh.type, eh.handler); }); }; Interaction.prototype.destroy = function () { this._unbindEvents(); this._reset(); }; return Interaction; }()); exports.default = Interaction; },{"@antv/util":803}],443:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDataByScaleRange = void 0; var util_1 = require("@antv/util"); /** * 按照scale字段values中的start和end信息从全部数据中取出对应的部分 * * @param field scale field * @param values scale values * @param data original data * @param range range start & end */ exports.getDataByScaleRange = function (field, values, data, _a, vertical) { var start = _a[0], end = _a[1]; if (vertical === void 0) { vertical = false; } var groupedData = util_1.groupBy(data, field); var newValues = vertical ? values.slice(values.length - end, values.length - start) : values.slice(start, end); return util_1.flatten(util_1.map(newValues, function (value) { return groupedData[value] || []; })); }; },{"@antv/util":803}],444:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = tslib_1.__importDefault(require("./base")); var scrollbar_1 = tslib_1.__importDefault(require("./scrollbar")); var slider_1 = tslib_1.__importDefault(require("./slider")); var timeline_1 = tslib_1.__importDefault(require("./timeline")); var tooltip_indicator_1 = tslib_1.__importDefault(require("./tooltip-indicator")); base_1.default.registerInteraction('slider', slider_1.default); base_1.default.registerInteraction('scrollbar', scrollbar_1.default); base_1.default.registerInteraction('timeline', timeline_1.default); base_1.default.registerInteraction('tooltip-indicator', tooltip_indicator_1.default); tslib_1.__exportStar(require("./base"), exports); exports.default = base_1.default; },{"./base":441,"./scrollbar":445,"./slider":446,"./timeline":447,"./tooltip-indicator":448,"tslib":894}],445:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dependents_1 = require("../dependents"); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); var data_range_1 = require("./helper/data-range"); var constant_1 = require("@antv/g2/lib/constant"); var constants_1 = require("../base/constants"); var DEFAULT_PADDING = 4; var DEFAULT_SIZE = 8; var DEFAULT_CATEGORY_SIZE = 32; var MIN_THUMB_LENGTH = 20; var SCROLL_BAR_Z_INDEX = 999; var getValidScrollbarConfig = function (cfg) { if (cfg === void 0) { cfg = {}; } var _cfg = tslib_1.__assign({ type: 'horizontal', categorySize: DEFAULT_CATEGORY_SIZE, width: DEFAULT_SIZE, height: DEFAULT_SIZE, padding: [0, 0, 0, 0] }, cfg); // default padding if (!cfg.padding) { _cfg.padding = _cfg.type === 'horizontal' ? [DEFAULT_PADDING, 0, DEFAULT_PADDING, 0] : [0, DEFAULT_PADDING, 0, DEFAULT_PADDING]; } return _cfg; }; var ScrollbarInteraction = /** @class */ (function (_super) { tslib_1.__extends(ScrollbarInteraction, _super); function ScrollbarInteraction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.onChangeFn = util_1.throttle(_this.onChange.bind(_this), 20, { leading: true, }); return _this; } ScrollbarInteraction.getInteractionRange = function (layerRange, interaction) { var config = getValidScrollbarConfig(interaction); var _a = config.padding, paddingTop = _a[0], paddingRight = _a[1], paddingBottom = _a[2], paddingLeft = _a[3]; if (config.type === 'horizontal') { return new bbox_1.default(layerRange.minX, layerRange.maxY - config.height - paddingTop - paddingBottom, layerRange.width, config.height + paddingTop + paddingBottom); } else { return new bbox_1.default(layerRange.maxX - config.width - paddingLeft - paddingRight, layerRange.minY, config.width + paddingLeft + paddingRight, layerRange.height); } }; ScrollbarInteraction.prototype.render = function () { var _this = this; var layer = this.getViewLayer(); var view = this.view; this.ratio = 0; this.thumbOffset = 0; var callback = function () { var padding = _this.view.padding; // if we're not in `auto padding` process if (padding === 'auto' || util_1.isEqual(padding, [0, 0, 0, 1])) { return; } if (!_this.trackLen) { _this.measureScrollBar(); _this.changeViewData(_this.getScrollRange(), true); } else { _this.renderScrollbar(); } }; var changeDataCallback = function () { // reset _this.trackLen = 0; }; view.on(constant_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); this.addDisposable(function () { return view.off(constant_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); }); view.on(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback); this.addDisposable(function () { return view.off(constant_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback); }); layer.on(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_CHANGE_DATA, changeDataCallback); this.addDisposable(function () { return layer.off(constants_1.VIEW_LAYER_LIFE_CYCLE.BEFORE_CHANGE_DATA, changeDataCallback); }); }; ScrollbarInteraction.prototype.start = function () { return; }; ScrollbarInteraction.prototype.clear = function () { if (this.scrollbar) { this.scrollbar.destroy(); this.scrollbar = null; } if (this.container) { this.container.remove(true); this.container = null; } this.trackLen = null; this.thumbLen = null; }; ScrollbarInteraction.prototype.renderScrollbar = function () { var config = getValidScrollbarConfig(this.getInteractionConfig()); var range = this.getRange(); var isHorizontal = config.type !== 'vertical'; var panelRange = this.view.coordinateBBox; var _a = config.padding, paddingTop = _a[0], paddingLeft = _a[3]; var position = isHorizontal ? { x: panelRange.minX + paddingLeft, y: range.minY + paddingTop } : { x: range.minX + paddingLeft, y: panelRange.minY + paddingTop }; if (!this.scrollbar) { this.container = this.canvas.addGroup(); this.scrollbar = new dependents_1.Scrollbar({ container: this.container, x: position.x, y: position.y, isHorizontal: isHorizontal, trackLen: this.trackLen, thumbLen: this.thumbLen, thumbOffset: this.ratio * this.trackLen, }); this.scrollbar.init(); this.scrollbar.render(); this.scrollbar.get('group').set('zIndex', SCROLL_BAR_Z_INDEX); this.scrollbar.on('scrollchange', this.onChangeFn); } else { this.scrollbar.update({ trackLen: this.trackLen, thumbLen: this.thumbLen, thumbOffset: this.thumbOffset, x: position.x, y: position.y, }); this.scrollbar.render(); } }; ScrollbarInteraction.prototype.measureScrollBar = function () { var config = getValidScrollbarConfig(this.getInteractionConfig()); var _a = config.padding, paddingTop = _a[0], paddingRight = _a[1], paddingBottom = _a[2], paddingLeft = _a[3]; var isHorizontal = config.type !== 'vertical'; var panelRange = this.view.coordinateBBox; var xScale = this.view.getXScale(); var yScales = this.view.getYScales().filter(function (scale) { return scale; }); this.cnt = xScale.values.length; this.xScaleCfg = { field: xScale.field, values: xScale.values || [] }; this.yScalesCfg = yScales; this.step = Math.floor((isHorizontal ? panelRange.width : panelRange.height) / config.categorySize); this.trackLen = isHorizontal ? panelRange.width - paddingLeft - paddingRight : panelRange.height - paddingTop - paddingBottom; this.thumbLen = Math.max(this.trackLen * util_1.clamp(this.step / xScale.values.length, 0, 1), MIN_THUMB_LENGTH); }; ScrollbarInteraction.prototype.getScrollRange = function () { var startIdx = Math.floor((this.cnt - this.step) * util_1.clamp(this.ratio, 0, 1)); var endIdx = Math.min(startIdx + this.step, this.cnt); return [startIdx, endIdx]; }; ScrollbarInteraction.prototype.changeViewData = function (_a, render) { var _this = this; var startIdx = _a[0], endIdx = _a[1]; var config = getValidScrollbarConfig(this.getInteractionConfig()); var viewLayer = this.getViewLayer(); var meta = viewLayer.options.meta; var origData = viewLayer.getData(); var newData = data_range_1.getDataByScaleRange(this.xScaleCfg.field, this.xScaleCfg.values, origData, [startIdx, endIdx], config.type === 'vertical'); // ScrollBar在滚动过程中保持Y轴上scale配置: min/max/ticks this.yScalesCfg.forEach(function (cfg) { var metaCfg = util_1.get(meta, cfg.field) || {}; _this.view.scale(cfg.field, tslib_1.__assign(tslib_1.__assign({ formatter: cfg.formatter }, metaCfg), { type: cfg.type, min: cfg.min, max: cfg.max })); }); if (render) { this.view.data(newData); this.view.render(); } else { this.view.changeData(newData); } }; ScrollbarInteraction.prototype.onChange = function (_a) { var ratio = _a.ratio, thumbOffset = _a.thumbOffset; this.ratio = ratio; this.thumbOffset = thumbOffset; var origAnimate = this.view.getOptions().animate; this.view.animate(false); this.changeViewData(this.getScrollRange(), true); this.view.animate(origAnimate); // update scrollbar this.renderScrollbar(); }; return ScrollbarInteraction; }(base_1.default)); exports.default = ScrollbarInteraction; },{"../base/constants":386,"../dependents":425,"../util/bbox":672,"./base":441,"./helper/data-range":443,"@antv/g2/lib/constant":237,"@antv/util":803,"tslib":894}],446:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dependents_1 = require("../dependents"); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); var data_range_1 = require("./helper/data-range"); var DEFAULT_PADDING = 4; var DEFAULT_SIZE = 16; var getValidSliderConfig = function (cfg) { if (cfg === void 0) { cfg = {}; } var _cfg = tslib_1.__assign({ type: 'horizontal', start: 0, end: 1, width: undefined, height: undefined, padding: [0, 0, 0, 0], backgroundStyle: {}, foregroundStyle: {}, handlerStyle: {}, textStyle: {}, trendCfg: {} }, cfg); // default padding if (!cfg.padding) { _cfg.padding = _cfg.type === 'horizontal' ? [DEFAULT_PADDING, 0, DEFAULT_PADDING, 0] : [0, DEFAULT_PADDING, 0, DEFAULT_PADDING]; } // default size if (!cfg.height) { _cfg.height = DEFAULT_SIZE; } if (!cfg.width) { _cfg.width = DEFAULT_SIZE; } // start & end var start = util_1.clamp(Math.min(_cfg.start, _cfg.end), 0, 1); var end = util_1.clamp(Math.max(_cfg.start, _cfg.end), 0, 1); _cfg.start = start; _cfg.end = end; return _cfg; }; var SliderInteraction = /** @class */ (function (_super) { tslib_1.__extends(SliderInteraction, _super); function SliderInteraction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.onChangeFn = util_1.throttle(_this.onChange.bind(_this), 20, { leading: true }); return _this; } SliderInteraction.getInteractionRange = function (layerRange, interaction) { var config = getValidSliderConfig(interaction); var _a = config.padding || [0, 0, 0, 0], paddingTop = _a[0], paddingRight = _a[1], paddingBottom = _a[2], paddingLeft = _a[3]; if (config.type === 'horizontal') { var bbox = new bbox_1.default(layerRange.minX, layerRange.maxY - config.height - paddingTop - paddingBottom, layerRange.width, config.height + paddingTop + paddingBottom); return bbox; } else { return new bbox_1.default(layerRange.maxX - config.width - paddingLeft - paddingRight, layerRange.minY, config.width + paddingLeft + paddingRight, layerRange.height); } }; SliderInteraction.prototype.render = function () { var _this = this; var layer = this.getViewLayer(); var view = this.view; // 设置初始化的 start/end var config = getValidSliderConfig(this.getInteractionConfig()); this.curStart = config.start; this.curEnd = config.end; this.xScaleCfg = undefined; // 等待 view 每次 render 完成后更新 slider 组件 var callback = function () { var padding = _this.view.padding; if (padding === 'auto' || util_1.isEqual(padding, [0, 0, 0, 1])) { return; } if (util_1.isEmpty(layer.options.data)) { return; } if (!_this.xScaleCfg) { // 初始化配置和数据 var xScale = view.getXScale(); _this.xScaleCfg = { field: xScale.field, values: xScale.values || [], }; // 初始化 data view.data(_this.getSliderData(_this.curStart, _this.curEnd)); view.render(); } else { _this.renderSlider(); } }; view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); this.addDisposable(function () { return view.off(dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); }); view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback); this.addDisposable(function () { return view.off(dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback); }); }; SliderInteraction.prototype.start = function () { return; }; SliderInteraction.prototype.clear = function () { if (this.slider) { this.slider.destroy(); this.slider = null; } if (this.container) { this.container.remove(true); this.container = null; } }; SliderInteraction.prototype.renderSlider = function () { if (!this.slider) { this.container = this.canvas.addGroup(); this.slider = new dependents_1.Slider(tslib_1.__assign(tslib_1.__assign({}, this.getSliderConfig()), { container: this.container })); this.slider.init(); this.slider.render(); this.slider.on('sliderchange', this.onChangeFn); } else { this.slider.update(this.getSliderConfig()); this.slider.render(); } }; SliderInteraction.prototype.getSliderConfig = function () { var view = this.view; var panelRange = view.coordinateBBox; var range = this.getRange(); var config = getValidSliderConfig(this.getInteractionConfig()); var _a = config || {}, _b = _a.padding, padding = _b === void 0 ? [0, 0, 0, 0] : _b, backgroundStyle = _a.backgroundStyle, foregroundStyle = _a.foregroundStyle, handlerStyle = _a.handlerStyle, textStyle = _a.textStyle, _c = _a.trendCfg, trendCfg = _c === void 0 ? {} : _c; var paddingTop = padding[0], paddingRight = padding[1], paddingBottom = padding[2], paddingLeft = padding[3]; var _d = this.getSliderMinMaxText(this.curStart, this.curEnd), minText = _d.minText, maxText = _d.maxText; var cfg = { x: panelRange.minX + paddingLeft, y: range.minY + paddingTop, width: panelRange.width - paddingLeft - paddingRight, height: range.height - paddingTop - paddingBottom, start: this.curStart, end: this.curEnd, minText: minText, maxText: maxText, backgroundStyle: backgroundStyle, foregroundStyle: foregroundStyle, handlerStyle: handlerStyle, textStyle: textStyle, trendCfg: tslib_1.__assign(tslib_1.__assign({ isArea: false, smooth: false }, trendCfg), { data: this.getSliderTrendData() }), }; return cfg; }; SliderInteraction.prototype.getSliderTrendData = function () { var _a = this.getViewLayer().options, data = _a.data, yField = _a.yField; return util_1.map(data, function (item) { return item[yField]; }); }; SliderInteraction.prototype.getSliderData = function (start, end) { var origData = this.getViewLayer().getData(); var length = util_1.size(this.xScaleCfg.values); var startIdx = Math.round(start * length); var endIdx = Math.max(startIdx + 1, Math.round(end * length)); return data_range_1.getDataByScaleRange(this.xScaleCfg.field, this.xScaleCfg.values, origData, [startIdx, endIdx]); }; SliderInteraction.prototype.getSliderMinMaxText = function (start, end) { var _a = this.getViewLayer().options, _b = _a.data, data = _b === void 0 ? [] : _b, xField = _a.xField; var length = util_1.size(data); var startIdx = Math.round(start * length); var endIdx = Math.max(startIdx + 1, Math.round(end * length)); var newData = data.slice(startIdx, endIdx); return { minText: newData.length > 0 ? util_1.head(newData)[xField] : '', maxText: newData.length > 0 ? util_1.last(newData)[xField] : '', }; }; SliderInteraction.prototype.onChange = function (range) { var view = this.view; var start = util_1.clamp(Math.min(range[0], range[1]), 0, 1); var end = util_1.clamp(Math.max(range[0], range[1]), 0, 1); var data = this.getSliderData(start, end); var _a = this.getSliderMinMaxText(start, end), minText = _a.minText, maxText = _a.maxText; this.curStart = start; this.curEnd = end; this.slider.update({ start: start, end: end, minText: minText, maxText: maxText, }); this.slider.render(); var origAnimate = view.getOptions().animate; view.animate(false); view.data(data); view.render(); view.animate(origAnimate); }; return SliderInteraction; }(base_1.default)); exports.default = SliderInteraction; },{"../dependents":425,"../util/bbox":672,"./base":441,"./helper/data-range":443,"@antv/util":803,"tslib":894}],447:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../dependents"); var base_1 = tslib_1.__importDefault(require("./base")); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var timeline_1 = tslib_1.__importDefault(require("../components/timeline")); var DEFAULT_HEIGHT = 40; function getValidTimeLineConfig(interaction) { return tslib_1.__assign({ loop: false, auto: true, height: DEFAULT_HEIGHT, padding: [0, 20, 0, 0], speed: 2 }, interaction); } var TimeLineInteraction = /** @class */ (function (_super) { tslib_1.__extends(TimeLineInteraction, _super); function TimeLineInteraction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.onChangeFn = util_1.throttle(_this.onChange.bind(_this), 20, { leading: true }); return _this; } /** TimeLineInteraction new 时的范围参数 interactionRange */ TimeLineInteraction.getInteractionRange = function (layerRange, interaction) { var config = getValidTimeLineConfig(interaction); var paddingTop = config.padding[0]; var paddingBottom = config.padding[2]; return new bbox_1.default(layerRange.minX, layerRange.maxY - config.height - paddingTop - paddingBottom, layerRange.width, config.height + paddingTop + paddingBottom); }; TimeLineInteraction.prototype.setAnimate = function (isAnimate) { var geometries = this.view.geometries; this.view.animate(isAnimate); geometries.forEach(function (geom) { geom.animate(isAnimate); }); }; TimeLineInteraction.prototype.start = function () { return; }; TimeLineInteraction.prototype.renderTimeLine = function () { var _this = this; this.config = getValidTimeLineConfig(this.getInteractionConfig()); var viewRange = this.view.viewBBox; var _a = this.config, loop = _a.loop, padding = _a.padding, speed = _a.speed; var paddingTop = padding[0], paddingRight = padding[1], paddingBottom = padding[2], paddingLeft = padding[3]; var range = this.getRange(); var ticks = this.getTicks(); var width = viewRange.width - paddingLeft - paddingRight; var timeLineConfig = { x: viewRange.minX + paddingLeft, y: range.tl.y + paddingTop, width: width, height: range.height - paddingTop - paddingBottom, loop: loop, ticks: ticks, speed: speed, defaultCurrentTick: ticks[0], }; if (this.timeline) { if (!util_1.isEqual(timeLineConfig, this.timeLineConfig)) { this.timeLineConfig = timeLineConfig; this.timeline.update(timeLineConfig); } } else { this.container = this.canvas.addGroup(); this.timeline = new timeline_1.default(tslib_1.__assign({ container: this.container }, timeLineConfig)); this.timeline.init(); this.timeline.render(); this.timeline.on('timelinestart', function () { _this.originAnimation = _this.view.getOptions().animate; _this.setAnimate(true); }); this.timeline.on('timelineend', function () { _this.setAnimate(_this.originAnimation); }); this.timeline.on('timelinechange', this.onChangeFn); this.timeline.on('timelineupdate', this.onChange.bind(this)); this.view.data(this.getFilterData(ticks[0])); this.timeLineConfig = timeLineConfig; } }; TimeLineInteraction.prototype.onChange = function (tick) { var filterData = this.getFilterData(tick); this.view.changeData(filterData); }; TimeLineInteraction.prototype.getFilterData = function (tick) { var field = this.config.field; var data = this.getViewLayer().options.data; return data.filter(function (item) { return item[field] === tick; }); }; TimeLineInteraction.prototype.getTicks = function () { var field = this.config.field; var data = this.getViewLayer().options.data; return util_1.uniq(data.map(function (item) { return item[field]; })); }; /** 渲染 timeline */ TimeLineInteraction.prototype.render = function () { var _this = this; this.firstRender = true; this.view.on(dependents_1.VIEW_LIFE_CIRCLE.BEFORE_RENDER, function () { _this.renderTimeLine(); }); this.view.on(dependents_1.VIEW_LIFE_CIRCLE.BEFORE_PAINT, function () { _this.renderTimeLine(); }); this.view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, function () { if (_this.config.auto && _this.firstRender) { _this.timeline.isPlay = true; _this.timeline.changePlayStatus(); } _this.firstRender = false; }); this.view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, function () { if (_this.config.auto && _this.firstRender) { _this.timeline.isPlay = true; _this.timeline.changePlayStatus(); } _this.firstRender = false; }); }; TimeLineInteraction.prototype.clear = function () { if (this.timeline) { this.timeline.destroy(); this.timeline = null; } if (this.container) { this.container.remove(true); this.container = null; } }; return TimeLineInteraction; }(base_1.default)); exports.default = TimeLineInteraction; },{"../components/timeline":422,"../dependents":425,"../util/bbox":672,"./base":441,"@antv/util":803,"tslib":894}],448:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TooltipIndicationAction = exports.TOOLTIP_INDICATOR_EVENTS = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = tslib_1.__importDefault(require("./base")); var dependents_1 = require("../dependents"); var tooltip_indicator_1 = tslib_1.__importStar(require("../components/tooltip-indicator")); var view_1 = require("../util/view"); var bbox_1 = tslib_1.__importDefault(require("../util/bbox")); var DEFAULT_PADDING = 8; var getValidTooltipIndicatorConfig = function (cfg) { if (cfg === void 0) { cfg = {}; } var newCfg = tslib_1.__assign({ showTotal: false, showPercent: false, padding: [DEFAULT_PADDING, 24, DEFAULT_PADDING, 24], height: cfg.showPercent ? 72 : 54 }, cfg); return newCfg; }; var TOOLTIP_INDICATOR_EVENTS; (function (TOOLTIP_INDICATOR_EVENTS) { TOOLTIP_INDICATOR_EVENTS["ACTIVE_ELEMENT"] = "tooltip_indicator_active_element"; TOOLTIP_INDICATOR_EVENTS["ACTIVE_ELEMENT_BY_X"] = "tooltip_indicator_active_element_by_x"; })(TOOLTIP_INDICATOR_EVENTS = exports.TOOLTIP_INDICATOR_EVENTS || (exports.TOOLTIP_INDICATOR_EVENTS = {})); /** * Tooltip Indicator Action 实现 */ var TooltipIndicationAction = /** @class */ (function (_super) { tslib_1.__extends(TooltipIndicationAction, _super); function TooltipIndicationAction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = 'selected'; _this.isSingle = false; return _this; } /** 交互语法触发点 */ TooltipIndicationAction.prototype.active = function () { var element = dependents_1.InteractionUtils.getCurrentElement(this.context); if (element.hasState('selected')) { if (this.isSingle) { this.setStateByX(element); } else { this.setState(element); } } else { this.setStateByX(element); } }; /** 单个元素的 enable */ TooltipIndicationAction.prototype.setState = function (element) { var _this = this; view_1.forEachElement(this.getView(), function (item) { if (item === element) { if (!item.hasState(_this.state)) { item.setState(_this.state, true); } } else { item.setState(_this.state, false); } }); this.isSingle = true; this.getView().emit(TOOLTIP_INDICATOR_EVENTS.ACTIVE_ELEMENT, { element: element, isSingle: true }); }; /** 同 X 的元素的 enable */ TooltipIndicationAction.prototype.setStateByX = function (element) { var _this = this; var xField = this.getXField(); var xValue = element.getData()[xField]; view_1.forEachElement(this.getView(), function (item) { if (item.getData()[xField] === xValue) { if (!item.hasState(_this.state)) { item.setState(_this.state, true); } } else { item.setState(_this.state, false); } }); this.isSingle = false; this.getView().emit(TOOLTIP_INDICATOR_EVENTS.ACTIVE_ELEMENT_BY_X, { element: element, isSingle: false }); }; /** 通过字段值来 enable */ TooltipIndicationAction.prototype.setStateByField = function (xFieldValue, groupFieldValue) { var _this = this; var xField = this.getView().getXScale().field; var groupField = this.getView().getGroupScales()[0].field; view_1.forEachElement(this.getView(), function (element) { var data = element.getData(); element.setState(_this.state, data[xField] === xFieldValue && (groupFieldValue === undefined || data[groupField] === groupFieldValue)); }); }; TooltipIndicationAction.prototype.getView = function () { return this.context.view; }; TooltipIndicationAction.prototype.getXField = function () { var view = this.context.view; return view.getXScale().field; }; return TooltipIndicationAction; }(dependents_1.InteractionAction)); exports.TooltipIndicationAction = TooltipIndicationAction; dependents_1.registerAction('tooltip-indicator', TooltipIndicationAction); dependents_1.registerInteraction('element-tooltip-indicator', { start: [ { trigger: 'element:mousemove', action: 'tooltip-indicator:active', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'element:touchmove', action: 'tooltip-indicator:active', throttle: { wait: 50, leading: true, trailing: false }, }, ], }); /** * 组件 Interaction 实现 */ var TooltipIndicatorInteraction = /** @class */ (function (_super) { tslib_1.__extends(TooltipIndicatorInteraction, _super); function TooltipIndicatorInteraction() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.onElementActive = function (_a) { var element = _a.element, isSingle = _a.isSingle; var xScale = _this.view.getXScale(); var xField = _this.view.getXScale().field; var groupField = _this.view.getGroupScales()[0].field; var data = element.getData(); var xValue = data[xField]; var items = _this.getLegendItems(xValue); _this.component.update({ items: items, title: { text: xScale.getText(xValue) } }); _this.component.render(); if (isSingle) { _this.component.selectItem(data[groupField]); } _this.curX = xValue; }; _this.onSelectTooltipIndicatorItem = function (itemId) { if (_this.component && itemId) { _this.getInteractionAction().setStateByField(_this.curX, itemId); } }; return _this; } TooltipIndicatorInteraction.getInteractionRange = function (layerRange, interaction) { var config = getValidTooltipIndicatorConfig(interaction); var _a = config.padding, paddingTop = _a[0], paddingBottom = _a[2]; return new bbox_1.default(layerRange.minX, layerRange.minY, layerRange.width, config.height + paddingTop + paddingBottom); }; TooltipIndicatorInteraction.prototype.clear = function () { if (this.component) { this.component.destroy(); } if (this.container) { this.container.remove(true); } this.component = null; this.container = null; }; TooltipIndicatorInteraction.prototype.render = function () { var _this = this; var view = this.view; var callback = function () { var xScale = _this.view.getXScale(); var lastX = util_1.last(xScale.getTicks()).tickValue; var padding = _this.view.padding; if (!util_1.isEqual([0, 0, 0, 0], padding)) { if (_this.component) { _this.updateComponent(); } else { _this.createComponent(); _this.component.on(tooltip_indicator_1.EVENTS.ON_SELECT_ITEM, _this.onSelectTooltipIndicatorItem); } // 默认选中最后的 X _this.curX = lastX; _this.component.update({ title: { text: xScale.getText(_this.curX) }, }); _this.component.render(); _this.getInteractionAction().setStateByField(lastX); } }; // 移除冲突/重复的组件和交互 view.legend(false); view.removeInteraction('active-region'); view.removeInteraction('tooltip'); view.interaction('element-tooltip-indicator'); // 监听 View, 创建/更新组件 view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, callback); view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, callback); // 监听组件事件,更新 action view.on(TOOLTIP_INDICATOR_EVENTS.ACTIVE_ELEMENT, this.onElementActive); view.on(TOOLTIP_INDICATOR_EVENTS.ACTIVE_ELEMENT_BY_X, this.onElementActive); }; TooltipIndicatorInteraction.prototype.getInteractionAction = function () { var interaction = this.view.interactions['element-tooltip-indicator']; return interaction && interaction.context.getAction('tooltip-indicator'); }; TooltipIndicatorInteraction.prototype.createComponent = function () { var padding = getValidTooltipIndicatorConfig(this.getInteractionConfig()).padding; var paddingTop = padding[0], paddingRight = padding[1], paddingBottom = padding[2], paddingLeft = padding[3]; var items = this.getLegendItems(); var range = this.getRange(); var xScale = this.view.getXScale(); var lastX = util_1.last(xScale.getTicks()).tickValue; this.container = this.canvas.addGroup(); this.component = new tooltip_indicator_1.default({ container: this.container, x: range.x + paddingLeft, y: range.y + paddingTop, width: range.width - paddingLeft - paddingRight, height: range.height - paddingTop - paddingBottom, theme: this.getViewLayer().getPlotTheme(), items: items, }); this.component.init(); this.getInteractionAction().setStateByField(lastX); }; TooltipIndicatorInteraction.prototype.updateComponent = function () { var items = this.getLegendItems(); this.component.update({ items: items, }); }; TooltipIndicatorInteraction.prototype.getLegendItems = function (xValue) { var view = this.view; var data = view.getData(); var defaultColor = view.getTheme().defaultColor; var xScale = view.getXScale(); var yScale = view.getYScales()[0]; var curX = xValue || util_1.last(xScale.getTicks()).tickValue; var groupAttrs = view.getLegendAttributes(); var colorAttr = groupAttrs.find(function (attr) { return attr.type === 'color'; }); var items = []; // 取第一个分组scale,暂不考虑多个分组情况 var groupScale = view.getGroupScales()[0]; var groupField = groupScale.field; if (groupScale && groupScale.isCategory) { // 只处理离散情况 groupScale.getTicks().forEach(function (tick) { var name = tick.text, value = tick.tickValue; var color = colorAttr.mapping(value).join('') || defaultColor; items.push({ id: value, title: name, color: color, values: [], }); }); } var selectedData = (data === null || data === void 0 ? void 0 : data.filter(function (datum) { return datum[xScale.field] === curX; })) || []; items.forEach(function (item) { var datum = selectedData.find(function (curDatum) { return curDatum[groupField] === item.id; }); item.values.push({ value: yScale.formatter ? yScale.formatter(datum[yScale.field]) : datum[yScale.field], }); }); return items; }; return TooltipIndicatorInteraction; }(base_1.default)); exports.default = TooltipIndicatorInteraction; },{"../components/tooltip-indicator":423,"../dependents":425,"../util/bbox":672,"../util/view":715,"./base":441,"@antv/util":803,"tslib":894}],449:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.timeIntervals = void 0; var dependents_1 = require("../dependents"); var SECOND = 1000; var MINUTE = 60 * SECOND; var HOUR = 60 * MINUTE; var DAY = 24 * HOUR; var WEEK = DAY * 7; var MONTH = DAY * 30; var YEAR = DAY * 365; exports.timeIntervals = { second: { value: SECOND, format: 'HH:mm:ss' }, miniute: { value: MINUTE, format: 'HH:mm' }, hour: { value: HOUR, format: 'HH' }, day: { value: DAY, format: 'YYYY-MM-DD' }, week: { value: WEEK, format: 'YYYY-MM-DD' }, month: { value: MONTH, format: 'YYYY-MM' }, year: { value: YEAR, format: 'YYYY' }, }; },{"../dependents":425}],450:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var axis_1 = tslib_1.__importDefault(require("../../../util/responsive/apply/axis")); function responsiveAxis(layer) { var responsiveTheme = layer.getResponsiveTheme(); var canvas = layer.canvas; // x-axis new axis_1.default({ plot: layer, responsiveTheme: responsiveTheme, dim: 'x', }); // y-axis new axis_1.default({ plot: layer, responsiveTheme: responsiveTheme, dim: 'y', }); canvas.draw(); } exports.default = responsiveAxis; },{"../../../util/responsive/apply/axis":682,"tslib":894}],451:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var axis_1 = tslib_1.__importDefault(require("./axis")); var preRenderResponsive = []; var afterRenderResponsive = [{ name: 'responsiveAxis', method: axis_1.default }]; exports.default = { preRender: preRenderResponsive, afterRender: afterRenderResponsive, }; },{"./axis":450,"tslib":894}],452:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../../../../components/label/base"); var point_auto_1 = tslib_1.__importDefault(require("../../../../components/label/point-auto")); var view_1 = require("../../../../util/view"); var math_1 = require("../../../../util/math"); var color_1 = require("../../../../util/color"); var AreaPointAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(AreaPointAutoLabel, _super); function AreaPointAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } AreaPointAutoLabel.prototype.layoutLabels = function (geometry, labels) { _super.prototype.layoutLabels.call(this, geometry, labels); this.adjustAreaLabelsStyle(labels); }; AreaPointAutoLabel.prototype.adjustAreaLabelsStyle = function (labels) { var view = this.view; var _a = this.options, darkStyle = _a.darkStyle, lightStyle = _a.lightStyle; var areaGeometry = view_1.getGeometryByType(view, 'area'); var areas = view_1.getGeometryShapes(areaGeometry).sort(function (left, right) { return right.getBBox().height - left.getBBox().height; }); util_1.each(labels, function (label) { var labelBBox = label.getBBox(); var points = math_1.getStrokePoints(labelBBox.x, labelBBox.y, labelBBox.width, labelBBox.height); var match = util_1.map(areas, function (area) { return ({ area: area, matches: util_1.filter(points, function (point) { return !!area.isHit(point[0], point[1]); }).length, }); }).sort(function (left, right) { return left.matches - right.matches; }); if (util_1.last(match).matches > 0) { var bgColor = util_1.last(match).area.attr('fill'); var fillWhite = color_1.isContrastColorWhite(bgColor); label.attr({ fill: fillWhite ? lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.fill : darkStyle === null || darkStyle === void 0 ? void 0 : darkStyle.fill, fillOpacity: fillWhite ? lightStyle.fillOpacity : darkStyle.fillOpacity, stroke: fillWhite ? lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.stroke : darkStyle === null || darkStyle === void 0 ? void 0 : darkStyle.stroke, }); } }); }; return AreaPointAutoLabel; }(point_auto_1.default)); exports.default = AreaPointAutoLabel; base_1.registerLabelComponent('area-point-auto', AreaPointAutoLabel); },{"../../../../components/label/base":414,"../../../../components/label/point-auto":416,"../../../../util/color":673,"../../../../util/math":680,"../../../../util/view":715,"@antv/util":803,"tslib":894}],453:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../../components/label/base"); var point_1 = tslib_1.__importDefault(require("../../../../components/label/point")); var AreaPointLabel = /** @class */ (function (_super) { tslib_1.__extends(AreaPointLabel, _super); function AreaPointLabel() { return _super !== null && _super.apply(this, arguments) || this; } return AreaPointLabel; }(point_1.default)); exports.default = AreaPointLabel; base_1.registerLabelComponent('area-point', AreaPointLabel); },{"../../../../components/label/base":414,"../../../../components/label/point":417,"tslib":894}],454:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { area: 'area', line: 'line', point: 'point', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],455:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Area = /** @class */ (function (_super) { tslib_1.__extends(Area, _super); function Area() { return _super !== null && _super.apply(this, arguments) || this; } Area.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'area'; _super.prototype.createLayers.call(this, layerProps); }; Area.getDefaultOptions = layer_1.default.getDefaultOptions; return Area; }(plot_1.default)); exports.default = Area; },{"../../base/plot":394,"./layer":456,"@antv/util":803,"tslib":894}],456:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); require("./component/label/area-point"); require("./component/label/area-point-auto"); var scale_1 = require("../../util/scale"); var apply_responsive_1 = tslib_1.__importDefault(require("./apply-responsive")); var EventParser = tslib_1.__importStar(require("./event")); require("./theme"); var view_1 = require("../../util/view"); var GEOM_MAP = { area: 'area', line: 'line', point: 'point', }; var AreaLayer = /** @class */ (function (_super) { tslib_1.__extends(AreaLayer, _super); function AreaLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'area'; return _this; } AreaLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { smooth: false, areaStyle: { opacity: 0.25, }, line: { visible: true, size: 2, style: { opacity: 1, lineJoin: 'round', lineCap: 'round', }, }, point: { visible: false, size: 4, shape: 'point', }, label: { visible: false, type: 'point', }, legend: { visible: true, position: 'top-left', wordSpacing: 4, }, tooltip: { visible: true, shared: true, showCrosshairs: true, crosshairs: { type: 'x', }, offset: 20, }, }); }; AreaLayer.prototype.beforeInit = function () { _super.prototype.beforeInit.call(this); /** 响应式图形 */ if (this.options.responsive && this.options.padding !== 'auto') { this.applyResponsive('preRender'); } }; AreaLayer.prototype.afterRender = function () { this.renderLabel(); /** 响应式 */ if (this.options.responsive && this.options.padding !== 'auto') { this.applyResponsive('afterRender'); } _super.prototype.afterRender.call(this); }; AreaLayer.prototype.geometryParser = function (dim, type) { return GEOM_MAP[type]; }; AreaLayer.prototype.scale = function () { var props = this.options; var scales = {}; /** 配置x-scale */ scales[props.xField] = { type: 'cat', }; if (util_1.has(props, 'xAxis')) { scale_1.extractScale(scales[props.xField], props.xAxis); } /** 配置y-scale */ scales[props.yField] = {}; if (util_1.has(props, 'yAxis')) { scale_1.extractScale(scales[props.yField], props.yAxis); } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; AreaLayer.prototype.coord = function () { return null; }; AreaLayer.prototype.addGeometry = function () { var props = this.options; var area = factory_1.getGeom('area', 'main', { plot: this, }); this.area = area; if (props.label) { this.label(); } if (props.tooltip && (props.tooltip.fields || props.tooltip.formatter)) { this.geometryTooltip(); } this.adjustArea(area); this.setConfig('geometry', area); this.addLine(); this.addPoint(); }; //eslint-disable-next-line @typescript-eslint/no-unused-vars AreaLayer.prototype.adjustArea = function (area) { return; }; //eslint-disable-next-line @typescript-eslint/no-unused-vars AreaLayer.prototype.adjustLine = function (line) { return; }; //eslint-disable-next-line @typescript-eslint/no-unused-vars AreaLayer.prototype.adjustPoint = function (point) { return; }; AreaLayer.prototype.addLine = function () { var props = this.options; var lineConfig = util_1.deepMix({}, props.line); if (lineConfig.visible) { var line = factory_1.getGeom('line', 'guide', { type: 'line', plot: this, line: lineConfig, }); this.adjustLine(line); this.setConfig('geometry', line); this.line = line; } }; AreaLayer.prototype.addPoint = function () { var props = this.options; var pointConfig = util_1.deepMix({}, props.point); if (pointConfig.visible) { var point = factory_1.getGeom('point', 'guide', { plot: this, }); this.adjustPoint(point); this.setConfig('geometry', point); this.point = point; } }; AreaLayer.prototype.renderLabel = function () { var scales = this.config.scales; var _a = this.options, label = _a.label, yField = _a.yField; var scale = scales[yField]; if (label.visible) { var geometry = view_1.getGeometryByType(this.view, 'area'); this.doRenderLabel(geometry, tslib_1.__assign({ type: 'area-point', formatter: scale.formatter && (function (value) { return scale.formatter(value); }) }, this.options.label)); } }; AreaLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { // 关闭动画 this.area.animate = false; if (this.line) this.line.animate = false; if (this.point) this.point.animate = false; } }; AreaLayer.prototype.label = function () { return; }; AreaLayer.prototype.geometryTooltip = function () { this.area.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.area.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.area.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.area.tooltip.fields = [this.options.xField, this.options.yField]; if (this.options.seriesField) { this.area.tooltip.fields.push(this.options.seriesField); } } } }; AreaLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; AreaLayer.prototype.applyResponsive = function (stage) { var _this = this; var methods = apply_responsive_1.default[stage]; util_1.each(methods, function (r) { var responsive = r; responsive.method(_this); }); }; return AreaLayer; }(view_layer_1.default)); exports.default = AreaLayer; global_1.registerPlotType('area', AreaLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../geoms/factory":430,"../../util/scale":712,"../../util/view":715,"./apply-responsive":451,"./component/label/area-point":453,"./component/label/area-point-auto":452,"./event":454,"./theme":457,"@antv/util":803,"tslib":894}],457:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_AREA_THEME = void 0; var theme_1 = require("../../theme"); var AREA_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity }; }; var AREA_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var LINE_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity }; }; var LINE_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var LINE_SELECTED_STYLE = function (style) { var lineWidth = style.lineWidth || 1; return { lineWidth: lineWidth + 2 }; }; var POINT_ACTIVE_STYLE = function (style) { var color = style.fill || style.fillStyle; var radius = style.size || style.radius; return { radius: radius + 1, shadowBlur: radius, shadowColor: color, stroke: color, strokeOpacity: 1, lineWidth: 1, }; }; var POINT_SELECTED_STYLE = function (style) { var color = style.fill || style.fillStyle; var radius = style.size || style.radius; return { radius: radius + 2, shadowBlur: radius, shadowColor: color, stroke: color, strokeOpacity: 1, lineWidth: 2, }; }; var POINT_DISABLED_STYLE = function (style) { var opacity = style.opacity || style.fillOpacity || 1; return { opacity: opacity * 0.5 }; }; exports.DEFAULT_AREA_THEME = { areaStyle: { normal: {}, active: AREA_ACTIVE_STYLE, disable: AREA_DISABLE_STYLE, selected: { lineWidth: 1, stroke: '#333333' }, }, lineStyle: { normal: {}, active: LINE_ACTIVE_STYLE, disable: LINE_DISABLE_STYLE, selected: LINE_SELECTED_STYLE, }, pointStyle: { normal: {}, active: POINT_ACTIVE_STYLE, disable: POINT_DISABLED_STYLE, selected: POINT_SELECTED_STYLE, }, label: { darkStyle: { fill: '#2c3542', stroke: '#ffffff', fillOpacity: 0.85, }, lightStyle: { fill: '#ffffff', fillOpacity: 1, stroke: '#2c3542', }, }, }; theme_1.registerTheme('area', exports.DEFAULT_AREA_THEME); },{"../../theme":669}],458:[function(require,module,exports){ arguments[4][450][0].apply(exports,arguments) },{"../../../util/responsive/apply/axis":682,"dup":450,"tslib":894}],459:[function(require,module,exports){ arguments[4][451][0].apply(exports,arguments) },{"./axis":458,"dup":451,"tslib":894}],460:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../../../components/label/base"); var dependents_1 = require("../../../dependents"); var label_1 = tslib_1.__importDefault(require("./label")); var view_1 = require("../../../util/view"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var color_1 = require("../../../util/color"); /** 自动模式的 Column 数据标签,会根据图形和数据标签自动优化数据标签布局和样式等 */ var BarAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(BarAutoLabel, _super); function BarAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } BarAutoLabel.prototype.getPosition = function (element) { var offset = this.getDefaultOffset(); var value = this.getValue(element); var bbox = this.getElementShapeBBox(element); var minX = bbox.minX, maxX = bbox.maxX, minY = bbox.minY, height = bbox.height; var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY; var y = minY + height / 2 + offsetY; var dir = value < 0 ? -1 : 1; var root = value > 0 ? maxX : minX; var x = root + offset * dir + offsetX; // 统一先设置为 right return { x: x, y: y }; }; BarAutoLabel.prototype.getTextAlign = function (element) { var value = this.getValue(element); return value > 0 ? 'left' : 'right'; }; /** 默认的 fill 取自用户配置或主题配置 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars BarAutoLabel.prototype.getTextFill = function (element) { var style = this.options.style; return style.fill; }; /** 默认不描边 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars BarAutoLabel.prototype.getTextStroke = function (element) { return undefined; }; /** 默认无处理:在 layout 阶段处理 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars BarAutoLabel.prototype.adjustLabel = function (label, element) { // empty }; /** 自动布局所有的数据标签 */ BarAutoLabel.prototype.layoutLabels = function (geometry, labels) { if (this.shouldInShapeLabels(labels)) { this.inShapeLabels(geometry, labels); } this.autoHideLabels(geometry, labels); }; /** 判断是否可以把数据标签放置在柱子内部 */ BarAutoLabel.prototype.shouldInShapeLabels = function (labels) { var _this = this; return util_1.every(labels, function (label) { var labelBBox = label.getBBox(); var element = label.get('element'); var bbox = _this.getElementShapeBBox(element); return bbox.height >= labelBBox.height; }); }; /** 内置数据标签,并自动设置颜色描边等属性 */ BarAutoLabel.prototype.inShapeLabels = function (geometry, labels) { var _this = this; var coordinateBBox = this.getCoordinateBBox(); var xField = geometry.getXYFields()[0]; var _a = this.options, darkStyle = _a.darkStyle, lightStyle = _a.lightStyle; var groupedLabels = util_1.groupBy(labels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; }); util_1.each(labels, function (label) { var curGroup = groupedLabels[label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]] || []; var element = label.get('element'); var shape = element.shape; var fillWhite = color_1.isContrastColorWhite(shape.attr('fill')); var shapeBBox = _this.getElementShapeBBox(element); var labelBBox = bbox_1.default.fromBBoxObject(label.getBBox()); // 如果 Column 本身就不可见,直接隐藏对应的 label if (view_1.getOverlapArea(coordinateBBox, shapeBBox) <= 0) { label.set('visible', false); } if (labelBBox.width > shapeBBox.width) { // 处理放不下的情况 var idx = util_1.findIndex(curGroup, function (item) { return item === label; }); if (idx !== curGroup.length - 1) { label.set('visible', false); } } else { // 数据标签展示在图形中央 label.attr({ x: shapeBBox.x + shapeBBox.width / 2, textAlign: 'center', }); var overflow = labelBBox.width > shapeBBox.width || labelBBox.height > shapeBBox.height; if (overflow) { // 出现了溢出情况,添加描边 label.attr({ stroke: lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.stroke, }); } else { // 放置在柱形内部,颜色取反 label.attr({ fill: fillWhite ? lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.fill : darkStyle === null || darkStyle === void 0 ? void 0 : darkStyle.fill, fillOpacity: fillWhite ? lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.fillOpacity : darkStyle === null || darkStyle === void 0 ? void 0 : darkStyle.fillOpacity, stroke: undefined, }); } } }); }; /** 数据标签防重叠抽样 */ BarAutoLabel.prototype.autoHideLabels = function (geometry, labels) { var coordinateBBox = this.getCoordinateBBox(); var filteredLabels = this.filterLabels(labels); var xField = geometry.getXYFields()[0]; var dones = []; var todo = []; var groupedLabels = util_1.groupBy(filteredLabels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; }); var xValues = util_1.uniq(util_1.map(filteredLabels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; })); var xValue; if (util_1.size(xValues) > 0) { // 第一组 xValue = xValues.shift(); util_1.each(groupedLabels[xValue], function (label) { return todo.push(label); }); } if (util_1.size(xValues) > 0) { // 最后一组 xValue = xValues.pop(); util_1.each(groupedLabels[xValue], function (label) { return todo.push(label); }); } util_1.each(xValues.reverse(), function (val) { // 其他组 util_1.each(groupedLabels[val], function (label) { return todo.push(label); }); }); while (todo.length > 0) { var cur = todo.shift(); if (cur.get('visible')) { view_1.moveInPanel(cur, coordinateBBox); if (view_1.checkShapeOverlap(cur, dones)) { cur.set('visible', false); } else { dones.push(cur); } } } }; /** 抽样数据标签,设置最大数量的数据标签,其他的统一隐藏 */ BarAutoLabel.prototype.filterLabels = function (labels) { var MAX_CNT = 500; // 最多显示 500 个数据标签 var filteredLabels = []; var pages = Math.max(Math.floor(labels.length / MAX_CNT), 1); util_1.each(labels, function (label, idx) { if (idx % pages === 0) { filteredLabels.push(label); } else { label.set('visible', false); } }); return filteredLabels; }; return BarAutoLabel; }(label_1.default)); exports.default = BarAutoLabel; base_1.registerLabelComponent('bar-auto', BarAutoLabel); },{"../../../components/label/base":414,"../../../dependents":425,"../../../util/bbox":672,"../../../util/color":673,"../../../util/view":715,"./label":461,"@antv/util":803,"tslib":894}],461:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../../dependents"); var base_1 = tslib_1.__importStar(require("../../../components/label/base")); var color_1 = require("../../../util/color"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var BarLabel = /** @class */ (function (_super) { tslib_1.__extends(BarLabel, _super); function BarLabel() { return _super !== null && _super.apply(this, arguments) || this; } BarLabel.prototype.getLabelItemAttrs = function (element, index) { var _a; var _b = this.options, style = _b.style, formatter = _b.formatter; var mappingData = [].concat(element.getModel().mappingData); var value = this.getValue(element); return util_1.deepMix({}, style, tslib_1.__assign(tslib_1.__assign({}, this.getPosition(element)), { text: formatter ? formatter(value, (_a = {}, _a[dependents_1._ORIGIN] = mappingData[0]._origin, _a.mappingDatum = mappingData[0], _a.mappingDatumIndex = 0, _a.element = element, _a.elementIndex = index, _a), index) : value, fill: this.getTextFill(element), stroke: this.getTextStroke(element), textAlign: this.getTextAlign(element), textBaseline: this.getTextBaseline() })); }; BarLabel.prototype.adjustLabel = function (label, element) { var _a = this.options, adjustPosition = _a.adjustPosition, style = _a.style; if (adjustPosition) { var offset = this.getDefaultOffset(); var labelRange = label.getBBox(); var shapeRange = this.getElementShapeBBox(element); if (shapeRange.width <= labelRange.width) { var xPosition = shapeRange.maxX + this.options.offsetX + offset; label.attr('x', xPosition); label.attr('fill', style.fill); } } }; BarLabel.prototype.getDefaultOptions = function () { var theme = this.layer.theme; var _a = theme.label, label = _a === void 0 ? {} : _a; return tslib_1.__assign({ offsetX: 0, offsetY: 0, adjustPosition: true }, label); }; BarLabel.prototype.getValue = function (element) { return util_1.get(element.getData(), this.layer.options.xField); }; BarLabel.prototype.getPosition = function (element) { var offset = this.getDefaultOffset(); var value = this.getValue(element); var bbox = this.getElementShapeBBox(element); var minX = bbox.minX, maxX = bbox.maxX, minY = bbox.minY, height = bbox.height, width = bbox.width; var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY, position = _a.position; var y = minY + height / 2 + offsetY; var dir = value < 0 ? -1 : 1; var x; if (position === 'left') { var root = value > 0 ? minX : maxX; x = root + offset * dir + offsetX; } else if (position === 'right') { var root = value > 0 ? maxX : minX; x = root + offset * dir + offsetX; } else { x = minX + width / 2 + offsetX; } return { x: x, y: y }; }; BarLabel.prototype.getTextFill = function (element) { var shape = element.shape; if (this.options.adjustColor && this.options.position !== 'right') { var shapeColor = shape.attr('fill'); var shapeOpacity = shape.attr('opacity') ? shape.attr('opacity') : 1; var rgb = color_1.rgb2arr(shapeColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / shapeOpacity; var colorBand = [ { from: 0, to: 85, color: 'white' }, { from: 85, to: 170, color: '#F6F6F6' }, { from: 170, to: 255, color: 'black' }, ]; var reflect = color_1.mappingColor(colorBand, gray); return reflect; } var defaultColor = this.options.style.fill; return defaultColor; }; BarLabel.prototype.getTextStroke = function (element) { var fill = this.getTextFill(element); var _a = this.options, position = _a.position, adjustColor = _a.adjustColor; return position !== 'right' && adjustColor && fill !== 'black' ? null : undefined; }; BarLabel.prototype.getTextAlign = function (element) { var value = this.getValue(element); var position = this.options.position; var alignOptions = { right: 'left', left: 'left', middle: 'center', }; var alignOptionsReverse = { right: 'right', left: 'right', middle: 'center', }; if (value < 0) { return alignOptionsReverse[position]; } return alignOptions[position]; }; BarLabel.prototype.getTextBaseline = function () { return 'middle'; }; BarLabel.prototype.getElementShapeBBox = function (element) { var _this = this; var shape = element.shape; var points = []; util_1.each(shape.get('origin').points, function (p) { points.push(_this.coord.convertPoint(p)); }); var xValues = points.map(function (point) { return point.x; }); var xValuesMin = Math.min.apply(Math, xValues); var xValueMax = Math.max.apply(Math, xValues); var yValues = points.map(function (point) { return point.y; }); var yValuesMin = Math.min.apply(Math, yValues); var yValuesMax = Math.max.apply(Math, yValues); var bbox = new bbox_1.default(xValuesMin, yValuesMin, xValueMax - xValuesMin, yValuesMax - yValuesMin); return bbox; }; BarLabel.prototype.getLabelOffset = function () { // Column 的 offset 在 getPosition 中因 position 不同单独处理 return { x: 0, y: 0, }; }; return BarLabel; }(base_1.default)); exports.default = BarLabel; base_1.registerLabelComponent('bar', BarLabel); },{"../../../components/label/base":414,"../../../dependents":425,"../../../util/bbox":672,"../../../util/color":673,"@antv/util":803,"tslib":894}],462:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { bar: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],463:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Bar = /** @class */ (function (_super) { tslib_1.__extends(Bar, _super); function Bar() { return _super !== null && _super.apply(this, arguments) || this; } Bar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'bar'; _super.prototype.createLayers.call(this, layerProps); }; Bar.getDefaultOptions = layer_1.default.getDefaultOptions; return Bar; }(plot_1.default)); exports.default = Bar; },{"../../base/plot":394,"./layer":464,"@antv/util":803,"tslib":894}],464:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../components/factory"); var conversion_tag_1 = tslib_1.__importDefault(require("../../components/conversion-tag")); var factory_2 = require("../../geoms/factory"); var scale_1 = require("../../util/scale"); var apply_responsive_1 = tslib_1.__importDefault(require("./apply-responsive")); require("./theme"); require("./component/label"); require("./component/label-auto"); var EventParser = tslib_1.__importStar(require("./event")); var view_1 = require("../../util/view"); var G2_GEOM_MAP = { bar: 'interval', }; var PLOT_GEOM_MAP = { interval: 'bar', }; var BaseBarLayer = /** @class */ (function (_super) { tslib_1.__extends(BaseBarLayer, _super); function BaseBarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'bar'; return _this; } BaseBarLayer.getDefaultOptions = function () { var cfg = { xAxis: { visible: true, line: { visible: false, }, title: { visible: true, }, label: { visible: false, }, tickLine: { visible: false, }, grid: { visible: false, }, nice: true, }, yAxis: { visible: true, grid: { visible: false, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoRotate: false, autoHide: true, }, title: { visible: false, spacing: 12, }, }, tooltip: { visible: true, shared: true, showCrosshairs: false, showMarkers: false, }, label: { visible: true, position: 'left', adjustColor: true, }, legend: { visible: false, position: 'top-left', }, interactions: [ { type: 'tooltip' }, { type: 'active-region' }, { type: 'legend-active' }, { type: 'legend-filter' }, ], conversionTag: { visible: false, }, }; return util_1.deepMix({}, _super.getDefaultOptions.call(this), cfg); }; BaseBarLayer.prototype.beforeInit = function () { _super.prototype.beforeInit.call(this); var props = this.options; /** 响应式图形 */ if (props.responsive && props.padding !== 'auto') { this.applyResponsive('preRender'); } }; BaseBarLayer.prototype.afterRender = function () { var props = this.options; this.renderLabel(); /** 响应式 */ if (props.responsive && props.padding !== 'auto') { this.applyResponsive('afterRender'); } if (props.conversionTag.visible) { this.conversionTag = new conversion_tag_1.default(tslib_1.__assign({ view: this.view, field: props.xField, animation: props.animation === false ? false : true }, props.conversionTag)); } _super.prototype.afterRender.call(this); }; BaseBarLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; BaseBarLayer.prototype.processData = function (originData) { var inputData = originData ? originData.slice().reverse() : originData; var yField = this.options.yField; var processedData = []; util_1.each(inputData, function (data) { var d = util_1.clone(data); d[yField] = d[yField].toString(); processedData.push(d); }); return processedData; }; BaseBarLayer.prototype.scale = function () { var props = this.options; var scales = {}; /** 配置x-scale */ scales[props.yField] = { type: 'cat', }; if (util_1.has(props, 'yAxis')) { scale_1.extractScale(scales[props.yField], props.yAxis); } /** 配置y-scale */ scales[props.xField] = {}; if (util_1.has(props, 'xAxis')) { scale_1.extractScale(scales[props.xField], props.xAxis); } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; BaseBarLayer.prototype.coord = function () { this.setConfig('coordinate', { actions: [['transpose']], }); }; BaseBarLayer.prototype.axis = function () { var xAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'x', }); var yAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'y', }); /** 转置坐标系特殊配置 */ if (xAxis_parser) { xAxis_parser.position = 'left'; } if (yAxis_parser) { yAxis_parser.position = 'bottom'; } var axesConfig = {}; axesConfig[this.options.xField] = xAxis_parser; axesConfig[this.options.yField] = yAxis_parser; /** 存储坐标轴配置项到config */ this.setConfig('axes', axesConfig); }; //eslint-disable-next-line @typescript-eslint/no-unused-vars BaseBarLayer.prototype.adjustBar = function (bar) { return null; }; BaseBarLayer.prototype.addGeometry = function () { var props = this.options; var bar = factory_2.getGeom('interval', 'main', { positionFields: [props.yField, props.xField], plot: this, }); if (props.conversionTag.visible) { this.setConfig('theme', util_1.deepMix({}, this.getTheme(), { columnWidthRatio: 1 / 3, })); } this.adjustBar(bar); this.bar = bar; if (props.tooltip && (props.tooltip.fields || props.tooltip.formatter)) { this.geometryTooltip(); } this.setConfig('geometry', bar); }; BaseBarLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { /** 关闭动画 */ this.bar.animate = false; } }; BaseBarLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; BaseBarLayer.prototype.renderLabel = function () { var scales = this.config.scales; var _a = this.options, label = _a.label, xField = _a.xField; var scale = scales[xField]; if (label === null || label === void 0 ? void 0 : label.visible) { var geometry = view_1.getGeometryByType(this.view, 'interval'); this.doRenderLabel(geometry, tslib_1.__assign({ type: 'bar', formatter: scale.formatter && (function (value) { return scale.formatter(value); }) }, this.options.label)); } }; BaseBarLayer.prototype.geometryTooltip = function () { this.bar.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.bar.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.bar.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.bar.tooltip.fields = [this.options.xField, this.options.yField]; if (this.options.colorField) { this.bar.tooltip.fields.push(this.options.colorField); } } } }; BaseBarLayer.prototype.applyResponsive = function (stage) { var _this = this; var methods = apply_responsive_1.default[stage]; util_1.each(methods, function (r) { var responsive = r; responsive.method(_this); }); }; BaseBarLayer.prototype.getLabelOptionsByPosition = function (position) { if (position === 'middle') { return { offset: 0, }; } if (position === 'left') { return { offset: 7, style: { stroke: null, lineWidth: 0, }, }; } if (position === 'right') { return { offset: 4, }; } }; return BaseBarLayer; }(view_layer_1.default)); exports.default = BaseBarLayer; global_1.registerPlotType('bar', BaseBarLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/conversion-tag":410,"../../components/factory":412,"../../geoms/factory":430,"../../util/scale":712,"../../util/view":715,"./apply-responsive":459,"./component/label":461,"./component/label-auto":460,"./event":462,"./theme":465,"@antv/util":803,"tslib":894}],465:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_BAR_THEME = void 0; var theme_1 = require("../../theme"); var BAR_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var BAR_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; exports.DEFAULT_BAR_THEME = { label: { darkStyle: { fill: '#2c3542', stroke: '#ffffff', fillOpacity: 0.85, }, lightStyle: { fill: '#ffffff', stroke: '#ffffff', fillOpacity: 1, }, }, columnStyle: { normal: {}, active: BAR_ACTIVE_STYLE, disable: BAR_DISABLE_STYLE, selected: { lineWidth: 1, stroke: 'black' }, }, }; theme_1.registerTheme('bar', exports.DEFAULT_BAR_THEME); },{"../../theme":669}],466:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Bubble = /** @class */ (function (_super) { tslib_1.__extends(Bubble, _super); function Bubble() { return _super !== null && _super.apply(this, arguments) || this; } Bubble.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'bubble'; _super.prototype.createLayers.call(this, layerProps); }; Bubble.prototype.getSizeScale = function () { var layer = this.layers[0]; return layer.getSizeScale(); }; Bubble.getDefaultOptions = layer_1.default.getDefaultOptions; return Bubble; }(plot_1.default)); exports.default = Bubble; },{"../../base/plot":394,"./layer":467,"@antv/util":803,"tslib":894}],467:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var EventParser = tslib_1.__importStar(require("../scatter/event")); var layer_1 = tslib_1.__importDefault(require("../scatter/layer")); require("./shape"); require("./theme"); var BubbleLayer = /** @class */ (function (_super) { tslib_1.__extends(BubbleLayer, _super); function BubbleLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'bubble'; return _this; } BubbleLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { // 直径 min 4px;max 64px pointSize: [2, 32], pointStyle: { stroke: null, strokeOpacity: 1, fillOpacity: 0.5, }, label: { position: 'middle', style: { stroke: '#fff', lineWidth: 2, }, }, shape: 'bubble-point', }); }; BubbleLayer.prototype.getSizeScale = function () { var sizeField = this.options.sizeField; if (sizeField) { this.view.getScaleByField(sizeField); } }; BubbleLayer.prototype.legend = function () { var _a; _super.prototype.legend.call(this); if (this.options.legend && this.options.legend.visible === false) { return; } this.setConfig('legends', (_a = {}, _a[this.options.sizeField] = false, _a)); }; BubbleLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; return BubbleLayer; }(layer_1.default)); exports.default = BubbleLayer; global_1.registerPlotType('bubble', BubbleLayer); },{"../../base/global":392,"../scatter/event":603,"../scatter/layer":605,"./shape":468,"./theme":469,"@antv/util":803,"tslib":894}],468:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var g2_1 = require("@antv/g2"); var util_1 = require("@antv/g2/lib/geometry/shape/point/util"); g2_1.registerShape('point', 'bubble-point', { draw: function (cfg, container) { var point = util_1.drawPoints(this, cfg, container, 'circle', false); // 如果用户未配置 stroke,气泡图 stroke 默认用 fill 颜色 if (!cfg.style.stroke) { var fill = point.attr('fill'); point.attr('stroke', fill); } return point; }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'circle', style: { r: 4.5, fill: color, }, }; }, }); },{"@antv/g2":309,"@antv/g2/lib/geometry/shape/point/util":295}],469:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var POINT_ACTIVE_STYLE = function (style) { var stroke = style.stroke || '#000'; var fillOpacity = style.fillOpacity || style.opacity || 0.95; return { stroke: stroke, fillOpacity: fillOpacity, }; }; var POINT_SELECTED_STYLE = function (style) { var stroke = style.stroke || '#000'; var lineWidth = style.lineWidth || 2; return { stroke: stroke, lineWidth: lineWidth, }; }; var POINT_INACTIVE_STYLE = function (style) { var fillOpacity = style.fillOpacity || style.opacity || 0.3; return { fillOpacity: fillOpacity, }; }; theme_1.registerTheme('bubble', { pointStyle: { normal: {}, active: POINT_ACTIVE_STYLE, selected: POINT_SELECTED_STYLE, inactive: POINT_INACTIVE_STYLE, }, }); },{"../../theme":669}],470:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var BulletRect = /** @class */ (function () { function BulletRect(view, cfg) { this.view = view; this.cfg = cfg; this._init(); } /** 绘制辅助labels */ BulletRect.prototype.draw = function () { if (!this.view || this.view.destroyed) { return; } this.container = this.view.middleGroup.addGroup(); this.container.set('name', 'rectGroups'); this.container.setZIndex(-100); var geometry = this.getGeometry(); var shapes = util_1.map(geometry === null || geometry === void 0 ? void 0 : geometry.elements, function (element) { return element.shape; }); for (var i = 0; i < this.cfg.ranges.length; i += 1) { var shapeBox = shapes[i].getBBox(); var widthRatio = shapeBox.width / shapes[i].get('origin').data[this.cfg.yField]; this.drawRect(shapeBox, this.cfg.ranges[i] || [0, 1], widthRatio); } this.view.canvas.draw(); }; BulletRect.prototype.drawRect = function (box, ranges, widthRatio) { var options = this.cfg; var rangeColors = options.rangeColors; var xPos = box.minX; var yPos = box.minY - (box.height * (options.rangeSize - 1)) / 2; for (var i = 1; i < ranges.length; i += 1) { var width = (ranges[i] - ranges[i - 1]) * options.rangeMax * widthRatio; this.container .addShape('rect', { name: 'bullet-rect', attrs: { width: width, height: box.height * options.rangeSize, x: xPos, y: yPos, fill: rangeColors[(i - 1) % rangeColors.length], fillOpacity: 0.25, }, }) .set('zIndex', -1); xPos += width; } if (options.axis && options.axis.visible) { var tickInterval = options.rangeMax / (options.axis.tickCount - 1); var rangeBox = new bbox_1.default(box.x, yPos, xPos, box.height * options.rangeSize); this.drawBulletTicks(rangeBox, tickInterval, widthRatio); } }; /** 添加 ticks */ BulletRect.prototype.drawBulletTicks = function (box, tickInterval, widthRatio) { var options = this.cfg; var ticksStyle = options.axis.style; var tickCount = options.axis.tickCount; var tickPosition = options.axis.position; var tickOffset = util_1.get(ticksStyle, 'lineHeight', 0) - ticksStyle.fontSize / 2; for (var tickIdx = 0; tickIdx < tickCount; tickIdx += 1) { var x = box.minX + tickInterval * tickIdx * widthRatio; var tickText = "" + tickInterval * tickIdx; if (options.axis.formatter) { tickText = options.axis.formatter(tickText, tickIdx); } this.container.addShape('text', { name: 'tick', attrs: tslib_1.__assign({ x: x, y: tickPosition === 'before' ? box.minY - tickOffset : box.maxY + tickOffset, text: "" + tickText }, ticksStyle), }); if (options.axis.tickLine && options.axis.tickLine.visible) { var tickLineCfg = options.axis.tickLine; if (tickIdx > 0 && tickIdx !== tickCount - 1) { this.container .addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', x, box.minY], ['L', x, box.maxY], ] }, tickLineCfg), }) .set('zIndex', -1); } } } }; BulletRect.prototype.clear = function () { if (this.container) { this.container.clear(); } }; BulletRect.prototype.destroy = function () { if (this.container) { this.container.remove(); } }; BulletRect.prototype._init = function () { var _this = this; this.view.on('beforerender', function () { _this.clear(); }); this.view.on('afterrender', function () { _this.draw(); }); }; BulletRect.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geometry) { return geometry.type === 'interval'; }); }; return BulletRect; }()); exports.default = BulletRect; },{"../../../util/bbox":672,"@antv/util":803,"tslib":894}],471:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var BulletTarget = /** @class */ (function () { function BulletTarget(view, cfg) { this.view = view; this.cfg = cfg; this._init(); } /** 绘制辅助labels */ BulletTarget.prototype.draw = function () { if (!this.view || this.view.destroyed) { return; } this.container = this.view.foregroundGroup.addGroup(); this.container.set('name', 'targetGroups'); var shapes = util_1.map(this.getGeometry().elements, function (element) { return element.shape; }); for (var i = 0; i < this.cfg.targets.length; i += 1) { var shapeBox = shapes[i].getBBox(); var widthRatio = shapeBox.width / shapes[i].get('origin').data[this.cfg.yField]; this.drawTarget(shapeBox, this.cfg.targets[i], widthRatio); } this.view.canvas.draw(); }; BulletTarget.prototype.drawTarget = function (box, targets, widthRatio) { var _this = this; var options = this.cfg; var colors = options.markerColors; /** 添加目标值 */ targets.forEach(function (target, i) { var markerStyle = options.markerStyle; _this.container.addShape('rect', { name: 'bullet-target', attrs: tslib_1.__assign(tslib_1.__assign({ width: markerStyle.width, height: box.height * options.markerSize - markerStyle.width / 2, x: box.minX + target * widthRatio, y: box.minY - (box.height * (options.markerSize - 1)) / 2 }, markerStyle), { fill: colors[i % colors.length] || markerStyle.fill }), }); }); }; BulletTarget.prototype.clear = function () { if (this.container) { this.container.clear(); } }; BulletTarget.prototype.destroy = function () { if (this.container) { this.container.remove(); } }; BulletTarget.prototype._init = function () { var _this = this; this.view.on('beforerender', function () { _this.clear(); }); this.view.on('afterrender', function () { _this.draw(); }); }; BulletTarget.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geometry) { return geometry.type === 'interval'; }); }; return BulletTarget; }()); exports.default = BulletTarget; },{"@antv/util":803,"tslib":894}],472:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { bullet: 'interval', bulletTarget: 'bullet-target', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],473:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Bullet = /** @class */ (function (_super) { tslib_1.__extends(Bullet, _super); function Bullet() { return _super !== null && _super.apply(this, arguments) || this; } Bullet.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'bullet'; _super.prototype.createLayers.call(this, layerProps); }; Bullet.getDefaultOptions = layer_1.default.getDefaultOptions; return Bullet; }(plot_1.default)); exports.default = Bullet; },{"../../base/plot":394,"./layer":474,"@antv/util":803,"tslib":894}],474:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Y_FIELD = exports.X_FIELD = exports.STACK_FIELD = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var EventParser = tslib_1.__importStar(require("./event")); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var scale_1 = require("../../util/scale"); var factory_1 = require("../../components/factory"); var factory_2 = require("../../geoms/factory"); var global_1 = require("../../base/global"); var bulletRect_1 = tslib_1.__importDefault(require("./component/bulletRect")); var bulletTarget_1 = tslib_1.__importDefault(require("./component/bulletTarget")); require("./theme"); var G2_GEOM_MAP = { bullet: 'interval', }; var PLOT_GEOM_MAP = { interval: 'bullet', }; exports.STACK_FIELD = '$$stackField$$'; exports.X_FIELD = '$$xField$$'; exports.Y_FIELD = '$$yField$$'; var BulletLayer = /** @class */ (function (_super) { tslib_1.__extends(BulletLayer, _super); function BulletLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'bullet'; return _this; } BulletLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { data: [], stackField: exports.STACK_FIELD, xField: exports.X_FIELD, yField: exports.Y_FIELD, rangeColors: ['rgba(91, 143, 249, 0.45)'], measureSize: 12, rangeSize: 2, markerSize: 2, markerColors: [], markerStyle: { width: 2, fill: '#5B8FF9', lineWidth: 0, }, axis: { visible: false, position: 'before', tickCount: 6, formatter: function (text, idx) { return "" + idx; }, style: { fill: 'rgba(0, 0, 0, 0.25)', textBaseline: 'middle', textAlign: 'center', fontSize: 12, lineHeight: 16, }, tickLine: { visible: true, lineWidth: 1, stroke: '#FFF', lineDash: [4, 2], }, }, xAxis: { visible: true, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, }, }, yAxis: { visible: false, nice: false, }, tooltip: { visible: false, trigger: 'item', crosshairs: false, }, label: { visible: true, offset: 4, style: { fill: 'rgba(0, 0, 0, 0.45)', stroke: '#fff', lineWidth: 1, }, }, }); }; BulletLayer.prototype.afterRender = function () { _super.prototype.afterRender.call(this); this.view.removeInteraction('legend-filter'); }; BulletLayer.prototype.scale = function () { var options = this.options; var scales = {}; /** 配置y-scale */ scales[options.yField] = {}; if (util_1.has(options, 'yAxis')) { scale_1.extractScale(scales[options.yField], options.yAxis); } /** 配置x-scale */ scales[options.xField] = { type: 'cat', }; if (util_1.has(options, 'xAxis')) { scale_1.extractScale(scales[options.xField], options.xAxis); } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; BulletLayer.prototype.getOptions = function (props) { var options = _super.prototype.getOptions.call(this, props); this.adjustOptions(options); return options; }; BulletLayer.prototype.afterInit = function () { _super.prototype.afterInit.call(this); var options = this.options; var ranges = options.data.map(function (d) { return d.ranges; }); var targets = options.data.map(function (d) { return d.targets; }); this.bulletRect = new bulletRect_1.default(this.view, { ranges: ranges, rangeMax: options.rangeMax, yField: options.yField, rangeSize: options.rangeSize, rangeColors: options.rangeColors || [], axis: options.axis, }); this.bulletTarget = new bulletTarget_1.default(this.view, { targets: targets, yField: options.yField, markerSize: options.markerSize, markerColors: options.markerColors || [], markerStyle: options.markerStyle, }); }; BulletLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; BulletLayer.prototype.coord = function () { this.setConfig('coordinate', { actions: [['transpose']], }); }; /** 自定义子弹图图例 */ BulletLayer.prototype.legend = function () { var options = this.options; var markerColor = options.markerStyle.fill; var measureColors = options.measureColors || this.theme.colors; var items = [ { name: '实际进度', value: '实际进度', marker: { symbol: 'square', style: { fill: measureColors[0], }, }, }, { name: '目标值', value: '目标值', marker: { symbol: 'line', style: { stroke: markerColor, lineWidth: 2, }, }, }, ]; var legendOptions = tslib_1.__assign({ custom: true, position: 'bottom', items: items }, options.legend); // @ts-ignore this.setConfig('legends', legendOptions); }; BulletLayer.prototype.addGeometry = function () { var options = this.options; var bullet = factory_2.getGeom('interval', 'main', { positionFields: [options.xField, options.yField], plot: this, }); bullet.adjust = [ { type: 'stack', }, ]; if (options.label) { bullet.label = this.extractLabel(); } this.bullet = bullet; this.setConfig('geometry', bullet); }; BulletLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; BulletLayer.prototype.extractLabel = function () { var options = this.options; var label = util_1.deepMix({}, options.label); if (label.visible === false) { return false; } var labelConfig = factory_1.getComponent('label', tslib_1.__assign({ plot: this, labelType: 'barLabel', fields: [options.yField] }, label)); return labelConfig; }; BulletLayer.prototype.adjustOptions = function (options) { options.barSize = options.measureSize || 12; this.adjustYAxisOptions(options); }; BulletLayer.prototype.adjustYAxisOptions = function (options) { var values = []; options.data.forEach(function (d) { return values.push(d.measures.reduce(function (a, b) { return a + b; }, 0)); }); values.push(options.rangeMax); options.yAxis.max = Math.max.apply([], values); }; BulletLayer.prototype.processData = function (dataOptions) { var options = this.options; var data = []; dataOptions.forEach(function (dataItem, dataIdx) { var _a; for (var valueIdx = 0; valueIdx < dataItem.measures.length; valueIdx += 1) { var value = dataItem.measures[valueIdx]; var xField = dataItem.title || "" + dataIdx; data.push((_a = {}, _a[options.xField] = xField, _a[options.yField] = value, _a[options.stackField] = "" + valueIdx, _a)); } }); return data; }; return BulletLayer; }(view_layer_1.default)); exports.default = BulletLayer; global_1.registerPlotType('bullet', BulletLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../geoms/factory":430,"../../util/scale":712,"./component/bulletRect":470,"./component/bulletTarget":471,"./event":472,"./theme":475,"@antv/util":803,"tslib":894}],475:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var BULLET_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5, lineWidth: 0 }; }; var BULLET_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; theme_1.registerTheme('bullet', { columnStyle: { normal: {}, active: BULLET_ACTIVE_STYLE, disable: BULLET_DISABLE_STYLE, selected: {}, }, }); },{"../../theme":669}],476:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WEEKS = exports.MONTHS = exports.FORMATTER = exports.IS_MONTH_CENTER_FIELD = exports.DATE_FIELD = exports.WEEK_FIELD = exports.DAY_FIELD = void 0; /** * 当前一周中的第几天(周日 = 0) */ exports.DAY_FIELD = '$$day$$'; /** * 当前是一年中的第几周 */ exports.WEEK_FIELD = '$$week$$'; /** * 日期字段,Date 类型 */ exports.DATE_FIELD = '$$date$$'; /** * 数据处理阶段,标记这周是否是当月中间 */ exports.IS_MONTH_CENTER_FIELD = '$$is_month_center$$'; /** * 格式化日期 */ exports.FORMATTER = 'YYYY-MM-DD'; /** * 月份枚举 */ exports.MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; /** * 周枚举 */ exports.WEEKS = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; },{}],477:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { rect: 'polygon', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],478:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); // 注册日历图的自定义 shape require("./shape"); /** * 日历图 */ var Calendar = /** @class */ (function (_super) { tslib_1.__extends(Calendar, _super); function Calendar() { return _super !== null && _super.apply(this, arguments) || this; } /** * 复写父类方法 * @param props */ Calendar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'calendar'; _super.prototype.createLayers.call(this, layerProps); }; Calendar.getDefaultOptions = layer_1.default.getDefaultOptions; return Calendar; }(plot_1.default)); exports.default = Calendar; },{"../../base/plot":394,"./layer":479,"./shape":480,"@antv/util":803,"tslib":894}],479:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var fecha_1 = tslib_1.__importDefault(require("fecha")); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var constant_1 = require("./constant"); var util_2 = require("./util"); var global_1 = require("../../base/global"); var date_1 = require("../../util/date"); var factory_1 = require("../../components/factory"); var EventParser = tslib_1.__importStar(require("./event")); /** * 日历图 */ var CalendarLayer = /** @class */ (function (_super) { tslib_1.__extends(CalendarLayer, _super); function CalendarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'calendar'; return _this; } CalendarLayer.getDefaultOptions = function () { var _a; return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { line: { visible: false, }, grid: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoRotate: false, autoHide: false, }, }, yAxis: { line: { visible: false, }, grid: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoRotate: false, autoHide: false, }, }, legend: { visible: false }, meta: (_a = {}, _a[constant_1.DAY_FIELD] = { type: 'cat', alias: 'Day', values: [0, 1, 2, 3, 4, 5, 6], }, _a[constant_1.WEEK_FIELD] = { type: 'cat', alias: 'Month', }, _a), tooltip: { visible: true, showTitle: true, showCrosshairs: false, showMarkers: false, title: 'date', }, }); }; /** * 复写父类的数据处理类,主要完成: * 1. 生成 polygon 的 x y field(虚拟的,无需用户传入) * * @param data */ CalendarLayer.prototype.processData = function (data) { var dateField = this.options.dateField; var dateRange = this.options.dateRange; // 给与默认值是当前这一年 if (util_1.isNil(dateRange)) { var dates = util_1.map(data, function (datum) { return fecha_1.default.parse("" + datum[dateField], constant_1.FORMATTER); }); dateRange = date_1.getDateRange(dates); } return util_2.generateCalendarData(data, dateRange, dateField); }; CalendarLayer.prototype.addGeometry = function () { var _a = this.options, valueField = _a.valueField, colors = _a.colors, tooltip = _a.tooltip; var polygonConfig = { type: 'polygon', position: { fields: [constant_1.WEEK_FIELD, constant_1.DAY_FIELD], }, shape: { values: ['calendar-polygon'], }, color: { fields: [valueField], values: colors, }, label: this.extractLabel(), }; if (tooltip && (tooltip.fields || tooltip.formatter)) { this.geometryTooltip(polygonConfig); } this.setConfig('geometry', polygonConfig); }; CalendarLayer.prototype.geometryTooltip = function (geomConfig) { geomConfig.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { geomConfig.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { geomConfig.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { geomConfig.tooltip.fields = [constant_1.WEEK_FIELD, constant_1.DAY_FIELD]; } } }; CalendarLayer.prototype.extractLabel = function () { var props = this.options; var label = props.label; if (label && label.visible === false) { return false; } var valueField = this.options.valueField; return factory_1.getComponent('label', tslib_1.__assign({ plot: this, fields: [valueField], position: 'top', offset: 0 }, label)); }; /** * 写入坐标系配置,默认增加镜像 */ CalendarLayer.prototype.coord = function () { // 默认做镜像处理 var coordinateConfig = { type: 'rect', cfg: {}, actions: [['reflect', 'y']], }; this.setConfig('coordinate', coordinateConfig); }; /** * 无需 geometry parser,直接使用 polygon 即可 */ CalendarLayer.prototype.geometryParser = function () { return ''; }; CalendarLayer.prototype.axis = function () { var xAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'x', }); var yAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'y', }); var axesConfig = {}; axesConfig[constant_1.WEEK_FIELD] = xAxis_parser; axesConfig[constant_1.DAY_FIELD] = yAxis_parser; /** 存储坐标轴配置项到config */ this.setConfig('axes', axesConfig); }; CalendarLayer.prototype.scale = function () { _super.prototype.scale.call(this); var monthWeek = util_2.getMonthCenterWeek(this.options.dateRange); // 拿出 scale 二次加工,主要是配置 x y 中的标题显示 var scales = this.config.scales; var _a = this.options, _b = _a.weeks, weeks = _b === void 0 ? constant_1.WEEKS : _b, _c = _a.months, months = _c === void 0 ? constant_1.MONTHS : _c; var x = scales[constant_1.WEEK_FIELD]; var y = scales[constant_1.DAY_FIELD]; // 1. 设置 formatter x.formatter = function (v) { var m = monthWeek[v]; return m !== undefined ? months[m] : ''; }; y.formatter = function (v) { return weeks[v] || ''; }; // 2. 设置 alias var _d = this.options, xAxis = _d.xAxis, yAxis = _d.yAxis; x.alias = util_1.get(xAxis, ['title', 'text'], x.alias); y.alias = util_1.get(yAxis, ['title', 'text'], y.alias); this.setConfig('scales', scales); }; CalendarLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; return CalendarLayer; }(view_layer_1.default)); exports.default = CalendarLayer; // 注册到池子中 global_1.registerPlotType('calendar', CalendarLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../util/date":676,"./constant":476,"./event":477,"./util":481,"@antv/util":803,"fecha":881,"tslib":894}],480:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var g2_1 = require("@antv/g2"); var constant_1 = require("./constant"); var date_1 = require("../../util/date"); /** * 注册自定义日历图的 shape * code from https://g2.antv.vision/zh/examples/heatmap/heatmap#calendar-horizontal */ g2_1.registerShape('polygon', 'calendar-polygon', { draw: function (cfg, container) { if (!util_1.isEmpty(cfg.points)) { var points = cfg.points; // rect path var path = [ ['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['L', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['Z'], ]; path = this.parsePath(path); var attrs = tslib_1.__assign(tslib_1.__assign({ stroke: '#fff', lineWidth: 1, fill: cfg.color }, cfg.style), { path: path }); var polygon = container.addShape('path', { attrs: attrs, }); var date = cfg.data[constant_1.DATE_FIELD]; if (date_1.isLastWeekOfMonth(date)) { var linePath = [ ['M', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ]; // 最后一周的多边形添加右侧边框 container.addShape('path', { zIndex: 1, attrs: { path: this.parsePath(linePath), lineWidth: 1, stroke: '#404040', }, }); if (date_1.isLastDayOfMonth(date)) { container.addShape('path', { zIndex: 1, attrs: { path: this.parsePath([ ['M', points[1].x, points[1].y], ['L', points[2].x, points[2].y], ]), lineWidth: 1, stroke: '#404040', }, }); } } container.sort(); return polygon; } }, }); },{"../../util/date":676,"./constant":476,"@antv/g2":309,"@antv/util":803,"tslib":894}],481:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMonthCenterWeek = exports.generateCalendarData = void 0; var tslib_1 = require("tslib"); var fecha_1 = tslib_1.__importDefault(require("fecha")); var util_1 = require("@antv/util"); var constant_1 = require("./constant"); var date_1 = require("../../util/date"); /** * 解析日期 * @param dateRange */ function parseDateRange(dateRange) { var _a; var from = dateRange[0], to = dateRange[1]; var fromDate = fecha_1.default.parse(from, constant_1.FORMATTER); var toDate = fecha_1.default.parse(to, constant_1.FORMATTER); // 交换顺序 if (fromDate > toDate) { _a = [fromDate, toDate], toDate = _a[0], fromDate = _a[1]; } return [fromDate, toDate]; } /** * 根据 range 补齐日历图的数据 * @param data 传入数据 * @param dateRange 日期区间 * @param dateField 日期字段 */ function generateCalendarData(data, dateRange, dateField) { var all = []; var _a = parseDateRange(dateRange), fromDate = _a[0], toDate = _a[1]; // copy 一份 var curr = new Date(fromDate); var _loop_1 = function () { var _a; var dateString = fecha_1.default.format(curr, constant_1.FORMATTER); // 找到对应的数据 var datum = util_1.find(data, function (datum) { return datum[dateField] === dateString; }); all.push(tslib_1.__assign((_a = {}, _a[constant_1.DAY_FIELD] = date_1.getDay(curr), _a[constant_1.WEEK_FIELD] = "" + date_1.getWeek(curr), _a[dateField] = dateString, _a[constant_1.DATE_FIELD] = new Date(curr), _a), datum)); // 向前移动一天 date_1.advanceBy(curr, date_1.DAY_MS); }; while (curr <= toDate) { _loop_1(); } return all; } exports.generateCalendarData = generateCalendarData; /** * 计算每个月的中间周。 */ function getMonthCenterWeek(dateRange) { var _a = parseDateRange(dateRange), fromDate = _a[0], toDate = _a[1]; var monthWeekMap = new Map(); function append(current) { var month = current.getMonth(); // 从 0 开始 var week = date_1.getWeek(current); if (!monthWeekMap.has(month)) { monthWeekMap.set(month, []); } monthWeekMap.get(month).push(week); } // copy 一份 var curr = new Date(fromDate); while (curr <= toDate) { // 设置到 map 中 append(curr); // 向前移动 7 天(一周) date_1.advanceBy(curr, date_1.DAY_MS * 7); } // 增加最后一个日期的计算 if (toDate < curr) { append(toDate); } // 处理数据,返回结果 var result = {}; // week -> month monthWeekMap.forEach(function (v, k) { var w = Math.ceil((util_1.head(v) + util_1.last(v)) / 2); // 取平均值 result[w] = k; }); return result; } exports.getMonthCenterWeek = getMonthCenterWeek; },{"../../util/date":676,"./constant":476,"@antv/util":803,"fecha":881,"tslib":894}],482:[function(require,module,exports){ arguments[4][450][0].apply(exports,arguments) },{"../../../util/responsive/apply/axis":682,"dup":450,"tslib":894}],483:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var axis_1 = tslib_1.__importDefault(require("./axis")); var label_1 = tslib_1.__importDefault(require("./label")); var preRenderResponsive = []; var afterRenderResponsive = [ { name: 'responsiveAxis', method: axis_1.default }, { name: 'responsiveLabel', method: label_1.default }, ]; exports.default = { preRender: preRenderResponsive, afterRender: afterRenderResponsive, }; },{"./axis":482,"./label":484,"tslib":894}],484:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var label_1 = tslib_1.__importDefault(require("../../../util/responsive/apply/label")); var ApplyResponsiveColumnLabel = /** @class */ (function (_super) { tslib_1.__extends(ApplyResponsiveColumnLabel, _super); function ApplyResponsiveColumnLabel() { return _super !== null && _super.apply(this, arguments) || this; } ApplyResponsiveColumnLabel.prototype.getType = function () { return util_1.get(this.plot.options, ['label', 'position'], 'inner'); }; return ApplyResponsiveColumnLabel; }(label_1.default)); function responsivePointLabel(layer) { var responsiveTheme = layer.getResponsiveTheme(); new ApplyResponsiveColumnLabel({ plot: layer, responsiveTheme: responsiveTheme, }); } exports.default = responsivePointLabel; },{"../../../util/responsive/apply/label":684,"@antv/util":803,"tslib":894}],485:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../../util/responsive/theme"); /** 组装theme */ var columnTheme = { label: { top: { constraints: [{ name: 'elementCollision' }], rules: { elementCollision: [ { name: 'nodeJitterUpward' }, { name: 'nodesResamplingByState', option: { keep: ['min', 'max', 'median'], }, }, { name: 'textHide', }, ], }, }, }, }; theme_1.registerResponsiveTheme('column', columnTheme); },{"../../../util/responsive/theme":711}],486:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../../../components/label/base"); var dependents_1 = require("../../../dependents"); var label_1 = tslib_1.__importDefault(require("./label")); var view_1 = require("../../../util/view"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var color_1 = require("../../../util/color"); /** 自动模式的 Column 数据标签,会根据图形和数据标签自动优化数据标签布局和样式等 */ var ColumnAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(ColumnAutoLabel, _super); function ColumnAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } ColumnAutoLabel.prototype.getPosition = function (element) { var offset = this.getDefaultOffset(); var value = this.getValue(element); var bbox = this.getElementShapeBBox(element); var minX = bbox.minX, minY = bbox.minY, maxY = bbox.maxY, width = bbox.width; var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY; var x = minX + width / 2 + offsetX; var dir = value > 0 ? -1 : 1; var root = value > 0 ? minY : maxY; var y = root + offset * dir + offsetY; // 默认全部先设置为 top return { x: x, y: y }; }; /** 默认的 fill 取自用户配置或主题配置 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars ColumnAutoLabel.prototype.getTextFill = function (element) { var style = this.options.style; return style.fill; }; /** 默认不描边 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars ColumnAutoLabel.prototype.getTextStroke = function (element) { return undefined; }; /** 默认无处理:在 layout 阶段处理 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars ColumnAutoLabel.prototype.adjustLabel = function (label, element) { // empty }; /** 自动布局所有的数据标签 */ ColumnAutoLabel.prototype.layoutLabels = function (geometry, labels) { if (this.shouldInShapeLabels(labels)) { this.inShapeLabels(geometry, labels); } this.autoHideLabels(geometry, labels); }; /** 判断是否可以把数据标签放置在柱子内部 */ ColumnAutoLabel.prototype.shouldInShapeLabels = function (labels) { var _this = this; return util_1.every(labels, function (label) { var labelBBox = label.getBBox(); var element = label.get('element'); var bbox = _this.getElementShapeBBox(element); return bbox.width >= labelBBox.width; }); }; /** 内置数据标签,并自动设置颜色描边等属性 */ ColumnAutoLabel.prototype.inShapeLabels = function (geometry, labels) { var _this = this; var coordinateBBox = this.getCoordinateBBox(); var xField = geometry.getXYFields()[0]; var _a = this.options, darkStyle = _a.darkStyle, lightStyle = _a.lightStyle; var groupedLabels = util_1.groupBy(labels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; }); util_1.each(labels, function (label) { var curGroup = groupedLabels[label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]] || []; var element = label.get('element'); var shape = element.shape; var fillWhite = color_1.isContrastColorWhite(shape.attr('fill')); var shapeBBox = _this.getElementShapeBBox(element); var labelBBox = bbox_1.default.fromBBoxObject(label.getBBox()); // 如果 Column 本身就不可见,直接隐藏对应的 label if (view_1.getOverlapArea(coordinateBBox, shapeBBox) <= 0) { label.set('visible', false); } if (labelBBox.height > shapeBBox.height) { // 处理放不下的情况 var idx = util_1.findIndex(curGroup, function (item) { return item === label; }); if (idx !== 0) { label.set('visible', false); } } else { // 数据标签展示在图形中央 label.attr({ y: shapeBBox.y + shapeBBox.height / 2, textBaseline: 'middle', }); var overflow = labelBBox.width > shapeBBox.width || labelBBox.height > shapeBBox.height; if (overflow) { // 出现了溢出情况,添加描边 label.attr({ stroke: lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.stroke, }); } else { // 放置在柱形内部,颜色取反 label.attr({ fill: fillWhite ? lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.fill : darkStyle === null || darkStyle === void 0 ? void 0 : darkStyle.fill, fillOpacity: fillWhite ? lightStyle === null || lightStyle === void 0 ? void 0 : lightStyle.fillOpacity : darkStyle === null || darkStyle === void 0 ? void 0 : darkStyle.fillOpacity, stroke: undefined, }); } } }); }; /** 数据标签防重叠抽样 */ ColumnAutoLabel.prototype.autoHideLabels = function (geometry, labels) { var coordinateBBox = this.getCoordinateBBox(); var filteredLabels = this.filterLabels(labels); var xField = geometry.getXYFields()[0]; var dones = []; var todo = []; var groupedLabels = util_1.groupBy(filteredLabels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; }); var xValues = util_1.uniq(util_1.map(filteredLabels, function (label) { return label.get(dependents_1.ORIGIN)[dependents_1.FIELD_ORIGIN][xField]; })); var xValue; if (util_1.size(xValues) > 0) { // 第一组 xValue = xValues.shift(); util_1.each(groupedLabels[xValue], function (label) { return todo.push(label); }); } if (util_1.size(xValues) > 0) { // 最后一组 xValue = xValues.pop(); util_1.each(groupedLabels[xValue], function (label) { return todo.push(label); }); } util_1.each(xValues.reverse(), function (val) { // 其他组 util_1.each(groupedLabels[val], function (label) { return todo.push(label); }); }); while (todo.length > 0) { var cur = todo.shift(); if (cur.get('visible')) { view_1.moveInPanel(cur, coordinateBBox); if (view_1.checkShapeOverlap(cur, dones)) { cur.set('visible', false); } else { dones.push(cur); } } } }; /** 抽样数据标签,设置最大数量的数据标签,其他的统一隐藏 */ ColumnAutoLabel.prototype.filterLabels = function (labels) { var MAX_CNT = 500; // 最多显示 500 个数据标签 var filteredLabels = []; var pages = Math.max(Math.floor(labels.length / MAX_CNT), 1); util_1.each(labels, function (label, idx) { if (idx % pages === 0) { filteredLabels.push(label); } else { label.set('visible', false); } }); return filteredLabels; }; return ColumnAutoLabel; }(label_1.default)); exports.default = ColumnAutoLabel; base_1.registerLabelComponent('column-auto', ColumnAutoLabel); },{"../../../components/label/base":414,"../../../dependents":425,"../../../util/bbox":672,"../../../util/color":673,"../../../util/view":715,"./label":487,"@antv/util":803,"tslib":894}],487:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../../dependents"); var base_1 = tslib_1.__importStar(require("../../../components/label/base")); var color_1 = require("../../../util/color"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var ColumnLabel = /** @class */ (function (_super) { tslib_1.__extends(ColumnLabel, _super); function ColumnLabel() { return _super !== null && _super.apply(this, arguments) || this; } ColumnLabel.prototype.getLabelItemAttrs = function (element, index) { var _a; var _b; var _c = this.options, style = _c.style, formatter = _c.formatter; var mappingData = [].concat(element.getModel().mappingData); var value = this.getValue(element); return util_1.deepMix({}, style, tslib_1.__assign(tslib_1.__assign({}, this.getPosition(element)), { text: formatter ? formatter(value, (_a = {}, _a[dependents_1._ORIGIN] = (_b = mappingData[0]) === null || _b === void 0 ? void 0 : _b._origin, _a.mappingDatum = mappingData[0], _a.mappingDatumIndex = 0, _a.element = element, _a.elementIndex = index, _a), index) : value, fill: this.getTextFill(element), stroke: this.getTextStroke(element), textAlign: this.getTextAlign(), textBaseline: this.getTextBaseLine() })); }; ColumnLabel.prototype.getDefaultOptions = function () { var theme = this.layer.theme; var _a = theme.label, label = _a === void 0 ? {} : _a; return tslib_1.__assign({ offsetX: 0, offsetY: 0, adjustPosition: true }, label); }; ColumnLabel.prototype.adjustLabel = function (label, element) { var adjustPosition = this.options.adjustPosition; if (adjustPosition) { var offset = this.getDefaultOffset(); var labelRange = label.getBBox(); var shapeRange = this.getElementShapeBBox(element); if (shapeRange.height <= labelRange.height) { var yPosition = shapeRange.minY + this.options.offsetY - offset; label.attr('y', yPosition); label.attr('textBaseline', 'bottom'); label.attr('fill', this.options.style.fill); } } }; ColumnLabel.prototype.getValue = function (element) { return util_1.get(element.getData(), this.layer.options.yField); }; ColumnLabel.prototype.getPosition = function (element) { var offset = this.getDefaultOffset(); var value = this.getValue(element); var bbox = this.getElementShapeBBox(element); var minX = bbox.minX, minY = bbox.minY, maxY = bbox.maxY, height = bbox.height, width = bbox.width; var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY, position = _a.position; var x = minX + width / 2 + offsetX; var dir = value > 0 ? -1 : 1; var y; if (position === 'top') { var root = value > 0 ? minY : maxY; y = root + offset * dir + offsetY; } else if (position === 'bottom') { var root = value > 0 ? maxY : minY; y = root + offset * dir + offsetY; } else { y = minY + height / 2 + offsetY; } return { x: x, y: y }; }; ColumnLabel.prototype.getTextFill = function (element) { var shape = element.shape; if (this.options.adjustColor && this.options.position !== 'top') { var shapeColor = shape.attr('fill'); var shapeOpacity = shape.attr('opacity') ? shape.attr('opacity') : 1; var rgb = color_1.rgb2arr(shapeColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / shapeOpacity; var colorBand = [ { from: 0, to: 85, color: 'white' }, { from: 85, to: 170, color: '#F6F6F6' }, { from: 170, to: 255, color: 'black' }, ]; var reflect = color_1.mappingColor(colorBand, gray); return reflect; } var defaultColor = this.options.style.fill; return defaultColor; }; ColumnLabel.prototype.getTextStroke = function (element) { var fill = this.getTextFill(element); var _a = this.options, position = _a.position, adjustColor = _a.adjustColor; return position !== 'top' && adjustColor && fill !== 'black' ? null : undefined; }; ColumnLabel.prototype.getElementShapeBBox = function (element) { var _this = this; var shape = element.shape; var points = []; util_1.each(shape.get('origin').points, function (p) { points.push(_this.coord.convertPoint(p)); }); var xValues = points.map(function (point) { return point.x; }); var xValuesMin = Math.min.apply(Math, xValues); var xValueMax = Math.max.apply(Math, xValues); var yValues = points.map(function (point) { return point.y; }); var yValuesMin = Math.min.apply(Math, yValues); var yValuesMax = Math.max.apply(Math, yValues); var bbox = new bbox_1.default(xValuesMin, yValuesMin, xValueMax - xValuesMin, yValuesMax - yValuesMin); return bbox; }; ColumnLabel.prototype.getTextAlign = function () { return 'center'; }; ColumnLabel.prototype.getTextBaseLine = function () { return 'middle'; }; ColumnLabel.prototype.getLabelOffset = function () { // Column 的 offset 在 getPosition 中因 position 不同单独处理 return { x: 0, y: 0, }; }; return ColumnLabel; }(base_1.default)); exports.default = ColumnLabel; base_1.registerLabelComponent('column', ColumnLabel); },{"../../../components/label/base":414,"../../../dependents":425,"../../../util/bbox":672,"../../../util/color":673,"@antv/util":803,"tslib":894}],488:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { column: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],489:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Column = /** @class */ (function (_super) { tslib_1.__extends(Column, _super); function Column() { return _super !== null && _super.apply(this, arguments) || this; } Column.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'column'; _super.prototype.createLayers.call(this, layerProps); }; Column.getDefaultOptions = layer_1.default.getDefaultOptions; return Column; }(plot_1.default)); exports.default = Column; },{"../../base/plot":394,"./layer":490,"@antv/util":803,"tslib":894}],490:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); var conversion_tag_1 = tslib_1.__importDefault(require("../../components/conversion-tag")); var scale_1 = require("../../util/scale"); var apply_responsive_1 = tslib_1.__importDefault(require("./apply-responsive")); require("./apply-responsive/theme"); require("./component/label"); require("./component/label-auto"); var EventParser = tslib_1.__importStar(require("./event")); require("./theme"); var view_1 = require("../../util/view"); var G2_GEOM_MAP = { column: 'interval', }; var PLOT_GEOM_MAP = { interval: 'column', }; var BaseColumnLayer = /** @class */ (function (_super) { tslib_1.__extends(BaseColumnLayer, _super); function BaseColumnLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'column'; return _this; } BaseColumnLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, tickLine: { visible: false, }, title: { visible: true, }, }, yAxis: { nice: true, title: { visible: true, }, label: { visible: true, }, grid: { visible: true, }, }, tooltip: { visible: true, shared: true, showCrosshairs: false, showMarkers: false, }, label: { visible: false, position: 'top', adjustColor: true, }, legend: { visible: true, position: 'top-left', }, interactions: [ { type: 'tooltip' }, { type: 'active-region' }, { type: 'legend-active' }, { type: 'legend-filter' }, ], conversionTag: { visible: false, }, }); }; BaseColumnLayer.prototype.beforeInit = function () { _super.prototype.beforeInit.call(this); /** 响应式图形 */ if (this.options.responsive && this.options.padding !== 'auto') { this.applyResponsive('preRender'); } }; BaseColumnLayer.prototype.afterRender = function () { var props = this.options; this.renderLabel(); /** 响应式 */ if (this.options.responsive && this.options.padding !== 'auto') { this.applyResponsive('afterRender'); } if (props.conversionTag.visible) { this.conversionTag = new conversion_tag_1.default(tslib_1.__assign({ view: this.view, field: props.yField, transpose: true, animation: props.animation === false ? false : true }, props.conversionTag)); } _super.prototype.afterRender.call(this); }; BaseColumnLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; BaseColumnLayer.prototype.processData = function (originData) { var xField = this.options.xField; var processedData = []; util_1.each(originData, function (data) { var d = util_1.clone(data); d[xField] = d[xField].toString(); processedData.push(d); }); return processedData; }; BaseColumnLayer.prototype.scale = function () { var options = this.options; var scales = {}; /** 配置x-scale */ scales[options.xField] = { type: 'cat' }; if (util_1.has(options, 'xAxis')) { scale_1.extractScale(scales[options.xField], options.xAxis); } /** 配置y-scale */ scales[options.yField] = {}; if (util_1.has(options, 'yAxis')) { scale_1.extractScale(scales[options.yField], options.yAxis); } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; BaseColumnLayer.prototype.coord = function () { return; }; //eslint-disable-next-line @typescript-eslint/no-unused-vars BaseColumnLayer.prototype.adjustColumn = function (column) { return; }; BaseColumnLayer.prototype.addGeometry = function () { var options = this.options; var column = factory_1.getGeom('interval', 'main', { positionFields: [options.xField, options.yField], plot: this, }); if (options.conversionTag.visible) { this.setConfig('theme', util_1.deepMix({}, this.getTheme(), { columnWidthRatio: 1 / 3, })); } this.adjustColumn(column); this.column = column; if (options.tooltip && (options.tooltip.fields || options.tooltip.formatter)) { this.geometryTooltip(); } this.setConfig('geometry', column); }; BaseColumnLayer.prototype.geometryTooltip = function () { this.column.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.column.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.column.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.column.tooltip.fields = [this.options.xField, this.options.yField]; if (this.options.colorField) { this.column.tooltip.fields.push(this.options.colorField); } } } }; BaseColumnLayer.prototype.animation = function () { _super.prototype.animation.call(this); if (this.options.animation === false) { /** 关闭动画 */ this.column.animate = false; } }; BaseColumnLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; BaseColumnLayer.prototype.renderLabel = function () { var scales = this.config.scales; var _a = this.options, label = _a.label, yField = _a.yField; var scale = scales[yField]; if (label === null || label === void 0 ? void 0 : label.visible) { var geometry = view_1.getGeometryByType(this.view, 'interval'); this.doRenderLabel(geometry, tslib_1.__assign({ type: 'column', formatter: scale.formatter && (function (value) { return scale.formatter(value); }) }, this.options.label)); } }; BaseColumnLayer.prototype.applyResponsive = function (stage) { var _this = this; var methods = apply_responsive_1.default[stage]; util_1.each(methods, function (r) { var responsive = r; responsive.method(_this); }); }; return BaseColumnLayer; }(view_layer_1.default)); exports.default = BaseColumnLayer; global_1.registerPlotType('column', BaseColumnLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/conversion-tag":410,"../../geoms/factory":430,"../../util/scale":712,"../../util/view":715,"./apply-responsive":483,"./apply-responsive/theme":485,"./component/label":487,"./component/label-auto":486,"./event":488,"./theme":491,"@antv/util":803,"tslib":894}],491:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_COLUMN_THEME = void 0; var theme_1 = require("../../theme"); var COLUMN_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var COLUMN_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5, fillOpacity: opacity * 0.5 }; }; exports.DEFAULT_COLUMN_THEME = { label: { darkStyle: { fill: '#2c3542', stroke: '#ffffff', fillOpacity: 0.85, }, lightStyle: { fill: '#ffffff', stroke: '#ffffff', fillOpacity: 1, }, }, columnStyle: { normal: {}, active: COLUMN_ACTIVE_STYLE, disable: COLUMN_DISABLE_STYLE, selected: { lineWidth: 1, stroke: 'black' }, }, }; theme_1.registerTheme('column', exports.DEFAULT_COLUMN_THEME); },{"../../theme":669}],492:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../grouped-bar/layer")); var GroupBar = /** @class */ (function (_super) { tslib_1.__extends(GroupBar, _super); function GroupBar() { return _super !== null && _super.apply(this, arguments) || this; } GroupBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'groupedBar'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "GroupedBar" instead of "GroupBar" which was not recommended.'); }; GroupBar.getDefaultOptions = layer_1.default.getDefaultOptions; return GroupBar; }(plot_1.default)); exports.default = GroupBar; },{"../../../base/plot":394,"../../grouped-bar/layer":529,"@antv/util":803,"tslib":894,"warning":895}],493:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../grouped-column/layer")); var GroupColumn = /** @class */ (function (_super) { tslib_1.__extends(GroupColumn, _super); function GroupColumn() { return _super !== null && _super.apply(this, arguments) || this; } GroupColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'groupedColumn'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "GroupedColumn" instead of "GroupColumn" which was not recommended.'); }; GroupColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return GroupColumn; }(plot_1.default)); exports.default = GroupColumn; },{"../../../base/plot":394,"../../grouped-column/layer":532,"@antv/util":803,"tslib":894,"warning":895}],494:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // 兼容 0.x的图表类型 var ring_1 = require("./ring"); Object.defineProperty(exports, "Ring", { enumerable: true, get: function () { return ring_1.default; } }); var group_column_1 = require("./group-column"); Object.defineProperty(exports, "GroupColumn", { enumerable: true, get: function () { return group_column_1.default; } }); var group_bar_1 = require("./group-bar"); Object.defineProperty(exports, "GroupBar", { enumerable: true, get: function () { return group_bar_1.default; } }); var percentage_stack_area_1 = require("./percentage-stack-area"); Object.defineProperty(exports, "PercentageStackArea", { enumerable: true, get: function () { return percentage_stack_area_1.default; } }); var percentage_stack_bar_1 = require("./percentage-stack-bar"); Object.defineProperty(exports, "PercentageStackBar", { enumerable: true, get: function () { return percentage_stack_bar_1.default; } }); var percentage_stack_column_1 = require("./percentage-stack-column"); Object.defineProperty(exports, "PercentageStackColumn", { enumerable: true, get: function () { return percentage_stack_column_1.default; } }); var stack_area_1 = require("./stack-area"); Object.defineProperty(exports, "StackArea", { enumerable: true, get: function () { return stack_area_1.default; } }); var stack_bar_1 = require("./stack-bar"); Object.defineProperty(exports, "StackBar", { enumerable: true, get: function () { return stack_bar_1.default; } }); var stack_column_1 = require("./stack-column"); Object.defineProperty(exports, "StackColumn", { enumerable: true, get: function () { return stack_column_1.default; } }); },{"./group-bar":492,"./group-column":493,"./percentage-stack-area":495,"./percentage-stack-bar":496,"./percentage-stack-column":497,"./ring":498,"./stack-area":499,"./stack-bar":500,"./stack-column":501}],495:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../percent-stacked-area/layer")); var PercentageStackArea = /** @class */ (function (_super) { tslib_1.__extends(PercentageStackArea, _super); function PercentageStackArea() { return _super !== null && _super.apply(this, arguments) || this; } PercentageStackArea.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'percentStackedArea'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "PercentStackedArea" instead of "PercentageStackArea" which was not recommended.'); }; PercentageStackArea.getDefaultOptions = layer_1.default.getDefaultOptions; return PercentageStackArea; }(plot_1.default)); exports.default = PercentageStackArea; },{"../../../base/plot":394,"../../percent-stacked-area/layer":570,"@antv/util":803,"tslib":894,"warning":895}],496:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../percent-stacked-bar/layer")); var PercentageStackBar = /** @class */ (function (_super) { tslib_1.__extends(PercentageStackBar, _super); function PercentageStackBar() { return _super !== null && _super.apply(this, arguments) || this; } PercentageStackBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'percentStackedBar'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "PercentStackedBar" instead of "PercentageStackBar" which was not recommended.'); }; PercentageStackBar.getDefaultOptions = layer_1.default.getDefaultOptions; return PercentageStackBar; }(plot_1.default)); exports.default = PercentageStackBar; },{"../../../base/plot":394,"../../percent-stacked-bar/layer":572,"@antv/util":803,"tslib":894,"warning":895}],497:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../percent-stacked-column/layer")); var PercentageStackColumn = /** @class */ (function (_super) { tslib_1.__extends(PercentageStackColumn, _super); function PercentageStackColumn() { return _super !== null && _super.apply(this, arguments) || this; } PercentageStackColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'percentStackedColumn'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "PercentStackedColumn" instead of "PercentageStackColumn" which was not recommended.'); }; PercentageStackColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return PercentageStackColumn; }(plot_1.default)); exports.default = PercentageStackColumn; },{"../../../base/plot":394,"../../percent-stacked-column/layer":574,"@antv/util":803,"tslib":894,"warning":895}],498:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../donut/layer")); var Ring = /** @class */ (function (_super) { tslib_1.__extends(Ring, _super); function Ring() { return _super !== null && _super.apply(this, arguments) || this; } Ring.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'donut'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "Donut" instead of "Ring" which was not recommended.'); }; Ring.getDefaultOptions = layer_1.default.getDefaultOptions; return Ring; }(plot_1.default)); exports.default = Ring; },{"../../../base/plot":394,"../../donut/layer":514,"@antv/util":803,"tslib":894,"warning":895}],499:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../stacked-area/layer")); var StackArea = /** @class */ (function (_super) { tslib_1.__extends(StackArea, _super); function StackArea() { return _super !== null && _super.apply(this, arguments) || this; } StackArea.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedArea'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "StackedArea" instead of "StackArea" which was not recommended.'); }; StackArea.getDefaultOptions = layer_1.default.getDefaultOptions; return StackArea; }(plot_1.default)); exports.default = StackArea; },{"../../../base/plot":394,"../../stacked-area/layer":613,"@antv/util":803,"tslib":894,"warning":895}],500:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../stacked-bar/layer")); var StackBar = /** @class */ (function (_super) { tslib_1.__extends(StackBar, _super); function StackBar() { return _super !== null && _super.apply(this, arguments) || this; } StackBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedBar'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "StackedBar" instead of "StackBar" which was not recommended.'); }; StackBar.getDefaultOptions = layer_1.default.getDefaultOptions; return StackBar; }(plot_1.default)); exports.default = StackBar; },{"../../../base/plot":394,"../../stacked-bar/layer":618,"@antv/util":803,"tslib":894,"warning":895}],501:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../../base/plot")); var warning_1 = tslib_1.__importDefault(require("warning")); var layer_1 = tslib_1.__importDefault(require("../../stacked-column/layer")); var StackColumn = /** @class */ (function (_super) { tslib_1.__extends(StackColumn, _super); function StackColumn() { return _super !== null && _super.apply(this, arguments) || this; } StackColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedColumn'; _super.prototype.createLayers.call(this, layerProps); warning_1.default(false, 'Please use "StackedColumn" instead of "StackColumn" which was not recommended.'); }; StackColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return StackColumn; }(plot_1.default)); exports.default = StackColumn; },{"../../../base/plot":394,"../../stacked-column/layer":623,"@antv/util":803,"tslib":894,"warning":895}],502:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); var HeatmapBackground = /** @class */ (function (_super) { tslib_1.__extends(HeatmapBackground, _super); function HeatmapBackground(cfg) { var _this = _super.call(this) || this; _this.options = cfg; _this.view = _this.options.view; _this.init(); return _this; } HeatmapBackground.prototype.init = function () { var coord = this.getCoordinate(); this.width = coord.getWidth(); this.height = coord.getHeight(); this.x = coord.start.x; this.y = coord.end.y; this.container = this.view.backgroundGroup.addGroup({}); }; HeatmapBackground.prototype.render = function () { if (this.options.type === 'color') { this.renderColorBackground(); } else if (this.options.type === 'image') { this.renderImageBackground(); } else if (this.options.callback) { var callbackCfg = { x: this.x, y: this.y, width: this.width, height: this.height, container: this.container, }; this.options.callback(callbackCfg); } }; HeatmapBackground.prototype.renderColorBackground = function () { this.container.addShape('rect', { attrs: { x: this.x, y: this.y, width: this.width, height: this.height, fill: this.options.value, }, name: 'heatmap-background', }); }; HeatmapBackground.prototype.renderImageBackground = function () { this.container.addShape('image', { attrs: { x: this.x, y: this.y, width: this.width, height: this.height, img: this.options.src, }, name: 'heatmap-background', }); }; HeatmapBackground.prototype.clear = function () { if (this.container) { this.container.clear(); this.emit('background:clear'); } }; HeatmapBackground.prototype.destroy = function () { if (this.container) { this.container.remove(); // 使用callback定制的html background需要自己监听销毁事件自行销毁 this.emit('background:destroy'); } }; HeatmapBackground.prototype.getCoordinate = function () { var coordinate; util_1.each(this.view.geometries, function (geom) { if (geom.type === 'heatmap') { coordinate = geom.coordinate; } }); return coordinate; }; return HeatmapBackground; }(event_emitter_1.default)); exports.default = HeatmapBackground; },{"@antv/event-emitter":94,"@antv/util":803,"tslib":894}],503:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlotComponents = void 0; var tslib_1 = require("tslib"); var background_1 = tslib_1.__importDefault(require("./background")); var legend_1 = tslib_1.__importDefault(require("./legend")); var ComponentsInfo = { background: { Ctr: background_1.default }, legend: { Ctr: legend_1.default, padding: 'outer' }, }; function getPlotComponents(plot, type, cfg) { if (plot.options[type] && plot.options[type].visible) { var componentInfo = ComponentsInfo[type]; var component = new componentInfo.Ctr(cfg); if (componentInfo.padding) { plot.paddingController.registerPadding(component, componentInfo.padding); } return component; } } exports.getPlotComponents = getPlotComponents; },{"./background":502,"./legend":504,"tslib":894}],504:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var LABEL_MARGIN = 4; var ACTIVE_OPACITY = 1; var DEACTIVE_OPACITY = 0.1; var HeatmapLegend = /** @class */ (function () { function HeatmapLegend(cfg) { this.destroyed = false; this.dataSlides = {}; var defaultOptions = this.getDefaultOptions(); if (cfg.plot.options.theme && cfg.plot.options.theme === 'dark') { defaultOptions = this.getDarkOptions(); } this.options = util_1.deepMix({}, defaultOptions, cfg); this.view = this.options.view; this.afterRender = true; this.init(); } HeatmapLegend.prototype.init = function () { this.layout = this.getLayout(); this.width = this.options.width ? this.options.width : this.getDefaultWidth(); this.height = this.options.height ? this.options.height : this.getDefaultHeight(); var plotContainer = this.options.plot.container; this.container = plotContainer.addGroup(); }; HeatmapLegend.prototype.render = function () { var scales = this.getScales(); var colorField = this.options.plot.options.colorField; this.colorScale = scales[colorField]; var _a = this.colorScale, min = _a.min, max = _a.max; var color = this.options.plot.options.color; if (this.layout === 'horizontal') { this.renderHorizontal(min, max, color); } else { this.renderVertical(min, max, color); } this.legendLayout(); this.addInteraction(); this.options.plot.canvas.draw(); }; HeatmapLegend.prototype.hide = function () { this.container.set('visible', false); this.options.plot.canvas.draw(); }; HeatmapLegend.prototype.show = function () { this.container.set('visible', true); this.options.plot.canvas.draw(); }; HeatmapLegend.prototype.clear = function () { if (this.container) { this.container.clear(); } }; HeatmapLegend.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; HeatmapLegend.prototype.getBBox = function () { var origin_bbox = this.container.getBBox(); return new bbox_1.default(this.x, this.y, origin_bbox.width, origin_bbox.height); }; HeatmapLegend.prototype.renderVertical = function (min, max, colors) { var _this = this; var gridWidth = this.width; var gridHeight = this.height / colors.length; var gridLineContainer = this.container.addGroup(); var gridColors = util_1.clone(colors).reverse(); var valueStep = (max - min) / colors.length; // 绘制色彩格子 util_1.each(gridColors, function (c, i) { var y = gridHeight * i; // 记录每个grid代表的区间信息用于legend交互 var appendInfo = { to: max - valueStep * i, from: max - valueStep * (i + 1) }; var rect = _this.container.addShape('rect', { attrs: { x: 0, y: y, width: gridWidth, height: gridHeight, fill: c, opacity: ACTIVE_OPACITY, cursor: 'pointer', }, name: 'legend', }); rect.set('info', appendInfo); var dataSlide = _this.getDataSlide(appendInfo); _this.dataSlides[appendInfo.from + "-" + appendInfo.to] = { mode: 'active', data: dataSlide }; gridLineContainer.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', 0, y + gridHeight], ['L', gridWidth, y + gridHeight], ] }, _this.options.gridlineStyle), }); }); // 绘制两边的label this.container.addShape('text', { attrs: tslib_1.__assign({ text: max, x: gridWidth / 2, y: -LABEL_MARGIN, textAlign: 'center', textBaseline: 'bottom' }, this.options.text.style), name: 'legend-label', }); this.container.addShape('text', { attrs: tslib_1.__assign(tslib_1.__assign({ text: min, x: gridWidth / 2, y: this.height + LABEL_MARGIN, textAlign: 'center', textBaseline: 'top' }, this.options.text.style), { name: 'legend-label' }), }); // 绘制包围线 gridLineContainer.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', 0, 0], ['L', this.width, 0], ['L', this.width, this.height], ['L', 0, this.height], ['L', 0, 0], ] }, this.options.gridlineStyle), }); }; HeatmapLegend.prototype.renderHorizontal = function (min, max, colors) { var _this = this; var gridWidth = this.width / colors.length; var gridHeight = this.height; var gridLineContainer = this.container.addGroup(); var valueStep = (max - min) / colors.length; // 绘制色彩格子 util_1.each(colors, function (c, i) { var x = gridWidth * i; // 记录每个grid代表的区间信息用于legend交互 var appendInfo = { from: valueStep * i, to: valueStep * (i + 1) }; var rect = _this.container.addShape('rect', { attrs: { x: x, y: 0, width: gridWidth, height: gridHeight, fill: c, opacity: 0.8, cursor: 'pointer', }, name: 'legend', }); rect.set('info', appendInfo); gridLineContainer.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', x + gridWidth, 0], ['L', x + gridWidth, gridHeight], ] }, _this.options.gridlineStyle), }); }); // 绘制两边的label this.container.addShape('text', { attrs: tslib_1.__assign(tslib_1.__assign({ text: min, x: -LABEL_MARGIN, y: gridHeight / 2 }, this.options.text.style), { textAlign: 'right', textBaseline: 'middle' }), name: 'legend-label', }); this.container.addShape('text', { attrs: tslib_1.__assign({ text: max, x: this.width + LABEL_MARGIN, y: gridHeight / 2, textAlign: 'left', textBaseline: 'middle' }, this.options.text.style), name: 'legend-label', }); // 绘制包围线 gridLineContainer.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', 0, 0], ['L', this.width, 0], ['L', this.width, this.height], ['L', 0, this.height], ['L', 0, 0], ] }, this.options.gridlineStyle), }); }; HeatmapLegend.prototype.getLayout = function () { var positions = this.options.position.split('-'); this.position = positions[0]; if (positions[0] === 'left' || positions[0] === 'right') { return 'vertical'; } return 'horizontal'; }; HeatmapLegend.prototype.getDefaultWidth = function () { if (this.layout === 'horizontal') { var width = this.options.plot.options.width; return width * 0.5; } return 10; }; HeatmapLegend.prototype.getDefaultHeight = function () { if (this.layout === 'vertical') { var height = this.options.plot.options.height; return height * 0.5; } return 10; }; HeatmapLegend.prototype.legendLayout = function () { var _this = this; var bleeding = this.options.plot.getPlotTheme().bleeding; if (util_1.isArray(bleeding)) { util_1.each(bleeding, function (it, index) { if (typeof bleeding[index] === 'function') { bleeding[index] = bleeding[index](_this.options.plot.options); } }); } var bbox = this.container.getBBox(); var x = 0; var y = 0; var positions = this.options.position.split('-'); var plotWidth = this.options.plot.width; var plotHeight = this.options.plot.height; // 先确定x if (positions[0] === 'left') { x = bleeding[3]; } else if (positions[0] === 'right') { x = plotWidth - bleeding[1] - bbox.width; } else if (positions[1] === 'center') { x = (plotWidth - bbox.width) / 2; } else if (positions[1] === 'left') { x = bleeding[3]; } else if (positions[1] === 'right') { x = this.options.plot.width - bleeding[1] - bbox.width; } // 再确定y if (positions[0] === 'bottom') { y = plotHeight - bleeding[2] - bbox.height; } else if (positions[0] === 'top') { y = this.getTopPosition(bleeding); } else if (positions[1] === 'center') { y = (plotHeight - bbox.height) / 2; } else if (positions[1] === 'top') { y = bleeding[0]; } else if (positions[1] === 'bottom') { y = plotHeight - bleeding[2] - bbox.height; } this.x = x; this.y = y; this.container.translate(x, y); }; HeatmapLegend.prototype.getDefaultOptions = function () { return { text: { style: { fontSize: 12, fill: 'rgba(0, 0, 0, 0.45)', }, }, gridlineStyle: { lineWidth: 1, stroke: 'rgba(0, 0, 0, 0.45)', }, }; }; HeatmapLegend.prototype.getDarkOptions = function () { return { text: { style: { fontSize: 12, fill: 'rgba(255, 255, 255, 0.45)', }, }, gridlineStyle: { lineWidth: 1, stroke: 'rgba(255, 255, 255, 0.25)', }, }; }; HeatmapLegend.prototype.addInteraction = function () { var _this = this; var colorField = this.options.plot.options.colorField; this.container.on('click', function (ev) { var target = ev.target; if (target.get('name') === 'legend') { var appendInfo = target.get('info'); var targetInfo = appendInfo.from + "-" + appendInfo.to; var relativeData = _this.dataSlides[targetInfo]; if (relativeData.mode === 'active') { relativeData.mode = 'deactive'; target.stopAnimate(); target.animate({ opacity: DEACTIVE_OPACITY, }, 200); } else { relativeData.mode = 'active'; target.stopAnimate(); target.animate({ opacity: ACTIVE_OPACITY, }, 200); } var filteredData = _this.getFilteredData(); if (filteredData.length > 0) { _this.view.changeData(filteredData); //this.view.set('data', filteredData); _this.view.scale(colorField, { min: _this.colorScale.min, max: _this.colorScale.max, nice: _this.colorScale.nice, }); _this.view.render(); } } }); }; HeatmapLegend.prototype.getFilteredData = function () { var filteredData = []; util_1.each(this.dataSlides, function (s) { if (s.mode == 'active') { filteredData.push.apply(filteredData, s.data); } }); return filteredData; }; //预先对数据进行分组 HeatmapLegend.prototype.getDataSlide = function (range) { var slide = []; var _a = this.options.plot.options, colorField = _a.colorField, data = _a.data; util_1.each(data, function (d) { var value = d[colorField]; if (value >= range.from && value < range.to) { slide.push(d); } }); return slide; }; HeatmapLegend.prototype.getTopPosition = function (bleeding) { if (this.options.plot.description) { var bbox = this.options.plot.description.getBBox(); return bbox.maxY + 10; } else if (this.options.plot.title) { var bbox = this.options.plot.title.getBBox(); return bbox.maxY + 10; } return bleeding[0]; }; HeatmapLegend.prototype.getScales = function () { var scales; util_1.each(this.view.geometries, function (geom) { if (geom.type === 'heatmap') { scales = geom.scales; } }); return scales; }; return HeatmapLegend; }()); exports.default = HeatmapLegend; },{"../../../util/bbox":672,"@antv/util":803,"tslib":894}],505:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { heatmap: 'heatmap', legendLabel: 'legend-label', heatmapBackground: 'heatmap-background', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],506:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var DensityHeatmap = /** @class */ (function (_super) { tslib_1.__extends(DensityHeatmap, _super); function DensityHeatmap() { return _super !== null && _super.apply(this, arguments) || this; } DensityHeatmap.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'densityHeatmap'; _super.prototype.createLayers.call(this, layerProps); }; DensityHeatmap.getDefaultOptions = layer_1.default.getDefaultOptions; return DensityHeatmap; }(plot_1.default)); exports.default = DensityHeatmap; },{"../../base/plot":394,"./layer":507,"@antv/util":803,"tslib":894}],507:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../components/factory"); var factory_2 = require("../../geoms/factory"); var scale_1 = require("../../util/scale"); require("../../geoms/heatmap/linear"); var components_1 = require("./components"); var EventParser = tslib_1.__importStar(require("./event")); var DensityHeatmapLayer = /** @class */ (function (_super) { tslib_1.__extends(DensityHeatmapLayer, _super); function DensityHeatmapLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'densityHeatmap'; _this.plotComponents = []; return _this; } DensityHeatmapLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, autoRotateTitle: false, grid: { visible: false, }, line: { visible: true, }, tickLine: { visible: true, }, label: { visible: true, autoHide: true, autoRotate: true, }, title: { visible: false, spacing: 12, }, }, yAxis: { visible: true, autoRotateTitle: true, grid: { visible: false, }, line: { visible: true, }, tickLine: { visible: true, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { visible: false, spacing: 12, }, }, tooltip: { visible: true, showCrosshairs: true, crosshairs: { type: 'xy', line: { style: { stroke: '#000000', lineWidth: 1, opacity: 0.5, }, }, }, showMarkers: false, }, legend: { visible: true, position: 'bottom-center', }, color: [ 'rgba(33,102,172,0)', 'rgb(103,169,207)', 'rgb(209,229,240)', 'rgb(253,219,199)', 'rgb(239,138,98)', 'rgb(178,24,43)', ], interactions: [{ type: 'tooltip' }], }); }; DensityHeatmapLayer.prototype.afterRender = function () { this.renderPlotComponents(); _super.prototype.afterRender.call(this); }; DensityHeatmapLayer.prototype.destroy = function () { util_1.each(this.plotComponents, function (component) { component.destroy(); }); _super.prototype.destroy.call(this); }; DensityHeatmapLayer.prototype.scale = function () { var props = this.options; var scales = {}; /** 配置x-scale */ scales[props.xField] = {}; if (util_1.has(props, 'xAxis')) { scale_1.extractScale(scales[props.xField], props.xAxis); } /** 配置y-scale */ scales[props.yField] = {}; if (util_1.has(props, 'yAxis')) { scale_1.extractScale(scales[props.yField], props.yAxis); } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; DensityHeatmapLayer.prototype.coord = function () { return; }; DensityHeatmapLayer.prototype.geometryParser = function () { return 'heatmap'; }; DensityHeatmapLayer.prototype.addGeometry = function () { if (this.options.data.length > 1) { var config = { type: 'linearheatmap', position: { fields: [this.options.xField, this.options.yField], }, color: { fields: [this.options.colorField], values: this.options.color, }, cfg: { intensity: this.options.intensity, radius: this.options.radius, }, }; if (this.options.radius) { config.radius = this.options.radius; } if (this.options.intensity) { config.intensity = this.options.intensity; } if (this.options.tooltip && (this.options.tooltip.fields || this.options.tooltip.formatter)) { this.geometryTooltip(config); } this.setConfig('geometry', config); this.addPoint(); } }; DensityHeatmapLayer.prototype.addPoint = function () { var props = this.options; var defaultConfig = { visible: false, size: 0 }; if (props.point && props.point.visible) { props.point = util_1.deepMix(defaultConfig, props.point); } else { props.point = defaultConfig; } var point = factory_2.getGeom('point', 'guide', { plot: this, }); point.active = false; // point.label = this.extractLabel(); this.setConfig('geometry', point); }; DensityHeatmapLayer.prototype.extractLabel = function () { var props = this.options; var label = props.label; if (label && label.visible === false) { return false; } var labelConfig = factory_1.getComponent('label', tslib_1.__assign({ plot: this, labelType: 'scatterLabel', fields: [props.xField, props.yField], position: 'middle', offset: 0 }, label)); return labelConfig; }; DensityHeatmapLayer.prototype.legend = function () { this.setConfig('legends', false); }; DensityHeatmapLayer.prototype.geometryTooltip = function (config) { config.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { config.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { config.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { config.tooltip.fields = [this.options.xField, this.options.yField]; if (this.options.colorField) { config.tooltip.fields.push(this.options.colorField); } } } }; DensityHeatmapLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; DensityHeatmapLayer.prototype.renderPlotComponents = function () { var _this = this; util_1.each(this.plotComponents, function (component) { component.destroy(); }); var componentsType = ['legend', 'background']; util_1.each(componentsType, function (t) { var cfg = tslib_1.__assign({ view: _this.view, plot: _this }, _this.options[t]); var component = components_1.getPlotComponents(_this, t, cfg); if (component) { component.render(); _this.plotComponents.push(component); } }); }; return DensityHeatmapLayer; }(view_layer_1.default)); exports.default = DensityHeatmapLayer; global_1.registerPlotType('densityHeatmap', DensityHeatmapLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../geoms/factory":430,"../../geoms/heatmap/linear":431,"../../util/scale":712,"./components":503,"./event":505,"@antv/util":803,"tslib":894}],508:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Density = /** @class */ (function (_super) { tslib_1.__extends(Density, _super); function Density() { return _super !== null && _super.apply(this, arguments) || this; } Density.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'density'; _super.prototype.createLayers.call(this, layerProps); }; Density.getDefaultOptions = layer_1.default.getDefaultOptions; return Density; }(plot_1.default)); exports.default = Density; },{"../../base/plot":394,"./layer":509,"@antv/util":803,"tslib":894}],509:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var scale_1 = require("@antv/scale"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var math_1 = require("../../util/math"); var layer_1 = tslib_1.__importDefault(require("../area/layer")); var kernels = { epanechnikov: function (dist) { return Math.abs(dist) <= 1 ? 0.75 * (1 - dist * dist) : 0; }, gaussian: function (dist) { return (1 / Math.sqrt(Math.PI * 2)) * Math.exp(-0.5 * Math.pow(dist, 2)); }, uniform: function (dist) { return Math.abs(dist) <= 1 ? 0.5 : 0; }, triangle: function (dist) { return Math.abs(dist) <= 1 ? 1 - Math.abs(dist) : 0; }, quartic: function (dist) { var v = 1 - dist * dist; return Math.abs(dist) <= 1 ? (15 / 16) * v * v : 0; }, triweight: function (dist) { var v = 1 - dist * dist; return Math.abs(dist) <= 1 ? (15 / 16) * Math.pow(v, 3) : 0; }, cosinus: function (dist) { var v = (Math.PI / 4) * Math.cos(0.5 * Math.PI * dist); return Math.abs(dist) <= 1 ? v : 0; }, }; var DensityLayer = /** @class */ (function (_super) { tslib_1.__extends(DensityLayer, _super); function DensityLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'density'; return _this; } DensityLayer.prototype.init = function () { var originXAxisConfig = this.options.xAxis ? util_1.clone(this.options.xAxis) : {}; this.options.xField = 'value'; this.options.yField = 'density'; this.options.xAxis = util_1.deepMix({}, originXAxisConfig, { type: 'linear' }); this.options.smooth = true; _super.prototype.init.call(this); }; DensityLayer.prototype.processData = function (originData) { var _this = this; var _a = this.options, binField = _a.binField, binWidth = _a.binWidth, binNumber = _a.binNumber, kernel = _a.kernel; var _kernel = kernel ? kernel : 'epanechnikov'; var kernelFunc = kernels[_kernel]; var originDataCopy = util_1.clone(originData); util_1.sortBy(originDataCopy, binField); // 计算分箱,直方图分箱的计算基于binWidth,如配置了binNumber则将其转为binWidth进行计算 var values = util_1.valuesOfKey(originDataCopy, binField); var range = util_1.getRange(values); var rangeWidth = range.max - range.min; var _binNumber = binNumber; var _binWidth = binWidth; if (!binNumber && binWidth) { _binNumber = Math.floor(rangeWidth / binWidth); } if (!binWidth && binNumber) { _binWidth = rangeWidth / binNumber; } // 当binWidth和binNumber都没有指定的情况,采用Sturges formula自动生成binWidth if (!binNumber && !binWidth) { _binNumber = math_1.sturges(values); _binWidth = rangeWidth / binNumber; } // 根据binNumber获取samples var LinearScale = scale_1.getScale('linear'); var scale = new LinearScale({ min: range.min, max: range.max, tickCount: _binNumber, nice: false, }); var samples = scale.getTicks(); // 计算KDE var densities = []; util_1.each(samples, function (s) { var density = _this.kernelDensityEstimator(_binWidth, kernelFunc, s, values); densities.push({ value: s.text, density: density }); }); return densities; }; DensityLayer.prototype.kernelDensityEstimator = function (binWidth, kernelFunc, x, values) { var sum = 0; util_1.each(values, function (v) { var dist = (x.tickValue - v) / binWidth; sum += kernelFunc(dist); }); return values.length === 0 ? 0 : sum / values.length; }; return DensityLayer; }(layer_1.default)); exports.default = DensityLayer; global_1.registerPlotType('density', DensityLayer); },{"../../base/global":392,"../../util/math":680,"../area/layer":456,"@antv/scale":747,"@antv/util":803,"tslib":894}],510:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var statistic_1 = tslib_1.__importDefault(require("../../../components/statistic")); var statistic_template_1 = require("./statistic-template"); var util_2 = require("@antv/util"); var RingStatistic = /** @class */ (function (_super) { tslib_1.__extends(RingStatistic, _super); function RingStatistic(cfg) { var _this = _super.call(this, cfg) || this; _this.view = cfg.view; _this.plot = cfg.plot; _this.statisticClass = cfg.statisticClass; _this.adjustOptions(); return _this; } RingStatistic.prototype.triggerOn = function () { var _this = this; var triggerOnEvent = this.options.triggerOn; this.view.on("interval:" + triggerOnEvent, util_2.debounce(function (e) { var displayData = _this.parseStatisticData('item', e.data.data, e.data.color); var htmlString = _this.getStatisticHtmlString(displayData); _this.updateHtml(htmlString); }, 150)); var triggerOffEvent = this.options.triggerOff ? this.options.triggerOff : 'mouseleave'; this.view.on("interval:" + triggerOffEvent, util_2.debounce(function () { var htmlString = _this.getTotalHtmlString(); _this.updateHtml(htmlString); }, 150)); }; RingStatistic.prototype.getTotalHtmlString = function () { var displayData; if (this.options.content) { displayData = this.options.content; } else { /** 用户没有指定文本内容时,默认显示总计 */ var data = this.getTotalValue(); displayData = this.parseStatisticData('total', data); } /** 中心文本显示 */ var htmlContent; if (this.options.htmlContent) { htmlContent = this.options.htmlContent(displayData, this.getStatisticSize()); } else { htmlContent = this.getStatisticTemplate(displayData); } var statisticContainer = document.createElement('div'); if (util_1.isType(htmlContent, 'HTMLDivElement')) { // @ts-ignore statisticContainer.appendChild(htmlContent); } else { statisticContainer.innerHTML = htmlContent; } return statisticContainer; }; RingStatistic.prototype.adjustOptions = function () { this.html = this.getTotalHtmlString(); var _a = this.view.coordinateBBox, minX = _a.minX, minY = _a.minY, width = _a.width, height = _a.height; this.x = minX + width / 2; this.y = minY + height / 2; }; RingStatistic.prototype.getTotalValue = function () { var _a; var total = 0; var _b = this.plot.options, angleField = _b.angleField, colorField = _b.colorField; var totalLabel = this.options.totalLabel; util_2.each(this.plot.options.data, function (item) { if (typeof item[angleField] === 'number') { total += item[angleField]; } }); var data = (_a = {}, _a[angleField] = total, _a[colorField] = totalLabel, _a); return data; }; RingStatistic.prototype.parseStatisticData = function (type, data, color) { var plot = this.plot; var _a = plot.options, angleField = _a.angleField, colorField = _a.colorField; var angleScale = plot.getScaleByField(angleField); var colorScale = plot.getScaleByField(colorField); var statisticData = { name: colorScale ? colorScale.getText(data[colorField]) : null, value: angleScale.getText(data[angleField]), }; if (type === 'item') { // 每一个扇形区域的数据 statisticData.itemData = data; statisticData.color = color; } return statisticData; }; RingStatistic.prototype.getStatisticTemplate = function (data) { var size = this.getStatisticSize(); var htmlString = statistic_template_1.getTemplate(data.name, data.value, this.statisticClass, size); /** 更为复杂的文本要求用户自行制定html模板 */ return htmlString; }; RingStatistic.prototype.getStatisticSize = function () { var viewRange = this.plot.view.coordinateBBox; var _a = this.plot.options, radius = _a.radius, innerRadius = _a.innerRadius; var minContainerSize = Math.min(viewRange.width, viewRange.height); var size = minContainerSize * radius * innerRadius; return size; }; RingStatistic.prototype.getStatisticHtmlString = function (data) { var htmlContent = this.options.htmlContent; var htmlString; if (htmlContent) { htmlString = htmlContent(data, this.getStatisticSize()); } else { htmlString = this.getStatisticTemplate(data); } return htmlString; }; return RingStatistic; }(statistic_1.default)); exports.default = RingStatistic; },{"../../../components/statistic":420,"./statistic-template":511,"@antv/util":803,"tslib":894}],511:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTemplate = void 0; /*tslint:disable*/ var containerStyle = "color:#4d4d4d;font-size:14px;text-align:center;line-height:2;font-family:'-apple-system',BlinkMacSystemFont,'SegoeUI',Roboto,'HelveticaNeue',Helvetica,'PingFangSC','HiraginoSansGB','MicrosoftYaHei',SimSun,'sans-serif';pointer-events:none;"; var nameStyle = 'font-weight:300;white-space: nowrap;text-overflow: ellipsis;'; var valueStyle = 'font-size:32px;font-weight:bold;color:#4D4D4D'; function getTemplate(name, value, classId, size) { var domStyle = containerStyle + "width:" + size + "px;"; var nameDomStr = name ? "" + name + "
    " : ''; var valueDomStr = "" + value + ""; return "
    " + nameDomStr + valueDomStr + "
    "; } exports.getTemplate = getTemplate; },{}],512:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { ring: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],513:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Donut = /** @class */ (function (_super) { tslib_1.__extends(Donut, _super); function Donut() { return _super !== null && _super.apply(this, arguments) || this; } Donut.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'donut'; _super.prototype.createLayers.call(this, layerProps); }; Donut.prototype.getAngleScale = function () { var layer = this.layers[0]; return layer.getAngleScale(); }; Donut.getDefaultOptions = layer_1.default.getDefaultOptions; return Donut; }(plot_1.default)); exports.default = Donut; },{"../../base/plot":394,"./layer":514,"@antv/util":803,"tslib":894}],514:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var dom_util_1 = require("@antv/dom-util"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../pie/layer")); var EventParser = tslib_1.__importStar(require("./event")); var ring_statistic_1 = tslib_1.__importDefault(require("./component/ring-statistic")); var G2_GEOM_MAP = { ring: 'interval', }; var PLOT_GEOM_MAP = { interval: 'ring', }; var DonutLayer = /** @class */ (function (_super) { tslib_1.__extends(DonutLayer, _super); function DonutLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'donut'; return _this; } DonutLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { radius: 0.8, innerRadius: 0.64, tooltip: { visible: false, }, statistic: { visible: true, totalLabel: '总计', triggerOn: 'mouseenter', triggerOff: 'mouseleave', }, }); }; DonutLayer.prototype.beforeInit = function () { _super.prototype.beforeInit.call(this); DonutLayer.centralId++; this.statisticClass = "statisticClassId" + DonutLayer.centralId; this.adjustLabelDefaultOptions(); // if (this.options.statistic.visible && this.options.statistic.triggerOn) { // this.options.tooltip.visible = false; // } }; DonutLayer.prototype.afterRender = function () { var container = this.canvas.get('container'); if (this.statistic) { container.removeChild(this.statistic.wrapperNode); this.statistic = null; } /**环图中心文本 */ if (this.options.statistic && this.options.statistic.visible) { var container_1 = this.canvas.get('container'); dom_util_1.modifyCSS(container_1, { position: 'relative' }); this.statistic = new ring_statistic_1.default(tslib_1.__assign({ container: container_1, view: this.view, plot: this, statisticClass: this.statisticClass }, this.options.statistic)); this.statistic.render(); /**响应交互 */ if (this.options.statistic.triggerOn) { this.statistic.triggerOn(); } } _super.prototype.afterRender.call(this); }; DonutLayer.prototype.destroy = function () { if (this.statistic) { this.statistic.destroy(); } _super.prototype.destroy.call(this); }; DonutLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; DonutLayer.prototype.coord = function () { var props = this.options; var coordConfig = { type: 'theta', cfg: { radius: props.radius, innerRadius: props.innerRadius, }, }; this.setConfig('coordinate', coordConfig); }; DonutLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; /** @override 调整 label 默认 options */ DonutLayer.prototype.adjustLabelDefaultOptions = function () { var labelConfig = this.options.label; if (labelConfig && labelConfig.type === 'inner') { var labelStyleConfig = (labelConfig.style || {}); if (!labelStyleConfig.textAlign) { labelStyleConfig.textAlign = 'center'; } labelConfig.style = labelStyleConfig; if (!labelConfig.offset) { labelConfig.offset = ((this.options.innerRadius - 1) / 2) * 100 + "%"; } } }; DonutLayer.centralId = 0; return DonutLayer; }(layer_1.default)); exports.default = DonutLayer; global_1.registerPlotType('donut', DonutLayer); },{"../../base/global":392,"../pie/layer":584,"./component/ring-statistic":510,"./event":512,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],515:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var FanGauge = /** @class */ (function (_super) { tslib_1.__extends(FanGauge, _super); function FanGauge() { return _super !== null && _super.apply(this, arguments) || this; } FanGauge.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'fanGauge'; _super.prototype.createLayers.call(this, layerProps); }; FanGauge.getDefaultOptions = layer_1.default.getDefaultOptions; return FanGauge; }(plot_1.default)); exports.default = FanGauge; },{"../../base/plot":394,"./layer":516,"@antv/util":803,"tslib":894}],516:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../gauge/layer")); var gauge_shape_1 = require("../gauge/geometry/shape/gauge-shape"); var FanGaugeLayer = /** @class */ (function (_super) { tslib_1.__extends(FanGaugeLayer, _super); function FanGaugeLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'fanGauge'; return _this; } FanGaugeLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { rangeColor: '#F6445A', rangeSize: 70, axis: { visible: true, offset: 5, tickCount: 10, subTickCount: 4, tickLine: { visible: true, length: 3, style: { stroke: '#aaa', lineWidth: 3, }, }, label: { visible: true, style: { fill: '#aaa', fontSize: 16, textAlign: 'center', textBaseline: 'middle', }, }, }, }); }; FanGaugeLayer.prototype.initG2Shape = function () { this.gaugeShape = new gauge_shape_1.GaugeShape(util_1.uniqueId()); this.gaugeShape.setOption(this.type, util_1.deepMix({}, this.options, { radius: 1, angle: 120, textPosition: '125%', bottomRatio: 3.5, })); this.gaugeShape.render(); }; FanGaugeLayer.prototype.axis = function () { var axesConfig = { value: false, 1: false, }; this.setConfig('axes', axesConfig); }; FanGaugeLayer.prototype.annotation = function () { var statistic = this.options.statistic; var annotationConfigs = []; // @ts-ignore if (statistic && statistic.visible) { var statistics = this.renderStatistic(); annotationConfigs.push(statistics); } var siderTexts = this.renderSideText(); var allAnnotations = annotationConfigs.concat(siderTexts); this.setConfig('annotations', allAnnotations); }; FanGaugeLayer.prototype.renderSideText = function () { var _a = this.options, max = _a.max, min = _a.min, format = _a.format, rangeSize = _a.rangeSize, axis = _a.axis; var OFFSET_Y = 12; return [min, max].map(function (value, index) { return { type: 'text', top: true, position: ['50%', '50%'], content: format(value), style: util_1.deepMix({}, axis.label.style, { textAlign: 'center', }), offsetX: !index ? -rangeSize : rangeSize, offsetY: OFFSET_Y, }; }); }; return FanGaugeLayer; }(layer_1.default)); exports.default = FanGaugeLayer; global_1.registerPlotType('fanGauge', FanGaugeLayer); },{"../../base/global":392,"../gauge/geometry/shape/gauge-shape":525,"../gauge/layer":527,"@antv/util":803,"tslib":894}],517:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var matrix_util_1 = require("@antv/matrix-util"); var g2_1 = require("@antv/g2"); function funnelScaleInX(shape, animateCfg) { var _a = animateCfg || {}, _b = _a.duration, duration = _b === void 0 ? 200 : _b, delay = _a.delay, easing = _a.easing, callback = _a.callback, reverse = _a.reverse; var bbox = shape.getBBox(); var originX = reverse ? bbox.maxX : bbox.minX; var originY = (bbox.minY + bbox.maxY) / 2; var clip = shape.setClip({ type: 'rect', attrs: { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height, }, }); var clipTargetAttrs = { matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1], }; clip.setMatrix(matrix_util_1.ext.transform(clip.getMatrix(), [ ['t', -originX, -originY], ['s', 0, 1], ['t', originX, originY], ])); var shapeTargetAttrs = { fillOpacity: shape.attr('fillOpacity'), strokeOpacity: shape.attr('strokeOpacity'), opacity: shape.attr('opacity'), }; shape.attr({ fillOpacity: 0, strokeOpacity: 0, opacity: 0, }); clip.animate(clipTargetAttrs, { duration: 200, easing: easing, callback: function () { shape.setClip(null); clip.remove(); }, delay: delay, }); shape.animate(shapeTargetAttrs, { duration: duration, easing: easing, delay: delay }); callback && setTimeout(function () { return callback(shape); }, duration + delay); } funnelScaleInX.animationName = 'funnelScaleInX'; g2_1.registerAnimation('funnelScaleInX', funnelScaleInX); },{"@antv/g2":309,"@antv/matrix-util":717}],518:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var matrix_util_1 = require("@antv/matrix-util"); var g2_1 = require("@antv/g2"); function funnelScaleInY(shape, animateCfg) { var _a = animateCfg || {}, _b = _a.duration, duration = _b === void 0 ? 200 : _b, delay = _a.delay, easing = _a.easing, callback = _a.callback, reverse = _a.reverse; var bbox = shape.getBBox(); var originX = (bbox.minX + bbox.maxX) / 2; var originY = reverse ? bbox.maxY : bbox.minY; var clip = shape.setClip({ type: 'rect', attrs: { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height, }, }); var clipTargetAttrs = { matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1], }; clip.setMatrix(matrix_util_1.ext.transform(clip.getMatrix(), [ ['t', -originX, -originY], ['s', 1, 0], ['t', originX, originY], ])); var shapeTargetAttrs = { fillOpacity: shape.attr('fillOpacity'), strokeOpacity: shape.attr('strokeOpacity'), opacity: shape.attr('opacity'), }; shape.attr({ fillOpacity: 0, strokeOpacity: 0, opacity: 0, }); clip.animate(clipTargetAttrs, { duration: 200, easing: easing, callback: function () { shape.setClip(null); clip.remove(); }, delay: delay, }); shape.animate(shapeTargetAttrs, { duration: duration, easing: easing, delay: delay }); callback && setTimeout(function () { return callback(shape); }, duration + delay); } funnelScaleInY.animationName = 'funnelScaleInY'; g2_1.registerAnimation('funnelScaleInY', funnelScaleInY); },{"@antv/g2":309,"@antv/matrix-util":717}],519:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var g2_1 = require("@antv/g2"); var get_style_1 = require("@antv/g2/lib/geometry/shape/util/get-style"); // 根据数据点生成矩形的四个关键点 function _getRectPoints(cfg, isPyramid) { if (isPyramid === void 0) { isPyramid = false; } var x = cfg.x, y = cfg.y, y0 = cfg.y0, size = cfg.size; // 有 4 种情况, // 1. x, y 都不是数组 // 2. y是数组,x不是 // 3. x是数组,y不是 // 4. x, y 都是数组 var yMin; var yMax; if (util_1.isArray(y)) { yMin = y[0]; yMax = y[1]; } else { yMin = y0; yMax = y; } var xMin; var xMax; if (util_1.isArray(x)) { xMin = x[0]; xMax = x[1]; } else { xMin = x - size / 2; xMax = x + size / 2; } var points = [ { x: xMin, y: yMin }, { x: xMin, y: yMax }, ]; if (isPyramid) { // 绘制尖底漏斗图 // 金字塔漏斗图的关键点 // 1 // | 2 // 0 points.push({ x: xMax, y: (yMax + yMin) / 2, }); } else { // 矩形的四个关键点,结构如下(左下角顺时针连接) // 1 ---- 2 // | | // 0 ---- 3 points.push({ x: xMax, y: yMax }, { x: xMax, y: yMin }); } return points; } // 根据关键点绘制漏斗图的 path function _getFunnelPath(cfg, compare) { var path = []; var points = cfg.points, nextPoints = cfg.nextPoints; if (compare) { // 对比漏斗 var yValues = compare.yValues, yValuesMax = compare.yValuesMax, yValuesNext = compare.yValuesNext; var originY = (points[0].y + points[1].y) / 2; var yValueTotal_1 = yValues[0] + yValues[1]; var yRatios = yValues.map(function (yValue) { return yValue / yValueTotal_1 / 0.5; }); var yOffset = (yValuesMax[0] / (yValuesMax[0] + yValuesMax[1]) - 0.5) * 0.9; var spacing = 0.001; if (!util_1.isNil(nextPoints)) { var yValueTotalNext_1 = yValuesNext[0] + yValuesNext[1]; var yRatiosNext = yValuesNext.map(function (yValueNext) { return yValueNext / yValueTotalNext_1 / 0.5; }); path.push(['M', points[0].x, yOffset + (points[0].y - originY) * yRatios[0] + originY - spacing], ['L', points[1].x, yOffset + originY - spacing], ['L', nextPoints[1].x, yOffset + originY - spacing], ['L', nextPoints[0].x, yOffset + (nextPoints[3].y - originY) * yRatiosNext[0] + originY - spacing], ['Z']); path.push(['M', points[0].x, yOffset + originY + spacing], ['L', points[1].x, yOffset + (points[1].y - originY) * yRatios[1] + originY + spacing], ['L', nextPoints[1].x, yOffset + (nextPoints[2].y - originY) * yRatiosNext[1] + originY + spacing], ['L', nextPoints[0].x, yOffset + originY + spacing], ['Z']); } else { path.push(['M', points[0].x, yOffset + (points[0].y - originY) * yRatios[0] + originY], ['L', points[1].x, yOffset + originY], ['L', points[2].x, yOffset + originY], ['L', points[3].x, yOffset + (points[3].y - originY) * yRatios[0] + originY], ['Z']); path.push(['M', points[0].x, yOffset + 0.002 + originY], ['L', points[1].x, yOffset + 0.002 + (points[1].y - originY) * yRatios[1] + originY], ['L', points[2].x, yOffset + 0.002 + (points[2].y - originY) * yRatios[1] + originY], ['L', points[3].x, yOffset + 0.002 + originY], ['Z']); } } else { // 标准漏斗 if (!util_1.isNil(nextPoints)) { path.push(['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['L', nextPoints[1].x, nextPoints[1].y], ['L', nextPoints[0].x, nextPoints[0].y], ['Z']); } else { path.push(['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y], ['L', points[2].x, points[2].y], ['L', points[3].x, points[3].y], ['Z']); } } return path; } g2_1.registerShape('interval', 'funnel-basic-rect', { getPoints: function (pointInfo) { pointInfo.size = pointInfo.size * 1.8; // 调整面积 return _getRectPoints(pointInfo); }, draw: function (cfg, container) { var _a; var style = get_style_1.getStyle(cfg, false, true); var compare = util_1.get(cfg, 'data.__compare__'); var path = this.parsePath(_getFunnelPath(cfg, compare)); return container.addShape('path', (_a = { name: 'interval', attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }) }, _a['__compare__'] = compare, _a)); }, getMarker: function (markerCfg) { var color = markerCfg.color; return { symbol: 'square', style: { r: 4, fill: color, }, }; }, }); },{"@antv/g2":309,"@antv/g2/lib/geometry/shape/util/get-style":302,"@antv/util":803,"tslib":894}],520:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var g2_1 = require("@antv/g2"); var get_style_1 = require("@antv/g2/lib/geometry/shape/util/get-style"); function lerp(a, b, factor) { return (1 - factor) * a + factor * b; } // 根据矩形关键点绘制 path function _getRectPath(points, _a) { var reverse = _a.reverse, ratioUpper = _a.ratioUpper, ratioLower = _a.ratioLower; var path = []; var firstPoint = points[0]; var originX = (points[1].x + points[2].x) / 2; var factorTop = 1.2; var factorBottom = 0.6; if (reverse) { var tmp = ratioLower; ratioLower = ratioUpper; ratioUpper = tmp; } var firstPointX = (firstPoint.x - originX) * lerp(factorBottom, factorTop, ratioLower) + originX; path.push(['M', firstPointX, firstPoint.y]); for (var i = 1, len = points.length; i < len; i++) { var pointX = points[i].x; switch (i) { case 1: case 2: pointX = (pointX - originX) * lerp(factorBottom, factorTop, ratioUpper) + originX; break; case 3: pointX = (pointX - originX) * lerp(factorBottom, factorTop, ratioLower) + originX; break; } path.push(['L', pointX, points[i].y]); } path.push(['L', firstPointX, firstPoint.y]); // 需要闭合 path.push(['z']); return path; } g2_1.registerShape('interval', 'funnel-dynamic-rect', { draw: function (cfg, container) { var style = get_style_1.getStyle(cfg, false, true); var custom = util_1.get(cfg, 'data.__custom__'); var path = this.parsePath(_getRectPath(cfg.points, custom)); return container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), }); }, getMarker: function (markerCfg) { var color = markerCfg.color, isInPolar = markerCfg.isInPolar; return { symbol: isInPolar ? 'circle' : 'square', style: { r: isInPolar ? 4.5 : 4, fill: color, }, }; }, }); },{"@antv/g2":309,"@antv/g2/lib/geometry/shape/util/get-style":302,"@antv/util":803,"tslib":894}],521:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Funnel = /** @class */ (function (_super) { tslib_1.__extends(Funnel, _super); function Funnel() { return _super !== null && _super.apply(this, arguments) || this; } Funnel.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'funnel'; _super.prototype.createLayers.call(this, layerProps); }; Funnel.getDefaultOptions = layer_1.default.getDefaultOptions; return Funnel; }(plot_1.default)); exports.default = Funnel; },{"../../base/plot":394,"./layer":522,"@antv/util":803,"tslib":894}],522:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dom_util_1 = require("@antv/dom-util"); var dependents_1 = require("../../dependents"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); require("./theme"); require("./geometry/shape/funnel-basic-rect"); require("./geometry/shape/funnel-dynamic-rect"); require("./animation/funnel-scale-in-x"); require("./animation/funnel-scale-in-y"); var color_1 = require("../../util/color"); function lerp(a, b, factor) { return (1 - factor) * a + factor * b; } var G2_GEOM_MAP = { column: 'interval', }; var PLOT_GEOM_MAP = { interval: 'funnel', }; var FunnelLayer = /** @class */ (function (_super) { tslib_1.__extends(FunnelLayer, _super); function FunnelLayer(props) { var _this = _super.call(this, props) || this; _this.type = 'funnel'; _this._shouldResetPercentages = true; _this._shouldResetLabels = true; _this._shouldResetCompareTexts = true; _this._legendsListenerAttached = false; _this._onLegendContainerMouseDown = function (e) { var props = _this.options; var targetName = e.target.get('name'); if (targetName.startsWith('legend-item')) { var legendItem = e.target.get('parent'); legendItem.set('unchecked', !legendItem.get('unchecked')); _this.refreshPercentages(); _this.refreshLabels(); if (props.dynamicHeight) { var data = _this._findCheckedDataByMouseDownLegendItem(legendItem); _this._genCustomFieldForDynamicHeight(data); } if (props.compareField) { var data = _this._findCheckedDataByMouseDownLegendItem(legendItem); _this._updateDataForCompare(data); _this.refreshCompareTexts(); } } }; _this.adjustProps(_this.options); if (props.dynamicHeight) { _this._genCustomFieldForDynamicHeight(_this.getData()); } if (props.compareField) { _this.options.data = _this._reduceDataForCompare(_this.getData()); } return _this; } FunnelLayer.getDefaultOptions = function (props) { var cfg = { label: { visible: true, adjustColor: true, }, percentage: { visible: true, offsetX: props.transpose ? 0 : 40, offsetY: props.transpose ? 40 : 0, spacing: 4, line: { visible: true, style: { lineWidth: 1, stroke: 'rgba(0, 0, 0, 0.15)', }, }, text: { content: '转化率', style: { fill: 'rgba(0, 0, 0, 0.65)', }, }, value: { visible: true, style: { fill: 'black', }, formatter: function (yValueUpper, yValueLower) { return ((100 * yValueLower) / yValueUpper).toFixed(2) + "%"; }, }, }, tooltip: { visible: true, shared: true, showTitle: false, showCrosshairs: false, showMarkers: false, }, animation: util_1.deepMix({}, dependents_1.DEFAULT_ANIMATE_CFG, { appear: { duration: 800, }, }), dynamicHeight: false, compareText: { visible: true, offsetX: -16, offsetY: -16, style: { fill: 'black', }, }, legend: { position: 'bottom-center', }, interactions: [{ type: 'tooltip' }, { type: 'legend-filter' }], }; return util_1.deepMix({}, _super.getDefaultOptions.call(this), cfg); }; FunnelLayer.prototype.getColorScale = function () { var xField = this.options.xField; if (xField) { return this.view.getScaleByField(xField); } }; FunnelLayer.prototype.coord = function () { var props = this.options; var coordConfig = { type: 'rect', actions: props.transpose ? props.dynamicHeight ? [['transpose'], ['scale', 1, -1]] : [['scale', 1, -1]] : props.dynamicHeight ? [] : [['transpose'], ['scale', 1, -1]], }; // @ts-ignore this.setConfig('coordinate', coordConfig); }; FunnelLayer.prototype.axis = function () { this.setConfig('axes', false); }; FunnelLayer.prototype.adjustFunnel = function (funnel) { var props = this.options; // @ts-ignore funnel.shape = props.dynamicHeight ? 'funnel-dynamic-rect' : 'funnel-basic-rect'; funnel.color = { fields: [props.xField], values: props.color && (Array.isArray(props.color) ? props.color : [props.color]), }; if (util_1.isFunction(props.funnelStyle)) { // @ts-ignore funnel.style = { callback: props.funnelStyle }; } else { // @ts-ignore funnel.style = { cfg: props.funnelStyle }; } funnel.adjust = [ { type: props.dynamicHeight ? 'stack' : 'symmetric', }, ]; }; FunnelLayer.prototype.tooltip = function () { var props = this.options; if (props.compareField) { util_1.deepMix(props.tooltip, { htmlContent: function (title, items) { var clss, el, color, elMarker; clss = dependents_1.TooltipCssConst.CONTAINER_CLASS; el = dom_util_1.createDom("
    "); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); var elRoot = el; if (title) { clss = dependents_1.TooltipCssConst.TITLE_CLASS; el = dom_util_1.createDom("
    "); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); elRoot.appendChild(el); var elTitle = el; clss = dependents_1.TooltipCssConst.MARKER_CLASS; el = dom_util_1.createDom(""); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); dom_util_1.modifyCSS(el, { width: '10px', height: '10px' }); elTitle.appendChild(el); elMarker = el; el = dom_util_1.createDom("" + title + ""); elTitle.appendChild(el); } if (items) { clss = dependents_1.TooltipCssConst.LIST_CLASS; el = dom_util_1.createDom("
      "); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); elRoot.appendChild(el); var elList_1 = el; items .reduce(function (pairs, item) { if (!color) { color = item.color; } var compareValues = util_1.get(item, 'point._origin.__compare__.compareValues'); var yValues = util_1.get(item, 'point._origin.__compare__.yValues'); yValues.forEach(function (yValue, i) { return pairs.push([compareValues[i], yValue]); }); return pairs; }, []) .forEach(function (_a, index) { var compareValue = _a[0], yValue = _a[1]; clss = dependents_1.TooltipCssConst.LIST_ITEM_CLASS; el = dom_util_1.createDom("
    • "); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); elList_1.appendChild(el); var elListItem = el; clss = dependents_1.TooltipCssConst.NAME_CLASS; el = dom_util_1.createDom("" + compareValue + ""); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); elListItem.appendChild(el); clss = dependents_1.TooltipCssConst.VALUE_CLASS; el = dom_util_1.createDom("" + yValue + ""); dom_util_1.modifyCSS(el, dependents_1.HtmlTooltipTheme[clss]); elListItem.appendChild(el); }); } if (color && elMarker) { dom_util_1.modifyCSS(elMarker, { backgroundColor: color }); } return elRoot; }, }); } _super.prototype.tooltip.call(this); }; FunnelLayer.prototype.addGeometry = function () { var props = this.options; var funnel = factory_1.getGeom('interval', 'main', { positionFields: [props.dynamicHeight ? '_' : props.xField, props.yField], plot: this, }); this.adjustFunnel(funnel); this.funnel = funnel; this.setConfig('geometry', funnel); if (!props.compareField) { this.geometryTooltip(); } }; FunnelLayer.prototype.geometryTooltip = function () { var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { if (!this.funnel.tooltip) { this.funnel.tooltip = {}; } this.funnel.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { if (!this.funnel.tooltip) { this.funnel.tooltip = {}; } this.funnel.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.funnel.tooltip.fields = [this.options.xField, this.options.yField]; } } }; FunnelLayer.prototype.animation = function () { var _this = this; _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { /** 关闭动画 */ this.funnel.animate = false; } else { var data_1 = this.getData(); var appearDuration = util_1.get(props, 'animation.appear.duration'); var appearDurationEach_1 = appearDuration / (data_1.length || 1); if (this._animationAppearTimeoutHandler) { clearTimeout(this._animationAppearTimeoutHandler); delete this._animationAppearTimeoutHandler; } this._animationAppearTimeoutHandler = setTimeout(function () { _this.fadeInPercentages(appearDurationEach_1); if (props.compareField) { _this.fadeInCompareTexts(appearDurationEach_1); } delete _this._animationAppearTimeoutHandler; }, appearDuration); this.funnel.animate = util_1.deepMix({}, props.animation, { appear: { animation: props.transpose ? 'funnelScaleInX' : 'funnelScaleInY', duration: appearDurationEach_1, delay: function (datum) { return util_1.findIndex(data_1, function (o) { return util_1.isEqual(o, datum); }) * appearDurationEach_1; }, callback: function (shape) { _this.fadeInLabels(shape, 0.5 * appearDurationEach_1); }, }, enter: { animation: 'fade-in', }, }); } }; FunnelLayer.prototype.afterRender = function () { var props = this.options; this.resetLabels(); this.resetPercentages(); if (props.compareField) { this.resetCompareTexts(); } if (props.padding == 'auto') { var percentageContainer = this._findPercentageContainer(); if (percentageContainer) { this.paddingController.registerPadding(percentageContainer, 'inner', true); } var compareTextContainer = this._findCompareTextContainer(); if (compareTextContainer) { this.paddingController.registerPadding(compareTextContainer, 'inner', true); } } _super.prototype.afterRender.call(this); if (props.animation === false) { this.fadeInLabels(); this.fadeInPercentages(); if (props.compareField) { this.fadeInCompareTexts(); } } if (!this._legendsListenerAttached) { this._legendsListenerAttached = true; // @ts-ignore var legendContainer = this.view.getController('legend').container; legendContainer.on('mousedown', this._onLegendContainerMouseDown); } }; FunnelLayer.prototype.updateConfig = function (cfg) { cfg = this.adjustProps(cfg); _super.prototype.updateConfig.call(this, cfg); this._legendsListenerAttached = false; }; FunnelLayer.prototype.changeData = function (data) { var props = this.options; if (props.animation !== false) { this._shouldResetPercentages = false; this._shouldResetLabels = false; } if (props.dynamicHeight) { var checkedData = this._findCheckedDataInNewData(data); this._genCustomFieldForDynamicHeight(checkedData); } if (props.compareField) { data = this._reduceDataForCompare(data); var checkedData = this._findCheckedDataInNewData(data); this._updateDataForCompare(checkedData); } _super.prototype.changeData.call(this, data); this.refreshPercentages(); this.refreshLabels(); if (props.compareField) { this.fadeInCompareTexts(); } }; FunnelLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; FunnelLayer.prototype.adjustProps = function (props) { if (props.compareField) { props.dynamicHeight = false; } if (props.dynamicHeight) { util_1.set(props, "meta." + props.yField + ".nice", false); util_1.set(props, 'tooltip.shared', false); } return props; }; FunnelLayer.prototype.resetPercentages = function () { var _this = this; if (!this._shouldResetPercentages) return; var props = this.options; var _a = props.percentage || {}, offsetX = _a.offsetX, offsetY = _a.offsetY, spacing = _a.spacing, _b = _a.line, percentageLine = _b === void 0 ? {} : _b, _c = _a.text, percentageText = _c === void 0 ? {} : _c, _d = _a.value, percentageValue = _d === void 0 ? {} : _d; var adjustTimestamp = Date.now(); var container = this._findPercentageContainer(true); this._eachShape(function (shape, index, datumLower, datumUpper) { if (index > 0) { var _a = shape.getBBox(), minX = _a.minX, maxX = _a.maxX, maxY = _a.maxY, minY = _a.minY; var x1 = props.transpose ? minX : maxX; var y1 = props.transpose ? (props.compareField ? maxY : minY) : minY; var _b = _this._findPercentageMembersInContainerByIndex(container, index, true), line_1 = _b.line, text_1 = _b.text, value_1 = _b.value; var eachProcs_1 = [ function (x, y, line, text, value) { if (line) { line.attr(util_1.deepMix({}, percentageLine.style, { x1: x, y1: y, x2: props.transpose ? x + offsetX : x - offsetX, y2: props.transpose ? y - offsetY : y + offsetY, opacity: 0, })); line.set('adjustTimestamp', adjustTimestamp); } var textWidth = 0; var valueWidth = 0; var textProc = function () { if (text) { text.attr(util_1.deepMix({}, percentageText.style, { x: props.transpose ? x + offsetX : x - offsetX - spacing - valueWidth - spacing, y: props.transpose ? y - offsetY - spacing : y + offsetY, opacity: 0, text: percentageText.content, textAlign: props.transpose ? 'left' : 'right', textBaseline: props.transpose ? 'bottom' : 'middle', })); text.set('adjustTimestamp', adjustTimestamp); textWidth = text.getBBox().width; } }; var valueProc = function () { if (value) { value.attr(util_1.deepMix({}, percentageValue.style, { x: props.transpose ? x + offsetX + textWidth + spacing : x - offsetX - spacing, y: props.transpose ? y - offsetY - spacing : y + offsetY, opacity: 0, text: util_1.isFunction(percentageValue.formatter) ? props.compareField ? percentageValue.formatter(util_1.get(datumUpper, '__compare__.yValues.0'), util_1.get(datumLower, '__compare__.yValues.0')) : percentageValue.formatter(datumUpper[props.yField], datumLower[props.yField]) : '', textAlign: props.transpose ? 'left' : 'right', textBaseline: props.transpose ? 'bottom' : 'middle', })); value.set('adjustTimestamp', adjustTimestamp); valueWidth = value.getBBox().width; } }; if (props.transpose) { textProc(); valueProc(); } else { valueProc(); textProc(); } }, function (x, y, line, text, value) { if (line) { line.attr(util_1.deepMix({}, percentageLine.style, { x1: x, y1: y, x2: x + offsetX, y2: props.transpose ? (props.compareField ? y + offsetY : y - offsetY) : y + offsetY, opacity: 0, })); line.set('adjustTimestamp', adjustTimestamp); } var textWidth = 0; if (text) { text.attr(util_1.deepMix({}, percentageText.style, { x: props.transpose ? x + offsetX : x + offsetX + spacing, y: props.transpose ? props.compareField ? y + offsetY + spacing : y - offsetY - spacing : y + offsetY, opacity: 0, text: percentageText.content, textAlign: 'left', textBaseline: props.transpose ? (props.compareField ? 'top' : 'bottom') : 'middle', })); text.set('adjustTimestamp', adjustTimestamp); textWidth = text.getBBox().width; } if (value) { value.attr(util_1.deepMix({}, percentageValue.style, { x: props.transpose ? x + offsetX + textWidth + spacing : x + offsetX + spacing + textWidth + spacing, y: props.transpose ? props.compareField ? y + offsetY + spacing : y - offsetY - spacing : y + offsetY, opacity: 0, text: util_1.isFunction(percentageValue.formatter) ? props.compareField ? percentageValue.formatter(util_1.get(datumUpper, "__compare__.yValues.1"), util_1.get(datumLower, "__compare__.yValues.1")) : percentageValue.formatter(datumUpper[props.yField], datumLower[props.yField]) : '', textAlign: 'left', textBaseline: props.transpose ? (props.compareField ? 'top' : 'bottom') : 'middle', })); value.set('adjustTimestamp', adjustTimestamp); } }, ]; if (props.compareField) { var _c = [minX, minY], x0 = _c[0], y0 = _c[1]; [ [x0, y0], [x1, y1], ].forEach(function (_a, i) { var x = _a[0], y = _a[1]; return eachProcs_1[i](x, y, line_1 && line_1[i], text_1 && text_1[i], value_1 && value_1[i]); }); } else { eachProcs_1[1](x1, y1, line_1, text_1, value_1); } } datumUpper = datumLower; index++; }); container.get('children').forEach(function (child) { if (child.get('adjustTimestamp') != adjustTimestamp) { child.attr({ opacity: 0 }); container.set(child.get('id'), null); setTimeout(function () { return child.remove(); }, 0); } }); }; FunnelLayer.prototype.fadeInPercentages = function (duration, callback) { var _this = this; var props = this.options; var container = this._findPercentageContainer(); var eachProc = function (i) { var lastBBox = { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity }; _this._eachShape(function (shape, index) { var members = _this._findPercentageMembersInContainerByIndex(container, index); var currBBox = { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity }; var eachCalc = function (member) { if (member && member.get('type') == 'text') { var _a = member.getBBox(), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY; if (minX < currBBox.minX) currBBox.minX = minX; if (maxX > currBBox.maxX) currBBox.maxX = maxX; if (minY < currBBox.minY) currBBox.minY = minY; if (maxY > currBBox.maxY) currBBox.maxY = maxY; } }; util_1.each(members, function (member) { return (util_1.isArray(member) ? eachCalc(member[i]) : eachCalc(member)); }); if (currBBox.minX > lastBBox.maxX || currBBox.maxX < lastBBox.minX || currBBox.minY > lastBBox.maxY || currBBox.maxY < lastBBox.minY) { var eachShow_1 = function (member) { if (member) { var attrs = { opacity: 1, }; duration ? member.animate(attrs, duration) : member.attr(attrs); } }; util_1.each(members, function (member) { return (util_1.isArray(member) ? eachShow_1(member[i]) : eachShow_1(member)); }); util_1.assign(lastBBox, currBBox); } }); }; props.compareField ? [0, 1].forEach(eachProc) : eachProc(); duration && callback && setTimeout(callback, duration); }; FunnelLayer.prototype.fadeOutPercentages = function (duration, callback) { var _this = this; var container = this._findPercentageContainer(); this._eachShape(function (shape, index) { var members = _this._findPercentageMembersInContainerByIndex(container, index); var eachProc = function (member) { if (member) { var attrs = { opacity: 0, }; duration ? member.animate(attrs, duration) : member.attr(attrs); } }; util_1.each(members, function (member) { return (util_1.isArray(member) ? member.forEach(eachProc) : eachProc(member)); }); }); duration && callback && setTimeout(callback, duration); }; FunnelLayer.prototype.refreshPercentages = function (callback) { var _this = this; var props = this.options; if (props.animation !== false) { var _a = this._calcRefreshFadeDurations(), fadeOutDuration = _a.fadeOutDuration, fadeInDuration_1 = _a.fadeInDuration; this._shouldResetPercentages = false; this.fadeOutPercentages(fadeOutDuration, function () { _this._shouldResetPercentages = true; _this.resetPercentages(); _this.fadeInPercentages(fadeInDuration_1, callback); }); } }; FunnelLayer.prototype._findPercentageContainer = function (createIfNotFound) { if (createIfNotFound === void 0) { createIfNotFound = false; } var middleGroup = this.view.middleGroup; var percentageContainer = middleGroup.get('percentageContainer'); if (!percentageContainer && createIfNotFound) { percentageContainer = middleGroup.addGroup(); middleGroup.set('percentageContainer', percentageContainer); } return percentageContainer; }; FunnelLayer.prototype._findPercentageMembersInContainerByIndex = function (container, index, createIfNotFound) { if (createIfNotFound === void 0) { createIfNotFound = false; } var props = this.options; var _a = props.percentage || {}, visible = _a.visible, _b = _a.line, percentageLine = _b === void 0 ? {} : _b, _c = _a.text, percentageText = _c === void 0 ? {} : _c, _d = _a.value, percentageValue = _d === void 0 ? {} : _d; var members = { line: undefined, text: undefined, value: undefined, }; if (visible === false || !container) { return members; } if (percentageLine.visible !== false) { var find = function (i) { var lineId = "_percentage-line-" + index + "-" + i; var line = container.get(lineId); if (!line && createIfNotFound) { line = container.addShape({ id: lineId, type: 'line', attrs: {} }); container.set(lineId, line); } return line; }; var line = props.compareField ? [0, 1].map(find) : find(0); members.line = line; } if (percentageText.visible !== false) { var find = function (i) { var textId = "_percentage-text-" + index + "-" + i; var text = container.get(textId); if (!text && createIfNotFound) { text = container.addShape({ id: textId, type: 'text', attrs: {} }); container.set(textId, text); } return text; }; var text = props.compareField ? [0, 1].map(find) : find(0); members.text = text; } if (percentageValue.visible !== false) { var find = function (i) { var valueId = "_percentage-value-" + index + "-" + i; var value = container.get(valueId); if (!value && createIfNotFound) { value = container.addShape({ id: valueId, type: 'text', attrs: {} }); container.set(valueId, value); } return value; }; var value = props.compareField ? [0, 1].map(find) : find(0); members.value = value; } return members; }; FunnelLayer.prototype._calcRefreshFadeDurations = function () { var props = this.options; var updateDuration = util_1.get(props, 'animation.update.duration'); var enterDuration = util_1.get(props, 'animation.enter.duration'); var fadeInDuration = Math.min(enterDuration, updateDuration) * 0.6; var fadeOutDuration = Math.max(enterDuration, updateDuration) * 1.2; return { fadeInDuration: fadeInDuration, fadeOutDuration: fadeOutDuration }; }; FunnelLayer.prototype.resetLabels = function () { var _this = this; if (!this._shouldResetLabels) return; var props = this.options; var xField = props.xField, yField = props.yField; var adjustTimestamp = Date.now(); var labelsContainer = this._getGeometry().labelsContainer; var labelProps = props.label || {}; var labelStyle = util_1.deepMix(tslib_1.__assign({}, this.theme.label), props.label.style, { opacity: 0, textAlign: 'center', textBaseline: 'middle', }); var datumTop; this._eachShape(function (shape, index, datum, elementIndex) { var _a; var element = shape.get('element'); if (index == 0) { datumTop = datum; } var _b = shape.getBBox(), minX = _b.minX, maxX = _b.maxX, minY = _b.minY, maxY = _b.maxY; var xValue = datum[xField]; var yValue = datum[yField]; if (labelProps.adjustColor) { labelStyle.fill = _this._getAdjustedTextFillByShape(shape); } var compare = datum.__compare__; var content; var formatArgs = (_a = {}, _a[dependents_1._ORIGIN] = datum, _a.element = element, _a.elementIndex = elementIndex, _a.mappingDatum = [].concat(element.getModel().mappingData)[0], _a.mappingDatumIndex = 0, _a); if (labelProps.formatter) { content = labelProps.formatter(xValue, formatArgs, index, yValue, datumTop[yField]); } else { if (compare) { content = [0, 1].map(function () { return "" + yValue; }).join(props.transpose ? '\n\n' : ' '); } else { content = xValue + " " + yValue; } } var label = _this._findLabelInContainerByIndex(labelsContainer, index, true); var ratio = compare ? compare.yValues[0] / (compare.yValues[0] + compare.yValues[1]) : 0.5; if (label) { label.attr(tslib_1.__assign(tslib_1.__assign({}, labelStyle), { x: lerp(minX, maxX, !props.transpose ? ratio : 0.5), y: lerp(minY, maxY, props.transpose ? ratio : 0.5), text: content })); label.set('adjustTimestamp', adjustTimestamp); } }); labelsContainer.get('children').forEach(function (label) { if (label.get('adjustTimestamp') != adjustTimestamp) { label.attr({ opacity: 0 }); labelsContainer.set(label.get('id'), null); setTimeout(function () { return label.remove(); }); } }); }; FunnelLayer.prototype.fadeInLabels = function (targetShape, duration, callback) { var _this = this; var labelsContainer = this._getGeometry().labelsContainer; this._eachShape(function (shape, index) { if (!targetShape || targetShape == shape) { var label = _this._findLabelInContainerByIndex(labelsContainer, index); if (label) { var shapeBBox = shape.getBBox(); var labelBBox = label.getBBox(); if (labelBBox.minX >= shapeBBox.minX && labelBBox.maxX <= shapeBBox.maxX && labelBBox.minY >= shapeBBox.minY && labelBBox.maxY <= shapeBBox.maxY) { var attrs = { opacity: 1, }; duration ? label.animate(attrs, duration) : label.attr(attrs); } } } }); duration && callback && setTimeout(callback, duration); }; FunnelLayer.prototype.fadeOutLabels = function (targetShape, duration, callback) { var _this = this; var labelsContainer = this._getGeometry().labelsContainer; this._eachShape(function (shape, index) { if (!targetShape || targetShape == shape) { var label = _this._findLabelInContainerByIndex(labelsContainer, index); if (label) { var attrs = { opacity: 0, }; duration ? label.animate(attrs, duration) : label.attr(attrs); } } }); duration && callback && setTimeout(callback, duration); }; FunnelLayer.prototype.refreshLabels = function (callback) { var _this = this; var props = this.options; if (props.animation !== false) { var _a = this._calcRefreshFadeDurations(), fadeOutDuration = _a.fadeOutDuration, fadeInDuration_2 = _a.fadeInDuration; this._shouldResetLabels = false; this.fadeOutLabels(null, fadeOutDuration, function () { _this._shouldResetLabels = true; _this.resetLabels(); _this.fadeInLabels(null, fadeInDuration_2, callback); }); } }; FunnelLayer.prototype._findLabelInContainerByIndex = function (container, index, createIfNotFound) { var _a; if (createIfNotFound === void 0) { createIfNotFound = false; } var props = this.options; var label; if (((_a = props.label) === null || _a === void 0 ? void 0 : _a.visible) === false) { return label; } var labelId = "_label-" + index; label = container.get(labelId); if (!label && createIfNotFound) { label = container.addShape({ id: labelId, type: 'text', attrs: {}, }); container.set(labelId, label); } return label; }; FunnelLayer.prototype.resetCompareTexts = function () { if (!this._shouldResetCompareTexts) return; var props = this.options; var shapeParentBBox; var compare; this._eachShape(function (shape, index, datum) { if (index == 0) { shapeParentBBox = shape.get('parent').getBBox(); compare = util_1.get(datum, '__compare__'); } }); if (shapeParentBBox && compare && util_1.get(props, 'compareText.visible') !== false) { var container_1 = this._findCompareTextContainer(true); var yValuesMax_1 = compare.yValuesMax, compareValues_1 = compare.compareValues; var minX_1 = shapeParentBBox.minX, maxX_1 = shapeParentBBox.maxX, minY_1 = shapeParentBBox.minY, maxY_1 = shapeParentBBox.maxY; var compareTexts_1 = container_1.get('children'); [0, 1].forEach(function (i) { var compareText = compareTexts_1[i]; if (!compareText) { compareText = container_1.addShape({ type: 'text' }); } compareText.attr(util_1.deepMix({}, util_1.get(props, 'compareText.style'), { text: props.transpose ? compareValues_1[i] : i ? " " + compareValues_1[i] : compareValues_1[i] + " ", x: props.transpose ? minX_1 + util_1.get(props, 'compareText.offsetX') : lerp(minX_1, maxX_1, yValuesMax_1[0] / (yValuesMax_1[0] + yValuesMax_1[1])), y: props.transpose ? lerp(minY_1, maxY_1, yValuesMax_1[0] / (yValuesMax_1[0] + yValuesMax_1[1])) + (i ? 8 : -8) : minY_1 + util_1.get(props, 'compareText.offsetY'), opacity: 0, textAlign: props.transpose ? 'right' : i ? 'left' : 'right', textBaseline: props.transpose ? (i ? 'top' : 'bottom') : 'bottom', })); }); } }; FunnelLayer.prototype.fadeInCompareTexts = function (duration, callback) { var container = this._findCompareTextContainer(); if (container) { var compareTexts_2 = container.get('children'); [0, 1].forEach(function (i) { var compareText = compareTexts_2[i]; if (compareText) { var attrs = { opacity: 1, }; duration ? compareText.animate(attrs, duration) : compareText.attr(attrs); } }); } duration && callback && setTimeout(callback, duration); }; FunnelLayer.prototype.fadeOutCompareTexts = function (duration, callback) { var container = this._findCompareTextContainer(); if (container) { var compareTexts_3 = container.get('children'); [0, 1].forEach(function (i) { var compareText = compareTexts_3[i]; if (compareText) { var attrs = { opacity: 0, }; duration ? compareText.animate(attrs, duration) : compareText.attr(attrs); } }); } duration && callback && setTimeout(callback, duration); }; FunnelLayer.prototype.refreshCompareTexts = function (callback) { var _this = this; var props = this.options; if (props.animation !== false) { var _a = this._calcRefreshFadeDurations(), fadeInDuration_3 = _a.fadeInDuration, fadeOutDuration = _a.fadeOutDuration; this._shouldResetCompareTexts = false; this.fadeOutCompareTexts(fadeOutDuration, function () { _this._shouldResetCompareTexts = true; _this.resetCompareTexts(); _this.fadeInCompareTexts(fadeInDuration_3, callback); }); } }; FunnelLayer.prototype._findCompareTextContainer = function (createIfNotFound) { if (createIfNotFound === void 0) { createIfNotFound = false; } var middleGroup = this.view.middleGroup; var compareTextContainer = middleGroup.get('compareTextContainer'); if (!compareTextContainer && createIfNotFound) { compareTextContainer = middleGroup.addGroup(); middleGroup.set('compareTextContainer', compareTextContainer); } return compareTextContainer; }; FunnelLayer.prototype._eachShape = function (fn) { var _a; var data = this._findCheckedData(this.getData()); var dataLen = data.length; var index = 0; var datumUpper; (_a = this._getGeometry()) === null || _a === void 0 ? void 0 : _a.elements.forEach(function (element, elementIndex) { var shape = element.shape; var datumLower = data[index]; if (index < dataLen) { fn(shape, index, datumLower, datumUpper, elementIndex); } datumUpper = datumLower; index++; }); }; FunnelLayer.prototype._getGeometry = function () { return this.view.geometries[0]; }; FunnelLayer.prototype._getAdjustedTextFillByShape = function (shape) { var shapeColor = shape.attr('fill'); var shapeOpacity = shape.attr('opacity') ? shape.attr('opacity') : 1; var rgb = color_1.rgb2arr(shapeColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / shapeOpacity; var colorBand = [ { from: 0, to: 85, color: 'white' }, { from: 85, to: 170, color: '#F6F6F6' }, { from: 170, to: 255, color: 'black' }, ]; var reflect = color_1.mappingColor(colorBand, gray); return reflect; }; FunnelLayer.prototype._genCustomFieldForDynamicHeight = function (data) { var props = this.options; var total = data.reduce(function (total, datum) { return total + datum[props.yField]; }, 0); var ratioUpper = 1; data.forEach(function (datum, index) { var value = datum[props.yField]; var share = value / total; var ratioLower = ratioUpper - share; datum['__custom__'] = { datumIndex: index, dataLength: data.length, ratioUpper: ratioUpper, ratioLower: ratioLower, reverse: props.transpose, }; ratioUpper = ratioLower; }); }; FunnelLayer.prototype._findCheckedDataByMouseDownLegendItem = function (legendItem) { var flags = legendItem .get('parent') .get('children') .map(function (legendItem) { return !legendItem.get('unchecked'); }); var data = this.getData().filter(function (datum, index) { return flags[index]; }); return data; }; FunnelLayer.prototype._findCheckedDataInNewData = function (newData) { var props = this.options; // @ts-ignore var legendContainer = this.view.getController('legend').container; var uncheckedXValues = legendContainer .findAll(function (shape) { return shape.get('name') == 'legend-item'; }) .filter(function (legendItem) { return legendItem.get('unchecked'); }) .map(function (legendItem) { return legendItem.get('id').replace('-legend-item-', ''); }); var checkedData = newData.filter(function (datum) { return !util_1.contains(uncheckedXValues, datum[props.xField]); }); return checkedData; }; FunnelLayer.prototype._findCheckedData = function (data) { var _a; var props = this.options; if ((_a = props.legend) === null || _a === void 0 ? void 0 : _a.visible) { // @ts-ignore var legendContainer = this.view.getController('legend').container; var checkedXValues_1 = legendContainer .findAll(function (shape) { return shape.get('name') == 'legend-item'; }) .filter(function (legendItem) { return !legendItem.get('unchecked'); }) .map(function (legendItem) { return legendItem.get('id').replace('-legend-item-', ''); }); var checkedData = data.filter(function (datum) { return util_1.contains(checkedXValues_1, datum[props.xField]); }); return checkedData; } else { return this.processData(props.data); } }; FunnelLayer.prototype._reduceDataForCompare = function (data) { var props = this.options; var compareValueFirstVisited; var yValuesMax = [-Infinity, -Infinity]; data = data.reduce(function (newData, datum) { var _a; var xValue = datum[props.xField]; var yValue = datum[props.yField]; var compareValue = datum[props.compareField]; if (!compareValueFirstVisited) compareValueFirstVisited = compareValue; var newDatum = newData.find(function (newDatum) { return newDatum[props.xField] == xValue; }); if (!newDatum) { newDatum = (_a = {}, _a[props.xField] = xValue, _a[props.yField] = 0, _a['__compare__'] = { compareValues: [], yValues: [], yValuesMax: [], yValuesNext: undefined, transpose: props.transpose, }, _a); newData.push(newDatum); } var idx = compareValue == compareValueFirstVisited ? 0 : 1; newDatum['__compare__'].yValues[idx] = yValue; if (yValuesMax[idx] < yValue) { yValuesMax[idx] = yValue; } newDatum['__compare__'].compareValues[idx] = compareValue; return newData; }, []); data.forEach(function (datum, index) { datum[props.yField] = util_1.get(datum, '__compare__.yValues', []).reduce(function (yTotal, yValue) { return (yTotal += yValue); }, 0); util_1.set(datum, '__compare__.yValuesMax', yValuesMax); util_1.set(datum, '__compare__.yValuesNext', util_1.get(data, index + 1 + ".__compare__.yValues")); }); return data; }; FunnelLayer.prototype._updateDataForCompare = function (data) { var yValuesMax = [-Infinity, -Infinity]; data.forEach(function (datum) { var yValues = util_1.get(datum, '__compare__.yValues'); [0, 1].forEach(function (i) { if (yValues[i] > yValuesMax[i]) { yValuesMax[i] = yValues[i]; } }); }); data.forEach(function (datum, index) { util_1.set(datum, '__compare__.yValuesMax', yValuesMax); util_1.set(datum, '__compare__.yValuesNext', util_1.get(data, index + 1 + ".__compare__.yValues")); }); }; return FunnelLayer; }(view_layer_1.default)); exports.default = FunnelLayer; global_1.registerPlotType('funnel', FunnelLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../dependents":425,"../../geoms/factory":430,"../../util/color":673,"./animation/funnel-scale-in-x":517,"./animation/funnel-scale-in-y":518,"./geometry/shape/funnel-basic-rect":519,"./geometry/shape/funnel-dynamic-rect":520,"./theme":523,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],523:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var BAR_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var BAR_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; theme_1.registerTheme('funnel', { columnStyle: { normal: {}, active: BAR_ACTIVE_STYLE, disable: BAR_DISABLE_STYLE, selected: { lineWidth: 1, stroke: 'black' }, }, }); },{"../../theme":669}],524:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { range: 'point', statistic: 'annotation-text', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],525:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GaugeShape = void 0; var tslib_1 = require("tslib"); /** * @author linhuiw * @description 仪表盘形状 */ var util_1 = require("@antv/util"); var g2_1 = require("@antv/g2"); var theme_1 = require("../../../../theme"); var common_1 = require("../../../../util/common"); /** * 仪表盘指针图形 * 指针主体由梯形和一大一小圆形组成, * 中心处由灰色圆底和小白圆加以装饰 */ var GaugeShape = /** @class */ (function () { function GaugeShape(uid) { this.uid = uid; } GaugeShape.prototype.setOption = function (type, options) { this.type = type; this.options = options; this.axis = options.axis; this.pivot = options.pivot; }; GaugeShape.prototype.render = function () { var Gauge = this; // eslint-disable-line @typescript-eslint/no-this-alias g2_1.registerShape('point', 'gauge', { draw: function (cfg, group) { var _a, _b, _c; this.gauge = {}; this.gauge.options = Gauge.options; this.gauge.axis = Gauge.axis; this.gauge.pivot = Gauge.pivot; this.gauge.type = Gauge.type; var gauge = this.gauge; var type = this.gauge.type; var point = cfg.points[0]; var center = this.parsePoint({ x: 0, y: 0, }); var target = this.parsePoint({ x: point.x || 0, y: 1, }); gauge.center = center; gauge.group = group; var r = { x: center.x - target.x, y: center.y - target.y }; this.gauge.ringRadius = Math.sqrt(r.x * r.x + r.y * r.y); var _d = this.getAngleRange(), starAngle = _d.starAngle, endAngle = _d.endAngle; var currentAngle = point.x * (endAngle - starAngle) + starAngle; switch (type) { case 'meterGauge': this.drawBarGauge(currentAngle); if (this.gauge.axis.visible && ((_a = this.gauge.axis.tickLine) === null || _a === void 0 ? void 0 : _a.visible)) { this.drawInSideAxis(); } break; case 'fanGauge': this.drawGauge(currentAngle); if (this.gauge.axis.visible && ((_b = this.gauge.axis.tickLine) === null || _b === void 0 ? void 0 : _b.visible)) { this.drawOutSideAxis(); } break; case 'standardGauge': default: this.drawGauge(currentAngle); if (this.gauge.axis.visible && ((_c = this.gauge.axis.tickLine) === null || _c === void 0 ? void 0 : _c.visible)) { this.drawAxis(); } break; } // 绘制指针 if (this.gauge.pivot.visible) { this.drawPivot(cfg, group); } }, drawGauge: function (currentAngle) { var range = this.gauge.options.range; this.drawBottomRing(); // 绘制灰底色 if (range && range.length) { this.drawRangeColor(); } else { this.drawCurrentRing(currentAngle); } }, drawRangeColor: function () { var _a = this.gauge.options, min = _a.min, max = _a.max, range = _a.range, color = _a.color, rangeStyle = _a.rangeStyle; var colors = color || theme_1.getGlobalTheme().colors; var _b = this.getAngleRange(), starAngle = _b.starAngle, endAngle = _b.endAngle; var config = { min: min, max: max, starAngle: starAngle, endAngle: endAngle, }; for (var i = 0; i < range.length; i++) { var start = this.valueToAngle(range[i], config); var end = this.valueToAngle(range[i + 1], config); if (end >= start) { var path2 = this.getPath(start, end); var style = util_1.deepMix({ fill: colors[i] }, rangeStyle); this.drawRing(path2, style); } } }, drawBottomRing: function () { var _a = this.getAngleRange(), starAngle = _a.starAngle, endAngle = _a.endAngle; var backgroundStyle = this.gauge.options.rangeBackgroundStyle; var path = this.getPath(starAngle, endAngle); this.drawRing(path, backgroundStyle); }, drawCurrentRing: function (current) { var starAngle = this.getAngleRange().starAngle; var rangeStyle = this.gauge.rangeStyle; var path3 = this.getPath(starAngle, current); this.drawRing(path3, rangeStyle); }, drawInSideAxis: function () { var _a = this.gauge.options, min = _a.min, max = _a.max, axis = _a.axis; var _b = this.getAngleRange(), starAngle = _b.starAngle, endAngle = _b.endAngle; var config = { min: min, max: max, starAngle: starAngle, endAngle: endAngle, }; var interval = (max - min) / axis.tickCount; for (var i = 0; i < axis.tickCount; i++) { var startValue = min + i * interval; var angle = this.valueToAngle(startValue + interval / 2, config); this.drawRect(angle, { length: axis.tickLine.length, style: axis.tickLine.style, }); } }, drawAxis: function () { var axis = this.gauge.axis; var _a = this.gauge.options, min = _a.min, max = _a.max; var _b = this.getAngleRange(), starAngle = _b.starAngle, endAngle = _b.endAngle; var config = { min: min, max: max, starAngle: starAngle, endAngle: endAngle, }; var interval = (max - min) / (axis.tickCount - 1); for (var i = 0; i < axis.tickCount; i++) { var startValue = min + i * interval; var angle = this.valueToAngle(startValue, config); var tickLineStyle = util_1.clone(axis.tickLine.style); if (i % 5 !== 0) { tickLineStyle.lineWidth = tickLineStyle.lineWidth / 2; } this.drawRect(angle, { length: i % 5 === 0 ? axis.tickLine.length : axis.tickLine.length / 2, style: tickLineStyle, }); } }, drawOutSideAxis: function () { var axis = this.gauge.axis; var _a = this.gauge.options, min = _a.min, max = _a.max; var _b = this.getAngleRange(), starAngle = _b.starAngle, endAngle = _b.endAngle; var config = { min: min, max: max, starAngle: starAngle, endAngle: endAngle, }; var interval = (max - min) / (axis.tickCount - 1); for (var i = 0; i < axis.tickCount; i++) { var startValue = min + i * interval; var angle = this.valueToAngle(startValue, config); this.drawRect(angle, { length: axis.tickLine.length, style: axis.tickLine.style, }); } }, drawBarGauge: function (current) { var _this = this; var _a = this.gauge.options, min = _a.min, max = _a.max, range = _a.range, color = _a.color, rangeStyle = _a.rangeStyle, rangeBackgroundStyle = _a.rangeBackgroundStyle; var colors = color || theme_1.getGlobalTheme().colors; var _b = this.getAngleRange(), starAngle = _b.starAngle, endAngle = _b.endAngle; var config = { min: min, max: max, starAngle: starAngle, endAngle: endAngle, }; var interval = (endAngle - starAngle) / (50 - 1); var offset = interval / 3; // 由50个柱子组成 for (var i = 0; i < 50; i++) { var start = starAngle + i * interval; var path2 = this.getPath(start - offset / 2, start + offset - offset / 2); var style = rangeBackgroundStyle; if (range && range.length) { var result1 = range.map(function (item) { return _this.valueToAngle(item, config); }); var index = common_1.sortedLastIndex(result1, start); /** 最后一个值也在最后一个区间内 */ var colorIndex = Math.min(index, range.length - 1); style = util_1.deepMix({}, { fill: colors[colorIndex - 1] }, rangeStyle) || rangeBackgroundStyle; } else { style = current >= start ? util_1.deepMix({}, { fill: color }, rangeStyle) : rangeBackgroundStyle; } this.drawRing(path2, style); } }, getAngleRange: function () { var angle = this.gauge.options.angle; var angleValue = 90 - (360 - angle) * 0.5; var starAngle = ((270 - 90 - angleValue) * Math.PI) / 180; var endAngle = ((270 + 90 + angleValue) * Math.PI) / 180; return { starAngle: starAngle, endAngle: endAngle }; }, valueToAngle: function (value, config) { var min = config.min, max = config.max, starAngle = config.starAngle, endAngle = config.endAngle; if (value === max) { return endAngle; } if (value === min) { return starAngle; } var ratio = (value - min) / (max - min); if (max === min) { ratio = 1; } var angle = ratio * (endAngle - starAngle) + starAngle; angle = Math.max(angle, starAngle); angle = Math.min(angle, endAngle); return angle; }, drawRing: function (path, style) { this.gauge.group.addShape('path', { attrs: util_1.deepMix({}, { path: path, }, style), }); }, drawRect: function (angle, param) { var axis = this.gauge.axis; var config = tslib_1.__assign(tslib_1.__assign({}, axis), param); var offset = config.offset, length = config.length; var center = this.gauge.center; var radius; if (offset < 0) { radius = this.gauge.ringRadius - this.gauge.options.rangeSize + offset; } else { radius = this.gauge.ringRadius + offset; } var xA1 = radius * Math.cos(angle) + center.x; var yA1 = radius * Math.sin(angle) + center.y; var xB1 = (radius + length) * Math.cos(angle) + center.x; var yB1 = (radius + length) * Math.sin(angle) + center.y; var line = this.gauge.group.addShape('line', { attrs: util_1.deepMix({}, { x1: xA1, y1: yA1, x2: xB1, y2: yB1, }, param.style), }); line.set('name', 'axis-tickLine'); }, getPath: function (starAngle, endAngle) { /* const type = this.gauge.type; const height = get(gauge, 'options.height'); const width = get(gauge, 'options.width');*/ var center = this.gauge.center; var length = this.gauge.ringRadius; /*let thick; const { minThickness, minThickCanvsSize } = this.gauge.ringStyle; const size = Math.min(width, height); if (type === 'fan' && size < minThickCanvsSize) { thick = length - minThickness; } else {*/ var thick = this.gauge.options.rangeSize; //} var xA1 = length * Math.cos(starAngle) + center.x; var yA1 = length * Math.sin(starAngle) + center.y; var xA2 = (length - thick) * Math.cos(starAngle) + center.x; var yA2 = (length - thick) * Math.sin(starAngle) + center.y; var xB1 = length * Math.cos(endAngle) + center.x; var yB1 = length * Math.sin(endAngle) + center.y; var xB2 = (length - thick) * Math.cos(endAngle) + center.x; var yB2 = (length - thick) * Math.sin(endAngle) + center.y; var largeArcFlag = Math.abs(starAngle - endAngle) > Math.PI ? 1 : 0; return [ ['M', xA1, yA1], ['A', length, length, 0, largeArcFlag, 1, xB1, yB1], ['L', xB2, yB2], ['A', length - thick, length - thick, 0, largeArcFlag, 0, xA2, yA2], ['Z'], ]; }, drawPivot: function (cfg) { var _a = this.getAngleRange(), starAngle = _a.starAngle, endAngle = _a.endAngle; var _b = this.gauge.options, radius = _b.radius, rangeSize = _b.rangeSize; var pivotConfig = this.gauge.pivot; var bigCircle = pivotConfig.thickness; var smCircle = pivotConfig.thickness / 2.5; var group = this.gauge.group; var point = cfg.points[0]; var center = this.parsePoint({ x: 0, y: 0, }); // radius var current = point.x * (endAngle - starAngle) + starAngle; var x = (this.gauge.ringRadius - rangeSize) * radius * Math.cos(current) + this.gauge.center.x; var y = (this.gauge.ringRadius - rangeSize) * radius * Math.sin(current) + this.gauge.center.y; var target = { x: x, y: y, }; // 外底色灰圆 if (pivotConfig.base.visible) { group.addShape('circle', { attrs: util_1.deepMix({}, { x: center.x, y: center.y, r: pivotConfig.base.size ? pivotConfig.base.size / 2 : bigCircle * 2.2, }, pivotConfig.base.style), }); } // 指针 if (pivotConfig.pointer.visible) { var dirVec = { x: center.x - target.x, y: center.y - target.y }; var length_1 = Math.sqrt(dirVec.x * dirVec.x + dirVec.y * dirVec.y); dirVec.x *= 1 / length_1; dirVec.y *= 1 / length_1; var angle1 = -Math.PI / 2; var x1 = Math.cos(angle1) * dirVec.x - Math.sin(angle1) * dirVec.y; var y1 = Math.sin(angle1) * dirVec.x + Math.cos(angle1) * dirVec.y; var angle2 = Math.PI / 2; var x2 = Math.cos(angle2) * dirVec.x - Math.sin(angle2) * dirVec.y; var y2 = Math.sin(angle2) * dirVec.x + Math.cos(angle2) * dirVec.y; var path = [ ['M', target.x + x1 * smCircle, target.y + y1 * smCircle], ['L', center.x + x1 * bigCircle, center.y + y1 * bigCircle], ['L', center.x + x2 * bigCircle, center.y + y2 * bigCircle], ['L', target.x + x2 * smCircle, target.y + y2 * smCircle], ['Z'], ]; group.addShape('path', { attrs: util_1.deepMix({}, { path: path, }, pivotConfig.pointer.style), }); group.addShape('circle', { attrs: { x: target.x, y: target.y, r: smCircle, fill: pivotConfig.pointer.style.fill, }, }); group.addShape('circle', { attrs: { x: center.x, y: center.y, r: bigCircle, fill: pivotConfig.pointer.style.fill, }, }); } if (pivotConfig.pin.visible) { // 内部白色小圆 group.addShape('circle', { attrs: util_1.deepMix({}, { x: center.x, y: center.y, r: smCircle / 1.2, }, pivotConfig.pin.style), }); } }, }); }; return GaugeShape; }()); exports.GaugeShape = GaugeShape; },{"../../../../theme":669,"../../../../util/common":674,"@antv/g2":309,"@antv/util":803,"tslib":894}],526:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Gauge = /** @class */ (function (_super) { tslib_1.__extends(Gauge, _super); function Gauge() { return _super !== null && _super.apply(this, arguments) || this; } Gauge.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'gauge'; _super.prototype.createLayers.call(this, layerProps); }; Gauge.getDefaultOptions = layer_1.default.getDefaultOptions; return Gauge; }(plot_1.default)); exports.default = Gauge; },{"../../base/plot":394,"./layer":527,"@antv/util":803,"tslib":894}],527:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * @author linhuiw * @description 仪表盘 layer */ var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var scale_1 = require("../../util/scale"); var gauge_shape_1 = require("./geometry/shape/gauge-shape"); var EventParser = tslib_1.__importStar(require("./event")); var GaugeLayer = /** @class */ (function (_super) { tslib_1.__extends(GaugeLayer, _super); function GaugeLayer(props) { var _this = _super.call(this, props) || this; _this.type = 'gauge'; return _this; } GaugeLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { startAngle: -7 / 6, endAngle: 1 / 6, rangeBackgroundStyle: { fill: '#f0f0f0', }, rangeSize: 24, statistic: { position: ['50%', '80%'], }, axis: { visible: true, offset: -10, tickCount: 21, subTickCount: 4, tickLine: { visible: true, length: 5, style: { stroke: '#aaa', lineWidth: 2, }, }, label: { visible: true, offset: 8, style: { fill: '#aaa', fontSize: 16, textAlign: 'center', textBaseline: 'middle', }, }, }, pivot: { visible: true, thickness: 6, pin: { visible: true, size: 2, style: { fill: '#2E364B', }, }, base: { visible: true, style: { fill: '#EEEEEE', }, }, pointer: { visible: true, style: { fill: '#CFCFCF', }, }, }, }); }; GaugeLayer.prototype.init = function () { var _a = this.options, value = _a.value, range = _a.range; var rangeSorted = (range || []).map(function (d) { return +d; }).sort(function (a, b) { return a - b; }); var _b = this.options, _c = _b.min, min = _c === void 0 ? rangeSorted[0] : _c, _d = _b.max, max = _d === void 0 ? rangeSorted[rangeSorted.length - 1] : _d, _e = _b.format, format = _e === void 0 ? function (d) { return "" + d; } : _e; var valueText = format(value); //const styleMix = this.getStyleMix(); //this.options.styleMix = styleMix; this.options.data = [{ value: value || 0 }]; this.options.valueText = valueText; this.options.min = min; this.options.max = max; this.options.format = format; this.initG2Shape(); _super.prototype.init.call(this); }; /** * 绘制指针 */ GaugeLayer.prototype.initG2Shape = function () { this.gaugeShape = new gauge_shape_1.GaugeShape(util_1.uniqueId()); this.gaugeShape.setOption(this.type, util_1.deepMix({}, this.options, { radius: 0.6, angle: 240, textPosition: '100%', })); this.gaugeShape.render(); }; GaugeLayer.prototype.geometryParser = function () { return 'gauge'; }; GaugeLayer.prototype.scale = function () { var _a = this.options, min = _a.min, max = _a.max, format = _a.format; var scales = { value: {}, }; scale_1.extractScale(scales.value, { min: min, max: max, minLimit: min, maxLimit: max, nice: true, formatter: format, // 自定义 tick step tickInterval: 20, }); // @ts-ignore this.setConfig('scales', scales); _super.prototype.scale.call(this); }; GaugeLayer.prototype.coord = function () { var coordConfig = { type: 'polar', cfg: { radius: 1, startAngle: this.options.startAngle * Math.PI, endAngle: this.options.endAngle * Math.PI, }, }; this.setConfig('coordinate', coordConfig); }; GaugeLayer.prototype.axis = function () { var axis = this.options.axis; var axesConfig = { value: { line: null, grid: null, tickLine: null, }, }; var offsetValue; if (axis.offset < 0) { offsetValue = axis.offset - this.options.rangeSize - axis.tickLine.length - axis.label.offset; } else { offsetValue = axis.offset + axis.tickLine.length + axis.label.offset; } if (axis.label.visible) { axesConfig.value.label = { offset: offsetValue, textStyle: axis.label.style, autoRotate: true, }; } else { axesConfig.value.label = { style: { opacity: 0, }, }; } axesConfig['1'] = false; axesConfig['value'] = axis.visible ? axesConfig['value'] : false; this.setConfig('axes', axesConfig); }; GaugeLayer.prototype.addGeometry = function () { var pointerColor = this.options.pivot.pointer.style.fill || this.theme.defaultColor; var pointer = { type: 'point', position: { fields: ['value', '1'], }, shape: { values: ['gauge'], }, color: { values: [pointerColor], }, }; this.setConfig('geometry', pointer); }; GaugeLayer.prototype.annotation = function () { var statistic = this.options.statistic; var annotationConfigs = []; // @ts-ignore if (statistic && statistic.visible) { var statistics = this.renderStatistic(); annotationConfigs.push(statistics); } this.setConfig('annotations', annotationConfigs); }; GaugeLayer.prototype.renderStatistic = function () { var containerSize = Math.max(this.options.width, this.options.height) / 20; var statistic = this.options.statistic; var text = { type: 'text', content: statistic.text, top: true, position: statistic.position, style: { fill: statistic.color, fontSize: statistic.size ? statistic.size : containerSize * 1.2, textAlign: 'center', textBaseline: 'middle', }, }; return text; }; GaugeLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; return GaugeLayer; }(view_layer_1.default)); exports.default = GaugeLayer; global_1.registerPlotType('gauge', GaugeLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../util/scale":712,"./event":524,"./geometry/shape/gauge-shape":525,"@antv/util":803,"tslib":894}],528:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var GroupedBar = /** @class */ (function (_super) { tslib_1.__extends(GroupedBar, _super); function GroupedBar() { return _super !== null && _super.apply(this, arguments) || this; } GroupedBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'groupedBar'; _super.prototype.createLayers.call(this, layerProps); }; GroupedBar.getDefaultOptions = layer_1.default.getDefaultOptions; return GroupedBar; }(plot_1.default)); exports.default = GroupedBar; },{"../../base/plot":394,"./layer":529,"@antv/util":803,"tslib":894}],529:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../bar/layer")); require("./theme"); var GroupedBarLayer = /** @class */ (function (_super) { tslib_1.__extends(GroupedBarLayer, _super); function GroupedBarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'groupedBar'; _this.baseType = 'bar'; return _this; } GroupedBarLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, grid: { visible: true, }, }, yAxis: { visible: true, title: { visible: false, }, }, label: { visible: true, position: 'right', adjustColor: true, }, legend: { visible: true, position: 'right-top', offsetY: 0, }, }); }; GroupedBarLayer.prototype.afterRender = function () { _super.prototype.afterRender.call(this); var names = util_1.valuesOfKey(this.options.data, this.options.groupField) || []; this.view.on('tooltip:change', function (e) { var _a = e.items, items = _a === void 0 ? [] : _a; var fixedItems = util_1.sortBy(items.slice(), function (item) { return names.indexOf(item.name); }).reverse(); fixedItems.forEach(function (item, idx) { e.items[idx] = item; }); }); }; GroupedBarLayer.prototype.getColorScale = function () { var groupField = this.options.groupField; if (groupField) { return this.view.getScaleByField(groupField); } }; GroupedBarLayer.prototype.scale = function () { var defaultMeta = {}; defaultMeta[this.options.groupField] = { values: util_1.valuesOfKey(this.options.data, this.options.groupField), }; if (!this.options.meta) { this.options.meta = defaultMeta; } else { this.options.meta = util_1.deepMix({}, this.options.meta, defaultMeta); } _super.prototype.scale.call(this); }; GroupedBarLayer.prototype.adjustBar = function (bar) { bar.adjust = [ { type: 'dodge', marginRatio: 0.1, }, ]; }; GroupedBarLayer.prototype.geometryTooltip = function () { this.bar.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.bar.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.bar.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.bar.tooltip.fields = [this.options.xField, this.options.yField, this.options.groupField]; } } }; return GroupedBarLayer; }(layer_1.default)); exports.default = GroupedBarLayer; global_1.registerPlotType('groupedBar', GroupedBarLayer); },{"../../base/global":392,"../bar/layer":464,"./theme":530,"@antv/util":803,"tslib":894}],530:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var theme_2 = require("../bar/theme"); theme_1.registerTheme('groupedBar', theme_2.DEFAULT_BAR_THEME); },{"../../theme":669,"../bar/theme":465}],531:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var GroupedColumn = /** @class */ (function (_super) { tslib_1.__extends(GroupedColumn, _super); function GroupedColumn() { return _super !== null && _super.apply(this, arguments) || this; } GroupedColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'groupedColumn'; _super.prototype.createLayers.call(this, layerProps); }; GroupedColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return GroupedColumn; }(plot_1.default)); exports.default = GroupedColumn; },{"../../base/plot":394,"./layer":532,"@antv/util":803,"tslib":894}],532:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../column/layer")); require("./theme"); var GroupedColumnLayer = /** @class */ (function (_super) { tslib_1.__extends(GroupedColumnLayer, _super); function GroupedColumnLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.baseType = 'column'; _this.type = 'groupedColumn'; return _this; } GroupedColumnLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { yAxis: { title: { visible: true, }, }, }); }; GroupedColumnLayer.prototype.getResponsiveTheme = function () { return this.themeController.getResponsiveTheme('column'); }; GroupedColumnLayer.prototype.getColorScale = function () { var groupField = this.options.groupField; if (groupField) { return this.view.getScaleByField(groupField); } }; GroupedColumnLayer.prototype.addGeometry = function () { _super.prototype.addGeometry.call(this); }; GroupedColumnLayer.prototype.adjustColumn = function (column) { column.adjust = [ { type: 'dodge', marginRatio: 0.1, }, ]; }; GroupedColumnLayer.prototype.geometryTooltip = function () { this.column.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.column.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.column.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.column.tooltip.fields = [this.options.xField, this.options.yField, this.options.groupField]; } } }; return GroupedColumnLayer; }(layer_1.default)); exports.default = GroupedColumnLayer; global_1.registerPlotType('groupedColumn', GroupedColumnLayer); },{"../../base/global":392,"../column/layer":490,"./theme":533,"@antv/util":803,"tslib":894}],533:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var theme_2 = require("../column/theme"); theme_1.registerTheme('groupedColumn', theme_2.DEFAULT_COLUMN_THEME); },{"../../theme":669,"../column/theme":491}],534:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var GroupedRose = /** @class */ (function (_super) { tslib_1.__extends(GroupedRose, _super); function GroupedRose() { return _super !== null && _super.apply(this, arguments) || this; } GroupedRose.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'groupedRose'; _super.prototype.createLayers.call(this, layerProps); }; GroupedRose.getDefaultOptions = layer_1.default.getDefaultOptions; return GroupedRose; }(plot_1.default)); exports.default = GroupedRose; },{"../../base/plot":394,"./layer":535,"@antv/util":803,"tslib":894}],535:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../rose/layer")); var GroupedRoseLayer = /** @class */ (function (_super) { tslib_1.__extends(GroupedRoseLayer, _super); function GroupedRoseLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'groupedRose'; _this.baseType = 'rose'; return _this; } GroupedRoseLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, line: { visible: false, }, tickLine: { visible: false, }, grid: { visible: true, alignTick: false, style: { lineWidth: 0.5, }, }, label: { offset: 5, autoRotate: true, }, }, yAxis: { visible: false, }, }); }; GroupedRoseLayer.prototype.getColorScale = function () { var groupField = this.options.groupField; if (groupField) { return this.view.getScaleByField(groupField); } }; GroupedRoseLayer.prototype.adjustRoseAdjust = function () { return [ { type: 'dodge', marginRatio: 1, }, ]; }; GroupedRoseLayer.prototype.geometryTooltip = function () { this.rose.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.rose.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.rose.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.rose.tooltip.fields = [this.options.radiusField, this.options.categoryField, this.options.groupField]; } } }; return GroupedRoseLayer; }(layer_1.default)); exports.default = GroupedRoseLayer; global_1.registerPlotType('groupedRose', GroupedRoseLayer); },{"../../base/global":392,"../rose/layer":600,"@antv/util":803,"tslib":894}],536:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlotComponents = void 0; var tslib_1 = require("tslib"); var label_1 = tslib_1.__importDefault(require("./label")); var legend_1 = tslib_1.__importDefault(require("./legend")); var ComponentsInfo = { label: { Ctr: label_1.default }, legend: { Ctr: legend_1.default, padding: 'outer' }, }; function getPlotComponents(plot, type, cfg) { if (plot.options[type] && plot.options[type].visible) { var componentInfo = ComponentsInfo[type]; var component = new componentInfo.Ctr(cfg); if (componentInfo.padding) { plot.paddingController.registerPadding(component, componentInfo.padding); } return component; } } exports.getPlotComponents = getPlotComponents; },{"./label":537,"./legend":538,"tslib":894}],537:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var color_1 = require("../../../util/color"); var MatrixLabel = /** @class */ (function () { function MatrixLabel(cfg) { this.destroyed = false; this.view = cfg.view; this.plot = cfg.plot; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); this.init(); } MatrixLabel.prototype.init = function () { var _this = this; this.container = this.view.geometries[0].labelsContainer; this.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; MatrixLabel.prototype.render = function () { var _this = this; var elements = this.view.geometries[0].elements; util_1.each(elements, function (ele) { var shape = ele.shape; var _a = _this.options, style = _a.style, offsetX = _a.offsetX, offsetY = _a.offsetY; var formatter = _this.options.formatter; var content = formatter ? formatter(_this.getContent(shape)) : _this.getContent(shape); var position = _this.getPosition(shape); var color = _this.getTextColor(shape); var label = _this.container.addShape('text', { attrs: util_1.deepMix({}, style, { x: position.x + offsetX, y: position.y + offsetY, text: content, fill: color, textAlign: 'center', textBaseline: 'middle', }), name: 'label', }); if (_this.options.adjustPosition) { _this.adjustLabel(label, shape); } }); }; MatrixLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; MatrixLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; MatrixLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; MatrixLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; MatrixLabel.prototype.getBBox = function () { return this.container.getBBox(); }; MatrixLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { offsetX: 0, offsetY: 0, style: util_1.clone(labelStyle), }; }; MatrixLabel.prototype.getContent = function (shape) { var data = shape.get('origin').data; var field = this.plot.options.colorField; return data[field]; }; MatrixLabel.prototype.getPosition = function (shape) { var bbox = shape.getBBox(); return { x: bbox.minX + bbox.width / 2, y: bbox.minY + bbox.height / 2, }; }; MatrixLabel.prototype.getTextColor = function (shape) { if (this.options.adjustColor) { var shapeColor = shape.attr('fill'); var shapeOpacity = shape.attr('opacity') ? shape.attr('opacity') : 1; var rgb = color_1.rgb2arr(shapeColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / shapeOpacity; var colorBand = [ { from: 0, to: 85, color: 'white' }, { from: 85, to: 170, color: '#F6F6F6' }, { from: 170, to: 255, color: 'black' }, ]; var reflect = color_1.mappingColor(colorBand, gray); return reflect; } var defaultColor = this.options.style.fill; return defaultColor; }; MatrixLabel.prototype.adjustLabel = function (label, shape) { var labelRange = label.getBBox(); var shapeRange = shape.getBBox(); if (labelRange.width > shapeRange.width || labelRange.height > shapeRange.height) { label.attr('text', ''); } }; return MatrixLabel; }()); exports.default = MatrixLabel; },{"../../../util/color":673,"@antv/util":803}],538:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var LABEL_MARGIN = 4; var MatrixLegend = /** @class */ (function () { function MatrixLegend(cfg) { this.destroyed = false; this.dataSlides = {}; this.interactiveEvents = {}; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix({}, defaultOptions, cfg); this.view = this.options.view; this.afterRender = true; this.init(); } MatrixLegend.prototype.init = function () { var _this = this; this.layout = this.getLayout(); this.width = this.options.width ? this.options.width : this.getDefaultWidth(); this.height = this.options.height ? this.options.height : this.getDefaultHeight(); var plotContainer = this.options.plot.container; if (this.container) { this.container.remove(); } this.container = plotContainer.addGroup(); this.view.on('beforerender', function () { _this.clear(); _this.options.plot.canvas.draw(); }); }; MatrixLegend.prototype.render = function () { var scales = this.view.geometries[0].scales; var colorField = this.options.plot.options.colorField; this.colorScale = scales[colorField]; var _a = this.colorScale, min = _a.min, max = _a.max; var color = this.options.plot.options.color; if (this.layout === 'horizontal') { this.renderHorizontal(min, max, color); } else { this.renderVertical(min, max, color); } this.legendLayout(); this.addInteraction(); }; MatrixLegend.prototype.hide = function () { this.container.set('visible', false); this.options.plot.canvas.draw(); }; MatrixLegend.prototype.show = function () { this.container.set('visible', true); this.options.plot.canvas.draw(); }; MatrixLegend.prototype.clear = function () { if (this.container) { this.container.clear(); } }; MatrixLegend.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.offEvent(); this.destroyed = true; }; MatrixLegend.prototype.getBBox = function () { var origin_bbox = this.container.getBBox(); return new bbox_1.default(this.x, this.y, origin_bbox.width, origin_bbox.height); }; MatrixLegend.prototype.renderVertical = function (min, max, colors) { var _this = this; var valueStep = (max - min) / (colors.length - 1); var colorStep = 1 / (colors.length - 1); var tickStep = this.height / (colors.length - 1); var gradientColor = 'l(90)'; util_1.each(colors, function (c, index) { var stepNum = colorStep * index; gradientColor += stepNum + ":" + c + " "; }); this.container.addShape('rect', { attrs: { x: 0, y: 0, width: this.width, height: this.height, fill: gradientColor, }, name: 'legend', }); // draw tick and label util_1.each(colors, function (c, index) { // tick var step = tickStep * index; _this.container.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', 0, step], ['L', _this.width, step], ] }, _this.options.ticklineStyle), }); // value var value = Math.round(valueStep * index); _this.container.addShape('text', { attrs: tslib_1.__assign({ text: value, textAlign: 'left', textBaseline: 'middle', x: _this.width + LABEL_MARGIN, y: step }, _this.options.text.style), name: 'legend-label', }); }); //anchor var tri_width = 10; var tri_height = 14; var tri_path = [['M', -tri_width, -tri_height / 2], ['L', 0, 0], ['L', -tri_width, tri_height / 2], ['Z']]; this.anchor = this.container.addShape('path', { attrs: tslib_1.__assign({ path: tri_path }, this.options.anchorStyle), }); this.anchor.set('visible', false); }; MatrixLegend.prototype.renderHorizontal = function (min, max, colors) { var _this = this; var valueStep = (max - min) / (colors.length - 1); var colorStep = 1 / (colors.length - 1); var tickStep = this.width / (colors.length - 1); var gradientColor = 'l(0)'; util_1.each(colors, function (c, index) { var stepNum = colorStep * index; gradientColor += stepNum + ":" + c + " "; }); this.container.addShape('rect', { attrs: { x: 0, y: 0, width: this.width, height: this.height, fill: gradientColor, }, name: 'legend', }); // draw tick and label util_1.each(colors, function (c, index) { // tick var step = tickStep * index; _this.container.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', step, 0], ['L', step, _this.height], ] }, _this.options.ticklineStyle), name: 'legend-label', }); // value var value = Math.round(valueStep * index); _this.container.addShape('text', { attrs: tslib_1.__assign({ text: value, textAlign: 'center', textBaseline: 'top', x: step, y: _this.height + LABEL_MARGIN }, _this.options.text.style), }); }); //anchor var tri_width = 14; var tri_height = 10; var tri_path = [['M', 0, 0], ['L', -tri_width / 2, -tri_height], ['L', tri_width / 2, -tri_height], ['Z']]; this.anchor = this.container.addShape('path', { attrs: tslib_1.__assign({ path: tri_path }, this.options.anchorStyle), }); this.anchor.set('visible', false); }; MatrixLegend.prototype.getLayout = function () { var positions = this.options.position.split('-'); this.position = positions[0]; if (positions[0] === 'left' || positions[0] === 'right') { return 'vertical'; } return 'horizontal'; }; MatrixLegend.prototype.getDefaultWidth = function () { if (this.layout === 'horizontal') { var width = this.view.coordinateBBox.width; return width; } return 10; }; MatrixLegend.prototype.getDefaultHeight = function () { if (this.layout === 'vertical') { var height = this.view.coordinateBBox.height; return height; } return 10; }; MatrixLegend.prototype.legendLayout = function () { var _this = this; var panelRange = this.view.coordinateBBox; var bleeding = this.options.plot.getPlotTheme().bleeding; if (util_1.isArray(bleeding)) { util_1.each(bleeding, function (it, index) { if (typeof bleeding[index] === 'function') { bleeding[index] = bleeding[index](_this.options.plot.options); } }); } var bbox = this.container.getBBox(); var x = 0; var y = 0; var positions = this.options.position.split('-'); var plotWidth = this.options.plot.width; var plotHeight = this.options.plot.height; // 先确定x if (positions[0] === 'left') { x = bleeding[3]; } else if (positions[0] === 'right') { x = plotWidth - bleeding[1] - bbox.width; } else if (positions[1] === 'center') { // default if (this.width === panelRange.width) { x = panelRange.x; } else { x = (plotWidth - bbox.width) / 2; } } else if (positions[1] === 'left') { x = bleeding[3]; } else if (positions[1] === 'right') { x = this.options.plot.width - bleeding[1] - bbox.width; } // 再确定y if (positions[0] === 'bottom') { y = plotHeight - bleeding[2] - bbox.height; } else if (positions[0] === 'top') { y = this.getTopPosition(bleeding); } else if (positions[1] === 'center') { // default if (this.height === panelRange.height) { y = panelRange.y; } else { //用户自行设定 y = (plotHeight - bbox.height) / 2; } } else if (positions[1] === 'top') { y = bleeding[0]; } else if (positions[1] === 'bottom') { y = plotHeight - bleeding[2] - bbox.height; } this.x = x; this.y = y; this.container.translate(x, y); }; MatrixLegend.prototype.getDefaultOptions = function () { return { text: { style: { fontSize: 12, fill: 'rgba(0, 0, 0, 0.45)', }, }, ticklineStyle: { lineWidth: 1, stroke: 'rgba(0, 0, 0, 0.8)', }, anchorStyle: { fill: 'rgba(0,0,0,0.5)', }, triggerOn: 'mousemove', }; }; MatrixLegend.prototype.addInteraction = function () { var _this = this; var geomType; if (this.options.plot.options.shapeType === 'rect') { geomType = 'polygon'; } else { geomType = 'point'; } var eventName = geomType + ":" + this.options.triggerOn; //const labelEventName = `label:${this.options.triggerOn}`; var field = this.options.plot.options.colorField; var _a = this.colorScale, min = _a.min, max = _a.max; var geomEventHandler = function (ev) { var value = ev.data.data[field]; var ratio = (value - min) / (max - min); _this.moveAnchor(ratio); }; this.view.on(eventName, geomEventHandler); this.interactiveEvents[eventName] = { target: this.view, handler: geomEventHandler, }; /*this.view.on(labelEventName, (ev) => { const value = ev.data[field]; const ratio = (value - min) / (max - min); this.moveAnchor(ratio); });*/ var mouseleaveHandler = function () { _this.anchor.set('visible', false); }; this.options.plot.canvas.on('mouseleave', mouseleaveHandler); this.interactiveEvents.mouseleave = { target: this.options.plot.canvas, handler: mouseleaveHandler, }; }; MatrixLegend.prototype.moveAnchor = function (ratio) { this.anchor.set('visible', true); if (this.layout === 'vertical') { var pos = this.height * ratio; var ulMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; ulMatrix[7] = pos; this.anchor.stopAnimate(); this.anchor.animate({ matrix: ulMatrix, }, 400, 'easeLinear'); } else { var pos = this.width * ratio; var ulMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; ulMatrix[6] = pos; this.anchor.stopAnimate(); this.anchor.animate({ matrix: ulMatrix, }, 400, 'easeLinear'); } }; MatrixLegend.prototype.getTopPosition = function (bleeding) { if (this.options.plot.description) { var bbox = this.options.plot.description.getBBox(); return bbox.maxY + 10; } else if (this.options.plot.title) { var bbox = this.options.plot.title.getBBox(); return bbox.maxY + 10; } return bleeding[0]; }; MatrixLegend.prototype.offEvent = function () { util_1.each(this.interactiveEvents, function (event, key) { var target = event.target, handler = event.handler; target.off(key, handler); }); }; return MatrixLegend; }()); exports.default = MatrixLegend; },{"../../../util/bbox":672,"@antv/util":803,"tslib":894}],539:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Heatmap = /** @class */ (function (_super) { tslib_1.__extends(Heatmap, _super); function Heatmap() { return _super !== null && _super.apply(this, arguments) || this; } Heatmap.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'heatmap'; _super.prototype.createLayers.call(this, layerProps); }; Heatmap.prototype.changeShape = function (type) { var layer = this.layers[0]; layer.changeShape(type); }; Heatmap.prototype.mappingSize = function (field) { var layer = this.layers[0]; layer.mappingSize(field); }; Heatmap.prototype.disableMappingSize = function () { var layer = this.layers[0]; layer.disableMappingSize(); }; Heatmap.prototype.getSizeScale = function () { var layer = this.layers[0]; return layer.getSizeScale(); }; Heatmap.getDefaultOptions = layer_1.default.getDefaultOptions; return Heatmap; }(plot_1.default)); exports.default = Heatmap; },{"../../base/plot":394,"./layer":540,"@antv/util":803,"tslib":894}],540:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var scale_1 = require("@antv/scale"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var shape_1 = require("./shape"); var component_1 = require("./component"); var HeatmapLayer = /** @class */ (function (_super) { tslib_1.__extends(HeatmapLayer, _super); function HeatmapLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'heatmap'; _this.gridSize = []; _this.plotComponents = []; return _this; } HeatmapLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { shapeType: 'rect', legend: { visible: true, position: 'right-center', }, tooltip: { shared: false, showCrosshairs: false, showMarkers: false, }, xAxis: { visible: true, gridAlign: 'center', grid: { visible: true, }, tickLine: { visible: true, }, line: { visible: false, }, label: { visible: true, autoHide: true, autoRotate: true, }, }, yAxis: { visible: true, gridAlign: 'center', grid: { visible: true, align: 'center', }, tickLine: { visible: true, }, label: { autoHide: true, autoRotate: false, }, }, color: ['#9ae3d5', '#66cdbb', '#e7a744', '#f1e066', '#f27664', '#e7c1a2'], label: { visible: true, adjustColor: true, adjustPosition: true, offset: 0, style: { stroke: 'rgba(255,255,255,0)', lineWidth: 0, }, }, interactions: [{ type: 'tooltip' }], }); }; HeatmapLayer.prototype.afterRender = function () { this.renderPlotComponents(); _super.prototype.afterRender.call(this); }; HeatmapLayer.prototype.changeShape = function (type) { if (this.options.shapeType === type) { return; } this.options.shapeType = type; if (type === 'rect') { var shapes = this.getShape(); this.circleToRect(shapes); } else if (type === 'circle') { var shapes = this.getShape(); this.rectToCircle(shapes); } }; HeatmapLayer.prototype.mappingSize = function (field) { if (this.options.sizeField && this.options.sizeField === field) { return; } this.options.sizeField = field; // 创建scale var values = util_1.valuesOfKey(this.options.data, field); var min = Math.min.apply(Math, values); var max = Math.max.apply(Math, values); var LinearScale = scale_1.getScale('linear'); var scale = new LinearScale({ min: min, max: max, }); var shapes = this.getShape(); if (this.options.shapeType === 'rect') { this.rectSizeMapping(shapes, scale, field); } else if (this.options.shapeType === 'circle') { this.circleSizeMapping(shapes, scale, field); } }; HeatmapLayer.prototype.disableMappingSize = function () { var shapes = this.getShape(); if (this.options.shapeType === 'rect') { this.rectDisableSizeMapping(shapes); } else if (this.options.shapeType === 'circle') { this.circleDisableSizeMapping(shapes); } }; HeatmapLayer.prototype.destroy = function () { util_1.each(this.plotComponents, function (component) { component.destroy(); }); _super.prototype.destroy.call(this); }; HeatmapLayer.prototype.getSizeScale = function () { var sizeField = this.options.sizeField; if (sizeField) { this.view.getScaleByField(sizeField); } }; HeatmapLayer.prototype.geometryParser = function () { return ''; }; HeatmapLayer.prototype.coord = function () { return; }; HeatmapLayer.prototype.legend = function () { this.setConfig('legends', false); }; HeatmapLayer.prototype.addGeometry = function () { this.gridSize = this.getGridSize(); var geomConfig; if (this.options.shapeType === 'rect') { geomConfig = this.addRect(); } else { var circle = this.addCircle(); geomConfig = circle; } if (this.options.shapeStyle) { var styleConfig = {}; if (util_1.isFunction(this.options.shapeStyle)) { styleConfig.fields = [ this.options.colorField, this.options.xField, this.options.yField, this.options.sizeField, ]; styleConfig.callback = this.options.shapeStyle; } else if (util_1.isObject(this.options.shapeStyle)) { styleConfig.cfg = this.options.shapeStyle; } geomConfig.style = styleConfig; } if (this.options.tooltip && (this.options.tooltip.fields || this.options.tooltip.formatter)) { this.geometryTooltip(geomConfig); } this.setConfig('geometry', geomConfig); }; HeatmapLayer.prototype.addRect = function () { // 如果用户设置了size,将size数值转换为[0,1]区间 var size = [0.3, 0.9]; if (this.options.shapeSize) { size[0] = this.options.shapeSize[0] / this.gridSize[0]; size[1] = this.options.shapeSize[1] / this.gridSize[1]; } var rect = { type: 'polygon', position: { fields: [this.options.xField, this.options.yField], }, color: { fields: [this.options.colorField], values: this.options.color, }, shape: { values: ['rect'], }, label: false, }; if (this.options.sizeField) { rect.size = { fields: [this.options.sizeField], values: size, }; } else { rect.size = { values: [1], }; } return rect; }; HeatmapLayer.prototype.addCircle = function () { var size = [0.3, 0.9]; if (this.options.shapeSize) { size = this.options.shapeSize; } else { size[0] = this.gridSize[0] * size[0] * 0.5; size[1] = this.gridSize[1] * size[1] * 0.5; } var circle = { type: 'point', position: { fields: [this.options.xField, this.options.yField], }, color: { fields: [this.options.colorField], values: this.options.color, }, shape: { values: ['curvePoint'], }, label: false, }; if (this.options.sizeField) { circle.size = { fields: [this.options.sizeField], values: size, }; } else { circle.size = { values: [Math.min(this.gridSize[0], this.gridSize[1]) * 0.5 * 0.9], }; } return circle; }; HeatmapLayer.prototype.geometryTooltip = function (config) { config.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { config.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { config.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { config.tooltip.fields = [this.options.xField, this.options.yField]; if (this.options.colorField) { config.tooltip.fields.push(this.options.colorField); } } } }; HeatmapLayer.prototype.getGridSize = function () { if (this.options.padding === 'auto') { return [0, 0]; } else { var viewRange = this.getViewRange(); var _a = this.options, padding = _a.padding, xField = _a.xField, yField = _a.yField, data = _a.data; var width = viewRange.width - padding[1] - padding[3]; var height = viewRange.height - padding[0] - padding[2]; var xCount = util_1.valuesOfKey(data, xField).length; var yCount = util_1.valuesOfKey(data, yField).length; return [width / xCount, height / yCount]; } }; HeatmapLayer.prototype.circleToRect = function (shapes) { var _this = this; var gridSize = this.gridSize; util_1.each(shapes, function (shape) { var _a = shape.get('origin'), x = _a.x, y = _a.y, size = _a.size; var sizeRatio = (size * 2) / Math.min(gridSize[0], gridSize[1]); if (!_this.options.sizeField) { sizeRatio = 1; } var curvePath = shape_1.getCircleCurve(x, y, size); var rectPath = shape_1.getRectPath(x, y, gridSize[0], gridSize[1], sizeRatio); shape.stopAnimate(); shape.attr('path', curvePath); shape.animate({ path: rectPath, }, 500, 'easeLinear'); }); }; HeatmapLayer.prototype.rectToCircle = function (shapes) { var _this = this; util_1.each(shapes, function (shape) { var coord = shape.get('coord'); var points = shape.get('origin').points; var ps = []; util_1.each(points, function (p) { ps.push(coord.convertPoint(p)); }); var bbox = shape.getBBox(); var width = bbox.width; var height = bbox.height; var centerX = bbox.minX + width / 2; var centerY = bbox.minY + height / 2; var offsetRatio = _this.options.sizeField ? 1 : 0.9; var curvePath = shape_1.getCircleCurve(centerX, centerY, (Math.min(width, height) / 2) * offsetRatio); var circlePath = shape_1.getCirclePath(centerX, centerY, (Math.min(width, height) / 2) * offsetRatio); shape.stopAnimate(); shape.animate({ path: curvePath, }, 500, 'easeLinear', function () { shape.attr('path', circlePath); }); }); }; HeatmapLayer.prototype.rectSizeMapping = function (shapes, scale, field) { util_1.each(shapes, function (shape) { var data = shape.get('origin').data; var ratio = 0.3 + scale.scale(data[field]) * 0.6; shape.get('origin').size = ratio; var bbox = shape.getBBox(); var width = bbox.width; var height = bbox.height; var centerX = bbox.minX + width / 2; var centerY = bbox.minY + height / 2; var path = shape_1.getRectPath(centerX, centerY, width, height, ratio); shape.stopAnimate(); shape.animate({ path: path, }, 500, 'easeLinear'); }); }; HeatmapLayer.prototype.circleSizeMapping = function (shapes, scale, field) { util_1.each(shapes, function (shape) { var data = shape.get('origin').data; var ratio = 0.3 + scale.scale(data[field]) * 0.6; var _a = shape.get('origin'), x = _a.x, y = _a.y, size = _a.size; var path = shape_1.getCirclePath(x, y, size * ratio); shape.get('origin').size = size * ratio; shape.stopAnimate(); shape.animate({ path: path, }, 500, 'easeLinear'); }); }; HeatmapLayer.prototype.circleDisableSizeMapping = function (shapes) { var _this = this; this.options.sizeField = null; util_1.each(shapes, function (shape) { var _a = shape.get('origin'), x = _a.x, y = _a.y; var size = Math.min(_this.gridSize[0], _this.gridSize[1]) * 0.9; shape.get('origin').size = size / 2; var path = shape_1.getCirclePath(x, y, size / 2); shape.stopAnimate(); shape.animate({ path: path, }, 500, 'easeLinear'); }); }; HeatmapLayer.prototype.rectDisableSizeMapping = function (shapes) { var _this = this; this.options.sizeField = null; util_1.each(shapes, function (shape) { var bbox = shape.getBBox(); var width = bbox.width; var height = bbox.height; var centerX = bbox.minX + width / 2; var centerY = bbox.minY + height / 2; var path = shape_1.getRectPath(centerX, centerY, _this.gridSize[0], _this.gridSize[1], 1); shape.get('origin').size = 1; shape.stopAnimate(); shape.animate({ path: path, }, 500, 'easeLinear'); }); }; HeatmapLayer.prototype.getShape = function () { var elements = this.view.geometries[0].elements; var shapes = []; util_1.each(elements, function (ele) { shapes.push(ele.shape); }); return shapes; }; HeatmapLayer.prototype.renderPlotComponents = function () { var _this = this; util_1.each(this.plotComponents, function (component) { component.destroy(); }); this.plotComponents = []; var componentsType = ['label', 'legend']; util_1.each(componentsType, function (t) { var cfg = tslib_1.__assign({ view: _this.view, plot: _this }, _this.options[t]); var component = component_1.getPlotComponents(_this, t, cfg); if (component) { component.render(); _this.plotComponents.push(component); } }); }; return HeatmapLayer; }(view_layer_1.default)); exports.default = HeatmapLayer; global_1.registerPlotType('heatmap', HeatmapLayer); },{"../../base/global":392,"../../base/view-layer":395,"./component":536,"./shape":541,"@antv/scale":747,"@antv/util":803,"tslib":894}],541:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCircleCurve = exports.getCirclePath = exports.getRectPath = void 0; var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); function getRectPath(cx, cy, width, height, size) { var w = width * size; var h = height * size; var path = [ ['M', cx - w / 2, cy + h / 2], ['Q', cx - w / 2, cy, cx - w / 2, cy - h / 2], ['Q', cx, cy - h / 2, cx + w / 2, cy - h / 2], ['Q', cx + w / 2, cy, cx + w / 2, cy + h / 2], ['Q', cx, cy + h / 2, cx - w / 2, cy + h / 2], ['Z'], ]; return path; } exports.getRectPath = getRectPath; function getCirclePath(x, y, size) { var path = [ ['M', x, y], ['l', -size, 0], ['a', size, size, 0, 1, 0, size * 2, 0], ['a', size, size, 0, 1, 0, -(size * 2), 0], ['Z'], ]; return path; } exports.getCirclePath = getCirclePath; function getCircleCurve(x, y, size) { // 计算四个角和中点 var path = [ ['M', x - size, y], ['Q', x - size, y - size, x, y - size], ['Q', x + size, y - size, x + size, y], ['Q', x + size, y + size, x, y + size], ['Q', x - size, y + size, x - size, y], ['Z'], ]; return path; } exports.getCircleCurve = getCircleCurve; dependents_1.registerShape('polygon', 'rect', { draw: function (cfg, container) { var points = this.parsePoints(cfg.points); var width = points[2].x - points[0].x; var height = points[0].y - points[1].y; var centerX = points[0].x + width / 2; var centerY = points[1].y + height / 2; /* const path = [ ['M', centerX - w / 2, centerY + h / 2], ['L', centerX - w / 2, centerY - h / 2], ['L', centerX + w / 2, centerY - h / 2], ['L', centerX + w / 2, centerY + h / 2], ['Z'], ]; */ var path = getRectPath(centerX, centerY, width, height, cfg.size); return container.addShape('path', { attrs: util_1.deepMix({}, { path: path, fill: cfg.color, opacity: 1, }, cfg.style), }); }, }); dependents_1.registerShape('point', 'curvePoint', { draw: function (cfg, container) { var path = getCirclePath(cfg.x, cfg.y, cfg.size); return container.addShape('path', { attrs: util_1.deepMix({}, { path: path, fill: cfg.color, opacity: 1, }, cfg.style), }); }, }); },{"../../dependents":425,"@antv/util":803}],542:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Histogram = /** @class */ (function (_super) { tslib_1.__extends(Histogram, _super); function Histogram() { return _super !== null && _super.apply(this, arguments) || this; } Histogram.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'histogram'; _super.prototype.createLayers.call(this, layerProps); }; Histogram.getDefaultOptions = layer_1.default.getDefaultOptions; return Histogram; }(plot_1.default)); exports.default = Histogram; },{"../../base/plot":394,"./layer":543,"@antv/util":803,"tslib":894}],543:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var math_1 = require("../../util/math"); var layer_1 = tslib_1.__importDefault(require("../column/layer")); var HistogramLayer = /** @class */ (function (_super) { tslib_1.__extends(HistogramLayer, _super); function HistogramLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'histogram'; return _this; } HistogramLayer.prototype.init = function () { this.options.xField = 'range'; this.options.yField = 'count'; _super.prototype.init.call(this); }; HistogramLayer.prototype.processData = function (originData) { var _this = this; var _a = this.options, binField = _a.binField, binWidth = _a.binWidth, binNumber = _a.binNumber; var originData_copy = util_1.clone(originData); // 根据binField value对源数据进行排序 util_1.sortBy(originData_copy, binField); // 获取源数据binField values的range var values = util_1.valuesOfKey(originData_copy, binField); var range = util_1.getRange(values); var rangeWidth = range.max - range.min; // 计算分箱,直方图分箱的计算基于binWidth,如配置了binNumber则将其转为binWidth进行计算 var _binWidth = binWidth; if (!binWidth && binNumber) { _binWidth = rangeWidth / binNumber; } // 当binWidth和binNumber都没有指定的情况,采用Sturges formula自动生成binWidth if (!binWidth && !binNumber) { var _defaultBinNumber = math_1.sturges(values); _binWidth = rangeWidth / _defaultBinNumber; } var bins = {}; util_1.each(originData_copy, function (data) { var value = data[binField]; var bin = _this.getBin(value, _binWidth); var binName = bin[0] + "-" + bin[1]; if (!util_1.hasKey(bins, binName)) { bins[binName] = { name: binName, range: bin, count: 0, data: [] }; } bins[binName].data.push(data); bins[binName].count += 1; }); // 将分箱数据转换为plotData var plotData = []; util_1.each(bins, function (bin) { plotData.push(bin); }); return plotData; }; HistogramLayer.prototype.scale = function () { _super.prototype.scale.call(this); // fixme: 类型定义 var range = this.config.scales.range; range.nice = false; range.type = 'linear'; }; HistogramLayer.prototype.getBin = function (value, binWidth) { var index = Math.floor(value / binWidth); return [binWidth * index, binWidth * (index + 1)]; }; return HistogramLayer; }(layer_1.default)); exports.default = HistogramLayer; global_1.registerPlotType('histogram', HistogramLayer); },{"../../base/global":392,"../../util/math":680,"../column/layer":490,"@antv/util":803,"tslib":894}],544:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var line_1 = require("./line"); Object.defineProperty(exports, "Line", { enumerable: true, get: function () { return line_1.default; } }); var treemap_1 = require("./treemap"); Object.defineProperty(exports, "Treemap", { enumerable: true, get: function () { return treemap_1.default; } }); var step_line_1 = require("./step-line"); Object.defineProperty(exports, "StepLine", { enumerable: true, get: function () { return step_line_1.default; } }); var bar_1 = require("./bar"); Object.defineProperty(exports, "Bar", { enumerable: true, get: function () { return bar_1.default; } }); var stacked_bar_1 = require("./stacked-bar"); Object.defineProperty(exports, "StackedBar", { enumerable: true, get: function () { return stacked_bar_1.default; } }); var grouped_bar_1 = require("./grouped-bar"); Object.defineProperty(exports, "GroupedBar", { enumerable: true, get: function () { return grouped_bar_1.default; } }); var percent_stacked_bar_1 = require("./percent-stacked-bar"); Object.defineProperty(exports, "PercentStackedBar", { enumerable: true, get: function () { return percent_stacked_bar_1.default; } }); var range_bar_1 = require("./range-bar"); Object.defineProperty(exports, "RangeBar", { enumerable: true, get: function () { return range_bar_1.default; } }); var area_1 = require("./area"); Object.defineProperty(exports, "Area", { enumerable: true, get: function () { return area_1.default; } }); var stacked_area_1 = require("./stacked-area"); Object.defineProperty(exports, "StackedArea", { enumerable: true, get: function () { return stacked_area_1.default; } }); var percent_stacked_area_1 = require("./percent-stacked-area"); Object.defineProperty(exports, "PercentStackedArea", { enumerable: true, get: function () { return percent_stacked_area_1.default; } }); var column_1 = require("./column"); Object.defineProperty(exports, "Column", { enumerable: true, get: function () { return column_1.default; } }); var label_1 = require("./column/component/label"); Object.defineProperty(exports, "ColumnLabel", { enumerable: true, get: function () { return label_1.default; } }); var grouped_column_1 = require("./grouped-column"); Object.defineProperty(exports, "GroupedColumn", { enumerable: true, get: function () { return grouped_column_1.default; } }); var stacked_column_1 = require("./stacked-column"); Object.defineProperty(exports, "StackedColumn", { enumerable: true, get: function () { return stacked_column_1.default; } }); var label_2 = require("./stacked-column/component/label"); Object.defineProperty(exports, "StackedColumnLabel", { enumerable: true, get: function () { return label_2.default; } }); var range_column_1 = require("./range-column"); Object.defineProperty(exports, "RangeColumn", { enumerable: true, get: function () { return range_column_1.default; } }); var percent_stacked_column_1 = require("./percent-stacked-column"); Object.defineProperty(exports, "PercentStackedColumn", { enumerable: true, get: function () { return percent_stacked_column_1.default; } }); var pie_1 = require("./pie"); Object.defineProperty(exports, "Pie", { enumerable: true, get: function () { return pie_1.default; } }); var density_heatmap_1 = require("./density-heatmap"); Object.defineProperty(exports, "DensityHeatmap", { enumerable: true, get: function () { return density_heatmap_1.default; } }); var heatmap_1 = require("./heatmap"); Object.defineProperty(exports, "Heatmap", { enumerable: true, get: function () { return heatmap_1.default; } }); var word_cloud_1 = require("./word-cloud"); Object.defineProperty(exports, "WordCloud", { enumerable: true, get: function () { return word_cloud_1.default; } }); var rose_1 = require("./rose"); Object.defineProperty(exports, "Rose", { enumerable: true, get: function () { return rose_1.default; } }); var funnel_1 = require("./funnel"); Object.defineProperty(exports, "Funnel", { enumerable: true, get: function () { return funnel_1.default; } }); var stacked_rose_1 = require("./stacked-rose"); Object.defineProperty(exports, "StackedRose", { enumerable: true, get: function () { return stacked_rose_1.default; } }); var grouped_rose_1 = require("./grouped-rose"); Object.defineProperty(exports, "GroupedRose", { enumerable: true, get: function () { return grouped_rose_1.default; } }); var radar_1 = require("./radar"); Object.defineProperty(exports, "Radar", { enumerable: true, get: function () { return radar_1.default; } }); var liquid_1 = require("./liquid"); Object.defineProperty(exports, "Liquid", { enumerable: true, get: function () { return liquid_1.default; } }); var histogram_1 = require("./histogram"); Object.defineProperty(exports, "Histogram", { enumerable: true, get: function () { return histogram_1.default; } }); var density_1 = require("./density"); Object.defineProperty(exports, "Density", { enumerable: true, get: function () { return density_1.default; } }); var donut_1 = require("./donut"); Object.defineProperty(exports, "Donut", { enumerable: true, get: function () { return donut_1.default; } }); var waterfall_1 = require("./waterfall"); Object.defineProperty(exports, "Waterfall", { enumerable: true, get: function () { return waterfall_1.default; } }); var scatter_1 = require("./scatter"); Object.defineProperty(exports, "Scatter", { enumerable: true, get: function () { return scatter_1.default; } }); var bubble_1 = require("./bubble"); Object.defineProperty(exports, "Bubble", { enumerable: true, get: function () { return bubble_1.default; } }); var bullet_1 = require("./bullet"); Object.defineProperty(exports, "Bullet", { enumerable: true, get: function () { return bullet_1.default; } }); var calendar_1 = require("./calendar"); Object.defineProperty(exports, "Calendar", { enumerable: true, get: function () { return calendar_1.default; } }); var gauge_1 = require("./gauge"); Object.defineProperty(exports, "Gauge", { enumerable: true, get: function () { return gauge_1.default; } }); var fan_gauge_1 = require("./fan-gauge"); Object.defineProperty(exports, "FanGauge", { enumerable: true, get: function () { return fan_gauge_1.default; } }); var meter_gauge_1 = require("./meter-gauge"); Object.defineProperty(exports, "MeterGauge", { enumerable: true, get: function () { return meter_gauge_1.default; } }); tslib_1.__exportStar(require("./compatiblePlots"), exports); },{"./area":455,"./bar":463,"./bubble":466,"./bullet":473,"./calendar":478,"./column":489,"./column/component/label":487,"./compatiblePlots":494,"./density":508,"./density-heatmap":506,"./donut":513,"./fan-gauge":515,"./funnel":521,"./gauge":526,"./grouped-bar":528,"./grouped-column":531,"./grouped-rose":534,"./heatmap":539,"./histogram":542,"./line":552,"./liquid":565,"./meter-gauge":567,"./percent-stacked-area":569,"./percent-stacked-bar":571,"./percent-stacked-column":573,"./pie":583,"./radar":587,"./range-bar":592,"./range-column":596,"./rose":599,"./scatter":604,"./stacked-area":612,"./stacked-bar":617,"./stacked-column":622,"./stacked-column/component/label":621,"./stacked-rose":625,"./step-line":627,"./treemap":631,"./waterfall":643,"./word-cloud":645,"tslib":894}],545:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlotOption = void 0; var dependents_1 = require("../../../dependents"); var util_1 = require("@antv/util"); var plotInfo; function clipingWithData(shape, animateCfg) { var defaultCfg = { easing: 'easeLinear', duration: 10000, }; var animationConfig = util_1.deepMix({}, animateCfg, defaultCfg); var geometry = shape.get('element').geometry; geometry.labelsContainer.set('visible', false); /** 动画初始状态 */ var index = shape.get('index'); var coord = geometry.coordinate; var scales = geometry.scales; var yScale = scales[plotInfo.options.yField]; var shapeData = util_1.clone(shape.get('origin')); setClip(shape, coord); var clip = shape.get('clipShape'); var parent = shape.get('parent'); var offsetX = 12; var title = null; var seriesField = plotInfo.options.seriesField; if (seriesField) { title = parent.addShape('text', { attrs: { x: coord.start.x + offsetX, y: 0, text: shapeData.data[0][seriesField], fill: shape.attr('stroke'), fontSize: 12, textAlign: 'start', textBaseline: 'middle', }, }); } var offsetY = title ? 16 : 0; var marker = parent.addShape('text', { attrs: { x: coord.start.x + offsetX, y: offsetY, text: "test" + index, fill: shape.attr('stroke'), fontSize: 12, textAlign: 'start', textBaseline: 'middle', }, }); /** 动画执行之后 */ animationConfig.callback = function () { if (shape && !shape.get('destroyed')) { shape.setClip(null); clip.remove(); marker.animate({ opacity: 0, }, 300, function () { marker.remove(); if (!util_1.isNil(title)) { title.remove(); } var labelsContainer = geometry.labelsContainer; if (!labelsContainer.get('visible')) { labelsContainer.set('visible', true); } }); } }; /** 执行动画 */ /** 准备动画参数 */ var delay = animationConfig.delay; if (util_1.isFunction(delay)) { delay = animationConfig.delay(index); } var easing = animationConfig.easing; if (util_1.isFunction(easing)) { easing = animationConfig.easing(index); } /** 动起来 */ clip.animate({ width: coord.getWidth(), }, animationConfig.duration, easing, animationConfig.callback, delay); (animationConfig.onFrame = function (ratio) { var position = getPositionByRatio(ratio, shapeData, coord); if (!position) return; marker.attr('x', position[0] + offsetX); marker.attr('y', position[1] + offsetY); var yText = getDataByPosition(yScale, position[1], coord); // use formatter if (yScale.formatter) { yText = yScale.formatter(yText); } marker.attr('text', yText); }), marker.animate(animationConfig.onFrame, { duration: animationConfig.duration, easing: easing, callback: animationConfig.callback, delay: delay, }); if (title) { title.animate({ onFrame: function (ratio) { var position = getPositionByRatio(ratio, shapeData, coord); if (!position) return; title.attr('x', position[0] + offsetX); title.attr('y', position[1]); }, }, animationConfig.duration, easing, animationConfig.callback, delay); } } function setClip(shape, coord) { var start = coord.start, end = coord.end, height = coord.height; shape.setClip({ type: 'rect', attrs: { x: start.x, y: end.y, width: 0, height: height, }, }); } function getPositionByRatio(ratio, dataPoints, coord) { var points = dataPoints.points; var currentX = coord.start.x + coord.getWidth() * ratio; for (var i = 0; i < points.length - 1; i++) { var current = points[i]; var next = points[i + 1]; if (currentX >= current.x && currentX <= next.x) { var m = (next.y - current.y) / (next.x - current.x); // 斜率 var y = current.y + m * (currentX - current.x); return [currentX, y]; } } } function getDataByPosition(scale, y, coord) { var yRatio = (y - coord.start.y) / (coord.end.y - coord.start.y); return scale.invert(yRatio).toFixed(2); } function getPlotOption(option) { plotInfo = option; } exports.getPlotOption = getPlotOption; dependents_1.registerAnimation('clipingWithData', clipingWithData); },{"../../../dependents":425,"@antv/util":803}],546:[function(require,module,exports){ arguments[4][450][0].apply(exports,arguments) },{"../../../util/responsive/apply/axis":682,"dup":450,"tslib":894}],547:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var axis_1 = tslib_1.__importDefault(require("./axis")); var label_1 = tslib_1.__importDefault(require("./label")); var preRenderResponsive = []; var afterRenderResponsive = [ { name: 'responsiveAxis', method: axis_1.default }, { name: 'responsivePointLabel', method: label_1.default }, ]; exports.default = { preRender: preRenderResponsive, afterRender: afterRenderResponsive, }; },{"./axis":546,"./label":548,"tslib":894}],548:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var label_1 = tslib_1.__importDefault(require("../../../util/responsive/apply/label")); var util_1 = require("@antv/util"); var ApplyResponsiveLineLabel = /** @class */ (function (_super) { tslib_1.__extends(ApplyResponsiveLineLabel, _super); function ApplyResponsiveLineLabel() { return _super !== null && _super.apply(this, arguments) || this; } ApplyResponsiveLineLabel.prototype.getType = function () { return util_1.get(this.plot.options, ['label', 'type'], 'point'); }; return ApplyResponsiveLineLabel; }(label_1.default)); function responsivePointLabel(layer) { var responsiveTheme = layer.getResponsiveTheme(); new ApplyResponsiveLineLabel({ plot: layer, responsiveTheme: responsiveTheme, }); } exports.default = responsivePointLabel; },{"../../../util/responsive/apply/label":684,"@antv/util":803,"tslib":894}],549:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../../util/responsive/theme"); /** 组装theme */ var lineTheme = { label: { point: { constraints: [{ name: 'elementCollision' }], rules: { elementCollision: [{ name: 'nodesResamplingByChange' }, { name: 'clearOverlapping' }], }, }, }, }; theme_1.registerResponsiveTheme('line', lineTheme); },{"../../../util/responsive/theme":711}],550:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var DEFAULT_OFFSET = 8; var LineLabel = /** @class */ (function () { function LineLabel(cfg) { this.destroyed = false; this.view = cfg.view; this.plot = cfg.plot; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); this.init(); } LineLabel.prototype.init = function () { var _this = this; this.container = this.getGeometry().labelsContainer; this.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; LineLabel.prototype.render = function () { var _this = this; var elements = this.getGeometry().elements; util_1.each(elements, function (ele) { var shapeInfo = _this.getShapeInfo(ele.shape); var _a = _this.options, style = _a.style, offsetX = _a.offsetX, offsetY = _a.offsetY; var formatter = _this.options.formatter; var content = formatter ? formatter(shapeInfo.name) : shapeInfo.name; _this.container.addShape('text', { attrs: util_1.deepMix({}, { x: shapeInfo.x + offsetX, y: shapeInfo.y + offsetY, text: content, fill: shapeInfo.color, textAlign: 'left', textBaseline: 'middle', }, style), name: 'label', }); }); }; LineLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; LineLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; LineLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; LineLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; LineLabel.prototype.getBBox = function () { return this.container.getBBox(); }; LineLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = util_1.clone(theme.label.style); delete labelStyle.fill; return { offsetX: DEFAULT_OFFSET, offsetY: 0, style: labelStyle, }; }; LineLabel.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geom) { return geom.type === 'line'; }); }; LineLabel.prototype.getShapeInfo = function (shape) { var originPoints = shape.get('origin').points; var lastPoint = originPoints[originPoints.length - 1]; var color = shape.attr('stroke'); var seriesField = this.plot.options.seriesField; var name = shape.get('origin').data[0][seriesField]; return { x: lastPoint.x, y: lastPoint.y, color: color, name: name }; }; return LineLabel; }()); exports.default = LineLabel; },{"@antv/util":803}],551:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { line: 'line', point: 'point', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],552:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Line = /** @class */ (function (_super) { tslib_1.__extends(Line, _super); function Line() { return _super !== null && _super.apply(this, arguments) || this; } Line.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'line'; _super.prototype.createLayers.call(this, layerProps); }; Line.getDefaultOptions = layer_1.default.getDefaultOptions; return Line; }(plot_1.default)); exports.default = Line; },{"../../base/plot":394,"./layer":558,"@antv/util":803,"tslib":894}],553:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LineSelect = exports.LineActive = void 0; var tslib_1 = require("tslib"); var line_active_1 = tslib_1.__importDefault(require("./line-active")); exports.LineActive = line_active_1.default; var line_select_1 = tslib_1.__importDefault(require("./line-select")); exports.LineSelect = line_select_1.default; var dependents_1 = require("../../../dependents"); var selected_tooltip_1 = require("./selected-tooltip"); var marker_active_1 = tslib_1.__importDefault(require("./marker-active")); dependents_1.registerAction('selected-tooltip', selected_tooltip_1.SelectedTooltipAction); dependents_1.registerInteraction('selected-tooltip', { start: [ { trigger: dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, action: 'selected-tooltip:show' }, { trigger: dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, action: 'selected-tooltip:show' }, { trigger: 'plot:mousemove', action: 'selected-tooltip:show', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'plot:touchmove', action: 'selected-tooltip:show', throttle: { wait: 50, leading: true, trailing: false }, }, ], }); dependents_1.registerAction('marker-active', marker_active_1.default); dependents_1.registerInteraction('marker-active', { start: [ { trigger: dependents_1.VIEW_LIFE_CIRCLE.AFTER_PAINT, action: 'marker-active:show' }, { trigger: dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, action: 'marker-active:show' }, { trigger: 'plot:mousemove', action: 'marker-active:show', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'plot:touchmove', action: 'marker-active:show', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'plot:mouseleave', action: 'marker-active:hide', throttle: { wait: 50, leading: true, trailing: false }, }, { trigger: 'plot:touchend', action: 'marker-active:hide', throttle: { wait: 50, leading: true, trailing: false }, }, ], }); },{"../../../dependents":425,"./line-active":554,"./line-select":555,"./marker-active":556,"./selected-tooltip":557,"tslib":894}],554:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var core_1 = tslib_1.__importDefault(require("../../../interaction/core")); var LineActive = /** @class */ (function (_super) { tslib_1.__extends(LineActive, _super); function LineActive(cfg) { return _super.call(this, tslib_1.__assign({ /** 没有用 line:mouseenter 和 line:mouseleave 事件,是因为可能在多条折线的情况下,从一条线滑动到另一条会同时触发process和reset,使画面出现闪动 */ processEvent: 'mousemove' }, cfg)) || this; } LineActive.prototype.start = function () { return; }; LineActive.prototype.process = function (ev) { var lines = util_1.filter(this.view.geometries, function (geom) { return geom.type == 'line'; }); var target = ev.target; if (target.get('name') === 'line') { var data_1 = util_1.get(ev, 'data.data'); util_1.each(lines, function (line) { util_1.each(line.elements, function (element) { element.setState('active', element.data === data_1); }); }); } else { util_1.each(lines, function (line) { util_1.each(line.elements, function (element) { element.setState('active', false); }); }); } }; return LineActive; }(core_1.default)); exports.default = LineActive; },{"../../../interaction/core":442,"@antv/util":803,"tslib":894}],555:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var core_1 = tslib_1.__importDefault(require("../../../interaction/core")); var LineSelect = /** @class */ (function (_super) { tslib_1.__extends(LineSelect, _super); function LineSelect(cfg) { return _super.call(this, tslib_1.__assign({ endEvent: 'click' }, cfg)) || this; } LineSelect.prototype.start = function () { return; }; LineSelect.prototype.end = function (ev) { var target = ev.target; var lines = util_1.filter(this.view.geometries, function (geom) { return geom.type == 'line'; }); if (target.get('name') === 'line') { var data_1 = util_1.get(ev, 'data.data'); util_1.each(lines, function (line) { util_1.each(line.elements, function (element) { element.setState('inactive', element.data !== data_1); }); }); // TODO: 设置z-index } else { util_1.each(lines, function (line) { util_1.each(line.elements, function (element) { element.setState('inactive', false); }); }); // TODO: 重置z-index } }; return LineSelect; }(core_1.default)); exports.default = LineSelect; },{"../../../interaction/core":442,"@antv/util":803,"tslib":894}],556:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ActiveTooltipController = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../../dependents"); // @ts-ignore var ActiveTooltipController = /** @class */ (function (_super) { tslib_1.__extends(ActiveTooltipController, _super); function ActiveTooltipController() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(ActiveTooltipController.prototype, "name", { get: function () { return 'tooltip-active'; }, enumerable: false, configurable: true }); ActiveTooltipController.prototype.getTooltipCfg = function () { // @ts-ignore var cfg = _super.prototype.getTooltipCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { showCrosshairs: true, showMarkers: false, shared: true }); }; return ActiveTooltipController; }(dependents_1.TooltipController)); exports.ActiveTooltipController = ActiveTooltipController; dependents_1.registerComponentController('tooltip-active', ActiveTooltipController); var MarkerActiveAction = /** @class */ (function (_super) { tslib_1.__extends(MarkerActiveAction, _super); function MarkerActiveAction() { return _super !== null && _super.apply(this, arguments) || this; } MarkerActiveAction.prototype.init = function () { // 移除默认的tooltip交互 this.getView().removeInteraction('tooltip'); }; MarkerActiveAction.prototype.show = function () { var curLocation = this.getPoint(); if (curLocation) { this.showTooltip(curLocation); } }; MarkerActiveAction.prototype.hide = function () { var view = this.getView(); var controller = this.getTooltipController(); controller.hideTooltip(); var points = util_1.filter(view.geometries, function (geom) { return geom.type == 'point'; }); util_1.each(points, function (point) { util_1.each(point.elements, function (element) { element.setState('active', false); }); }); }; MarkerActiveAction.prototype.showTooltip = function (point) { var view = this.getView(); var controller = this.getTooltipController(); controller.showTooltip(point); var items = controller.getTooltipItems(point); var points = util_1.filter(view.geometries, function (geom) { return geom.type == 'point'; }); util_1.each(points, function (point) { util_1.each(point.elements, function (element) { element.setState('active', util_1.findIndex(items, function (item) { return item.data === element.data; }) !== -1); }); }); }; MarkerActiveAction.prototype.getPoint = function () { var ev = this.context.event; return ev ? { x: ev.x, y: ev.y } : null; }; MarkerActiveAction.prototype.getView = function () { return this.context.view; }; MarkerActiveAction.prototype.getTooltipController = function () { return this.getView().getController('tooltip-active'); }; return MarkerActiveAction; }(dependents_1.InteractionAction)); exports.default = MarkerActiveAction; },{"../../../dependents":425,"@antv/util":803,"tslib":894}],557:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SelectedTooltipAction = exports.SelectedTooltipController = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dependents_1 = require("../../../dependents"); // @ts-ignore var SelectedTooltipController = /** @class */ (function (_super) { tslib_1.__extends(SelectedTooltipController, _super); function SelectedTooltipController() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(SelectedTooltipController.prototype, "name", { get: function () { return 'selected-tooltip'; }, enumerable: false, configurable: true }); SelectedTooltipController.prototype.getTooltipCfg = function () { // @ts-ignore var cfg = _super.prototype.getTooltipCfg.call(this); return tslib_1.__assign(tslib_1.__assign({}, cfg), { showContent: false, showCrosshairs: true, showMarkers: true, shared: true }); }; return SelectedTooltipController; }(dependents_1.TooltipController)); exports.SelectedTooltipController = SelectedTooltipController; dependents_1.registerComponentController('selected-tooltip', SelectedTooltipController); var SelectedTooltipAction = /** @class */ (function (_super) { tslib_1.__extends(SelectedTooltipAction, _super); function SelectedTooltipAction() { return _super !== null && _super.apply(this, arguments) || this; } SelectedTooltipAction.prototype.show = function () { var curLocation = this.getPoint(); if (!util_1.isEqual(curLocation, this.location)) { this.location = curLocation; this.showTooltip(curLocation); } }; SelectedTooltipAction.prototype.hide = function () { var controller = this.getTooltipController(); controller.hideTooltip(); }; SelectedTooltipAction.prototype.showTooltip = function (point) { var controller = this.getTooltipController(); controller.showTooltip(point); }; SelectedTooltipAction.prototype.getPoint = function () { var ev = this.context.event; return ev ? { x: ev.x, y: ev.y } : this.getLastXPoint(); }; SelectedTooltipAction.prototype.getLastXPoint = function () { var view = this.getView(); var xScale = view.getXScale(); var yScale = view.getYScales()[0]; var coordinate = view.getCoordinate(); var lastX = util_1.last(xScale.getTicks()).value; return coordinate.convert({ x: lastX, y: (yScale.range[0] + yScale.range[1]) / 2 }); }; SelectedTooltipAction.prototype.getView = function () { return this.context.view; }; SelectedTooltipAction.prototype.getTooltipController = function () { return this.getView().getController('selected-tooltip'); }; return SelectedTooltipAction; }(dependents_1.InteractionAction)); exports.SelectedTooltipAction = SelectedTooltipAction; },{"../../../dependents":425,"@antv/util":803,"tslib":894}],558:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); var scale_1 = require("../../util/scale"); var clipIn_with_data_1 = require("./animation/clipIn-with-data"); var apply_responsive_1 = tslib_1.__importDefault(require("./apply-responsive")); require("../../components/label/point"); require("../../components/label/point-auto"); var line_label_1 = tslib_1.__importDefault(require("./component/label/line-label")); var EventParser = tslib_1.__importStar(require("./event")); var marker_point_1 = tslib_1.__importDefault(require("../../components/marker-point")); require("./theme"); require("./apply-responsive/theme"); var index_1 = require("./interaction/index"); var view_1 = require("../../util/view"); var GEOM_MAP = { line: 'line', point: 'point', }; var LineLayer = /** @class */ (function (_super) { tslib_1.__extends(LineLayer, _super); function LineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'line'; _this.markerPoints = []; return _this; } LineLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { connectNulls: false, smooth: false, lineSize: 2, lineStyle: { lineJoin: 'round', lineCap: 'round', }, point: { visible: false, size: 3, shape: 'circle', }, label: { visible: false, type: 'point', }, legend: { visible: true, position: 'top-left', wordSpacing: 4, }, tooltip: { showContent: true, crosshairs: { line: { style: { stroke: 'rgba(0,0,0,0.45)', }, }, }, }, markerPoints: [], }); }; LineLayer.prototype.afterRender = function () { var _this = this; var options = this.options; this.renderLabel(); if (options.markerPoints) { // 清空 util_1.each(this.markerPoints, function (markerPoint) { return markerPoint.destroy(); }); this.markerPoints = []; options.markerPoints.forEach(function (markerPointOpt) { if (markerPointOpt.visible) { var markerPoint = new marker_point_1.default(tslib_1.__assign(tslib_1.__assign({}, markerPointOpt), { view: _this.view })); _this.markerPoints.push(markerPoint); } }); } // 响应式 if (options.responsive && options.padding !== 'auto') { this.applyResponsive('afterRender'); } _super.prototype.afterRender.call(this); }; LineLayer.prototype.getColorScale = function () { var seriesField = this.options.seriesField; if (seriesField) { return this.view.getScaleByField(seriesField); } }; LineLayer.prototype.geometryParser = function (dim, type) { return GEOM_MAP[type]; }; LineLayer.prototype.scale = function () { var props = this.options; var scales = {}; /** 配置x-scale */ scales[props.xField] = {}; if (util_1.has(props, 'xAxis')) { scale_1.extractScale(scales[props.xField], props.xAxis); } /** 配置y-scale */ scales[props.yField] = {}; if (util_1.has(props, 'yAxis')) { scale_1.extractScale(scales[props.yField], props.yAxis); } this.setConfig('scales', scales); scale_1.trySetScaleMinToZero(scales[props.yField], util_1.map(props.data || [], function (item) { return item[props.yField]; })); _super.prototype.scale.call(this); }; LineLayer.prototype.coord = function () { return; }; LineLayer.prototype.tooltip = function () { // 如果有标注点,则不展示markers if (util_1.some(this.options.markerPoints, function (markerPointOpt) { return markerPointOpt.visible; })) { this.options.tooltip.showMarkers = false; } _super.prototype.tooltip.call(this); }; LineLayer.prototype.addGeometry = function () { // 配置线 this.addLine(); // 配置数据点 this.addPoint(); }; LineLayer.prototype.addLine = function () { var props = this.options; this.line = factory_1.getGeom('line', 'main', { plot: this, }); if (props.tooltip && (props.tooltip.fields || props.tooltip.formatter)) { this.geometryTooltip(); } this.setConfig('geometry', this.line); }; LineLayer.prototype.addPoint = function () { var props = this.options; var defaultConfig = { visible: false }; if (props.point) { props.point = util_1.deepMix(defaultConfig, props.point); } if (props.point && props.point.visible) { this.point = factory_1.getGeom('point', 'guide', { plot: this, }); this.setConfig('geometry', this.point); } }; LineLayer.prototype.renderLabel = function () { var scales = this.config.scales; var _a = this.options, label = _a.label, yField = _a.yField; var scale = scales[yField]; if (label.visible) { var geometry = view_1.getGeometryByType(this.view, 'line'); if (label.type === 'line') { // TODO: Line Label 迁移 var label_1 = new line_label_1.default(tslib_1.__assign({ view: this.view, plot: this }, this.options.label)); label_1.render(); } else { this.doRenderLabel(geometry, tslib_1.__assign({ type: 'point', formatter: scale.formatter && (function (value) { return scale.formatter(value); }) }, this.options.label)); } } }; LineLayer.prototype.geometryTooltip = function () { this.line.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.line.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.line.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.line.tooltip.fields = [this.options.xField, this.options.yField]; if (this.options.seriesField) { this.line.tooltip.fields.push(this.options.seriesField); } } } }; LineLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (!props.animation) { // 关闭动画 this.line.animate = false; if (this.point) this.point.animate = false; } else { clipIn_with_data_1.getPlotOption({ options: this.options, view: this.view, }); this.line.animate = props.animation; } }; LineLayer.prototype.applyInteractions = function () { _super.prototype.applyInteractions.call(this); this.interactions.push(new index_1.LineActive({ view: this.view, })); this.interactions.push(new index_1.LineSelect({ view: this.view, })); }; LineLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; LineLayer.prototype.applyResponsive = function (stage) { var _this = this; var methods = apply_responsive_1.default[stage]; util_1.each(methods, function (r) { var responsive = r; responsive.method(_this); }); }; LineLayer.prototype.singleLineLabelCheck = function () { // 不允许单折线设置尾部跟随label return !this.options.seriesField && this.options.label.type && this.options.label.type === 'line'; }; return LineLayer; }(view_layer_1.default)); exports.default = LineLayer; global_1.registerPlotType('line', LineLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/label/point":417,"../../components/label/point-auto":416,"../../components/marker-point":419,"../../geoms/factory":430,"../../util/scale":712,"../../util/view":715,"./animation/clipIn-with-data":545,"./apply-responsive":547,"./apply-responsive/theme":549,"./component/label/line-label":550,"./event":551,"./interaction/index":553,"./theme":559,"@antv/util":803,"tslib":894}],559:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var LINE_ACTIVE_STYLE = function (_a) { var shape = _a.shape; var lineWidth = shape.attr('lineWidth') || 1; return { lineWidth: lineWidth + 1 }; }; var LINE_DISABLE_STYLE = function (_a) { var shape = _a.shape; var opacity = shape.attr('opacity') || 1; return { opacity: opacity * 0.2 }; }; var LINE_SELECTED_STYLE = function (_a) { var shape = _a.shape; var lineWidth = shape.attr('lineWidth') || 1; return { lineWidth: lineWidth + 2 }; }; theme_1.registerTheme('line', { lineStyle: { normal: {}, active: LINE_ACTIVE_STYLE, disable: LINE_DISABLE_STYLE, selected: LINE_SELECTED_STYLE, }, pointStyle: { normal: {}, active: {}, disable: {}, selected: {}, }, }); },{"../../theme":669}],560:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dependents_1 = require("../../../dependents"); var util_1 = require("@antv/util"); var g_util_1 = require("../../../util/g-util"); function liquidMoveIn(shape, animateCfg) { var container = shape.get('parent'); var box = container.getBBox(); var factor = Math.min(Math.max(0, util_1.get(animateCfg, 'factor', 0.5)), 1); var delay = util_1.get(animateCfg, 'delay', 0); var duration = util_1.get(animateCfg, 'duration', 800); var callback = animateCfg.callback; var originX = (box.minX + box.maxX) / 2; var originY = box.maxY; var wrap = container.find(function (shape) { return shape.get('name') == 'wrap'; }); var wrapTargetOpacity = wrap.attr('opacity'); wrap.attr('opacity', 0); wrap.animate({ opacity: wrapTargetOpacity }, duration * factor, 'easeLinear', null, delay); var waves = container.find(function (shape) { return shape.get('name') == 'waves'; }); var wavesTargetMatrix = util_1.clone(waves.attr('matrix')) || [1, 0, 0, 0, 1, 0, 0, 0, 1]; var transformMatrix = g_util_1.transform(wavesTargetMatrix, [ ['t', -originX, -originY], ['s', 1, 0], ['t', originX, originY], ]); waves.setMatrix(transformMatrix); waves.animate({ matrix: wavesTargetMatrix }, duration, animateCfg.easing, function () { return callback && callback(container, wrap, waves); }, delay); } liquidMoveIn.animationName = 'liquidMoveIn'; dependents_1.registerAnimation('liquidMoveIn', liquidMoveIn); },{"../../../dependents":425,"../../../util/g-util":679,"@antv/util":803}],561:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var statistic_1 = tslib_1.__importDefault(require("../../../components/statistic")); var statistic_template_1 = require("./statistic-template"); var RingStatistic = /** @class */ (function (_super) { tslib_1.__extends(RingStatistic, _super); function RingStatistic(cfg) { var _this = _super.call(this, cfg) || this; _this.view = cfg.view; _this.plot = cfg.plot; _this.statisticClass = cfg.statisticClass; _this.adjustOptions(); return _this; } /** 中心文本显示 */ RingStatistic.prototype.getTotalHtmlString = function () { var statisticContainer = document.createElement('div'); var _a = this.plot.options, _b = _a.value, value = _b === void 0 ? 0 : _b, statistic = _a.statistic; if (statistic && !statistic.visible) { return statisticContainer; } var htmlContent = this.options.htmlContent(value); if (util_1.isType(htmlContent, 'HTMLDivElement')) { statisticContainer.appendChild(htmlContent); } else { statisticContainer.innerHTML = statistic_template_1.getTemplate(htmlContent, this.statisticClass); } return statisticContainer; }; RingStatistic.prototype.adjustOptions = function () { this.html = this.getTotalHtmlString(); var _a = this.view.coordinateBBox, minX = _a.minX, minY = _a.minY, width = _a.width, height = _a.height; this.x = minX + width / 2; this.y = minY + height / 2; }; return RingStatistic; }(statistic_1.default)); exports.default = RingStatistic; },{"../../../components/statistic":420,"./statistic-template":562,"@antv/util":803,"tslib":894}],562:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTemplate = void 0; /*tslint:disable*/ var containerStyle = "color:#4d4d4d;font-size:14px;text-align:center;line-height:2;font-family:'-apple-system',BlinkMacSystemFont,'SegoeUI',Roboto,'HelveticaNeue',Helvetica,'PingFangSC','HiraginoSansGB','MicrosoftYaHei',SimSun,'sans-serif';pointer-events:none;"; var valueStyle = 'font-size:32px;font-weight:bold;color:#4D4D4D'; function getTemplate(value, className) { var valueDomStr = "" + value + ""; return "
      " + valueDomStr + "
      "; } exports.getTemplate = getTemplate; },{}],563:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { liquid: 'intervl', statistic: 'annotation-text', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],564:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dependents_1 = require("../../../../dependents"); var util_1 = require("@antv/util"); var theme_1 = require("../../../../theme"); var g_util_1 = require("../../../../util/g-util"); var globalTheme = theme_1.getGlobalTheme(); var ShapeUtil = { splitPoints: function (obj) { var points = []; var x = obj.x; var y = obj.y; y = util_1.isArray(y) ? y : [y]; util_1.each(y, function (yItem, index) { var point = { x: util_1.isArray(x) ? x[index] : x, y: yItem, }; points.push(point); }); return points; }, addFillAttrs: function (attrs, cfg) { if (cfg.color && !attrs.fill) { attrs.fill = cfg.color; } if (util_1.isNumber(cfg.opacity)) { attrs.opacity = attrs.fillOpacity = cfg.opacity; } }, addStrokeAttrs: function (attrs, cfg) { if (cfg.color && !attrs.stroke) { attrs.stroke = cfg.color; } if (util_1.isNumber(cfg.opacity)) { attrs.opacity = attrs.strokeOpacity = cfg.opacity; } }, }; var ValueUtil = { lerp: function (a, b, factor) { return (1 - factor) * a + factor * b; }, }; var getFillAttrs = function (cfg) { var defaultAttrs = { lineWidth: 0, fill: globalTheme.color, fillOpacity: 0.85, }; var attrs = util_1.mix({}, defaultAttrs, cfg.style); ShapeUtil.addFillAttrs(attrs, cfg); if (cfg.color && !attrs.stroke) { attrs.stroke = attrs.stroke || cfg.color; } return attrs; }; var getLineAttrs = function (cfg) { var defaultAttrs = { fill: '#fff', stroke: globalTheme.color, fillOpacity: 0, lineWidth: 2, }; var attrs = util_1.mix({}, defaultAttrs, cfg.style); ShapeUtil.addStrokeAttrs(attrs, cfg); return attrs; }; /** * 用贝塞尔曲线模拟正弦波 * Using Bezier curves to fit sine wave. * There is 4 control points for each curve of wave, * which is at 1/4 wave length of the sine wave. * * The control points for a wave from (a) to (d) are a-b-c-d: * c *----* d * b * * | * ... a * .................. * * whose positions are a: (0, 0), b: (0.5, 0.5), c: (1, 1), d: (PI / 2, 1) * * @param {number} x x position of the left-most point (a) * @param {number} stage 0-3, stating which part of the wave it is * @param {number} waveLength wave length of the sine wave * @param {number} amplitude wave amplitude * @return {Array} 正弦片段曲线 */ function getWaterWavePositions(x, stage, waveLength, amplitude) { if (stage === 0) { return [ [x + ((1 / 2) * waveLength) / Math.PI / 2, amplitude / 2], [x + ((1 / 2) * waveLength) / Math.PI, amplitude], [x + waveLength / 4, amplitude], ]; } if (stage === 1) { return [ [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 2), amplitude], [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 1), amplitude / 2], [x + waveLength / 4, 0], ]; } if (stage === 2) { return [ [x + ((1 / 2) * waveLength) / Math.PI / 2, -amplitude / 2], [x + ((1 / 2) * waveLength) / Math.PI, -amplitude], [x + waveLength / 4, -amplitude], ]; } return [ [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 2), -amplitude], [x + (((1 / 2) * waveLength) / Math.PI / 2) * (Math.PI - 1), -amplitude / 2], [x + waveLength / 4, 0], ]; } /** * 获取水波路径 * @param {number} radius 半径 * @param {number} waterLevel 水位 * @param {number} waveLength 波长 * @param {number} phase 相位 * @param {number} amplitude 震幅 * @param {number} cx 圆心x * @param {number} cy 圆心y * @return {Array} path 路径 * @reference http://gitlab.alipay-inc.com/datavis/g6/blob/1.2.0/src/graph/utils/path.js#L135 */ function getWaterWavePath(radius, waterLevel, waveLength, phase, amplitude, cx, cy) { var curves = Math.ceil(((2 * radius) / waveLength) * 4) * 2; var path = []; var _phase = phase; // map phase to [-Math.PI * 2, 0] while (_phase < -Math.PI * 2) { _phase += Math.PI * 2; } while (_phase > 0) { _phase -= Math.PI * 2; } _phase = (_phase / Math.PI / 2) * waveLength; var left = cx - radius + _phase - radius * 2; /** * top-left corner as start point * * draws this point * | * \|/ * ~~~~~~~~ * | | * +------+ */ path.push(['M', left, waterLevel]); /** * top wave * * ~~~~~~~~ <- draws this sine wave * | | * +------+ */ var waveRight = 0; for (var c = 0; c < curves; ++c) { var stage = c % 4; var pos = getWaterWavePositions((c * waveLength) / 4, stage, waveLength, amplitude); path.push([ 'C', pos[0][0] + left, -pos[0][1] + waterLevel, pos[1][0] + left, -pos[1][1] + waterLevel, pos[2][0] + left, -pos[2][1] + waterLevel, ]); if (c === curves - 1) { waveRight = pos[2][0]; } } /** * top-right corner * * ~~~~~~~~ * 3. draws this line -> | | <- 1. draws this line * +------+ * ^ * | * 2. draws this line */ path.push(['L', waveRight + left, cy + radius]); path.push(['L', left, cy + radius]); path.push(['L', left, waterLevel]); return path; } /** * 添加水波 * @param {number} x 中心x * @param {number} y 中心y * @param {number} level 水位等级 0~1 * @param {number} waveCount 水波数 * @param {number} colors 色值 * @param {number} group 图组 * @param {number} clip 用于剪切的图形 * @param {number} radius 绘制图形的高度 */ function addWaterWave(x, y, level, waveCount, color, group, clip, radius) { var bbox = clip.getBBox(); var width = bbox.maxX - bbox.minX; var height = bbox.maxY - bbox.minY; var duration = 5000; for (var i = 0; i < waveCount; i++) { var factor = waveCount <= 1 ? 0 : i / (waveCount - 1); var wave = group.addShape('path', { attrs: { path: getWaterWavePath(radius, bbox.minY + height * level, width / 4, 0, width / ValueUtil.lerp(56, 64, factor), x, y), fill: color, opacity: ValueUtil.lerp(0.6, 0.3, factor), }, }); /*wave.setClip({ type:'circle', attrs: clip.attrs })*/ // FIXME wave animation error in svg // if (Global.renderer === 'canvas') { var matrix = g_util_1.transform([['t', width / 2, 0]]); wave.animate({ matrix: matrix }, { duration: ValueUtil.lerp(duration, 0.7 * duration, factor), repeat: true, }); //} } } dependents_1.registerShape('interval', 'liquid-fill-gauge', { draw: function (cfg, container) { var cy = 0.5; var minX = Infinity; util_1.each(cfg.points, function (p) { if (p.x < minX) { minX = p.x; } }); var cx = 0.5; var cp = this.parsePoint({ x: cx, y: cy }); var minP = this.parsePoint({ x: minX, y: 0.5 }); var xWidth = cp.x - minP.x; var radius = Math.min(xWidth, minP.y); var fill = getFillAttrs(cfg).fill; var waves = container.addGroup({ name: 'waves', attrs: { x: cp.x, y: cp.y, }, }); waves.setClip({ type: 'circle', attrs: { x: cp.x, y: cp.y, r: radius, }, }); var clipCircle = waves.get('clipShape'); addWaterWave(cp.x, cp.y, 1 - cfg.points[1].y, // cfg.y / (2 * cp.y), 3, fill, waves, clipCircle, radius * 4); container.addShape('circle', { name: 'wrap', attrs: util_1.mix(getLineAttrs(cfg), { x: cp.x, y: cp.y, r: radius, fill: 'transparent', }), }); return waves[0]; }, }); },{"../../../../dependents":425,"../../../../theme":669,"../../../../util/g-util":679,"@antv/util":803}],565:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Liquid = /** @class */ (function (_super) { tslib_1.__extends(Liquid, _super); function Liquid() { return _super !== null && _super.apply(this, arguments) || this; } Liquid.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'liquid'; _super.prototype.createLayers.call(this, layerProps); }; Liquid.prototype.changeValue = function (value, all) { if (all === void 0) { all = false; } if (all) { this.eachLayer(function (layer) { if (layer instanceof layer_1.default) { layer.changeValue(value); } }); } else { var layer = this.layers[0]; if (layer instanceof layer_1.default) { layer.changeValue(value); } } }; Liquid.getDefaultOptions = layer_1.default.getDefaultOptions; return Liquid; }(plot_1.default)); exports.default = Liquid; },{"../../base/plot":394,"./layer":566,"@antv/util":803,"tslib":894}],566:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var dom_util_1 = require("@antv/dom-util"); var bbox_1 = tslib_1.__importDefault(require("../../util/bbox")); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); var scale_1 = require("../../util/scale"); var color_1 = require("../../util/color"); var liquid_statistic_1 = tslib_1.__importDefault(require("./component/liquid-statistic")); var EventParser = tslib_1.__importStar(require("./event")); require("./geometry/shape/liquid"); require("./animation/liquid-move-in"); var G2_GEOM_MAP = { column: 'interval', }; var PLOT_GEOM_MAP = { interval: 'liquid', }; var LiquidLayer = /** @class */ (function (_super) { tslib_1.__extends(LiquidLayer, _super); function LiquidLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'liquid'; _this.shouldFadeInAnnotation = true; return _this; } LiquidLayer.getDefaultOptions = function () { var cfg = { padding: [0, 0, 0, 0], animation: { factor: 0.4, easing: 'easeExpOut', duration: 800, }, liquidStyle: { lineWidth: 2, }, color: '#6a99f9', interactions: [], statistic: { visible: true, }, }; return util_1.deepMix({}, _super.getDefaultOptions.call(this), cfg); }; LiquidLayer.prototype.beforeInit = function () { var _a = this.options, min = _a.min, max = _a.max, value = _a.value; if (!util_1.isNumber(min)) { throw new Error('The min value of Liquid is required, and the type of min must be Number.'); } if (!util_1.isNumber(max)) { throw new Error('The max value of Liquid is required, and the type of max must be Number.'); } if (!util_1.isNumber(value)) { throw new Error('The value of Liquid is required, and the type of value must be Number.'); } }; LiquidLayer.prototype.init = function () { this.options.data = [{}]; _super.prototype.init.call(this); }; LiquidLayer.prototype.coord = function () { return; }; LiquidLayer.prototype.scale = function () { var props = this.options; var min = props.min, max = props.max; var scales = { value: {}, }; scale_1.extractScale(scales.value, { min: Math.min(min, max), max: Math.max(min, max), }); // @ts-ignore this.setConfig('scales', scales); _super.prototype.scale.call(this); }; LiquidLayer.prototype.axis = function () { this.setConfig('axes', false); }; LiquidLayer.prototype.adjustLiquid = function (liquid) { var props = this.options; liquid.shape = { values: ['liquid-fill-gauge'], }; liquid.tooltip = false; var liquidStyle = props.liquidStyle; if (util_1.isFunction(liquidStyle)) liquidStyle = liquidStyle(); if (liquidStyle) { liquid.style = liquidStyle; } }; LiquidLayer.prototype.addGeometry = function () { var liquid = factory_1.getGeom('interval', 'main', { positionFields: [1, 'value'], plot: this, }); this.adjustLiquid(liquid); var viewRange = this.getViewRange(); var defaultSize = Math.min(viewRange.width, viewRange.height) * 0.8; var liquidSize = this.options.liquidSize ? this.options.liquidSize : defaultSize; liquid.size = { values: [liquidSize] }; this.liquid = liquid; this.setConfig('geometry', liquid); }; LiquidLayer.prototype.animation = function () { var props = this.options; if (props.animation === false) { /** 关闭动画 */ this.liquid.animate = false; } else { var factor = util_1.get(props, 'animation.factor'); var easing = util_1.get(props, 'animation.easing'); var duration = util_1.get(props, 'animation.duration'); this.liquid.animate = { appear: { animation: 'liquidMoveIn', factor: factor, easing: easing, duration: duration, }, }; } }; LiquidLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; LiquidLayer.prototype.annotation = function () { var annotationConfigs = []; var statisticConfig = this.extractStatistic(); annotationConfigs.push(statisticConfig); this.setConfig('annotations', annotationConfigs); }; // 新增 htmlContent 支持,兼容旧功能 LiquidLayer.prototype.useHtmlContent = function () { var props = this.options; var statistic = props.statistic || {}; return util_1.isFunction(statistic.htmlContent); }; LiquidLayer.prototype.extractStatistic = function () { if (this.useHtmlContent()) { return; } var props = this.options; var statistic = props.statistic || {}; var content; if (util_1.isFunction(statistic.formatter)) { content = statistic.formatter(props.value); } else { content = "" + props.value; } var fontSize; var shadowBlur; if (content) { var contentWidth = Math.min(this.width, this.height); fontSize = (contentWidth / content.length) * 0.5; shadowBlur = Math.max(1, Math.ceil(0.025 * fontSize)); } var opacity; if (statistic.visible === false) { return; } var statisticConfig = util_1.deepMix({ style: { fontSize: fontSize, shadowBlur: shadowBlur, }, }, { top: true, content: content, type: 'text', position: ['50%', '50%'], style: { opacity: opacity, fill: 'transparent', shadowColor: 'transparent', textAlign: 'center', }, }, statistic); delete statisticConfig.visible; delete statisticConfig.formatter; delete statisticConfig.adjustColor; return statisticConfig; }; LiquidLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; LiquidLayer.prototype.afterRender = function () { var _a; if (((_a = this.options.statistic) === null || _a === void 0 ? void 0 : _a.visible) && !this.useHtmlContent()) { this.fadeInAnnotation(); } var options = this.options; var padding = options.padding ? options.padding : this.config.theme.padding; /** defaultState */ if (options.defaultState && padding !== 'auto') { this.stateController.defaultStates(options.defaultState); } /** autopadding */ if (padding === 'auto') { this.paddingController.processAutoPadding(); } if (this.useHtmlContent()) { var container = this.canvas.get('container'); if (this.statistic) { container.removeChild(this.statistic.wrapperNode); } /**图中心文本 */ if (this.options.statistic && this.options.statistic.visible) { var container_1 = this.canvas.get('container'); dom_util_1.modifyCSS(container_1, { position: 'relative' }); this.statistic = new liquid_statistic_1.default(tslib_1.__assign({ container: container_1, view: this.view, plot: this }, this.options.statistic)); this.statistic.render(); } _super.prototype.afterRender.call(this); } }; LiquidLayer.prototype.processData = function () { var props = this.options; return [{ _: '_', value: props.value }]; }; LiquidLayer.prototype.changeValue = function (value) { var props = this.options; props.value = value; this.changeData([]); }; LiquidLayer.prototype.fadeInAnnotation = function () { var _this = this; var props = this.options; var textShape = this.view.foregroundGroup.findAll(function (el) { return el.get('name') === 'annotation-text'; })[0]; var animation = props.animation || {}; var colorStyle = this.calcAnnotationColorStyle(); if (this.shouldFadeInAnnotation) { textShape.animate(colorStyle, animation.duration * Math.min(1, 1.5 * animation.factor), null, function () { _this.shouldFadeInAnnotation = false; }); } else { util_1.forIn(colorStyle, function (v, k) { return textShape.attr(k, v); }); } }; LiquidLayer.prototype.calcAnnotationColorStyle = function () { var props = this.options; var lightColorStyle = { fill: '#f6f6f6', shadowColor: 'black' }; var darkColorStyle = { fill: '#303030', shadowColor: 'white' }; if (util_1.get(props, 'statistic.adjustColor') === false) { return { fill: util_1.get(props, 'statistic.style.fill', darkColorStyle.fill), shadowColor: util_1.get(props, 'statistic.style.shadowColor', darkColorStyle.shadowColor), }; } var min = props.min, max = props.max; var value = props.value; min = Math.min(min, max); max = Math.max(min, max); var percent; if (min == max) { percent = 1; } else { percent = (value - min) / (max - min); } if (percent > 0.55) { var waveColor = this.options.color; var waveOpacity = 0.8; var rgb = color_1.rgb2arr(waveColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / waveOpacity; return gray < 156 ? lightColorStyle : darkColorStyle; } return darkColorStyle; }; LiquidLayer.prototype.updateConfig = function (cfg) { _super.prototype.updateConfig.call(this, cfg); this.shouldFadeInAnnotation = true; }; LiquidLayer.prototype.getViewRange = function () { var viewRange = _super.prototype.getViewRange.call(this); var liquidStyle = this.options.liquidStyle; var strokeWidth = liquidStyle.lineWidth ? liquidStyle.lineWidth : 2; var minX = viewRange.minX, minY = viewRange.minY, width = viewRange.width, height = viewRange.height; var size = Math.min(width, height) - strokeWidth * 2; var cx = minX + width / 2; var cy = minY + height / 2; var x = cx - size / 2; var y = cy - size / 2; return new bbox_1.default(x, y, size, size); }; return LiquidLayer; }(view_layer_1.default)); exports.default = LiquidLayer; global_1.registerPlotType('liquid', LiquidLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../geoms/factory":430,"../../util/bbox":672,"../../util/color":673,"../../util/scale":712,"./animation/liquid-move-in":560,"./component/liquid-statistic":561,"./event":563,"./geometry/shape/liquid":564,"@antv/dom-util":92,"@antv/util":803,"tslib":894}],567:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var MeterGauge = /** @class */ (function (_super) { tslib_1.__extends(MeterGauge, _super); function MeterGauge() { return _super !== null && _super.apply(this, arguments) || this; } MeterGauge.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'meterGauge'; _super.prototype.createLayers.call(this, layerProps); }; MeterGauge.getDefaultOptions = layer_1.default.getDefaultOptions; return MeterGauge; }(plot_1.default)); exports.default = MeterGauge; },{"../../base/plot":394,"./layer":568,"@antv/util":803,"tslib":894}],568:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../gauge/layer")); var MeterGaugeLayer = /** @class */ (function (_super) { tslib_1.__extends(MeterGaugeLayer, _super); function MeterGaugeLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'meterGauge'; return _this; } MeterGaugeLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { axis: { visible: true, offset: -10, tickCount: 25, subTickCount: 4, tickLine: { visible: true, length: 2, style: { stroke: '#aaa', lineWidth: 1, }, }, }, }); }; return MeterGaugeLayer; }(layer_1.default)); exports.default = MeterGaugeLayer; global_1.registerPlotType('meterGauge', MeterGaugeLayer); },{"../../base/global":392,"../gauge/layer":527,"@antv/util":803,"tslib":894}],569:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var PercentStackedArea = /** @class */ (function (_super) { tslib_1.__extends(PercentStackedArea, _super); function PercentStackedArea() { return _super !== null && _super.apply(this, arguments) || this; } PercentStackedArea.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'percentStackedArea'; _super.prototype.createLayers.call(this, layerProps); }; PercentStackedArea.getDefaultOptions = layer_1.default.getDefaultOptions; return PercentStackedArea; }(plot_1.default)); exports.default = PercentStackedArea; },{"../../base/plot":394,"./layer":570,"@antv/util":803,"tslib":894}],570:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../stacked-area/layer")); var data_1 = require("../../util/data"); var PercentStackedAreaLayer = /** @class */ (function (_super) { tslib_1.__extends(PercentStackedAreaLayer, _super); function PercentStackedAreaLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'percentStackedArea'; _this.baseType = 'stackedArea'; return _this; } PercentStackedAreaLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { yAxis: { visible: true, label: { visible: true, formatter: function (v) { var reg = /%/gi; return v.replace(reg, ''); }, }, }, }); }; PercentStackedAreaLayer.prototype.processData = function (originData) { var _a = this.options, xField = _a.xField, yField = _a.yField; return data_1.transformDataPercentage(originData, xField, [yField]); }; PercentStackedAreaLayer.prototype.scale = function () { var metaConfig = {}; var yField = this.options.yField; metaConfig[this.options.yField] = { tickCount: 6, alias: yField + " (%)", min: 0, max: 1, formatter: function (v) { var formattedValue = (v * 100).toFixed(1); return formattedValue + "%"; }, }; this.options.meta = util_1.deepMix({}, metaConfig, this.options.meta); _super.prototype.scale.call(this); }; return PercentStackedAreaLayer; }(layer_1.default)); exports.default = PercentStackedAreaLayer; global_1.registerPlotType('percentStackedArea', PercentStackedAreaLayer); },{"../../base/global":392,"../../util/data":675,"../stacked-area/layer":613,"@antv/util":803,"tslib":894}],571:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var PercentStackedBar = /** @class */ (function (_super) { tslib_1.__extends(PercentStackedBar, _super); function PercentStackedBar() { return _super !== null && _super.apply(this, arguments) || this; } PercentStackedBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'percentStackedBar'; _super.prototype.createLayers.call(this, layerProps); }; PercentStackedBar.getDefaultOptions = layer_1.default.getDefaultOptions; return PercentStackedBar; }(plot_1.default)); exports.default = PercentStackedBar; },{"../../base/plot":394,"./layer":572,"@antv/util":803,"tslib":894}],572:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../stacked-bar/layer")); var data_1 = require("../../util/data"); var PercentStackedBarLayer = /** @class */ (function (_super) { tslib_1.__extends(PercentStackedBarLayer, _super); function PercentStackedBarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'percentStackedBar'; return _this; } PercentStackedBarLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, tickLine: { visible: false, }, grid: { visible: false, }, title: { visible: true, formatter: function (v) { return v + " (%)"; }, }, label: { visible: false, formatter: function (v) { var reg = /%/gi; return v.replace(reg, ''); }, }, }, }); }; PercentStackedBarLayer.prototype.processData = function (originData) { var _a = this.options, xField = _a.xField, yField = _a.yField; var processData = _super.prototype.processData.call(this, originData); return data_1.transformDataPercentage(processData, yField, [xField]); }; PercentStackedBarLayer.prototype.scale = function () { var metaConfig = {}; var xField = this.options.xField; metaConfig[xField] = { tickCount: 6, alias: xField + " (%)", min: 0, max: 1, formatter: function (v) { var formattedValue = (v * 100).toFixed(1); return formattedValue + "%"; }, }; this.options.meta = util_1.deepMix({}, this.options.meta, metaConfig); _super.prototype.scale.call(this); }; return PercentStackedBarLayer; }(layer_1.default)); exports.default = PercentStackedBarLayer; global_1.registerPlotType('percentStackedBar', PercentStackedBarLayer); },{"../../base/global":392,"../../util/data":675,"../stacked-bar/layer":618,"@antv/util":803,"tslib":894}],573:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var PercentStackedColumn = /** @class */ (function (_super) { tslib_1.__extends(PercentStackedColumn, _super); function PercentStackedColumn() { return _super !== null && _super.apply(this, arguments) || this; } PercentStackedColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'percentStackedColumn'; _super.prototype.createLayers.call(this, layerProps); }; PercentStackedColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return PercentStackedColumn; }(plot_1.default)); exports.default = PercentStackedColumn; },{"../../base/plot":394,"./layer":574,"@antv/util":803,"tslib":894}],574:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../stacked-column/layer")); var data_1 = require("../../util/data"); var PercentStackedColumnLayer = /** @class */ (function (_super) { tslib_1.__extends(PercentStackedColumnLayer, _super); function PercentStackedColumnLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'percentStackedColumn'; return _this; } PercentStackedColumnLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { label: { visible: true, position: 'middle', offset: 0, }, yAxis: { visible: true, tick: { visible: false, }, grid: { visible: false, }, title: { visible: true, }, label: { visible: false, }, }, }); }; PercentStackedColumnLayer.prototype.processData = function (originData) { var _a = this.options, xField = _a.xField, yField = _a.yField; return data_1.transformDataPercentage(originData || [], xField, [yField]); }; PercentStackedColumnLayer.prototype.scale = function () { var metaConfig = {}; var yField = this.options.yField; metaConfig[yField] = { tickCount: 6, alias: yField + " (%)", min: 0, max: 1, formatter: function (v) { var formattedValue = (v * 100).toFixed(1); return formattedValue + "%"; }, }; this.options.meta = util_1.deepMix({}, this.options.meta, metaConfig); _super.prototype.scale.call(this); }; return PercentStackedColumnLayer; }(layer_1.default)); exports.default = PercentStackedColumnLayer; global_1.registerPlotType('percentStackedColumn', PercentStackedColumnLayer); },{"../../base/global":392,"../../util/data":675,"../stacked-column/layer":623,"@antv/util":803,"tslib":894}],575:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.percent2Number = exports.CROOK_DISTANCE = void 0; var tslib_1 = require("tslib"); var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var utils_1 = require("./utils"); var text_1 = require("../../../../util/text"); /** label text和line距离 4px */ exports.CROOK_DISTANCE = 4; function percent2Number(value) { var percentage = Number(value.endsWith('%') ? value.slice(0, -1) : value); return percentage / 100; } exports.percent2Number = percent2Number; /** * 超出panel边界的标签默认隐藏 */ function checkInPanel(label, panel) { var box = label.getBBox(); // 横向溢出 暂不隐藏 if (!(panel.y <= box.y && panel.y + panel.height >= box.y + box.height)) { label.get('parent').set('visible', false); } } var PieBaseLabel = /** @class */ (function () { function PieBaseLabel(plot, cfg) { this.destroyed = false; this.plot = plot; this.coordinateBBox = this.plot.view.coordinateBBox; var options = util_1.deepMix(this.getDefaultOptions(), cfg, {}); this.adjustOption(options); this.options = options; this.init(); } /** 处理标签遮挡问题 */ PieBaseLabel.prototype.adjustOverlap = function (labels, panel) { // clearOverlap; for (var i = 1; i < labels.length; i++) { var label = labels[i]; var overlapArea = 0; for (var j = i - 1; j >= 0; j--) { var prev = labels[j]; // fix: start draw point.x is error when textAlign is right var prevBox = prev.getBBox(); var currBox = label.getBBox(); // if the previous one is invisible, skip if (prev.get('parent').get('visible')) { overlapArea = utils_1.getOverlapArea(prevBox, currBox); if (!utils_1.near(overlapArea, 0)) { label.get('parent').set('visible', false); break; } } } } labels.forEach(function (label) { return checkInPanel(label, panel); }); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars PieBaseLabel.prototype.adjustItem = function (item) { return; }; PieBaseLabel.prototype.init = function () { var _this = this; this.container = this.getGeometry().labelsContainer; this.plot.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; PieBaseLabel.prototype.render = function () { // 先清空 再重新渲染(避免双次绘制) this.clear(); this.initArcPoints(); this.drawTexts(); this.drawLines(); }; PieBaseLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; PieBaseLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; PieBaseLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; PieBaseLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; PieBaseLabel.prototype.getFilteredSum = function () { var angleField = this.plot.options.angleField; var filteredData = this.plot.view.filteredData || []; return filteredData.reduce(function (pre, filteredDataItem) { return pre + filteredDataItem[angleField]; }, 0); }; /** 绘制文本 */ PieBaseLabel.prototype.drawTexts = function () { var _this = this; var _a = this.options, style = _a.style, formatter = _a.formatter, autoRotate = _a.autoRotate, offsetX = _a.offsetX, offsetY = _a.offsetY, adjustPosition = _a.adjustPosition, allowOverlap = _a.allowOverlap; var shapeInfos = this.getItems(); var shapes = []; shapeInfos.map(function (shapeInfo, idx) { var attrs = util_1.deepMix({}, shapeInfo, style); var filteredSum = _this.getFilteredSum(); var angleField = _this.plot.options.angleField; var percent = shapeInfo.origin[angleField] / filteredSum; var content = formatter ? formatter(shapeInfo.name, { _origin: shapeInfo.origin, percent: percent, }, idx) : shapeInfo.name; var itemGroup = _this.container.addGroup({ name: 'itemGroup', index: idx, capture: false, }); var textShape = itemGroup.addShape('text', { attrs: util_1.deepMix({}, attrs, { x: shapeInfo.x + offsetX, y: shapeInfo.y + offsetY, text: content, }), }); textShape.set('id', "text-" + shapeInfo.name + "-" + idx); shapes.push(textShape); }); shapes.forEach(function (shape) { var panelBox = _this.coordinateBBox; _this.adjustText(shape, panelBox); }); if (adjustPosition) { this.layout(shapes, shapeInfos, this.coordinateBBox); } if (!allowOverlap) { this.adjustOverlap(shapes, this.coordinateBBox); } shapes.forEach(function (label, idx) { if (autoRotate) { _this.rotateLabel(label, utils_1.getLabelRotate(shapeInfos[idx].angle)); } }); }; PieBaseLabel.prototype.adjustText = function (label, panelBox) { var box = label.getBBox(); var width = box.width; var deltaWidth = 0; if (box.maxX > panelBox.maxX) { width = panelBox.maxX - box.minX; } else if (box.minX < panelBox.minX) { width = box.maxX - panelBox.minX; } if (label.attr('textAlign') === 'left') { label.attr('x', Math.max(box.x - deltaWidth, 0)); } else if (label.attr('textAlign') === 'right') { label.attr('x', Math.max(box.maxX - deltaWidth, 0)); } if (width !== box.width) { var font_1 = {}; ['fontSize', 'fontFamily', 'fontWeight'].forEach(function (k) { font_1[k] = label.attr(k); }); var ellipsisTexts = label .attr('text') .split('\n') .map(function (t) { return text_1.getEllipsisText(t, width, font_1); }); label.attr('text', ellipsisTexts.join('\n')); } }; /** 绘制拉线 */ PieBaseLabel.prototype.drawLines = function () { var _this = this; if (this.options.line.visible) { var itemGroups = this.container.get('children'); var center_1 = this.getCoordinate().center; itemGroups.forEach(function (labelGroup, idx) { var label = labelGroup.get('children')[0]; var anchor = _this.arcPoints[idx]; var inLeft = anchor.x < center_1.x; // 拉线 和 label 之间的距离 var distance = _this.options.offset > 4 ? 4 : 0; var path = _this.getLinePath(label, anchor, distance); var style = _this.options.line; labelGroup.addShape('path', { attrs: tslib_1.__assign({ path: path, stroke: anchor.color }, style), }); // 由于拉线的存在 label 需要进行偏移 label.attr('x', label.attr('x') + (inLeft ? -distance : distance)); }); } }; /** 获取label leader-line, 默认 not smooth */ PieBaseLabel.prototype.getLinePath = function (label, anchor, distance) { var smooth = this.options.line ? this.options.line.smooth : false; var angle = anchor.angle; var _a = this.getCoordinate(), center = _a.center, radius = _a.radius; var breakAt = utils_1.getEndPoint(center, angle, radius + distance); if (distance < 4) { breakAt = anchor; } var inLeft = anchor.x < center.x; var box = label.getBBox(); var labelPosition = { x: inLeft ? box.maxX : box.minX, y: box.y + box.height / 2 }; var smoothPath = [ 'C', // 1st control point (of the curve) labelPosition.x + // 4 gives the connector a little horizontal bend (inLeft ? 1 : -1) * (distance < 4 ? distance / 2 : 4), labelPosition.y, 2 * breakAt.x - anchor.x, 2 * breakAt.y - anchor.y, breakAt.x, breakAt.y, ]; var straightPath = ['L', /** pointy break */ breakAt.x, breakAt.y]; var linePath = smooth ? smoothPath : straightPath; var path = ['M', labelPosition.x, labelPosition.y].concat(linePath).concat('L', anchor.x, anchor.y); return path.join(','); }; PieBaseLabel.prototype.getGeometry = function () { return this.plot.view.geometries[0]; }; PieBaseLabel.prototype.getCoordinate = function () { var coordinate = this.getGeometry().coordinate; var center = coordinate.getCenter(); // @ts-ignore var radius = coordinate.getRadius(); var startAngle = coordinate.startAngle; return { center: center, radius: radius, startAngle: startAngle }; }; PieBaseLabel.prototype.adjustOption = function (options) { var offset = options.offset; var radius = this.getCoordinate().radius; if (util_1.isString(offset)) { offset = radius * percent2Number(offset); } options.offset = offset; }; PieBaseLabel.prototype.rotateLabel = function (label, angle) { var x = label.attr('x'); var y = label.attr('y'); var matrix = matrix_util_1.ext.transform(label.getMatrix(), [ ['t', -x, -y], ['r', angle], ['t', x, y], ]); label.setMatrix(matrix); }; PieBaseLabel.prototype.getItems = function () { var _this = this; var offset = this.options.offset; var _a = this.getCoordinate(), center = _a.center, radius = _a.radius; var items = this.arcPoints.map(function (anchor) { var point = utils_1.getEndPoint(center, anchor.angle, radius + offset); var item = tslib_1.__assign(tslib_1.__assign({}, anchor), point); _this.adjustItem(item); return item; }); return items; }; // 初始化圆弧上锚点 PieBaseLabel.prototype.initArcPoints = function () { var _this = this; var angleField = this.plot.options.angleField; var elements = this.getGeometry().elements; var coord = this.getCoordinate(); var center = coord.center, radius = coord.radius; var startAngle = this.getCoordinate().startAngle; // 位置信息使用 positionScale var positionScales = this.getGeometry().attributes.position.scales; var scale = positionScales[1]; var scaleField = scale.field; var anchors = elements.map(function (ele) { var origin = ele.shape.get('origin'); var color = origin.color; var originData = origin.data[0] || origin.data; var endAngle = startAngle + Math.PI * 2 * scale.scale(originData[scaleField]); var angle = (startAngle + endAngle) / 2; var point = utils_1.getEndPoint(center, angle, radius); startAngle = endAngle; // 标签名 使用 angleField var name = scale.getText(originData[angleField]); var textAlign = point.x > center.x ? 'left' : 'right'; return { x: point.x, y: point.y, color: color, name: name, origin: originData, // 实际的角度 angle: utils_1.getAngleByPoint(_this.getGeometry().coordinate, point), textAlign: textAlign, }; }); this.arcPoints = anchors; }; return PieBaseLabel; }()); exports.default = PieBaseLabel; },{"../../../../util/text":714,"./utils":581,"@antv/matrix-util":717,"@antv/util":803,"tslib":894}],576:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPieLabel = void 0; var tslib_1 = require("tslib"); var inner_label_1 = tslib_1.__importDefault(require("./inner-label")); var outer_label_1 = tslib_1.__importDefault(require("./outer-label")); var outer_center_label_1 = tslib_1.__importDefault(require("./outer-center-label")); var PieLabels = { inner: inner_label_1.default, outer: outer_label_1.default, 'outer-center': outer_center_label_1.default, }; function getPieLabel(type) { if (!PieLabels[type]) { console.warn("this label " + type + " is not registered"); return; } return PieLabels[type]; } exports.getPieLabel = getPieLabel; },{"./inner-label":577,"./outer-center-label":578,"./outer-label":579,"tslib":894}],577:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.percent2Number = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_label_1 = tslib_1.__importDefault(require("./base-label")); var utils_1 = require("./utils"); var math_1 = require("../../../../util/math"); function percent2Number(value) { var percentage = Number(value.endsWith('%') ? value.slice(0, -1) : value); return percentage / 100; } exports.percent2Number = percent2Number; var PieInnerLabel = /** @class */ (function (_super) { tslib_1.__extends(PieInnerLabel, _super); function PieInnerLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** @override 不能大于0 */ PieInnerLabel.prototype.adjustOption = function (options) { _super.prototype.adjustOption.call(this, options); if (options.offset > 0) { options.offset = 0; } }; PieInnerLabel.prototype.adjustItem = function (item) { item.textAlign = 'middle'; }; /** @override 不绘制拉线 */ PieInnerLabel.prototype.drawLines = function () { return; }; PieInnerLabel.prototype.layout = function (labels, shapeInfos) { var _this = this; labels.forEach(function (label, idx) { if (idx > 0) { util_1.each(labels.slice(0, idx), function (prevLabel) { _this.resolveCollision(label, prevLabel, shapeInfos[idx]); }); } }); }; PieInnerLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { offsetX: 0, offsetY: 0, offset: '-30%', style: tslib_1.__assign(tslib_1.__assign({}, labelStyle), { textAlign: 'center', textBaseline: 'middle' }), }; }; /** label 碰撞调整 */ PieInnerLabel.prototype.resolveCollision = function (label, prev, shapeInfo) { var center = this.getCoordinate().center; var angle = shapeInfo.angle; var box = label.getBBox(); var prevBBox = prev.getBBox(); var pos = { x: (box.minX + box.maxX) / 2, y: (box.minY + box.maxY) / 2 }; // 两种调整方案 /** 先偏移 x 方向 -> 再计算 y 位置 */ var pos1 = util_1.clone(pos); /** 先偏移 y 方向 -> 再计算 x 位置 */ var pos2 = util_1.clone(pos); // check overlap if (prev.get('id') !== label.get('id')) { var _a = utils_1.getOverlapInfo(box, prevBBox), xOverlap = _a.xOverlap, yOverlap = _a.yOverlap; if (xOverlap) { pos1.x = pos.x + xOverlap; pos1.y = pos.y + Math.tan(angle) * xOverlap; } if (yOverlap) { // fix issue-460 var yMover = yOverlap; if (pos.y < center.y) { // 上方label优先往上偏移 yMover = yMover < 0 ? yMover : prevBBox.minY - box.maxY; } else { // 下方label优先往下偏移 yMover = yMover > 0 ? yMover : prevBBox.maxY - box.minY; } pos2.y = pos.y + yMover; pos2.x = pos.x + yMover / Math.tan(angle); } var dist1 = math_1.distBetweenPoints(pos, pos1); var dist2 = math_1.distBetweenPoints(pos, pos2); var actualPos = dist1 < dist2 ? pos1 : pos2; // 取偏移距离最小的 label.attr('x', actualPos.x); label.attr('y', actualPos.y); } }; return PieInnerLabel; }(base_label_1.default)); exports.default = PieInnerLabel; },{"../../../../util/math":680,"./base-label":575,"./utils":581,"@antv/util":803,"tslib":894}],578:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_OFFSET = void 0; var tslib_1 = require("tslib"); var base_label_1 = tslib_1.__importDefault(require("./base-label")); // 默认label和element的偏移 16px exports.DEFAULT_OFFSET = 16; var PieOuterCenterLabel = /** @class */ (function (_super) { tslib_1.__extends(PieOuterCenterLabel, _super); function PieOuterCenterLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** @override 不能大于0 */ PieOuterCenterLabel.prototype.adjustOption = function (options) { _super.prototype.adjustOption.call(this, options); if (options.offset < 0) { options.offset = 0; } }; PieOuterCenterLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { offsetX: 0, offsetY: 0, offset: 12, style: tslib_1.__assign(tslib_1.__assign({}, labelStyle), { textBaseline: 'middle' }), }; }; PieOuterCenterLabel.prototype.adjustItem = function (item) { var offset = this.options.offset; if (item.textAlign === 'left') { item.x += offset > 4 ? 4 : offset / 2; } else if (item.textAlign === 'right') { item.x -= offset > 4 ? 4 : offset / 2; } }; /** label 碰撞调整 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function PieOuterCenterLabel.prototype.layout = function (labels, items, panel) { }; return PieOuterCenterLabel; }(base_label_1.default)); exports.default = PieOuterCenterLabel; },{"./base-label":575,"tslib":894}],579:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_OFFSET = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_label_1 = tslib_1.__importDefault(require("./base-label")); var utils_1 = require("./utils"); // 默认label和element的偏移 16px exports.DEFAULT_OFFSET = 16; var PieOuterLabel = /** @class */ (function (_super) { tslib_1.__extends(PieOuterLabel, _super); function PieOuterLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** @override 不能大于0 */ PieOuterLabel.prototype.adjustOption = function (options) { _super.prototype.adjustOption.call(this, options); if (options.offset < 0) { options.offset = 0; } }; PieOuterLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { offsetX: 0, offsetY: 0, offset: 12, style: tslib_1.__assign(tslib_1.__assign({}, labelStyle), { textBaseline: 'middle' }), }; }; /** label 碰撞调整 */ PieOuterLabel.prototype.layout = function (labels, items, panel) { var _this = this; var center = this.getCoordinate().center; var leftHalf = util_1.filter(labels, function (l) { return l.attr('x') <= center.x; }); var rightHalf = util_1.filter(labels, function (l) { return l.attr('x') > center.x; }); [rightHalf, leftHalf].forEach(function (half, isLeft) { _this._antiCollision(half, !isLeft, panel); }); }; /** labels 碰撞处理(重点算法) */ PieOuterLabel.prototype._antiCollision = function (labels, isRight, panelBox) { var _this = this; var labelHeight = this.getLabelHeight(labels); var _a = this.getCoordinate(), center = _a.center, radius = _a.radius; var offset = this.options.offset; var totalR = radius + offset; var totalHeight = Math.min(panelBox.height, Math.max(totalR * 2 + labelHeight * 2, labels.length * labelHeight)); var maxLabelsCount = Math.floor(totalHeight / labelHeight); // fix-bug, maxLabelsCount 之后的labels 在非 allowOverlap 不显示(避免出现尾部label展示,而前置label不展示) if (!this.options.allowOverlap) { labels.slice(maxLabelsCount).forEach(function (label) { label.get('parent').set('visible', false); }); } labels.splice(maxLabelsCount, labels.length - maxLabelsCount); // sort by y DESC labels.sort(function (a, b) { return a.getBBox().y - b.getBBox().y; }); // adjust y position of labels to avoid overlapping var overlapping = true; var i; var maxY = center.y + totalHeight / 2; var minY = center.y - totalHeight / 2; var boxes = labels.map(function (label) { var labelBox = label.getBBox(); if (labelBox.maxY > maxY) { maxY = Math.min(panelBox.maxY, labelBox.maxY); } if (labelBox.minY < minY) { minY = Math.max(panelBox.minY, labelBox.minY); } return { text: label.attr('text'), size: labelHeight, pos: labelBox.y, targets: [], }; }); var j = 0; while (j < boxes.length) { if (j === boxes.length - 1) { boxes[j].targets[0] = maxY; } else { boxes[j].targets[0] = boxes[j + 1].pos - boxes[j + 1].size / 2; } j++; } while (overlapping) { boxes.forEach(function (box) { var target = util_1.last(box.targets); box.pos = Math.max(minY, Math.min(box.pos, target - box.size)); }); // detect overlapping and join boxes overlapping = false; i = boxes.length; while (i--) { if (i > 0) { var previousBox = boxes[i - 1]; var box = boxes[i]; if (previousBox.pos + previousBox.size > box.pos) { // overlapping previousBox.size += box.size; previousBox.targets = previousBox.targets.concat(box.targets); // overflow, shift up var target = util_1.last(previousBox.targets); if (previousBox.pos + previousBox.size > target) { previousBox.pos = target - previousBox.size; } boxes.splice(i, 1); // removing box overlapping = true; } else { // 换掉最后一个 previousBox.targets.splice(-1, 1, box.pos); } } } } i = 0; // step 4: normalize y and adjust x boxes.forEach(function (b) { var posInCompositeBox = labelHeight / 2; // middle of the label b.targets.forEach(function () { labels[i].attr('y', b.pos + posInCompositeBox); posInCompositeBox += labelHeight; i++; }); }); // 调整 x 位置在椭圆轨道上 var topLabels = []; var bottomLabels = []; labels.forEach(function (label, idx) { var anchor = _this.arcPoints[idx]; if (anchor.angle >= 0 && anchor.angle <= Math.PI) { bottomLabels.push(label); } else { topLabels.push(label); } }); [topLabels, bottomLabels].forEach(function (adjustLabels, isBottom) { if (!adjustLabels.length) { return; } var ry = isBottom ? util_1.last(adjustLabels).getBBox().maxY - center.y : center.y - util_1.head(adjustLabels).getBBox().minY; ry = Math.max(totalR, ry); var distance = offset > 4 ? 4 : 0; var maxLabelWidth = Math.max.apply(0, util_1.map(labels, function (label) { return label.getBBox().width; })) + offset + distance; var rx = Math.max(totalR, Math.min((ry + totalR) / 2, center.x - (panelBox.minX + maxLabelWidth))); var rxPow2 = rx * rx; var ryPow2 = ry * ry; adjustLabels.forEach(function (label, idx) { var anchor = _this.arcPoints[idx]; var box = label.getBBox(); var boxCenter = { x: box.minX + box.width / 2, y: box.minY + box.height / 2 }; var dyPow2 = Math.pow(boxCenter.y - center.y, 2); var endPoint = utils_1.getEndPoint(center, anchor.angle, radius); var distance_offset = (isRight ? 1 : -1) * distance * 2; if (dyPow2 > ryPow2) { console.warn('异常(一般不会出现)', label.attr('text')); label.attr('x', endPoint.x + distance_offset); } else { // (x - cx)^2 / rx ^ 2 + (y - cy)^2 / ry ^ 2 = 1 // 避免 label的 拉线 在 element 上 var xPos = center.x + (isRight ? 1 : -1) * Math.sqrt((1 - dyPow2 / ryPow2) * rxPow2); if ((center.x === endPoint.x && boxCenter.y === endPoint.y) || (center.y === endPoint.y && xPos === endPoint.x)) { xPos = endPoint.x; } else { // const k1 = (center.y - endPoint.y) / (center.x - endPoint.x); // const k2 = (boxCenter.y - endPoint.y) / (xPos - endPoint.x); // const theta = Math.atan((k1 - k2) / (1 + k1 * k2)); // 切角 < 90度(目前的坐标系 无法精准计算切角) // if (Math.cos(theta) > 0 && (!isRight ? xPos > endPoint.x : xPos < endPoint.x)) { // xPos = endPoint.x; // } } label.attr('x', xPos + distance_offset); } }); }); }; /** 获取label height */ PieOuterLabel.prototype.getLabelHeight = function (labels) { if (!this.options.labelHeight) { return util_1.head(labels) ? util_1.head(labels).getBBox().height : 14; } return this.options.labelHeight; }; return PieOuterLabel; }(base_label_1.default)); exports.default = PieOuterLabel; },{"./base-label":575,"./utils":581,"@antv/util":803,"tslib":894}],580:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var layer_1 = require("../../layer"); var ANCHOR_OFFSET = 0; // 锚点偏移量 var INFLECTION_OFFSET = 15; // 拐点偏移量 var DEFAULT_COLOR = '#CCC'; var LABEL1_OFFSETY = 2; var LABEL2_OFFSETY = -2; var ADJUSTOFFSET = 15; function getEndPoint(center, angle, r) { return { x: center.x + r * Math.cos(angle), y: center.y + r * Math.sin(angle), }; } var SpiderLabel = /** @class */ (function () { function SpiderLabel(cfg) { this.destroyed = false; this.view = cfg.view; this.options = util_1.deepMix({}, this.getDefaultOptions(), cfg); this._adjustOptions(this.options); this.init(); } SpiderLabel.prototype.init = function () { var _this = this; this.container = this.view.geometries[0].labelsContainer; this.view.on('beforerender', function () { _this.clear(); }); }; SpiderLabel.prototype.render = function () { var _this = this; if (!this.view || this.view.destroyed) { return; } /** 如果有formatter则事先处理数据 */ var data = util_1.clone(this.view.getData()); this.halves = [[], []]; var shapes = []; var elements = this.view.geometries[0].elements; util_1.each(elements, function (ele) { shapes.push(ele.shape); }); this.coord = this.view.geometries[0].coordinate; var _a = this.options, allZero = _a.allZero, trueAngleField = _a.angleField; var angleField = this.options.fields[0]; var scale = this.view.getScalesByDim('y')[angleField]; var center = this.coord.getCenter(); var startAngle = this.coord.startAngle; var radius = this.coord.polarRadius; var _b = this.view.coordinateBBox, width = _b.width, height = _b.height; this.width = width; this.height = height; var angle = startAngle; var _loop_1 = function (idx) { var d = data[idx]; // 计算每个切片的middle angle var angleValue = scale.scale(d[angleField]); var targetAngle = angle + Math.PI * 2 * angleValue; var middleAngle = angle + (targetAngle - angle) / 2; angle = targetAngle; // 根据middle angle计算锚点和拐点距离 var anchorPoint = getEndPoint(center, middleAngle, radius + ANCHOR_OFFSET); var inflectionPoint = getEndPoint(center, middleAngle, radius + INFLECTION_OFFSET); // 获取对应shape的color var color = DEFAULT_COLOR; if (this_1.options.fields.length === 2) { var colorField = this_1.options.fields[1]; var colorScale = this_1.view.geometries[0].scales[colorField]; var colorIndex = colorScale.scale(d[colorField]); if (colorIndex) { var shapeIndex = Math.floor(colorIndex * (shapes.length - 1)); color = shapes[shapeIndex].attr('fill'); } } // 组装label数据 var label = { _anchor: anchorPoint, _inflection: inflectionPoint, _data: d, x: inflectionPoint.x, y: inflectionPoint.y, r: radius + INFLECTION_OFFSET, fill: color, textGroup: null, _side: null, }; // 创建label文本 var texts = []; util_1.each(this_1.options.fields, function (f) { if (allZero && f === layer_1.percentageField) { texts.push(d[trueAngleField]); } else { texts.push(d[f]); } }); if (this_1.options.formatter) { var formatted = this_1.options.formatter(d[trueAngleField], { _origin: d, color: color }, idx); if (util_1.isString(formatted)) { formatted = [formatted]; } texts = formatted; } var textGroup = this_1.container.addGroup({ capture: false, visible: false, }); var textAttrs = { x: 0, y: 0, fontSize: this_1.options.text.fontSize, lineHeight: this_1.options.text.fontSize, fontWeight: this_1.options.text.fontWeight, fill: this_1.options.text.fill, }; // label1:下部label var lowerText = d[trueAngleField]; if (this_1.options.formatter) { lowerText = texts[0]; } var lowerTextAttrs = util_1.clone(textAttrs); if (texts.length === 2) { lowerTextAttrs.fontWeight = 700; } var lowerTextShape = textGroup.addShape('text', { attrs: util_1.mix({ textBaseline: texts.length === 2 ? 'top' : 'middle', text: lowerText, }, lowerTextAttrs), data: d, offsetY: texts.length === 2 ? LABEL1_OFFSETY : 0, name: 'label', }); lowerTextShape.name = 'label'; // 用于事件标记 shapeName /** label2:上部label */ if (texts.length === 2) { var topTextShape = textGroup.addShape('text', { attrs: util_1.mix({ textBaseline: 'bottom', text: texts[1], }, textAttrs), data: d, offsetY: LABEL2_OFFSETY, name: 'label', }); topTextShape.name = 'label'; // 用于事件标记 shapeName } label.textGroup = textGroup; /** 将label分组 */ if (anchorPoint.x < center.x) { label._side = 'left'; this_1.halves[0].push(label); } else { label._side = 'right'; this_1.halves[1].push(label); } }; var this_1 = this; // tslint:disable-next-line: prefer-for-of for (var idx = 0; idx < data.length; idx++) { _loop_1(idx); } /** 绘制label */ var maxCountForOneSide = Math.floor(height / this.options.lineHeight); util_1.each(this.halves, function (half) { if (half.length > maxCountForOneSide) { half.splice(maxCountForOneSide, half.length - maxCountForOneSide); } half.sort(function (a, b) { return a.y - b.y; }); _this._antiCollision(half); }); this.view.canvas.draw(); }; SpiderLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; SpiderLabel.prototype.hide = function () { this.container.set('visible', false); this.view.canvas.draw(); }; SpiderLabel.prototype.show = function () { this.container.set('visible', true); this.view.canvas.draw(); }; SpiderLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; SpiderLabel.prototype.getDefaultOptions = function () { return { text: { fill: 'rgba(0, 0, 0, 0.65)', fontSize: 12, }, line: { lineWidth: 0.5, stroke: 'rgba(0, 0, 0, 0.45)', }, lineHeight: 32, /** distance between label and edge */ sidePadding: 20, }; }; SpiderLabel.prototype._antiCollision = function (half) { var _this = this; var coord = this.coord; var canvasHeight = coord.getHeight(); var center = coord.center; var radius = coord.getRadius(); var startY = center.y - radius - INFLECTION_OFFSET - this.options.lineHeight; var overlapping = true; var totalH = canvasHeight; var i; var maxY = 0; var minY = Number.MIN_VALUE; var maxLabelWidth = 0; var boxes = half.map(function (label) { var labelY = label.y; if (labelY > maxY) { maxY = labelY; } if (labelY < minY) { minY = labelY; } var textGroup = label.textGroup; var labelWidth = textGroup.getBBox().width; if (labelWidth >= maxLabelWidth) { maxLabelWidth = labelWidth; } return { size: _this.options.lineHeight, targets: [labelY - startY], }; }); if (maxY - startY > totalH) { totalH = maxY - startY; } var iteratorBoxed = function (items) { items.forEach(function (box) { var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2; box.pos = Math.min(Math.max(minY, target - box.size / 2), totalH - box.size); }); }; while (overlapping) { iteratorBoxed(boxes); // detect overlapping and join boxes overlapping = false; i = boxes.length; while (i--) { if (i > 0) { var previousBox = boxes[i - 1]; var box = boxes[i]; if (previousBox.pos + previousBox.size > box.pos) { // overlapping previousBox.size += box.size; previousBox.targets = previousBox.targets.concat(box.targets); // overflow, shift up if (previousBox.pos + previousBox.size > totalH) { previousBox.pos = totalH - previousBox.size; } boxes.splice(i, 1); // removing box overlapping = true; } } } } i = 0; boxes.forEach(function (b) { var posInCompositeBox = startY; // middle of the label b.targets.forEach(function () { half[i].y = b.pos + posInCompositeBox + _this.options.lineHeight / 2; posInCompositeBox += _this.options.lineHeight; i++; }); }); var drawnLabels = []; half.forEach(function (label) { var textGroup = _this._drawLabel(label); _this._drawLabelLine(label, maxLabelWidth, textGroup); drawnLabels.push(textGroup); }); }; SpiderLabel.prototype._drawLabel = function (label) { var coord = this.coord; var center = coord.getCenter(); var radius = coord.getRadius(); var y = label.y, textGroup = label.textGroup; var children = textGroup.get('children'); var x_dir = label._side === 'left' ? 1 : -1; var textAttrs = tslib_1.__assign({ textAlign: label._side === 'left' ? 'right' : 'left', x: label._side === 'left' ? center.x - radius - this.options.sidePadding : center.x + radius + this.options.sidePadding }, this.options.style); if (this.options.offsetX) { textAttrs.x += this.options.offsetX * x_dir; } children.forEach(function (child) { var offsetY = child.get('offsetY'); var yPosition = y + offsetY; child.attr(textAttrs); child.attr('y', yPosition); }); textGroup.show(); return textGroup; }; SpiderLabel.prototype._drawLabelLine = function (label, maxLabelWidth, container) { var _anchor = [label._anchor.x, label._anchor.y]; var _inflection = [label._inflection.x, label._inflection.y]; var y = label.y, textGroup = label.textGroup; if (!textGroup) return; var lastPoint = [label._side === 'left' ? textGroup.getBBox().maxX + 4 : textGroup.getBBox().minX - 4, y]; var points = [_anchor, _inflection, lastPoint]; if (_inflection[1] !== y) { // 展示全部文本文本位置做过调整 if ((_inflection[1] < this.height / 2 && _inflection[1] < y) || (_inflection[1] >= this.height / 2 && _inflection[1] > y)) { // 文本被调整下去了,则添加拐点连接线 var point1 = _inflection; var leftPoint = lastPoint[0] + ADJUSTOFFSET; var rightPoint = lastPoint[0] - ADJUSTOFFSET; var point2 = [label._side === 'left' ? leftPoint : rightPoint, _inflection[1]]; points = [_anchor, point1, point2, lastPoint]; if ((label._side === 'right' && point2[0] < point1[0]) || (label._side === 'left' && point2[0] > point1[0])) { points = [_anchor, point1, lastPoint]; } } else { points = [_anchor, [_inflection[0], y], lastPoint]; } } var path = []; for (var i = 0; i < points.length; i++) { var p = points[i]; var starter = 'L'; if (i === 0) { starter = 'M'; } path.push([starter, p[0], p[1]]); } container.addShape('path', { attrs: { path: path, lineWidth: this.options.line.lineWidth, stroke: this.options.line.stroke, }, }); // 绘制锚点 // container.addShape('circle', { // attrs: { // x: _anchor[0], // y: _anchor[1], // r: this.config.anchorSize, // fill, // }, // }); }; SpiderLabel.prototype._adjustOptions = function (config) { if (config.text.fontSize) { config.lineHeight = config.text.fontSize * 3; } }; return SpiderLabel; }()); exports.default = SpiderLabel; },{"../../layer":584,"@antv/util":803,"tslib":894}],581:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLabelRotate = exports.getAngleByPoint = exports.near = exports.inPanel = exports.getOverlapInfo = exports.getOverlapArea = exports.getCenter = exports.getEndPoint = void 0; function getEndPoint(center, angle, r) { return { x: center.x + r * Math.cos(angle), y: center.y + r * Math.sin(angle), }; } exports.getEndPoint = getEndPoint; /** 获取矩形中点 */ function getCenter(box) { return { x: box.x + box.width / 2, y: box.y + box.height / 2, }; } exports.getCenter = getCenter; function getOverlapArea(a, b, margin) { if (margin === void 0) { margin = 0; } var xOverlap = Math.max(0, Math.min(a.x + a.width + margin, b.x + b.width + margin) - Math.max(a.x - margin, b.x - margin)); var yOverlap = Math.max(0, Math.min(a.y + a.height + margin, b.y + b.height + margin) - Math.max(a.y - margin, b.y - margin)); return xOverlap * yOverlap; } exports.getOverlapArea = getOverlapArea; /** * 计算两个矩形之间的堆叠情况 * @return xOverlap x方向重叠大小 * @return yOverlap y方向重叠大小 */ function getOverlapInfo(a, b, margin) { if (margin === void 0) { margin = 0; } var xOverlap = Math.max(0, Math.min(a.x + a.width + margin, b.x + b.width + margin) - Math.max(a.x - margin, b.x - margin)); var yOverlap = Math.max(0, Math.min(a.y + a.height + margin, b.y + b.height + margin) - Math.max(a.y - margin, b.y - margin)); // 添加 sign if (xOverlap && a.x < b.x) { xOverlap = -xOverlap; } if (yOverlap && a.y < b.y) { yOverlap = -yOverlap; } // 重叠 if (a.x === b.x && a.width === b.width) { xOverlap = b.width; } if (a.y === b.y && a.height === b.height) { yOverlap = b.height; } return { xOverlap: xOverlap, yOverlap: yOverlap }; } exports.getOverlapInfo = getOverlapInfo; /** * 粗略地判断是否在panel内部 * @param panel * @param shape */ function inPanel(panel, shape) { return (panel.x < shape.x && panel.x + panel.width > shape.x + shape.width && panel.y < shape.y && panel.y + panel.height > shape.y + shape.height); } exports.inPanel = inPanel; /** * 判断两个数值 是否接近 * - 解决精度问题(由于无法确定精度上限,根据具体场景可传入 精度 参数) */ exports.near = function (x, y, e) { if (e === void 0) { e = Math.pow(Number.EPSILON, 0.5); } return [x, y].includes(Infinity) ? Math.abs(x) === Math.abs(y) : Math.abs(x - y) < e; }; /** * 获取点到圆心的连线与水平方向的夹角 */ function getAngleByPoint(coordinate, point) { var center = coordinate.getCenter(); return Math.atan2(point.y - center.y, point.x - center.x); } exports.getAngleByPoint = getAngleByPoint; /** * 获取 label 的旋转角度 * @param angle */ function getLabelRotate(angle) { var HALF_PI = Math.PI / 2; var rotate = angle; if (rotate > HALF_PI || rotate < -HALF_PI) { rotate = rotate + Math.PI; } return rotate; } exports.getLabelRotate = getLabelRotate; },{}],582:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { pie: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],583:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Pie = /** @class */ (function (_super) { tslib_1.__extends(Pie, _super); function Pie() { return _super !== null && _super.apply(this, arguments) || this; } Pie.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'pie'; _super.prototype.createLayers.call(this, layerProps); }; Pie.prototype.getAngleScale = function () { var layer = this.layers[0]; return layer.getAngleScale(); }; Pie.getDefaultOptions = layer_1.default.getDefaultOptions; return Pie; }(plot_1.default)); exports.default = Pie; },{"../../base/plot":394,"./layer":584,"@antv/util":803,"tslib":894}],584:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.percentageField = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var EventParser = tslib_1.__importStar(require("./event")); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); var label_1 = require("./component/label"); var spider_label_1 = tslib_1.__importDefault(require("./component/label/spider-label")); var global_1 = require("../../base/global"); require("./theme"); exports.percentageField = '$$percentage$$'; var G2_GEOM_MAP = { pie: 'interval', }; var PLOT_GEOM_MAP = { pie: 'column', }; // @ts-ignore var PieLayer = /** @class */ (function (_super) { tslib_1.__extends(PieLayer, _super); function PieLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'pie'; return _this; } PieLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { width: 400, height: 400, title: { visible: false, }, description: { visible: false, }, forceFit: true, padding: 'auto', radius: 0.8, label: { visible: true, type: 'inner', autoRotate: false, adjustPosition: true, allowOverlap: false, line: { visible: true, smooth: true, }, }, legend: { visible: true, position: 'right-center', }, tooltip: { visible: true, shared: false, showCrosshairs: false, showMarkers: false, }, pieStyle: { stroke: 'white', lineWidth: 1, }, }); }; PieLayer.prototype.afterInit = function () { _super.prototype.afterInit.call(this); var _a = this.options, angleField = _a.angleField, colorField = _a.colorField, data = _a.data; var allZero = util_1.every(data, function (d) { return d[angleField] === 0; }); if (allZero) { var pieGeom = this.view.geometries[0]; pieGeom.tooltip(colorField + "*" + angleField); } }; PieLayer.prototype.afterRender = function () { _super.prototype.afterRender.call(this); var options = this.options; /** 蜘蛛布局label */ if (options.label && options.label.visible) { // 清除,避免二次渲染 if (this.labelComponent) { this.labelComponent.clear(); } var labelConfig = options.label; if (labelConfig.type === 'spider') { var data = options.data, colorField = options.colorField, angleField_1 = options.angleField; var allZero = util_1.every(data, function (d) { return d[angleField_1] === 0; }); var valueField = allZero ? exports.percentageField : angleField_1; this.labelComponent = new spider_label_1.default(tslib_1.__assign({ view: this.view, fields: colorField ? [valueField, colorField] : [valueField], angleField: angleField_1, allZero: allZero }, this.options.label)); this.labelComponent.render(); } else { var LabelCtor = label_1.getPieLabel(labelConfig.type); this.labelComponent = new LabelCtor(this, options.label); this.labelComponent.render(); } } }; PieLayer.prototype.getAngleScale = function () { var angleField = this.options.angleField; if (angleField) { return this.view.getScaleByField(angleField); } }; PieLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; PieLayer.prototype.scale = function () { var props = this.options; _super.prototype.scale.call(this); var scales = {}; scales[props.angleField] = {}; scales[props.colorField] = { type: 'cat' }; scales = util_1.deepMix({}, this.config.scales, scales); this.setConfig('scales', scales); }; PieLayer.prototype.processData = function (data) { var key = this.options.angleField; var allZero = util_1.every(data, function (d) { return d[key] === 0; }); if (allZero) { return data.map(function (item) { var _a; return (tslib_1.__assign(tslib_1.__assign({}, item), (_a = {}, _a[key] = typeof item[key] === 'string' ? Number.parseFloat(item[key]) : item[key], _a[exports.percentageField] = 1 / data.length, _a))); }); } return data.map(function (item) { var _a; var value = item[key]; return tslib_1.__assign(tslib_1.__assign({}, item), (_a = {}, _a[key] = value && !isNaN(value) ? +value : value, _a)); }); }; PieLayer.prototype.axis = function () { return; }; PieLayer.prototype.coord = function () { var props = this.options; var coordConfig = { type: 'theta', cfg: { radius: props.radius, // @ts-ignore 业务定制,不开放配置 innerRadius: props.innerRadius || 0, }, }; this.setConfig('coordinate', coordConfig); }; PieLayer.prototype.addGeometry = function () { var props = this.options; var data = props.data, angleField = props.angleField; var pie; var allZero = util_1.every(data, function (d) { return d[angleField] === 0; }); if (allZero) { pie = factory_1.getGeom('interval', 'main', { plot: this, positionFields: [1, exports.percentageField], }); } else { pie = factory_1.getGeom('interval', 'main', { plot: this, positionFields: [1, props.angleField], }); } pie.adjust = [{ type: 'stack' }]; this.pie = pie; if (props.label) { this.label(); } if (props.tooltip && (props.tooltip.fields || props.tooltip.formatter)) { this.geometryTooltip(); } this.setConfig('geometry', pie); }; PieLayer.prototype.geometryTooltip = function () { this.pie.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.pie.tooltip.fields = tooltipOptions.fields; } else { this.pie.tooltip.fields = [this.options.angleField, this.options.colorField]; } if (tooltipOptions.formatter) { this.pie.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.pie.tooltip.fields = [this.options.angleField, this.options.colorField]; } } }; PieLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { /** 关闭动画 */ this.pie.animate = false; } }; PieLayer.prototype.annotation = function () { return; }; PieLayer.prototype.parseEvents = function (eventParser) { if (eventParser) { _super.prototype.parseEvents.call(this, eventParser); } else { _super.prototype.parseEvents.call(this, EventParser); } }; PieLayer.prototype.label = function () { // 不使用 g2 内置label this.pie.label = false; }; return PieLayer; }(view_layer_1.default)); exports.default = PieLayer; global_1.registerPlotType('pie', PieLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../geoms/factory":430,"./component/label":576,"./component/label/spider-label":580,"./event":582,"./theme":585,"@antv/util":803,"tslib":894}],585:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var PIE_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { fillOpacity: opacity * 0.8 }; }; var PIE_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { fillOpacity: opacity * 0.5 }; }; theme_1.registerTheme('pie', { columnStyle: { normal: {}, active: PIE_ACTIVE_STYLE, disable: PIE_DISABLE_STYLE, selected: { lineWidth: 1, stroke: 'black' }, }, }); },{"../../theme":669}],586:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; /** * Create By Bruce Too * On 2020-02-14 */ var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { area: 'area', line: 'line', point: 'point', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],587:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-14 */ var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Radar = /** @class */ (function (_super) { tslib_1.__extends(Radar, _super); function Radar() { return _super !== null && _super.apply(this, arguments) || this; } Radar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'radar'; _super.prototype.createLayers.call(this, layerProps); }; Radar.prototype.getAngleScale = function () { var layer = this.layers[0]; return layer.getAngleScale(); }; Radar.prototype.getRadiusScale = function () { var layer = this.layers[0]; return layer.getRadiusScale(); }; Radar.prototype.getColorScale = function () { var layer = this.layers[0]; return layer.getColorScale(); }; Radar.getDefaultOptions = layer_1.default.getDefaultOptions; return Radar; }(plot_1.default)); exports.default = Radar; },{"../../base/plot":394,"./layer":588,"@antv/util":803,"tslib":894}],588:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-14 */ var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../components/factory"); var factory_2 = require("../../geoms/factory"); var scale_1 = require("../../util/scale"); var EventParser = tslib_1.__importStar(require("./event")); require("./theme"); var GEOM_MAP = { area: 'area', line: 'line', point: 'point', }; var RadarLayer = /** @class */ (function (_super) { tslib_1.__extends(RadarLayer, _super); function RadarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'radar'; return _this; } RadarLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { width: 400, height: 400, title: { visible: false, }, description: { visible: false, }, forceFit: true, padding: 'auto', radius: 0.8, smooth: false, line: { visible: true, size: 2, style: { opacity: 1, }, }, area: { visible: true, style: { opacity: 0.25, }, }, point: { visible: false, size: 4, shape: 'point', style: { opacity: 1, }, }, angleAxis: { visible: true, autoRotateTitle: true, line: { visible: false, }, tickLine: { visible: false, }, grid: { visible: true, line: { style: { lineDash: [0, 0], }, }, }, label: { visible: true, offset: 16, autoRotate: true, autoHide: true, }, title: { visible: false, }, }, radiusAxis: { min: 0, visible: true, /** G2 4.0 默认 nice 不生效,需要手动添加 */ nice: true, autoRotateTitle: true, line: { visible: true, }, tickLine: { visible: true, }, gridType: 'line', grid: { visible: true, line: { style: { lineDash: [0, 0], }, }, }, label: { visible: true, autoHide: true, autoRotate: true, }, title: { visible: false, }, }, label: { visible: false, type: 'point', }, legend: { visible: true, position: 'left-top', }, tooltip: { visible: true, shared: true, showCrosshairs: false, }, }); }; RadarLayer.prototype.init = function () { var props = this.options; props.xField = props.angleField; props.yField = props.radiusField; _super.prototype.init.call(this); }; RadarLayer.prototype.getAngleScale = function () { var angleField = this.options.angleField; return this.view.getScaleByField(angleField); }; RadarLayer.prototype.getRadiusScale = function () { var radiusField = this.options.radiusField; return this.view.getScaleByField(radiusField); }; RadarLayer.prototype.getColorScale = function () { var seriesField = this.options.seriesField; return this.view.getScaleByField(seriesField); }; RadarLayer.prototype.geometryParser = function (dim, type) { return GEOM_MAP[type]; }; RadarLayer.prototype.scale = function () { var props = this.options; var scales = {}; /** 配置x-scale */ scales[props.angleField] = {}; if (util_1.has(props, 'angleAxis')) { scale_1.extractScale(scales[props.angleField], props.angleAxis); } /** 配置y-scale */ scales[props.radiusField] = {}; if (util_1.has(props, 'radiusAxis')) { scale_1.extractScale(scales[props.radiusField], props.radiusAxis); } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; RadarLayer.prototype.coord = function () { var props = this.options; var coordConfig = { type: 'polar', cfg: { radius: props.radius, }, }; this.setConfig('coordinate', coordConfig); }; RadarLayer.prototype.axis = function () { var props = this.options; var xAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'angle', }); var yAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'radius', }); var axesConfig = {}; axesConfig[props.angleField] = xAxis_parser; axesConfig[props.radiusField] = yAxis_parser; /** 存储坐标轴配置项到config */ this.setConfig('axes', axesConfig); }; RadarLayer.prototype.addGeometry = function () { var props = this.options; /** 配置面积 */ if (props.area.visible) { var area = factory_2.getGeom('area', 'main', { plot: this, }); this.setConfig('geometry', area); this.area = area; } /** 配置线 */ if (props.line && props.line.visible) { var line = factory_2.getGeom('line', 'main', { plot: this, }); this.setConfig('geometry', line); this.line = line; } /** 配置点 */ if (props.point && props.point.visible) { var point = factory_2.getGeom('point', 'guide', { plot: this, }); this.setConfig('geometry', point); this.point = point; } if (props.label) { this.label(); } if (props.tooltip && (props.tooltip.fields || props.tooltip.formatter)) { this.geometryTooltip(); } }; RadarLayer.prototype.geometryTooltip = function () { var geomConfig = this.line ? this.line : this.area; geomConfig.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { geomConfig.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { geomConfig.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { geomConfig.tooltip.fields = [this.options.angleField, this.options.radiusField]; } if (this.options.seriesField) { geomConfig.tooltip.fields.push(this.options.seriesField); } } }; RadarLayer.prototype.label = function () { var props = this.options; if (props.label.visible === false) { if (this.point) { this.point.label = false; } if (this.line) { this.line.label = false; } if (this.area) { this.area.label = false; } return; } // @Todo 雷达图标签布局算法后续补充 var label = factory_1.getComponent('label', tslib_1.__assign({ fields: [props.radiusField], cfg: { type: 'polar', autoRotate: false, }, plot: this }, props.label)); if (this.point) { this.point.label = label; } else if (this.line) { this.line.label = label; } else if (this.area) { this.area.label = label; } }; RadarLayer.prototype.annotation = function () { return; }; RadarLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { // 关闭动画 if (this.area) this.area.animate = false; if (this.line) this.line.animate = false; if (this.point) this.point.animate = false; } }; RadarLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; return RadarLayer; }(view_layer_1.default)); exports.default = RadarLayer; global_1.registerPlotType('radar', RadarLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../geoms/factory":430,"../../util/scale":712,"./event":586,"./theme":589,"@antv/util":803,"tslib":894}],589:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * Create By Bruce Too * On 2020-02-14 */ var theme_1 = require("../../theme"); var AREA_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity }; }; var AREA_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var LINE_ACTIVE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity }; }; var LINE_DISABLE_STYLE = function (style) { var opacity = style.opacity || 1; return { opacity: opacity * 0.5 }; }; var LINE_SELECTED_STYLE = function (style) { var lineWidth = style.lineWidth || 1; return { lineWidth: lineWidth + 2 }; }; var POINT_ACTIVE_STYLE = function (style) { var color = style.fill || style.fillStyle; var radius = style.size || style.radius; return { radius: radius + 1, shadowBlur: radius, shadowColor: color, stroke: color, strokeOpacity: 1, lineWidth: 1, }; }; var POINT_SELECTED_STYLE = function (style) { var color = style.fill || style.fillStyle; var radius = style.size || style.radius; return { radius: radius + 2, shadowBlur: radius, shadowColor: color, stroke: color, strokeOpacity: 1, lineWidth: 2, }; }; var POINT_DISABLED_STYLE = function (style) { var opacity = style.opacity || style.fillOpacity || 1; return { opacity: opacity * 0.5 }; }; theme_1.registerTheme('radar', { areaStyle: { normal: {}, active: AREA_ACTIVE_STYLE, disable: AREA_DISABLE_STYLE, selected: { lineWidth: 1, stroke: '#333333' }, }, lineStyle: { normal: {}, active: LINE_ACTIVE_STYLE, disable: LINE_DISABLE_STYLE, selected: LINE_SELECTED_STYLE, }, pointStyle: { normal: {}, active: POINT_ACTIVE_STYLE, disable: POINT_DISABLED_STYLE, selected: POINT_SELECTED_STYLE, }, }); },{"../../theme":669}],590:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setShapeCache = void 0; var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); // 记录之前的状态 var shapeCache; function clipInFromCenter(shape, animateCfg) { var bbox = shape.getBBox(); var centerX = bbox.minX + bbox.width / 2; shape.setClip({ type: 'rect', attrs: { x: centerX, y: bbox.minY, width: 0, height: bbox.height, }, }); var cliper = shape.get('clipShape'); cliper.animate({ width: bbox.width, x: bbox.minX, }, animateCfg.duration, animateCfg.easing, function () { shape.setClip(null); }, animateCfg.delay); } clipInFromCenter.animationName = 'clipInFromCenter'; function setShapeCache(shapes) { shapeCache = shapes; } exports.setShapeCache = setShapeCache; function updateFromCenter(shape, animateCfg) { var fromPath = getShapeFromCache(shape).attr('path'); var toPath = util_1.clone(shape.attr('path')); shape.attr('path', fromPath); shape.animate({ path: toPath, }, animateCfg.duration, animateCfg.easing, animateCfg.callback, 100); } function getShapeFromCache(shape) { var id = shape.id; var target; util_1.each(shapeCache, function (s) { if (s.id === id) { target = s; } }); return target; } updateFromCenter.animationName = 'updateFromCenter'; dependents_1.registerAnimation('clipInFromCenter', clipInFromCenter); dependents_1.registerAnimation('updateFromCenter', updateFromCenter); },{"../../dependents":425,"@antv/util":803}],591:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var color_1 = require("../../../util/color"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var DEFAULT_OFFSET = 8; function mappingColor(band, gray) { var reflect; util_1.each(band, function (b) { var map = b; if (gray >= map.from && gray < map.to) { reflect = map.color; } }); return reflect; } var RangeBarLabel = /** @class */ (function () { function RangeBarLabel(cfg) { this.destroyed = false; this.view = cfg.view; this.plot = cfg.plot; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); if (!this.options.leftStyle) { this.options.leftStyle = this.options.style; } if (!this.options.rightStyle) { this.options.rightStyle = this.options.style; } this.init(); } RangeBarLabel.prototype.init = function () { var _this = this; this.container = this.getGeometry().labelsContainer; this.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; RangeBarLabel.prototype.render = function () { var _this = this; var _a = this.getGeometry(), elements = _a.elements, coordinate = _a.coordinate; this.coord = coordinate; util_1.each(elements, function (ele) { var shape = ele.shape; var positions = _this.getPosition(shape); var values = _this.getValue(shape); var textAlign = _this.getTextAlign(); var labels = []; util_1.each(positions, function (pos, i) { var style = i === 0 ? _this.options.leftStyle : _this.options.rightStyle; var color = _this.getTextColor(shape, i); if (_this.options.position === 'inner' && _this.options.adjustColor && color !== 'black') { style.stroke = null; } var formatter = _this.options.formatter; var content = formatter ? formatter(values[i]) : values[i]; var label = _this.container.addShape('text', { attrs: util_1.deepMix({}, style, { x: pos.x, y: pos.y, text: content, fill: color, textAlign: textAlign[i], textBaseline: 'middle', }), name: 'label', }); labels.push(label); _this.doAnimation(label); }); shape.set('labelShapes', labels); _this.adjustPosition(labels[0], labels[1], shape); }); this.plot.canvas.draw(); }; RangeBarLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; RangeBarLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; RangeBarLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; RangeBarLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; RangeBarLabel.prototype.getBBox = function () { return this.container.getBBox(); }; RangeBarLabel.prototype.getShapeBbox = function (shape) { var _this = this; var points = []; util_1.each(shape.get('origin').points, function (p) { points.push(_this.coord.convertPoint(p)); }); var bbox = new bbox_1.default(points[0].x, points[1].y, Math.abs(points[2].x - points[0].x), Math.abs(points[0].y - points[1].y)); return bbox; }; RangeBarLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { position: 'outer', offsetX: DEFAULT_OFFSET, offsetY: 0, style: util_1.clone(labelStyle), adjustColor: true, adjustPosition: true, }; }; RangeBarLabel.prototype.getPosition = function (shape) { var bbox = this.getShapeBbox(shape); var minX = bbox.minX, maxX = bbox.maxX, minY = bbox.minY, height = bbox.height; var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY; var y = minY + height / 2 + offsetY; var x1, x2; if (this.options.position === 'outer') { x1 = minX - offsetX; x2 = maxX + offsetX; } else { x1 = minX + offsetX; x2 = maxX - offsetX; } return [ { x: x1, y: y }, { x: x2, y: y }, ]; }; RangeBarLabel.prototype.getValue = function (shape) { var xField = this.plot.options.xField; return shape.get('origin').data[xField]; }; RangeBarLabel.prototype.getTextAlign = function () { if (this.options.position === 'outer') { return ['right', 'left']; } else { return ['left', 'right']; } }; RangeBarLabel.prototype.getTextColor = function (shape, index) { if (this.options.adjustColor && this.options.position === 'inner') { var shapeColor = shape.attr('fill'); var shapeOpacity = shape.attr('opacity') ? shape.attr('opacity') : 1; var rgb = color_1.rgb2arr(shapeColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / shapeOpacity; var colorBand = [ { from: 0, to: 85, color: 'white' }, { from: 85, to: 170, color: '#F6F6F6' }, { from: 170, to: 255, color: 'black' }, ]; var reflect = mappingColor(colorBand, gray); return reflect; } var defaultColor = index === 0 ? this.options.leftStyle.fill : this.options.rightStyle.fill; return defaultColor; }; RangeBarLabel.prototype.doAnimation = function (label) { if (this.plot.animation && this.plot.animation === false) { return; } label.attr('fillOpacity', 0); label.attr('strokeOpacity', 0); label.stopAnimate(); label.animate({ fillOpacity: 1, strokeOpacity: 1, }, 800, 'easeLinear', 500); }; RangeBarLabel.prototype.adjustPosition = function (la, lb, shape) { var origin = shape.get('origin'); var shapeMinX = origin.x[0]; var shapeMaxX = origin.x[1]; var shapeWidth = Math.abs(shapeMaxX - shapeMinX); var panelRange = this.view.coordinateBBox; var boxes = [la.getBBox(), lb.getBBox()]; var ax = la.attr('x'); var bx = lb.attr('x'); if (this.options.adjustPosition && this.options.position === 'inner') { var totalLength = boxes[0].width + boxes[1].width; var isOverlap = boxes[0].maxX - boxes[1].minX > 2; var isTooShort = totalLength > shapeWidth; if (isOverlap || isTooShort) { ax = shapeMinX - this.options.offsetX; la.attr('fill', this.options.leftStyle.fill); la.attr('textAlign', 'right'); boxes[0] = la.getBBox(); bx = shapeMaxX + this.options.offsetX; lb.attr('fill', this.options.rightStyle.fill); lb.attr('textAlign', 'left'); boxes[1] = lb.getBBox(); } } if (boxes[0].minX < panelRange.minX) { ax = panelRange.minX + DEFAULT_OFFSET; la.attr('textAlign', 'left'); } la.attr('x', ax); lb.attr('x', bx); this.plot.canvas.draw(); }; RangeBarLabel.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geom) { return geom.type === 'interval'; }); }; return RangeBarLabel; }()); exports.default = RangeBarLabel; },{"../../../util/bbox":672,"../../../util/color":673,"@antv/util":803,"tslib":894}],592:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var RangeBar = /** @class */ (function (_super) { tslib_1.__extends(RangeBar, _super); function RangeBar() { return _super !== null && _super.apply(this, arguments) || this; } RangeBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'rangeBar'; _super.prototype.createLayers.call(this, layerProps); }; RangeBar.getDefaultOptions = layer_1.default.getDefaultOptions; return RangeBar; }(plot_1.default)); exports.default = RangeBar; },{"../../base/plot":394,"./layer":593,"@antv/util":803,"tslib":894}],593:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../bar/layer")); var label_1 = tslib_1.__importDefault(require("./component/label")); var animation_1 = require("./animation"); var RangeBarLayer = /** @class */ (function (_super) { tslib_1.__extends(RangeBarLayer, _super); function RangeBarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'rangeBar'; return _this; } RangeBarLayer.getDefaultOptions = function () { return util_1.deepMix(_super.getDefaultOptions.call(this), { label: { visible: true, position: 'outer', }, xAxis: { visible: true, autoRotateTitle: false, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoRotate: true, autoHide: true, }, title: { visible: true, spacing: 12, }, }, yAxis: { visible: true, autoRotateTitle: true, grid: { visible: false, }, line: { visible: true, }, tickLine: { visible: true, }, label: { visible: true, autoHide: true, autoRotate: false, }, title: { visible: false, spacing: 12, }, }, }, {}); }; RangeBarLayer.prototype.afterRender = function () { this.renderLabel(); // 为更新动画缓存shape var shapeCaches = []; var geoms = this.view.geometries; util_1.each(geoms, function (geom) { var elements = geom.elements; util_1.each(elements, function (ele) { shapeCaches.push(ele.shape); }); }); animation_1.setShapeCache(shapeCaches); _super.prototype.afterRender.call(this); }; RangeBarLayer.prototype.renderLabel = function () { if (this.options.label && this.options.label.visible) { var label = new label_1.default(tslib_1.__assign({ view: this.view, plot: this }, this.options.label)); label.render(); } }; RangeBarLayer.prototype.animation = function () { _super.prototype.animation.call(this); }; return RangeBarLayer; }(layer_1.default)); exports.default = RangeBarLayer; global_1.registerPlotType('rangeBar', RangeBarLayer); },{"../../base/global":392,"../bar/layer":464,"./animation":590,"./component/label":591,"@antv/util":803,"tslib":894}],594:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setShapeCache = void 0; var dependents_1 = require("../../dependents"); var util_1 = require("@antv/util"); // 记录之前的状态 var shapeCache; function clipInFromCenterVertical(shape, animateCfg) { var bbox = shape.getBBox(); var centerY = bbox.minY + bbox.height / 2; shape.setClip({ type: 'rect', attrs: { x: bbox.minX, y: centerY, width: bbox.width, height: 0, }, }); var cliper = shape.get('clipShape'); cliper.animate({ height: bbox.height, y: bbox.minY, }, animateCfg.duration, animateCfg.easing, function () { shape.setClip(null); }, animateCfg.delay); } clipInFromCenterVertical.animationName = 'clipInFromCenterVertical'; function setShapeCache(shapes) { shapeCache = shapes; } exports.setShapeCache = setShapeCache; function updateFromCenterVertical(shape, animateCfg) { var fromPath = getShapeFromCache(shape).attr('path'); var toPath = util_1.clone(shape.attr('path')); shape.attr('path', fromPath); shape.animate({ path: toPath, }, animateCfg.duration, animateCfg.easing, animateCfg.callback, 100); } function getShapeFromCache(shape) { var id = shape.id; var target; util_1.each(shapeCache, function (s) { if (s.id === id) { target = s; } }); return target; } updateFromCenterVertical.animationName = 'updateFromCenterVertical'; dependents_1.registerAnimation('clipInFromCenterVertical', clipInFromCenterVertical); dependents_1.registerAnimation('updateFromCenterVertical', updateFromCenterVertical); },{"../../dependents":425,"@antv/util":803}],595:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var color_1 = require("../../../util/color"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var DEFAULT_OFFSET = 8; function mappingColor(band, gray) { var reflect; util_1.each(band, function (b) { var map = b; if (gray >= map.from && gray < map.to) { reflect = map.color; } }); return reflect; } var RangeColumnLabel = /** @class */ (function () { function RangeColumnLabel(cfg) { this.destroyed = false; this.view = cfg.view; this.plot = cfg.plot; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); if (!this.options.topStyle) { this.options.topStyle = this.options.style; } if (!this.options.bottomStyle) { this.options.bottomStyle = this.options.style; } this.init(); } RangeColumnLabel.prototype.init = function () { var _this = this; this.container = this.getGeometry().labelsContainer; this.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; RangeColumnLabel.prototype.render = function () { var _this = this; var _a = this.getGeometry(), coordinate = _a.coordinate, elements = _a.elements; this.coord = coordinate; util_1.each(elements, function (ele) { var shape = ele.shape; var positions = _this.getPosition(shape); var values = _this.getValue(shape); var textBaeline = _this.getTextBaseline(); var labels = []; util_1.each(positions, function (pos, i) { var style = i === 1 ? _this.options.topStyle : _this.options.bottomStyle; var color = _this.getTextColor(shape, i); if (_this.options.position === 'inner' && _this.options.adjustColor && color !== 'black') { style.stroke = null; } var formatter = _this.options.formatter; var content = formatter ? formatter(values[i]) : values[i]; var label = _this.container.addShape('text', { attrs: util_1.deepMix({}, style, { x: pos.x, y: pos.y, text: content, fill: color, textAlign: 'center', textBaseline: textBaeline[i], }), name: 'label', }); labels.push(label); _this.doAnimation(label); }); shape.set('labelShapes', labels); _this.adjustPosition(labels[0], labels[1], shape); }); this.plot.canvas.draw(); }; RangeColumnLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; RangeColumnLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; RangeColumnLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; RangeColumnLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; RangeColumnLabel.prototype.getBBox = function () { return this.container.getBBox(); }; RangeColumnLabel.prototype.getShapeBbox = function (shape) { var _this = this; var points = []; util_1.each(shape.get('origin').points, function (p) { points.push(_this.coord.convertPoint(p)); }); var bbox = new bbox_1.default(points[0].x, points[1].y, Math.abs(points[2].x - points[0].x), Math.abs(points[0].y - points[1].y)); return bbox; }; RangeColumnLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { position: 'outer', offsetX: 0, offsetY: DEFAULT_OFFSET, style: util_1.clone(labelStyle), adjustColor: true, adjustPosition: true, }; }; RangeColumnLabel.prototype.getPosition = function (shape) { var bbox = this.getShapeBbox(shape); var minX = bbox.minX, minY = bbox.minY, maxY = bbox.maxY, width = bbox.width; var offsetY = this.options.offsetY; var x = minX + width / 2; var y1, y2; if (this.options.position === 'outer') { y1 = minY - offsetY; y2 = maxY + offsetY; } else { y1 = minY + offsetY; y2 = maxY - offsetY; } return [ { x: x, y: y2 }, { x: x, y: y1 }, ]; }; RangeColumnLabel.prototype.getValue = function (shape) { var yField = this.plot.options.yField; return shape.get('origin').data[yField]; }; RangeColumnLabel.prototype.getTextBaseline = function () { if (this.options.position === 'outer') { return ['top', 'bottom']; } else { return ['bottom', 'top']; } }; RangeColumnLabel.prototype.getTextColor = function (shape, index) { if (this.options.adjustColor && this.options.position === 'inner') { var shapeColor = shape.attr('fill'); var shapeOpacity = shape.attr('opacity') ? shape.attr('opacity') : 1; var rgb = color_1.rgb2arr(shapeColor); var gray = Math.round(rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) / shapeOpacity; var colorBand = [ { from: 0, to: 85, color: 'white' }, { from: 85, to: 170, color: '#F6F6F6' }, { from: 170, to: 255, color: 'black' }, ]; var reflect = mappingColor(colorBand, gray); return reflect; } var defaultColor = index === 1 ? this.options.topStyle.fill : this.options.bottomStyle.fill; return defaultColor; }; RangeColumnLabel.prototype.doAnimation = function (label) { if (this.plot.animation && this.plot.animation === false) { return; } label.attr('fillOpacity', 0); label.attr('strokeOpacity', 0); label.stopAnimate(); label.animate({ fillOpacity: 1, strokeOpacity: 1, }, 800, 'easeLinear', 500); }; RangeColumnLabel.prototype.adjustPosition = function (la, lb, shape) { var origin = shape.get('origin'); var shapeMinY = origin.y[1]; var shapeMaxY = origin.y[0]; var bbox = shape.getBBox(); var height = bbox.height; var shapeHeight = height; var panelRange = this.view.coordinateBBox; var boxes = [la.getBBox(), lb.getBBox()]; var ay = la.attr('y'); var by = lb.attr('y'); if (this.options.adjustPosition && this.options.position === 'inner') { var totalLength = boxes[0].height + boxes[1].height; var isOverlap = boxes[1].maxY - boxes[0].minY > 2; var isTooShort = totalLength > shapeHeight; if (isOverlap || isTooShort) { by = shapeMinY - this.options.offsetY; lb.attr('fill', this.options.topStyle.fill); lb.attr('textBaseline', 'bottom'); ay = shapeMaxY + this.options.offsetY; la.attr('fill', this.options.bottomStyle.fill); la.attr('textBaseline', 'top'); boxes[0] = la.getBBox(); boxes[1] = lb.getBBox(); } } // fixme: textBaseline 取不准bbox if (boxes[0].maxY > panelRange.maxY - DEFAULT_OFFSET) { ay = panelRange.maxY - DEFAULT_OFFSET / 2; la.attr('textBaseline', 'bottom'); } la.attr('y', ay); lb.attr('y', by); this.plot.canvas.draw(); }; RangeColumnLabel.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geom) { return geom.type === 'interval'; }); }; return RangeColumnLabel; }()); exports.default = RangeColumnLabel; },{"../../../util/bbox":672,"../../../util/color":673,"@antv/util":803,"tslib":894}],596:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var RangeColumn = /** @class */ (function (_super) { tslib_1.__extends(RangeColumn, _super); function RangeColumn() { return _super !== null && _super.apply(this, arguments) || this; } RangeColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'rangeColumn'; _super.prototype.createLayers.call(this, layerProps); }; RangeColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return RangeColumn; }(plot_1.default)); exports.default = RangeColumn; },{"../../base/plot":394,"./layer":597,"@antv/util":803,"tslib":894}],597:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../column/layer")); var label_1 = tslib_1.__importDefault(require("./component/label")); var animation_1 = require("./animation"); var RangeColumnLayer = /** @class */ (function (_super) { tslib_1.__extends(RangeColumnLayer, _super); function RangeColumnLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'rangeColumn'; return _this; } RangeColumnLayer.getDefaultOptions = function () { return util_1.deepMix(_super.getDefaultOptions.call(this), { label: { visible: true, position: 'outer', }, }, {}); }; RangeColumnLayer.prototype.afterRender = function () { this.renderLabel(); // 为更新动画缓存shape var shapeCaches = []; var geoms = this.view.geometries; util_1.each(geoms, function (geom) { var elements = geom.elements; util_1.each(elements, function (ele) { shapeCaches.push(ele.shape); }); }); animation_1.setShapeCache(shapeCaches); _super.prototype.afterRender.call(this); }; RangeColumnLayer.prototype.animation = function () { _super.prototype.animation.call(this); this.column.animate = { appear: { animation: 'clipInFromCenterVertical', duration: 600, }, update: { animation: 'updateFromCenterVertical', duration: 600, }, }; }; RangeColumnLayer.prototype.renderLabel = function () { if (this.options.label && this.options.label.visible) { var label = new label_1.default(tslib_1.__assign({ view: this.view, plot: this }, this.options.label)); label.render(); } }; return RangeColumnLayer; }(layer_1.default)); exports.default = RangeColumnLayer; global_1.registerPlotType('rangeColumn', RangeColumnLayer); },{"../../base/global":392,"../column/layer":490,"./animation":594,"./component/label":595,"@antv/util":803,"tslib":894}],598:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { rose: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],599:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-17 */ var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); // TODO label的优化,可能要重新参考 https://github.com/antvis/G2Plot/blob/master/src/plots/rose/component/label/rose-label.ts var Rose = /** @class */ (function (_super) { tslib_1.__extends(Rose, _super); function Rose() { return _super !== null && _super.apply(this, arguments) || this; } Rose.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'rose'; _super.prototype.createLayers.call(this, layerProps); }; Rose.prototype.getRadiusScale = function () { var layer = this.layers[0]; return layer.getRadiusScale(); }; Rose.prototype.getAngleScale = function () { var layer = this.layers[0]; return layer.getAngleScale(); }; Rose.getDefaultOptions = layer_1.default.getDefaultOptions; return Rose; }(plot_1.default)); exports.default = Rose; },{"../../base/plot":394,"./layer":600,"@antv/util":803,"tslib":894}],600:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-17 */ var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../components/factory"); var factory_2 = require("../../geoms/factory"); var EventParser = tslib_1.__importStar(require("./event")); var G2_GEOM_MAP = { rose: 'interval', }; var PLOT_GEOM_MAP = { rose: 'column', }; var RoseLayer = /** @class */ (function (_super) { tslib_1.__extends(RoseLayer, _super); function RoseLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'rose'; return _this; } RoseLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { width: 400, height: 400, title: { visible: false, }, description: { visible: false, }, forceFit: true, padding: 'auto', radius: 0.8, innerRadius: 0, label: { visible: true, type: 'inner', autoRotate: true, adjustColor: false, }, legend: { visible: true, position: 'right', }, tooltip: { visible: true, shared: false, showCrosshairs: false, showMarkers: false, }, columnStyle: { stroke: 'white', lineWidth: 1, }, xAxis: { visible: false, line: { visible: false, }, tickLine: { visible: false, }, grid: { visible: true, alignTick: false, style: { lineWidth: 0.5, }, }, label: { offset: 5, autoRotate: true, }, }, yAxis: { visible: false, }, }); }; RoseLayer.prototype.getOptions = function (props) { var options = _super.prototype.getOptions.call(this, props); var columnStyle = props.sectorStyle; var xField = props.categoryField; var yField = props.radiusField; return util_1.deepMix({}, options, { columnStyle: columnStyle, xField: xField, yField: yField }); }; RoseLayer.prototype.getRadiusScale = function () { var radiusField = this.options.radiusField; if (radiusField) { this.view.getScaleByField(radiusField); } }; RoseLayer.prototype.getAngleScale = function () { var categoryField = this.options.categoryField; if (categoryField) { this.view.getScaleByField(categoryField); } }; RoseLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; RoseLayer.prototype.scale = function () { // super.scale(); var props = this.options; var scales = {}; scales[props.radiusField] = {}; scales[props.categoryField] = { type: 'cat' }; this.setConfig('scales', scales); }; /** 不显示坐标轴 */ /*protected axis() { super.axis(); const options = this.options; if (!options.stackField && !options.groupField) { this.setConfig('axes', false); } }*/ RoseLayer.prototype.coord = function () { var props = this.options; var coordConfig = { type: 'polar', cfg: { radius: props.radius, innerRadius: props.innerRadius || 0, }, }; this.setConfig('coordinate', coordConfig); }; RoseLayer.prototype.addGeometry = function () { var options = this.options; var rose = factory_2.getGeom('interval', 'main', { plot: this, positionFields: [options.categoryField, options.radiusField], widthRatio: { rose: 1, }, }); rose.label = this.extractLabel(); rose.adjust = this.adjustRoseAdjust(); this.rose = rose; if (options.tooltip && (options.tooltip.fields || options.tooltip.formatter)) { this.geometryTooltip(); } this.setConfig('geometry', rose); }; RoseLayer.prototype.adjustRoseAdjust = function () { return; }; RoseLayer.prototype.geometryTooltip = function () { this.rose.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.rose.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.rose.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.rose.tooltip.fields = [this.options.radiusField, this.options.categoryField, this.options.colorField]; } } }; RoseLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { /** 关闭动画 */ this.rose.animate = false; } }; RoseLayer.prototype.annotation = function () { return; }; RoseLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; RoseLayer.prototype.extractLabel = function () { var options = this.options; if (!options.label || !options.label.visible) { return false; } var label = util_1.deepMix({}, options.label); this.adjustLabelOptions(label); var fields = [options.categoryField, options.radiusField]; var labelConfig = factory_1.getComponent('label', tslib_1.__assign({ plot: this, labelType: 'polar', fields: fields }, label)); return labelConfig; }; RoseLayer.prototype.adjustLabelOptions = function (labelOptions) { var radiusField = this.options.radiusField; if (labelOptions) { var offset = labelOptions.offset, type = labelOptions.type, content = labelOptions.content; if (type === 'inner') { labelOptions.offset = offset < 0 ? offset : -10; } else if (type === 'outer') { labelOptions.offset = offset >= 0 ? offset : 10; } if (!content) { // 默认显示 数值 labelOptions.content = function (text, item) { return "" + item._origin[radiusField]; }; } } }; return RoseLayer; }(view_layer_1.default)); exports.default = RoseLayer; global_1.registerPlotType('rose', RoseLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../geoms/factory":430,"./event":598,"@antv/util":803,"tslib":894}],601:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var Quadrant = /** @class */ (function () { function Quadrant(cfg) { this.quadrantGroups = []; this.regionData = []; this.lineData = []; this.options = cfg; this.view = this.options.view; this.init(); } Quadrant.prototype.init = function () { var _a = this.options, xBaseline = _a.xBaseline, yBaseline = _a.yBaseline; var coord = this.view.getCoordinate(); // TODO: xBaseline和yBaseline支持百分比 // 根据 xBaseline 和 yBaseline 分割象限 var xScale = this.view.getScaleByField(this.options.plotOptions.xField); var yScale = this.view.getScaleByField(this.options.plotOptions.yField); // 先进行 x 方向的分割 var xRegion; if (xBaseline > xScale.min && xBaseline < xScale.max) { var ratio = (xBaseline - xScale.min) / (xScale.max - xScale.min); xRegion = [ new bbox_1.default(coord.start.x, coord.end.y, coord.getWidth() * ratio, coord.getHeight()), new bbox_1.default(coord.start.x + coord.getWidth() * ratio, coord.end.y, coord.getWidth() * (1 - ratio), coord.getHeight()), ]; var verticalLineData = { start: { x: coord.start.x + coord.getWidth() * ratio, y: coord.end.y }, end: { x: coord.start.x + coord.getWidth() * ratio, y: coord.start.y }, }; this.lineData.push(verticalLineData); } else { xRegion = [new bbox_1.default(coord.start.x, coord.end.y, coord.getWidth(), coord.getHeight())]; } // 再进行 y 方向的分割 if (yBaseline > yScale.min && yBaseline < yScale.max) { var ratio = (yBaseline - yScale.min) / (yScale.max - yScale.min); var horizontalLineData = { start: { x: coord.start.x, y: coord.start.y - coord.getHeight() * ratio }, end: { x: coord.end.x, y: coord.start.y - coord.getHeight() * ratio }, }; this.lineData.push(horizontalLineData); var topQuadrant = { name: xBaseline <= xScale.min ? 'top-right' : 'top-left', bbox: new bbox_1.default(xRegion[0].minX, xRegion[0].minY, xRegion[0].width, xRegion[0].height * (1 - ratio)), index: xBaseline <= xScale.min ? 2 : 0, }; this.regionData.push(topQuadrant); var bottomQuadrant = { name: xBaseline <= xScale.min ? 'bottom-right' : 'bottom-left', bbox: new bbox_1.default(xRegion[0].minX, xRegion[0].minY + xRegion[0].height * (1 - ratio), xRegion[0].width, xRegion[0].height * ratio), index: xBaseline <= xScale.min ? 3 : 1, }; this.regionData.push(bottomQuadrant); // 四象限齐全 if (xRegion.length > 1) { var rightTopQuadrant = { name: 'top-right', bbox: new bbox_1.default(xRegion[1].minX, xRegion[1].minY, xRegion[1].width, xRegion[1].height * (1 - ratio)), index: 2, }; this.regionData.push(rightTopQuadrant); var rightBottomQuadrant = { name: 'bottom-right', bbox: new bbox_1.default(xRegion[1].minX, xRegion[1].minY + xRegion[1].height * (1 - ratio), xRegion[1].width, xRegion[1].height * ratio), index: 3, }; this.regionData.push(rightBottomQuadrant); } } else if (xRegion.length === 2) { if (yBaseline <= yScale.min) { var leftTopQuadrant = { name: 'top-left', bbox: xRegion[0], index: 0, }; this.regionData.push(leftTopQuadrant); var rightTopQuadrant = { name: 'top-right', bbox: xRegion[1], index: 2, }; this.regionData.push(rightTopQuadrant); } else { var leftBottomQuadrant = { name: 'bottom-left', bbox: xRegion[0], index: 1, }; this.regionData.push(leftBottomQuadrant); var rightBottomQuadrant = { name: 'bottom-right', bbox: xRegion[1], index: 3, }; this.regionData.push(rightBottomQuadrant); } } else { // 当前绘制区域全部在一个象限中 if (xBaseline <= xScale.min) { if (yBaseline <= yScale.min) { var rightTopQuadrant = { name: 'top-right', bbox: xRegion[0], index: 2, }; this.regionData.push(rightTopQuadrant); } else { var rightBottomQuadrant = { name: 'bottom-right', bbox: xRegion[0], index: 3, }; this.regionData.push(rightBottomQuadrant); } } else { if (yBaseline <= yScale.min) { var leftTopQuadrant = { name: 'top-left', bbox: xRegion[0], index: 0, }; this.regionData.push(leftTopQuadrant); } else { var leftBottomQuadrant = { name: 'bottom-left', bbox: xRegion[0], index: 1, }; this.regionData.push(leftBottomQuadrant); } } } // 创建container this.container = this.view.backgroundGroup.addGroup(); }; Quadrant.prototype.render = function () { var _this = this; if (this.regionData.length > 0) { var defaultStyle_1 = this.getDefaultStyle(); var regionStyle_1 = this.getRegionStyle(this.regionData); util_1.each(this.regionData, function (d) { var index = d.index; var group = _this.container.addGroup(); var rect = group.addShape('rect', { attrs: tslib_1.__assign({ x: d.bbox.minX, y: d.bbox.minY, width: d.bbox.width, height: d.bbox.height }, regionStyle_1[index]), name: 'quadrant', }); if (_this.options.label && _this.options.label.text) { var labelOptions = util_1.deepMix({}, defaultStyle_1.label, _this.options.label); var labelCfg = _this.getLabelConfig(d, labelOptions); group.addShape('text', { attrs: tslib_1.__assign({}, labelCfg), name: 'quadrant-label', }); } // rect.setSilent('data', d); rect.set('data', d); _this.quadrantGroups.push(group); }); // 绘制象限辅助线 var lineStyle_1 = util_1.deepMix({}, defaultStyle_1.line, this.options.lineStyle); util_1.each(this.lineData, function (d) { _this.container.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', d.start.x, d.start.y], ['L', d.end.x, d.end.y], ] }, lineStyle_1), name: 'quadrant-line', }); }); this.view.canvas.draw(); } }; Quadrant.prototype.clear = function () { if (this.container) { this.container.clear(); } }; Quadrant.prototype.destroy = function () { if (this.container) { this.container.remove(); } }; Quadrant.prototype.getDefaultStyle = function () { return { line: { stroke: '#9ba29a', lineWidth: 1, }, regionStyle: [ { fill: '#000000', opacity: 0.05 }, { fill: '#ffffff', opacity: 0 }, { fill: '#ffffff', opacity: 0 }, { fill: '#000000', opacity: 0.05 }, ], label: { position: 'outter-inner', offset: 10, style: { fontSize: 14, fill: '#ccc', }, }, }; }; Quadrant.prototype.getRegionStyle = function (regionData) { var defaultStyle = this.getDefaultStyle(); var style = defaultStyle.regionStyle; if (this.options.regionStyle) { var regionStyle_2 = this.options.regionStyle; if (util_1.isArray(regionStyle_2)) { style = style.map(function (s, index) { if (regionStyle_2.length > index && regionStyle_2[index]) { return regionStyle_2[index]; } return s; }); } else if (util_1.isFunction(regionStyle_2)) { util_1.each(regionData, function (d, index) { style[index] = regionStyle_2(d); }); } } return style; }; Quadrant.prototype.getLabelConfig = function (region, labelOptions) { var index = region.index; var x = 0; var y = 0; var style = {}; var text = labelOptions.text; if (util_1.isFunction(text)) { text = text(region); } else if (util_1.isArray(text)) { text = text[index]; } var position = labelOptions.position; var pos = position.split('-'); var dim = region.name.split('-'); // x方向 if (dim[1] === 'left') { if (pos[0] === 'inner') { x = region.bbox.maxX - labelOptions.offset; style.textAlign = 'right'; } if (pos[0] === 'outter') { x = region.bbox.minX + labelOptions.offset; style.textAlign = 'left'; } } else if (dim[1] === 'right') { if (pos[0] === 'inner') { x = region.bbox.minX + labelOptions.offset; style.textAlign = 'left'; } if (pos[0] === 'outter') { x = region.bbox.maxX - labelOptions.offset; style.textAlign = 'right'; } } // y方向 if (dim[0] === 'top') { if (pos[1] === 'inner') { y = region.bbox.maxY - labelOptions.offset; style.textBaseline = 'bottom'; } if (pos[1] === 'outter') { y = region.bbox.minY + labelOptions.offset; style.textBaseline = 'top'; } } else if (dim[0] === 'bottom') { if (pos[1] === 'inner') { y = region.bbox.minY + labelOptions.offset; style.textBaseline = 'top'; } if (pos[1] === 'outter') { y = region.bbox.maxY - labelOptions.offset; style.textBaseline = 'bottom'; } } style = util_1.deepMix({}, labelOptions.style, style); style.lineHeight = style.fontSize; return tslib_1.__assign({ x: x, y: y, text: text }, style); }; return Quadrant; }()); exports.default = Quadrant; },{"../../../util/bbox":672,"@antv/util":803,"tslib":894}],602:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var scale_1 = require("@antv/scale"); var d3_regression_1 = require("d3-regression"); var path_1 = require("../../../util/path"); var REGRESSION_MAP = { exp: d3_regression_1.regressionExp, linear: d3_regression_1.regressionLinear, loess: d3_regression_1.regressionLoess, log: d3_regression_1.regressionLog, poly: d3_regression_1.regressionPoly, pow: d3_regression_1.regressionPow, quad: d3_regression_1.regressionQuad, }; function se95(p, n) { return Math.sqrt((p * (1 - p)) / n) * 1.96; } var TrendLine = /** @class */ (function () { function TrendLine(cfg) { var defaultOptions = { type: 'linear', style: { stroke: '#9ba29a', lineWidth: 2, opacity: 0.5, lineJoin: 'round', lineCap: 'round', }, showConfidence: false, confidenceStyle: { fill: '#ccc', opacity: 0.1, }, }; this.options = util_1.deepMix({}, defaultOptions, cfg); this.view = this.options.view; this.init(); } TrendLine.prototype.init = function () { // 处理数据 var _a = this.options.plotOptions, xField = _a.xField, yField = _a.yField, data = _a.data; var reg = REGRESSION_MAP[this.options.type]() .x(function (d) { return d[xField]; }) .y(function (d) { return d[yField]; }); this.data = this.processData(reg(data)); // 创建container this.container = this.view.backgroundGroup.addGroup(); }; TrendLine.prototype.render = function () { var xscale_view = this.view.getScaleByField(this.options.plotOptions.xField); var yscale_view = this.view.getScaleByField(this.options.plotOptions.yField); var coord = this.view.getCoordinate(); var trendlineData = this.data.trendlineData; // 创建图形绘制的scale var LinearScale = scale_1.getScale('linear'); var xRange = this.adjustScale(xscale_view, trendlineData, 'x'); var xScale = new LinearScale({ min: xRange.min, max: xRange.max, }); var yRange = this.adjustScale(yscale_view, trendlineData, 'y'); var yScale = new LinearScale({ min: yRange.min, max: yRange.max, }); // 绘制置信区间曲线 if (this.options.showConfidence) { var confidencePath = this.getConfidencePath(xScale, yScale, coord); this.container.addShape('path', { attrs: tslib_1.__assign({ path: confidencePath }, this.options.confidenceStyle), name: 'confidence', }); } // 绘制trendline var points = this.getTrendlinePoints(xScale, yScale, coord); var constraint = [ [0, 0], [1, 1], ]; var path = path_1.getSplinePath(points, false, constraint); this.shape = this.container.addShape('path', { attrs: tslib_1.__assign({ path: path }, this.options.style), name: 'trendline', }); }; TrendLine.prototype.clear = function () { if (this.container) { this.container.clear(); } }; TrendLine.prototype.destroy = function () { if (this.container) { this.container.destroy(); } }; TrendLine.prototype.processData = function (data) { var trendline = []; var confidence = []; util_1.each(data, function (d) { trendline.push({ x: d[0], y: d[1] }); var conf = se95(data.rSquared, d[1]); confidence.push({ x: d[0], y0: d[1] - conf, y1: d[1] + conf }); }); return { trendlineData: trendline, confidenceData: confidence }; }; TrendLine.prototype.getTrendlinePoints = function (xScale, yScale, coord) { var points = []; util_1.each(this.data.trendlineData, function (d) { var xRatio = xScale.scale(d.x); var yRatio = yScale.scale(d.y); var x = coord.start.x + coord.width * xRatio; var y = coord.start.y - coord.height * yRatio; points.push({ x: x, y: y }); }); return points; }; TrendLine.prototype.getConfidencePath = function (xScale, yScale, coord) { var upperPoints = []; var lowerPoints = []; var path = []; util_1.each(this.data.confidenceData, function (d) { var xRatio = xScale.scale(d.x); var y0Ratio = yScale.scale(d.y0); var y1Ratio = yScale.scale(d.y1); var x = coord.start.x + coord.width * xRatio; var y0 = coord.start.y - coord.height * y0Ratio; var y1 = coord.start.y - coord.height * y1Ratio; upperPoints.push({ x: x, y: y0 }); lowerPoints.push({ x: x, y: y1 }); }); for (var i = 0; i < upperPoints.length; i++) { var flag = i === 0 ? 'M' : 'L'; var p = upperPoints[i]; if (!isNaN(p.x) && !isNaN(p.y)) { path.push([flag, p.x, p.y]); } } for (var j = lowerPoints.length - 1; j > 0; j--) { var p = lowerPoints[j]; if (!isNaN(p.x) && !isNaN(p.y)) { path.push(['L', p.x, p.y]); } } return path; }; TrendLine.prototype.adjustScale = function (viewScale, trendlineData, dim) { // 处理用户自行配置min max的情况 var min = viewScale.min, max = viewScale.max; var _a = this.options.plotOptions, data = _a.data, xField = _a.xField, yField = _a.yField; var field = dim === 'x' ? xField : yField; var dataMin = util_1.minBy(data, field)[field]; var dataMax = util_1.maxBy(data, field)[field]; var minRatio = (min - dataMin) / (dataMax - dataMin); var maxRatio = (max - dataMax) / (dataMax - dataMin); var trendMin = util_1.minBy(trendlineData, dim)[dim]; var trendMax = util_1.maxBy(trendlineData, dim)[dim]; return { min: trendMin + minRatio * (trendMax - trendMin), max: trendMax + maxRatio * (trendMax - trendMin), }; }; return TrendLine; }()); exports.default = TrendLine; },{"../../../util/path":681,"@antv/scale":747,"@antv/util":803,"d3-regression":878,"tslib":894}],603:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { point: 'point', trendline: 'trendline', confidence: 'confidence', quadrant: 'quadrant', quadrantLabel: 'quadrant-label', quadrantLine: 'quadrant-line', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],604:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Scatter = /** @class */ (function (_super) { tslib_1.__extends(Scatter, _super); function Scatter() { return _super !== null && _super.apply(this, arguments) || this; } Scatter.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'scatter'; _super.prototype.createLayers.call(this, layerProps); }; Scatter.getDefaultOptions = layer_1.default.getDefaultOptions; return Scatter; }(plot_1.default)); exports.default = Scatter; },{"../../base/plot":394,"./layer":605,"@antv/util":803,"tslib":894}],605:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var factory_1 = require("../../geoms/factory"); var scale_1 = require("../../util/scale"); var quadrant_1 = tslib_1.__importDefault(require("./components/quadrant")); var trendline_1 = tslib_1.__importDefault(require("./components/trendline")); var EventParser = tslib_1.__importStar(require("./event")); var factory_2 = require("../../components/factory"); require("./theme"); var G2_GEOM_MAP = { scatter: 'point', }; var PLOT_GEOM_MAP = { point: 'point', }; var ScatterLayer = /** @class */ (function (_super) { tslib_1.__extends(ScatterLayer, _super); function ScatterLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'scatter'; return _this; } ScatterLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { pointSize: 4, pointStyle: { lineWidth: 1, strokeOpacity: 1, fillOpacity: 0.95, stroke: '#fff', }, xAxis: { nice: true, grid: { visible: true, }, line: { visible: true, }, }, yAxis: { nice: true, grid: { visible: true, }, line: { visible: true, }, }, tooltip: { visible: true, // false 会造成 tooltip 只能显示一条数据,true 会造成 tooltip 在空白区域也会显示 shared: null, showTitle: false, showMarkers: false, showCrosshairs: false, }, label: { visible: false, }, shape: 'circle', }); }; ScatterLayer.prototype.afterRender = function () { _super.prototype.afterRender.call(this); if (this.quadrant) { this.quadrant.destroy(); } if (this.trendline) { this.trendline.destroy(); } if (this.options.quadrant && this.options.quadrant.visible) { this.quadrant = new quadrant_1.default(tslib_1.__assign({ view: this.view, plotOptions: this.options }, this.options.quadrant)); this.quadrant.render(); } if (this.options.trendline && this.options.trendline.visible) { this.trendline = new trendline_1.default(tslib_1.__assign({ view: this.view, plotOptions: this.options }, this.options.trendline)); this.trendline.render(); } }; ScatterLayer.prototype.destroy = function () { if (this.quadrant) { this.quadrant.destroy(); this.quadrant = null; } if (this.trendline) { this.trendline.destroy(); this.trendline = null; } _super.prototype.destroy.call(this); }; ScatterLayer.prototype.isValidLinearValue = function (value) { if (util_1.isNil(value)) { return false; } else if (Number.isNaN(Number(value))) { return false; } return true; }; ScatterLayer.prototype.processData = function (data) { var _this = this; var _a = this.options, xField = _a.xField, yField = _a.yField; var xAxisType = util_1.get(this.options, ['xAxis', 'type'], 'linear'); var yAxisType = util_1.get(this.options, ['yAxis', 'type'], 'linear'); if (xAxisType && yAxisType) { var fiteredData = data .filter(function (item) { if (xAxisType === 'linear' && !_this.isValidLinearValue(item[xField])) { return false; } if (yAxisType === 'linear' && !_this.isValidLinearValue(item[yField])) { return false; } return true; }) .map(function (item) { var _a; return tslib_1.__assign(tslib_1.__assign({}, item), (_a = {}, _a[xField] = xAxisType === 'linear' ? Number(item[xField]) : String(item[xField]), _a[yField] = yAxisType === 'linear' ? Number(item[yField]) : String(item[yField]), _a)); }); return fiteredData; } return data; }; ScatterLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; ScatterLayer.prototype.scale = function () { var props = this.options; var scales = {}; /** 配置x-scale */ scales[props.xField] = {}; if (util_1.has(props, 'xAxis')) { scale_1.extractScale(scales[props.xField], props.xAxis); } /** 配置y-scale */ scales[props.yField] = {}; if (util_1.has(props, 'yAxis')) { scale_1.extractScale(scales[props.yField], props.yAxis); } var timeLineInteraction = util_1.find(props.interactions, function (interaction) { return interaction.type === 'timeline'; }); if (timeLineInteraction && util_1.get(timeLineInteraction, 'cfg.key')) { var keyField = timeLineInteraction.cfg.key; if (scales[keyField]) { scales[keyField].key = true; } else { scales[keyField] = { key: true }; } } this.setConfig('scales', scales); _super.prototype.scale.call(this); }; ScatterLayer.prototype.coord = function () { return; }; ScatterLayer.prototype.annotation = function () { return; }; ScatterLayer.prototype.addGeometry = function () { var points = factory_1.getGeom('point', 'circle', { plot: this, }); this.points = points; if (this.options.tooltip && this.options.tooltip.visible) { var _a = this.options.tooltip, showTitle = _a.showTitle, titleField = _a.titleField; this.extractTooltip(); this.setConfig('tooltip', tslib_1.__assign({ showTitle: showTitle, title: showTitle ? titleField : undefined }, this.options.tooltip)); } if (this.options.label) { this.label(); } this.setConfig('geometry', points); }; ScatterLayer.prototype.label = function () { var props = this.options; if (props.label.visible === false) { if (this.points) { this.points.label = false; } return; } var label = factory_2.getComponent('label', tslib_1.__assign(tslib_1.__assign({ fields: props.label.field ? [props.label.field] : [props.yField] }, props.label), { plot: this })); if (this.points) { this.points.label = label; } }; ScatterLayer.prototype.animation = function () { _super.prototype.animation.call(this); var props = this.options; if (props.animation === false) { /** 关闭动画 */ this.points.animate = false; } }; ScatterLayer.prototype.parseEvents = function (eventParser) { // 气泡图继承散点图时,会存在 eventParser _super.prototype.parseEvents.call(this, eventParser || EventParser); }; ScatterLayer.prototype.extractTooltip = function () { this.points.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.points.tooltip.fields = tooltipOptions.fields; } else { this.points.tooltip.fields = [this.options.xField, this.options.yField]; } if (tooltipOptions.formatter) { this.points.tooltip.callback = tooltipOptions.formatter; if (this.options.colorField) { this.points.tooltip.fields.push(this.options.colorField); } } }; return ScatterLayer; }(view_layer_1.default)); exports.default = ScatterLayer; global_1.registerPlotType('scatter', ScatterLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../geoms/factory":430,"../../util/scale":712,"./components/quadrant":601,"./components/trendline":602,"./event":603,"./theme":606,"@antv/util":803,"tslib":894}],606:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var POINT_ACTIVE_STYLE = function (style) { var stroke = style.stroke || '#000'; return { stroke: stroke, }; }; var POINT_SELECTED_STYLE = function (style) { var stroke = style.stroke || '#000'; var lineWidth = style.lineWidth || 2; return { stroke: stroke, lineWidth: lineWidth, }; }; var POINT_INACTIVE_STYLE = function (style) { var fillOpacity = style.fillOpacity || style.opacity || 0.3; return { fillOpacity: fillOpacity, }; }; theme_1.registerTheme('scatter', { pointStyle: { normal: {}, active: POINT_ACTIVE_STYLE, selected: POINT_SELECTED_STYLE, inactive: POINT_INACTIVE_STYLE, }, }); },{"../../theme":669}],607:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPlotComponents = void 0; var tslib_1 = require("tslib"); var line_label_1 = tslib_1.__importDefault(require("./label/line-label")); var area_label_1 = tslib_1.__importDefault(require("./label/area-label")); var ComponentsInfo = { lineLabel: { Ctr: line_label_1.default }, areaLabel: { Ctr: area_label_1.default }, }; function getPlotComponents(plot, type, cfg) { if (plot.options[type] && plot.options[type].visible) { var componentInfo = ComponentsInfo[type]; var component = new componentInfo.Ctr(cfg); if (componentInfo.padding) { plot.paddingController.registerPadding(component, componentInfo.padding); } return component; } } exports.getPlotComponents = getPlotComponents; },{"./label/area-label":608,"./label/line-label":611,"tslib":894}],608:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var DEFAULT_SIZE = 12; var TOLERANCE = 0.01; var MAX_ITERATION = 100; var MIN_HEIGHT = 12; function getRange(points) { var maxHeight = -Infinity; var min = Infinity; var max = -Infinity; util_1.each(points, function (p) { min = Math.min(p.x, min); max = Math.max(p.x, max); var height = Math.abs(p.y[0] - p.y[1]); maxHeight = Math.max(maxHeight, height); }); return { xRange: [min, max], maxHeight: maxHeight, }; } function interpolateY(x, points, index) { var leftPoint = points[0]; var rightPoint = points[points.length - 1]; util_1.each(points, function (p) { if (p.x === x) { return p.y[index]; } if (p.x < x && p.x > leftPoint.x) { leftPoint = p; } if (p.x > x && p.x < rightPoint.x) { rightPoint = p; } }); var t = (x - leftPoint.x) / (rightPoint.x - leftPoint.x); return leftPoint.y[index] * (1 - t) + rightPoint.y[index] * t; } function getXIndex(data, x) { // tslint:disable-next-line: prefer-for-of var i; for (i = 0; i < data.length; i++) { var d = data[i]; if (d.x === x || d.x > x) { break; } } return i; } var AreaLabel = /** @class */ (function () { function AreaLabel(cfg) { this.destroyed = false; this.scaleFactor = []; this.view = cfg.view; this.plot = cfg.plot; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); this.init(); } AreaLabel.prototype.init = function () { var _this = this; this.container = this.getGeometry().labelsContainer; this.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; AreaLabel.prototype.render = function () { var _this = this; var stackField = this.plot.options.stackField; var groupedPoints = this.getGeometry().dataArray; var labelPoints = []; util_1.each(groupedPoints, function (pointArray, name) { var labelPoint = _this.drawLabel(pointArray, name); if (labelPoint) { labelPoints.push(util_1.deepMix({}, pointArray[0], labelPoint)); _this.scaleFactor.push(labelPoint.scaleFactor); } }); var labelShapes = []; util_1.each(labelPoints, function (p, index) { var _a = _this.options, style = _a.style, offsetX = _a.offsetX, offsetY = _a.offsetY; var labelSize = _this.getFontSize(index); var formatter = _this.options.formatter; var content = formatter ? formatter(p._origin[stackField]) : p._origin[stackField]; var text = _this.container.addShape('text', { attrs: util_1.deepMix({}, { x: p.x + offsetX, y: p.y + offsetY, text: content, fill: p.color, fontSize: labelSize, textAlign: 'center', textBaseline: 'top', }, style), name: 'label', }); labelShapes.push(text); }); this.plot.canvas.draw(); }; AreaLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; AreaLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; AreaLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; AreaLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; AreaLabel.prototype.getBBox = function () { return this.container.getBBox(); }; AreaLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = util_1.clone(theme.label.style); labelStyle.stroke = null; delete labelStyle.fill; return { offsetX: 0, offsetY: 0, style: labelStyle, autoScale: true, }; }; AreaLabel.prototype.drawLabel = function (points, name) { var _a = getRange(points), xRange = _a.xRange, maxHeight = _a.maxHeight; // 根据area宽度在x方向各点间做插值 var resolution = xRange[1] - xRange[0]; var interpolatedPoints = this.getInterpolatedPoints(xRange[0], resolution, points); // 获取label的bbox var bbox = this.getLabelBbox(name); var fitOption = { xRange: xRange, aspect: bbox.width / bbox.height, data: interpolatedPoints, justTest: true, }; var height = this.bisection(MIN_HEIGHT, maxHeight, this.testFit, fitOption, TOLERANCE, MAX_ITERATION); if (height === null) { return; } fitOption.justTest = false; var fit = this.testFit(fitOption); fit.x = fit.x; fit.y = fit.y0 + (fit.y1 - fit.y0) / 2; fit.scaleFactor = (height / bbox.height) * 0.2; return fit; }; AreaLabel.prototype.getInterpolatedPoints = function (minX, resolution, points) { var interpolatedPoints = []; var step = 2; for (var i = minX; i < resolution; i += step) { var y0 = interpolateY(i, points, 0); var y1 = interpolateY(i, points, 1); interpolatedPoints.push({ x: i, y: [y0, y1], }); } return interpolatedPoints; }; AreaLabel.prototype.bisection = function (min, max, test, testOption, tolerance, maxIteration) { for (var i = 0; i < maxIteration; i++) { var middle = (min + max) / 2; var options = testOption; options.height = middle; options.width = middle * options.aspect; var passesTest = test(options); var withinTolerance = (max - min) / 2 < tolerance; if (passesTest && withinTolerance) { return middle; } if (passesTest) { min = middle; } else { max = middle; } } return null; }; AreaLabel.prototype.testFit = function (option) { var xRange = option.xRange, width = option.width, height = option.height, data = option.data, justTest = option.justTest; for (var i = 0; i < data.length; i++) { var d = data[i]; var x0 = d.x; var x1 = x0 + width; if (x1 > xRange[1]) { break; } var x1_index = getXIndex(data, x1); var ceiling = -Infinity; var ceilingFloor = null; // 保存ceiling时对应的bottom位置,ceil和floor不一定是一对坐标 var floor = Infinity; for (var j = i; j < x1_index; j++) { var top_1 = data[j].y[1]; var bottom = data[j].y[0]; if (bottom < floor) { floor = bottom; } if (top_1 > ceiling) { ceiling = top_1; ceilingFloor = bottom; } if (floor - ceiling < height) { break; } } if (floor - ceiling >= height) { if (justTest) { return true; } return { x: x0, y0: ceiling, y1: ceilingFloor, width: width, height: height, }; } } return false; }; AreaLabel.prototype.getLabelBbox = function (text) { var labelStyle = util_1.clone(this.plot.theme.label.textStyle); labelStyle.fontSize = DEFAULT_SIZE; var tShape = this.container.addShape('text', { attrs: tslib_1.__assign({ text: text, x: 0, y: 0 }, labelStyle), }); var bbox = tShape.getBBox(); tShape.remove(); return bbox; }; AreaLabel.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geom) { return geom.type === 'area'; }); }; AreaLabel.prototype.getFontSize = function (index) { if (this.options.autoScale) { var scaleFactor = this.scaleFactor[index]; return DEFAULT_SIZE * scaleFactor; } return DEFAULT_SIZE; }; return AreaLabel; }()); exports.default = AreaLabel; },{"@antv/util":803,"tslib":894}],609:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../../components/label/base"); var area_point_auto_1 = tslib_1.__importDefault(require("../../../area/component/label/area-point-auto")); var StackedAreaPointAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(StackedAreaPointAutoLabel, _super); function StackedAreaPointAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** 对堆积面积使用自定义的排序 */ StackedAreaPointAutoLabel.prototype.sortLabels = function (geometry, labels) { var sorted = []; if (labels.length > 0) { sorted.push(labels.shift()); } if (labels.length > 0) { sorted.push(labels.pop()); } sorted.push.apply(sorted, labels); return sorted; }; return StackedAreaPointAutoLabel; }(area_point_auto_1.default)); exports.default = StackedAreaPointAutoLabel; base_1.registerLabelComponent('stackedArea-point-auto', StackedAreaPointAutoLabel); },{"../../../../components/label/base":414,"../../../area/component/label/area-point-auto":452,"tslib":894}],610:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../../components/label/base"); var area_point_1 = tslib_1.__importDefault(require("../../../area/component/label/area-point")); var StackedAreaPointLabel = /** @class */ (function (_super) { tslib_1.__extends(StackedAreaPointLabel, _super); function StackedAreaPointLabel() { return _super !== null && _super.apply(this, arguments) || this; } return StackedAreaPointLabel; }(area_point_1.default)); exports.default = StackedAreaPointLabel; base_1.registerLabelComponent('stackedArea-point', StackedAreaPointLabel); },{"../../../../components/label/base":414,"../../../area/component/label/area-point":453,"tslib":894}],611:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var line_label_1 = tslib_1.__importDefault(require("../../../line/component/label/line-label")); /** * 复用扎线图的 label,并修改取值方式 */ var AreaLineLabel = /** @class */ (function (_super) { tslib_1.__extends(AreaLineLabel, _super); function AreaLineLabel() { return _super !== null && _super.apply(this, arguments) || this; } AreaLineLabel.prototype.getShapeInfo = function (shape) { var originPoints = shape.get('origin').points; var lastPoint = originPoints[originPoints.length - 1]; var color = shape.attr('stroke'); var stackField = this.plot.options.stackField; var name = shape.get('origin').data[0][stackField]; var y = util_1.reduce(lastPoint.y, function (r, a) { return r + a; }, 0) / util_1.size(lastPoint.y); return { x: lastPoint.x, y: y, color: color, name: name }; }; return AreaLineLabel; }(line_label_1.default)); exports.default = AreaLineLabel; },{"../../../line/component/label/line-label":550,"@antv/util":803,"tslib":894}],612:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var StackedArea = /** @class */ (function (_super) { tslib_1.__extends(StackedArea, _super); function StackedArea() { return _super !== null && _super.apply(this, arguments) || this; } StackedArea.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedArea'; _super.prototype.createLayers.call(this, layerProps); }; StackedArea.getDefaultOptions = layer_1.default.getDefaultOptions; return StackedArea; }(plot_1.default)); exports.default = StackedArea; },{"../../base/plot":394,"./layer":613,"@antv/util":803,"tslib":894}],613:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../area/layer")); var component_1 = require("./component"); require("./component/label/area-point"); require("./component/label/area-point-auto"); require("./theme"); var StackedAreaLayer = /** @class */ (function (_super) { tslib_1.__extends(StackedAreaLayer, _super); function StackedAreaLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.plotComponents = []; _this.type = 'stackedArea'; _this.baseType = 'area'; return _this; } StackedAreaLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { label: { visible: false, type: 'area', }, }); }; StackedAreaLayer.prototype.beforeInit = function () { var visible = util_1.get(this.options, ['label', 'visible']); var type = util_1.get(this.options, ['label', 'type']); var options = this.options; if (visible) { if (type === 'line') { options.lineLabel = this.options.label; } if (type === 'area') { options.areaLabel = this.options.label; } } _super.prototype.beforeInit.call(this); }; StackedAreaLayer.prototype.getColorScale = function () { var stackField = this.options.stackField; return this.view.getScaleByField(stackField); }; StackedAreaLayer.prototype.label = function () { var props = this.options; var label = props.label; if (label && label.visible === false) { if (this.line) { this.line.label = false; } if (this.point) { this.point.label = false; } this.area.label = false; return; } }; StackedAreaLayer.prototype.adjustArea = function (ele) { ele.adjust = [ { type: 'stack', }, ]; }; StackedAreaLayer.prototype.adjustLine = function (ele) { ele.adjust = [ { type: 'stack', }, ]; }; StackedAreaLayer.prototype.adjustPoint = function (ele) { ele.adjust = [ { type: 'stack', }, ]; }; StackedAreaLayer.prototype.afterRender = function () { this.renderPlotComponents(); this.options.responsive = false; _super.prototype.afterRender.call(this); }; StackedAreaLayer.prototype.geometryTooltip = function () { this.area.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.area.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.area.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.area.tooltip.fields = [this.options.xField, this.options.yField, this.options.stackField]; } } }; StackedAreaLayer.prototype.renderPlotComponents = function () { var _this = this; var componentsType = ['areaLabel', 'lineLabel']; util_1.each(componentsType, function (t) { var cfg = tslib_1.__assign({ view: _this.view, plot: _this }, _this.options[t]); var component = component_1.getPlotComponents(_this, t, cfg); if (component) { component.render(); _this.plotComponents.push(component); } }); }; return StackedAreaLayer; }(layer_1.default)); exports.default = StackedAreaLayer; global_1.registerPlotType('stackedArea', StackedAreaLayer); },{"../../base/global":392,"../area/layer":456,"./component":607,"./component/label/area-point":610,"./component/label/area-point-auto":609,"./theme":614,"@antv/util":803,"tslib":894}],614:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var theme_2 = require("../area/theme"); theme_1.registerTheme('stackedArea', theme_2.DEFAULT_AREA_THEME); },{"../../theme":669,"../area/theme":457}],615:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../components/label/base"); var label_auto_1 = tslib_1.__importDefault(require("../../bar/component/label-auto")); /** 自动模式的 StackedBar 数据标签,会根据图形和数据标签自动优化数据标签布局和样式等 */ var StackedBarAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(StackedBarAutoLabel, _super); function StackedBarAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** 堆积柱形图全部内置 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars StackedBarAutoLabel.prototype.shouldInShapeLabels = function (labels) { return true; }; return StackedBarAutoLabel; }(label_auto_1.default)); exports.default = StackedBarAutoLabel; base_1.registerLabelComponent('stacked-bar-auto', StackedBarAutoLabel); },{"../../../components/label/base":414,"../../bar/component/label-auto":460,"tslib":894}],616:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../components/label/base"); var label_1 = tslib_1.__importDefault(require("../../bar/component/label")); var StackedBarLabel = /** @class */ (function (_super) { tslib_1.__extends(StackedBarLabel, _super); function StackedBarLabel() { return _super !== null && _super.apply(this, arguments) || this; } StackedBarLabel.prototype.adjustLabel = function (label, element) { if (this.options.adjustPosition) { var labelRange = label.getBBox(); var shapeRange = this.getElementShapeBBox(element); // label 有 offset if (shapeRange.maxX <= labelRange.maxX) { label.set('visible', false); } } }; return StackedBarLabel; }(label_1.default)); exports.default = StackedBarLabel; base_1.registerLabelComponent('stacked-bar', StackedBarLabel); },{"../../../components/label/base":414,"../../bar/component/label":461,"tslib":894}],617:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var StackedBar = /** @class */ (function (_super) { tslib_1.__extends(StackedBar, _super); function StackedBar() { return _super !== null && _super.apply(this, arguments) || this; } StackedBar.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedBar'; _super.prototype.createLayers.call(this, layerProps); }; StackedBar.getDefaultOptions = layer_1.default.getDefaultOptions; return StackedBar; }(plot_1.default)); exports.default = StackedBar; },{"../../base/plot":394,"./layer":618,"@antv/util":803,"tslib":894}],618:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../bar/layer")); require("./theme"); require("./component/label"); require("./component/label-auto"); var view_1 = require("../../util/view"); var StackedBarLayer = /** @class */ (function (_super) { tslib_1.__extends(StackedBarLayer, _super); function StackedBarLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'stackedBar'; _this.baseType = 'bar'; return _this; } StackedBarLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, autoRotateTitle: false, grid: { visible: true, }, line: { visible: false, }, tickLine: { visible: true, }, label: { visible: true, autoRotate: true, autoHide: true, }, title: { visible: true, spacing: 12, }, }, yAxis: { visible: true, autoRotateTitle: true, grid: { visible: false, }, line: { visible: false, }, tickLine: { visible: false, }, label: { visible: true, autoRotate: true, autoHide: true, }, title: { visible: false, spacing: 12, }, }, legend: { visible: true, position: 'top-left', offsetY: 0, }, }); }; StackedBarLayer.prototype.getColorScale = function () { var stackField = this.options.stackField; return this.view.getScaleByField(stackField); }; StackedBarLayer.prototype.adjustBar = function (bar) { bar.adjust = [ { type: 'stack', }, ]; }; StackedBarLayer.prototype.renderLabel = function () { var scales = this.config.scales; var _a = this.options, label = _a.label, xField = _a.xField; var scale = scales[xField]; if (label === null || label === void 0 ? void 0 : label.visible) { var geometry = view_1.getGeometryByType(this.view, 'interval'); this.doRenderLabel(geometry, tslib_1.__assign({ type: 'stacked-bar', formatter: scale.formatter && (function (value) { return scale.formatter(value); }) }, this.options.label)); } }; StackedBarLayer.prototype.geometryTooltip = function () { this.bar.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.bar.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.bar.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.bar.tooltip.fields = [this.options.xField, this.options.yField, this.options.stackField]; } } }; return StackedBarLayer; }(layer_1.default)); exports.default = StackedBarLayer; global_1.registerPlotType('stackedBar', StackedBarLayer); },{"../../base/global":392,"../../util/view":715,"../bar/layer":464,"./component/label":616,"./component/label-auto":615,"./theme":619,"@antv/util":803,"tslib":894}],619:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var theme_2 = require("../bar/theme"); theme_1.registerTheme('stackedBar', theme_2.DEFAULT_BAR_THEME); },{"../../theme":669,"../bar/theme":465}],620:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../components/label/base"); var label_auto_1 = tslib_1.__importDefault(require("../../column/component/label-auto")); /** 自动模式的 StackedColumn 数据标签,会根据图形和数据标签自动优化数据标签布局和样式等 */ var StackedColumnAutoLabel = /** @class */ (function (_super) { tslib_1.__extends(StackedColumnAutoLabel, _super); function StackedColumnAutoLabel() { return _super !== null && _super.apply(this, arguments) || this; } /** 堆积柱形图全部内置 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars StackedColumnAutoLabel.prototype.shouldInShapeLabels = function (labels) { return true; }; return StackedColumnAutoLabel; }(label_auto_1.default)); exports.default = StackedColumnAutoLabel; base_1.registerLabelComponent('stacked-column-auto', StackedColumnAutoLabel); },{"../../../components/label/base":414,"../../column/component/label-auto":486,"tslib":894}],621:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("../../../components/label/base"); var label_1 = tslib_1.__importDefault(require("../../column/component/label")); var StackedColumnLabel = /** @class */ (function (_super) { tslib_1.__extends(StackedColumnLabel, _super); function StackedColumnLabel() { return _super !== null && _super.apply(this, arguments) || this; } StackedColumnLabel.prototype.adjustLabel = function (label, element) { var adjustPosition = this.options.adjustPosition; if (adjustPosition) { var labelRange = label.getBBox(); var shapeRange = this.getElementShapeBBox(element); if (shapeRange.height < labelRange.height || shapeRange.width < labelRange.width) { // 如果文本的高度超出图形的高度或者文本的宽度超出图形的宽度就不显示 label.hide(); } } }; return StackedColumnLabel; }(label_1.default)); exports.default = StackedColumnLabel; base_1.registerLabelComponent('stacked-column', StackedColumnLabel); },{"../../../components/label/base":414,"../../column/component/label":487,"tslib":894}],622:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var StackedColumn = /** @class */ (function (_super) { tslib_1.__extends(StackedColumn, _super); function StackedColumn() { return _super !== null && _super.apply(this, arguments) || this; } StackedColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedColumn'; _super.prototype.createLayers.call(this, layerProps); }; StackedColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return StackedColumn; }(plot_1.default)); exports.default = StackedColumn; },{"../../base/plot":394,"./layer":623,"@antv/util":803,"tslib":894}],623:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var connected_area_1 = tslib_1.__importDefault(require("../../components/connected-area")); var layer_1 = tslib_1.__importDefault(require("../column/layer")); require("./theme"); require("./component/label"); require("./component/label-auto"); var view_1 = require("../../util/view"); var StackedColumnLayer = /** @class */ (function (_super) { tslib_1.__extends(StackedColumnLayer, _super); function StackedColumnLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'stackedColumn'; _this.baseType = 'column'; return _this; } StackedColumnLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { legend: { visible: true, position: 'right-top', }, label: { visible: false, position: 'middle', offset: 0, adjustColor: true, }, connectedArea: { visible: false, triggerOn: 'mouseenter', }, }); }; StackedColumnLayer.prototype.init = function () { if (this.options.connectedArea.visible) { this.options.tooltip.crosshairs = null; } _super.prototype.init.call(this); }; StackedColumnLayer.prototype.afterRender = function () { var props = this.options; // 绘制区域连接组件 if (props.connectedArea.visible) { this.connectedArea = new connected_area_1.default(tslib_1.__assign({ view: this.view, field: props.stackField, animation: props.animation === false ? false : true }, props.connectedArea)); } _super.prototype.afterRender.call(this); }; StackedColumnLayer.prototype.getColorScale = function () { var stackField = this.options.stackField; return this.view.getScaleByField(stackField); }; StackedColumnLayer.prototype.adjustColumn = function (column) { column.adjust = [ { type: 'stack', }, ]; }; StackedColumnLayer.prototype.renderLabel = function () { var scales = this.config.scales; var _a = this.options, label = _a.label, yField = _a.yField; var scale = scales[yField]; if (label && label.visible) { var geometry = view_1.getGeometryByType(this.view, 'interval'); this.doRenderLabel(geometry, tslib_1.__assign({ type: 'stacked-column', formatter: scale.formatter && (function (value) { return scale.formatter(value); }) }, this.options.label)); } }; StackedColumnLayer.prototype.geometryTooltip = function () { this.column.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.column.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.column.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.column.tooltip.fields = [this.options.xField, this.options.yField, this.options.stackField]; } } }; return StackedColumnLayer; }(layer_1.default)); exports.default = StackedColumnLayer; global_1.registerPlotType('stackedColumn', StackedColumnLayer); },{"../../base/global":392,"../../components/connected-area":409,"../../util/view":715,"../column/layer":490,"./component/label":621,"./component/label-auto":620,"./theme":624,"@antv/util":803,"tslib":894}],624:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var theme_1 = require("../../theme"); var theme_2 = require("../column/theme"); theme_1.registerTheme('stackedColumn', theme_2.DEFAULT_COLUMN_THEME); },{"../../theme":669,"../column/theme":491}],625:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var StackedRose = /** @class */ (function (_super) { tslib_1.__extends(StackedRose, _super); function StackedRose() { return _super !== null && _super.apply(this, arguments) || this; } StackedRose.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'stackedRose'; _super.prototype.createLayers.call(this, layerProps); }; StackedRose.prototype.getRadiusScale = function () { var layer = this.layers[0]; return layer.getRadiusScale(); }; StackedRose.prototype.getAngleScale = function () { var layer = this.layers[0]; return layer.getAngleScale(); }; StackedRose.getDefaultOptions = layer_1.default.getDefaultOptions; return StackedRose; }(plot_1.default)); exports.default = StackedRose; },{"../../base/plot":394,"./layer":626,"@antv/util":803,"tslib":894}],626:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var layer_1 = tslib_1.__importDefault(require("../rose/layer")); var StackedRoseLayer = /** @class */ (function (_super) { tslib_1.__extends(StackedRoseLayer, _super); function StackedRoseLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'stackedRose'; _this.baseType = 'rose'; return _this; } StackedRoseLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { xAxis: { visible: true, line: { visible: false, }, tickLine: { visible: false, }, grid: { visible: true, alignTick: false, style: { lineWidth: 0.5, }, }, label: { offset: 5, autoRotate: true, }, }, yAxis: { visible: false, }, }); }; StackedRoseLayer.prototype.getColorScale = function () { var stackField = this.options.stackField; return this.view.getScaleByField(stackField); }; StackedRoseLayer.prototype.adjustRoseAdjust = function () { return [ { type: 'stack', }, ]; }; StackedRoseLayer.prototype.geometryTooltip = function () { this.rose.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.rose.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.rose.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.rose.tooltip.fields = [this.options.radiusField, this.options.categoryField, this.options.stackField]; } } }; return StackedRoseLayer; }(layer_1.default)); exports.default = StackedRoseLayer; global_1.registerPlotType('stackedRose', StackedRoseLayer); },{"../../base/global":392,"../rose/layer":600,"@antv/util":803,"tslib":894}],627:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var layer_1 = require("./layer"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var StepLine = /** @class */ (function (_super) { tslib_1.__extends(StepLine, _super); function StepLine() { return _super !== null && _super.apply(this, arguments) || this; } /** * 复写父类方法 * @param props */ StepLine.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'step-line'; _super.prototype.createLayers.call(this, layerProps); }; StepLine.getDefaultOptions = layer_1.StepLineLayer.getDefaultOptions; return StepLine; }(plot_1.default)); exports.default = StepLine; },{"../../base/plot":394,"./layer":628,"@antv/util":803,"tslib":894}],628:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StepLineLayer = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var layer_1 = tslib_1.__importDefault(require("../line/layer")); var global_1 = require("../../base/global"); var StepLineLayer = /** @class */ (function (_super) { tslib_1.__extends(StepLineLayer, _super); function StepLineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'step-line'; // 覆写父类的 type return _this; } StepLineLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { step: 'hv', }); }; return StepLineLayer; }(layer_1.default)); exports.StepLineLayer = StepLineLayer; global_1.registerPlotType('step-line', StepLineLayer); },{"../../base/global":392,"../line/layer":558,"@antv/util":803,"tslib":894}],629:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var common_1 = require("../../../util/common"); var LEAF_LABEL_OFFSET = 4; var MIN_FONTSIZE = 8; function isLeaf(data, maxLevel) { return !data.children || data.depth >= maxLevel; } function textWrapper(label, width, container) { var fontSize = label.attr('fontSize'); var textContent = label.attr('text'); var tShape = container.addShape('text', { attrs: { text: '', x: 0, y: 0, fontSize: fontSize, }, }); var textArr = textContent.split('\n'); var wrappedTextArr = textArr.map(function (wrappedText) { var text = ''; var chars = wrappedText.split(''); var breakIndex = []; for (var i = 0; i < chars.length; i++) { var item = chars[i]; tShape.attr('text', (text += item)); var currentWidth = tShape.getBBox().width - 1; if (currentWidth > width) { // 如果是第一个字符就大于宽度不做任何换行处理 if (i === 0) { break; } breakIndex.push(i); text = ''; } } return common_1.breakText(chars, breakIndex); }); tShape.remove(); return wrappedTextArr.join('\n'); } function textAbbreviate(text, fontSize, width, container) { var tailShape = container.addShape('text', { attrs: { text: '...', x: 0, y: 0, fontSize: fontSize, }, }); var tailWidth = tailShape.getBBox().width; var tShape = container.addShape('text', { attrs: { text: '', x: 0, y: 0, fontSize: fontSize, }, }); var t = ''; var abbreviateWidth = width - tailWidth; for (var i = 0; i < text.length; i++) { var item = text[i]; tShape.attr('text', (t += item)); var currentWidth = tShape.getBBox().width; if (currentWidth >= abbreviateWidth) { var string = t.substr(0, t.length - 1); if (string.length > 0) { return string + '...'; } } } tShape.remove(); tailShape.remove(); return t; } var TreemapLabel = /** @class */ (function () { function TreemapLabel(cfg) { this.destroyed = false; this.view = cfg.view; this.plot = cfg.plot; var defaultOptions = this.getDefaultOptions(); this.options = util_1.deepMix(defaultOptions, cfg, {}); this.init(); } TreemapLabel.prototype.init = function () { var _this = this; this.container = this.getGeometry().labelsContainer; this.view.on('beforerender', function () { _this.clear(); _this.plot.canvas.draw(); }); }; TreemapLabel.prototype.render = function () { var _this = this; var elements = this.getGeometry().elements; util_1.each(elements, function (ele) { var shape = ele.shape; var data = shape.get('origin').data; var isLeafNode = isLeaf(data, _this.plot.options.maxLevel); if (data.showLabel) { var style = util_1.clone(_this.options.style); var position = _this.getPosition(shape, isLeafNode); var formatter = _this.options.formatter; var content = formatter ? formatter(data.name) : data.name; var textBaseline = _this.getTextBaseLine(isLeafNode); var label = _this.container.addShape('text', { attrs: util_1.deepMix({}, style, { x: position.x, y: position.y, text: content, fill: 'black', textAlign: 'center', textBaseline: textBaseline, fontWeight: isLeafNode ? 300 : 600, }), name: 'label', }); _this.adjustLabel(label, shape, isLeafNode); } }); }; TreemapLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; TreemapLabel.prototype.hide = function () { this.container.set('visible', false); this.plot.canvas.draw(); }; TreemapLabel.prototype.show = function () { this.container.set('visible', true); this.plot.canvas.draw(); }; TreemapLabel.prototype.destroy = function () { if (this.container) { this.container.remove(); } this.destroyed = true; }; TreemapLabel.prototype.getBBox = function () { return this.container.getBBox(); }; TreemapLabel.prototype.getPosition = function (shape, isLeafNode) { var shapeBbox = shape.getBBox(); var x = 0; var y = 0; if (!isLeafNode) { x = shapeBbox.x + shapeBbox.width / 2; y = shapeBbox.y + 4; } else { x = shapeBbox.minX + shapeBbox.width / 2; y = shapeBbox.minY + shapeBbox.height / 2; } return { x: x, y: y }; }; TreemapLabel.prototype.getTextBaseLine = function (isLeafNode) { return isLeafNode ? 'middle' : 'top'; }; TreemapLabel.prototype.adjustLabel = function (label, shape, isLeafNode) { if (isLeafNode) { this.adjustLeafLabel(label, shape); } else { this.adjustParentLabel(label, shape); } }; TreemapLabel.prototype.adjustLeafLabel = function (label, shape) { var bbox = shape.getBBox(); var labelBBox = label.getBBox(); var labelText = util_1.clone(label.attr('text')); var sizeOffset = 2; var fontSize = Math.max(label.attr('fontSize') - sizeOffset, MIN_FONTSIZE); var centerX = bbox.x + bbox.width / 2; var centerY = bbox.y + bbox.height / 2; label.attr({ x: centerX, y: centerY, textAlign: 'center', textBaseline: 'middle', lineHeight: fontSize, fontSize: fontSize, }); var wrapperWidth = bbox.width - LEAF_LABEL_OFFSET * 2; if (labelBBox.width > bbox.width && labelBBox.height > bbox.height) { label.attr('text', ''); return; } else if (wrapperWidth < fontSize) { label.attr('text', ''); return; } if (labelBBox.width > bbox.width) { var wrappedText = textWrapper(label, wrapperWidth, this.container); label.attr({ lineHeight: label.attr('fontSize'), text: wrappedText, }); var tem_bbox = label.getBBox(); if (tem_bbox.height > bbox.height) { var text = textAbbreviate(labelText, fontSize, wrapperWidth, this.container); label.attr('text', text); } } }; TreemapLabel.prototype.adjustParentLabel = function (label, shape) { var shapeBbox = shape.getBBox(); var wrapperWidth = shapeBbox.width - LEAF_LABEL_OFFSET * 2; if (label.getBBox().width > wrapperWidth) { var text = textAbbreviate(label.attr('text'), label.attr('fontSize'), wrapperWidth, this.container); label.attr('text', text); } }; TreemapLabel.prototype.getDefaultOptions = function () { var theme = this.plot.theme; var labelStyle = theme.label.style; return { offsetX: 0, offsetY: 0, style: util_1.clone(labelStyle), }; }; TreemapLabel.prototype.getGeometry = function () { return util_1.find(this.view.geometries, function (geom) { return geom.type === 'polygon'; }); }; return TreemapLabel; }()); exports.default = TreemapLabel; },{"../../../util/common":674,"@antv/util":803}],630:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { rect: 'polygon', breadcrumb: 'breadcrumb', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],631:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Treemap = /** @class */ (function (_super) { tslib_1.__extends(Treemap, _super); function Treemap() { return _super !== null && _super.apply(this, arguments) || this; } Treemap.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'treemap'; _super.prototype.createLayers.call(this, layerProps); }; Treemap.getDefaultOptions = layer_1.default.getDefaultOptions; return Treemap; }(plot_1.default)); exports.default = Treemap; },{"../../base/plot":394,"./layer":635,"@antv/util":803,"tslib":894}],632:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rollingUp = exports.drillingDown = void 0; var util_1 = require("@antv/util"); var g_util_1 = require("../../../util/g-util"); var ulMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; var duration = 400; var easing = 'easeQuadInOut'; function drillingDown(target, view, callback) { var rect = getRect(target); var range = getRange(view); var xRatio = range.width / rect.width; var yRatio = range.height / rect.height; var offsetX = (range.minX - rect.minX) * xRatio; var offsetY = (range.minY - rect.minY) * yRatio; var transformMatrix = g_util_1.transform([ ['s', xRatio, yRatio], ['t', offsetX, offsetY], ]); var geometry = view.geometries[0]; hideLabel(geometry); var tem_container = view.backgroundGroup.addGroup(); tem_container.set('zIndex', -100); tem_container.setClip({ type: 'rect', attrs: { x: range.minX, y: range.minY, width: range.width, height: range.height, }, }); var tem_shapes = getTemShapes(geometry, tem_container); geometry.container.set('visible', false); view.canvas.draw(); callback(); window.setTimeout(function () { util_1.each(tem_shapes, function (shape, index) { if (index === 0) { shape.animate({ matrix: transformMatrix }, duration, easing, function () { tem_container.remove(); view.canvas.draw(); }); } else { shape.animate(g_util_1.transform, duration); } }); geometry = view.geometries[0]; hideLabel(geometry); var shapes = geometry.getShapes(); util_1.each(shapes, function (shape) { shape.attr('opacity', 0); shape.animate({ opacity: 1, }, duration, easing); }); var container = geometry.container; container.stopAnimate(); container.set('visible', true); container.attr('matrix', util_1.clone(ulMatrix)); g_util_1.groupTransform(container, [ ['s', rect.width / range.width, rect.height / range.height], ['t', rect.minX, rect.minY], ]); var matrix = util_1.clone(ulMatrix); geometry.container.animate({ matrix: matrix, }, duration, easing, function () { showLabel(geometry); }); view.canvas.draw(); }, 16); } exports.drillingDown = drillingDown; function getTemShapes(geometry, container) { var shapes = geometry.getShapes(); var tem_shapes = []; util_1.each(shapes, function (shape) { var s = container.addShape('path', { attrs: util_1.deepMix({}, shape.attrs, { capture: false }), }); tem_shapes.push(s); }); return tem_shapes; } function rollingUp(name, view, callback) { var geometry = view.geometries[0]; hideLabel(geometry); var container = geometry.container; container.attr('matrix', util_1.clone(ulMatrix)); var tem_container = view.backgroundGroup.addGroup(); tem_container.set('zIndex', -100); var tem_shapes = getTemShapes(geometry, tem_container); container.set('visible', false); view.canvas.draw(); callback(); geometry = view.geometries[0]; hideLabel(geometry); container = geometry.container; var shape = findShapeByName(geometry.getShapes(), name); //根据name获得上一级shape var rect = getRect(shape); var range = getRange(view); var containerParent = container.get('parent'); if (!containerParent.get('clipShape')) { container.setClip({ type: 'rect', attrs: { x: range.minX, y: range.minY, width: range.width, height: range.height, }, }); } shrinkTemp(tem_container, tem_shapes, rect, range); var xRatio = range.width / rect.width; var yRatio = range.height / rect.height; var offsetX = (range.minX - rect.minX) * xRatio; var offsetY = (range.minY - rect.minY) * yRatio; var transformMatrix = g_util_1.transform([ ['s', xRatio, yRatio], ['t', offsetX, offsetY], ]); container.setMatrix(transformMatrix); container.set('visible', true); container.animate({ matrix: ulMatrix, }, duration, easing, function () { showLabel(geometry); }); } exports.rollingUp = rollingUp; function findShapeByName(shapes, n) { var shape; util_1.each(shapes, function (s) { var name = s.get('origin').data.name; if (name === n) { shape = s; } }); return shape; } function getRange(view) { var viewRange = view.coordinateBBox; var range = { minX: viewRange.minX, minY: viewRange.minY, centerX: (viewRange.maxX - viewRange.minX) / 2, centerY: (viewRange.maxY - viewRange.minY) / 2, width: viewRange.width, height: viewRange.height, }; return range; } function getRect(shape) { var path = shape.attr('path'); var x0 = path[0][1]; var y1 = path[0][2]; var x1 = path[1][1]; var y0 = path[2][2]; var rect = { minX: x0, minY: y0, centerX: (x1 - x0) / 2, centerY: (y1 - y0) / 2, width: Math.abs(x1 - x0), height: Math.abs(y1 - y0), }; return rect; } function shrinkTemp(container, shapes, rect, range) { var xRatio = rect.width / range.width; var yRatio = rect.height / range.height; var transformMatrix = g_util_1.transform([ ['s', xRatio, yRatio], ['t', rect.minX, rect.minY], ]); container.animate({ matrix: transformMatrix }, duration, easing, function () { container.remove(); }); util_1.each(shapes, function (shape) { shape.animate({ opacity: 0, }, duration, easing); }); } function hideLabel(geometry) { var labelContainer = geometry.labelsContainer; labelContainer.set('visible', false); } function showLabel(geometry) { var labelContainer = geometry.labelsContainer; labelContainer.set('visible', true); } },{"../../../util/g-util":679,"@antv/util":803}],633:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var breadcrumb_1 = tslib_1.__importDefault(require("../../../components/breadcrumb")); var base_1 = tslib_1.__importDefault(require("../../../interaction/base")); var bbox_1 = tslib_1.__importDefault(require("../../../util/bbox")); var util_1 = require("@antv/util"); var animation_1 = require("./animation"); var DEFAULT_ITEM_WIDTH = 100; var DEFAULT_ITEM_HEIGHT = 30; var PADDING_TOP = 10; var getValidBreadcrumbConfig = function (cfg) { if (cfg === void 0) { cfg = {}; } var _cfg = tslib_1.__assign({ x: 0, y: 0, startNode: { name: 'root' }, itemWidth: DEFAULT_ITEM_WIDTH, itemHeight: DEFAULT_ITEM_HEIGHT, padding: [0, 0, 0, 0] }, cfg); return _cfg; }; var DrillDownInteraction = /** @class */ (function (_super) { tslib_1.__extends(DrillDownInteraction, _super); function DrillDownInteraction() { return _super !== null && _super.apply(this, arguments) || this; } DrillDownInteraction.getInteractionRange = function (layerRange, interaction) { var config = getValidBreadcrumbConfig(interaction); var _a = config.padding, paddingTop = _a[0], paddingBottom = _a[1]; if (layerRange) { return new bbox_1.default(layerRange.minX, layerRange.maxY - config.itemHeight - paddingTop - paddingBottom, layerRange.width, config.itemHeight + paddingTop + paddingBottom); } }; DrillDownInteraction.prototype.start = function (ev) { var _this = this; var data = ev.data.data; if (data.children) { this.parentNode = { color: ev.target.attr('fill'), shape: ev.target, data: { name: util_1.clone(this.currentNode.name), value: util_1.clone(this.currentNode.value), }, depth: util_1.clone(this.currentDepth), }; this.currentDepth++; animation_1.drillingDown(ev.target, this.view, function () { _this.update(data); }); } }; DrillDownInteraction.prototype.update = function (data) { if (!util_1.hasKey(this.cache, data.name)) { this.cache[data.name] = data; } var tempoData = this.plot.getTreemapData(data, data.depth); this.view.changeData(tempoData); this.adjustScale(this.currentDepth); this.currentNode = data; this.render(); }; DrillDownInteraction.prototype.render = function () { if (this.breadcrumb) { var items = this.getItems(); this.breadcrumb.update({ items: items, }); this.breadcrumb.render(); this.layout(); } else { this.initGeometry(); this.cache = {}; this.saveOriginMapping(); this.container = this.plot.canvas.addGroup(); if (!this.startNode) { this.startNode = { name: 'root', }; } if (this.startNode.name === 'root') { this.startNodeName = util_1.hasKey(this.plot.options.data, 'name') ? this.plot.options.data.name : 'root'; this.currentNode = this.plot.options.data; this.currentDepth = 1; } else { this.startNodeName = this.startNode.name; this.currentNode = this.startNode; } this.y = this.view.coordinateBBox.maxY + PADDING_TOP; this.breadcrumb = new breadcrumb_1.default({ container: this.container, x: 0, y: this.y, items: this.getItems(), }); this.breadcrumb.init(); this.breadcrumb.render(); this.plot.canvas.draw(); this.layout(); } this.onInteraction(); }; DrillDownInteraction.prototype.clear = function () { return; }; DrillDownInteraction.prototype.layout = function () { var currentWidth = this.container.getBBox().width; var x = (this.plot.width - currentWidth) / 2; this.breadcrumb.update({ x: x, y: this.y, }); this.breadcrumb.render(); }; DrillDownInteraction.prototype.getItems = function () { var items = []; if (this.currentNode.name && this.currentNode.name === this.startNodeName) { var rootItem = this.getRootItem(); items.push(rootItem); } else { items = []; var parents = []; this.findParent(this.currentNode, parents); items.push(this.getRootItem()); util_1.each(parents, function (p, index) { items.push({ key: String(index + 2), text: p.name, data: p }); }); items.push({ key: String(parents.length + 2), text: this.currentNode.name, data: this.currentNode }); } return items; }; DrillDownInteraction.prototype.findParent = function (data, parents) { if (data.parent) { if (util_1.hasKey(this.cache, data.parent.name)) { parents.push(this.cache[data.parent.name]); } else { parents.push(data.parent); } this.findParent(data.parent, parents); } else { return; } }; DrillDownInteraction.prototype.onInteraction = function () { var _this = this; this.container.on('click', function (ev) { var targetParent = ev.target.get('parent'); if (targetParent && targetParent.get('class') === 'item-group') { var data_1 = targetParent.get('data'); if (data_1.data) { if (data_1.text === _this.startNodeName) { var targetDepth = 1; //只有前后depth相邻才执行上卷动画,否则直接更新 if (_this.currentDepth - 1 === targetDepth) { animation_1.rollingUp(_this.currentNode.name, _this.view, function () { _this.updateRoot(data_1); }); } else { _this.updateRoot(data_1); } _this.currentDepth = 1; } else if (_this.currentNode === data_1.data) { return; } else { var previousDepth = util_1.clone(_this.currentDepth); _this.currentDepth = parseInt(data_1.key); if (previousDepth - 1 === _this.currentDepth) { animation_1.rollingUp(_this.currentNode.name, _this.view, function () { _this.update(data_1.data); }); } else { _this.update(data_1.data); } } } } }); }; DrillDownInteraction.prototype.getRootItem = function () { var rootData = this.plot.options.data; var rootName = util_1.hasKey(rootData, 'name') ? rootData.name : 'root'; return { key: '1', text: rootName, data: this.plot.rootData }; }; DrillDownInteraction.prototype.saveOriginMapping = function () { var _a = this.plot.options, colorField = _a.colorField, colors = _a.colors; var mappingInfo = { field: colorField, values: colors }; this.originMapping = mappingInfo; }; DrillDownInteraction.prototype.adjustScale = function (index) { var view = this.view; // 根据当前层级确定mapping配置项 if (this.mapping && util_1.hasKey(this.mapping, String(index))) { var mappingCfg = util_1.clone(this.mapping[index]); if (mappingCfg.values && util_1.isFunction(mappingCfg.values)) { var values = mappingCfg.values(this.parentNode, this.currentNode); mappingCfg.values = values; } this.view.geometries[0].color(mappingCfg.field, mappingCfg.values); } else { var mappingCfg = util_1.clone(this.originMapping); this.view.geometries[0].color(mappingCfg.field, mappingCfg.values); } view.render(); }; DrillDownInteraction.prototype.initGeometry = function () { this.geometry = this.view.geometries[0]; var viewRange = this.view.viewBBox; var container = this.geometry.container; container.setClip({ type: 'rect', attrs: { x: viewRange.minX, y: viewRange.minY, width: viewRange.width, height: viewRange.height, }, }); }; DrillDownInteraction.prototype.updateRoot = function (data) { this.view.changeData(data.data); this.adjustScale(1); this.currentNode = this.plot.options.data; this.render(); }; return DrillDownInteraction; }(base_1.default)); exports.default = DrillDownInteraction; base_1.default.registerInteraction('drilldown', DrillDownInteraction); },{"../../../components/breadcrumb":408,"../../../interaction/base":441,"../../../util/bbox":672,"./animation":632,"@antv/util":803,"tslib":894}],634:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.INTERACTION_MAP = void 0; var tslib_1 = require("tslib"); var drillDown_1 = tslib_1.__importDefault(require("./drillDown")); exports.INTERACTION_MAP = { drilldown: drillDown_1.default, }; },{"./drillDown":633,"tslib":894}],635:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var squarify_1 = tslib_1.__importDefault(require("./layout/squarify")); var interaction_1 = require("./interaction"); var EventParser = tslib_1.__importStar(require("./event")); var label_1 = tslib_1.__importDefault(require("./components/label")); var PARENT_NODE_OFFSET = 4; var BLOCK_MARGIN = 4; var TreemapLayer = /** @class */ (function (_super) { tslib_1.__extends(TreemapLayer, _super); function TreemapLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'treemap'; return _this; } TreemapLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { maxLevel: 2, padding: [0, 0, 0, 0], tooltip: { visible: false, showTitle: false, showCrosshairs: false, showMarkers: false, shared: false, }, legend: { visible: false, }, xAxis: { visible: false, }, yAxis: { visible: false, }, xField: 'x', yField: 'y', label: { visible: true, adjustPosition: true, style: { stroke: 'rgba(0,0,0,0)', lineWidth: 0, fontSize: 12, }, }, meta: { x: { nice: false, }, y: { nice: false, }, }, interactions: [{ type: 'tooltip' }], }); }; TreemapLayer.prototype.beforeInit = function () { var _this = this; _super.prototype.beforeInit.call(this); var interactions = this.options.interactions; if (interactions) { util_1.each(interactions, function (interaction) { if (interaction.type === 'drilldown') { _this.isDrilldown = true; _this.options.maxLevel = 1; } }); } var data = this.options.data; var treemapData = this.getTreemapData(data); this.rootData = treemapData; }; TreemapLayer.prototype.afterRender = function () { _super.prototype.afterRender.call(this); if (this.options.label && this.options.label.visible) { var label = new label_1.default(tslib_1.__assign({ view: this.view, plot: this }, this.options.label)); label.render(); } }; TreemapLayer.prototype.geometryParser = function () { return 'polygon'; }; TreemapLayer.prototype.getTreemapData = function (data, level) { var viewRange = this.getViewRange(); var root = squarify_1.default(data, viewRange.x, viewRange.y, viewRange.width, viewRange.height); this.recursive(root, 1); var treemapData = []; this.getAllNodes(root, treemapData, level); treemapData.sort(function (a, b) { return a.depth - b.depth; }); this.options.xField = 'x'; this.options.yField = 'y'; return treemapData; }; TreemapLayer.prototype.processData = function () { return this.rootData; }; TreemapLayer.prototype.coord = function () { return; }; TreemapLayer.prototype.addGeometry = function () { var _this = this; var _a = this.options, data = _a.data, colorField = _a.colorField, color = _a.color; var treemapData = this.getTreemapData(data); this.rootData = treemapData; var isNested = this.isNested(treemapData); this.rect = { type: 'polygon', position: { fields: ['x', 'y'], }, color: { fields: [colorField], values: color, }, style: { fields: ['depth'], callback: function (d) { var defaultStyle = _this.adjustStyleByDepth(d, isNested); return util_1.deepMix({}, defaultStyle, _this.options.rectStyle); }, }, tooltip: { fields: ['name', 'value'], }, }; if (this.options.tooltip && this.options.tooltip.formatter) { this.rect.tooltip.callback = this.options.tooltip.formatter; } this.setConfig('geometry', this.rect); }; TreemapLayer.prototype.applyInteractions = function () { var _this = this; var interactionCfg = this.options.interactions; var interactions = this.view.interactions; util_1.each(interactionCfg, function (inter) { var Ctr = interaction_1.INTERACTION_MAP[inter.type]; if (Ctr) { var interaction = new Ctr(util_1.deepMix({}, { view: _this.view, plot: _this, startEvent: 'polygon:click', }, inter.cfg, Ctr.getInteractionRange(_this.layerBBox, inter.cfg))); interactions[inter.type] = interaction; } }); }; TreemapLayer.prototype.animation = function () { _super.prototype.animation.call(this); if (this.isDrilldown) { this.rect.animate = false; } }; TreemapLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; TreemapLayer.prototype.recursive = function (rows, depth) { var _this = this; var colorField = this.options.colorField; util_1.each(rows, function (r) { util_1.each(r.children, function (c) { c.depth = depth; if (depth > 1) c.parent = r; if (!util_1.hasKey(c, colorField)) { c[colorField] = r[colorField]; } c.showLabel = true; var leaf = _this.isLeaf(c); if (!leaf) { var cliperHeight = Math.abs(c.y1 - c.y0); var labelHeight = _this.getLabelHeight(); var parentLabelOffset = cliperHeight / 2 > labelHeight ? labelHeight : BLOCK_MARGIN; c.showLabel = parentLabelOffset === BLOCK_MARGIN ? false : true; var c_rows = squarify_1.default(c, c.x0 + BLOCK_MARGIN, c.y0 + parentLabelOffset, c.x1 - BLOCK_MARGIN, c.y1 - BLOCK_MARGIN); _this.fillColorField(c_rows, colorField, c[colorField]); _this.recursive(c_rows, c.depth + 1); } }); }); }; TreemapLayer.prototype.getAllNodes = function (data, nodes, level) { var _this = this; var max = level ? level : this.options.maxLevel; var viewRange = this.getViewRange(); util_1.each(data, function (d) { if (util_1.hasKey(d, 'x0') && d.depth <= max) { nodes.push(tslib_1.__assign(tslib_1.__assign({}, d), { x: [d.x0, d.x1, d.x1, d.x0], y: [viewRange.height - d.y1, viewRange.height - d.y1, viewRange.height - d.y0, viewRange.height - d.y0] })); } if (util_1.hasKey(d, 'children')) { _this.getAllNodes(d.children, nodes); } }); }; TreemapLayer.prototype.fillColorField = function (rows, fieldName, value) { util_1.each(rows, function (r) { if (!util_1.hasKey(r, fieldName)) { r[fieldName] = value; } }); }; TreemapLayer.prototype.getLabelHeight = function () { var label = this.options.label; var fontSize = this.getPlotTheme().label.style.fontSize; var size = 0; if (label && label.visible) { var labelStyle = label.style; size = labelStyle && labelStyle.fontSize ? labelStyle.fontSize : fontSize; } return size + PARENT_NODE_OFFSET * 2; }; TreemapLayer.prototype.isLeaf = function (data) { return !data.children || data.children.length === 0; }; TreemapLayer.prototype.isNested = function (data) { var maxLevel = this.options.maxLevel; if (maxLevel === 1) { return false; } var nested = false; for (var i = 0; i < data.length; i++) { if (data[i].children) { nested = true; break; } } return nested; }; TreemapLayer.prototype.adjustStyleByDepth = function (depth, isNested) { var maxLevel = this.options.maxLevel; if (!isNested) { return { lineWidth: 1, stroke: 'rgba(0,0,0,0.9)', opacity: 0.9, }; } else if (depth === 1) { return { lineWidth: 1, stroke: 'black', opacity: depth / maxLevel, }; } else { return { lineWidth: 1, stroke: 'rgba(0,0,0,0.3)', opacity: depth / maxLevel, }; } }; return TreemapLayer; }(view_layer_1.default)); exports.default = TreemapLayer; global_1.registerPlotType('treemap', TreemapLayer); },{"../../base/global":392,"../../base/view-layer":395,"./components/label":629,"./event":630,"./interaction":634,"./layout/squarify":638,"@antv/util":803,"tslib":894}],636:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dice = void 0; var util_1 = require("@antv/util"); function dice(root, x0, y0, x1, y1) { var width = x1 - x0; var children = root.children, value = root.value; children.sort(function (a, b) { return b.value - a.value; }); var k = width / value; var node_x = x0; util_1.each(children, function (c) { c.y0 = y0; c.y1 = y1; c.x0 = node_x; node_x += c.value * k; c.x1 = c.x0 + c.value * k; }); } exports.dice = dice; },{"@antv/util":803}],637:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.slice = void 0; var util_1 = require("@antv/util"); function slice(root, x0, y0, x1, y1) { var height = y1 - y0; var children = root.children, value = root.value; children.sort(function (a, b) { return b.value - a.value; }); var k = height / value; var node_y = y0; util_1.each(children, function (c) { c.x0 = x0; c.x1 = x1; c.y0 = node_y; node_y += c.value * k; c.y1 = c.y0 + c.value * k; }); } exports.slice = slice; },{"@antv/util":803}],638:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dice_1 = require("./dice"); var slice_1 = require("./slice"); //reference: https://github.com/d3/d3-hierarchy/blob/master/src/treemap/squarify.js // 黄金分割 var ratio = (1 + Math.sqrt(5)) / 2; function squarify(root, x0, y0, x1, y1) { var children = root.children; var value = root.value; children.sort(function (a, b) { return b.value - a.value; }); var rows = []; var sumValue, maxValue, minValue; var alpha, beta; var newRatio, minRatio; var nodeValue; var i = 0, j = 0; // todo: 剔除empty node while (i < children.length) { var width = x1 - x0; var height = y1 - y0; sumValue = children[j++].value; maxValue = sumValue; minValue = sumValue; alpha = Math.max(height / width, width / height) / (value * ratio); beta = sumValue * sumValue * alpha; minRatio = Math.max(maxValue / beta, beta / minValue); for (; j < children.length; j++) { nodeValue = children[j].value; sumValue += nodeValue; if (nodeValue < minValue) minValue = nodeValue; if (nodeValue > maxValue) maxValue = nodeValue; beta = sumValue * sumValue * alpha; newRatio = Math.max(maxValue / beta, beta / minValue); if (newRatio > minRatio) { sumValue -= nodeValue; break; } minRatio = newRatio; } var row = { value: sumValue, dice: width < height, children: children.slice(i, j) }; rows.push(row); if (row.dice) { var h = value ? (height * sumValue) / value : height; dice_1.dice(row, x0, y0, x1, y0 + h); if (value) { y0 += h; } } else { var w = value ? (width * sumValue) / value : width; slice_1.slice(row, x0, y0, x0 + w, y1); if (value) { x0 += w; } } value -= sumValue; i = j; } return rows; } exports.default = squarify; },{"./dice":636,"./slice":637}],639:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-18 */ var util_1 = require("@antv/util"); var layer_1 = require("../../layer"); var dependents_1 = require("../../../../dependents"); function getDefaultCfg() { return { fill: '#fff', fontSize: 12, lineHeight: 12, stroke: 'rgba(0, 0, 0, 0.45)', }; } var DiffLabel = /** @class */ (function () { function DiffLabel(cfg) { this.textAttrs = {}; this.view = cfg.view; this.fields = cfg.fields; this.formatter = cfg.formatter; this.textAttrs = util_1.mix(getDefaultCfg(), cfg.style); this._init(); } /** 绘制辅助labels */ DiffLabel.prototype.draw = function () { var _this = this; if (!this.view || this.view.destroyed) { return; } var data = util_1.clone(this.view.getData()); this.container = this.view.foregroundGroup.addGroup(); var shapes = this.view.geometries[0].elements.map(function (value) { return value.shape; }); util_1.each(shapes, function (shape, idx) { if (!shape.cfg.origin) return; var _origin = shape.cfg.origin.data; var shapeBox = shape.getBBox(); var values = _origin[layer_1.VALUE_FIELD]; var diff = values; if (util_1.isArray(values)) { diff = values[1] - values[0]; } diff = diff > 0 ? "+" + diff : diff; /** is total, total do not need `+` sign */ if (_origin[layer_1.IS_TOTAL]) { diff = values[0] - values[1]; } var formattedText = diff; if (_this.formatter) { var color = shapes[idx].attr('fill'); formattedText = _this.formatter("" + diff, { _origin: data[idx], color: color }, idx); } var text = _this.container.addShape('text', { attrs: tslib_1.__assign({ text: formattedText, textBaseline: 'middle', textAlign: 'center', x: (shapeBox.minX + shapeBox.maxX) / 2, y: (shapeBox.minY + shapeBox.maxY) / 2 }, _this.textAttrs), name: 'dill-label', }); if (text.getBBox().height > shapeBox.height) { text.set('visible', false); } }); this.view.getCanvas().draw(); }; DiffLabel.prototype.clear = function () { if (this.container) { this.container.clear(); } }; DiffLabel.prototype._init = function () { var _this = this; this.view.on(dependents_1.VIEW_LIFE_CIRCLE.BEFORE_RENDER, function () { _this.clear(); }); this.view.on(dependents_1.VIEW_LIFE_CIRCLE.AFTER_RENDER, function () { _this.draw(); }); }; return DiffLabel; }()); exports.default = DiffLabel; },{"../../../../dependents":425,"../../layer":644,"@antv/util":803,"tslib":894}],640:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-18 */ var util_1 = require("@antv/util"); var label_1 = tslib_1.__importDefault(require("../../../column/component/label")); var layer_1 = require("../../layer"); var base_1 = require("../../../../components/label/base"); var dependents_1 = require("../../../../dependents"); var MARGIN = 2; var WaterfallLabel = /** @class */ (function (_super) { tslib_1.__extends(WaterfallLabel, _super); function WaterfallLabel() { return _super !== null && _super.apply(this, arguments) || this; } WaterfallLabel.prototype.adjustLabel = function (label, element) { var _a; var _b; var shape = element.shape; var shapeBox = shape.getBBox(); var data = element.getData(); var values = data[layer_1.VALUE_FIELD]; var diff = data[this.layer.options.yField]; var value = util_1.isArray(values) ? values[1] : values; var formatter = this.options.formatter; var mappingData = [].concat(element.getModel().mappingData); var elementIndex = formatter ? mappingData[0] && mappingData[0]['_origin'][layer_1.INDEX_FIELD] : 0; var formatterValue = formatter ? formatter(value, (_a = {}, _a[dependents_1._ORIGIN] = (_b = mappingData[0]) === null || _b === void 0 ? void 0 : _b._origin, _a.mappingDatum = mappingData[0], _a.mappingDatumIndex = 0, _a.element = element, _a.elementIndex = elementIndex, _a), elementIndex) : value; var yPos = (shapeBox.minY + shapeBox.maxY) / 2; var textBaseline = 'bottom'; if (diff < 0) { yPos = shapeBox.maxY + MARGIN; textBaseline = 'top'; } else { yPos = shapeBox.minY - MARGIN; } label.attr('y', yPos); label.attr('text', formatterValue); label.attr('textBaseline', textBaseline); }; return WaterfallLabel; }(label_1.default)); exports.default = WaterfallLabel; base_1.registerLabelComponent('waterfall', WaterfallLabel); },{"../../../../components/label/base":414,"../../../../dependents":425,"../../../column/component/label":487,"../../layer":644,"@antv/util":803,"tslib":894}],641:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * Create By Bruce Too * On 2020-02-18 */ /** * @file events of waterfall chart is equal to column chart */ var event_1 = require("../column/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); },{"../column/event":488}],642:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-18 */ var util_1 = require("@antv/util"); var dependents_1 = require("../../../../dependents"); function getStyle(cfg, isStroke, isFill) { var style = cfg.style, defaultStyle = cfg.defaultStyle, color = cfg.color; var attrs = tslib_1.__assign(tslib_1.__assign({}, defaultStyle), style); if (color) { if (isStroke) { attrs.stroke = color; } if (isFill) { attrs.fill = color; } } return attrs; } function getRectPath(points) { var path = []; var firstPoint = points[0]; path.push(['M', firstPoint.x, firstPoint.y]); for (var i = 1, len = points.length; i < len; i++) { path.push(['L', points[i].x, points[i].y]); } path.push(['L', firstPoint.x, firstPoint.y]); // 需要闭合 path.push(['z']); return path; } // @ts-ignore dependents_1.registerShape('interval', 'waterfall', { // @ts-ignore draw: function (cfg, container) { var style = getStyle(cfg, false, true); var path = this.parsePath(getRectPath(cfg.points)); var shape = container.addShape('path', { attrs: tslib_1.__assign(tslib_1.__assign({}, style), { path: path }), name: 'interval', }); var leaderLine = util_1.get(cfg.style, 'leaderLine'); if (leaderLine && leaderLine.visible) { var lineStyle = leaderLine.style || {}; // 2. 虚线连线 if (cfg.nextPoints) { var linkPath = [ // @ts-ignore ['M', cfg.points[2].x, cfg.points[2].y], // @ts-ignore ['L', cfg.nextPoints[0].x, cfg.nextPoints[0].y], ]; linkPath = this.parsePath(linkPath); container.addShape('path', { attrs: tslib_1.__assign({ path: linkPath, stroke: '#d3d3d3', lineDash: [4, 2], lineWidth: 1 }, lineStyle), name: 'leader-line', }); } } return shape; }, }); },{"../../../../dependents":425,"@antv/util":803,"tslib":894}],643:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-18 */ var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Waterfall = /** @class */ (function (_super) { tslib_1.__extends(Waterfall, _super); function Waterfall() { return _super !== null && _super.apply(this, arguments) || this; } Waterfall.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'waterfall'; _super.prototype.createLayers.call(this, layerProps); }; Waterfall.getDefaultOptions = layer_1.default.getDefaultOptions; return Waterfall; }(plot_1.default)); exports.default = Waterfall; },{"../../base/plot":394,"./layer":644,"@antv/util":803,"tslib":894}],644:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.INDEX_FIELD = exports.IS_TOTAL = exports.VALUE_FIELD = void 0; var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-18 */ var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); require("./geometry/shape/waterfall"); var view_layer_1 = tslib_1.__importDefault(require("../../base/view-layer")); var scale_1 = require("../../util/scale"); var factory_1 = require("../../components/factory"); var EventParser = tslib_1.__importStar(require("./event")); require("./component/label/waterfall-label"); var diff_label_1 = tslib_1.__importDefault(require("./component/label/diff-label")); var view_1 = require("../../util/view"); var G2_GEOM_MAP = { waterfall: 'interval', }; var PLOT_GEOM_MAP = { interval: 'waterfall', }; exports.VALUE_FIELD = '$$value$$'; exports.IS_TOTAL = '$$total$$'; exports.INDEX_FIELD = '$$index$$'; var WaterfallLayer = /** @class */ (function (_super) { tslib_1.__extends(WaterfallLayer, _super); function WaterfallLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'watarfall'; return _this; } WaterfallLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { legend: { visible: false, position: 'bottom', }, label: { visible: true, adjustPosition: true, }, /** 差值 label */ diffLabel: { visible: true, }, /** 迁移线 */ leaderLine: { visible: true, }, /** 显示总计 */ showTotal: { visible: true, label: '总计值', }, waterfallStyle: { /** 默认无描边 */ lineWidth: 0, }, tooltip: { visible: true, shared: true, showCrosshairs: false, showMarkers: false, }, }); }; WaterfallLayer.prototype.getOptions = function (props) { var options = _super.prototype.getOptions.call(this, props); this.adjustLegendOptions(options); this.adjustMeta(options); return options; }; WaterfallLayer.prototype.afterInit = function () { _super.prototype.afterInit.call(this); var options = this.options; if (options.diffLabel && options.diffLabel.visible) { this.diffLabel = new diff_label_1.default({ view: this.view, fields: [options.xField, options.yField, exports.VALUE_FIELD], formatter: options.diffLabel.formatter, style: options.diffLabel.style, }); } else if (this.diffLabel) { this.diffLabel.clear(); this.diffLabel = null; } }; WaterfallLayer.prototype.afterRender = function () { _super.prototype.afterRender.call(this); var options = this.options; this.view.on('tooltip:change', function (e) { var items = e.items; for (var i = 0; i < items.length; i++) { var item = items[i]; var data = util_1.get(item, 'data', {}); // 改变 tooltip 显示的name和value item.name = data[options.xField]; item.value = data[options.yField]; if (!item.value && data[exports.IS_TOTAL]) { var values = data[exports.VALUE_FIELD]; item.value = values[0] - values[1]; } e.items[i] = item; } }); this.renderLabel(); }; WaterfallLayer.prototype.renderLabel = function () { var geometry = view_1.getGeometryByType(this.view, 'interval'); if (this.options.label && this.options.label.visible) { this.doRenderLabel(geometry, tslib_1.__assign({ type: 'waterfall' }, this.options.label)); } }; WaterfallLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; WaterfallLayer.prototype.interaction = function () { this.setConfig('interactions', [{ type: 'tooltip' }, { type: 'active-region' }]); }; WaterfallLayer.prototype.addGeometry = function () { var options = this.options; var waterfall = { type: 'interval', position: { fields: [options.xField, exports.VALUE_FIELD], }, shape: { values: ['waterfall'], }, }; waterfall.style = this._parseStyle(); waterfall.color = this._parseColor(); this.waterfall = waterfall; if (this.options.tooltip && (this.options.tooltip.fields || this.options.tooltip.formatter)) { this.geometryTooltip(); } this.setConfig('geometry', waterfall); }; WaterfallLayer.prototype.processData = function (originData) { var _a; var plotData = []; var xField = this.options.xField; var yField = this.options.yField; util_1.map(originData, function (dataItem, idx) { var _a; var value = dataItem[yField]; if (idx > 0) { var prevValue = plotData[idx - 1][exports.VALUE_FIELD]; if (util_1.isArray(prevValue)) { value = [prevValue[1], dataItem[yField] + prevValue[1]]; } else { value = [prevValue, dataItem[yField] + prevValue]; } } plotData.push(tslib_1.__assign(tslib_1.__assign({}, dataItem), (_a = {}, _a[exports.VALUE_FIELD] = value, _a[exports.INDEX_FIELD] = idx, _a))); }); if (this.options.showTotal && this.options.showTotal.visible) { var values = util_1.map(originData, function (o) { return o[yField]; }); var totalValue = util_1.reduce(values, function (p, n) { return p + n; }, 0); plotData.push((_a = {}, _a[xField] = this.options.showTotal.label, _a[yField] = null, _a[exports.VALUE_FIELD] = [totalValue, 0], _a[exports.INDEX_FIELD] = plotData.length, _a[exports.IS_TOTAL] = true, _a)); } return plotData; }; WaterfallLayer.prototype.scale = function () { var options = this.options; var scales = {}; /** 配置x-scale */ scales[options.xField] = { type: 'cat' }; if (util_1.has(options, 'xAxis')) { scale_1.extractScale(scales[options.xField], options.xAxis); } /** 配置y-scale */ scales[exports.VALUE_FIELD] = {}; if (util_1.has(options, 'yAxis')) { scale_1.extractScale(scales[exports.VALUE_FIELD], options.yAxis); } this.setConfig('scales', scales); }; /** @override */ WaterfallLayer.prototype.axis = function () { var xAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'x', }); var yAxis_parser = factory_1.getComponent('axis', { plot: this, dim: 'y', }); var axesConfig = {}; axesConfig[this.options.xField] = xAxis_parser; axesConfig[exports.VALUE_FIELD] = yAxis_parser; /** 存储坐标轴配置项到config */ this.setConfig('axes', axesConfig); }; WaterfallLayer.prototype.coord = function () { return; }; WaterfallLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; WaterfallLayer.prototype.geometryTooltip = function () { this.waterfall.tooltip = {}; var tooltipOptions = this.options.tooltip; if (tooltipOptions.fields) { this.waterfall.tooltip.fields = tooltipOptions.fields; } if (tooltipOptions.formatter) { this.waterfall.tooltip.callback = tooltipOptions.formatter; if (!tooltipOptions.fields) { this.waterfall.tooltip.fields = [this.options.xField, exports.VALUE_FIELD]; } } }; /** 牵引线的样式注入到style中 */ WaterfallLayer.prototype._parseStyle = function () { var style = this.options.waterfallStyle; var leaderLine = this.options.leaderLine; var config = {}; if (util_1.isFunction(style)) { config.callback = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return Object.assign({}, style.apply(void 0, args), { leaderLine: leaderLine }); }; } else { config.cfg = tslib_1.__assign(tslib_1.__assign({}, style), { leaderLine: leaderLine }); } return config; }; WaterfallLayer.prototype._parseColor = function () { var _this = this; var options = this.options; var _a = this.options, xField = _a.xField, yField = _a.yField; var config = { fields: [xField, yField, exports.VALUE_FIELD, exports.INDEX_FIELD], }; if (util_1.isFunction(options.color)) { config.callback = options.color; } else { var risingColor_1 = '#f4664a'; var fallingColor_1 = '#30bf78'; var totalColor_1 = 'rgba(0, 0, 0, 0.25)'; if (util_1.isString(options.color)) { risingColor_1 = fallingColor_1 = totalColor_1 = options.color; } else if (util_1.isObject(options.color)) { var _b = options.color, rising = _b.rising, falling = _b.falling, total = _b.total; risingColor_1 = rising; fallingColor_1 = falling; totalColor_1 = total; } config.callback = function (type, value, values, index) { if (index === _this.options.data.length) { return totalColor_1 || (values[0] >= 0 ? risingColor_1 : fallingColor_1); } return (util_1.isArray(values) ? values[1] - values[0] : values) >= 0 ? risingColor_1 : fallingColor_1; }; } return config; }; /** 复写 legend 配置, 瀑布图默认无legend */ WaterfallLayer.prototype.adjustLegendOptions = function (options) { var legendOptions = options.legend; if (legendOptions) { legendOptions.visible = false; } }; /** 复写 meta 配置 */ WaterfallLayer.prototype.adjustMeta = function (options) { var metaOptions = options.meta; if (metaOptions) { var valueFieldMeta = metaOptions ? metaOptions[options.yField] : {}; valueFieldMeta.alias = valueFieldMeta.alias || options.yField; options.meta[exports.VALUE_FIELD] = valueFieldMeta; } }; return WaterfallLayer; }(view_layer_1.default)); exports.default = WaterfallLayer; global_1.registerPlotType('waterfall', WaterfallLayer); },{"../../base/global":392,"../../base/view-layer":395,"../../components/factory":412,"../../util/scale":712,"../../util/view":715,"./component/label/diff-label":639,"./component/label/waterfall-label":640,"./event":641,"./geometry/shape/waterfall":642,"@antv/util":803,"tslib":894}],645:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-14 */ var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var global_1 = require("../../base/global"); var WordCloud = /** @class */ (function (_super) { tslib_1.__extends(WordCloud, _super); function WordCloud(container, props) { var _this = this; // only canvas works for now props.renderer = 'canvas'; _this = _super.call(this, container, props) || this; return _this; } WordCloud.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'wordCloud'; layerProps.container = this.containerDOM; _super.prototype.createLayers.call(this, layerProps); }; return WordCloud; }(plot_1.default)); exports.default = WordCloud; global_1.registerPlotType('wordCloud', layer_1.default); },{"../../base/global":392,"../../base/plot":394,"./layer":646,"@antv/util":803,"tslib":894}],646:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var layer_1 = tslib_1.__importDefault(require("../../base/layer")); var word_cloud_tooltips_1 = tslib_1.__importDefault(require("./word-cloud-tooltips")); var wordcloud2_1 = tslib_1.__importDefault(require("./wordcloud2")); var WordCloudLayer = /** @class */ (function (_super) { tslib_1.__extends(WordCloudLayer, _super); function WordCloudLayer(props) { var _this = _super.call(this, props) || this; _this._toolTipsAction = function (item, dimension, evt, start) { if (dimension) { _this._toolTips.update({ items: [ { color: item.color || 'red', name: item.word, value: item.weight, }, ], x: evt.offsetX, y: evt.offsetY, }); _this._toolTips.show(); } else { _this._toolTips.hide(); } _this._toolTips.render(); _this._configHoverAction && _this._configHoverAction(item, dimension, evt, start); }; _this._configHoverAction = props.onWordCloudHover; _this._enableToolTips = util_1.get(props, 'tooltip.visible', true); _this.options = util_1.deepMix({}, { width: 400, height: 400, enableToolTips: true, }, props, // replace use config's hover action if needed, and trigger later { onWordCloudHover: _this._enableToolTips ? _this._toolTipsAction : _this._configHoverAction, }); return _this; } WordCloudLayer.prototype.init = function () { _super.prototype.init.call(this); this._initToolTips(); }; WordCloudLayer.prototype.render = function () { _super.prototype.render.call(this); this._render(); }; WordCloudLayer.prototype._initToolTips = function () { this._toolTips = new word_cloud_tooltips_1.default({ showTitle: false, visible: false, parent: this.options.container, follow: true, inPanel: false, items: [], }); this._toolTips.init(); }; WordCloudLayer.prototype._render = function () { this._targetCanvas = this.canvas.get('el'); if (this.options.maskImage) { this._handleMaskImage(); } else { // mask image not exist this._start(); } }; WordCloudLayer.prototype._handleMaskImage = function () { var _this = this; var image = new Image(); image.src = this.options.maskImage + '?' + new Date().getTime(); image.crossOrigin = 'Anonymous'; image.onload = function () { if (image.naturalHeight + image.naturalWidth === 0 || image.width + image.height === 0) { _this._start(); } else { // handle no-zero image silhouette _this._startWithMaskImage(image); } }; image.onerror = function () { console.error('image %s load failed !!!', _this.options.maskImage); // load image error, ignore this mask _this._start(); }; }; WordCloudLayer.prototype._start = function () { this._handleG2PlotConfig(); var targetCtx = this._targetCanvas.getContext('2d'); // it's a trick, because 「g」 use context to scale canvas by pixelRatio, // but here i need scale it back var pixelRatio = this.canvas.get('width') / this.canvas.get('el').width; targetCtx.scale(pixelRatio, pixelRatio); wordcloud2_1.default(this._targetCanvas, this.options); }; WordCloudLayer.prototype._handleG2PlotConfig = function () { var fontSize = this.options.wordStyle.fontSize || [10, 60]; var rotation = this.options.wordStyle.rotation || [-Math.PI / 2, Math.PI / 2]; var active, shadowColor, shadowBlur; if (this.options.wordStyle.active) { active = true; shadowColor = this.options.wordStyle.active.shadowColor || '#333'; shadowBlur = this.options.wordStyle.active.shadowBlur || 10; } else { active = false; } this.options = util_1.deepMix({}, this.options, { minFontSize: fontSize[0], maxFontSize: fontSize[1], minRotation: rotation[0], maxRotation: rotation[1], active: active, shadowColor: shadowColor, shadowBlur: shadowBlur, }); }; WordCloudLayer.prototype._startWithMaskImage = function (image) { var _a = this._scaleMaskImageCanvas(this._transformWhite2BlackPixels(image)), maskImageCanvas = _a.maskImageCanvas, maskImageContext = _a.maskImageContext; /* Determine bgPixel by creating another canvas and fill the specified background color. */ var bctx = document.createElement('canvas').getContext('2d'); bctx.fillStyle = this.options.backgroundColor || '#fff'; bctx.fillRect(0, 0, 1, 1); var bgPixel = bctx.getImageData(0, 0, 1, 1).data; var imageData = maskImageContext.getImageData(0, 0, maskImageCanvas.width, maskImageCanvas.height); var newImageData = maskImageContext.createImageData(imageData); for (var i = 0; i < imageData.data.length; i += 4) { if (imageData.data[i + 3] > 128) { // keep this area's data the same as pixel color newImageData.data[i] = bgPixel[0]; newImageData.data[i + 1] = bgPixel[1]; newImageData.data[i + 2] = bgPixel[2]; newImageData.data[i + 3] = bgPixel[3]; } else { // This color must not be the same as the bgPixel. // check wordcloud2.js#1192 's condition newImageData.data[i] = bgPixel[0]; newImageData.data[i + 1] = bgPixel[1]; newImageData.data[i + 2] = bgPixel[2]; newImageData.data[i + 3] = 254; // just for not same as the bg color } } maskImageContext.putImageData(newImageData, 0, 0); var targetCtx = this._targetCanvas.getContext('2d'); targetCtx.drawImage(maskImageCanvas, 0, 0); this.options = util_1.deepMix({}, this.options, { clearCanvas: false }); this._start(); }; WordCloudLayer.prototype._scaleMaskImageCanvas = function (maskImageCanvas) { var maskCanvasScaled = document.createElement('canvas'); // get real canvas determined by pixelRatio maskCanvasScaled.width = this.canvas.get('width'); maskCanvasScaled.height = this.canvas.get('height'); var ctx = maskCanvasScaled.getContext('2d'); // keep scale smooth ctx.imageSmoothingEnabled = true; // ctx.mozImageSmoothingEnabled = true; // ctx.webkitImageSmoothingEnabled = true; // ctx.msImageSmoothingEnabled = true; ctx.drawImage(maskImageCanvas, 0, 0, maskImageCanvas.width, maskImageCanvas.height, 0, 0, maskCanvasScaled.width, maskCanvasScaled.height); return { maskImageCanvas: maskCanvasScaled, maskImageContext: ctx, }; }; WordCloudLayer.prototype._transformWhite2BlackPixels = function (image) { var maskImageCanvas = document.createElement('canvas'); maskImageCanvas.width = image.width; maskImageCanvas.height = image.height; var ctx = maskImageCanvas.getContext('2d'); ctx.drawImage(image, 0, 0, image.width, image.height); var imageData = ctx.getImageData(0, 0, maskImageCanvas.width, maskImageCanvas.height); var SINGLE_COMPONENT_SIZE = 4; var BLACK_PIXEL = 0; var FULL_PIXEL = 255; // R - G - B - A for (var i = 0; i < imageData.data.length; i += SINGLE_COMPONENT_SIZE) { var rgb = imageData.data[i] + imageData.data[i + 1] + imageData.data[i + 2]; var alpha = imageData.data[i + 3]; if (alpha < 128 || rgb > 250 * 3) { // white area(not to draw) imageData.data[i] = FULL_PIXEL; imageData.data[i + 1] = FULL_PIXEL; imageData.data[i + 2] = FULL_PIXEL; imageData.data[i + 3] = BLACK_PIXEL; } else { // black area wait to draw(image black silhouette) imageData.data[i] = BLACK_PIXEL; imageData.data[i + 1] = BLACK_PIXEL; imageData.data[i + 2] = BLACK_PIXEL; imageData.data[i + 3] = FULL_PIXEL; } } ctx.putImageData(imageData, 0, 0); return maskImageCanvas; }; return WordCloudLayer; }(layer_1.default)); exports.default = WordCloudLayer; },{"../../base/layer":393,"./word-cloud-tooltips":647,"./wordcloud2":648,"@antv/util":803,"tslib":894}],647:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * Create By Bruce Too * On 2020-02-14 */ var util_1 = require("@antv/util"); var dependents_1 = require("../../dependents"); var WordCloudTooltips = /** @class */ (function (_super) { tslib_1.__extends(WordCloudTooltips, _super); function WordCloudTooltips(cfg) { var _this = this; var newCfg = util_1.deepMix({}, cfg, { itemTpl: "
      \n \n {name}{value}
      ", }, cfg); _this = _super.call(this, newCfg) || this; return _this; } return WordCloudTooltips; }(dependents_1.HtmlTooltip)); exports.default = WordCloudTooltips; },{"../../dependents":425,"@antv/util":803,"tslib":894}],648:[function(require,module,exports){ /** * Create By Bruce Too * On 2020-02-14 */ /* eslint-disable unicorn/no-abusive-eslint-disable */ /* eslint-disable */ // @ts-nocheck // TODO rewrite with typescript @brucetoo /*! * wordcloud2.js * http://timdream.org/wordcloud2.js/ * * Copyright 2011 - 2013 Tim Chien * Released under the MIT license */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); // setImmediate if (!window.setImmediate) { window.setImmediate = (function setupSetImmediate() { return (window.msSetImmediate || window.webkitSetImmediate || window.mozSetImmediate || window.oSetImmediate || (function setupSetZeroTimeout() { if (!window.postMessage || !window.addEventListener) { return null; } var callbacks = [undefined]; var message = 'zero-timeout-message'; // Like setTimeout, but only takes a function argument. There's // no time argument (always zero) and no arguments (you have to // use a closure). var setZeroTimeout = function setZeroTimeout(callback) { var id = callbacks.length; callbacks.push(callback); window.postMessage(message + id.toString(36), '*'); return id; }; window.addEventListener('message', function setZeroTimeoutMessage(evt) { // Skipping checking event source, retarded IE confused this window // object with another in the presence of iframe if (typeof evt.data !== 'string' || evt.data.substr(0, message.length) !== message /* || evt.source !== window */) { return; } evt.stopImmediatePropagation(); var id = parseInt(evt.data.substr(message.length), 36); if (!callbacks[id]) { return; } callbacks[id](); callbacks[id] = undefined; }, true); /* specify clearImmediate() here since we need the scope */ window.clearImmediate = function clearZeroTimeout(id) { if (!callbacks[id]) { return; } callbacks[id] = undefined; }; return setZeroTimeout; })() || // fallback function setImmediateFallback(fn) { window.setTimeout(fn, 0); }); })(); } if (!window.clearImmediate) { window.clearImmediate = (function setupClearImmediate() { return (window.msClearImmediate || window.webkitClearImmediate || window.mozClearImmediate || window.oClearImmediate || // "clearZeroTimeout" is implement on the previous block || // fallback function clearImmediateFallback(timer) { window.clearTimeout(timer); }); })(); } // Check if WordCloud can run on this browser var isSupported = (function isSupported() { var canvas = document.createElement('canvas'); if (!canvas || !canvas.getContext) { return false; } var ctx = canvas.getContext('2d'); if (!ctx.getImageData) { return false; } if (!ctx.fillText) { return false; } if (!Array.prototype.some) { return false; } if (!Array.prototype.push) { return false; } return true; })(); // Find out if the browser impose minium font size by // drawing small texts on a canvas and measure it's width. var minFontSize = (function getMinFontSize() { if (!isSupported) { return; } var ctx = document.createElement('canvas').getContext('2d'); // start from 20 var size = 20; // two sizes to measure var hanWidth, mWidth; while (size) { ctx.font = size.toString(10) + 'px sans-serif'; if (ctx.measureText('\uFF37').width === hanWidth && ctx.measureText('m').width === mWidth) { return size + 1; } hanWidth = ctx.measureText('\uFF37').width; mWidth = ctx.measureText('m').width; size--; } return 0; })(); // Based on http://jsfromhell.com/array/shuffle var shuffleArray = function shuffleArray(arr) { for (var j, x, i = arr.length; i; j = Math.floor(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x) { } return arr; }; var WordCloud = function WordCloud(elements, options) { if (!isSupported) { return; } if (!Array.isArray(elements)) { elements = [elements]; } elements.forEach(function (el, i) { if (typeof el === 'string') { elements[i] = document.getElementById(el); if (!elements[i]) { throw 'The element id specified is not found.'; } } else if (!el.tagName && !el.appendChild) { throw 'You must pass valid HTML elements, or ID of the element.'; } }); /* Default values to be overwritten by options object */ var settings = { data: [], fontFamily: '"Trebuchet MS", "Heiti TC", "微軟正黑體", ' + '"Arial Unicode MS", "Droid Fallback Sans", sans-serif', fontWeight: 'normal', color: 'random-dark', minFontSize: minFontSize, maxFontSize: 60, clearCanvas: true, backgroundColor: '#fff', gridSize: 8, drawOutOfBound: false, origin: null, drawMask: false, maskColor: 'rgba(255,0,0,0.3)', maskGapWidth: 0.3, wait: 0, abortThreshold: 0, abort: function noop() { }, minRotation: -Math.PI / 2, maxRotation: Math.PI / 2, rotateRatio: 0.5, rotationSteps: 1, shuffle: true, shape: 'circle', ellipticity: 1, active: true, animatable: true, selected: -1, shadowColor: '#333', shadowBlur: 10, fontScale: 1.2, classes: null, onWordCloudHover: null, onWordCloudClick: null, }; var interactionItems = []; if (options) { for (var key in options) { if (key === 'wordStyle') { for (var fontKey in options[key]) { if (fontKey in settings) { settings[fontKey] = options[key][fontKey]; } } } else { if (key in settings) { settings[key] = options[key]; } } } } if (settings.minFontSize < minFontSize) { // can't less than browse's min font size settings.minFontSize = minFontSize; } if (settings.minFontSize > settings.maxFontSize) { console.error('minSize cant bigger than maxSize'); return; } var maxWeight = 0; for (var i = 0; i < settings.data.length; i++) { if (maxWeight < settings.data[i].weight) { maxWeight = settings.data[i].weight; } } var getRealFontSize = function getRealFontSize(weight) { var fontSize = Math.min(Math.max(settings.minFontSize, (settings.maxFontSize * weight) / maxWeight), settings.maxFontSize); if (twiceRender) { return fontSize * settings.fontScale; } return fontSize; }; var isCardioid = false; /* Convert shape into a function */ if (typeof settings.shape !== 'function') { switch (settings.shape) { case 'circle': /* falls through */ default: // 'circle' is the default and a shortcut in the code loop. settings.shape = 'circle'; break; case 'cardioid': // https://baike.baidu.com/item/%E5%BF%83%E8%84%8F%E7%BA%BF/10323843?fromtitle=%E5%BF%83%E5%BD%A2%E7%BA%BF&fromid=10018818 settings.shape = function shapeCardioid(theta) { return 1 - Math.sin(theta); }; isCardioid = true; break; /* To work out an X-gon, one has to calculate "m", where 1/(cos(2*PI/X)+m*sin(2*PI/X)) = 1/(cos(0)+m*sin(0)) http://www.wolframalpha.com/input/?i=1%2F%28cos%282*PI%2FX%29%2Bm*sin%28 2*PI%2FX%29%29+%3D+1%2F%28cos%280%29%2Bm*sin%280%29%29 Copy the solution into polar equation r = 1/(cos(t') + m*sin(t')) where t' equals to mod(t, 2PI/X); */ case 'diamond': settings.shape = function shapeSquare(theta) { var thetaPrime = theta % ((2 * Math.PI) / 4); return 1 / (Math.cos(thetaPrime) + Math.sin(thetaPrime)); }; break; case 'square': // http://www.wolframalpha.com/input/?i=plot+r+%3D+1%2F%28cos%28mod+ // %28t%2C+PI%2F2%29%29%2Bsin%28mod+%28t%2C+PI%2F2%29%29%29%2C+t+%3D // +0+..+2*PI settings.shape = function shapeSquare(theta) { var thetaPrime = (theta + Math.PI / 4) % ((2 * Math.PI) / 4); return 1 / (Math.cos(thetaPrime) + Math.sin(thetaPrime)); }; break; case 'triangle-forward': // http://www.wolframalpha.com/input/?i=plot+r+%3D+1%2F%28cos%28mod+ // %28t%2C+2*PI%2F3%29%29%2Bsqrt%283%29sin%28mod+%28t%2C+2*PI%2F3%29 // %29%29%2C+t+%3D+0+..+2*PI settings.shape = function shapeTriangle(theta) { var thetaPrime = theta % ((2 * Math.PI) / 3); return 1 / (Math.cos(thetaPrime) + Math.sqrt(3) * Math.sin(thetaPrime)); }; break; case 'triangle-backward': settings.shape = function shapeTriangle(theta) { var thetaPrime = (theta + Math.PI) % ((2 * Math.PI) / 3); return 1 / (Math.cos(thetaPrime) + Math.sqrt(3) * Math.sin(thetaPrime)); }; break; case 'triangle': case 'triangle-up': settings.shape = function shapeTriangle(theta) { var thetaPrime = (theta + (Math.PI * 3) / 2) % ((2 * Math.PI) / 3); return 1 / (Math.cos(thetaPrime) + Math.sqrt(3) * Math.sin(thetaPrime)); }; break; case 'triangle-down': settings.shape = function shapeTriangle(theta) { var thetaPrime = (theta + (Math.PI * 5) / 2) % ((2 * Math.PI) / 3); return 1 / (Math.cos(thetaPrime) + Math.sqrt(3) * Math.sin(thetaPrime)); }; break; case 'pentagon': settings.shape = function shapePentagon(theta) { var thetaPrime = (theta + 0.955) % ((2 * Math.PI) / 5); return 1 / (Math.cos(thetaPrime) + 0.726543 * Math.sin(thetaPrime)); }; break; case 'star': settings.shape = function shapeStar(theta) { var thetaPrime = (theta + 0.955) % ((2 * Math.PI) / 10); if (((theta + 0.955) % ((2 * Math.PI) / 5)) - (2 * Math.PI) / 10 >= 0) { return (1 / (Math.cos((2 * Math.PI) / 10 - thetaPrime) + 3.07768 * Math.sin((2 * Math.PI) / 10 - thetaPrime))); } else { return 1 / (Math.cos(thetaPrime) + 3.07768 * Math.sin(thetaPrime)); } }; break; } } /* Make sure gridSize is a whole number and is not smaller than 4px */ settings.gridSize = Math.max(Math.floor(settings.gridSize), 4); /* shorthand */ var g = settings.gridSize; var maskRectWidth = g - settings.maskGapWidth; /* normalize rotation settings */ var rotationRange = Math.abs(settings.maxRotation - settings.minRotation); var minRotation = Math.min(settings.maxRotation, settings.minRotation); var rotationSteps = settings.rotationSteps; /* information/object available to all functions, set when start() */ var grid, // 2d array containing filling information ngx, ngy, // width and height of the grid center, // position of the center of the cloud maxRadius; /* timestamp for measuring each putWord() action */ var escapeTime; /* function for getting the color of the text */ var getTextColor; function random_hsl_color(min, max) { return ('hsl(' + (Math.random() * 360).toFixed() + ',' + (Math.random() * 30 + 70).toFixed() + '%,' + (Math.random() * (max - min) + min).toFixed() + '%)'); } switch (settings.color) { case 'random-dark': getTextColor = function getRandomDarkColor() { return random_hsl_color(10, 50); }; break; case 'random-light': getTextColor = function getRandomLightColor() { return random_hsl_color(50, 90); }; break; default: if (typeof settings.color === 'function') { getTextColor = settings.color; } break; } /* function for getting the classes of the text */ var getTextClasses = null; if (typeof settings.classes === 'function') { getTextClasses = settings.classes; } /* Interactive */ var interactive = false; var infoGrid = []; var hovered; var getInfoGridFromMouseTouchEvent = function getInfoGridFromMouseTouchEvent(evt) { var canvas = evt.currentTarget; var rect = canvas.getBoundingClientRect(); var clientX; var clientY; /** Detect if touches are available */ if (evt.touches) { clientX = evt.touches[0].clientX; clientY = evt.touches[0].clientY; } else { clientX = evt.clientX; clientY = evt.clientY; } var eventX = clientX - rect.left; var eventY = clientY - rect.top; var x = Math.floor((eventX * (canvas.width / rect.width || 1)) / g); var y = Math.floor((eventY * (canvas.height / rect.height || 1)) / g); return infoGrid && infoGrid[x] && infoGrid[x][y]; }; var defaultHoverAction = function defaultHoverAction(item, dimension, evt, start) { if (item) { start(item.id); } else { start(-1); } }; var wordcloudhover = function wordcloudhover(evt) { var info = getInfoGridFromMouseTouchEvent(evt); if (hovered === info) { return; } if (twiceRender && info && info.item && !util_1.get(info, ['item', 'twiceRender'])) { return; } if (!info) { settings.onWordCloudHover(undefined, undefined, evt, start); if (settings.active) { defaultHoverAction(undefined, undefined, evt, start); } return; } settings.onWordCloudHover(info.item, info.dimension, evt, start); if (settings.active) { defaultHoverAction(info.item, info.dimension, evt, start); } hovered = info; }; var wordcloudclick = function wordcloudclick(evt) { var info = getInfoGridFromMouseTouchEvent(evt); if (!info) { return; } settings.onWordCloudClick(info.item, info.dimension, evt); evt.preventDefault(); }; /* Get points on the grid for a given radius away from the center */ var pointsAtRadius = []; var getPointsAtRadius = function getPointsAtRadius(radius) { if (pointsAtRadius[radius]) { return pointsAtRadius[radius]; } // Look for these number of points on each radius var T = radius * 8; // Getting all the points at this radius var t = T; var points = []; if (radius === 0) { points.push([center[0], center[1], 0]); } while (t--) { // distort the radius to put the cloud in shape var rx = 1; if (settings.shape !== 'circle') { rx = settings.shape((t / T) * 2 * Math.PI); // 0 to 1 } // Push [x, y, t]; t is used solely for getTextColor() points.push([ center[0] + radius * rx * Math.cos((-t / T) * 2 * Math.PI), center[1] + radius * rx * Math.sin((-t / T) * 2 * Math.PI) * settings.ellipticity, (t / T) * 2 * Math.PI, ]); } pointsAtRadius[radius] = points; return points; }; /* Return true if we had spent too much time */ var exceedTime = function exceedTime() { return settings.abortThreshold > 0 && new Date().getTime() - escapeTime > settings.abortThreshold; }; /* Get the deg of rotation according to settings, and luck. */ var getRotateDeg = function getRotateDeg() { if (settings.rotateRatio === 0) { return 0; } if (Math.random() > settings.rotateRatio) { return 0; } if (rotationRange === 0) { return minRotation; } // return minRotation + Math.round(Math.random() * rotationRange / rotationSteps) * rotationSteps; if (rotationSteps > 0) { // Min rotation + zero or more steps * span of one step return minRotation + (Math.floor(Math.random() * rotationSteps) * rotationRange) / rotationSteps; } else { return minRotation + Math.random() * rotationRange; } }; var getTextInfo = function getTextInfo(word, weight, rotateDeg) { // calculate the acutal font size // fontSize === 0 means wants the text skipped, // and size < minSize means we cannot draw the text var debug = false; var fontSize = getRealFontSize(weight); if (fontSize <= 0) { return false; } // Scale factor here is to make sure fillText is not limited by // the minium font size set by browser. // It will always be 1 or 2n. var mu = 1; if (fontSize < minFontSize) { mu = (function calculateScaleFactor() { var mu = 2; while (mu * fontSize < minFontSize) { mu += 2; } return mu; })(); } var fcanvas = document.createElement('canvas'); var fctx = fcanvas.getContext('2d', { willReadFrequently: true }); fctx.font = settings.fontWeight + ' ' + (fontSize * mu).toString(10) + 'px ' + settings.fontFamily; // Estimate the dimension of the text with measureText(). var fw = fctx.measureText(word).width / mu; var fh = Math.max(fontSize * mu, fctx.measureText('m').width, fctx.measureText('\uFF37').width) / mu; // Create a boundary box that is larger than our estimates, // so text don't get cut of (it sill might) var boxWidth = fw + fh * 2; var boxHeight = fh * 3; var fgw = Math.ceil(boxWidth / g); var fgh = Math.ceil(boxHeight / g); boxWidth = fgw * g; boxHeight = fgh * g; // Calculate the proper offsets to make the text centered at // the preferred position. // This is simply half of the width. var fillTextOffsetX = -fw / 2; // Instead of moving the box to the exact middle of the preferred // position, for Y-offset we move 0.4 instead, so Latin alphabets look // vertical centered. var fillTextOffsetY = -fh * 0.4; // Calculate the actual dimension of the canvas, considering the rotation. var cgh = Math.ceil((boxWidth * Math.abs(Math.sin(rotateDeg)) + boxHeight * Math.abs(Math.cos(rotateDeg))) / g); var cgw = Math.ceil((boxWidth * Math.abs(Math.cos(rotateDeg)) + boxHeight * Math.abs(Math.sin(rotateDeg))) / g); var width = cgw * g; var height = cgh * g; fcanvas.setAttribute('width', width); fcanvas.setAttribute('height', height); if (debug) { // Attach fcanvas to the DOM document.body.appendChild(fcanvas); // Save it's state so that we could restore and draw the grid correctly. fctx.save(); } // Scale the canvas with |mu|. fctx.scale(1 / mu, 1 / mu); fctx.translate((width * mu) / 2, (height * mu) / 2); fctx.rotate(-rotateDeg); // Once the width/height is set, ctx info will be reset. // Set it again here. fctx.font = settings.fontWeight + ' ' + (fontSize * mu).toString(10) + 'px ' + settings.fontFamily; // Fill the text into the fcanvas. // XXX: We cannot because textBaseline = 'top' here because // Firefox and Chrome uses different default line-height for canvas. // Please read https://bugzil.la/737852#c6. // Here, we use textBaseline = 'middle' and draw the text at exactly // 0.5 * fontSize lower. fctx.fillStyle = '#000'; fctx.textBaseline = 'middle'; fctx.fillText(word, fillTextOffsetX * mu, (fillTextOffsetY + fontSize * 0.5) * mu); // Get the pixels of the text var imageData; try { imageData = fctx.getImageData(0, 0, width, height).data; } catch (e) { // data not long type return false; } if (exceedTime()) { return false; } if (debug) { // Draw the box of the original estimation fctx.strokeRect(fillTextOffsetX * mu, fillTextOffsetY, fw * mu, fh * mu); fctx.restore(); } // Read the pixels and save the information to the occupied array var occupied = []; var gx = cgw, gy, x, y; var bounds = [cgh / 2, cgw / 2, cgh / 2, cgw / 2]; while (gx--) { gy = cgh; while (gy--) { y = g; singleGridLoop: { while (y--) { x = g; while (x--) { if (imageData[((gy * g + y) * width + (gx * g + x)) * 4 + 3]) { occupied.push([gx, gy]); if (gx < bounds[3]) { bounds[3] = gx; } if (gx > bounds[1]) { bounds[1] = gx; } if (gy < bounds[0]) { bounds[0] = gy; } if (gy > bounds[2]) { bounds[2] = gy; } if (debug) { fctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; fctx.fillRect(gx * g, gy * g, g - 0.5, g - 0.5); } break singleGridLoop; } } } if (debug) { fctx.fillStyle = 'rgba(0, 0, 255, 0.5)'; fctx.fillRect(gx * g, gy * g, g - 0.5, g - 0.5); } } } } if (debug) { // real bounds fctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; fctx.fillRect(bounds[3] * g, bounds[0] * g, (bounds[1] - bounds[3] + 1) * g, (bounds[2] - bounds[0] + 1) * g); } // Return information needed to create the text on the real canvas return { mu: mu, occupied: occupied, bounds: bounds, gw: cgw, gh: cgh, fillTextOffsetX: fillTextOffsetX, fillTextOffsetY: fillTextOffsetY, fillTextWidth: fw, fillTextHeight: fh, fontSize: fontSize, }; }; /* Determine if there is room available in the given dimension */ var canFitText = function canFitText(gx, gy, gw, gh, occupied) { // Go through the occupied points, // return false if the space is not available. var i = occupied.length; while (i--) { var px = gx + occupied[i][0]; var py = gy + occupied[i][1]; if (px >= ngx || py >= ngy || px < 0 || py < 0) { if (!settings.drawOutOfBound) { return false; } continue; } if (!grid[px][py]) { return false; } } return true; }; /* Actually draw the text on the grid */ var drawText = function drawText(gx, gy, info, word, weight, distance, theta, rotateDeg, attributes, id, refresh) { var fontSize = info.fontSize; var color = settings.color; var classes = settings.classes; if (!refresh) { if (getTextColor) { color = getTextColor(word, weight, fontSize, distance, theta); } else { color = settings.color; } if (getTextClasses) { classes = getTextClasses(word, weight, fontSize, distance, theta); } else { classes = settings.classes; } } else { var find = getInteractionItemById(id); color = find ? find.color : settings.color; } var dimension; var bounds = info.bounds; dimension = { x: (gx + bounds[3]) * g, y: (gy + bounds[0]) * g, w: (bounds[1] - bounds[3] + 1) * g, h: (bounds[2] - bounds[0] + 1) * g, }; elements.forEach(function (el) { if (el.getContext) { var ctx = el.getContext('2d'); var mu = info.mu; // Save the current state before messing it ctx.save(); var font = settings.fontWeight + ' ' + (fontSize * mu).toString(10) + 'px ' + settings.fontFamily; ctx.scale(1 / mu, 1 / mu); ctx.font = font; ctx.fillStyle = color; // Translate the canvas position to the origin coordinate of where // the text should be put. var transX = (gx + info.gw / 2) * g * mu; var transY = (gy + info.gh / 2) * g * mu; ctx.translate(transX, transY); if (rotateDeg !== 0) { ctx.rotate(-rotateDeg); } // Finally, fill the text. // XXX: We cannot because textBaseline = 'top' here because // Firefox and Chrome uses different default line-height for canvas. // Please read https://bugzil.la/737852#c6. // Here, we use textBaseline = 'middle' and draw the text at exactly // 0.5 * fontSize lower. ctx.textBaseline = 'middle'; if (settings.selected === id) { ctx.shadowColor = settings.shadowColor; ctx.shadowBlur = settings.shadowBlur; } ctx.fillText(word, info.fillTextOffsetX * mu, (info.fillTextOffsetY + fontSize * 0.5) * mu); // The below box is always matches how s are positioned // ctx.strokeRect(info.fillTextOffsetX, info.fillTextOffsetY, // info.fillTextWidth, info.fillTextHeight); if (!refresh) { interactionItems.push({ gx: gx, gy: gy, info: info, word: word, weight: weight, distance: distance, theta: theta, rotateDeg: rotateDeg, attributes: attributes, id: id, color: color, }); } // Restore the state. ctx.restore(); } else { // drawText on DIV element var span = document.createElement('span'); var transformRule = ''; transformRule = 'rotate(' + (-rotateDeg / Math.PI) * 180 + 'deg) '; if (info.mu !== 1) { transformRule += 'translateX(-' + info.fillTextWidth / 4 + 'px) ' + 'scale(' + 1 / info.mu + ')'; } var styleRules = { position: 'absolute', display: 'block', font: settings.fontWeight + ' ' + fontSize * info.mu + 'px ' + settings.fontFamily, left: (gx + info.gw / 2) * g + info.fillTextOffsetX + 'px', top: (gy + info.gh / 2) * g + info.fillTextOffsetY + 'px', width: info.fillTextWidth + 'px', height: info.fillTextHeight + 'px', lineHeight: fontSize + 'px', whiteSpace: 'nowrap', transform: transformRule, webkitTransform: transformRule, msTransform: transformRule, transformOrigin: '50% 40%', webkitTransformOrigin: '50% 40%', msTransformOrigin: '50% 40%', }; if (color) { styleRules.color = color; } span.textContent = word; for (var cssProp in styleRules) { span.style[cssProp] = styleRules[cssProp]; } if (attributes) { for (var attribute in attributes) { span.setAttribute(attribute, attributes[attribute]); } } if (classes) { span.className += classes; } el.appendChild(span); } }); }; /* Help function to updateGrid */ var fillGridAt = function fillGridAt(x, y, drawMask, dimension, item) { if (x >= ngx || y >= ngy || x < 0 || y < 0) { return; } grid[x][y] = false; if (drawMask) { var ctx = elements[0].getContext('2d'); ctx.fillRect(x * g, y * g, maskRectWidth, maskRectWidth); } if (interactive) { infoGrid[x][y] = { item: item, dimension: dimension }; } }; /* Update the filling information of the given space with occupied points. Draw the mask on the canvas if necessary. */ var updateGrid = function updateGrid(gx, gy, gw, gh, info) { var occupied = info.occupied; var drawMask = settings.drawMask; var ctx; if (drawMask) { ctx = elements[0].getContext('2d'); ctx.save(); ctx.fillStyle = settings.maskColor; } var dimension; if (interactive) { var bounds = info.bounds; dimension = { x: (gx + bounds[3]) * g, y: (gy + bounds[0]) * g, w: (bounds[1] - bounds[3] + 1) * g, h: (bounds[2] - bounds[0] + 1) * g, }; } var i = occupied.length; while (i--) { var px = gx + occupied[i][0]; var py = gy + occupied[i][1]; if (px >= ngx || py >= ngy || px < 0 || py < 0) { continue; } // save item's color from info var find = getInteractionItemById(info.item.id); if (find) { info.item.color = find.color; } fillGridAt(px, py, drawMask, dimension, info.item); } if (drawMask) { ctx.restore(); } }; var tryToPutWordAtPoint = function tryToPutWordAtPoint(gxy, info, word, weight, distance, rotateDeg, attributes, id) { var gx = Math.floor(gxy[0] - info.gw / 2); var gy = Math.floor(gxy[1] - info.gh / 2); var gw = info.gw; var gh = info.gh; // If we cannot fit the text at this position, return false // and go to the next position. if (!canFitText(gx, gy, gw, gh, info.occupied)) { return false; } // Actually put the text on the canvas drawText(gx, gy, info, word, weight, distance, gxy[2], rotateDeg, attributes, id, false); // Mark the spaces on the grid as filled updateGrid(gx, gy, gw, gh, info); return { gx: gx, gy: gy, rot: rotateDeg, info: info, }; }; /* putWord() processes each item on the list, calculate it's size and determine it's position, and actually put it on the canvas. */ var putWord = function putWord(item) { var word, weight, attributes, id; if (Array.isArray(item)) { word = item[0]; weight = item[1]; } else { word = item.word; weight = item.weight; attributes = item.attributes; id = item.id; } var rotateDeg = util_1.isNil(item.rotateDeg) ? getRotateDeg() : item.rotateDeg; // get info needed to put the text onto the canvas var info = getTextInfo(word, weight, rotateDeg); if (info) { info['item'] = item; } // not getting the info means we shouldn't be drawing this one. if (!info) { return false; } if (exceedTime()) { return false; } // If drawOutOfBound is set to false, // skip the loop if we have already know the bounding box of // word is larger than the canvas. if (!settings.drawOutOfBound) { var bounds = info.bounds; if (bounds[1] - bounds[3] + 1 > ngx || bounds[2] - bounds[0] + 1 > ngy) { return false; } } // Determine the position to put the text by // start looking for the nearest points var r = maxRadius + 1; while (r--) { var points = getPointsAtRadius(maxRadius - r); if (settings.shuffle) { points = [].concat(points); shuffleArray(points); } // Try to fit the words by looking at each point. // array.some() will stop and return true // when putWordAtPoint() returns true. for (var i = 0; i < points.length; i++) { var res = tryToPutWordAtPoint(points[i], info, word, weight, maxRadius - r, rotateDeg, attributes, id); if (res) { return res; } } // var drawn = points.some(tryToPutWordAtPoint); // if (drawn) { // // leave putWord() and return true // return true; // } } // we tried all distances but text won't fit, return null return null; }; /* Send DOM event to all elements. Will stop sending event and return if the previous one is canceled (for cancelable events). */ var sendEvent = function sendEvent(type, cancelable, detail) { if (cancelable) { return !elements.some(function (el) { var evt = document.createEvent('CustomEvent'); evt.initCustomEvent(type, true, cancelable, detail || {}); return !el.dispatchEvent(evt); }, this); } else { elements.forEach(function (el) { var evt = document.createEvent('CustomEvent'); evt.initCustomEvent(type, true, cancelable, detail || {}); el.dispatchEvent(evt); }, this); } }; var getInteractionItemById = function getInteractionItemById(id) { for (var i = 0; i < interactionItems.length; i++) { var find = interactionItems[i]; if (interactionItems[i].id === id) { return find; } } return undefined; }; var twiceRender; /* Start drawing on a canvas */ var start = function start(selected) { if (selected !== undefined) { // re-refresh canvas with selected // work in canvas only for now if (settings.selected !== selected && elements[0].getContext) { settings.selected = selected; var ctx = elements[0].getContext('2d'); // draw background ctx.fillStyle = settings.backgroundColor; ctx.clearRect(0, 0, elements[0].width, elements[0].height); ctx.fillRect(0, 0, elements[0].width, elements[0].height); // draw text for (var i_1 = 0; i_1 < interactionItems.length; i_1++) { var find = interactionItems[i_1]; if (!twiceRender || (twiceRender && util_1.get(find, ['info', 'item', 'twiceRender']))) { /** * 词云图词量较少的时候,重新渲染一次词汇,放大词云图效果 * 这里先临时解决,后续还是需要优化词云图算法来解决 */ drawText(find.gx, find.gy, find.info, find.word, find.weight, find.distance, find.theta, find.rotateDeg, find.attributes, find.id, true); } } } return; } // For dimensions, clearCanvas etc., // we only care about the first element. var canvas = elements[0]; if (canvas.getContext) { ngx = Math.ceil(canvas.width / g); ngy = Math.ceil(canvas.height / g); } else { var rect = canvas.getBoundingClientRect(); ngx = Math.ceil(rect.width / g); ngy = Math.ceil(rect.height / g); } // Sending a wordcloudstart event which cause the previous loop to stop. // Do nothing if the event is canceled. if (!sendEvent('wordcloudstart', true)) { return; } // Determine the center of the word cloud center = settings.origin ? [settings.origin[0] / g, settings.origin[1] / g] : [ngx / 2, ngy / (isCardioid ? 4 : 2)]; // Maxium radius to look for space maxRadius = Math.floor(Math.sqrt(ngx * ngx + ngy * ngy)); /* Clear the canvas only if the clearCanvas is set, if not, update the grid to the current canvas state */ grid = []; var gx, gy, i; if (!canvas.getContext || settings.clearCanvas) { elements.forEach(function (el) { if (el.getContext) { var ctx = el.getContext('2d'); ctx.fillStyle = settings.backgroundColor; ctx.clearRect(0, 0, ngx * (g + 1), ngy * (g + 1)); ctx.fillRect(0, 0, ngx * (g + 1), ngy * (g + 1)); } else { el.textContent = ''; el.style.backgroundColor = settings.backgroundColor; el.style.position = 'relative'; } }); /* fill the grid with empty state */ gx = ngx; while (gx--) { grid[gx] = []; gy = ngy; while (gy--) { grid[gx][gy] = true; } } } else { /* Determine bgPixel by creating another canvas and fill the specified background color. */ var bctx = document.createElement('canvas').getContext('2d'); bctx.fillStyle = settings.backgroundColor; bctx.fillRect(0, 0, 1, 1); var bgPixel = bctx.getImageData(0, 0, 1, 1).data; /* Read back the pixels of the canvas we got to tell which part of the canvas is empty. (no clearCanvas only works with a canvas, not divs) */ var imageData = canvas.getContext('2d').getImageData(0, 0, ngx * g, ngy * g).data; gx = ngx; var x, y; while (gx--) { grid[gx] = []; gy = ngy; while (gy--) { y = g; singleGridLoop: while (y--) { x = g; while (x--) { i = 4; while (i--) { if (imageData[((gy * g + y) * ngx * g + (gx * g + x)) * 4 + i] !== bgPixel[i]) { grid[gx][gy] = false; break singleGridLoop; } } } } if (grid[gx][gy] !== false) { grid[gx][gy] = true; } } } imageData = bctx = bgPixel = undefined; } // fill the infoGrid with empty state if we need it if (settings.onWordCloudHover || settings.onWordCloudClick) { interactive = true; /* fill the grid with empty state */ gx = ngx + 1; while (gx--) { infoGrid[gx] = []; } if (settings.onWordCloudHover) { canvas.addEventListener('mousemove', wordcloudhover); } if (settings.onWordCloudClick) { canvas.addEventListener('click', wordcloudclick); canvas.addEventListener('touchstart', wordcloudclick); canvas.addEventListener('touchend', function (e) { e.preventDefault(); }); canvas.style.webkitTapHighlightColor = 'rgba(0, 0, 0, 0)'; } canvas.addEventListener('wordcloudstart', function stopInteraction() { canvas.removeEventListener('wordcloudstart', stopInteraction); canvas.removeEventListener('mousemove', wordcloudhover); canvas.removeEventListener('click', wordcloudclick); hovered = undefined; }); } if (!settings.animatable) { if (options.maskImage) { /** 修复颜色透明,还留有 maskImage 的情况 */ elements.forEach(function (el) { if (el.getContext) { var ctx = el.getContext('2d'); ctx.fillStyle = settings.backgroundColor; ctx.clearRect(0, 0, ngx * (g + 1), ngy * (g + 1)); ctx.fillRect(0, 0, ngx * (g + 1), ngy * (g + 1)); } }); } var renderedWords = []; for (var i_2 = 0; i_2 < settings.data.length; i_2++) { var response = putWord(settings.data[i_2]); if (response) { renderedWords.push(response); } } if (renderedWords.length === settings.data.length) { if (!twiceRender) { elements.forEach(function (el) { if (el.getContext) { var ctx = el.getContext('2d'); ctx.fillStyle = settings.backgroundColor; ctx.clearRect(0, 0, ngx * (g + 1), ngy * (g + 1)); ctx.fillRect(0, 0, ngx * (g + 1), ngy * (g + 1)); } }); /* fill the grid with empty state */ gx = ngx; while (gx--) { grid[gx] = []; gy = ngy; while (gy--) { grid[gx][gy] = true; } } twiceRender = true; for (var i_3 = 0; i_3 < settings.data.length; i_3++) { putWord(tslib_1.__assign(tslib_1.__assign({}, settings.data[i_3]), { twiceRender: twiceRender })); } } } } else { i = 0; var loopingFunction, stoppingFunction; if (settings.wait !== 0) { loopingFunction = window.setTimeout; stoppingFunction = window.clearTimeout; } else { loopingFunction = window.setImmediate; stoppingFunction = window.clearImmediate; } var addEventListener = function addEventListener(type, listener) { elements.forEach(function (el) { el.addEventListener(type, listener); }, this); }; var removeEventListener = function removeEventListener(type, listener) { elements.forEach(function (el) { el.removeEventListener(type, listener); }, this); }; var anotherWordCloudStart = function anotherWordCloudStart() { removeEventListener('wordcloudstart', anotherWordCloudStart); stoppingFunction(timer); }; addEventListener('wordcloudstart', anotherWordCloudStart); var timer = loopingFunction(function loop() { if (i >= settings.data.length) { stoppingFunction(timer); sendEvent('wordcloudstop', false); removeEventListener('wordcloudstart', anotherWordCloudStart); return; } escapeTime = new Date().getTime(); var drawn = putWord(settings.data[i]); var canceled = !sendEvent('wordclouddrawn', true, { item: settings.data[i], drawn: drawn, }); if (exceedTime() || canceled) { stoppingFunction(timer); settings.abort(); sendEvent('wordcloudabort', false); sendEvent('wordcloudstop', false); removeEventListener('wordcloudstart', anotherWordCloudStart); return; } i++; timer = loopingFunction(loop, settings.wait); }, settings.wait); } }; // All set, start the drawing start(); }; WordCloud.isSupported = isSupported; WordCloud.minFontSize = minFontSize; exports.default = WordCloud; },{"@antv/util":803,"tslib":894}],649:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var Marker = /** @class */ (function () { function Marker(cfg) { util_1.assign(this, cfg); this.init(); } Marker.prototype.destroy = function () { if (this.shape) { this.shape.destroy(); } }; Marker.prototype.update = function (cfg, duration, easing) { var updateCfg = {}; util_1.assign(this, cfg); this.coord = this.view.geometries[0].coordinate; if (cfg.value) { var x = this.coord.convert({ x: 0, y: this.value }).x; var matrix = [1, 0, 0, 0, 1, 0, x, 0, 1]; updateCfg.matrix = matrix; } if (cfg.style) { var shape = this.shape; var origin_attr = shape.attrs; var attrs = util_1.deepMix({}, origin_attr, cfg.style); updateCfg = util_1.deepMix({}, attrs, updateCfg); } this.shape.stopAnimate(); this.shape.animate(updateCfg, duration, easing); }; Marker.prototype.init = function () { this.coord = this.view.geometries[0].coordinate; this.container = this.view.foregroundGroup.addGroup(); var x = this.coord.convert({ x: 0, y: this.value }).x; // progress坐标系是转置坐标系 var y0 = this.coord.center.y - this.progressSize / 2 - 2; var y1 = this.coord.center.y + this.progressSize / 2 + 2; var style = util_1.deepMix({}, { stroke: 'grey', lineWidth: 1 }, this.style); this.shape = this.container.addShape('path', { attrs: tslib_1.__assign({ path: [ ['M', 0, y0], ['L', 0, y1], ] }, style), name: 'progress-marker', }); this.shape.move(x, 0); this.canvas.draw(); }; return Marker; }()); exports.default = Marker; },{"@antv/util":803,"tslib":894}],650:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { progress: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],651:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var Progress = /** @class */ (function (_super) { tslib_1.__extends(Progress, _super); function Progress() { return _super !== null && _super.apply(this, arguments) || this; } Progress.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'progress'; _super.prototype.createLayers.call(this, layerProps); }; Progress.prototype.update = function (value, style) { var layer = this.layers[0]; layer.update(value, style); }; Progress.getDefaultOptions = layer_1.default.getDefaultOptions; return Progress; }(plot_1.default)); exports.default = Progress; },{"../../base/plot":394,"./layer":652,"@antv/util":803,"tslib":894}],652:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var factory_1 = require("../../geoms/factory"); var tiny_layer_1 = tslib_1.__importDefault(require("../tiny-layer")); var marker_1 = tslib_1.__importDefault(require("./component/marker")); var EventParser = tslib_1.__importStar(require("./event")); var G2_GEOM_MAP = { progress: 'interval', }; var PLOT_GEOM_MAP = { interval: 'progress', }; var DEFAULT_COLOR = ['#55A6F3', '#E8EDF3']; var ProgressLayer = /** @class */ (function (_super) { tslib_1.__extends(ProgressLayer, _super); function ProgressLayer() { /** * 将进度条配置项转为堆叠条形图配置项 */ var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'progress'; _this.isEntered = false; return _this; } ProgressLayer.prototype.processProps = function () { var props = this.options; props.data = this.processData(); var cfg = { padding: [0, 0, 0, 0], xField: 'value', yField: '1', stackField: 'type', barSize: props.size ? props.size : this.getSize(), barStyle: props.progressStyle, color: this.parseColorProps(props) || DEFAULT_COLOR, }; props = util_1.mix(props, cfg); }; ProgressLayer.prototype.init = function () { this.processProps(); _super.prototype.init.call(this); }; ProgressLayer.prototype.beforeInit = function () { var percent = this.options.percent; if (!util_1.isNumber(percent)) { throw new Error('Percent value is required, and the type of percent must be Number.'); } }; ProgressLayer.prototype.update = function (cfg) { var props = this.options; if (util_1.hasKey(cfg, 'percent')) { props.percent = cfg.percent; this.changeData(this.processData()); } if (cfg.style) { this.styleUpdateAnimation(cfg.style); this.updateColorConfigByStyle(cfg.style); } if (cfg.color) { var style = void 0; if (util_1.isArray(cfg.color)) { this.options.color = cfg.color; style = [{ fill: cfg.color[0] }, { fill: cfg.color[1] }]; } else { this.options.color[0] = cfg.color; style = { fill: cfg.color }; } this.styleUpdateAnimation(style); } if (cfg.marker) { this.updateMarkers(cfg.marker); this.options.marker = cfg.marker; } }; ProgressLayer.prototype.destroy = function () { if (this.markers && this.markers.length > 0) { util_1.each(this.markers, function (marker) { marker.destroy(); }); this.markers = []; } _super.prototype.destroy.call(this); }; ProgressLayer.prototype.afterRender = function () { var _this = this; if (this.options.marker && !this.markers) { this.markers = []; util_1.each(this.options.marker, function (cfg) { var markerCfg = util_1.mix({ canvas: _this.canvas, view: _this.view, progressSize: _this.options.barSize, }, cfg); var marker = new marker_1.default(markerCfg); _this.markers.push(marker); }); } var progressContainer = this.view.geometries[0].container; var bbox = progressContainer.getBBox(); var rect = progressContainer.addShape('rect', { attrs: { width: bbox.width, height: bbox.height, x: bbox.minX, y: bbox.minY, fill: 'rgba(0,0,0,0)', }, }); this.canvas.draw(); rect.on('mouseenter', function (ev) { _this.isEntered = true; _this.view.emit('progress:mouseenter', ev); }); rect.on('mouseleave', function (ev) { _this.isEntered = false; _this.view.emit('progress:mouseleave', ev); }); var canvasDom = this.canvas.get('container'); canvasDom.addEventListener('mouseleave', function (ev) { if (_this.isEntered) { _this.view.emit('progress:mouseleave', ev); _this.isEntered = false; } }); }; ProgressLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; ProgressLayer.prototype.coord = function () { this.setConfig('coordinate', { actions: [['transpose']], }); }; ProgressLayer.prototype.addGeometry = function () { var props = this.options; var bar = factory_1.getGeom('interval', 'main', { positionFields: [props.yField, props.xField], plot: this, }); bar.adjust = [ { type: 'stack', }, ]; if (util_1.has(props, 'animation')) { bar.animate = props.animation; } this.setConfig('geometry', bar); }; ProgressLayer.prototype.parseEvents = function (eventParser) { if (eventParser) { _super.prototype.parseEvents.call(this, eventParser); } else { _super.prototype.parseEvents.call(this, EventParser); } }; ProgressLayer.prototype.parseColorProps = function (props) { var colorOption; if (props.color) { if (util_1.isFunction(props.color)) { colorOption = props.color(props.percent); } else { colorOption = props.color; } if (util_1.isString(colorOption)) { var color = util_1.clone(DEFAULT_COLOR); color[0] = colorOption; return color; } else { return colorOption; } } return props.color; }; ProgressLayer.prototype.processData = function () { var props = this.options; var data = [ { type: 'current', value: props.percent }, { type: 'rest', value: 1.0 - props.percent }, ]; return data; }; ProgressLayer.prototype.updateMarkers = function (markerCfg) { var markerLength = markerCfg.length; var animationOptions = this.getUpdateAnimationOptions(); // marker diff util_1.each(this.markers, function (marker, index) { if (index > markerLength - 1) { marker.destroy(); } else { marker.update(markerCfg[index], animationOptions.duration, animationOptions.easing); } }); // add new markers if (this.markers.length < markerLength) { var startIndex = this.markers.length; for (var i = startIndex; i < markerLength; i++) { var cfg = util_1.deepMix({}, { canvas: this.canvas, view: this.view, progressSize: this.options.barSize, }, markerCfg[i]); var marker = new marker_1.default(cfg); this.markers.push(marker); } } }; ProgressLayer.prototype.getSize = function () { var height = this.height; if (height >= 50) { return 10; } return 4; }; ProgressLayer.prototype.styleUpdateAnimation = function (style) { // style更新动画接受用户animation配置的透传 var _a = this.getUpdateAnimationOptions(), duration = _a.duration, easing = _a.easing; // get geometry shapes var progressShapes = []; var view = this.view; var geometry = view.geometries; util_1.each(geometry, function (geom) { if (geom.type === 'interval') { var elements = geom.elements; util_1.each(elements, function (ele) { progressShapes.push.apply(progressShapes, ele.shape); }); } }); if (util_1.isArray(style)) { util_1.each(style, function (s, index) { progressShapes[index].animate(s, duration, easing); }); } else { progressShapes[0].animate(style, duration, easing); } }; ProgressLayer.prototype.getUpdateAnimationOptions = function () { var duration = 450; var easing = 'easeQuadInOut'; var animationOptions = this.options.animation; if (animationOptions && animationOptions.update) { if (animationOptions.update.duration) { duration = animationOptions.update.duration; } if (animationOptions.update.easing) { easing = animationOptions.update.easing; } } return { duration: duration, easing: easing }; }; ProgressLayer.prototype.updateColorConfigByStyle = function (style) { var _this = this; if (util_1.isArray(style)) { util_1.each(style, function (s, index) { if (s.fill) { _this.options.color[index] = s.fill; } }); } else if (style.fill) { this.options.color[0] = style.fill; } }; return ProgressLayer; }(tiny_layer_1.default)); exports.default = ProgressLayer; global_1.registerPlotType('progress', ProgressLayer); },{"../../base/global":392,"../../geoms/factory":430,"../tiny-layer":662,"./component/marker":649,"./event":650,"@antv/util":803,"tslib":894}],653:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var componentMap = { ringProgress: 'interval', }; var SHAPE_EVENT_MAP = event_1.getEventMap(componentMap); util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],654:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var RingProgress = /** @class */ (function (_super) { tslib_1.__extends(RingProgress, _super); function RingProgress() { return _super !== null && _super.apply(this, arguments) || this; } RingProgress.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'ringProgress'; _super.prototype.createLayers.call(this, layerProps); }; RingProgress.prototype.update = function (value) { var layer = this.layers[0]; layer.update(value); }; RingProgress.getDefaultOptions = layer_1.default.getDefaultOptions; return RingProgress; }(plot_1.default)); exports.default = RingProgress; },{"../../base/plot":394,"./layer":655,"@antv/util":803,"tslib":894}],655:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var factory_1 = require("../../geoms/factory"); var layer_1 = tslib_1.__importDefault(require("../progress/layer")); var EventParser = tslib_1.__importStar(require("./event")); var DEFAULT_COLOR = ['#55A6F3', '#E8EDF3']; var RingProgressLayer = /** @class */ (function (_super) { tslib_1.__extends(RingProgressLayer, _super); function RingProgressLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'ringProgrsss'; return _this; } RingProgressLayer.prototype.processProps = function () { var props = this.options; props.data = this.processData(); var cfg = { padding: [0, 0, 0, 0], xField: 'value', yField: '1', stackField: 'type', barStyle: props.progressStyle, color: this.parseColorProps(props) || DEFAULT_COLOR, }; props = util_1.mix(props, cfg); }; RingProgressLayer.prototype.coord = function () { var coordConfig = { type: 'theta', cfg: { radius: 1.0, innerRadius: this.getThickness(this.options.size), }, }; this.setConfig('coordinate', coordConfig); }; RingProgressLayer.prototype.annotation = function () { return; }; RingProgressLayer.prototype.addGeometry = function () { var props = this.options; this.ring = factory_1.getGeom('interval', 'main', { positionFields: [props.yField, props.xField], plot: this, }); this.ring.adjust = [ { type: 'stack', }, ]; this.setConfig('geometry', this.ring); }; RingProgressLayer.prototype.animation = function () { this.ring.animate = { appear: { duration: 1000, }, }; }; RingProgressLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; RingProgressLayer.prototype.getThickness = function (value) { var width = this.width; var height = this.height; var size = Math.min(width, height); if (value) { return 1.0 - value / size; } if (size >= 60) { return 1.0 - 20 / size; } return 1.0 - 10 / size; }; return RingProgressLayer; }(layer_1.default)); exports.default = RingProgressLayer; global_1.registerPlotType('ringProgress', RingProgressLayer); },{"../../base/global":392,"../../geoms/factory":430,"../progress/layer":652,"./event":653,"@antv/util":803,"tslib":894}],656:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var SHAPE_EVENT_MAP = { onAreaClick: 'area:click', onAreaDblclick: 'area:dblclick', onAreaMousemove: 'area:mousemove', onAreaMousedown: 'area:mousedown', onAreaMouseup: 'area:mouseup', onAreaMouseenter: 'area:mouseenter', onAreaMouseleave: 'area:mouseleave', onAreaContextmenu: 'area:contextmenu', onLineClick: 'line:click', onLineDblclick: 'line:dblclick', onLineMousemove: 'line:mousemove', onLineMousedown: 'line:mousedown', onLineMouseup: 'line:mouseup', onLineMouseenter: 'line:mouseenter', onLineMouseleave: 'line:mouseleave', onLineContextmenu: 'line:contextmenu', }; util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],657:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var TinyArea = /** @class */ (function (_super) { tslib_1.__extends(TinyArea, _super); function TinyArea() { return _super !== null && _super.apply(this, arguments) || this; } TinyArea.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'tinyArea'; _super.prototype.createLayers.call(this, layerProps); }; TinyArea.getDefaultOptions = layer_1.default.getDefaultOptions; return TinyArea; }(plot_1.default)); exports.default = TinyArea; },{"../../base/plot":394,"./layer":658,"@antv/util":803,"tslib":894}],658:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var global_1 = require("../../base/global"); var factory_1 = require("../../geoms/factory"); var tiny_layer_1 = tslib_1.__importDefault(require("../tiny-layer")); var EventParser = tslib_1.__importStar(require("./event")); var GEOM_MAP = { area: 'area', line: 'line', }; var TinyAreaLayer = /** @class */ (function (_super) { tslib_1.__extends(TinyAreaLayer, _super); function TinyAreaLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'tinyArea'; return _this; } TinyAreaLayer.prototype.geometryParser = function (dim, type) { return GEOM_MAP[type]; }; TinyAreaLayer.prototype.addGeometry = function () { this.area = factory_1.getGeom('area', 'mini', { plot: this, }); this.setConfig('geometry', this.area); this.line = factory_1.getGeom('line', 'mini', { plot: this, }); this.setConfig('geometry', this.line); }; TinyAreaLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; return TinyAreaLayer; }(tiny_layer_1.default)); exports.default = TinyAreaLayer; global_1.registerPlotType('tinyArea', TinyAreaLayer); },{"../../base/global":392,"../../geoms/factory":430,"../tiny-layer":662,"./event":656,"tslib":894}],659:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var SHAPE_EVENT_MAP = { onColumnClick: 'interval:click', onColumnDblclick: 'interval:dblclick', onColumnMousemove: 'interval:mousemove', onColumnMousedown: 'interval:mousedown', onColumnMouseup: 'interval:mouseup', onColumnMouseenter: 'interval:mouseenter', onColumnMouseleave: 'interval:mouseleave', onColumnContextmenu: 'interval:contextmenu', }; util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],660:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var TinyColumn = /** @class */ (function (_super) { tslib_1.__extends(TinyColumn, _super); function TinyColumn() { return _super !== null && _super.apply(this, arguments) || this; } TinyColumn.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'tinyColumn'; _super.prototype.createLayers.call(this, layerProps); }; TinyColumn.getDefaultOptions = layer_1.default.getDefaultOptions; return TinyColumn; }(plot_1.default)); exports.default = TinyColumn; },{"../../base/plot":394,"./layer":661,"@antv/util":803,"tslib":894}],661:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var global_1 = require("../../base/global"); var factory_1 = require("../../geoms/factory"); var tiny_layer_1 = tslib_1.__importDefault(require("../tiny-layer")); var EventParser = tslib_1.__importStar(require("./event")); var WIDTH_RATIO = 0.6; var G2_GEOM_MAP = { column: 'interval', }; var PLOT_GEOM_MAP = { interval: 'column', }; var TinyColumnLayer = /** @class */ (function (_super) { tslib_1.__extends(TinyColumnLayer, _super); function TinyColumnLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'tinyColumn'; return _this; } TinyColumnLayer.prototype.init = function () { this.processProps(); _super.prototype.init.call(this); }; TinyColumnLayer.prototype.geometryParser = function (dim, type) { if (dim === 'g2') { return G2_GEOM_MAP[type]; } return PLOT_GEOM_MAP[type]; }; TinyColumnLayer.prototype.scale = function () { var options = this.options; var scales = {}; /** 配置x-scale */ scales[options.xField] = { type: 'cat' }; this.setConfig('scales', scales); }; TinyColumnLayer.prototype.addGeometry = function () { var props = this.options; var column = factory_1.getGeom('interval', 'main', { positionFields: [props.xField, props.yField], plot: this, }); this.setConfig('geometry', column); }; TinyColumnLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; TinyColumnLayer.prototype.processProps = function () { var cfg = { padding: [0, 0, 0, 0], columnSize: this.getSize(), }; this.options = util_1.mix(this.options, cfg); }; TinyColumnLayer.prototype.getSize = function () { var props = this.options; var columnNumber = this.getColumnNum(props.data, props.xField); var width = this.width; return (width / columnNumber) * WIDTH_RATIO; }; TinyColumnLayer.prototype.getColumnNum = function (data, field) { var values = []; util_1.each(data, function (d) { var v = d[field]; if (values.indexOf(v) < 0) { values.push(v); } }); return values.length; }; return TinyColumnLayer; }(tiny_layer_1.default)); exports.default = TinyColumnLayer; global_1.registerPlotType('tinyColumn', TinyColumnLayer); },{"../../base/global":392,"../../geoms/factory":430,"../tiny-layer":662,"./event":659,"@antv/util":803,"tslib":894}],662:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var view_layer_1 = tslib_1.__importDefault(require("../base/view-layer")); var factory_1 = require("../components/factory"); require("../geoms/line/mini"); var TinyLayer = /** @class */ (function (_super) { tslib_1.__extends(TinyLayer, _super); function TinyLayer() { return _super !== null && _super.apply(this, arguments) || this; } TinyLayer.getDefaultOptions = function () { return util_1.deepMix({}, _super.getDefaultOptions.call(this), { title: { visible: false, }, description: { visible: false, }, padding: [0, 0, 0, 0], legend: { visible: false, }, xAxis: { visible: false, }, yAxis: { visible: false, }, tooltip: { visible: false, }, }); }; TinyLayer.prototype.coord = function () { return; }; TinyLayer.prototype.addGeometry = function () { return; }; TinyLayer.prototype.annotation = function () { var _this = this; var props = this.options; var config = []; var defaultGuidelineCfg = { line: { style: { lineWidth: 1, stroke: '#66d6a8', }, }, }; util_1.each(props.guideLine, function (line) { var guideLine = factory_1.getComponent('guideLine', { plot: _this, cfg: util_1.deepMix({}, defaultGuidelineCfg, line), }); config.push(guideLine); }); this.setConfig('annotations', config); }; return TinyLayer; }(view_layer_1.default)); exports.default = TinyLayer; },{"../base/view-layer":395,"../components/factory":412,"../geoms/line/mini":437,"@antv/util":803,"tslib":894}],663:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.EVENT_MAP = void 0; var util_1 = require("@antv/util"); var event_1 = require("../../util/event"); Object.defineProperty(exports, "EVENT_MAP", { enumerable: true, get: function () { return event_1.EVENT_MAP; } }); Object.defineProperty(exports, "onEvent", { enumerable: true, get: function () { return event_1.onEvent; } }); var SHAPE_EVENT_MAP = { onLineClick: 'line:click', onLineDblclick: 'line:dblclick', onLineMousemove: 'line:mousemove', onLineMousedown: 'line:mousedown', onLineMouseup: 'line:mouseup', onLineMouseenter: 'line:mouseenter', onLineMouseleave: 'line:mouseleave', onLineContextmenu: 'line:contextmenu', }; util_1.assign(event_1.EVENT_MAP, SHAPE_EVENT_MAP); },{"../../util/event":677,"@antv/util":803}],664:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var plot_1 = tslib_1.__importDefault(require("../../base/plot")); var layer_1 = tslib_1.__importDefault(require("./layer")); var TinyLine = /** @class */ (function (_super) { tslib_1.__extends(TinyLine, _super); function TinyLine() { return _super !== null && _super.apply(this, arguments) || this; } TinyLine.prototype.createLayers = function (props) { var layerProps = util_1.deepMix({}, props); layerProps.type = 'tinyLine'; _super.prototype.createLayers.call(this, layerProps); }; TinyLine.getDefaultOptions = layer_1.default.getDefaultOptions; return TinyLine; }(plot_1.default)); exports.default = TinyLine; },{"../../base/plot":394,"./layer":665,"@antv/util":803,"tslib":894}],665:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var global_1 = require("../../base/global"); var factory_1 = require("../../geoms/factory"); var tiny_layer_1 = tslib_1.__importDefault(require("../tiny-layer")); var EventParser = tslib_1.__importStar(require("./event")); var GEOM_MAP = { line: 'line', }; var TinyLineLayer = /** @class */ (function (_super) { tslib_1.__extends(TinyLineLayer, _super); function TinyLineLayer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'tinyLine'; return _this; } TinyLineLayer.prototype.geometryParser = function (dim, type) { return GEOM_MAP[type]; }; TinyLineLayer.prototype.addGeometry = function () { this.line = factory_1.getGeom('line', 'mini', { plot: this, }); this.setConfig('geometry', this.line); }; TinyLineLayer.prototype.parseEvents = function () { _super.prototype.parseEvents.call(this, EventParser); }; return TinyLineLayer; }(tiny_layer_1.default)); exports.default = TinyLineLayer; global_1.registerPlotType('tinyLine', TinyLineLayer); },{"../../base/global":392,"../../geoms/factory":430,"../tiny-layer":662,"./event":663,"tslib":894}],666:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_DARK_THEME = void 0; var default_1 = require("./default"); exports.DEFAULT_DARK_THEME = { backgroundStyle: { fill: '#262626', }, defaultColor: '#5B8FF9', width: 400, height: 400, bleeding: [default_1.TOP_BLEEDING, 24, default_1.BOTTOM_BLEEDING, 24], padding: 'auto', title: { padding: [24, 24, 24, 24], fontFamily: 'PingFang SC', fontSize: 18, fontWeight: 'bold', fill: 'rgba(255,255,255,0.65)', stroke: 'rgba(0,0,0,0.95)', textAlign: 'left', textBaseline: 'top', lineHeight: 20, alignWithAxis: false, }, description: { padding: [10, 24, default_1.DESCRIPTION_BOTTOM_MARGIN, 24], fontFamily: 'PingFang SC', fontSize: 12, fill: 'rgba(255, 255, 255, 0.65)', stroke: 'rgba(0,0,0,0.95)', textAlign: 'left', textBaseline: 'top', lineHeight: 16, alignWithAxis: false, }, axis: { y: { visible: true, position: 'left', autoRotateTitle: true, grid: { visible: true, line: { style: { stroke: 'rgba(255, 255, 255, 0.15)', lineWidth: 1, lineDash: null, }, }, }, line: { visible: false, style: { stroke: 'rgba(255, 255, 255, 0.45)', lineWidth: 1, }, }, tickLine: { visible: false, style: { stroke: 'rgba(255, 255, 255, 0.45)', lineWidth: 0.5, length: 4, }, }, label: { visible: true, offset: 8, autoRotate: false, autoHide: true, textStyle: { fill: 'rgba(255, 255, 255, 0.45)', fontSize: 12, }, }, title: { visible: false, spacing: 12, style: { fill: 'rgba(255, 255, 255, 0.65)', fontSize: 12, textBaseline: 'bottom', }, }, }, x: { visible: true, position: 'bottom', autoRotateTitle: false, grid: { visible: false, line: { style: { stroke: 'rgba(255, 255, 255, 0.15)', lineWidth: 1, lineDash: null, }, }, }, line: { visible: false, style: { stroke: 'rgba(255, 255, 255, 0.45)', }, }, tickLine: { visible: true, style: { length: 4, stroke: 'rgba(255, 255, 255, 0.45)', lineWidth: 0.5, }, }, label: { visible: true, textStyle: { fill: 'rgba(255, 255, 255, 0.65)', fontSize: 12, }, offset: 16, autoHide: true, autoRotate: true, }, title: { visible: false, spacing: 12, style: { fill: 'rgba(255, 255, 255, 0.65)', fontSize: 12, }, }, }, circle: { autoRotateTitle: true, // gridType: 'line', grid: { style: { lineDash: null, lineWidth: 1, stroke: '#E3E8EC', }, }, line: { style: { lineWidth: 1, stroke: '#BFBFBF', }, }, tickLine: { style: { lineWidth: 1, stroke: '#bdc8d3', length: 4, alignWithLabel: true, }, }, label: { offset: 16, textStyle: { fill: '#a0a4aa', fontSize: 12, }, autoRotate: true, autoHide: true, }, title: { offset: 12, style: { fill: '#767b84', fontSize: 12 }, }, }, radius: { label: { offset: 12, textStyle: { fill: '#a0a4aa', fontSize: 12, }, }, }, }, legend: { flipPage: false, position: 'bottom', // 距离panelRange的距离 innerPadding: [16, 16, 16, 16], title: { visible: false, style: { fill: '#bdc8d3', }, }, text: { style: { fill: '#bdc8d3', }, }, }, label: { offset: 12, textStyle: { fill: 'rgba(255, 255, 255, 0.65)', }, style: { fill: 'rgba(255, 255, 255, 0.65)', lineWidth: 1, }, }, components: { tooltip: { domStyles: { 'g2-tooltip': { backgroundColor: 'rgba(33,33,33, 0.95)', boxShadow: '0px 0px 8px rgba(0,0,0,0.65)', color: 'rgba(255, 255, 255, 0.65)', }, }, }, }, }; },{"./default":667}],667:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_GLOBAL_THEME = exports.BOTTOM_BLEEDING = exports.TOP_BLEEDING = exports.DESCRIPTION_BOTTOM_MARGIN = exports.COLOR_PLATE_20 = exports.COLOR_PLATE_10 = void 0; var COLOR = '#5B8FF9'; exports.COLOR_PLATE_10 = [ '#5B8FF9', '#5AD8A6', '#5D7092', '#F6BD16', '#E8684A', '#6DC8EC', '#9270CA', '#FF9D4D', '#269A99', '#FF99C3', ]; exports.COLOR_PLATE_20 = [ '#5B8FF9', '#BDD2FD', '#5AD8A6', '#BDEFDB', '#5D7092', '#C2C8D5', '#F6BD16', '#FBE5A2', '#E8684A', '#F6C3B7', '#6DC8EC', '#B6E3F5', '#9270CA', '#D3C6EA', '#FF9D4D', '#FFD8B8', '#269A99', '#AAD8D8', '#FF99C3', '#FFD6E7', ]; var util_1 = require("@antv/util"); exports.DESCRIPTION_BOTTOM_MARGIN = function (legendPosition) { if (legendPosition && legendPosition.split('-')[0] === 'top') { return 12; } return 24; }; exports.TOP_BLEEDING = function (props) { var titleVisible = props.title && props.title.visible; var descriptionVisible = props.description && props.description.visible; if (titleVisible || descriptionVisible) { // 由 title/description 的 bottom-padding 负责 return 12; } return 24; }; exports.BOTTOM_BLEEDING = function (props) { if (util_1.some(props.interactions || [], function (interaction) { return (interaction.type === 'slider' || interaction.type === 'scrollbar') && (interaction.cfg && interaction.cfg.type) !== 'vertical'; })) { return 8; } return 24; }; exports.DEFAULT_GLOBAL_THEME = { width: 400, height: 400, bleeding: [exports.TOP_BLEEDING, 24, exports.BOTTOM_BLEEDING, 24], padding: 'auto', defaultColor: COLOR, colors: exports.COLOR_PLATE_10, colors_20: exports.COLOR_PLATE_20, title: { padding: [24, 24, 24, 24], fontFamily: 'PingFang SC', fontSize: 18, fill: 'black', textAlign: 'left', textBaseline: 'top', lineHeight: 20, alignWithAxis: false, }, description: { padding: [10, 24, exports.DESCRIPTION_BOTTOM_MARGIN, 24], fontFamily: 'PingFang SC', fontSize: 12, fill: 'grey', textAlign: 'left', textBaseline: 'top', lineHeight: 16, alignWithAxis: false, }, axis: { y: { visible: true, position: 'left', autoRotateTitle: true, grid: { visible: true, line: { style: { stroke: 'rgba(0, 0, 0, 0.15)', lineWidth: 1, lineDash: [0, 0], }, }, }, line: { visible: false, style: { stroke: 'rgba(0, 0, 0, 0.45)', lineWidth: 1, }, }, tickLine: { visible: false, style: { stroke: 'rgba(0,0,0,0.45)', lineWidth: 0.5, length: 4, }, }, label: { visible: true, offset: 8, textStyle: { fill: 'rgba(0,0,0,0.45)', fontSize: 12, }, autoRotate: false, autoHide: true, }, title: { visible: false, spacing: 12, style: { fill: 'rgba(0, 0, 0, 0.65)', fontSize: 12, textBaseline: 'bottom', }, }, }, x: { visible: true, position: 'bottom', autoRotateTitle: false, grid: { visible: false, line: { style: { stroke: 'rgba(0, 0, 0, 0.15)', lineWidth: 1, lineDash: [0, 0], }, }, }, line: { visible: false, style: { stroke: 'rgba(0, 0, 0, 0.45)', lineWidth: 1, }, }, tickLine: { visible: true, style: { length: 4, stroke: 'rgba(0, 0, 0, 0.45)', lineWidth: 0.5, }, }, label: { visible: true, textStyle: { fill: 'rgba(0,0,0,0.45)', fontSize: 12, }, offset: 16, autoRotate: true, autoHide: true, }, title: { visible: false, spacing: 12, style: { fill: 'rgba(0, 0, 0, 0.65)', fontSize: 12 }, }, }, circle: { autoHideLabel: false, // gridType: 'line', grid: { line: { style: { lineDash: null, lineWidth: 1, stroke: 'rgba(0, 0, 0, 0.15)', }, }, }, line: { style: { lineWidth: 1, stroke: 'rgba(0, 0, 0, 0.45)', }, }, tickLine: { style: { lineWidth: 1, stroke: 'rgba(0, 0, 0, 0.45)', length: 4, alignWithLabel: true, }, }, label: { offset: 16, textStyle: { fill: 'rgba(0,0,0,0.45)', fontSize: 12, }, autoRotate: true, autoHide: true, }, title: { offset: 12, style: { fill: 'rgba(0, 0, 0, 0.65)', fontSize: 12 }, }, }, radius: { label: { textStyle: { fill: 'rgba(0,0,0,0.45)', fontSize: 12, }, }, }, }, legend: { flipPage: false, position: 'bottom', // 距离panelRange的距离 innerPadding: [16, 16, 16, 16], margin: [0, 24, 24, 24], }, label: { offset: 12, textStyle: { fill: '#595959', }, style: { fill: '#595959', stroke: '#ffffff', lineWidth: 2, }, }, tooltip: { 'g2-tooltip': { boxShadow: '0px 0px 8px rgba(0,0,0,0.15)', }, offset: 10, }, // G2Plot 组件主题配置 components: { legend: { margin: [0, 24, 24, 24], }, tooltipIndicator: { title: { style: { fontSize: 14, fill: '#262626', }, }, line: { style: { opacity: 1, }, inactiveStyle: { opacity: 0.3, }, }, itemTitle: { style: { fontSize: 12, fill: '#8C8C8C', opacity: 1, }, inactiveStyle: { opacity: 0.3, }, }, itemName: { style: { fontSize: 12, fill: '#8C8C8C', opacity: 1, }, inactiveStyle: { opacity: 0.3, }, }, itemValue: { style: { fontSize: 14, fontWeight: 'bold', fill: '#595959', opacity: 1, }, inactiveStyle: { opacity: 0.3, }, }, }, }, }; },{"@antv/util":803}],668:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getGlobalTheme = exports.registerGlobalTheme = void 0; var util_1 = require("@antv/util"); var default_1 = require("./default"); var dark_1 = require("./dark"); /** 所有的全局主题 */ var GLOBAL_THEME_MAP = { default: default_1.DEFAULT_GLOBAL_THEME, dark: dark_1.DEFAULT_DARK_THEME, }; /** * 注册全局主题 * @param name * @param theme */ function registerGlobalTheme(name, theme) { var defaultTheme = getGlobalTheme(); GLOBAL_THEME_MAP[name.toLowerCase()] = util_1.deepMix({}, defaultTheme, theme); } exports.registerGlobalTheme = registerGlobalTheme; /** * 获取默认主题 * @param name 如果 name 为空,则返回默认的主题,否则返回指定 name 的主题 */ function getGlobalTheme(name) { if (name === void 0) { name = 'default'; } var theme = GLOBAL_THEME_MAP[name.toLowerCase()]; if (theme) { return theme; } // 如没有找到,则使用当前全局主题替代 console.warn("error in theme: Can't find the theme named %s. Please register theme first.", name); return default_1.DEFAULT_GLOBAL_THEME; } exports.getGlobalTheme = getGlobalTheme; },{"./dark":666,"./default":667,"@antv/util":803}],669:[function(require,module,exports){ "use strict"; // // defaultTheme 必须首先注册 // import defaultTheme from './default'; // // import Theme from './theme'; // // export { Theme as default, defaultTheme }; Object.defineProperty(exports, "__esModule", { value: true }); // 全局主题的方法 var global_1 = require("./global"); Object.defineProperty(exports, "getGlobalTheme", { enumerable: true, get: function () { return global_1.getGlobalTheme; } }); Object.defineProperty(exports, "registerGlobalTheme", { enumerable: true, get: function () { return global_1.registerGlobalTheme; } }); // 图表主题的方法 var theme_1 = require("./theme"); Object.defineProperty(exports, "getTheme", { enumerable: true, get: function () { return theme_1.getTheme; } }); Object.defineProperty(exports, "registerTheme", { enumerable: true, get: function () { return theme_1.registerTheme; } }); // 工具函数 var utils_1 = require("./utils"); Object.defineProperty(exports, "convertToG2Theme", { enumerable: true, get: function () { return utils_1.convertToG2Theme; } }); },{"./global":668,"./theme":670,"./utils":671}],670:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTheme = exports.registerTheme = exports.convertThemeToG2Theme = void 0; var util_1 = require("@antv/util"); /** * 所有的 plot theme object,每个图类型只会存在一个 theme */ var PLOT_THEME_MAP = {}; /** * 将 主题 转换为 G2 主题配置 * @param type plotType */ function convertThemeToG2Theme(type /** plot style */, theme) { var styleMapShape = { lineStyle: 'line.line', columnStyle: 'interval.rect', pointStyle: 'point.circle', }; var g2Theme = {}; if (type === 'area') { styleMapShape = { areaStyle: 'area.area', lineStyle: 'area.line', pointStyle: 'point.circle', }; } var geometryTheme = {}; util_1.each(theme, function (style, styleKey) { var _a; if (util_1.has(styleMapShape, styleKey)) { var shapePath_1 = styleMapShape[styleKey]; util_1.each(style, function (v, k) { util_1.set(geometryTheme, shapePath_1 + "." + [k === 'normal' ? 'default' : k === 'disable' ? 'inactive' : k] + ".style", v); }); } else { /** styleMap 找不到,直接放入 G2 theme */ g2Theme = util_1.deepMix({}, g2Theme, (_a = {}, _a[styleKey] = style, _a)); } }); if (!util_1.isEmpty(geometryTheme)) { g2Theme = util_1.deepMix({}, g2Theme, { geometries: geometryTheme }); } return g2Theme; } exports.convertThemeToG2Theme = convertThemeToG2Theme; /** * 注册新的图表主题 * @param type * @param theme */ function registerTheme(type, theme) { PLOT_THEME_MAP[type.toLowerCase()] = convertThemeToG2Theme(type, theme); } exports.registerTheme = registerTheme; /** * 根据类型获取主题 * @param type plotType, such as line, column, bar, pie, bullet, radar and so on */ function getTheme(type) { return PLOT_THEME_MAP[type.toLowerCase()] || {}; } exports.getTheme = getTheme; },{"@antv/util":803}],671:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertToG2Theme = void 0; var util_1 = require("@antv/util"); /** * mutable 的方式修改 axis 配置 * @param axis */ // function convertToG2Axis(axis: any): void { // if (axis.line && axis.line.style) { // const lineStyle = axis.line.style; // delete axis.line.style; // mix(axis.line, lineStyle); // } // if (axis.tickLine) { // const tickLineStyle = axis.tickLine.style; // delete axis.tickLine.style; // mix(axis.tickLine, tickLineStyle); // } // if (axis.grid) { // const gridStyle = axis.grid.style; // delete axis.grid.style; // mix(axis.grid, gridStyle); // } // if (axis.label) { // if (axis.label.style) { // axis.label.textStyle = axis.label.style; // delete axis.label.style; // } // } // if (axis.title) { // if (axis.title.style) { // axis.title.textStyle = axis.title.style; // delete axis.title.style; // } // } // } /** * 将图形主题转换成 g2 theme 格式 * @param plotTheme */ function convertToG2Theme(plotTheme) { var g2Theme = util_1.clone(plotTheme); /** tempo: legend margin设置为0 */ if (!g2Theme.legend) { g2Theme.legend = {}; } return g2Theme; } exports.convertToG2Theme = convertToG2Theme; },{"@antv/util":803}],672:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var bbox_1 = require("@antv/g2/lib/util/bbox"); var constant_1 = require("@antv/g2/lib/constant"); Object.defineProperty(exports, "DIRECTION", { enumerable: true, get: function () { return constant_1.DIRECTION; } }); var BBox = /** @class */ (function (_super) { tslib_1.__extends(BBox, _super); function BBox() { return _super !== null && _super.apply(this, arguments) || this; } BBox.fromBBoxObject = function (bbox) { return new BBox(bbox.x, bbox.y, bbox.width, bbox.height); }; return BBox; }(bbox_1.BBox)); exports.default = BBox; },{"@antv/g2/lib/constant":237,"@antv/g2/lib/util/bbox":370,"tslib":894}],673:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isContrastColorWhite = exports.mappingColor = exports.arr2rgb = exports.toHex = exports.rgb2arr = void 0; var util_1 = require("@antv/util"); function rgb2arr(str) { var colorStr = str.indexOf('#') === 0 ? str.substr(1) : str; var arr = []; arr.push(parseInt(colorStr.substr(0, 2), 16)); arr.push(parseInt(colorStr.substr(2, 2), 16)); arr.push(parseInt(colorStr.substr(4, 2), 16)); return arr; } exports.rgb2arr = rgb2arr; function toHex(value) { var v; v = Math.round(value); v = v.toString(16); if (v.length === 1) { v = "0" + value; } return v; } exports.toHex = toHex; function arr2rgb(arr) { return "#" + (toHex(arr[0]) + toHex(arr[1]) + toHex(arr[2])); } exports.arr2rgb = arr2rgb; function mappingColor(band, gray) { var reflect; util_1.each(band, function (b) { var map = b; if (gray >= map.from && gray < map.to) { reflect = map.color; } }); return reflect; } exports.mappingColor = mappingColor; // 根据YIQ亮度判断指定颜色取反色是不是白色 // http://24ways.org/2010/calculating-color-contrast exports.isContrastColorWhite = function (rgb) { var _a = rgb2arr(rgb), r = _a[0], g = _a[1], b = _a[2]; var isDark = (r * 299 + g * 587 + b * 114) / 1000 < 128; return isDark; }; },{"@antv/util":803}],674:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isMobile = exports.isBBoxIntersect = exports.sortedLastIndex = exports.getLegendShapes = exports.getAxisShapes = exports.getLegendComponents = exports.getAxisComponents = exports.breakText = exports.isTextUsable = void 0; var tslib_1 = require("tslib"); var dependents_1 = require("../dependents"); /** * 判断text是否可用, title description * * @param source */ function isTextUsable(source) { if (!source) return false; if (source.visible === true && typeof source.text === 'string' && source.text.trim()) return true; return false; } exports.isTextUsable = isTextUsable; /** * 为字符串添加换行符 * @param source - 字符串数组 ['a', 'b', 'c'] * @param breaks - 要添加换行的index * * @example * ```js * breakText(['a','b','c'], [1]) * * // a\nbc * ``` */ function breakText(source, breaks) { var result = tslib_1.__spreadArrays(source); breaks.forEach(function (pos, index) { result.splice(pos + index, 0, '\n'); }); return result.join(''); } exports.breakText = breakText; /** * 获取 View 中所有的 Axis 组件 */ function getAxisComponents(view) { return view .getComponents() .filter(function (co) { return co.type === dependents_1.COMPONENT_TYPE.AXIS; }) .map(function (co) { return co.component; }); } exports.getAxisComponents = getAxisComponents; function getLegendComponents(view) { return view .getComponents() .filter(function (co) { return co.type === dependents_1.COMPONENT_TYPE.LEGEND; }) .map(function (co) { return co.component; }); } exports.getLegendComponents = getLegendComponents; function getAxisShapes(view) { var axisShape = view.backgroundGroup.findAll(function (el) { if (el.get('name')) { var name_1 = el.get('name').split('-'); return name_1[0] === 'axis'; } }); return axisShape; } exports.getAxisShapes = getAxisShapes; function getLegendShapes(view) { var axisShape = view.foregroundGroup.findAll(function (el) { if (el.get('name')) { return el.get('name') === 'legend-item-group'; } }); return axisShape; } exports.getLegendShapes = getLegendShapes; function sortedLastIndex(arr, val) { var i = arr.length; while (i > 0) { if (val >= arr[i - 1]) { break; } i -= 1; } return i; } exports.sortedLastIndex = sortedLastIndex; /* 检测两个label包围盒是否重叠 */ function isBBoxIntersect(bboxA, bboxB) { if (bboxA.maxY < bboxB.minY || bboxB.maxY < bboxA.minY) { return false; } if (bboxA.maxX < bboxB.minX || bboxB.maxX < bboxA.minX) { return false; } return true; } exports.isBBoxIntersect = isBBoxIntersect; /** * 判断是否移动端环境 */ function isMobile() { return !!navigator.userAgent.match(/(Mobile)|(Android)|(WebOS)|(iPhone)|(iPad)/); } exports.isMobile = isMobile; },{"../dependents":425,"tslib":894}],675:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformDataPercentage = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); exports.transformDataPercentage = function (data, groupField, measures) { // 按照groupBy字段计算各个group的总和 var chain = util_1.groupBy(data, groupField); chain = util_1.mapValues(chain, function (items) { return util_1.map(items, function (item) { return util_1.map(measures, function (field) { return item[field]; }); }); }); chain = util_1.mapValues(chain, util_1.flatten); chain = util_1.mapValues(chain, function (vals) { return util_1.map(vals, function (val) { // @ts-ignore var v = Number.parseFloat(val); if (!util_1.isNumber(v) || isNaN(v)) { return 0; } return v; }); }); // @ts-ignore var groupTotals = util_1.mapValues(chain, function (vals) { return util_1.reduce(vals, function (sum, val) { return sum + val; }, 0); }); // 覆盖measures字段的值为对于的百分比 var newData = util_1.map(data, function (item) { // @ts-ignore var rst = tslib_1.__assign(tslib_1.__assign({}, item), { _origin: item, total: groupTotals[item[groupField]] }); util_1.each(measures, function (field) { // @ts-ignore rst[field] = item[field] / (groupTotals[item[groupField]] || 1); }); return rst; }); // 检查精度,确保总和为1 util_1.each(util_1.groupBy(newData, groupField), function (items) { var sum = 0; util_1.each(items, function (item, itemIdx) { util_1.each(measures, function (field, fieldIdx) { // @ts-ignore if (sum + item[field] >= 1 || (itemIdx === items.length - 1 && fieldIdx === measures.length - 1 && sum > 0)) { item[field] = 1 - sum; } // @ts-ignore sum += item[field]; }); }); }); // @ts-ignore return newData; }; },{"@antv/util":803,"tslib":894}],676:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.advanceBy = exports.getDay = exports.getWeek = exports.isLastDayOfMonth = exports.isLastWeekOfMonth = exports.getYearRange = exports.getDateRange = exports.DAY_MS = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var fecha_1 = tslib_1.__importDefault(require("fecha")); var constant_1 = require("../plots/calendar/constant"); /** * 一天多少 ms */ exports.DAY_MS = 86400000; /** * 获取最大最小日期范围 * @param dates */ function getDateRange(dates) { var ds = tslib_1.__spreadArrays(dates).sort(function (a, b) { return a.getTime() - b.getTime(); }); return [fecha_1.default.format(util_1.head(ds), constant_1.FORMATTER), fecha_1.default.format(util_1.last(ds), constant_1.FORMATTER)]; } exports.getDateRange = getDateRange; /** * 日期对应年的范围 * @param date */ function getYearRange(date) { var curr = date ? date : new Date(); return [ fecha_1.default.format(new Date(curr.getFullYear(), 0, 1), constant_1.FORMATTER), fecha_1.default.format(new Date(curr.getFullYear(), 11, 30), constant_1.FORMATTER), ]; } exports.getYearRange = getYearRange; /** * 是否当前月的最后一周 */ function isLastWeekOfMonth(date) { // 偏移 7 天之后,月份是否一样 return date.getMonth() !== advanceBy(new Date(date), 7 * exports.DAY_MS).getMonth(); } exports.isLastWeekOfMonth = isLastWeekOfMonth; /** * 是否是当月的最后一天 */ function isLastDayOfMonth(date) { // 偏移 1 天之后,月份是否一样 return date.getMonth() !== advanceBy(new Date(date), exports.DAY_MS).getMonth(); } exports.isLastDayOfMonth = isLastDayOfMonth; /** * 获取 date 对应的周索引(国际标准:一年的第一个周四为第一周) * @param date */ function getWeek(date) { // 当年的第一天 var oneJan = new Date(date.getFullYear(), 0, 1); return Math.ceil(((date.getTime() - oneJan.getTime()) / exports.DAY_MS + oneJan.getDay() + 1) / 7); } exports.getWeek = getWeek; /** * 获得一周的第几天(周日第 0 天) * @param date */ function getDay(date) { return date.getDay(); } exports.getDay = getDay; /** * 将 Date 前进 ms 时间 * @param d * @param ms */ function advanceBy(d, ms) { d.setMilliseconds(d.getMilliseconds() + ms); return d; } exports.advanceBy = advanceBy; },{"../plots/calendar/constant":476,"@antv/util":803,"fecha":881,"tslib":894}],677:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.onEvent = exports.LAYER_EVENT_MAP = exports.CANVAS_EVENT_MAP = exports.EVENT_MAP = exports.getMobileEventMap = exports.getRegionEventMap = exports.getEventMap = void 0; var util_1 = require("@antv/util"); var eventNames = [ 'click', 'dblclick', 'mousemove', 'mouseenter', 'mouseleave', 'mousedown', 'mouseup', 'contextmenu', ]; var mobileEventNames = [ /*'touchstart', 'touchmove', 'touchend', 'pressstart', 'press', 'pressend', 'swipestart', 'swipe', 'swipeend', 'pinchstart', 'pinch', 'pinchend', 'panstart', 'pan', 'panend',*/ ]; var viewComponentMap = { axis: 'axis-label', label: 'label', legend: 'legend-item', }; var canvasComponentMap = { title: 'title', description: 'description', breadcrumb: 'breadcrumb', }; var CANVAS_EVENT_MAP = util_1.deepMix(getEventMap(canvasComponentMap), getRegionEventMap('Plot', eventNames)); exports.CANVAS_EVENT_MAP = CANVAS_EVENT_MAP; var LAYER_EVENT_MAP = getRegionEventMap('Layer', eventNames); exports.LAYER_EVENT_MAP = LAYER_EVENT_MAP; //移动端事件暂时只支持view级 var EVENT_MAP = util_1.deepMix({}, getEventMap(viewComponentMap), getRegionEventMap('View', eventNames), getMobileEventMap()); exports.EVENT_MAP = EVENT_MAP; function onEvent(layer, eventName, handler) { layer.view.on(eventName, function (ev) { var eventData = { x: ev === null || ev === void 0 ? void 0 : ev.x, y: ev === null || ev === void 0 ? void 0 : ev.y, clientX: ev === null || ev === void 0 ? void 0 : ev.clientX, clientY: ev === null || ev === void 0 ? void 0 : ev.clientY, target: ev === null || ev === void 0 ? void 0 : ev.target, data: (ev === null || ev === void 0 ? void 0 : ev.data) ? ev.data.data : null, plot: layer, canvas: layer.canvas, gEvent: ev === null || ev === void 0 ? void 0 : ev.gEvent, }; handler(eventData); }); } exports.onEvent = onEvent; function getEventMap(map) { var eventMap = {}; util_1.each(map, function (item, key) { var componentName = util_1.upperFirst(key); var namePrefix = "on" + componentName; var eventPrefix = item + ":"; util_1.each(eventNames, function (name) { var eventName = util_1.upperFirst(name); var eventKey = "" + namePrefix + eventName; var event = "" + eventPrefix + name; eventMap[eventKey] = event; }); }); return eventMap; } exports.getEventMap = getEventMap; function getRegionEventMap(prefix, eventList) { var eventMap = {}; var namePrefix = "on"; util_1.each(eventList, function (name) { var eventName = util_1.upperFirst(name); var eventKey = "" + namePrefix + prefix + eventName; eventMap[eventKey] = name; }); return eventMap; } exports.getRegionEventMap = getRegionEventMap; function getMobileEventMap() { var eventMap = {}; var namePrefix = "on"; util_1.each(mobileEventNames, function (name) { var eventName = util_1.upperFirst(name); var eventKey = "" + namePrefix + eventName; eventMap[eventKey] = name; }); return eventMap; } exports.getMobileEventMap = getMobileEventMap; },{"@antv/util":803}],678:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSuffixFormatter = exports.getPrecisionFormatter = exports.getNoopFormatter = exports.combineFormatter = void 0; var util_1 = require("@antv/util"); exports.combineFormatter = function () { var formatters = []; for (var _i = 0; _i < arguments.length; _i++) { formatters[_i] = arguments[_i]; } return function (text, item, idx) { return formatters.reduce(function (curText, formatter) { return formatter(curText, item, idx); }, text); }; }; exports.getNoopFormatter = function () { return function (text) { return text; }; }; exports.getPrecisionFormatter = function (precision) { return function (text) { var num = Number(text); return isNaN(num) || util_1.isNil(precision) ? text : num.toFixed(precision); }; }; exports.getSuffixFormatter = function (suffix) { return function (text) { return util_1.isNil(suffix) ? text : text + " " + suffix; }; }; },{"@antv/util":803}],679:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rotate = exports.translate = exports.move = exports.transform = exports.groupTransform = void 0; var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); var dependents_1 = require("../dependents"); function groupTransform(group, actions) { var ulMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; var matrix = matrix_util_1.ext.transform(ulMatrix, actions); group.setMatrix(matrix); } exports.groupTransform = groupTransform; function transform(actions, matrix) { var ulMatrix = matrix ? util_1.clone(matrix) : [1, 0, 0, 0, 1, 0, 0, 0, 1]; return matrix_util_1.ext.transform(ulMatrix, actions); } exports.transform = transform; function move(element, x, y, matrix) { var ulMatrix = matrix ? util_1.clone(matrix) : [1, 0, 0, 0, 1, 0, 0, 0, 1]; ulMatrix[6] = x; ulMatrix[7] = y; element.setMatrix(ulMatrix); } exports.move = move; function translate(element, x, y) { dependents_1.Util.translate(element, x, y); } exports.translate = translate; function rotate(element, radian) { dependents_1.Util.rotate(element, radian); } exports.rotate = rotate; },{"../dependents":425,"@antv/matrix-util":717,"@antv/util":803}],680:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStrokePoints = exports.dist2 = exports.sturges = exports.getMean = exports.getMedian = exports.lineSimplification = exports.angleTo = exports.sub2D = exports.crossProduct3D = exports.crossProduct2D = exports.dotProduct2D = exports.bboxOnRotate = exports.minDistBetweenConvexPolygon = exports.isPolygonIntersection = exports.distBetweenPointLine = exports.distBetweenPoints = exports.isPointInPolygon = exports.getLineIntersect = exports.isBetween = exports.applyMatrix = void 0; var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); function magnitude(v) { var sum = 0; util_1.each(v, function (value) { sum += value * value; }); return Math.sqrt(sum); } function dotProduct2D(va, vb) { return va.x * vb.y + va.y * vb.x; } exports.dotProduct2D = dotProduct2D; function angleTo(va, vb) { var magA = magnitude(va); var magB = magnitude(vb); var dot = dotProduct2D(va, vb); var angle = Math.acos(dot / magA / magB); return angle; } exports.angleTo = angleTo; function crossProduct2D(va, vb) { var magA = magnitude(va); var magB = magnitude(vb); var dot = dotProduct2D(va, vb); var angle = Math.acos(dot / magA / magB); return magA * magB * Math.sin(angle); } exports.crossProduct2D = crossProduct2D; function crossProduct3D(va, vb) { var ax = va.x, ay = va.y, az = va.z; var bx = vb.x, by = vb.y, bz = vb.z; var x = ay * bz - az * by; var y = az * bx - ax * bz; var z = ax * by - ay * bx; return { x: x, y: y, z: z }; } exports.crossProduct3D = crossProduct3D; function sub2D(va, vb) { return { x: va.x - vb.x, y: va.y - vb.y }; } exports.sub2D = sub2D; function applyMatrix(point, matrix, tag) { if (tag === void 0) { tag = 1; } var vector = [point.x, point.y, tag]; matrix_util_1.vec3.transformMat3(vector, vector, matrix); return { x: vector[0], y: vector[1], }; } exports.applyMatrix = applyMatrix; function isBetween(value, min, max) { return value >= min && value <= max; } exports.isBetween = isBetween; var tolerance = 0.001; function getLineIntersect(p0, p1, p2, p3) { var E = { x: p2.x - p0.x, y: p2.y - p0.y, }; var D0 = { x: p1.x - p0.x, y: p1.y - p0.y, }; var D1 = { x: p3.x - p2.x, y: p3.y - p2.y, }; var kross = D0.x * D1.y - D0.y * D1.x; var sqrKross = kross * kross; var sqrLen0 = D0.x * D0.x + D0.y * D0.y; var sqrLen1 = D1.x * D1.x + D1.y * D1.y; var point = null; if (sqrKross > tolerance * sqrLen0 * sqrLen1) { var s = (E.x * D1.y - E.y * D1.x) / kross; var t = (E.x * D0.y - E.y * D0.x) / kross; if (isBetween(s, 0, 1) && isBetween(t, 0, 1)) { point = { x: p0.x + s * D0.x, y: p0.y + s * D0.y, }; } } return point; } exports.getLineIntersect = getLineIntersect; function isPointInPolygon(p, polygon) { /** 射线法 */ var inside = false; for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { var xi = polygon[i].x; var yi = polygon[i].y; var xj = polygon[j].x; var yj = polygon[j].y; var intersect = yi > p.y !== yj > p.y && p.x <= ((xj - xi) * (p.y - yi)) / (yj - yi) + xi; if (intersect) { inside = !inside; } } return inside; } exports.isPointInPolygon = isPointInPolygon; function sqr(v) { return v * v; } function dist2(a, b) { return Math.sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } exports.dist2 = dist2; function distBetweenPoints(a, b) { return Math.sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } exports.distBetweenPoints = distBetweenPoints; function distBetweenPointLine(p, p1, p2) { var l2 = dist2(p1, p2); if (l2 === 0) { return dist2(p, p1); } var t = ((p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y) * (p2.y - p1.y)) / l2; t = Math.max(0, Math.min(1, t)); var distSquare = dist2(p, { x: p1.x + t * (p2.x - p1.x), y: p1.y + t * (p2.y - p1.y) }); return Math.sqrt(distSquare); } exports.distBetweenPointLine = distBetweenPointLine; // todo:待优化 https://blog.csdn.net/WilliamSun0122/article/details/77994526 function minDistBetweenPointPolygon(p, polygon) { var min = Infinity; /** vertice to vertice */ util_1.each(polygon, function (v) { var dist = Math.sqrt(dist2(v, p)); if (min > dist) { min = dist; } }); /** vertice to edge */ for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { var xi = polygon[i].x; var yi = polygon[i].y; var xj = polygon[j].x; var yj = polygon[j].y; var dist = distBetweenPointLine(p, { x: xi, y: yi }, { x: xj, y: yj }); if (min > dist) { min = dist; } } return min; } function isPolygonIntersection(polyA, polyB) { for (var _i = 0, polyA_1 = polyA; _i < polyA_1.length; _i++) { var p = polyA_1[_i]; var inside = isPointInPolygon(p, polyB); if (inside) { return true; } } return false; } exports.isPolygonIntersection = isPolygonIntersection; function minDistBetweenConvexPolygon(polyA, polyB) { if (isPolygonIntersection(polyA, polyB)) { return 0; } var minA = Infinity; var minB = Infinity; util_1.each(polyA, function (v) { var localMin = minDistBetweenPointPolygon(v, polyB); if (minA > localMin) { minA = localMin; } }); util_1.each(polyB, function (v) { var localMin = minDistBetweenPointPolygon(v, polyA); if (minB > localMin) { minB = localMin; } }); return Math.min(minA, minB); } exports.minDistBetweenConvexPolygon = minDistBetweenConvexPolygon; function bboxOnRotate(shape) { var bbox = shape.getBBox(); var x = bbox.minX; var y = bbox.minY; /* * step1: 获得旋转后的shape包围盒 * 将包围盒对齐到原点,apply旋转矩阵 * 移回原来的位置 */ var bboxWidth = bbox.maxX - bbox.minX; var bboxHeight = bbox.maxY - bbox.minY; // const matrix = shape.getTotalMatrix(); var matrix = shape.attr('matrix'); var ulMatrix; if (matrix) { ulMatrix = [matrix[0], matrix[1], 0, matrix[3], matrix[4], 0, 0, 0, 1]; } else { ulMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; } var top_left = applyMatrix({ x: 0, y: 0 }, ulMatrix); top_left.x += x; top_left.y += y; var top_right = applyMatrix({ x: bboxWidth, y: 0 }, ulMatrix); top_right.x += x; top_right.y += y; var bottom_left = applyMatrix({ x: 0, y: bboxHeight }, ulMatrix); bottom_left.x += x; bottom_left.y += y; var bottom_right = applyMatrix({ x: bboxWidth, y: bboxHeight }, ulMatrix); bottom_right.x += x; bottom_right.y += y; /** step2:根据旋转后的画布位置重新计算包围盒,以免图形进行旋转后上下颠倒 */ var points = [top_left, top_right, bottom_left, bottom_right]; points.sort(function (a, b) { return a.y - b.y; }); var minY = points[0].y; var maxY = points[points.length - 1].y; var tops = [points[0], points[1]]; var bottoms = [points[2], points[3]]; var topLeft = tops[0].x < tops[1].x ? tops[0] : tops[1]; var topRight = tops[0].x < tops[1].x ? tops[1] : tops[0]; var bottomLeft = bottoms[0].x < bottoms[1].x ? bottoms[0] : bottoms[1]; var bottomRight = bottoms[0].x < bottoms[1].x ? bottoms[1] : bottoms[0]; points.sort(function (a, b) { return a.x - b.x; }); var minX = points[0].x; var maxX = points[points.length - 1].x; var node = { width: maxX - minX, height: maxY - minY, left: minX, right: maxX, top: minY, bottom: maxY, topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight, centerX: minX + (maxX - minX) / 2, centerY: minY + (maxY - minY) / 2, }; return node; } exports.bboxOnRotate = bboxOnRotate; /** * 线简化算法 */ var THRESHOLD = 2; function lineSimplification(points) { if (points.length < 5) { return points; } return DouglasPeucker(points, THRESHOLD); } exports.lineSimplification = lineSimplification; // https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm function DouglasPeucker(points, threshold) { var result; var max = -Infinity; var index = 0; var endIndex = points.length - 1; for (var i = 1; i < endIndex; i++) { var point = points[i]; var line = { start: points[0], end: points[endIndex] }; var dist = distBetweenPointLine(point, line.start, line.end); if (dist > max) { max = dist; index = i; } } if (max > threshold) { var list1 = DouglasPeucker(points.slice(0, index + 1), threshold); var list2 = DouglasPeucker(points.slice(index, points.length), threshold); result = list1.concat(list2); } else { result = [points[0], points[points.length - 1]]; } return result; } /** 统计的以后迁出去,暂时先放这里 */ function getMedian(array) { var list = util_1.clone(array); list.sort(function (a, b) { return a - b; }); var half = Math.floor(list.length / 2); if (list.length % 2) { return list[half]; } return (list[half - 1] + list[half]) / 2.0; } exports.getMedian = getMedian; function getMean(array) { var sum = 0; util_1.each(array, function (num) { sum += num; }); return sum / array.length; } exports.getMean = getMean; function sturges(values) { return Math.ceil(Math.log(values.length) / Math.LN2) + 1; } exports.sturges = sturges; /** * 获取 x/y/width/height指定的BBox边界上的所有点,由step抽样 * @param x * @param y * @param width * @param height * @param step */ function getStrokePoints(x, y, width, height, step) { if (step === void 0) { step = 2; } var points = []; // top for (var curX = x; curX <= x + width; curX += step) { points.push([curX, y]); } // right for (var curY = y; curY <= y + height; curY += step) { points.push([x + width, curY]); } // bottom for (var curX = x + width; curX >= x; curX -= step) { points.push([curX, y + height]); } // left for (var curY = y + height; curY >= y; curY -= step) { points.push([x, curY]); } return points; } exports.getStrokePoints = getStrokePoints; },{"@antv/matrix-util":717,"@antv/util":803}],681:[function(require,module,exports){ "use strict"; /** * @description path 计算、转换的辅助工具 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.convertPolarPath = exports.convertNormalPath = exports.getPointAngle = exports.getPointRadius = exports.getSplinePath = exports.getLinePath = exports.catmullRom2bezier = exports.smoothBezier = void 0; var matrix_util_1 = require("@antv/matrix-util"); var util_1 = require("@antv/util"); function _points2path(points, isInCircle) { var path = []; if (points.length) { for (var i = 0, length_1 = points.length; i < length_1; i += 1) { var item = points[i]; var command = i === 0 ? 'M' : 'L'; path.push([command, item.x, item.y]); } if (isInCircle) { path.push(['Z']); } } return path; } function _getPointRadius(coord, point) { var center = coord.getCenter(); var r = Math.sqrt(Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)); return r; } function _convertArr(arr, coord) { var tmp = [arr[0]]; for (var i = 1, len = arr.length; i < len; i = i + 2) { var point = coord.convertPoint({ x: arr[i], y: arr[i + 1], }); tmp.push(point.x, point.y); } return tmp; } function _convertPolarPath(pre, cur, coord) { var isTransposed = coord.isTransposed, startAngle = coord.startAngle, endAngle = coord.endAngle; var prePoint = { x: pre[1], y: pre[2], }; var curPoint = { x: cur[1], y: cur[2], }; var rst = []; var xDim = isTransposed ? 'y' : 'x'; var angleRange = Math.abs(curPoint[xDim] - prePoint[xDim]) * (endAngle - startAngle); var direction = curPoint[xDim] >= prePoint[xDim] ? 1 : 0; // 圆弧的方向 var flag = angleRange > Math.PI ? 1 : 0; // 大弧还是小弧标志位 var convertPoint = coord.convertPoint(curPoint); var r = _getPointRadius(coord, convertPoint); if (r >= 0.5) { // 小于1像素的圆在图像上无法识别 if (angleRange === Math.PI * 2) { var middlePoint = { x: (curPoint.x + prePoint.x) / 2, y: (curPoint.y + prePoint.y) / 2, }; var middleConvertPoint = coord.convertPoint(middlePoint); rst.push(['A', r, r, 0, flag, direction, middleConvertPoint.x, middleConvertPoint.y]); rst.push(['A', r, r, 0, flag, direction, convertPoint.x, convertPoint.y]); } else { rst.push(['A', r, r, 0, flag, direction, convertPoint.x, convertPoint.y]); } } return rst; } // 当存在整体的圆时,去除圆前面和后面的线,防止出现直线穿过整个圆的情形 function _filterFullCirleLine(path) { util_1.each(path, function (subPath, index) { var cur = subPath; if (cur[0].toLowerCase() === 'a') { var pre = path[index - 1]; var next = path[index + 1]; if (next && next[0].toLowerCase() === 'a') { if (pre && pre[0].toLowerCase() === 'l') { pre[0] = 'M'; } } else if (pre && pre[0].toLowerCase() === 'a') { if (next && next[0].toLowerCase() === 'l') { next[0] = 'M'; } } } }); } exports.smoothBezier = function (points, smooth, isLoop, constraint) { var cps = []; var prevPoint; var nextPoint; var hasConstraint = !!constraint; var min; var max; if (hasConstraint) { min = [Infinity, Infinity]; max = [-Infinity, -Infinity]; for (var i = 0, l = points.length; i < l; i++) { var point = points[i]; min = matrix_util_1.vec2.min([0, 0], min, point); max = matrix_util_1.vec2.max([0, 0], max, point); } min = matrix_util_1.vec2.min([0, 0], min, constraint[0]); max = matrix_util_1.vec2.max([0, 0], max, constraint[1]); } for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; if (isLoop) { prevPoint = points[i ? i - 1 : len - 1]; nextPoint = points[(i + 1) % len]; } else { if (i === 0 || i === len - 1) { cps.push(point); continue; } else { prevPoint = points[i - 1]; nextPoint = points[i + 1]; } } var v = [0, 0]; v = matrix_util_1.vec2.sub(v, nextPoint, prevPoint); v = matrix_util_1.vec2.scale(v, v, smooth); var d0 = matrix_util_1.vec2.distance(point, prevPoint); var d1 = matrix_util_1.vec2.distance(point, nextPoint); var sum = d0 + d1; if (sum !== 0) { d0 /= sum; d1 /= sum; } var v1 = matrix_util_1.vec2.scale([0, 0], v, -d0); var v2 = matrix_util_1.vec2.scale([0, 0], v, d1); var cp0 = matrix_util_1.vec2.add([0, 0], point, v1); var cp1 = matrix_util_1.vec2.add([0, 0], point, v2); if (hasConstraint) { cp0 = matrix_util_1.vec2.max([0, 0], cp0, min); cp0 = matrix_util_1.vec2.min([0, 0], cp0, max); cp1 = matrix_util_1.vec2.max([0, 0], cp1, min); cp1 = matrix_util_1.vec2.min([0, 0], cp1, max); } cps.push(cp0); cps.push(cp1); } if (isLoop) { cps.push(cps.shift()); } return cps; }; // 贝塞尔曲线 function catmullRom2bezier(crp, z, constraint) { var isLoop = !!z; var pointList = []; for (var i = 0, l = crp.length; i < l; i += 2) { pointList.push([crp[i], crp[i + 1]]); } var controlPointList = exports.smoothBezier(pointList, 0.4, isLoop, constraint); var len = pointList.length; var d1 = []; var cp1; var cp2; var p; for (var i = 0; i < len - 1; i++) { cp1 = controlPointList[i * 2]; cp2 = controlPointList[i * 2 + 1]; p = pointList[i + 1]; d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]); } if (isLoop) { cp1 = controlPointList[len]; cp2 = controlPointList[len + 1]; p = pointList[0]; d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]); } return d1; } exports.catmullRom2bezier = catmullRom2bezier; // 将点连接成路径 path function getLinePath(points, isInCircle) { return _points2path(points, isInCircle); } exports.getLinePath = getLinePath; // get spline: 限定了范围的平滑线 function getSplinePath(points, isInCircle, constaint) { var data = []; var first = points[0]; var prePoint = null; if (points.length <= 2) { // 两点以内直接绘制成路径 return getLinePath(points, isInCircle); } util_1.each(points, function (point) { if (!prePoint || !(prePoint.x === point.x && prePoint.y === point.y)) { data.push(point.x); data.push(point.y); prePoint = point; } }); var constraint = constaint || [ // 范围 [0, 0], [1, 1], ]; var splinePath = catmullRom2bezier(data, isInCircle, constraint); splinePath.unshift(['M', first.x, first.y]); return splinePath; } exports.getSplinePath = getSplinePath; // 获取点到圆心的距离 function getPointRadius(coord, point) { return _getPointRadius(coord, point); } exports.getPointRadius = getPointRadius; // 获取点到圆心的夹角 function getPointAngle(coord, point) { var center = coord.getCenter(); return Math.atan2(point.y - center.y, point.x - center.x); } exports.getPointAngle = getPointAngle; function convertNormalPath(coord, path) { var tmp = []; util_1.each(path, function (subPath) { var action = subPath[0]; switch (action.toLowerCase()) { case 'm': case 'l': case 'c': tmp.push(_convertArr(subPath, coord)); break; case 'z': default: tmp.push(subPath); break; } }); return tmp; } exports.convertNormalPath = convertNormalPath; function convertPolarPath(coord, path) { var tmp = []; var pre; var cur; var transposed; var equals; util_1.each(path, function (subPath, index) { var action = subPath[0]; switch (action.toLowerCase()) { case 'm': case 'c': case 'q': tmp.push(_convertArr(subPath, coord)); break; case 'l': pre = path[index - 1]; cur = subPath; transposed = coord.isTransposed; // 是否半径相同,转换成圆弧 equals = transposed ? pre[pre.length - 2] === cur[1] : pre[pre.length - 1] === cur[2]; if (equals) { tmp = tmp.concat(_convertPolarPath(pre, cur, coord)); } else { // y 不相等,所以直接转换 tmp.push(_convertArr(subPath, coord)); } break; case 'z': default: tmp.push(subPath); break; } }); _filterFullCirleLine(tmp); // 过滤多余的直线 return tmp; } exports.convertPolarPath = convertPolarPath; },{"@antv/matrix-util":717,"@antv/util":803}],682:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var shape_nodes_1 = tslib_1.__importDefault(require("../node/shape-nodes")); var responsive_1 = tslib_1.__importDefault(require("../responsive")); var base_1 = tslib_1.__importDefault(require("./base")); var SCALE_MAPPER = { cat: 'category', timeCat: 'category', time: 'dateTime', linear: 'linear', }; var ApplyResponsiveAxis = /** @class */ (function (_super) { tslib_1.__extends(ApplyResponsiveAxis, _super); function ApplyResponsiveAxis() { return _super !== null && _super.apply(this, arguments) || this; } ApplyResponsiveAxis.prototype.init = function () { this.axisInstance = this.getAxisInstance(); _super.prototype.init.call(this); }; ApplyResponsiveAxis.prototype.shouldApply = function () { var options = this.plot.options; if (!this.responsiveTheme.axis) { return false; } if (this.responsiveTheme.axis[this.dim] && options[this.dim + "Axis"].visible && options[this.dim + "Axis"].label && options[this.dim + "Axis"].label.visible) { return true; } return false; }; ApplyResponsiveAxis.prototype.apply = function () { var _this = this; var rawLabels = this.plot.view.backgroundGroup.findAll(function (el) { var name = el.get('name'); if (name === 'axis-label') { var field = el.get('delegateObject').axis.get('field'); if (field === _this.plot.options[_this.dim + "Field"]) { return el; } } }); var shapes = []; for (var i = 0; i < rawLabels.length; i++) { shapes.push(rawLabels[i]); } var shapeNodes = new shape_nodes_1.default({ shapes: shapes, }); var _a = this.responsiveTheme.axis.x[this.type], constraints = _a.constraints, rules = _a.rules; new responsive_1.default({ nodes: shapeNodes, constraints: constraints, region: this.plot.getViewRange(), rules: rules, plot: this.plot, onEnd: function (nodes) { _this.updateTicks(nodes.origion_nodes); }, }); }; ApplyResponsiveAxis.prototype.getType = function () { var props = this.plot.options; var axis = this.dim + "Axis"; var field = this.dim + "Field"; if (props[axis] && props[axis].type && props[axis].type === 'dateTime') { return 'dateTime'; } var scaleType = this.plot.view.getScaleByField([props[field]]).type; return SCALE_MAPPER[scaleType]; }; ApplyResponsiveAxis.prototype.getAxisInstance = function () { var _a, _b; var axisIndex = this.dim === 'x' ? 0 : 1; var components = (_a = this.plot.view.getController('axis')) === null || _a === void 0 ? void 0 : _a.getComponents(); if (components) { return (_b = components[axisIndex]) === null || _b === void 0 ? void 0 : _b.component; } }; ApplyResponsiveAxis.prototype.updateTicks = function (nodes) { var _this = this; var tickLineContainer = this.plot.view.backgroundGroup.findAll(function (el) { var name = el.get('name'); if (name === 'axis-tickline-group') { var field = el.get('delegateObject').axis.get('field'); if (field === _this.plot.options[_this.dim + "Field"]) { return el; } } })[0]; if (tickLineContainer) { var tickShapes_1 = tickLineContainer.get('children'); util_1.each(nodes, function (n, index) { if (n.shape.attr('text') === '') { tickShapes_1[index].attr('opacity', 0); } }); } this.plot.canvas.draw(); }; return ApplyResponsiveAxis; }(base_1.default)); exports.default = ApplyResponsiveAxis; },{"../node/shape-nodes":694,"../responsive":695,"./base":683,"@antv/util":803,"tslib":894}],683:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var ApplyResponsive = /** @class */ (function () { function ApplyResponsive(cfg) { util_1.assign(this, cfg); this.init(); } ApplyResponsive.prototype.init = function () { this.type = this.getType(); if (this.shouldApply()) { this.apply(); } }; return ApplyResponsive; }()); exports.default = ApplyResponsive; },{"@antv/util":803}],684:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var shape_nodes_1 = tslib_1.__importDefault(require("../node/shape-nodes")); var responsive_1 = tslib_1.__importDefault(require("../responsive")); var base_1 = tslib_1.__importDefault(require("./base")); var util_1 = require("@antv/util"); var ApplyResponsiveLabel = /** @class */ (function (_super) { tslib_1.__extends(ApplyResponsiveLabel, _super); function ApplyResponsiveLabel() { return _super !== null && _super.apply(this, arguments) || this; } ApplyResponsiveLabel.prototype.shouldApply = function () { if (!this.responsiveTheme.label || !this.responsiveTheme.label[this.type]) { return false; } return true; }; ApplyResponsiveLabel.prototype.apply = function () { var labelShapesContainer = this.plot.view.geometries[0].labelsContainer.get('children'); var labelShapes = []; util_1.each(labelShapesContainer, function (c) { labelShapes = labelShapes.concat(c.findAllByName('label')); }); var nodes = new shape_nodes_1.default({ shapes: labelShapes, }); var _a = this.responsiveTheme.label[this.type], constraints = _a.constraints, rules = _a.rules; new responsive_1.default({ nodes: nodes, constraints: constraints, rules: rules, plot: this.plot, region: this.plot.view.coordinateBBox, }); }; ApplyResponsiveLabel.prototype.getType = function () { return null; }; return ApplyResponsiveLabel; }(base_1.default)); exports.default = ApplyResponsiveLabel; },{"../node/shape-nodes":694,"../responsive":695,"./base":683,"@antv/util":803,"tslib":894}],685:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function columnWidth(node, region, cfg) { if (cfg === void 0) { cfg = { ratio: 0.6 }; } return region.width * cfg.ratio; } exports.default = { type: 'padding', usage: 'assign', expression: columnWidth, }; },{}],686:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var MathUtil = tslib_1.__importStar(require("../../math")); function elementCollision(a, b) { var polygonA = [a.topLeft, a.topRight, a.bottomRight, a.bottomLeft]; // 顶点顺时针 var polygonB = [b.topLeft, b.topRight, b.bottomRight, b.bottomLeft]; var dist = MathUtil.minDistBetweenConvexPolygon(polygonA, polygonB); return Math.round(dist) >= 2; } exports.default = { type: 'group', usage: 'compare', expression: elementCollision, }; },{"../../math":680,"tslib":894}],687:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function elementDistVertical(a, b, cfg) { if (cfg === void 0) { cfg = { value: 5 }; } var dist = Math.abs(a.bottom - b.top); return Math.round(dist) >= cfg.value; } exports.default = { type: 'chain', usage: 'compare', expression: elementDistVertical, }; },{}],688:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var MathUtil = tslib_1.__importStar(require("../../math")); function elementDist(a, b, cfg) { if (cfg === void 0) { cfg = { value: 4 }; } var polygonA = [a.topLeft, a.topRight, a.bottomRight, a.bottomLeft]; // 顶点顺时针 var polygonB = [b.topLeft, b.topRight, b.bottomRight, b.bottomLeft]; var dist = MathUtil.minDistBetweenConvexPolygon(polygonA, polygonB); return Math.round(dist) >= cfg.value; } exports.default = { type: 'chain', usage: 'compare', expression: elementDist, }; },{"../../math":680,"tslib":894}],689:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function elementWidth(node, region, cfg) { if (cfg === void 0) { cfg = { ratio: 0.15 }; } return node.width < region.width * cfg.ratio; } exports.default = { type: 'padding', usage: 'compare', expression: elementWidth, }; },{}],690:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerResponsiveConstraint = exports.constraintsLib = void 0; var tslib_1 = require("tslib"); var column_width_1 = tslib_1.__importDefault(require("./column-width")); var element_collision_1 = tslib_1.__importDefault(require("./element-collision")); var element_dist_1 = tslib_1.__importDefault(require("./element-dist")); var element_dist_vertical_1 = tslib_1.__importDefault(require("./element-dist-vertical")); var element_width_1 = tslib_1.__importDefault(require("./element-width")); var min_ring_thickness_1 = tslib_1.__importDefault(require("./min-ring-thickness")); var ring_thickness_1 = tslib_1.__importDefault(require("./ring-thickness")); exports.constraintsLib = { elementDist: element_dist_1.default, elementDistVertical: element_dist_vertical_1.default, elementCollision: element_collision_1.default, elementWidth: element_width_1.default, columnWidth: column_width_1.default, ringThickness: ring_thickness_1.default, minRingThickness: min_ring_thickness_1.default, }; function registerResponsiveConstraint(name, constraint) { // todo: 防止覆盖 exports.constraintsLib[name] = constraint; } exports.registerResponsiveConstraint = registerResponsiveConstraint; },{"./column-width":685,"./element-collision":686,"./element-dist":688,"./element-dist-vertical":687,"./element-width":689,"./min-ring-thickness":691,"./ring-thickness":692,"tslib":894}],691:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function minRingThickness(node, region) { var minThicknessPixel = 2; var minThickness = region.coord.radius / minThicknessPixel; return Math.min(minThickness, node.value); } exports.default = { type: 'padding', usage: 'assign', expression: minRingThickness, }; },{}],692:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function ringThickness(node, region, cfg) { if (cfg === void 0) { cfg = { ratio: 0.8 }; } return region.radius * cfg.ratio; } exports.default = { type: 'padding', usage: 'assign', expression: ringThickness, }; },{}],693:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_RESPONSIVE_THEME = void 0; // 存储一些共用部分 exports.DEFAULT_RESPONSIVE_THEME = { axis: { x: { category: { constraints: [{ name: 'elementDist' }], rules: { elementDist: [ { name: 'textWrapper', option: { lineNumber: 2, }, }, { name: 'textRotation', option: { degree: 45, }, }, { name: 'textRotation', option: { degree: 90, }, }, { name: 'textAbbreviate', option: { abbreviateBy: 'end', }, }, { name: 'textHide', }, ], }, }, linear: { constraints: [{ name: 'elementDist' }], rules: { elementDist: [ { name: 'nodesResampling', option: { keep: ['end'], }, }, { name: 'textRotation', option: { degree: 45, }, }, { name: 'textRotation', option: { degree: 90, }, }, { name: 'robustAbbrevaite', option: { unit: 'thousand', decimal: 1, abbreviateBy: 'end', }, }, { name: 'textHide', }, ], }, }, dateTime: { constraints: [{ name: 'elementDist' }], rules: { elementDist: [ { name: 'datetimeStringAbbrevaite', }, { name: 'nodesResamplingByAbbrevate', option: { keep: ['end'], }, }, { name: 'textRotation', option: { degree: 45, }, }, { name: 'textRotation', option: { degree: 90, }, }, { name: 'nodesResampling', }, { name: 'nodesResampling', }, { name: 'textHide', }, ], }, }, }, y: { linear: { constraints: [{ name: 'elementDistVertical' }, { name: 'elementWidth' }], rules: { elementDistVertical: [{ name: 'nodesResampling' }, { name: 'textHide' }], elementWidth: [{ name: 'digitsAbbreviate' }, { name: 'textHide' }], }, }, category: { constraints: [{ name: 'elementDistVertical' }, { name: 'elementWidth' }], rules: { elementDistVertical: [{ name: 'nodesResampling' }, { name: 'textHide' }], elementWidth: [ { name: 'textAbbreviate', option: { abbreviateBy: 'end', }, }, { name: 'textHide' }, ], }, }, }, }, }; },{}],694:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var MathUtil = tslib_1.__importStar(require("../../math")); var ShapeNodes = /** @class */ (function () { function ShapeNodes(cfg) { this.type = 'shape'; this.shapes = cfg.shapes; this.nodes = []; this._parserNodes(); this.origion_nodes = util_1.deepMix([], this.nodes); } ShapeNodes.prototype.measure = function (shape) { var node = util_1.deepMix({}, MathUtil.bboxOnRotate(shape), { shape: shape }); return node; }; ShapeNodes.prototype.measureNodes = function () { var _this = this; var nodes = []; var shapes = []; util_1.each(this.shapes, function (shape, index) { var node = util_1.deepMix({}, _this.nodes[index], _this.measure(shape)); if (node.width !== 0 && node.height !== 0) { nodes.push(node); shapes.push(shape); } // this.nodes[index] = node; }); this.nodes = nodes; this.shapes = shapes; }; ShapeNodes.prototype._parserNodes = function () { var _this = this; util_1.each(this.shapes, function (shape) { var node = _this.measure(shape); _this.nodes.push(node); }); }; return ShapeNodes; }()); exports.default = ShapeNodes; },{"../../math":680,"@antv/util":803,"tslib":894}],695:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var index_1 = require("./constraints/index"); var index_2 = require("./rules/index"); var Responsive = /** @class */ (function () { function Responsive(cfg) { this.iterationTime = 10; this.iterationIndex = 0; this.rulesLocker = []; this.constraintIndex = 0; util_1.assign(this, cfg); this.currentConstraint = this.constraints[0]; if (this.rules) { this.iterationTime = this.rules[this.currentConstraint.name].length; } this._start(); this._run(); this._end(); } Responsive.prototype._start = function () { if (this.onStart) { this.onStart(this.nodes); } }; Responsive.prototype._iteration = function () { var nodes; if (this.nodes.type === 'shape') { nodes = this.nodes; } else { nodes = this.nodes; } if (nodes.type === 'shape') { nodes.measureNodes(); } if (this.rules) { this._applyRules(); } if (nodes.type === 'shape') { nodes.measureNodes(); } if (this.onIteration) { this.onIteration(this.nodes); } }; Responsive.prototype._end = function () { if (this.onEnd) { this.onEnd(this.nodes); } }; Responsive.prototype._run = function () { var constraintPassed = this._constraintsTest(); while (!constraintPassed) { if (this.iterationIndex > this.iterationTime - 1) { break; } this._iteration(); constraintPassed = this._constraintsTest(); this.iterationIndex++; } if (this.constraintIndex < this.constraints.length - 1) { this.constraintIndex++; this.currentConstraint = this.constraints[this.constraintIndex]; this.iterationTime = this.rules ? this.rules[this.currentConstraint.name].length : 1; this.iterationIndex = 0; this._run(); } }; Responsive.prototype._constraintsTest = function () { var constraint = index_1.constraintsLib[this.currentConstraint.name]; var constraintOption = this.currentConstraint.option; if (constraint.usage === 'compare') { return this._constraintCompare(constraint, constraintOption); } return this._constraintAssignment(constraint, constraintOption); }; Responsive.prototype._constraintCompare = function (constraint, option) { var type = constraint.type, expression = constraint.expression; var nodes = this.nodes.nodes; if (type === 'chain') { return this._chainConstraintCompare(expression, nodes, option); } if (type === 'padding') { return this._paddingConstraintCompare(expression, this.region, nodes, option); } if (type === 'group') { return this._groupConstraintCompare(expression, nodes, option); } }; Responsive.prototype._chainConstraintCompare = function (expression, nodes, option) { for (var i = 0; i < nodes.length - 1; i++) { var a = nodes[i]; var b = nodes[i + 1]; if (expression(a, b, option) === false) { return false; } } return true; }; Responsive.prototype._paddingConstraintCompare = function (expression, region, nodes, option) { if (region) { for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { var node = nodes_1[_i]; if (expression(node, region, option) === false) { return false; } } } return true; }; Responsive.prototype._groupConstraintCompare = function (expression, nodes, option) { for (var i = 0; i < nodes.length; i++) { var a = nodes[i]; for (var j = 0; j < nodes.length; j++) { if (j !== i) { var b = nodes[j]; if (expression(a, b, option) === false) { return false; } } } } return true; }; Responsive.prototype._constraintAssignment = function (constraint, option) { var type = constraint.type, expression = constraint.expression; var nodes = this.nodes.nodes; if (type === 'chain') { return this._chainConstraintAssign(); } if (type === 'padding') { return this._paddingConstraintAssign(expression, this.region, nodes, option); } }; Responsive.prototype._chainConstraintAssign = function () { return true; }; Responsive.prototype._paddingConstraintAssign = function (expression, region, nodes, option) { if (region) { for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) { var node = nodes_2[_i]; var value = expression(node, region, option); node.value = value; } } return true; }; Responsive.prototype._applyRules = function () { var ruleCfg = this.rules[this.currentConstraint.name][this.iterationIndex]; // if (this.rulesLocker.indexOf(ruleCfg) < 0) { var rule = index_2.rulesLib[ruleCfg.name]; var option = ruleCfg.option ? ruleCfg.option : {}; var nodes = this.nodes.nodes; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; /** apply rule上下文 */ this._applyRule(node.shape, rule, option, i); } // this.rulesLocker.push(ruleCfg); // } }; Responsive.prototype._applyRule = function (shape, rule, option, index) { var cfg = { nodes: this.nodes, region: this.region, plot: this.plot, }; // rule(shape, option, index, this); rule(shape, option, index, cfg); }; return Responsive; }()); exports.default = Responsive; },{"./constraints/index":690,"./rules/index":699,"@antv/util":803}],696:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isNodeOverlap = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var text_hide_1 = tslib_1.__importDefault(require("./text-hide")); function clearOverlapping(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; var current = nodes[index]; var overlapped = []; /** 找到所有与当前点overlap的node */ if (!current.shape.get('blank')) { for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; var _shape = node.shape; if (i !== index && !_shape.get('blank')) { var isOverlap = isNodeOverlap(current, node); if (isOverlap) { overlapped.push(node); } } } } /** overlap处理逻辑 */ if (overlapped.length > 0) { overlapped.push(current); overlapped.sort(function (a, b) { return b.top - a.top; }); /** 隐藏除最高点以外的node */ util_1.each(overlapped, function (node, idx) { if (idx > 0) { var _shape = node.shape; text_hide_1.default(_shape); _shape.set('blank', true); } }); } } exports.default = clearOverlapping; function isNodeOverlap(nodeA, nodeB) { if (nodeA.bottom < nodeB.top || nodeB.bottom < nodeA.top) { return false; } if (nodeA.right < nodeB.left || nodeB.right < nodeA.left) { return false; } return true; } exports.isNodeOverlap = isNodeOverlap; },{"./text-hide":708,"@antv/util":803,"tslib":894}],697:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isTime = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var fecha_1 = tslib_1.__importDefault(require("fecha")); var SECOND = 1000; var MINUTE = 60 * SECOND; var HOUR = 60 * MINUTE; var DAY = 24 * HOUR; var MONTH = 31 * DAY; var YEAR = 365 * DAY; function datetimeStringAbbrevaite(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; var campareText; if (index === nodes.length - 1) { campareText = nodes[index - 1].shape.get('delegateObject').item.name; } else { campareText = nodes[index + 1].shape.get('delegateObject').item.name; } var compare = new Date(campareText); /** 获取时间周期和时间间隔 */ var text = shape.get('delegateObject').item.name; var current = new Date(text); var startText = nodes[0].shape.get('delegateObject').item.name; var start = new Date(startText); var endText = nodes[nodes.length - 1].shape.get('delegateObject').item.name; var end = new Date(endText); var timeDuration = getDateTimeMode(start, end); var timeCycle = getDateTimeMode(current, compare); // time frequency // 如果duration和frequency在同一区间 if (timeDuration === timeCycle) { if (index !== 0 && index !== nodes.length - 1) { var formatter = sameSectionFormatter(timeDuration); shape.attr('text', fecha_1.default.format(current, formatter)); } return; } if (index !== 0) { var previousText = nodes[index - 1].shape.get('delegateObject').item.name; var previous = new Date(previousText); var isAbbreviate = needAbbrevaite(timeDuration, current, previous); if (isAbbreviate) { var formatter = getAbbrevaiteFormatter(timeDuration, timeCycle); shape.attr('text', fecha_1.default.format(current, formatter)); return; } } } exports.default = datetimeStringAbbrevaite; function needAbbrevaite(mode, current, previous) { var currentStamp = getTime(current, mode); var previousStamp = getTime(previous, mode); if (currentStamp !== previousStamp) { return false; } return true; } function getDateTimeMode(a, b) { var mode; var dist = Math.abs(a - b); var mapper = { minute: [MINUTE, HOUR], hour: [HOUR, DAY], day: [DAY, MONTH], month: [MONTH, YEAR], year: [YEAR, Infinity], }; util_1.each(mapper, function (range, key) { if (dist >= range[0] && dist < range[1]) { mode = key; } }); return mode; } function getAbbrevaiteFormatter(duration, cycle) { var times = ['year', 'month', 'day', 'hour', 'minute']; var formatters = ['YYYY', 'MM', 'DD', 'HH', 'MM']; var startIndex = times.indexOf(duration) + 1; var endIndex = times.indexOf(cycle); var formatter = ''; for (var i = startIndex; i <= endIndex; i++) { formatter += formatters[i]; if (i < endIndex) { formatter += '-'; } } return formatter; } function sameSectionFormatter(mode) { var times = ['year', 'month', 'day', 'hour', 'minute']; var formatters = ['YYYY', 'MM', 'DD', 'HH', 'MM']; var index = times.indexOf(mode); var formatter = formatters[index]; return formatter; } function getTime(date, mode) { if (mode === 'year') { return date.getFullYear(); } if (mode === 'month') { return date.getMonth() + 1; } if (mode === 'day') { return date.getDay() + 1; } if (mode === 'hour') { return date.getHours() + 1; } if (mode === 'minute') { return date.getMinutes() + 1; } } /*tslint:disable*/ function isTime(string) { var hourminExp = /^(?:(?:[0-2][0-3])|(?:[01]\d)):[0-5]\d$/; var hourminSecExp = /^(?:(?:[0-2][0-3])|(?:[01]\d))(?::[0-5]\d){2}$/; return hourminExp.test(string) || hourminSecExp.test(string); } exports.isTime = isTime; },{"@antv/util":803,"fecha":881,"tslib":894}],698:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var math_1 = require("../../math"); var unitMapper = { k: { number: 1e3, index: 0 }, m: { number: 1e6, index: 1 }, b: { number: 1e9, index: 2 }, t: { number: 1e12, index: 3 }, }; // https://gist.github.com/MartinMuzatko/1060fe584d17c7b9ca6e // https://jburrows.wordpress.com/2014/11/18/abbreviating-numbers/ /*tslint:disable*/ function digitsAbbreviate(shape, option, index, cfg) { if (!util_1.has(cfg, 'node') || !util_1.has(cfg.node, 'node')) { return; } var nodes = cfg.nodes.nodes; var number = parseFloat(shape.get('origin').text); if (number === 0) { return; } if (option.formatter) { shape.attr('text', option.formatter(number)); return; } if (option.unit) { var _a = abbravateDigitsByUnit(option, number), num = _a.num, unitname = _a.unitname; shape.attr('text', num + unitname); } else { // 自动换算逻辑 // 根据中位数得到换算单位 var numbers = extractNumbers(nodes); var median = math_1.getMedian(numbers); var unitname = getUnitByNumber(median); //根据数值的interval计算换算后保留的浮点数 var unitNumber = unitMapper[unitname].number; var interval = getLinearNodesInterval(nodes); var decimal = getDigitsDecimal(interval, unitNumber); var num = abbravateDigitsByUnit({ unit: unitname, decimal: decimal }, number).num; shape.attr('text', num + unitname); } } exports.default = digitsAbbreviate; function abbravateDigitsByUnit(option, number) { var units = ['k', 'm', 'b', 't']; var num; var unitname; if (option.unit === 'auto') { /** auto formatt k-m-b-t */ var order = Math.floor(Math.log(number) / Math.log(1000)); unitname = units[order - 1]; num = (number / Math.pow(1000, order)).toFixed(option.decimal); } else if (option.unit) { var unit = unitMapper[option.unit]; unitname = option.unit; num = (number / unit.number).toFixed(option.decimal); } return { num: num, unitname: unitname }; } function getUnitByNumber(number) { var units = ['k', 'm', 'b', 't']; var order = Math.floor(Math.log(number) / Math.log(1000)); return units[order - 1]; } function extractNumbers(nodes) { var numbers = []; util_1.each(nodes, function (node) { var n = node; var number = parseFloat(n.shape.get('origin').text); numbers.push(number); }); return numbers; } function getLinearNodesInterval(nodes) { if (nodes.length >= 2) { var a = parseFloat(nodes[0].shape.get('origin').text); var b = parseFloat(nodes[1].shape.get('origin').text); return Math.abs(a - b); } return 0; } function getDigitsDecimal(interval, unitNumber) { var unitBit = Math.floor(Math.log10(unitNumber)); if (interval >= unitNumber) { var remainder = interval % unitNumber; if (remainder > 0) { var remainderBit = Math.floor(Math.log10(remainder)); return Math.abs(remainderBit - unitBit); } } else { var intervalBit = Math.floor(Math.log10(interval)); return Math.abs(intervalBit - unitBit); } return 0; } },{"../../math":680,"@antv/util":803}],699:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerResponsiveRule = exports.rulesLib = void 0; var tslib_1 = require("tslib"); var clear_overlapping_1 = tslib_1.__importDefault(require("./clear-overlapping")); var datetime_string_abbrevaite_1 = tslib_1.__importDefault(require("./datetime-string-abbrevaite")); var digits_abbreviate_1 = tslib_1.__importDefault(require("./digits-abbreviate")); var node_jitter_1 = tslib_1.__importDefault(require("./node-jitter")); var node_jitter_upward_1 = tslib_1.__importDefault(require("./node-jitter-upward")); var nodes_resampling_1 = tslib_1.__importDefault(require("./nodes-resampling")); var nodes_resampling_by_abbrevate_1 = tslib_1.__importDefault(require("./nodes-resampling-by-abbrevate")); var nodes_resampling_by_change_1 = tslib_1.__importDefault(require("./nodes-resampling-by-change")); var nodes_resampling_by_state_1 = tslib_1.__importDefault(require("./nodes-resampling-by-state")); var robust_abbrevaite_1 = tslib_1.__importDefault(require("./robust-abbrevaite")); var text_abbreviate_1 = tslib_1.__importDefault(require("./text-abbreviate")); var text_hide_1 = tslib_1.__importDefault(require("./text-hide")); var text_rotation_1 = tslib_1.__importDefault(require("./text-rotation")); var text_wrapper_1 = tslib_1.__importDefault(require("./text-wrapper")); exports.rulesLib = { textWrapper: text_wrapper_1.default, textRotation: text_rotation_1.default, textAbbreviate: text_abbreviate_1.default, textHide: text_hide_1.default, digitsAbbreviate: digits_abbreviate_1.default, datetimeStringAbbrevaite: datetime_string_abbrevaite_1.default, robustAbbrevaite: robust_abbrevaite_1.default, nodesResampling: nodes_resampling_1.default, nodesResamplingByAbbrevate: nodes_resampling_by_abbrevate_1.default, nodesResamplingByChange: nodes_resampling_by_change_1.default, nodesResamplingByState: nodes_resampling_by_state_1.default, nodeJitter: node_jitter_1.default, nodeJitterUpward: node_jitter_upward_1.default, clearOverlapping: clear_overlapping_1.default, }; function registerResponsiveRule(name, method) { // todo: 防止覆盖 exports.rulesLib[name] = method; } exports.registerResponsiveRule = registerResponsiveRule; },{"./clear-overlapping":696,"./datetime-string-abbrevaite":697,"./digits-abbreviate":698,"./node-jitter":701,"./node-jitter-upward":700,"./nodes-resampling":705,"./nodes-resampling-by-abbrevate":702,"./nodes-resampling-by-change":703,"./nodes-resampling-by-state":704,"./robust-abbrevaite":706,"./text-abbreviate":707,"./text-hide":708,"./text-rotation":709,"./text-wrapper":710,"tslib":894}],700:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var clear_overlapping_1 = require("./clear-overlapping"); /** 图形向上抖开并拉线 */ // todo 允许设置offset和拉线样式 function nodeJitterUpward(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; if (index === 0) { return; } var current = nodes[index]; var previous = nodes[index - 1]; if (clear_overlapping_1.isNodeOverlap(current, previous)) { var element = cfg.plot.view.geometries[0].elements[0]; var y = previous.top - current.height / 2; var offset = 10; if (y - offset > cfg.region.top) { // 取到label对应的element-shape var origin_1 = current.shape.get('origin'); var shapeId = element.getShapeId(origin_1); var shapes = element.getShapes(); var shapeBbox = getShapeById(shapeId, shapes).get('box'); var originX = shapeBbox.left + shapeBbox.width / 2; var originY = shapeBbox.top; // 拉线 var container = element.get('labelController').labelsContainer; var labelLine = container.addShape('path', { attrs: { path: [ ['M', originX, originY], ['L', current.shape.attr('x'), y], ], stroke: '#ccc', lineWidth: 1, }, }); /** 保存labelLine和label初始位置信息 */ var origin_position = { x: shape.attr('x'), y: shape.attr('y') }; // 更新标签位置,同步更新node current.shape.attr('y', y - offset); nodes[index] = cfg.nodes.measure(current.shape); nodes[index].line = labelLine; nodes[index].origin_position = origin_position; } } } exports.default = nodeJitterUpward; function getShapeById(shapeId, shapes) { var target; util_1.each(shapes, function (shape) { var s = shape; var id = s.get('id'); if (id === shapeId) { target = s; } }); return target; } },{"./clear-overlapping":696,"@antv/util":803}],701:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var math_1 = require("../../math"); /** 图形在水平或垂直方向抖开 */ function nodeJitter(shape, index, cfg) { var nodes = cfg.nodes.nodes; if (index === nodes.length - 1) { return; } var current = nodes[index]; var next = nodes[index + 1]; var dir = alignDirection(current, next).dir; var startPoint = shape.get('startPoint'); if (dir === 'x') { shape.attr('y', startPoint.y + 20); } } exports.default = nodeJitter; function alignDirection(nodeA, nodeB) { var dir; /** 计算两个node 中心点向量的角度 */ var vector = { x: nodeB.centerX - nodeA.centerX, y: nodeB.centerY - nodeA.centerY }; var mag = Math.sqrt(vector.x * vector.x + vector.y * vector.y); var vector_horizontal = { x: 10, y: 0 }; // 水平方向向量 /*tslint:disable*/ var mag_horizontal = Math.sqrt(vector_horizontal.x * vector_horizontal.x + vector_horizontal.y * vector_horizontal.y); var dot = math_1.dotProduct2D(vector, vector_horizontal); var angle = ((dot / (mag * mag_horizontal)) * 180) / Math.PI; if (angle < 0) angle = 360 - angle; angle = adjustAngle(angle); // 将角度从0-360转换到0-90 /** 计算两个node在x、y两个方向上的距离 */ var distX = Math.abs(nodeA.centerX - nodeB.centerX); var distY = Math.abs(nodeA.centerY - nodeB.centerY); if (angle > 45) { dir = 'x'; } else if (angle < 45) { dir = 'y'; } return { dir: dir, distX: distX, distY: distY }; } function adjustAngle(angle) { if (angle > 90 && angle <= 180) { return 180 - angle; } if (angle > 180 && angle < 270) { return angle - 180; } return 360 - angle; } },{"../../math":680}],702:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var nodes_resampling_1 = require("./nodes-resampling"); var text_hide_1 = tslib_1.__importDefault(require("./text-hide")); function nodesResamplingByAbbrevate(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; if (nodes_resampling_1.isKeep(option.keep, index, nodes)) { return; } { var currentText = shape.attr('text'); var originText = shape.get('delegateObject').item.name; if (currentText !== originText) { text_hide_1.default(shape); } } } exports.default = nodesResamplingByAbbrevate; },{"./nodes-resampling":705,"./text-hide":708,"tslib":894}],703:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var text_hide_1 = tslib_1.__importDefault(require("./text-hide")); /** 根据变化进行抽样,保留变化较大的点,类似于点简化算法 */ function nodesResamplingByChange(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; var tolerance = getGlobalTolerance(nodes); if (index <= 1) { return; } var current = nodes[index]; // const previous = nodes[index-1]; var previous = findPrevious(index, nodes); var distX = previous.centerX - current.centerX; var distY = previous.centerY - current.centerY; var dist = Math.sqrt(distX * distX + distY * distY); if (dist < tolerance) { text_hide_1.default(shape); shape.set('blank', true); } } exports.default = nodesResamplingByChange; function findPrevious(index, nodes) { for (var i = index - 1; i > 0; i--) { var node = nodes[i]; if (!node.shape.get('blank')) { return node; } } } function getGlobalTolerance(nodes) { var nodesClone = util_1.deepMix([], nodes); nodesClone.sort(function (a, b) { return b.width - a.width; }); return Math.round(nodesClone[0].width); } },{"./text-hide":708,"@antv/util":803,"tslib":894}],704:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var text_hide_1 = tslib_1.__importDefault(require("./text-hide")); function nodesResamplingByState(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; var current = nodes[index]; if (current.line) { current.line.remove(); } var data = cfg.plot.initialOptions.data; var plotCfg = cfg.plot[cfg.plot.type] || cfg.plot[cfg.plot.baseType]; var field = util_1.get(plotCfg, ['label', 'fields', 0], util_1.get(plotCfg, ['position', 'fields', 1])); var stateNodes = getStateNodes(data, field, nodes); var isState = false; util_1.each(stateNodes, function (node) { // @ts-ignore if (node.shape.get('origin') === current.shape.get('origin')) { isState = true; } }); if (isState) { if (current.origin_position) { var _a = current.origin_position, x = _a.x, y = _a.y; shape.attr('x', x); shape.attr('y', y); } } else { text_hide_1.default(shape); } } exports.default = nodesResamplingByState; function getStateNodes(data, field, nodes) { var extract_data = []; util_1.each(data, function (d) { extract_data.push(d[field]); }); extract_data.sort(function (a, b) { return a - b; }); var min = extract_data[0]; var min_node = getNodeByNumber(nodes, field, min); var max = extract_data[extract_data.length - 1]; var max_node = getNodeByNumber(nodes, field, max); var median = getMedian(extract_data); var median_node = getNodeByNumber(nodes, field, median); return { min: min_node, max: max_node, median: median_node }; } function getMedian(array) { var list = util_1.clone(array); list.sort(function (a, b) { return a - b; }); var half = Math.floor(list.length / 2); if (list.length % 2) { return list[half]; } return list[half]; } function getNodeByNumber(nodes, field, num) { for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { var node = nodes_1[_i]; var d = node.shape.get('origin')['_origin']; if (d[field] === num) { return node; } } } },{"./text-hide":708,"@antv/util":803,"tslib":894}],705:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isKeep = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var text_hide_1 = tslib_1.__importDefault(require("./text-hide")); function nodesResampling(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; /** nodeLength为偶数,则奇数index的shape保留,反之则偶数index的shape保留 */ var oddKeep = nodes.length % 2 === 0 ? false : true; if (isKeep(option.keep, index, nodes)) { return; } { var isOdd = index % 2 === 0 ? true : false; if ((!oddKeep && isOdd) || (oddKeep && !isOdd)) { text_hide_1.default(shape); } } } exports.default = nodesResampling; function isKeep(keepCfg, index, nodes) { /** 允许设置start end 或任意index */ var conditions = []; util_1.each(keepCfg, function (cfg) { if (cfg === 'start') { conditions.push(index === 0); } else if (cfg === 'end') { conditions.push(index === nodes.length - 1); } else if (util_1.isNumber(cfg)) { conditions.push(index === cfg); } }); for (var _i = 0, conditions_1 = conditions; _i < conditions_1.length; _i++) { var condition = conditions_1[_i]; if (condition === true) { return true; } } return false; } exports.isKeep = isKeep; },{"./text-hide":708,"@antv/util":803,"tslib":894}],706:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var datetime_string_abbrevaite_1 = tslib_1.__importStar(require("./datetime-string-abbrevaite")); var digits_abbreviate_1 = tslib_1.__importDefault(require("./digits-abbreviate")); var text_abbreviate_1 = tslib_1.__importDefault(require("./text-abbreviate")); function robustAbbrevaite(shape, option, index, cfg) { var nodes = cfg.nodes.nodes; var text = shape.attr('text'); /** 判断text类型: 数字、时间、文本 */ var isnum = /^\d+$/.test(text); if (isnum) { digits_abbreviate_1.default(shape, option, index, nodes); } else if (datetime_string_abbrevaite_1.isTime(text)) { datetime_string_abbrevaite_1.default(shape, option, index, nodes); } else { text_abbreviate_1.default(shape, option); } } exports.default = robustAbbrevaite; },{"./datetime-string-abbrevaite":697,"./digits-abbreviate":698,"./text-abbreviate":707,"tslib":894}],707:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function textAbbreviate(shape, option) { var abbreviateBy = option.abbreviateBy ? option.abbreviateBy : 'end'; var text = shape.attr('text'); var abbravateText; if (abbreviateBy === 'end') { abbravateText = text[0] + "..."; } if (abbreviateBy === 'start') { abbravateText = "..." + text[text.length - 1]; } if (abbreviateBy === 'middle') { abbravateText = text[0] + "..." + text[text.length - 1]; } shape.resetMatrix(); shape.attr({ text: abbravateText, textAlign: 'center', textBaseline: 'top', }); } exports.default = textAbbreviate; },{}],708:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function textHide(shape) { shape.attr('text', ''); } exports.default = textHide; },{}],709:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function textRotation(shape, option) { shape.resetMatrix(); shape.attr({ rotate: 360 - option.degree, textAlign: 'right', textBaseline: 'middle', }); } exports.default = textRotation; },{}],710:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function textWrapper(shape, option) { var text = shape.attr('text'); var step = Math.ceil(text.length / option.lineNumber); var wrapperText = ''; for (var i = 1; i < option.lineNumber; i++) { var index = step * i; wrapperText = text.slice(0, index) + "\n" + text.slice(index); } var fontSize = shape.attr('fontSize'); shape.attr({ text: wrapperText, lineHeight: fontSize, textAlign: 'center', textBaseline: 'top', }); } exports.default = textWrapper; },{}],711:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getResponsiveTheme = exports.registerResponsiveTheme = void 0; var util_1 = require("@antv/util"); var default_1 = require("./default"); /** * 所有的响应式主题配置 */ var RESPONSIVE_THEME_MAP = { default: default_1.DEFAULT_RESPONSIVE_THEME, }; /** * 添加一个响应式主题配置 * @param name * @param theme */ function registerResponsiveTheme(name, theme) { RESPONSIVE_THEME_MAP[name.toLowerCase()] = util_1.deepMix({}, default_1.DEFAULT_RESPONSIVE_THEME, theme); } exports.registerResponsiveTheme = registerResponsiveTheme; /** * 获取一个响应式主题配置,如果找不到则返回默认 * @param name */ function getResponsiveTheme(name) { var theme = RESPONSIVE_THEME_MAP[name.toLowerCase()]; return theme ? theme : default_1.DEFAULT_RESPONSIVE_THEME; } exports.getResponsiveTheme = getResponsiveTheme; },{"./default":693,"@antv/util":803}],712:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.trySetScaleMinToZero = exports.extractScale = void 0; var util_1 = require("@antv/util"); var config_1 = require("../interface/config"); function adjustTimeTickInterval(interval) { var intervals = config_1.timeIntervals; var intervalArr = interval.split(' '); var basicInterval = intervals[intervalArr[1]]; var intervalCount = parseInt(intervalArr[0], 10); return [basicInterval.format, intervalCount * basicInterval.value]; } function extractScale(desScale, axisConfig) { if (!axisConfig) { return desScale; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'tickCount')) { desScale.tickCount = axisConfig.tickCount; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'type')) { // fixme: dateTime plot层处理 if (axisConfig.type !== 'dateTime') { desScale.type = axisConfig.type; } } if (Object.prototype.hasOwnProperty.call(axisConfig, 'tickInterval')) { if (axisConfig.type === 'time') { desScale.tickInterval = adjustTimeTickInterval(axisConfig.tickInterval); } else { desScale.tickInterval = axisConfig.tickInterval; } } if (axisConfig.type === 'time' && axisConfig.mask) { desScale.mask = axisConfig.mask; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'min')) { desScale.min = axisConfig.min; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'max')) { desScale.max = axisConfig.max; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'minLimit')) { desScale.minLimit = axisConfig.minLimit; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'maxLimit')) { desScale.maxLimit = axisConfig.maxLimit; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'nice')) { desScale.nice = axisConfig.nice; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'formatter')) { desScale.formatter = axisConfig.formatter; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'exponent')) { desScale.exponent = axisConfig.exponent; } if (Object.prototype.hasOwnProperty.call(axisConfig, 'base')) { desScale.base = axisConfig.base; } if (axisConfig.tickMethod) { desScale.tickMethod = axisConfig.tickMethod; } } exports.extractScale = extractScale; function trySetScaleMinToZero(desScale, data) { var validData = util_1.filter(data, function (v) { return util_1.isNumber(v); }); var min = Math.min.apply(Math, validData); var max = Math.max.apply(Math, validData); if (min > 0) { if (util_1.isNil(desScale.min)) { desScale.min = 0; } } else if (max < 0) { if (util_1.isNil(desScale.max)) { desScale.max = 0; } } } exports.trySetScaleMinToZero = trySetScaleMinToZero; },{"../interface/config":449,"@antv/util":803}],713:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * 可插拔的状态量管理机 */ // todo: 后续还需要加入交互互斥的维护机制 var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); var util_1 = require("@antv/util"); var StateManager = /** @class */ (function (_super) { tslib_1.__extends(StateManager, _super); function StateManager() { var _this = _super.call(this) || this; _this._states = {}; _this._stateStack = {}; return _this; } StateManager.prototype.setState = function (name, exp) { this._stateStack[name] = exp; this._onUpdate(); }; StateManager.prototype.getState = function (name) { return this._states[name]; }; StateManager.prototype.getAllStates = function () { return this._states; }; StateManager.prototype.clear = function () { this._states = {}; this._stateStack = {}; if (this._changeTimer) { clearTimeout(this._changeTimer); this._changeTimer = null; } }; StateManager.prototype._onUpdate = function () { var _this = this; var stateStack = this._stateStack; if (this._changeTimer) { clearTimeout(this._changeTimer); this._changeTimer = null; } this._changeTimer = setTimeout(function () { // for (const name in stateStack) { util_1.each(stateStack, function (exp, name) { var state = stateStack[name]; if (!_this._states[name] || _this._states[name] !== exp) { // update states _this._states[name] = exp; // dispatch state event _this._triggerEvent(name, state); } }); // } // clear stack _this._stateStack = {}; }, 16); }; StateManager.prototype._triggerEvent = function (name, exp) { this.emit(name + ":change", { name: name, exp: exp, }); }; return StateManager; }(event_emitter_1.default)); exports.default = StateManager; },{"@antv/event-emitter":94,"@antv/util":803,"tslib":894}],714:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getEllipsisText = exports.measureTextWidth = void 0; var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); /** * 计算文本在画布中的宽度 */ exports.measureTextWidth = util_1.memoize(function (text, font) { if (font === void 0) { font = {}; } var fontSize = font.fontSize, fontFamily = font.fontFamily, fontWeight = font.fontWeight, fontStyle = font.fontStyle, fontVariant = font.fontVariant; ctx.font = [fontStyle, fontVariant, fontWeight, fontSize + "px", fontFamily].join(' '); return ctx.measureText(util_1.isString(text) ? text : '').width; }, function (text, font) { return (font ? tslib_1.__spreadArrays([text], util_1.values(font)).join('') : text); }); /** * 获取文本的 ... 文本。 * 算法(减少每次 measureText 的长度,measureText 的性能跟字符串时间相关): * 1. 先通过 STEP 逐步计算,找到最后一个小于 maxWidth 的字符串 * 2. 然后对最后这个字符串二分计算 * @param text 需要计算的文本, 由于历史原因 除了支持string,还支持空值,number和数组等 * @param maxWidth * @param font * TODO 后续更新省略算法 */ exports.getEllipsisText = function (text, maxWidth, font) { var STEP = 16; // 每次 16,调参工程师 var DOT_WIDTH = exports.measureTextWidth('...', font); var leftText; if (!util_1.isString(text)) { leftText = util_1.toString(text); } else { leftText = text; } var leftWidth = maxWidth; var r = []; // 最终的分段字符串 var currentText; var currentWidth; if (exports.measureTextWidth(text, font) <= maxWidth) { return text; } // 首先通过 step 计算,找出最大的未超出长度的 // eslint-disable-next-line no-constant-condition while (true) { // 更新字符串 currentText = leftText.substr(0, STEP); // 计算宽度 currentWidth = exports.measureTextWidth(currentText, font); // 超出剩余宽度,则停止 if (currentWidth + DOT_WIDTH > leftWidth) { if (currentWidth > leftWidth) { break; } } r.push(currentText); // 没有超出,则计算剩余宽度 leftWidth -= currentWidth; leftText = leftText.substr(STEP); // 字符串整体没有超出 if (!leftText) { return r.join(''); } } // 最下的最后一个 STEP,使用 1 递增(用二分效果更高) //eslint-disable-next-line no-constant-condition while (true) { // 更新字符串 currentText = leftText.substr(0, 1); // 计算宽度 currentWidth = exports.measureTextWidth(currentText, font); // 超出剩余宽度,则停止 if (currentWidth + DOT_WIDTH > leftWidth) { break; } r.push(currentText); // 没有超出,则计算剩余宽度 leftWidth -= currentWidth; leftText = leftText.substr(1); if (!leftText) { return r.join(''); } } return r.join('') + "..."; }; },{"@antv/util":803,"tslib":894}],715:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkShapeOverlap = exports.getOverlapArea = exports.moveInPanel = exports.checkOriginEqual = exports.forEachElement = exports.forEachGeometry = exports.getGeometryShapes = exports.getGeometryByType = exports.getAllGeometryByType = void 0; var util_1 = require("@antv/util"); var dependents_1 = require("../dependents"); function getAllGeometryByType(view, type) { return util_1.filter(view.geometries, function (geometry) { return geometry.type === type; }); } exports.getAllGeometryByType = getAllGeometryByType; function getGeometryByType(view, type) { return util_1.head(getAllGeometryByType(view, type)); } exports.getGeometryByType = getGeometryByType; function getGeometryShapes(geometry) { return util_1.map(geometry.elements, function (element) { return element.shape; }); } exports.getGeometryShapes = getGeometryShapes; function forEachGeometry(view, callback) { view.geometries.forEach(callback); } exports.forEachGeometry = forEachGeometry; function forEachElement(view, callback) { view.geometries.forEach(function (geometry) { geometry.elements.forEach(function (element) { callback(element); }); }); } exports.forEachElement = forEachElement; /** 检测是否有和已存在的Shape数据`相等`的情况 */ function checkOriginEqual(cur, dones, compare) { return util_1.some(dones, function (done) { return compare(done.get(dependents_1.ORIGIN), cur.get(dependents_1.ORIGIN)); }); } exports.checkOriginEqual = checkOriginEqual; /** 将label调整到panel内 */ function moveInPanel(shape, panel) { var box = shape.getBBox(); var deltaX = 0; var deltaY = 0; if (box.minX < panel.minX) { deltaX = box.minX - panel.minX; } else if (box.maxX > panel.maxX) { deltaX = box.maxX - panel.maxX; } if (deltaX) { shape.attr('x', shape.attr('x') - deltaX); } if (box.minY < panel.minY) { deltaY = box.minY - panel.minY; } else if (box.maxY > panel.maxY) { deltaY = box.maxY - panel.maxY; } if (deltaY) { shape.attr('y', shape.attr('y') - deltaY); } } exports.moveInPanel = moveInPanel; /** * 计算两个矩形之间的堆叠区域面积 */ function getOverlapArea(a, b, margin) { if (margin === void 0) { margin = 0; } var xOverlap = Math.max(0, Math.min(a.x + a.width + margin, b.x + b.width + margin) - Math.max(a.x - margin, b.x - margin)); var yOverlap = Math.max(0, Math.min(a.y + a.height + margin, b.y + b.height + margin) - Math.max(a.y - margin, b.y - margin)); return xOverlap * yOverlap; } exports.getOverlapArea = getOverlapArea; /** 检测是否和已布局的堆叠 */ function checkShapeOverlap(cur, dones) { var box = cur.getBBox(); return util_1.some(dones, function (done) { var target = done.getBBox(); return getOverlapArea(box, target, 2) > 0; }); } exports.checkShapeOverlap = checkShapeOverlap; },{"../dependents":425,"@antv/util":803}],716:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @description 扩展方法,提供 gl-matrix 为提供的方法 * */ var gl_matrix_1 = require("gl-matrix"); function leftTranslate(out, a, v) { var transMat = [0, 0, 0, 0, 0, 0, 0, 0, 0]; gl_matrix_1.mat3.fromTranslation(transMat, v); return gl_matrix_1.mat3.multiply(out, transMat, a); } exports.leftTranslate = leftTranslate; function leftRotate(out, a, rad) { var rotateMat = [0, 0, 0, 0, 0, 0, 0, 0, 0]; gl_matrix_1.mat3.fromRotation(rotateMat, rad); return gl_matrix_1.mat3.multiply(out, rotateMat, a); } exports.leftRotate = leftRotate; function leftScale(out, a, v) { var scaleMat = [0, 0, 0, 0, 0, 0, 0, 0, 0]; gl_matrix_1.mat3.fromScaling(scaleMat, v); return gl_matrix_1.mat3.multiply(out, scaleMat, a); } exports.leftScale = leftScale; function leftMultiply(out, a, a1) { return gl_matrix_1.mat3.multiply(out, a1, a); } /** * 根据 actions 来做 transform * @param m * @param actions */ function transform(m, actions) { var matrix = m ? [].concat(m) : [1, 0, 0, 0, 1, 0, 0, 0, 1]; for (var i = 0, len = actions.length; i < len; i++) { var action = actions[i]; switch (action[0]) { case 't': leftTranslate(matrix, matrix, [action[1], action[2]]); break; case 's': leftScale(matrix, matrix, [action[1], action[2]]); break; case 'r': leftRotate(matrix, matrix, action[1]); break; case 'm': leftMultiply(matrix, matrix, action[1]); break; default: break; } } return matrix; } exports.transform = transform; /** * 向量 v1 到 向量 v2 夹角的方向 * @param {Array} v1 向量 * @param {Array} v2 向量 * @return {Boolean} >= 0 顺时针 < 0 逆时针 */ function direction(v1, v2) { return v1[0] * v2[1] - v2[0] * v1[1]; } exports.direction = direction; /** * 二维向量 v1 到 v2 的夹角 * @param v1 * @param v2 * @param direct */ function angleTo(v1, v2, direct) { var ang = gl_matrix_1.vec2.angle(v1, v2); var angleLargeThanPI = direction(v1, v2) >= 0; if (direct) { if (angleLargeThanPI) { return Math.PI * 2 - ang; } return ang; } if (angleLargeThanPI) { return ang; } return Math.PI * 2 - ang; } exports.angleTo = angleTo; /** * 计算二维向量的垂直向量 * @param out * @param v * @param flag */ function vertical(out, v, flag) { if (flag) { out[0] = v[1]; out[1] = -1 * v[0]; } else { out[0] = -1 * v[1]; out[1] = v[0]; } return out; } exports.vertical = vertical; },{"gl-matrix":883}],717:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gl_matrix_1 = require("gl-matrix"); exports.mat3 = gl_matrix_1.mat3; exports.vec2 = gl_matrix_1.vec2; exports.vec3 = gl_matrix_1.vec3; var ext = require("./ext"); exports.ext = ext; },{"./ext":716,"gl-matrix":883}],718:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // http://schepers.cc/getting-to-the-point function catmullRom2Bezier(crp, z) { var d = []; // @ts-ignore for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { var p = [{ x: +crp[i - 2], y: +crp[i - 1], }, { x: +crp[i], y: +crp[i + 1], }, { x: +crp[i + 2], y: +crp[i + 3], }, { x: +crp[i + 4], y: +crp[i + 5], }]; if (z) { if (!i) { p[0] = { x: +crp[iLen - 2], y: +crp[iLen - 1], }; } else if (iLen - 4 === i) { p[3] = { x: +crp[0], y: +crp[1], }; } else if (iLen - 2 === i) { p[2] = { x: +crp[0], y: +crp[1], }; p[3] = { x: +crp[2], y: +crp[3], }; } } else { if (iLen - 4 === i) { p[3] = p[2]; } else if (!i) { p[0] = { x: +crp[i], y: +crp[i + 1], }; } } d.push(['C', (-p[0].x + 6 * p[1].x + p[2].x) / 6, (-p[0].y + 6 * p[1].y + p[2].y) / 6, (p[1].x + 6 * p[2].x - p[3].x) / 6, (p[1].y + 6 * p[2].y - p[3].y) / 6, p[2].x, p[2].y, ]); } return d; } exports.default = catmullRom2Bezier; },{}],719:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_equal_1 = require("@antv/util/lib/is-equal"); function getMinDiff(del, add, modify) { var type = null; var min = modify; if (add < min) { min = add; type = 'add'; } if (del < min) { min = del; type = 'del'; } return { type: type, min: min, }; } /* * https://en.wikipedia.org/wiki/Levenshtein_distance * 计算两条path的编辑距离 */ var levenshteinDistance = function (source, target) { var sourceLen = source.length; var targetLen = target.length; var sourceSegment, targetSegment; var temp = 0; if (sourceLen === 0 || targetLen === 0) { return null; } var dist = []; for (var i = 0; i <= sourceLen; i++) { dist[i] = []; dist[i][0] = { min: i }; } for (var j = 0; j <= targetLen; j++) { dist[0][j] = { min: j }; } for (var i = 1; i <= sourceLen; i++) { sourceSegment = source[i - 1]; for (var j = 1; j <= targetLen; j++) { targetSegment = target[j - 1]; if (is_equal_1.default(sourceSegment, targetSegment)) { temp = 0; } else { temp = 1; } var del = dist[i - 1][j].min + 1; var add = dist[i][j - 1].min + 1; var modify = dist[i - 1][j - 1].min + temp; dist[i][j] = getMinDiff(del, add, modify); } } return dist; }; function fillPathByDiff(source, target) { var diffMatrix = levenshteinDistance(source, target); var sourceLen = source.length; var targetLen = target.length; var changes = []; var index = 1; var minPos = 1; // 如果source和target不是完全不相等 // @ts-ignore if (diffMatrix[sourceLen][targetLen] !== sourceLen) { // 获取从source到target所需改动 for (var i = 1; i <= sourceLen; i++) { var min = diffMatrix[i][i].min; minPos = i; for (var j = index; j <= targetLen; j++) { if (diffMatrix[i][j].min < min) { min = diffMatrix[i][j].min; minPos = j; } } index = minPos; if (diffMatrix[i][index].type) { changes.push({ index: i - 1, type: diffMatrix[i][index].type }); } } // 对source进行增删path for (var i = changes.length - 1; i >= 0; i--) { index = changes[i].index; if (changes[i].type === 'add') { // @ts-ignore source.splice(index, 0, [].concat(source[index])); } else { // @ts-ignore source.splice(index, 1); } } } // source尾部补齐 sourceLen = source.length; if (sourceLen < targetLen) { for (var i = 0; i < (targetLen - sourceLen); i++) { if (source[sourceLen - 1][0] === 'z' || source[sourceLen - 1][0] === 'Z') { // @ts-ignore source.splice(sourceLen - 2, 0, source[sourceLen - 2]); } else { // @ts-ignore source.push(source[sourceLen - 1]); } } } return source; } exports.default = fillPathByDiff; },{"@antv/util/lib/is-equal":813}],720:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function decasteljau(points, t) { var left = []; var right = []; function recurse(points, t) { if (points.length === 1) { left.push(points[0]); right.push(points[0]); } else { var middlePoints = []; for (var i = 0; i < points.length - 1; i++) { if (i === 0) { left.push(points[0]); } if (i === points.length - 2) { right.push(points[i + 1]); } middlePoints[i] = [(1 - t) * points[i][0] + t * points[i + 1][0], (1 - t) * points[i][1] + t * points[i + 1][1]]; } recurse(middlePoints, t); } } if (points.length) { recurse(points, t); } return { left: left, right: right.reverse() }; } function splitCurve(start, end, count) { var points = [[start[1], start[2]]]; count = count || 2; var segments = []; if (end[0] === 'A') { points.push(end[6]); points.push(end[7]); } else if (end[0] === 'C') { points.push([end[1], end[2]]); points.push([end[3], end[4]]); points.push([end[5], end[6]]); } else if (end[0] === 'S' || end[0] === 'Q') { points.push([end[1], end[2]]); points.push([end[3], end[4]]); } else { points.push([end[1], end[2]]); } var leftSegments = points; var t = 1 / count; for (var i = 0; i < count - 1; i++) { var rt = t / (1 - t * i); var split = decasteljau(leftSegments, rt); segments.push(split.left); leftSegments = split.right; } segments.push(leftSegments); var result = segments.map(function (segment) { var cmd = []; if (segment.length === 4) { cmd.push('C'); cmd = cmd.concat(segment[2]); } if (segment.length >= 3) { if (segment.length === 3) { cmd.push('Q'); } cmd = cmd.concat(segment[1]); } if (segment.length === 2) { cmd.push('L'); } cmd = cmd.concat(segment[segment.length - 1]); return cmd; }); return result; } function splitSegment(start, end, count) { if (count === 1) { return [[].concat(start)]; } var segments = []; if (end[0] === 'L' || end[0] === 'C' || end[0] === 'Q') { segments = segments.concat(splitCurve(start, end, count)); } else { var temp = [].concat(start); if (temp[0] === 'M') { temp[0] = 'L'; } for (var i = 0; i <= count - 1; i++) { segments.push(temp); } } return segments; } function fillPath(source, target) { if (source.length === 1) { return source; } var sourceLen = source.length - 1; var targetLen = target.length - 1; var ratio = sourceLen / targetLen; var segmentsToFill = []; if (source.length === 1 && source[0][0] === 'M') { for (var i = 0; i < targetLen - sourceLen; i++) { source.push(source[0]); } return source; } for (var i = 0; i < targetLen; i++) { var index = Math.floor(ratio * i); segmentsToFill[index] = (segmentsToFill[index] || 0) + 1; } var filled = segmentsToFill.reduce(function (filled, count, i) { if (i === sourceLen) { return filled.concat(source[sourceLen]); } return filled.concat(splitSegment(source[i], source[i + 1], count)); }, []); filled.unshift(source[0]); if (target[targetLen] === 'Z' || target[targetLen] === 'z') { filled.push('Z'); } return filled; } exports.default = fillPath; },{}],721:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* * 抽取pathSegment中的关键点 * M,L,A,Q,H,V一个端点 * Q, S抽取一个端点,一个控制点 * C抽取一个端点,两个控制点 */ function _getSegmentPoints(segment) { var points = []; switch (segment[0]) { case 'M': points.push([segment[1], segment[2]]); break; case 'L': points.push([segment[1], segment[2]]); break; case 'A': points.push([segment[6], segment[7]]); break; case 'Q': points.push([segment[3], segment[4]]); points.push([segment[1], segment[2]]); break; case 'T': points.push([segment[1], segment[2]]); break; case 'C': points.push([segment[5], segment[6]]); points.push([segment[1], segment[2]]); points.push([segment[3], segment[4]]); break; case 'S': points.push([segment[3], segment[4]]); points.push([segment[1], segment[2]]); break; case 'H': points.push([segment[1], segment[1]]); break; case 'V': points.push([segment[1], segment[1]]); break; default: } return points; } // 将两个点均分成count个点 function _splitPoints(points, former, count) { var result = [].concat(points); var index; var t = 1 / (count + 1); var formerEnd = _getSegmentPoints(former)[0]; for (var i = 1; i <= count; i++) { t *= i; index = Math.floor(points.length * t); if (index === 0) { result.unshift([formerEnd[0] * t + points[index][0] * (1 - t), formerEnd[1] * t + points[index][1] * (1 - t)]); } else { result.splice(index, 0, [formerEnd[0] * t + points[index][0] * (1 - t), formerEnd[1] * t + points[index][1] * (1 - t)]); } } return result; } function formatPath(fromPath, toPath) { if (fromPath.length <= 1) { return fromPath; } var points; for (var i = 0; i < toPath.length; i++) { if (fromPath[i][0] !== toPath[i][0]) { // 获取fromPath的pathSegment的端点,根据toPath的指令对其改造 points = _getSegmentPoints(fromPath[i]); switch (toPath[i][0]) { case 'M': fromPath[i] = ['M'].concat(points[0]); break; case 'L': fromPath[i] = ['L'].concat(points[0]); break; case 'A': fromPath[i] = [].concat(toPath[i]); fromPath[i][6] = points[0][0]; fromPath[i][7] = points[0][1]; break; case 'Q': if (points.length < 2) { if (i > 0) { points = _splitPoints(points, fromPath[i - 1], 1); } else { fromPath[i] = toPath[i]; break; } } fromPath[i] = ['Q'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, [])); break; case 'T': fromPath[i] = ['T'].concat(points[0]); break; case 'C': if (points.length < 3) { if (i > 0) { points = _splitPoints(points, fromPath[i - 1], 2); } else { fromPath[i] = toPath[i]; break; } } fromPath[i] = ['C'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, [])); break; case 'S': if (points.length < 2) { if (i > 0) { points = _splitPoints(points, fromPath[i - 1], 1); } else { fromPath[i] = toPath[i]; break; } } fromPath[i] = ['S'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, [])); break; default: fromPath[i] = toPath[i]; } } } return fromPath; } exports.default = formatPath; },{}],722:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var mod_1 = require("@antv/util/lib/mod"); var to_radian_1 = require("@antv/util/lib/to-radian"); // 向量长度 function vMag(v) { return Math.sqrt(v[0] * v[0] + v[1] * v[1]); } // u.v/|u||v|,计算夹角的余弦值 function vRatio(u, v) { // 当存在一个向量的长度为 0 时,夹角也为 0,即夹角的余弦值为 1 return vMag(u) * vMag(v) ? (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)) : 1; } // 向量角度 function vAngle(u, v) { return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v)); } /** * 判断两个点是否重合,点坐标的格式为 [x, y] * @param {Array} point1 第一个点 * @param {Array} point2 第二个点 */ function isSamePoint(point1, point2) { return point1[0] === point2[0] && point1[1] === point2[1]; } exports.isSamePoint = isSamePoint; // A 0:rx 1:ry 2:x-axis-rotation 3:large-arc-flag 4:sweep-flag 5: x 6: y function getArcParams(startPoint, params) { var rx = params[1]; var ry = params[2]; var xRotation = mod_1.default(to_radian_1.default(params[3]), Math.PI * 2); var arcFlag = params[4]; var sweepFlag = params[5]; // 弧形起点坐标 var x1 = startPoint[0]; var y1 = startPoint[1]; // 弧形终点坐标 var x2 = params[6]; var y2 = params[7]; var xp = (Math.cos(xRotation) * (x1 - x2)) / 2.0 + (Math.sin(xRotation) * (y1 - y2)) / 2.0; var yp = (-1 * Math.sin(xRotation) * (x1 - x2)) / 2.0 + (Math.cos(xRotation) * (y1 - y2)) / 2.0; var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); if (lambda > 1) { rx *= Math.sqrt(lambda); ry *= Math.sqrt(lambda); } var diff = rx * rx * (yp * yp) + ry * ry * (xp * xp); var f = diff ? Math.sqrt((rx * rx * (ry * ry) - diff) / diff) : 1; if (arcFlag === sweepFlag) { f *= -1; } if (isNaN(f)) { f = 0; } // 旋转前的起点坐标,且当长半轴和短半轴的长度为 0 时,坐标按 (0, 0) 处理 var cxp = ry ? (f * rx * yp) / ry : 0; var cyp = rx ? (f * -ry * xp) / rx : 0; // 椭圆圆心坐标 var cx = (x1 + x2) / 2.0 + Math.cos(xRotation) * cxp - Math.sin(xRotation) * cyp; var cy = (y1 + y2) / 2.0 + Math.sin(xRotation) * cxp + Math.cos(xRotation) * cyp; // 起始点的单位向量 var u = [(xp - cxp) / rx, (yp - cyp) / ry]; // 终止点的单位向量 var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry]; // 计算起始点和圆心的连线,与 x 轴正方向的夹角 var theta = vAngle([1, 0], u); // 计算圆弧起始点和终止点与椭圆圆心连线的夹角 var dTheta = vAngle(u, v); if (vRatio(u, v) <= -1) { dTheta = Math.PI; } if (vRatio(u, v) >= 1) { dTheta = 0; } if (sweepFlag === 0 && dTheta > 0) { dTheta = dTheta - 2 * Math.PI; } if (sweepFlag === 1 && dTheta < 0) { dTheta = dTheta + 2 * Math.PI; } return { cx: cx, cy: cy, // 弧形的起点和终点相同时,长轴和短轴的长度按 0 处理 rx: isSamePoint(startPoint, [x2, y2]) ? 0 : rx, ry: isSamePoint(startPoint, [x2, y2]) ? 0 : ry, startAngle: theta, endAngle: theta + dTheta, xRotation: xRotation, arcFlag: arcFlag, sweepFlag: sweepFlag, }; } exports.default = getArcParams; },{"@antv/util/lib/mod":845,"@antv/util/lib/to-radian":865}],723:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var isBetween = function (value, min, max) { return value >= min && value <= max; }; function getLineIntersect(p0, p1, p2, p3) { var tolerance = 0.001; var E = { x: p2.x - p0.x, y: p2.y - p0.y, }; var D0 = { x: p1.x - p0.x, y: p1.y - p0.y, }; var D1 = { x: p3.x - p2.x, y: p3.y - p2.y, }; var kross = D0.x * D1.y - D0.y * D1.x; var sqrKross = kross * kross; var sqrLen0 = D0.x * D0.x + D0.y * D0.y; var sqrLen1 = D1.x * D1.x + D1.y * D1.y; var point = null; if (sqrKross > tolerance * sqrLen0 * sqrLen1) { var s = (E.x * D1.y - E.y * D1.x) / kross; var t = (E.x * D0.y - E.y * D0.x) / kross; if (isBetween(s, 0, 1) && isBetween(t, 0, 1)) { point = { x: p0.x + s * D0.x, y: p0.y + s * D0.y, }; } } return point; } exports.default = getLineIntersect; ; },{}],724:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var parse_path_1 = require("./parse-path"); exports.parsePath = parse_path_1.default; var catmull_rom_2_bezier_1 = require("./catmull-rom-2-bezier"); exports.catmullRom2Bezier = catmull_rom_2_bezier_1.default; var fill_path_1 = require("./fill-path"); exports.fillPath = fill_path_1.default; var fill_path_by_diff_1 = require("./fill-path-by-diff"); exports.fillPathByDiff = fill_path_by_diff_1.default; var format_path_1 = require("./format-path"); exports.formatPath = format_path_1.default; var path_intersection_1 = require("./path-intersection"); exports.pathIntersection = path_intersection_1.default; var parse_path_array_1 = require("./parse-path-array"); exports.parsePathArray = parse_path_array_1.default; var parse_path_string_1 = require("./parse-path-string"); exports.parsePathString = parse_path_string_1.default; var path_2_curve_1 = require("./path-2-curve"); exports.path2Curve = path_2_curve_1.default; var path_2_absolute_1 = require("./path-2-absolute"); exports.path2Absolute = path_2_absolute_1.default; var rect_path_1 = require("./rect-path"); exports.reactPath = rect_path_1.default; var get_arc_params_1 = require("./get-arc-params"); exports.getArcParams = get_arc_params_1.default; var path_2_segments_1 = require("./path-2-segments"); exports.path2Segments = path_2_segments_1.default; var get_line_intersect_1 = require("./get-line-intersect"); exports.getLineIntersect = get_line_intersect_1.default; var is_polygons_intersect_1 = require("./is-polygons-intersect"); exports.isPolygonsIntersect = is_polygons_intersect_1.default; var point_in_polygon_1 = require("./point-in-polygon"); exports.isPointInPolygon = point_in_polygon_1.default; },{"./catmull-rom-2-bezier":718,"./fill-path":720,"./fill-path-by-diff":719,"./format-path":721,"./get-arc-params":722,"./get-line-intersect":723,"./is-polygons-intersect":725,"./parse-path":728,"./parse-path-array":726,"./parse-path-string":727,"./path-2-absolute":729,"./path-2-curve":730,"./path-2-segments":731,"./path-intersection":732,"./point-in-polygon":733,"./rect-path":734}],725:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var point_in_polygon_1 = require("./point-in-polygon"); var get_line_intersect_1 = require("./get-line-intersect"); var util_1 = require("@antv/util"); function parseToLines(points) { var lines = []; var count = points.length; for (var i = 0; i < count - 1; i++) { var point = points[i]; var next = points[i + 1]; lines.push({ from: { x: point[0], y: point[1] }, to: { x: next[0], y: next[1] } }); } if (lines.length > 1) { var first = points[0]; var last = points[count - 1]; lines.push({ from: { x: last[0], y: last[1] }, to: { x: first[0], y: first[1] } }); } return lines; } function lineIntersectPolygon(lines, line) { var isIntersect = false; util_1.each(lines, function (l) { if (get_line_intersect_1.default(l.from, l.to, line.from, line.to)) { isIntersect = true; return false; } }); return isIntersect; } function getBBox(points) { var xArr = points.map(function (p) { return p[0]; }); var yArr = points.map(function (p) { return p[1]; }); return { minX: Math.min.apply(null, xArr), maxX: Math.max.apply(null, xArr), minY: Math.min.apply(null, yArr), maxY: Math.max.apply(null, yArr) }; } function intersectBBox(box1, box2) { return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY); } function isPolygonsIntersect(points1, points2) { // 空数组,或者一个点返回 false if (points1.length < 2 || points2.length < 2) { return false; } var bbox1 = getBBox(points1); var bbox2 = getBBox(points2); // 判定包围盒是否相交,比判定点是否在多边形内要快的多,可以筛选掉大多数情况 if (!intersectBBox(bbox1, bbox2)) { return false; } var isIn = false; // 判定点是否在多边形内部,一旦有一个点在另一个多边形内,则返回 util_1.each(points2, function (point) { if (point_in_polygon_1.default(points1, point[0], point[1])) { isIn = true; return false; } }); if (isIn) { return true; } // 两个多边形都需要判定 util_1.each(points1, function (point) { if (point_in_polygon_1.default(points2, point[0], point[1])) { isIn = true; return false; } }); if (isIn) { return true; } var lines1 = parseToLines(points1); var lines2 = parseToLines(points2); var isIntersect = false; util_1.each(lines2, function (line) { if (lineIntersectPolygon(lines1, line)) { isIntersect = true; return false; } }); return isIntersect; } exports.default = isPolygonsIntersect; },{"./get-line-intersect":723,"./point-in-polygon":733,"@antv/util":803}],726:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var p2s = /,?([a-z]),?/gi; function parsePathArray(path) { return path.join(',').replace(p2s, '$1'); } exports.default = parsePathArray; },{}],727:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("@antv/util/lib/is-array"); var SPACES = '\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029'; var PATH_COMMAND = new RegExp('([a-z])[' + SPACES + ',]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[' + SPACES + ']*,?[' + SPACES + ']*)+)', 'ig'); var PATH_VALUES = new RegExp('(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[' + SPACES + ']*,?[' + SPACES + ']*', 'ig'); // Parses given path string into an array of arrays of path segments function parsePathString(pathString) { if (!pathString) { return null; } if (is_array_1.default(pathString)) { return pathString; } var paramCounts = { a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0, }; var data = []; String(pathString).replace(PATH_COMMAND, function (a, b, c) { var params = []; var name = b.toLowerCase(); c.replace(PATH_VALUES, function (a, b) { b && params.push(+b); }); if (name === 'm' && params.length > 2) { data.push([b].concat(params.splice(0, 2))); name = 'l'; b = b === 'm' ? 'l' : 'L'; } if (name === 'o' && params.length === 1) { data.push([b, params[0]]); } if (name === 'r') { data.push([b].concat(params)); } else { while (params.length >= paramCounts[name]) { data.push([b].concat(params.splice(0, paramCounts[name]))); if (!paramCounts[name]) { break; } } } return ''; }); return data; } exports.default = parsePathString; },{"@antv/util/lib/is-array":806}],728:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("@antv/util/lib/each"); var is_array_1 = require("@antv/util/lib/is-array"); var is_string_1 = require("@antv/util/lib/is-string"); var regexTags = /[MLHVQTCSAZ]([^MLHVQTCSAZ]*)/ig; var regexDot = /[^\s\,]+/ig; function parsePath(p) { var path = p || []; if (is_array_1.default(path)) { return path; } if (is_string_1.default(path)) { path = path.match(regexTags); each_1.default(path, function (item, index) { // @ts-ignore item = item.match(regexDot); if (item[0].length > 1) { var tag = item[0].charAt(0); // @ts-ignore item.splice(1, 0, item[0].substr(1)); // @ts-ignore item[0] = tag; } // @ts-ignore each_1.default(item, function (sub, i) { if (!isNaN(sub)) { // @ts-ignore item[i] = +sub; } }); // @ts-ignore path[index] = item; }); return path; } } exports.default = parsePath; },{"@antv/util/lib/each":778,"@antv/util/lib/is-array":806,"@antv/util/lib/is-string":832}],729:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var parse_path_string_1 = require("./parse-path-string"); var REGEX_MD = /[a-z]/; function toSymmetry(p, c) { return [ c[0] + (c[0] - p[0]), c[1] + (c[1] - p[1]), ]; } function pathToAbsolute(pathString) { var pathArray = parse_path_string_1.default(pathString); if (!pathArray || !pathArray.length) { return [ ['M', 0, 0], ]; } var needProcess = false; // 如果存在小写的命令或者 V,H,T,S 则需要处理 for (var i = 0; i < pathArray.length; i++) { var cmd = pathArray[i][0]; // 如果存在相对位置的命令,则中断返回 if (REGEX_MD.test(cmd) || ['V', 'H', 'T', 'S'].indexOf(cmd) >= 0) { needProcess = true; break; } } // 如果不存在相对命令,则直接返回 // 如果在业务上都写绝对路径,这种方式最快,仅做了一次检测 if (!needProcess) { return pathArray; } var res = []; var x = 0; var y = 0; var mx = 0; var my = 0; var start = 0; var pa0; var dots; var first = pathArray[0]; if (first[0] === 'M' || first[0] === 'm') { x = +first[1]; y = +first[2]; mx = x; my = y; start++; res[0] = ['M', x, y]; } for (var i = start, ii = pathArray.length; i < ii; i++) { var pa = pathArray[i]; var preParams = res[i - 1]; // 取前一个已经处理后的节点,否则会出现问题 var r = []; var cmd = pa[0]; var upCmd = cmd.toUpperCase(); if (cmd !== upCmd) { r[0] = upCmd; switch (upCmd) { case 'A': r[1] = pa[1]; r[2] = pa[2]; r[3] = pa[3]; r[4] = pa[4]; r[5] = pa[5]; r[6] = +pa[6] + x; r[7] = +pa[7] + y; break; case 'V': r[1] = +pa[1] + y; break; case 'H': r[1] = +pa[1] + x; break; case 'M': mx = +pa[1] + x; my = +pa[2] + y; break; // for lint default: for (var j = 1, jj = pa.length; j < jj; j++) { r[j] = +pa[j] + ((j % 2) ? x : y); } } } else { // 如果本来已经大写,则不处理 r = pathArray[i]; } // 需要在外面统一做,同时处理 V,H,S,T 等特殊指令 switch (upCmd) { case 'Z': x = +mx; y = +my; break; case 'H': x = r[1]; r = ['L', x, y]; break; case 'V': y = r[1]; r = ['L', x, y]; break; case 'T': x = r[1]; y = r[2]; // 以 x, y 为中心的,上一个控制点的对称点 // 需要假设上一个节点的命令为 Q var symetricT = toSymmetry([preParams[1], preParams[2]], [preParams[3], preParams[4]]); r = ['Q', symetricT[0], symetricT[1], x, y]; break; case 'S': x = r[r.length - 2]; y = r[r.length - 1]; // 以 x,y 为中心,取上一个控制点, // 需要假设上一个线段为 C 或者 S var length_1 = preParams.length; var symetricS = toSymmetry([preParams[length_1 - 4], preParams[length_1 - 3]], [preParams[length_1 - 2], preParams[length_1 - 1]]); r = ['C', symetricS[0], symetricS[1], r[1], r[2], x, y]; break; case 'M': mx = r[r.length - 2]; my = r[r.length - 1]; break; // for lint default: x = r[r.length - 2]; y = r[r.length - 1]; } res.push(r); } return res; } exports.default = pathToAbsolute; },{"./parse-path-string":727}],730:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path_2_absolute_1 = require("./path-2-absolute"); var a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { // for more information of where this math came from visit: // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes if (rx === ry) { rx += 1; } var _120 = (Math.PI * 120) / 180; var rad = (Math.PI / 180) * (+angle || 0); var res = []; var xy; var f1; var f2; var cx; var cy; var rotate = function (x, y, rad) { var X = x * Math.cos(rad) - y * Math.sin(rad); var Y = x * Math.sin(rad) + y * Math.cos(rad); return { x: X, y: Y, }; }; if (!recursive) { xy = rotate(x1, y1, -rad); x1 = xy.x; y1 = xy.y; xy = rotate(x2, y2, -rad); x2 = xy.x; y2 = xy.y; if (x1 === x2 && y1 === y2) { // 若弧的起始点和终点重叠则错开一点 x2 += 1; y2 += 1; } // const cos = Math.cos(Math.PI / 180 * angle); // const sin = Math.sin(Math.PI / 180 * angle); var x = (x1 - x2) / 2; var y = (y1 - y2) / 2; var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); if (h > 1) { h = Math.sqrt(h); rx = h * rx; ry = h * ry; } var rx2 = rx * rx; var ry2 = ry * ry; var k = (large_arc_flag === sweep_flag ? -1 : 1) * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))); cx = (k * rx * y) / ry + (x1 + x2) / 2; cy = (k * -ry * x) / rx + (y1 + y2) / 2; f1 = Math.asin(Number(((y1 - cy) / ry).toFixed(9))); f2 = Math.asin(Number(((y2 - cy) / ry).toFixed(9))); f1 = x1 < cx ? Math.PI - f1 : f1; f2 = x2 < cx ? Math.PI - f2 : f2; f1 < 0 && (f1 = Math.PI * 2 + f1); f2 < 0 && (f2 = Math.PI * 2 + f2); if (sweep_flag && f1 > f2) { f1 = f1 - Math.PI * 2; } if (!sweep_flag && f2 > f1) { f2 = f2 - Math.PI * 2; } } else { f1 = recursive[0]; f2 = recursive[1]; cx = recursive[2]; cy = recursive[3]; } var df = f2 - f1; if (Math.abs(df) > _120) { var f2old = f2; var x2old = x2; var y2old = y2; f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); x2 = cx + rx * Math.cos(f2); y2 = cy + ry * Math.sin(f2); res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); } df = f2 - f1; var c1 = Math.cos(f1); var s1 = Math.sin(f1); var c2 = Math.cos(f2); var s2 = Math.sin(f2); var t = Math.tan(df / 4); var hx = (4 / 3) * rx * t; var hy = (4 / 3) * ry * t; var m1 = [x1, y1]; var m2 = [x1 + hx * s1, y1 - hy * c1]; var m3 = [x2 + hx * s2, y2 - hy * c2]; var m4 = [x2, y2]; m2[0] = 2 * m1[0] - m2[0]; m2[1] = 2 * m1[1] - m2[1]; if (recursive) { return [m2, m3, m4].concat(res); } res = [m2, m3, m4] .concat(res) .join() .split(','); var newres = []; for (var i = 0, ii = res.length; i < ii; i++) { newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; } return newres; }; var l2c = function (x1, y1, x2, y2) { return [x1, y1, x2, y2, x2, y2]; }; var q2c = function (x1, y1, ax, ay, x2, y2) { var _13 = 1 / 3; var _23 = 2 / 3; return [_13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2]; }; function pathTocurve(path, path2) { var p = path_2_absolute_1.default(path); var p2 = path2 && path_2_absolute_1.default(path2); var attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null, }; var attrs2 = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null, }; var pcoms1 = []; // path commands of original path p var pcoms2 = []; // path commands of original path p2 var pfirst = ''; // temporary holder for original path command var pcom = ''; // holder for previous path command of original path var ii; var processPath = function (path, d, pcom) { var nx, ny; if (!path) { return ['C', d.x, d.y, d.x, d.y, d.x, d.y]; } !(path[0] in { T: 1, Q: 1, }) && (d.qx = d.qy = null); switch (path[0]) { case 'M': d.X = path[1]; d.Y = path[2]; break; case 'A': path = ['C'].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1)))); break; case 'S': if (pcom === 'C' || pcom === 'S') { // In "S" case we have to take into account, if the previous command is C/S. nx = d.x * 2 - d.bx; // And reflect the previous ny = d.y * 2 - d.by; // command's control point relative to the current point. } else { // or some else or nothing nx = d.x; ny = d.y; } path = ['C', nx, ny].concat(path.slice(1)); break; case 'T': if (pcom === 'Q' || pcom === 'T') { // In "T" case we have to take into account, if the previous command is Q/T. d.qx = d.x * 2 - d.qx; // And make a reflection similar d.qy = d.y * 2 - d.qy; // to case "S". } else { // or something else or nothing d.qx = d.x; d.qy = d.y; } path = ['C'].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); break; case 'Q': d.qx = path[1]; d.qy = path[2]; path = ['C'].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4])); break; case 'L': path = ['C'].concat(l2c(d.x, d.y, path[1], path[2])); break; case 'H': path = ['C'].concat(l2c(d.x, d.y, path[1], d.y)); break; case 'V': path = ['C'].concat(l2c(d.x, d.y, d.x, path[1])); break; case 'Z': path = ['C'].concat(l2c(d.x, d.y, d.X, d.Y)); break; default: break; } return path; }; var fixArc = function (pp, i) { if (pp[i].length > 7) { pp[i].shift(); var pi = pp[i]; while (pi.length) { pcoms1[i] = 'A'; // if created multiple C:s, their original seg is saved p2 && (pcoms2[i] = 'A'); // the same as above pp.splice(i++, 0, ['C'].concat(pi.splice(0, 6))); } pp.splice(i, 1); ii = Math.max(p.length, (p2 && p2.length) || 0); } }; var fixM = function (path1, path2, a1, a2, i) { if (path1 && path2 && path1[i][0] === 'M' && path2[i][0] !== 'M') { path2.splice(i, 0, ['M', a2.x, a2.y]); a1.bx = 0; a1.by = 0; a1.x = path1[i][1]; a1.y = path1[i][2]; ii = Math.max(p.length, (p2 && p2.length) || 0); } }; ii = Math.max(p.length, (p2 && p2.length) || 0); for (var i = 0; i < ii; i++) { p[i] && (pfirst = p[i][0]); // save current path command if (pfirst !== 'C') { // C is not saved yet, because it may be result of conversion pcoms1[i] = pfirst; // Save current path command i && (pcom = pcoms1[i - 1]); // Get previous path command pcom } p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath if (pcoms1[i] !== 'A' && pfirst === 'C') pcoms1[i] = 'C'; // A is the only command // which may produce multiple C:s // so we have to make sure that C is also C in original path fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1 if (p2) { // the same procedures is done to p2 p2[i] && (pfirst = p2[i][0]); if (pfirst !== 'C') { pcoms2[i] = pfirst; i && (pcom = pcoms2[i - 1]); } p2[i] = processPath(p2[i], attrs2, pcom); if (pcoms2[i] !== 'A' && pfirst === 'C') { pcoms2[i] = 'C'; } fixArc(p2, i); } fixM(p, p2, attrs, attrs2, i); fixM(p2, p, attrs2, attrs, i); var seg = p[i]; var seg2 = p2 && p2[i]; var seglen = seg.length; var seg2len = p2 && seg2.length; attrs.x = seg[seglen - 2]; attrs.y = seg[seglen - 1]; attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x; attrs.by = parseFloat(seg[seglen - 3]) || attrs.y; attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x); attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y); attrs2.x = p2 && seg2[seg2len - 2]; attrs2.y = p2 && seg2[seg2len - 1]; } return p2 ? [p, p2] : p; } exports.default = pathTocurve; },{"./path-2-absolute":729}],731:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var get_arc_params_1 = require("./get-arc-params"); var get_arc_params_2 = require("./get-arc-params"); var parse_path_1 = require("./parse-path"); // 点对称 function toSymmetry(point, center) { return [center[0] + (center[0] - point[0]), center[1] + (center[1] - point[1])]; } function getSegments(path) { path = parse_path_1.default(path); var segments = []; var currentPoint = null; // 当前图形 var nextParams = null; // 下一节点的 path 参数 var startMovePoint = null; // 开始 M 的点,可能会有多个 var lastStartMovePointIndex = 0; // 最近一个开始点 M 的索引 var count = path.length; for (var i = 0; i < count; i++) { var params = path[i]; nextParams = path[i + 1]; var command = params[0]; // 数学定义上的参数,便于后面的计算 var segment = { command: command, prePoint: currentPoint, params: params, startTangent: null, endTangent: null, }; switch (command) { case 'M': startMovePoint = [params[1], params[2]]; lastStartMovePointIndex = i; break; case 'A': var arcParams = get_arc_params_1.default(currentPoint, params); segment['arcParams'] = arcParams; break; default: break; } if (command === 'Z') { // 有了 Z 后,当前节点从开始 M 的点开始 currentPoint = startMovePoint; // 如果当前点的命令为 Z,相当于当前点为最近一个 M 点,则下一个点直接指向最近一个 M 点的下一个点 nextParams = path[lastStartMovePointIndex + 1]; } else { var len = params.length; currentPoint = [params[len - 2], params[len - 1]]; } if (nextParams && nextParams[0] === 'Z') { // 如果下一个点的命令为 Z,则下一个点直接指向最近一个 M 点 nextParams = path[lastStartMovePointIndex]; if (segments[lastStartMovePointIndex]) { // 如果下一个点的命令为 Z,则最近一个 M 点的前一个点为当前点 segments[lastStartMovePointIndex].prePoint = currentPoint; } } segment['currentPoint'] = currentPoint; // 如果当前点与最近一个 M 点相同,则最近一个 M 点的前一个点为当前点的前一个点 if (segments[lastStartMovePointIndex] && get_arc_params_2.isSamePoint(currentPoint, segments[lastStartMovePointIndex].currentPoint)) { segments[lastStartMovePointIndex].prePoint = segment.prePoint; } var nextPoint = nextParams ? [nextParams[nextParams.length - 2], nextParams[nextParams.length - 1]] : null; segment['nextPoint'] = nextPoint; // Add startTangent and endTangent var prePoint = segment.prePoint; if (['L', 'H', 'V'].includes(command)) { segment.startTangent = [prePoint[0] - currentPoint[0], prePoint[1] - currentPoint[1]]; segment.endTangent = [currentPoint[0] - prePoint[0], currentPoint[1] - prePoint[1]]; } else if (command === 'Q') { // 二次贝塞尔曲线只有一个控制点 var cp = [params[1], params[2]]; // 二次贝塞尔曲线的终点为 currentPoint segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]]; segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]]; } else if (command === 'T') { var preSegment = segments[i - 1]; var cp = toSymmetry(preSegment.currentPoint, prePoint); if (preSegment.command === 'Q') { segment.command = 'Q'; segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]]; segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]]; } else { segment.command = 'TL'; segment.startTangent = [prePoint[0] - currentPoint[0], prePoint[1] - currentPoint[1]]; segment.endTangent = [currentPoint[0] - prePoint[0], currentPoint[1] - prePoint[1]]; } } else if (command === 'C') { // 三次贝塞尔曲线有两个控制点 var cp1 = [params[1], params[2]]; var cp2 = [params[3], params[4]]; segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]]; segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]]; } else if (command === 'S') { var preSegment = segments[i - 1]; var cp1 = toSymmetry(preSegment.currentPoint, prePoint); var cp2 = [params[1], params[2]]; if (preSegment.command === 'C') { segment.command = 'C'; // 将 S 命令变换为 C 命令 segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]]; segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]]; } else { segment.command = 'SQ'; // 将 S 命令变换为 SQ 命令 segment.startTangent = [prePoint[0] - cp2[0], prePoint[1] - cp2[1]]; segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]]; } } else if (command === 'A') { var d = 0.001; var _a = segment['arcParams'] || {}, _b = _a.cx, cx = _b === void 0 ? 0 : _b, _c = _a.cy, cy = _c === void 0 ? 0 : _c, _d = _a.rx, rx = _d === void 0 ? 0 : _d, _e = _a.ry, ry = _e === void 0 ? 0 : _e, _f = _a.sweepFlag, sweepFlag = _f === void 0 ? 0 : _f, _g = _a.startAngle, startAngle = _g === void 0 ? 0 : _g, _h = _a.endAngle, endAngle = _h === void 0 ? 0 : _h; if (sweepFlag === 0) { d *= -1; } var dx1 = rx * Math.cos(startAngle - d) + cx; var dy1 = ry * Math.sin(startAngle - d) + cy; segment.startTangent = [dx1 - startMovePoint[0], dy1 - startMovePoint[1]]; var dx2 = rx * Math.cos(startAngle + endAngle + d) + cx; var dy2 = ry * Math.sin(startAngle + endAngle - d) + cy; segment.endTangent = [prePoint[0] - dx2, prePoint[1] - dy2]; } segments.push(segment); } return segments; } exports.default = getSegments; },{"./get-arc-params":722,"./parse-path":728}],732:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var rect_path_1 = require("./rect-path"); var path_2_curve_1 = require("./path-2-curve"); var base3 = function (t, p1, p2, p3, p4) { var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4; var t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; return t * t2 - 3 * p1 + 3 * p2; }; var bezlen = function (x1, y1, x2, y2, x3, y3, x4, y4, z) { if (z === null) { z = 1; } z = z > 1 ? 1 : z < 0 ? 0 : z; var z2 = z / 2; var n = 12; var Tvalues = [-0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816, 0.9816]; var Cvalues = [0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472]; var sum = 0; for (var i = 0; i < n; i++) { var ct = z2 * Tvalues[i] + z2; var xbase = base3(ct, x1, x2, x3, x4); var ybase = base3(ct, y1, y2, y3, y4); var comb = xbase * xbase + ybase * ybase; sum += Cvalues[i] * Math.sqrt(comb); } return z2 * sum; }; var curveDim = function (x0, y0, x1, y1, x2, y2, x3, y3) { var tvalues = []; var bounds = [ [], [], ]; var a; var b; var c; var t; for (var i = 0; i < 2; ++i) { if (i === 0) { b = 6 * x0 - 12 * x1 + 6 * x2; a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; c = 3 * x1 - 3 * x0; } else { b = 6 * y0 - 12 * y1 + 6 * y2; a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; c = 3 * y1 - 3 * y0; } if (Math.abs(a) < 1e-12) { if (Math.abs(b) < 1e-12) { continue; } t = -c / b; if (t > 0 && t < 1) { tvalues.push(t); } continue; } var b2ac = b * b - 4 * c * a; var sqrtb2ac = Math.sqrt(b2ac); if (b2ac < 0) { continue; } var t1 = (-b + sqrtb2ac) / (2 * a); if (t1 > 0 && t1 < 1) { tvalues.push(t1); } var t2 = (-b - sqrtb2ac) / (2 * a); if (t2 > 0 && t2 < 1) { tvalues.push(t2); } } var j = tvalues.length; var jlen = j; var mt; while (j--) { t = tvalues[j]; mt = 1 - t; bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); } bounds[0][jlen] = x0; bounds[1][jlen] = y0; bounds[0][jlen + 1] = x3; bounds[1][jlen + 1] = y3; bounds[0].length = bounds[1].length = jlen + 2; return { min: { x: Math.min.apply(0, bounds[0]), y: Math.min.apply(0, bounds[1]), }, max: { x: Math.max.apply(0, bounds[0]), y: Math.max.apply(0, bounds[1]), }, }; }; var intersect = function (x1, y1, x2, y2, x3, y3, x4, y4) { if (Math.max(x1, x2) < Math.min(x3, x4) || Math.min(x1, x2) > Math.max(x3, x4) || Math.max(y1, y2) < Math.min(y3, y4) || Math.min(y1, y2) > Math.max(y3, y4)) { return; } var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4); var ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4); var denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (!denominator) { return; } var px = nx / denominator; var py = ny / denominator; var px2 = +px.toFixed(2); var py2 = +py.toFixed(2); if (px2 < +Math.min(x1, x2).toFixed(2) || px2 > +Math.max(x1, x2).toFixed(2) || px2 < +Math.min(x3, x4).toFixed(2) || px2 > +Math.max(x3, x4).toFixed(2) || py2 < +Math.min(y1, y2).toFixed(2) || py2 > +Math.max(y1, y2).toFixed(2) || py2 < +Math.min(y3, y4).toFixed(2) || py2 > +Math.max(y3, y4).toFixed(2)) { return; } return { x: px, y: py, }; }; var isPointInsideBBox = function (bbox, x, y) { return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; }; var box = function (x, y, width, height) { if (x === null) { x = y = width = height = 0; } if (y === null) { y = x.y; width = x.width; height = x.height; x = x.x; } return { x: x, y: y, width: width, w: width, height: height, h: height, x2: x + width, y2: y + height, cx: x + width / 2, cy: y + height / 2, r1: Math.min(width, height) / 2, r2: Math.max(width, height) / 2, r0: Math.sqrt(width * width + height * height) / 2, path: rect_path_1.default(x, y, width, height), vb: [x, y, width, height].join(' '), }; }; var isBBoxIntersect = function (bbox1, bbox2) { // @ts-ignore bbox1 = box(bbox1); // @ts-ignore bbox2 = box(bbox2); return isPointInsideBBox(bbox2, bbox1.x, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y); }; var bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { if (!util_1.isArray(p1x)) { p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]; } var bbox = curveDim.apply(null, p1x); return box(bbox.min.x, bbox.min.y, bbox.max.x - bbox.min.x, bbox.max.y - bbox.min.y); }; var findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { var t1 = 1 - t; var t13 = Math.pow(t1, 3); var t12 = Math.pow(t1, 2); var t2 = t * t; var t3 = t2 * t; var x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x; var y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y; var mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x); var my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y); var nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x); var ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y); var ax = t1 * p1x + t * c1x; var ay = t1 * p1y + t * c1y; var cx = t1 * c2x + t * p2x; var cy = t1 * c2y + t * p2y; var alpha = (90 - Math.atan2(mx - nx, my - ny) * 180 / Math.PI); // (mx > nx || my < ny) && (alpha += 180); return { x: x, y: y, m: { x: mx, y: my, }, n: { x: nx, y: ny, }, start: { x: ax, y: ay, }, end: { x: cx, y: cy, }, alpha: alpha, }; }; var interHelper = function (bez1, bez2, justCount) { // @ts-ignore var bbox1 = bezierBBox(bez1); // @ts-ignore var bbox2 = bezierBBox(bez2); if (!isBBoxIntersect(bbox1, bbox2)) { return justCount ? 0 : []; } var l1 = bezlen.apply(0, bez1); var l2 = bezlen.apply(0, bez2); var n1 = ~~(l1 / 8); var n2 = ~~(l2 / 8); var dots1 = []; var dots2 = []; var xy = {}; var res = justCount ? 0 : []; for (var i = 0; i < n1 + 1; i++) { var d = findDotsAtSegment.apply(0, bez1.concat(i / n1)); dots1.push({ x: d.x, y: d.y, t: i / n1, }); } for (var i = 0; i < n2 + 1; i++) { var d = findDotsAtSegment.apply(0, bez2.concat(i / n2)); dots2.push({ x: d.x, y: d.y, t: i / n2, }); } for (var i = 0; i < n1; i++) { for (var j = 0; j < n2; j++) { var di = dots1[i]; var di1 = dots1[i + 1]; var dj = dots2[j]; var dj1 = dots2[j + 1]; var ci = Math.abs(di1.x - di.x) < 0.001 ? 'y' : 'x'; var cj = Math.abs(dj1.x - dj.x) < 0.001 ? 'y' : 'x'; var is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y); if (is) { if (xy[is.x.toFixed(4)] === is.y.toFixed(4)) { continue; } xy[is.x.toFixed(4)] = is.y.toFixed(4); var t1 = di.t + Math.abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t); var t2 = dj.t + Math.abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { if (justCount) { // @ts-ignore res++; } else { // @ts-ignore res.push({ x: is.x, y: is.y, t1: t1, t2: t2, }); } } } } } return res; }; var interPathHelper = function (path1, path2, justCount) { // @ts-ignore path1 = path_2_curve_1.default(path1); // @ts-ignore path2 = path_2_curve_1.default(path2); var x1; var y1; var x2; var y2; var x1m; var y1m; var x2m; var y2m; var bez1; var bez2; var res = justCount ? 0 : []; for (var i = 0, ii = path1.length; i < ii; i++) { var pi = path1[i]; if (pi[0] === 'M') { x1 = x1m = pi[1]; y1 = y1m = pi[2]; } else { if (pi[0] === 'C') { bez1 = [x1, y1].concat(pi.slice(1)); x1 = bez1[6]; y1 = bez1[7]; } else { bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; x1 = x1m; y1 = y1m; } for (var j = 0, jj = path2.length; j < jj; j++) { var pj = path2[j]; if (pj[0] === 'M') { x2 = x2m = pj[1]; y2 = y2m = pj[2]; } else { if (pj[0] === 'C') { bez2 = [x2, y2].concat(pj.slice(1)); x2 = bez2[6]; y2 = bez2[7]; } else { bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; x2 = x2m; y2 = y2m; } var intr = interHelper(bez1, bez2, justCount); if (justCount) { // @ts-ignore res += intr; } else { // @ts-ignore for (var k = 0, kk = intr.length; k < kk; k++) { intr[k].segment1 = i; intr[k].segment2 = j; intr[k].bez1 = bez1; intr[k].bez2 = bez2; } // @ts-ignore res = res.concat(intr); } } } } } return res; }; function pathIntersection(path1, path2) { // @ts-ignore return interPathHelper(path1, path2); } exports.default = pathIntersection; },{"./path-2-curve":730,"./rect-path":734,"@antv/util":803}],733:[function(require,module,exports){ "use strict"; /** * @fileoverview 判断点是否在多边形内 * @author dxq613@gmail.com */ Object.defineProperty(exports, "__esModule", { value: true }); // 多边形的射线检测,参考:https://blog.csdn.net/WilliamSun0122/article/details/77994526 var tolerance = 1e-6; // 三态函数,判断两个double在eps精度下的大小关系 function dcmp(x) { if (Math.abs(x) < tolerance) { return 0; } return x < 0 ? -1 : 1; } // 判断点Q是否在p1和p2的线段上 function onSegment(p1, p2, q) { if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) && Math.min(p1[0], p2[0]) <= q[0] && q[0] <= Math.max(p1[0], p2[0]) && Math.min(p1[1], p2[1]) <= q[1] && q[1] <= Math.max(p1[1], p2[1])) { return true; } return false; } // 判断点P在多边形内-射线法 function isInPolygon(points, x, y) { var isHit = false; var n = points.length; if (n <= 2) { // svg 中点小于 3 个时,不显示,也无法被拾取 return false; } for (var i = 0; i < n; i++) { var p1 = points[i]; var p2 = points[(i + 1) % n]; if (onSegment(p1, p2, [x, y])) { // 点在多边形一条边上 return true; } // 前一个判断min(p1[1],p2[1]) 0 !== dcmp(p2[1] - y) > 0 && dcmp(x - ((y - p1[1]) * (p1[0] - p2[0])) / (p1[1] - p2[1]) - p1[0]) < 0) { isHit = !isHit; } } return isHit; } exports.default = isInPolygon; },{}],734:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function rectPath(x, y, w, h, r) { if (r) { return [ ['M', +x + (+r), y], ['l', w - r * 2, 0], ['a', r, r, 0, 0, 1, r, r], ['l', 0, h - r * 2], ['a', r, r, 0, 0, 1, -r, r], ['l', r * 2 - w, 0], ['a', r, r, 0, 0, 1, -r, -r], ['l', 0, r * 2 - h], ['a', r, r, 0, 0, 1, r, -r], ['z'], ]; } return [ ['M', x, y], ['l', w, 0], ['l', 0, h], ['l', -w, 0], ['z'], ]; // res.parsePathArray = parsePathArray; } exports.default = rectPath; },{}],735:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var register_1 = require("./tick-method/register"); var Scale = /** @class */ (function () { function Scale(cfg) { /** * 度量的类型 */ this.type = 'base'; /** * 是否分类类型的度量 */ this.isCategory = false; /** * 是否线性度量,有linear, time 度量 */ this.isLinear = false; /** * 是否连续类型的度量,linear,time,log, pow, quantile, quantize 都支持 */ this.isContinuous = false; /** * 是否是常量的度量,传入和传出一致 */ this.isIdentity = false; this.values = []; this.range = [0, 1]; this.ticks = []; this.__cfg__ = cfg; this.initCfg(); this.init(); } // 对于原始值的必要转换,如分类、时间字段需转换成数值,用transform/map命名可能更好 Scale.prototype.translate = function (v) { return v; }; /** 重新初始化 */ Scale.prototype.change = function (cfg) { // 覆盖配置项,而不替代 util_1.assign(this.__cfg__, cfg); this.init(); }; Scale.prototype.clone = function () { return this.constructor(this.__cfg__); }; /** 获取坐标轴需要的ticks */ Scale.prototype.getTicks = function () { var _this = this; return util_1.map(this.ticks, function (tick, idx) { if (util_1.isObject(tick)) { // 仅当符合Tick类型时才有意义 return tick; } return { text: _this.getText(tick, idx), tickValue: tick, value: _this.scale(tick), }; }); }; /** 获取Tick的格式化结果 */ Scale.prototype.getText = function (value, key) { var formatter = this.formatter; var res = formatter ? formatter(value, key) : value; if (util_1.isNil(res) || !util_1.isFunction(res.toString)) { return ''; } return res.toString(); }; // 获取配置项中的值,当前 scale 上的值可能会被修改 Scale.prototype.getConfig = function (key) { return this.__cfg__[key]; }; // scale初始化 Scale.prototype.init = function () { util_1.assign(this, this.__cfg__); this.setDomain(); if (util_1.isEmpty(this.getConfig('ticks'))) { this.ticks = this.calculateTicks(); } }; // 子类上覆盖某些属性,不能直接在类上声明,否则会被覆盖 Scale.prototype.initCfg = function () { }; Scale.prototype.setDomain = function () { }; Scale.prototype.calculateTicks = function () { var tickMethod = this.tickMethod; var ticks = []; if (util_1.isString(tickMethod)) { var method = register_1.getTickMethod(tickMethod); if (!method) { throw new Error('There is no method to to calculate ticks!'); } ticks = method(this); } else if (util_1.isFunction(tickMethod)) { ticks = tickMethod(this); } return ticks; }; // range 的最小值 Scale.prototype.rangeMin = function () { return util_1.head(this.range); }; // range 的最大值 Scale.prototype.rangeMax = function () { return util_1.last(this.range); }; /** 定义域转 0~1 */ Scale.prototype.calcPercent = function (value, min, max) { if (util_1.isNumber(value)) { return (value - min) / (max - min); } return NaN; }; /** 0~1转定义域 */ Scale.prototype.calcValue = function (percent, min, max) { return min + percent * (max - min); }; return Scale; }()); exports.default = Scale; },{"./tick-method/register":756,"@antv/util":803}],736:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); /** * 分类度量 * @class */ var Category = /** @class */ (function (_super) { tslib_1.__extends(Category, _super); function Category() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'cat'; _this.isCategory = true; return _this; } Category.prototype.translate = function (value) { var index = util_1.indexOf(this.values, value); if (index === -1) { return util_1.isNumber(value) ? value : NaN; } return index; }; Category.prototype.scale = function (value) { var order = this.translate(value); // 分类数据允许 0.5 范围内调整 // if (order < this.min - 0.5 || order > this.max + 0.5) { // return NaN; // } var percent = this.calcPercent(order, this.min, this.max); return this.calcValue(percent, this.rangeMin(), this.rangeMax()); }; Category.prototype.invert = function (scaledValue) { var domainRange = this.max - this.min; var percent = this.calcPercent(scaledValue, this.rangeMin(), this.rangeMax()); var idx = Math.round(domainRange * percent) + this.min; if (idx < this.min || idx > this.max) { return NaN; } return this.values[idx]; }; Category.prototype.getText = function (value) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var v = value; // value为index if (util_1.isNumber(value) && !this.values.includes(value)) { v = this.values[v]; } return _super.prototype.getText.apply(this, tslib_1.__spreadArrays([v], args)); }; // 复写属性 Category.prototype.initCfg = function () { this.tickMethod = 'cat'; }; // 设置 min, max Category.prototype.setDomain = function () { // 用户有可能设置 min if (util_1.isNil(this.getConfig('min'))) { this.min = 0; } if (util_1.isNil(this.getConfig('max'))) { var size = this.values.length; this.max = size > 1 ? size - 1 : size; } }; return Category; }(base_1.default)); exports.default = Category; },{"../base":735,"@antv/util":803,"tslib":768}],737:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var time_1 = require("../util/time"); var base_1 = require("./base"); /** * 时间分类度量 * @class */ var TimeCat = /** @class */ (function (_super) { tslib_1.__extends(TimeCat, _super); function TimeCat() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'timeCat'; return _this; } /** * @override */ TimeCat.prototype.translate = function (value) { value = time_1.toTimeStamp(value); var index = this.values.indexOf(value); if (index === -1) { if (util_1.isNumber(value) && value < this.values.length) { index = value; } else { index = NaN; } } return index; }; /** * 由于时间类型数据需要转换一下,所以复写 getText * @override */ TimeCat.prototype.getText = function (value, tickIndex) { var index = this.translate(value); if (index > -1) { var result = this.values[index]; var formatter = this.formatter; result = formatter ? formatter(result, tickIndex) : time_1.timeFormat(result, this.mask); return result; } return value; }; TimeCat.prototype.initCfg = function () { this.tickMethod = 'time-cat'; this.mask = 'YYYY-MM-DD'; this.tickCount = 7; // 一般时间数据会显示 7, 14, 30 天的数字 }; TimeCat.prototype.setDomain = function () { var values = this.values; // 针对时间分类类型,会将时间统一转换为时间戳 util_1.each(values, function (v, i) { values[i] = time_1.toTimeStamp(v); }); values.sort(function (v1, v2) { return v1 - v2; }); _super.prototype.setDomain.call(this); }; return TimeCat; }(base_1.default)); exports.default = TimeCat; },{"../util/time":767,"./base":736,"@antv/util":803,"tslib":768}],738:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); /** * 连续度量的基类 * @class */ var Continuous = /** @class */ (function (_super) { tslib_1.__extends(Continuous, _super); function Continuous() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.isContinuous = true; return _this; } Continuous.prototype.scale = function (value) { if (util_1.isNil(value)) { return NaN; } var rangeMin = this.rangeMin(); var rangeMax = this.rangeMax(); var max = this.max; var min = this.min; if (max === min) { return rangeMin; } var percent = this.getScalePercent(value); return rangeMin + percent * (rangeMax - rangeMin); }; Continuous.prototype.init = function () { _super.prototype.init.call(this); // init 完成后保证 min, max 包含 ticks 的范围 var ticks = this.ticks; var firstTick = util_1.head(ticks); var lastTick = util_1.last(ticks); if (firstTick < this.min) { this.min = firstTick; } if (lastTick > this.max) { this.max = lastTick; } // strict-limit 方式 if (!util_1.isNil(this.minLimit)) { this.min = firstTick; } if (!util_1.isNil(this.maxLimit)) { this.max = lastTick; } }; Continuous.prototype.setDomain = function () { var _a = util_1.getRange(this.values), min = _a.min, max = _a.max; if (util_1.isNil(this.min)) { this.min = min; } if (util_1.isNil(this.max)) { this.max = max; } if (this.min > this.max) { this.min = min; this.max = max; } }; Continuous.prototype.calculateTicks = function () { var _this = this; var ticks = _super.prototype.calculateTicks.call(this); if (!this.nice) { ticks = util_1.filter(ticks, function (tick) { return tick >= _this.min && tick <= _this.max; }); } return ticks; }; // 计算原始值值占的百分比 Continuous.prototype.getScalePercent = function (value) { var max = this.max; var min = this.min; return (value - min) / (max - min); }; Continuous.prototype.getInvertPercent = function (value) { return (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin()); }; return Continuous; }(base_1.default)); exports.default = Continuous; },{"../base":735,"@antv/util":803,"tslib":768}],739:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var base_1 = require("./base"); /** * 线性度量 * @class */ var Linear = /** @class */ (function (_super) { tslib_1.__extends(Linear, _super); function Linear() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'linear'; _this.isLinear = true; return _this; } Linear.prototype.invert = function (value) { var percent = this.getInvertPercent(value); return this.min + percent * (this.max - this.min); }; Linear.prototype.initCfg = function () { this.tickMethod = 'wilkinson-extended'; this.nice = false; }; return Linear; }(base_1.default)); exports.default = Linear; },{"./base":738,"tslib":768}],740:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var math_1 = require("../util/math"); var base_1 = require("./base"); /** * Log 度量,处理非均匀分布 */ var Log = /** @class */ (function (_super) { tslib_1.__extends(Log, _super); function Log() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'log'; return _this; } /** * @override */ Log.prototype.invert = function (value) { var base = this.base; var max = math_1.log(base, this.max); var rangeMin = this.rangeMin(); var range = this.rangeMax() - rangeMin; var min; var positiveMin = this.positiveMin; if (positiveMin) { if (value === 0) { return 0; } min = math_1.log(base, positiveMin / base); var appendPercent = (1 / (max - min)) * range; // 0 到 positiveMin的占比 if (value < appendPercent) { // 落到 0 - positiveMin 之间 return (value / appendPercent) * positiveMin; } } else { min = math_1.log(base, this.min); } var percent = (value - rangeMin) / range; var tmp = percent * (max - min) + min; return Math.pow(base, tmp); }; Log.prototype.initCfg = function () { this.tickMethod = 'log'; this.base = 10; this.tickCount = 6; this.nice = true; }; // 设置 Log.prototype.setDomain = function () { _super.prototype.setDomain.call(this); var min = this.min; if (min < 0) { throw new Error('When you use log scale, the minimum value must be greater than zero!'); } if (min === 0) { this.positiveMin = math_1.getLogPositiveMin(this.values, this.base, this.max); } }; // 根据当前值获取占比 Log.prototype.getScalePercent = function (value) { var max = this.max; var min = this.min; if (max === min) { return 0; } // 如果值小于等于0,则按照0处理 if (value <= 0) { return 0; } var base = this.base; var positiveMin = this.positiveMin; // 如果min == 0, 则根据比0大的最小值,计算比例关系。这个最小值作为坐标轴上的第二个tick,第一个是0但是不显示 if (positiveMin) { min = (positiveMin * 1) / base; } var percent; // 如果数值小于次小值,那么就计算 value / 次小值 占整体的比例 if (value < positiveMin) { percent = value / positiveMin / (math_1.log(base, max) - math_1.log(base, min)); } else { percent = (math_1.log(base, value) - math_1.log(base, min)) / (math_1.log(base, max) - math_1.log(base, min)); } return percent; }; return Log; }(base_1.default)); exports.default = Log; },{"../util/math":764,"./base":738,"tslib":768}],741:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var math_1 = require("../util/math"); var base_1 = require("./base"); /** * Pow 度量,处理非均匀分布 */ var Pow = /** @class */ (function (_super) { tslib_1.__extends(Pow, _super); function Pow() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'pow'; return _this; } /** * @override */ Pow.prototype.invert = function (value) { var percent = this.getInvertPercent(value); var exponent = this.exponent; var max = math_1.calBase(exponent, this.max); var min = math_1.calBase(exponent, this.min); var tmp = percent * (max - min) + min; var factor = tmp >= 0 ? 1 : -1; return Math.pow(tmp, exponent) * factor; }; Pow.prototype.initCfg = function () { this.tickMethod = 'pow'; this.exponent = 2; this.tickCount = 5; this.nice = true; }; // 获取度量计算时,value占的定义域百分比 Pow.prototype.getScalePercent = function (value) { var max = this.max; var min = this.min; if (max === min) { return 0; } var exponent = this.exponent; var percent = (math_1.calBase(exponent, value) - math_1.calBase(exponent, min)) / (math_1.calBase(exponent, max) - math_1.calBase(exponent, min)); return percent; }; return Pow; }(base_1.default)); exports.default = Pow; },{"../util/math":764,"./base":738,"tslib":768}],742:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var quantize_1 = require("./quantize"); var Quantile = /** @class */ (function (_super) { tslib_1.__extends(Quantile, _super); function Quantile() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'quantile'; return _this; } Quantile.prototype.initCfg = function () { this.tickMethod = 'quantile'; this.tickCount = 5; this.nice = true; }; return Quantile; }(quantize_1.default)); exports.default = Quantile; },{"./quantize":743,"tslib":768}],743:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("./base"); /** * 分段度量 */ var Quantize = /** @class */ (function (_super) { tslib_1.__extends(Quantize, _super); function Quantize() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'quantize'; return _this; } Quantize.prototype.invert = function (value) { var ticks = this.ticks; var length = ticks.length; var percent = this.getInvertPercent(value); var minIndex = Math.floor(percent * (length - 1)); // 最后一个 if (minIndex >= length - 1) { return util_1.last(ticks); } // 超出左边界, 则取第一个 if (minIndex < 0) { return util_1.head(ticks); } var minTick = ticks[minIndex]; var nextTick = ticks[minIndex + 1]; // 比当前值小的 tick 在度量上的占比 var minIndexPercent = minIndex / (length - 1); var maxIndexPercent = (minIndex + 1) / (length - 1); return minTick + (percent - minIndexPercent) / (maxIndexPercent - minIndexPercent) * (nextTick - minTick); }; Quantize.prototype.initCfg = function () { this.tickMethod = 'r-pretty'; this.tickCount = 5; this.nice = true; }; Quantize.prototype.calculateTicks = function () { var ticks = _super.prototype.calculateTicks.call(this); if (!this.nice) { // 如果 nice = false ,补充 min, max if (util_1.last(ticks) !== this.max) { ticks.push(this.max); } if (util_1.head(ticks) !== this.min) { ticks.unshift(this.min); } } return ticks; }; // 计算当前值在刻度中的占比 Quantize.prototype.getScalePercent = function (value) { var ticks = this.ticks; // 超出左边界 if (value < util_1.head(ticks)) { return 0; } // 超出右边界 if (value > util_1.last(ticks)) { return 1; } var minIndex = 0; util_1.each(ticks, function (tick, index) { if (value >= tick) { minIndex = index; } else { return false; } }); return minIndex / (ticks.length - 1); }; return Quantize; }(base_1.default)); exports.default = Quantize; },{"./base":738,"@antv/util":803,"tslib":768}],744:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var time_1 = require("../util/time"); var linear_1 = require("./linear"); /** * 时间度量 * @class */ var Time = /** @class */ (function (_super) { tslib_1.__extends(Time, _super); function Time() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'time'; return _this; } /** * @override */ Time.prototype.getText = function (value, index) { var numberValue = this.translate(value); var formatter = this.formatter; return formatter ? formatter(numberValue, index) : time_1.timeFormat(numberValue, this.mask); }; /** * @override */ Time.prototype.scale = function (value) { var v = value; if (util_1.isString(v) || util_1.isDate(v)) { v = this.translate(v); } return _super.prototype.scale.call(this, v); }; /** * 将时间转换成数字 * @override */ Time.prototype.translate = function (v) { return time_1.toTimeStamp(v); }; Time.prototype.initCfg = function () { this.tickMethod = 'time-pretty'; this.mask = 'YYYY-MM-DD'; this.tickCount = 7; this.nice = false; }; Time.prototype.setDomain = function () { var values = this.values; // 是否设置了 min, max,而不是直接取 this.min, this.max var minConfig = this.getConfig('min'); var maxConfig = this.getConfig('max'); // 如果设置了 min,max 则转换成时间戳 if (!util_1.isNil(minConfig) || !util_1.isNumber(minConfig)) { this.min = this.translate(this.min); } if (!util_1.isNil(maxConfig) || !util_1.isNumber(maxConfig)) { this.max = this.translate(this.max); } // 没有设置 min, max 时 if (values && values.length) { // 重新计算最大最小值 var timeStamps_1 = []; var min_1 = Infinity; // 最小值 var secondMin_1 = min_1; // 次小值 var max_1 = 0; // 使用一个循环,计算min,max,secondMin util_1.each(values, function (v) { var timeStamp = time_1.toTimeStamp(v); if (isNaN(timeStamp)) { throw new TypeError("Invalid Time: " + v + " in time scale!"); } if (min_1 > timeStamp) { secondMin_1 = min_1; min_1 = timeStamp; } else if (secondMin_1 > timeStamp) { secondMin_1 = timeStamp; } if (max_1 < timeStamp) { max_1 = timeStamp; } timeStamps_1.push(timeStamp); }); // 存在多个值时,设置最小间距 if (values.length > 1) { this.minTickInterval = secondMin_1 - min_1; } if (util_1.isNil(minConfig)) { this.min = min_1; } if (util_1.isNil(maxConfig)) { this.max = max_1; } } }; return Time; }(linear_1.default)); exports.default = Time; },{"../util/time":767,"./linear":739,"@antv/util":803,"tslib":768}],745:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerScale = exports.getScale = exports.Scale = void 0; var base_1 = require("./base"); exports.Scale = base_1.default; var map = {}; function getClass(key) { return map[key]; } exports.getScale = getClass; function registerClass(key, cls) { if (getClass(key)) { throw new Error("type '" + key + "' existed."); } map[key] = cls; } exports.registerScale = registerClass; },{"./base":735}],746:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var util_1 = require("@antv/util"); var base_1 = require("../base"); /** * identity scale原则上是定义域和值域一致,scale/invert方法也是一致的 * 参考R的实现:https://github.com/r-lib/scales/blob/master/R/pal-identity.r * 参考d3的实现(做了下转型):https://github.com/d3/d3-scale/blob/master/src/identity.js */ var Identity = /** @class */ (function (_super) { tslib_1.__extends(Identity, _super); function Identity() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'identity'; _this.isIdentity = true; return _this; } Identity.prototype.calculateTicks = function () { return this.values; }; Identity.prototype.scale = function (value) { // 如果传入的值不等于 identity 的值,则直接返回,用于一维图时的 dodge if (this.values[0] !== value && util_1.isNumber(value)) { return value; } return this.range[0]; }; Identity.prototype.invert = function (value) { var range = this.range; if (value < range[0] || value > range[1]) { return NaN; } return this.values[0]; }; return Identity; }(base_1.default)); exports.default = Identity; },{"../base":735,"@antv/util":803,"tslib":768}],747:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerTickMethod = exports.getTickMethod = exports.registerScale = exports.getScale = exports.Scale = exports.Quantize = exports.Quantile = exports.TimeCat = exports.Time = exports.Pow = exports.Log = exports.Linear = exports.Identity = exports.Category = void 0; var base_1 = require("./base"); exports.Scale = base_1.default; var base_2 = require("./category/base"); exports.Category = base_2.default; var time_1 = require("./category/time"); exports.TimeCat = time_1.default; var linear_1 = require("./continuous/linear"); exports.Linear = linear_1.default; var log_1 = require("./continuous/log"); exports.Log = log_1.default; var pow_1 = require("./continuous/pow"); exports.Pow = pow_1.default; var time_2 = require("./continuous/time"); exports.Time = time_2.default; var quantize_1 = require("./continuous/quantize"); exports.Quantize = quantize_1.default; var quantile_1 = require("./continuous/quantile"); exports.Quantile = quantile_1.default; var factory_1 = require("./factory"); Object.defineProperty(exports, "getScale", { enumerable: true, get: function () { return factory_1.getScale; } }); Object.defineProperty(exports, "registerScale", { enumerable: true, get: function () { return factory_1.registerScale; } }); var index_1 = require("./identity/index"); exports.Identity = index_1.default; var index_2 = require("./tick-method/index"); Object.defineProperty(exports, "getTickMethod", { enumerable: true, get: function () { return index_2.getTickMethod; } }); Object.defineProperty(exports, "registerTickMethod", { enumerable: true, get: function () { return index_2.registerTickMethod; } }); factory_1.registerScale('cat', base_2.default); factory_1.registerScale('category', base_2.default); factory_1.registerScale('identity', index_1.default); factory_1.registerScale('linear', linear_1.default); factory_1.registerScale('log', log_1.default); factory_1.registerScale('pow', pow_1.default); factory_1.registerScale('time', time_2.default); factory_1.registerScale('timeCat', time_1.default); factory_1.registerScale('quantize', quantize_1.default); factory_1.registerScale('quantile', quantile_1.default); },{"./base":735,"./category/base":736,"./category/time":737,"./continuous/linear":739,"./continuous/log":740,"./continuous/pow":741,"./continuous/quantile":742,"./continuous/quantize":743,"./continuous/time":744,"./factory":745,"./identity/index":746,"./tick-method/index":750}],748:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var extended_1 = require("../util/extended"); /** * 计算分类 ticks * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function calculateCatTicks(cfg) { var values = cfg.values, tickInterval = cfg.tickInterval, tickCount = cfg.tickCount; var ticks = values; if (util_1.isNumber(tickInterval)) { return util_1.filter(ticks, function (__, i) { return i % tickInterval === 0; }); } var min = cfg.min, max = cfg.max; if (util_1.isNil(min)) { min = 0; } if (util_1.isNil(max)) { max = values.length - 1; } if (util_1.isNumber(tickCount) && tickCount < max - min) { // 简单过滤,部分情况下小数的倍数也可以是整数 // tslint:disable-next-line: no-shadowed-variable var ticks_1 = extended_1.default(min, max, tickCount, false, [1, 2, 5, 3, 4, 7, 6, 8, 9]).ticks; var valid = util_1.filter(ticks_1, function (tick) { return tick >= min && tick <= max; }); return valid.map(function (index) { return values[index]; }); } return values.slice(min, max + 1); } exports.default = calculateCatTicks; },{"../util/extended":762,"@antv/util":803}],749:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var d3_linear_1 = require("../util/d3-linear"); var interval_1 = require("../util/interval"); var strict_limit_1 = require("../util/strict-limit"); function d3LinearTickMethod(cfg) { var min = cfg.min, max = cfg.max, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit; var ticks = d3_linear_1.default(cfg); if (!util_1.isNil(minLimit) || !util_1.isNil(maxLimit)) { return strict_limit_1.default(cfg, util_1.head(ticks), util_1.last(ticks)); } if (tickInterval) { return interval_1.default(min, max, tickInterval).ticks; } return ticks; } exports.default = d3LinearTickMethod; },{"../util/d3-linear":761,"../util/interval":763,"../util/strict-limit":766,"@antv/util":803}],750:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerTickMethod = exports.getTickMethod = void 0; var cat_1 = require("./cat"); var d3_linear_1 = require("./d3-linear"); var linear_1 = require("./linear"); var log_1 = require("./log"); var pow_1 = require("./pow"); var quantile_1 = require("./quantile"); var r_prettry_1 = require("./r-prettry"); var register_1 = require("./register"); Object.defineProperty(exports, "getTickMethod", { enumerable: true, get: function () { return register_1.getTickMethod; } }); Object.defineProperty(exports, "registerTickMethod", { enumerable: true, get: function () { return register_1.registerTickMethod; } }); var time_1 = require("./time"); var time_cat_1 = require("./time-cat"); var time_pretty_1 = require("./time-pretty"); register_1.registerTickMethod('cat', cat_1.default); register_1.registerTickMethod('time-cat', time_cat_1.default); register_1.registerTickMethod('wilkinson-extended', linear_1.default); register_1.registerTickMethod('r-pretty', r_prettry_1.default); register_1.registerTickMethod('time', time_1.default); register_1.registerTickMethod('time-pretty', time_pretty_1.default); register_1.registerTickMethod('log', log_1.default); register_1.registerTickMethod('pow', pow_1.default); register_1.registerTickMethod('quantile', quantile_1.default); register_1.registerTickMethod('d3-linear', d3_linear_1.default); },{"./cat":748,"./d3-linear":749,"./linear":751,"./log":752,"./pow":753,"./quantile":754,"./r-prettry":755,"./register":756,"./time":759,"./time-cat":757,"./time-pretty":758}],751:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var extended_1 = require("../util/extended"); var interval_1 = require("../util/interval"); var strict_limit_1 = require("../util/strict-limit"); /** * 计算线性的 ticks,使用 wilkinson extended 方法 * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function linear(cfg) { var min = cfg.min, max = cfg.max, tickCount = cfg.tickCount, nice = cfg.nice, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit; var ticks = extended_1.default(min, max, tickCount, nice).ticks; if (!util_1.isNil(minLimit) || !util_1.isNil(maxLimit)) { return strict_limit_1.default(cfg, util_1.head(ticks), util_1.last(ticks)); } if (tickInterval) { return interval_1.default(min, max, tickInterval).ticks; } return ticks; } exports.default = linear; },{"../util/extended":762,"../util/interval":763,"../util/strict-limit":766,"@antv/util":803}],752:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var math_1 = require("../util/math"); /** * 计算 log 的 ticks,考虑 min = 0 的场景 * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function calculateLogTicks(cfg) { var base = cfg.base, tickCount = cfg.tickCount, min = cfg.min, max = cfg.max, values = cfg.values; var minTick; var maxTick = math_1.log(base, max); if (min > 0) { minTick = Math.floor(math_1.log(base, min)); } else { var positiveMin = math_1.getLogPositiveMin(values, base, max); minTick = Math.floor(math_1.log(base, positiveMin)); } var count = maxTick - minTick; var avg = Math.ceil(count / tickCount); var ticks = []; for (var i = minTick; i < maxTick + avg; i = i + avg) { ticks.push(Math.pow(base, i)); } if (min <= 0) { // 最小值 <= 0 时显示 0 ticks.unshift(0); } return ticks; } exports.default = calculateLogTicks; },{"../util/math":764}],753:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var math_1 = require("../util/math"); var pretty_1 = require("../util/pretty"); /** * 计算 Pow 的 ticks * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function calculatePowTicks(cfg) { var exponent = cfg.exponent, tickCount = cfg.tickCount; var max = Math.ceil(math_1.calBase(exponent, cfg.max)); var min = Math.floor(math_1.calBase(exponent, cfg.min)); var ticks = pretty_1.default(min, max, tickCount).ticks; return ticks.map(function (tick) { var factor = tick >= 0 ? 1 : -1; return Math.pow(tick, exponent) * factor; }); } exports.default = calculatePowTicks; },{"../util/math":764,"../util/pretty":765}],754:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 计算几分位 https://github.com/simple-statistics/simple-statistics/blob/master/src/quantile_sorted.js * @param x 数组 * @param p 百分比 */ function quantileSorted(x, p) { var idx = x.length * p; /*if (x.length === 0) { // 当前场景这些条件不可能命中 throw new Error('quantile requires at least one value.'); } else if (p < 0 || p > 1) { throw new Error('quantiles must be between 0 and 1'); } else */ if (p === 1) { // If p is 1, directly return the last element return x[x.length - 1]; } else if (p === 0) { // If p is 0, directly return the first element return x[0]; } else if (idx % 1 !== 0) { // If p is not integer, return the next element in array return x[Math.ceil(idx) - 1]; } else if (x.length % 2 === 0) { // If the list has even-length, we'll take the average of this number // and the next value, if there is one return (x[idx - 1] + x[idx]) / 2; } else { // Finally, in the simple case of an integer value // with an odd-length list, return the x value at the index. return x[idx]; } } function calculateTicks(cfg) { var tickCount = cfg.tickCount, values = cfg.values; if (!values || !values.length) { return []; } var sorted = values.slice().sort(function (a, b) { return a - b; }); var ticks = []; for (var i = 0; i < tickCount; i++) { var p = i / (tickCount - 1); ticks.push(quantileSorted(sorted, p)); } return ticks; } exports.default = calculateTicks; },{}],755:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var interval_1 = require("../util/interval"); var pretty_1 = require("../util/pretty"); var strict_limit_1 = require("../util/strict-limit"); /** * 计算线性的 ticks,使用 R's pretty 方法 * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function linearPretty(cfg) { var min = cfg.min, max = cfg.max, tickCount = cfg.tickCount, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit; var ticks = pretty_1.default(min, max, tickCount).ticks; if (!util_1.isNil(minLimit) || !util_1.isNil(maxLimit)) { return strict_limit_1.default(cfg, util_1.head(ticks), util_1.last(ticks)); } if (tickInterval) { return interval_1.default(min, max, tickInterval).ticks; } return ticks; } exports.default = linearPretty; },{"../util/interval":763,"../util/pretty":765,"../util/strict-limit":766,"@antv/util":803}],756:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerTickMethod = exports.getTickMethod = void 0; var methodCache = {}; /** * 获取计算 ticks 的方法 * @param key 键值 * @returns 计算 ticks 的方法 */ function getTickMethod(key) { return methodCache[key]; } exports.getTickMethod = getTickMethod; /** * 注册计算 ticks 的方法 * @param key 键值 * @param method 方法 */ function registerTickMethod(key, method) { methodCache[key] = method; } exports.registerTickMethod = registerTickMethod; },{}],757:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); var cat_1 = require("./cat"); /** * 计算时间分类的 ticks, 保头,保尾 * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function calculateTimeCatTicks(cfg) { var ticks = cat_1.default(cfg); var lastValue = util_1.last(cfg.values); if (lastValue !== util_1.last(ticks)) { ticks.push(lastValue); } return ticks; } exports.default = calculateTimeCatTicks; },{"./cat":748,"@antv/util":803}],758:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var time_1 = require("../util/time"); function getYear(date) { return new Date(date).getFullYear(); } function createYear(year) { return new Date(year, 0, 1).getTime(); } function getMonth(date) { return new Date(date).getMonth(); } function diffMonth(min, max) { var minYear = getYear(min); var maxYear = getYear(max); var minMonth = getMonth(min); var maxMonth = getMonth(max); return (maxYear - minYear) * 12 + ((maxMonth - minMonth) % 12); } function creatMonth(year, month) { return new Date(year, month, 1).getTime(); } function diffDay(min, max) { return Math.ceil((max - min) / time_1.DAY); } function diffHour(min, max) { return Math.ceil((max - min) / time_1.HOUR); } function diffMinus(min, max) { return Math.ceil((max - min) / (60 * 1000)); } /** * 计算 time 的 ticks,对 month, year 进行 pretty 处理 * @param cfg 度量的配置项 * @returns 计算后的 ticks */ function timePretty(cfg) { var min = cfg.min, max = cfg.max, minTickInterval = cfg.minTickInterval; var tickInterval = cfg.tickInterval; var tickCount = cfg.tickCount; var ticks = []; // 指定 tickInterval 后 tickCount 不生效,需要重新计算 if (!tickInterval) { tickInterval = (max - min) / tickCount; // 如果设置了最小间距,则使用最小间距 if (minTickInterval && tickInterval < minTickInterval) { tickInterval = minTickInterval; } } var minYear = getYear(min); // 如果间距大于 1 年,则将开始日期从整年开始 if (tickInterval > time_1.YEAR) { var maxYear = getYear(max); var yearInterval = Math.ceil(tickInterval / time_1.YEAR); for (var i = minYear; i <= maxYear + yearInterval; i = i + yearInterval) { ticks.push(createYear(i)); } } else if (tickInterval > time_1.MONTH) { // 大于月时 var monthInterval = Math.ceil(tickInterval / time_1.MONTH); var mmMoth = getMonth(min); var dMonths = diffMonth(min, max); for (var i = 0; i <= dMonths + monthInterval; i = i + monthInterval) { ticks.push(creatMonth(minYear, i + mmMoth)); } } else if (tickInterval > time_1.DAY) { // 大于天 var date = new Date(min); var year = date.getFullYear(); var month = date.getMonth(); var mday = date.getDate(); var day = Math.ceil(tickInterval / time_1.DAY); var ddays = diffDay(min, max); for (var i = 0; i < ddays + day; i = i + day) { ticks.push(new Date(year, month, mday + i).getTime()); } } else if (tickInterval > time_1.HOUR) { // 大于小时 var date = new Date(min); var year = date.getFullYear(); var month = date.getMonth(); var day = date.getDate(); var hour = date.getHours(); var hours = Math.ceil(tickInterval / time_1.HOUR); var dHours = diffHour(min, max); for (var i = 0; i <= dHours + hours; i = i + hours) { ticks.push(new Date(year, month, day, hour + i).getTime()); } } else if (tickInterval > time_1.MINUTE) { // 大于分钟 var dMinus = diffMinus(min, max); var minutes = Math.ceil(tickInterval / time_1.MINUTE); for (var i = 0; i <= dMinus + minutes; i = i + minutes) { ticks.push(min + i * time_1.MINUTE); } } else { // 小于分钟 var interval = tickInterval; if (interval < time_1.SECOND) { interval = time_1.SECOND; } var minSecond = Math.floor(min / time_1.SECOND) * time_1.SECOND; var dSeconds = Math.ceil((max - min) / time_1.SECOND); var seconds = Math.ceil(interval / time_1.SECOND); for (var i = 0; i < dSeconds + seconds; i = i + seconds) { ticks.push(minSecond + i * time_1.SECOND); } } return ticks; } exports.default = timePretty; },{"../util/time":767}],759:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var time_1 = require("../util/time"); function calculateTimeTicks(cfg) { var min = cfg.min, max = cfg.max, minTickInterval = cfg.minTickInterval; var tickInterval = cfg.tickInterval; var tickCount = cfg.tickCount; // 指定 tickInterval 后 tickCount 不生效,需要重新计算 if (tickInterval) { tickCount = Math.ceil((max - min) / tickInterval); } else { tickInterval = time_1.getTickInterval(min, max, tickCount)[1]; var count = (max - min) / tickInterval; var ratio = count / tickCount; if (ratio > 1) { tickInterval = tickInterval * Math.ceil(ratio); } // 如果设置了最小间距,则使用最小间距 if (minTickInterval && tickInterval < minTickInterval) { tickInterval = minTickInterval; } } var ticks = []; for (var i = min; i < max + tickInterval; i += tickInterval) { ticks.push(i); } return ticks; } exports.default = calculateTimeTicks; },{"../util/time":767}],760:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); /** * 二分右侧查找 * https://github.com/d3/d3-array/blob/master/src/bisector.js */ function default_1(getter) { /** * x: 目标值 * lo: 起始位置 * hi: 结束位置 */ return function (a, x, _lo, _hi) { var lo = util_1.isNil(_lo) ? 0 : _lo; var hi = util_1.isNil(_hi) ? a.length : _hi; while (lo < hi) { var mid = (lo + hi) >>> 1; if (getter(a[mid]) > x) { hi = mid; } else { lo = mid + 1; } } return lo; }; } exports.default = default_1; },{"@antv/util":803}],761:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.D3Linear = void 0; function d3Linear(cfg) { var min = cfg.min, max = cfg.max, nice = cfg.nice, tickCount = cfg.tickCount; var linear = new D3Linear(); linear.domain([min, max]); if (nice) { linear.nice(tickCount); } return linear.ticks(tickCount); } exports.default = d3Linear; var DEFAULT_COUNT = 5; var e10 = Math.sqrt(50); var e5 = Math.sqrt(10); var e2 = Math.sqrt(2); // https://github.com/d3/d3-scale var D3Linear = /** @class */ (function () { function D3Linear() { this._domain = [0, 1]; } D3Linear.prototype.domain = function (domain) { if (domain) { this._domain = Array.from(domain, Number); return this; } return this._domain.slice(); }; D3Linear.prototype.nice = function (count) { var _a, _b; if (count === void 0) { count = DEFAULT_COUNT; } var d = this._domain.slice(); var i0 = 0; var i1 = this._domain.length - 1; var start = this._domain[i0]; var stop = this._domain[i1]; var step; if (stop < start) { _a = [stop, start], start = _a[0], stop = _a[1]; _b = [i1, i0], i0 = _b[0], i1 = _b[1]; } step = tickIncrement(start, stop, count); if (step > 0) { start = Math.floor(start / step) * step; stop = Math.ceil(stop / step) * step; step = tickIncrement(start, stop, count); } else if (step < 0) { start = Math.ceil(start * step) / step; stop = Math.floor(stop * step) / step; step = tickIncrement(start, stop, count); } if (step > 0) { d[i0] = Math.floor(start / step) * step; d[i1] = Math.ceil(stop / step) * step; this.domain(d); } else if (step < 0) { d[i0] = Math.ceil(start * step) / step; d[i1] = Math.floor(stop * step) / step; this.domain(d); } return this; }; D3Linear.prototype.ticks = function (count) { if (count === void 0) { count = DEFAULT_COUNT; } return d3ArrayTicks(this._domain[0], this._domain[this._domain.length - 1], count || DEFAULT_COUNT); }; return D3Linear; }()); exports.D3Linear = D3Linear; function d3ArrayTicks(start, stop, count) { var reverse; var i = -1; var n; var ticks; var step; (stop = +stop), (start = +start), (count = +count); if (start === stop && count > 0) { return [start]; } // tslint:disable-next-line if ((reverse = stop < start)) { (n = start), (start = stop), (stop = n); } // tslint:disable-next-line if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) { return []; } if (step > 0) { start = Math.ceil(start / step); stop = Math.floor(stop / step); ticks = new Array((n = Math.ceil(stop - start + 1))); while (++i < n) { ticks[i] = (start + i) * step; } } else { start = Math.floor(start * step); stop = Math.ceil(stop * step); ticks = new Array((n = Math.ceil(start - stop + 1))); while (++i < n) { ticks[i] = (start - i) / step; } } if (reverse) { ticks.reverse(); } return ticks; } function tickIncrement(start, stop, count) { var step = (stop - start) / Math.max(0, count); var power = Math.floor(Math.log(step) / Math.LN10); var error = step / Math.pow(10, power); return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); } },{}],762:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ALL_Q = exports.DEFAULT_Q = void 0; var util_1 = require("@antv/util"); exports.DEFAULT_Q = [1, 5, 2, 2.5, 4, 3]; exports.ALL_Q = [1, 5, 2, 2.5, 4, 3, 1.5, 7, 6, 8, 9]; var eps = Number.EPSILON * 100; // https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers function mod(n, m) { return ((n % m) + m) % m; } function simplicity(q, Q, j, lmin, lmax, lstep) { var n = util_1.size(Q); var i = util_1.indexOf(Q, q); var v = 0; var m = mod(lmin, lstep); if ((m < eps || lstep - m < eps) && lmin <= 0 && lmax >= 0) { v = 1; } return 1 - i / (n - 1) - j + v; } function simplicityMax(q, Q, j) { var n = util_1.size(Q); var i = util_1.indexOf(Q, q); var v = 1; return 1 - i / (n - 1) - j + v; } function density(k, m, dmin, dmax, lmin, lmax) { var r = (k - 1) / (lmax - lmin); var rt = (m - 1) / (Math.max(lmax, dmax) - Math.min(dmin, lmin)); return 2 - Math.max(r / rt, rt / r); } function densityMax(k, m) { if (k >= m) { return 2 - (k - 1) / (m - 1); } return 1; } function coverage(dmin, dmax, lmin, lmax) { var range = dmax - dmin; return 1 - (0.5 * (Math.pow(dmax - lmax, 2) + Math.pow(dmin - lmin, 2))) / Math.pow(0.1 * range, 2); } function coverageMax(dmin, dmax, span) { var range = dmax - dmin; if (span > range) { var half = (span - range) / 2; return 1 - Math.pow(half, 2) / Math.pow(0.1 * range, 2); } return 1; } function legibility() { return 1; } /** * An Extension of Wilkinson's Algorithm for Position Tick Labels on Axes * https://www.yuque.com/preview/yuque/0/2019/pdf/185317/1546999150858-45c3b9c2-4e86-4223-bf1a-8a732e8195ed.pdf * @param dmin 最小值 * @param dmax 最大值 * @param m tick个数 * @param onlyLoose 是否允许扩展min、max,不绝对强制,例如[3, 97] * @param Q nice numbers集合 * @param w 四个优化组件的权重 */ function extended(dmin, dmax, m, onlyLoose, Q, w) { if (m === void 0) { m = 5; } if (onlyLoose === void 0) { onlyLoose = true; } if (Q === void 0) { Q = exports.DEFAULT_Q; } if (w === void 0) { w = [0.25, 0.2, 0.5, 0.05]; } if (dmin === dmax || m === 1) { return { min: dmin, max: dmax, ticks: [dmin], }; } var best = { score: -2, lmin: 0, lmax: 0, lstep: 0, }; var j = 1; while (j < Infinity) { for (var _i = 0, Q_1 = Q; _i < Q_1.length; _i++) { var q = Q_1[_i]; var sm = simplicityMax(q, Q, j); if (Number.isNaN(sm)) { throw new Error('NaN'); } if (w[0] * sm + w[1] + w[2] + w[3] < best.score) { j = Infinity; break; } var k = 2; while (k < Infinity) { var dm = densityMax(k, m); if (w[0] * sm + w[1] + w[2] * dm + w[3] < best.score) { break; } var delta = (dmax - dmin) / (k + 1) / j / q; var z = Math.ceil(Math.log10(delta)); while (z < Infinity) { var step = j * q * Math.pow(10, z); var cm = coverageMax(dmin, dmax, step * (k - 1)); if (w[0] * sm + w[1] * cm + w[2] * dm + w[3] < best.score) { break; } var minStart = Math.floor(dmax / step) * j - (k - 1) * j; var maxStart = Math.ceil(dmin / step) * j; if (minStart > maxStart) { z = z + 1; continue; } for (var start = minStart; start <= maxStart; start = start + 1) { var lmin = start * (step / j); var lmax = lmin + step * (k - 1); var lstep = step; var s = simplicity(q, Q, j, lmin, lmax, lstep); var c = coverage(dmin, dmax, lmin, lmax); var g = density(k, m, dmin, dmax, lmin, lmax); var l = legibility(); var score = w[0] * s + w[1] * c + w[2] * g + w[3] * l; if (score > best.score && (!onlyLoose || (lmin <= dmin && lmax >= dmax))) { best.lmin = lmin; best.lmax = lmax; best.lstep = lstep; best.score = score; } } z = z + 1; } k = k + 1; } } j = j + 1; } // 步长为浮点数时处理精度 var toFixed = Number.isInteger(best.lstep) ? 0 : Math.ceil(Math.abs(Math.log10(best.lstep))); var range = []; for (var tick = best.lmin; tick <= best.lmax; tick += best.lstep) { range.push(tick); } var ticks = toFixed ? util_1.map(range, function (x) { return Number.parseFloat(x.toFixed(toFixed)); }) : range; return { min: Math.min(dmin, util_1.head(ticks)), max: Math.max(dmax, util_1.last(ticks)), ticks: ticks, }; } exports.default = extended; },{"@antv/util":803}],763:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); function snapMultiple(v, base, snapType) { var div; if (snapType === 'ceil') { div = Math.ceil(v / base); } else if (snapType === 'floor') { div = Math.floor(v / base); } else { div = Math.round(v / base); } return div * base; } function intervalTicks(min, max, interval) { // 变成 interval 的倍数 var minTick = snapMultiple(min, interval, 'floor'); var maxTick = snapMultiple(max, interval, 'ceil'); // 统一小数位数 minTick = util_1.fixedBase(minTick, interval); maxTick = util_1.fixedBase(maxTick, interval); var ticks = []; for (var i = minTick; i <= maxTick; i = i + interval) { var tickValue = util_1.fixedBase(i, interval); // 防止浮点数加法出现问题 ticks.push(tickValue); } return { min: minTick, max: maxTick, ticks: ticks }; } exports.default = intervalTicks; },{"@antv/util":803}],764:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLogPositiveMin = exports.log = exports.calBase = void 0; var util_1 = require("@antv/util"); // 求以a为次幂,结果为b的基数,如 x^^a = b;求x // 虽然数学上 b 不支持负数,但是这里需要支持 负数 function calBase(a, b) { var e = Math.E; var value; if (b >= 0) { value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底 } else { value = Math.pow(e, Math.log(-b) / a) * -1; // 使用换底公式求底 } return value; } exports.calBase = calBase; function log(a, b) { if (a === 1) { return 1; } return Math.log(b) / Math.log(a); } exports.log = log; function getLogPositiveMin(values, base, max) { if (util_1.isNil(max)) { max = Math.max.apply(null, values); } var positiveMin = max; util_1.each(values, function (value) { if (value > 0 && value < positiveMin) { positiveMin = value; } }); if (positiveMin === max) { positiveMin = max / base; } if (positiveMin > 1) { positiveMin = 1; } return positiveMin; } exports.getLogPositiveMin = getLogPositiveMin; },{"@antv/util":803}],765:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function pretty(min, max, n) { if (n === void 0) { n = 5; } var res = { max: 0, min: 0, ticks: [], }; /* R pretty: https://svn.r-project.org/R/trunk/src/appl/pretty.c https://www.rdocumentation.org/packages/base/versions/3.5.2/topics/pretty */ var h = 1.5; // high.u.bias var h5 = 0.5 + 1.5 * h; // u5.bias // 反正我也不会调参,跳过所有判断步骤 var d = max - min; var c = d / n; // 当d非常小的时候触发,但似乎没什么用 // const min_n = Math.floor(n / 3); // const shrink_sml = Math.pow(2, 5); // if (Math.log10(d) < -2) { // c = (_.max([ Math.abs(max), Math.abs(min) ]) * shrink_sml) / min_n; // } var base = Math.pow(10, Math.floor(Math.log10(c))); var toFixed = base < 1 ? Math.ceil(Math.abs(Math.log10(base))) : 0; var unit = base; if (2 * base - c < h * (c - unit)) { unit = 2 * base; if (5 * base - c < h5 * (c - unit)) { unit = 5 * base; if (10 * base - c < h * (c - unit)) { unit = 10 * base; } } } var nu = Math.ceil(max / unit); var ns = Math.floor(min / unit); res.max = Math.max(nu * unit, max); res.min = Math.min(ns * unit, min); var x = Number.parseFloat((ns * unit).toFixed(toFixed)); while (x < max) { res.ticks.push(x); x += unit; if (toFixed) { x = Number.parseFloat(x.toFixed(toFixed)); } } res.ticks.push(x); return res; } exports.default = pretty; },{}],766:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("@antv/util"); /** * 按照给定的 minLimit/maxLimit/tickCount 均匀计算出刻度 ticks * * @param cfg Scale 配置项 * @return ticks */ function strictLimit(cfg, defaultMin, defaultMax) { var _a; var minLimit = cfg.minLimit, maxLimit = cfg.maxLimit, min = cfg.min, max = cfg.max, _b = cfg.tickCount, tickCount = _b === void 0 ? 5 : _b; var tickMin = util_1.isNil(minLimit) ? (util_1.isNil(defaultMin) ? min : defaultMin) : minLimit; var tickMax = util_1.isNil(maxLimit) ? (util_1.isNil(defaultMax) ? max : defaultMax) : maxLimit; if (tickMin > tickMax) { _a = [tickMin, tickMax], tickMax = _a[0], tickMin = _a[1]; } if (tickCount <= 2) { return [tickMin, tickMax]; } var step = (tickMax - tickMin) / (tickCount - 1); var ticks = []; for (var i = 0; i < tickCount; i++) { ticks.push(tickMin + step * i); } return ticks; } exports.default = strictLimit; },{"@antv/util":803}],767:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTickInterval = exports.YEAR = exports.MONTH = exports.DAY = exports.HOUR = exports.MINUTE = exports.SECOND = exports.toTimeStamp = exports.timeFormat = void 0; var util_1 = require("@antv/util"); var fecha_1 = require("fecha"); var fecha1 = require("fecha"); var bisector_1 = require("./bisector"); var FORMAT_METHOD = 'format'; function timeFormat(time, mask) { var method = fecha1[FORMAT_METHOD] || fecha_1.default[FORMAT_METHOD]; return method(time, mask); } exports.timeFormat = timeFormat; /** * 转换成时间戳 * @param value 时间值 */ function toTimeStamp(value) { if (util_1.isString(value)) { if (value.indexOf('T') > 0) { value = new Date(value).getTime(); } else { // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于: // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间) // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间) value = new Date(value.replace(/-/gi, '/')).getTime(); } } if (util_1.isDate(value)) { value = value.getTime(); } return value; } exports.toTimeStamp = toTimeStamp; var SECOND = 1000; exports.SECOND = SECOND; var MINUTE = 60 * SECOND; exports.MINUTE = MINUTE; var HOUR = 60 * MINUTE; exports.HOUR = HOUR; var DAY = 24 * HOUR; exports.DAY = DAY; var MONTH = DAY * 31; exports.MONTH = MONTH; var YEAR = DAY * 365; exports.YEAR = YEAR; var intervals = [ ['HH:mm:ss', SECOND], ['HH:mm:ss', SECOND * 10], ['HH:mm:ss', SECOND * 30], ['HH:mm', MINUTE], ['HH:mm', MINUTE * 10], ['HH:mm', MINUTE * 30], ['HH', HOUR], ['HH', HOUR * 6], ['HH', HOUR * 12], ['YYYY-MM-DD', DAY], ['YYYY-MM-DD', DAY * 4], ['YYYY-WW', DAY * 7], ['YYYY-MM', MONTH], ['YYYY-MM', MONTH * 4], ['YYYY-MM', MONTH * 6], ['YYYY', DAY * 380], ]; function getTickInterval(min, max, tickCount) { var target = (max - min) / tickCount; var idx = bisector_1.default(function (o) { return o[1]; })(intervals, target) - 1; var interval = intervals[idx]; if (idx < 0) { interval = intervals[0]; } else if (idx >= intervals.length) { interval = util_1.last(intervals); } return interval; } exports.getTickInterval = getTickInterval; },{"./bisector":760,"@antv/util":803,"fecha":881}],768:[function(require,module,exports){ (function (global){ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global global, define, System, Reflect, Promise */ var __extends; var __assign; var __rest; var __decorate; var __param; var __metadata; var __awaiter; var __generator; var __exportStar; var __values; var __read; var __spread; var __spreadArrays; var __await; var __asyncGenerator; var __asyncDelegator; var __asyncValues; var __makeTemplateObject; var __importStar; var __importDefault; var __classPrivateFieldGet; var __classPrivateFieldSet; var __createBinding; (function (factory) { var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; if (typeof define === "function" && define.amd) { define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); } else if (typeof module === "object" && typeof module.exports === "object") { factory(createExporter(root, createExporter(module.exports))); } else { factory(createExporter(root)); } function createExporter(exports, previous) { if (exports !== root) { if (typeof Object.create === "function") { Object.defineProperty(exports, "__esModule", { value: true }); } else { exports.__esModule = true; } } return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; } }) (function (exporter) { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; __extends = function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; __assign = Object.assign || function (t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; __rest = function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; __decorate = function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; __param = function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; __metadata = function (metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); }; __awaiter = function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; __generator = function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; __exportStar = function(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); }; __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); __values = function (o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; __read = function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; __spread = function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; __spreadArrays = function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; __await = function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }; __asyncGenerator = function (thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; __asyncDelegator = function (o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; __asyncValues = function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; __makeTemplateObject = function (cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; __importStar = function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; __importDefault = function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; __classPrivateFieldGet = function (receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); }; __classPrivateFieldSet = function (receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; }; exporter("__extends", __extends); exporter("__assign", __assign); exporter("__rest", __rest); exporter("__decorate", __decorate); exporter("__param", __param); exporter("__metadata", __metadata); exporter("__awaiter", __awaiter); exporter("__generator", __generator); exporter("__exportStar", __exportStar); exporter("__createBinding", __createBinding); exporter("__values", __values); exporter("__read", __read); exporter("__spread", __spread); exporter("__spreadArrays", __spreadArrays); exporter("__await", __await); exporter("__asyncGenerator", __asyncGenerator); exporter("__asyncDelegator", __asyncDelegator); exporter("__asyncValues", __asyncValues); exporter("__makeTemplateObject", __makeTemplateObject); exporter("__importStar", __importStar); exporter("__importDefault", __importDefault); exporter("__classPrivateFieldGet", __classPrivateFieldGet); exporter("__classPrivateFieldSet", __classPrivateFieldSet); }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],769:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var mix_1 = require("./mix"); var is_function_1 = require("./is-function"); var augment = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var c = args[0]; for (var i = 1; i < args.length; i++) { var obj = args[i]; if (is_function_1.default(obj)) { obj = obj.prototype; } mix_1.default(c.prototype, obj); } }; exports.default = augment; },{"./is-function":817,"./mix":844}],770:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * k-v 存储 */ var default_1 = /** @class */ (function () { function default_1() { this.map = {}; } default_1.prototype.has = function (key) { return this.map[key] !== undefined; }; default_1.prototype.get = function (key, def) { var v = this.map[key]; return v === undefined ? def : v; }; default_1.prototype.set = function (key, value) { this.map[key] = value; }; default_1.prototype.clear = function () { this.map = {}; }; default_1.prototype.delete = function (key) { delete this.map[key]; }; default_1.prototype.size = function () { return Object.keys(this.map).length; }; return default_1; }()); exports.default = default_1; },{}],771:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var clamp = function (a, min, max) { if (a < min) { return min; } else if (a > max) { return max; } return a; }; exports.default = clamp; },{}],772:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function cancelAnimationFrame(handler) { var method = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || // @ts-ignore window.mozCancelAnimationFrame || // @ts-ignore window.msCancelAnimationFrame || clearTimeout; method(handler); } exports.default = cancelAnimationFrame; ; },{}],773:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var clone = function (obj) { if (typeof obj !== 'object' || obj === null) { return obj; } var rst; if (is_array_1.default(obj)) { rst = []; for (var i = 0, l = obj.length; i < l; i++) { if (typeof obj[i] === 'object' && obj[i] != null) { rst[i] = clone(obj[i]); } else { rst[i] = obj[i]; } } } else { rst = {}; for (var k in obj) { if (typeof obj[k] === 'object' && obj[k] != null) { rst[k] = clone(obj[k]); } else { rst[k] = obj[k]; } } } return rst; }; exports.default = clone; },{"./is-array":806}],774:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); var contains = function (arr, value) { if (!is_array_like_1.default(arr)) { return false; } return arr.indexOf(value) > -1; }; exports.default = contains; },{"./is-array-like":805}],775:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function debounce(func, wait, immediate) { var timeout; return function () { var context = this, args = arguments; var later = function () { timeout = null; if (!immediate) { func.apply(context, args); } }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) { func.apply(context, args); } }; } exports.default = debounce; },{}],776:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_plain_object_1 = require("./is-plain-object"); var MAX_MIX_LEVEL = 5; function _deepMix(dist, src, level, maxLevel) { level = level || 0; maxLevel = maxLevel || MAX_MIX_LEVEL; for (var key in src) { if (src.hasOwnProperty(key)) { var value = src[key]; if (value !== null && is_plain_object_1.default(value)) { if (!is_plain_object_1.default(dist[key])) { dist[key] = {}; } if (level < maxLevel) { _deepMix(dist[key], value, level + 1, maxLevel); } else { dist[key] = src[key]; } } else if (is_array_1.default(value)) { dist[key] = []; dist[key] = dist[key].concat(value); } else if (value !== undefined) { dist[key] = value; } } } } // todo 重写 var deepMix = function (rst) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } for (var i = 0; i < args.length; i += 1) { _deepMix(rst, args[i]); } return rst; }; exports.default = deepMix; },{"./is-array":806,"./is-plain-object":828}],777:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var filter_1 = require("./filter"); var contains_1 = require("./contains"); /** * Flattens `array` a single level deep. * * @param {Array} arr The array to inspect. * @param {Array} values The values to exclude. * @return {Array} Returns the new array of filtered values. * @example * difference([2, 1], [2, 3]); // => [1] */ var difference = function (arr, values) { if (values === void 0) { values = []; } return filter_1.default(arr, function (value) { return !contains_1.default(values, value); }); }; exports.default = difference; },{"./contains":774,"./filter":782}],778:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_object_1 = require("./is-object"); function each(elements, func) { if (!elements) { return; } var rst; if (is_array_1.default(elements)) { for (var i = 0, len = elements.length; i < len; i++) { rst = func(elements[i], i); if (rst === false) { break; } } } else if (is_object_1.default(elements)) { for (var k in elements) { if (elements.hasOwnProperty(k)) { rst = func(elements[k], k); if (rst === false) { break; } } } } } exports.default = each; },{"./is-array":806,"./is-object":826}],779:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_string_1 = require("./is-string"); function endsWith(arr, e) { return (is_array_1.default(arr) || is_string_1.default(arr)) ? arr[arr.length - 1] === e : false; } exports.default = endsWith; },{"./is-array":806,"./is-string":832}],780:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 只要有一个不满足条件就返回 false * @param arr * @param func */ var every = function (arr, func) { for (var i = 0; i < arr.length; i++) { if (!func(arr[i], i)) return false; } return true; }; exports.default = every; },{}],781:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var mix_1 = require("./mix"); var is_function_1 = require("./is-function"); var extend = function (subclass, superclass, overrides, staticOverrides) { // 如果只提供父类构造函数,则自动生成子类构造函数 if (!is_function_1.default(superclass)) { overrides = superclass; superclass = subclass; subclass = function () { }; } var create = Object.create ? function (proto, c) { return Object.create(proto, { constructor: { value: c } }); } : function (proto, c) { function Tmp() { } Tmp.prototype = proto; var o = new Tmp(); o.constructor = c; return o; }; var superObj = create(superclass.prototype, subclass); // new superclass(),//实例化父类作为子类的prototype subclass.prototype = mix_1.default(superObj, subclass.prototype); // 指定子类的prototype subclass.superclass = create(superclass.prototype, superclass); mix_1.default(superObj, overrides); mix_1.default(subclass, staticOverrides); return subclass; }; exports.default = extend; },{"./is-function":817,"./mix":844}],782:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); var filter = function (arr, func) { if (!is_array_like_1.default(arr)) { return arr; } var result = []; for (var index = 0; index < arr.length; index++) { var value = arr[index]; if (func(value, index)) { result.push(value); } } return result; }; exports.default = filter; },{"./is-array-like":805}],783:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function findIndex(arr, predicate, fromIndex) { if (fromIndex === void 0) { fromIndex = 0; } for (var i = fromIndex; i < arr.length; i++) { if (predicate(arr[i], i)) { // 找到终止循环 return i; } } return -1; } exports.default = findIndex; },{}],784:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_function_1 = require("./is-function"); var is_match_1 = require("./is-match"); var is_array_1 = require("./is-array"); var is_plain_object_1 = require("./is-plain-object"); function find(arr, predicate) { if (!is_array_1.default(arr)) return null; var _predicate; if (is_function_1.default(predicate)) { _predicate = predicate; } if (is_plain_object_1.default(predicate)) { _predicate = function (a) { return is_match_1.default(a, predicate); }; } if (_predicate) { for (var i = 0; i < arr.length; i += 1) { if (_predicate(arr[i])) { return arr[i]; } } } return null; } exports.default = find; },{"./is-array":806,"./is-function":817,"./is-match":819,"./is-plain-object":828}],785:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_nil_1 = require("./is-nil"); var is_array_1 = require("./is-array"); var firstValue = function (data, name) { var rst = null; for (var i = 0; i < data.length; i++) { var obj = data[i]; var value = obj[name]; if (!is_nil_1.default(value)) { if (is_array_1.default(value)) { rst = value[0]; // todo 这里是否应该使用递归,调用 firstValue @绝云 } else { rst = value; } break; } } return rst; }; exports.default = firstValue; },{"./is-array":806,"./is-nil":821}],786:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var fixedBase = function (v, base) { var str = base.toString(); var index = str.indexOf('.'); if (index === -1) { return Math.round(v); } var length = str.substr(index + 1).length; if (length > 20) { length = 20; } return parseFloat(v.toFixed(length)); }; exports.default = fixedBase; },{}],787:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); /** * Flattens `array` a single level deep. * * @param {Array} arr The array to flatten. * @param {Array} result The array to return. * @return {Array} Returns the new flattened array. * @example * * flattenDeep([1, [2, [3, [4]], 5]]); // => [1, 2, 3, 4, 5] */ var flattenDeep = function (arr, result) { if (result === void 0) { result = []; } if (!is_array_1.default(arr)) { result.push(arr); } else { for (var i = 0; i < arr.length; i += 1) { flattenDeep(arr[i], result); } } return result; }; exports.default = flattenDeep; },{"./is-array":806}],788:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); /** * Flattens `array` a single level deep. * * @param {Array} arr The array to flatten. * @return {Array} Returns the new flattened array. * @example * * flatten([1, [2, [3, [4]], 5]]); // => [1, 2, [3, [4]], 5] */ var flatten = function (arr) { if (!is_array_1.default(arr)) { return []; } var rst = []; for (var i = 0; i < arr.length; i++) { rst = rst.concat(arr[i]); } return rst; }; exports.default = flatten; },{"./is-array":806}],789:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); exports.default = each_1.default; },{"./each":778}],790:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var getRange = function (values) { // 存在 NaN 时,min,max 判定会出问题 var filterValues = values.filter(function (v) { return !isNaN(v); }); if (!filterValues.length) { // 如果没有数值则直接返回0 return { min: 0, max: 0, }; } if (is_array_1.default(values[0])) { var tmp = []; for (var i = 0; i < values.length; i++) { tmp = tmp.concat(values[i]); } filterValues = tmp; } var max = Math.max.apply(null, filterValues); var min = Math.min.apply(null, filterValues); return { min: min, max: max, }; }; exports.default = getRange; },{"./is-array":806}],791:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var toString = {}.toString; var getType = function (value) { return toString.call(value).replace(/^\[object /, '').replace(/]$/, ''); }; exports.default = getType; },{}],792:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 获取封装的事件 * @protected * @param {Object} obj 对象 * @param {String} action 事件名称 * @return {Function} 返回事件处理函数 */ function getWrapBehavior(obj, action) { return obj['_wrap_' + action]; } exports.default = getWrapBehavior; },{}],793:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_string_1 = require("./is-string"); /** * https://github.com/developit/dlv/blob/master/index.js * @param obj * @param key * @param defaultValue */ exports.default = (function (obj, key, defaultValue) { var p = 0; var keyArr = is_string_1.default(key) ? key.split('.') : key; while (obj && p < keyArr.length) { obj = obj[keyArr[p++]]; } return (obj === undefined || p < keyArr.length) ? defaultValue : obj; }); },{"./is-string":832}],794:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_function_1 = require("./is-function"); var hasOwnProperty = Object.prototype.hasOwnProperty; function groupBy(data, condition) { if (!condition || !is_array_1.default(data)) { return {}; } var result = {}; // 兼容方法和 字符串的写法 var predicate = is_function_1.default(condition) ? condition : function (item) { return item[condition]; }; var key; for (var i = 0; i < data.length; i++) { var item = data[i]; key = predicate(item); if (hasOwnProperty.call(result, key)) { result[key].push(item); } else { result[key] = [item]; } } return result; } exports.default = groupBy; },{"./is-array":806,"./is-function":817}],795:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_function_1 = require("./is-function"); var group_by_1 = require("./group-by"); var groupToMap = function (data, condition) { if (!condition) { return { 0: data, }; } if (!is_function_1.default(condition)) { var paramsCondition_1 = is_array_1.default(condition) ? condition : condition.replace(/\s+/g, '').split('*'); condition = function (row) { var unique = '_'; // 避免出现数字作为Key的情况,会进行按照数字的排序 for (var i = 0, l = paramsCondition_1.length; i < l; i++) { unique += row[paramsCondition_1[i]] && row[paramsCondition_1[i]].toString(); } return unique; }; } var groups = group_by_1.default(data, condition); return groups; }; exports.default = groupToMap; },{"./group-by":794,"./is-array":806,"./is-function":817}],796:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var group_to_map_1 = require("./group-to-map"); exports.default = (function (data, condition) { if (!condition) { // 没有条件,则自身改成数组 return [data]; } var groups = group_to_map_1.default(data, condition); var array = []; for (var i in groups) { array.push(groups[i]); } return array; }); },{"./group-to-map":795}],797:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var has_1 = require("./has"); exports.default = has_1.default; },{"./has":799}],798:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var contains_1 = require("./contains"); var values_1 = require("./values"); exports.default = (function (obj, value) { return contains_1.default(values_1.default(obj), value); }); },{"./contains":774,"./values":873}],799:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = (function (obj, key) { return obj.hasOwnProperty(key); }); },{}],800:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); function head(o) { if (is_array_like_1.default(o)) { return o[0]; } return undefined; } exports.default = head; },{"./is-array-like":805}],801:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = (function (v) { return v; }); },{}],802:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); var indexOf = function (arr, obj) { if (!is_array_like_1.default(arr)) { return -1; } var m = Array.prototype.indexOf; if (m) { return m.call(arr, obj); } var index = -1; for (var i = 0; i < arr.length; i++) { if (arr[i] === obj) { index = i; break; } } return index; }; exports.default = indexOf; },{"./is-array-like":805}],803:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // array var contains_1 = require("./contains"); exports.contains = contains_1.default; exports.includes = contains_1.default; var difference_1 = require("./difference"); exports.difference = difference_1.default; var find_1 = require("./find"); exports.find = find_1.default; var find_index_1 = require("./find-index"); exports.findIndex = find_index_1.default; var first_value_1 = require("./first-value"); exports.firstValue = first_value_1.default; var flatten_1 = require("./flatten"); exports.flatten = flatten_1.default; var flatten_deep_1 = require("./flatten-deep"); exports.flattenDeep = flatten_deep_1.default; var get_range_1 = require("./get-range"); exports.getRange = get_range_1.default; var pull_1 = require("./pull"); exports.pull = pull_1.default; var pull_at_1 = require("./pull-at"); exports.pullAt = pull_at_1.default; var reduce_1 = require("./reduce"); exports.reduce = reduce_1.default; var remove_1 = require("./remove"); exports.remove = remove_1.default; var sort_by_1 = require("./sort-by"); exports.sortBy = sort_by_1.default; var union_1 = require("./union"); exports.union = union_1.default; var uniq_1 = require("./uniq"); exports.uniq = uniq_1.default; var values_of_key_1 = require("./values-of-key"); exports.valuesOfKey = values_of_key_1.default; var head_1 = require("./head"); exports.head = head_1.default; var last_1 = require("./last"); exports.last = last_1.default; var starts_with_1 = require("./starts-with"); exports.startsWith = starts_with_1.default; var ends_with_1 = require("./ends-with"); exports.endsWith = ends_with_1.default; var filter_1 = require("./filter"); exports.filter = filter_1.default; var every_1 = require("./every"); exports.every = every_1.default; var some_1 = require("./some"); exports.some = some_1.default; var group_1 = require("./group"); exports.group = group_1.default; var group_by_1 = require("./group-by"); exports.groupBy = group_by_1.default; var group_to_map_1 = require("./group-to-map"); exports.groupToMap = group_to_map_1.default; // event var get_wrap_behavior_1 = require("./get-wrap-behavior"); exports.getWrapBehavior = get_wrap_behavior_1.default; var wrap_behavior_1 = require("./wrap-behavior"); exports.wrapBehavior = wrap_behavior_1.default; // format var number2color_1 = require("./number2color"); exports.number2color = number2color_1.default; var parse_radius_1 = require("./parse-radius"); exports.parseRadius = parse_radius_1.default; // math var clamp_1 = require("./clamp"); exports.clamp = clamp_1.default; var fixed_base_1 = require("./fixed-base"); exports.fixedBase = fixed_base_1.default; var is_decimal_1 = require("./is-decimal"); exports.isDecimal = is_decimal_1.default; var is_even_1 = require("./is-even"); exports.isEven = is_even_1.default; var is_integer_1 = require("./is-integer"); exports.isInteger = is_integer_1.default; var is_negative_1 = require("./is-negative"); exports.isNegative = is_negative_1.default; var is_number_equal_1 = require("./is-number-equal"); exports.isNumberEqual = is_number_equal_1.default; var is_odd_1 = require("./is-odd"); exports.isOdd = is_odd_1.default; var is_positive_1 = require("./is-positive"); exports.isPositive = is_positive_1.default; var max_by_1 = require("./max-by"); exports.maxBy = max_by_1.default; var min_by_1 = require("./min-by"); exports.minBy = min_by_1.default; var mod_1 = require("./mod"); exports.mod = mod_1.default; var to_degree_1 = require("./to-degree"); exports.toDegree = to_degree_1.default; var to_integer_1 = require("./to-integer"); exports.toInteger = to_integer_1.default; var to_radian_1 = require("./to-radian"); exports.toRadian = to_radian_1.default; // object var for_in_1 = require("./for-in"); exports.forIn = for_in_1.default; var has_1 = require("./has"); exports.has = has_1.default; var has_key_1 = require("./has-key"); exports.hasKey = has_key_1.default; var has_value_1 = require("./has-value"); exports.hasValue = has_value_1.default; var keys_1 = require("./keys"); exports.keys = keys_1.default; var is_match_1 = require("./is-match"); exports.isMatch = is_match_1.default; var values_1 = require("./values"); exports.values = values_1.default; // string var lower_case_1 = require("./lower-case"); exports.lowerCase = lower_case_1.default; var lower_first_1 = require("./lower-first"); exports.lowerFirst = lower_first_1.default; var substitute_1 = require("./substitute"); exports.substitute = substitute_1.default; var upper_case_1 = require("./upper-case"); exports.upperCase = upper_case_1.default; var upper_first_1 = require("./upper-first"); exports.upperFirst = upper_first_1.default; // type var get_type_1 = require("./get-type"); exports.getType = get_type_1.default; var is_arguments_1 = require("./is-arguments"); exports.isArguments = is_arguments_1.default; var is_array_1 = require("./is-array"); exports.isArray = is_array_1.default; var is_array_like_1 = require("./is-array-like"); exports.isArrayLike = is_array_like_1.default; var is_boolean_1 = require("./is-boolean"); exports.isBoolean = is_boolean_1.default; var is_date_1 = require("./is-date"); exports.isDate = is_date_1.default; var is_error_1 = require("./is-error"); exports.isError = is_error_1.default; var is_function_1 = require("./is-function"); exports.isFunction = is_function_1.default; var is_finite_1 = require("./is-finite"); exports.isFinite = is_finite_1.default; var is_nil_1 = require("./is-nil"); exports.isNil = is_nil_1.default; var is_null_1 = require("./is-null"); exports.isNull = is_null_1.default; var is_number_1 = require("./is-number"); exports.isNumber = is_number_1.default; var is_object_1 = require("./is-object"); exports.isObject = is_object_1.default; var is_object_like_1 = require("./is-object-like"); exports.isObjectLike = is_object_like_1.default; var is_plain_object_1 = require("./is-plain-object"); exports.isPlainObject = is_plain_object_1.default; var is_prototype_1 = require("./is-prototype"); exports.isPrototype = is_prototype_1.default; var is_reg_exp_1 = require("./is-reg-exp"); exports.isRegExp = is_reg_exp_1.default; var is_string_1 = require("./is-string"); exports.isString = is_string_1.default; var is_type_1 = require("./is-type"); exports.isType = is_type_1.default; var is_undefined_1 = require("./is-undefined"); exports.isUndefined = is_undefined_1.default; var is_element_1 = require("./is-element"); exports.isElement = is_element_1.default; var request_animation_frame_1 = require("./request-animation-frame"); exports.requestAnimationFrame = request_animation_frame_1.default; var clear_animation_frame_1 = require("./clear-animation-frame"); exports.clearAnimationFrame = clear_animation_frame_1.default; // other var augment_1 = require("./augment"); exports.augment = augment_1.default; var clone_1 = require("./clone"); exports.clone = clone_1.default; var debounce_1 = require("./debounce"); exports.debounce = debounce_1.default; var memoize_1 = require("./memoize"); exports.memoize = memoize_1.default; var deep_mix_1 = require("./deep-mix"); exports.deepMix = deep_mix_1.default; var each_1 = require("./each"); exports.each = each_1.default; var extend_1 = require("./extend"); exports.extend = extend_1.default; var index_of_1 = require("./index-of"); exports.indexOf = index_of_1.default; var is_empty_1 = require("./is-empty"); exports.isEmpty = is_empty_1.default; var is_equal_1 = require("./is-equal"); exports.isEqual = is_equal_1.default; var is_equal_with_1 = require("./is-equal-with"); exports.isEqualWith = is_equal_with_1.default; var map_1 = require("./map"); exports.map = map_1.default; var map_values_1 = require("./map-values"); exports.mapValues = map_values_1.default; var mix_1 = require("./mix"); exports.mix = mix_1.default; exports.assign = mix_1.default; var get_1 = require("./get"); exports.get = get_1.default; var set_1 = require("./set"); exports.set = set_1.default; var pick_1 = require("./pick"); exports.pick = pick_1.default; var throttle_1 = require("./throttle"); exports.throttle = throttle_1.default; var to_array_1 = require("./to-array"); exports.toArray = to_array_1.default; var to_string_1 = require("./to-string"); exports.toString = to_string_1.default; var unique_id_1 = require("./unique-id"); exports.uniqueId = unique_id_1.default; var noop_1 = require("./noop"); exports.noop = noop_1.default; var identity_1 = require("./identity"); exports.identity = identity_1.default; var size_1 = require("./size"); exports.size = size_1.default; // 不知道为什么,需要把这个 export,不然 ts 会报类型错误 var cache_1 = require("./cache"); exports.Cache = cache_1.default; },{"./augment":769,"./cache":770,"./clamp":771,"./clear-animation-frame":772,"./clone":773,"./contains":774,"./debounce":775,"./deep-mix":776,"./difference":777,"./each":778,"./ends-with":779,"./every":780,"./extend":781,"./filter":782,"./find":784,"./find-index":783,"./first-value":785,"./fixed-base":786,"./flatten":788,"./flatten-deep":787,"./for-in":789,"./get":793,"./get-range":790,"./get-type":791,"./get-wrap-behavior":792,"./group":796,"./group-by":794,"./group-to-map":795,"./has":799,"./has-key":797,"./has-value":798,"./head":800,"./identity":801,"./index-of":802,"./is-arguments":804,"./is-array":806,"./is-array-like":805,"./is-boolean":807,"./is-date":808,"./is-decimal":809,"./is-element":810,"./is-empty":811,"./is-equal":813,"./is-equal-with":812,"./is-error":814,"./is-even":815,"./is-finite":816,"./is-function":817,"./is-integer":818,"./is-match":819,"./is-negative":820,"./is-nil":821,"./is-null":822,"./is-number":824,"./is-number-equal":823,"./is-object":826,"./is-object-like":825,"./is-odd":827,"./is-plain-object":828,"./is-positive":829,"./is-prototype":830,"./is-reg-exp":831,"./is-string":832,"./is-type":833,"./is-undefined":834,"./keys":835,"./last":836,"./lower-case":837,"./lower-first":838,"./map":840,"./map-values":839,"./max-by":841,"./memoize":842,"./min-by":843,"./mix":844,"./mod":845,"./noop":846,"./number2color":847,"./parse-radius":848,"./pick":849,"./pull":851,"./pull-at":850,"./reduce":852,"./remove":853,"./request-animation-frame":854,"./set":855,"./size":856,"./some":857,"./sort-by":858,"./starts-with":859,"./substitute":860,"./throttle":861,"./to-array":862,"./to-degree":863,"./to-integer":864,"./to-radian":865,"./to-string":866,"./union":867,"./uniq":868,"./unique-id":869,"./upper-case":870,"./upper-first":871,"./values":873,"./values-of-key":872,"./wrap-behavior":874}],804:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 是否是参数类型 * * @param {Object} value 测试的值 * @return {Boolean} */ var is_type_1 = require("./is-type"); var isArguments = function (value) { return is_type_1.default(value, 'Arguments'); }; exports.default = isArguments; },{"./is-type":833}],805:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var isArrayLike = function (value) { /** * isArrayLike([1, 2, 3]) => true * isArrayLike(document.body.children) => true * isArrayLike('abc') => true * isArrayLike(Function) => false */ return value !== null && typeof value !== 'function' && isFinite(value.length); }; exports.default = isArrayLike; },{}],806:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_type_1 = require("./is-type"); exports.default = (function (value) { return Array.isArray ? Array.isArray(value) : is_type_1.default(value, 'Array'); }); },{"./is-type":833}],807:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 是否是布尔类型 * * @param {Object} value 测试的值 * @return {Boolean} */ var is_type_1 = require("./is-type"); var isBoolean = function (value) { return is_type_1.default(value, 'Boolean'); }; exports.default = isBoolean; },{"./is-type":833}],808:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_type_1 = require("./is-type"); var isDate = function (value) { return is_type_1.default(value, 'Date'); }; exports.default = isDate; },{"./is-type":833}],809:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_number_1 = require("./is-number"); var isDecimal = function (num) { return is_number_1.default(num) && num % 1 !== 0; }; exports.default = isDecimal; },{"./is-number":824}],810:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 判断是否HTML元素 * @return {Boolean} 是否HTML元素 */ var isElement = function (o) { return o instanceof Element || o instanceof HTMLDocument; }; exports.default = isElement; },{}],811:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_nil_1 = require("./is-nil"); var is_array_like_1 = require("./is-array-like"); var get_type_1 = require("./get-type"); var is_prototype_1 = require("./is-prototype"); var hasOwnProperty = Object.prototype.hasOwnProperty; function isEmpty(value) { /** * isEmpty(null) => true * isEmpty() => true * isEmpty(true) => true * isEmpty(1) => true * isEmpty([1, 2, 3]) => false * isEmpty('abc') => false * isEmpty({ a: 1 }) => false */ if (is_nil_1.default(value)) { return true; } if (is_array_like_1.default(value)) { return !value.length; } var type = get_type_1.default(value); if (type === 'Map' || type === 'Set') { return !value.size; } if (is_prototype_1.default(value)) { return !Object.keys(value).length; } for (var key in value) { if (hasOwnProperty.call(value, key)) { return false; } } return true; } exports.default = isEmpty; },{"./get-type":791,"./is-array-like":805,"./is-nil":821,"./is-prototype":830}],812:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_function_1 = require("./is-function"); var is_equal_1 = require("./is-equal"); /** * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {Function} [fn] The function to customize comparisons. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * function isGreeting(value) { * return /^h(?:i|ello)$/.test(value); * } * * function customizer(objValue, othValue) { * if (isGreeting(objValue) && isGreeting(othValue)) { * return true; * } * } * * var array = ['hello', 'goodbye']; * var other = ['hi', 'goodbye']; * * isEqualWith(array, other, customizer); // => true */ exports.default = (function (value, other, fn) { if (!is_function_1.default(fn)) { return is_equal_1.default(value, other); } return !!fn(value, other); }); },{"./is-equal":813,"./is-function":817}],813:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_object_like_1 = require("./is-object-like"); var is_array_like_1 = require("./is-array-like"); var is_string_1 = require("./is-string"); var isEqual = function (value, other) { if (value === other) { return true; } if (!value || !other) { return false; } if (is_string_1.default(value) || is_string_1.default(other)) { return false; } if (is_array_like_1.default(value) || is_array_like_1.default(other)) { if (value.length !== other.length) { return false; } var rst = true; for (var i = 0; i < value.length; i++) { rst = isEqual(value[i], other[i]); if (!rst) { break; } } return rst; } if (is_object_like_1.default(value) || is_object_like_1.default(other)) { var valueKeys = Object.keys(value); var otherKeys = Object.keys(other); if (valueKeys.length !== otherKeys.length) { return false; } var rst = true; for (var i = 0; i < valueKeys.length; i++) { rst = isEqual(value[valueKeys[i]], other[valueKeys[i]]); if (!rst) { break; } } return rst; } return false; }; exports.default = isEqual; },{"./is-array-like":805,"./is-object-like":825,"./is-string":832}],814:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 是否是参数类型 * * @param {Object} value 测试的值 * @return {Boolean} */ var is_type_1 = require("./is-type"); var isError = function (value) { return is_type_1.default(value, 'Error'); }; exports.default = isError; },{"./is-type":833}],815:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_number_1 = require("./is-number"); var isEven = function (num) { return is_number_1.default(num) && num % 2 === 0; }; exports.default = isEven; },{"./is-number":824}],816:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 判断是否为有限数 * @return {Boolean} */ var is_number_1 = require("./is-number"); function default_1(value) { return is_number_1.default(value) && isFinite(value); } exports.default = default_1; },{"./is-number":824}],817:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 是否为函数 * @param {*} fn 对象 * @return {Boolean} 是否函数 */ var is_type_1 = require("./is-type"); exports.default = (function (value) { return is_type_1.default(value, 'Function'); }); },{"./is-type":833}],818:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_number_1 = require("./is-number"); var isInteger = Number.isInteger ? Number.isInteger : function (num) { return is_number_1.default(num) && num % 1 === 0; }; exports.default = isInteger; },{"./is-number":824}],819:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_nil_1 = require("./is-nil"); var keys_1 = require("./keys"); function isMatch(obj, attrs) { var _keys = keys_1.default(attrs); var length = _keys.length; if (is_nil_1.default(obj)) return !length; for (var i = 0; i < length; i += 1) { var key = _keys[i]; if (attrs[key] !== obj[key] || !(key in obj)) { return false; } } return true; } exports.default = isMatch; },{"./is-nil":821,"./keys":835}],820:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_number_1 = require("./is-number"); var isNegative = function (num) { return is_number_1.default(num) && num < 0; }; exports.default = isNegative; },{"./is-number":824}],821:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // isFinite, var isNil = function (value) { /** * isNil(null) => true * isNil() => true */ return value === null || value === undefined; }; exports.default = isNil; },{}],822:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var isNull = function (value) { return value === null; }; exports.default = isNull; },{}],823:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var PRECISION = 0.00001; // numbers less than this is considered as 0 function isNumberEqual(a, b, precision) { if (precision === void 0) { precision = PRECISION; } return Math.abs((a - b)) < precision; } exports.default = isNumberEqual; ; },{}],824:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 判断是否数字 * @return {Boolean} 是否数字 */ var is_type_1 = require("./is-type"); var isNumber = function (value) { return is_type_1.default(value, 'Number'); }; exports.default = isNumber; },{"./is-type":833}],825:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var isObjectLike = function (value) { /** * isObjectLike({}) => true * isObjectLike([1, 2, 3]) => true * isObjectLike(Function) => false * isObjectLike(null) => false */ return typeof value === 'object' && value !== null; }; exports.default = isObjectLike; },{}],826:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = (function (value) { /** * isObject({}) => true * isObject([1, 2, 3]) => true * isObject(Function) => true * isObject(null) => false */ var type = typeof value; return value !== null && type === 'object' || type === 'function'; }); },{}],827:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_number_1 = require("./is-number"); var isOdd = function (num) { return is_number_1.default(num) && num % 2 !== 0; }; exports.default = isOdd; },{"./is-number":824}],828:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_object_like_1 = require("./is-object-like"); var is_type_1 = require("./is-type"); var isPlainObject = function (value) { /** * isObjectLike(new Foo) => false * isObjectLike([1, 2, 3]) => false * isObjectLike({ x: 0, y: 0 }) => true * isObjectLike(Object.create(null)) => true */ if (!is_object_like_1.default(value) || !is_type_1.default(value, 'Object')) { return false; } if (Object.getPrototypeOf(value) === null) { return true; } var proto = value; while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto); } return Object.getPrototypeOf(value) === proto; }; exports.default = isPlainObject; },{"./is-object-like":825,"./is-type":833}],829:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_number_1 = require("./is-number"); var isPositive = function (num) { return is_number_1.default(num) && num > 0; }; exports.default = isPositive; },{"./is-number":824}],830:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var objectProto = Object.prototype; var isPrototype = function (value) { var Ctor = value && value.constructor; var proto = (typeof Ctor === 'function' && Ctor.prototype) || objectProto; return value === proto; }; exports.default = isPrototype; },{}],831:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_type_1 = require("./is-type"); var isRegExp = function (str) { return is_type_1.default(str, 'RegExp'); }; exports.default = isRegExp; },{"./is-type":833}],832:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_type_1 = require("./is-type"); exports.default = (function (str) { return is_type_1.default(str, 'String'); }); },{"./is-type":833}],833:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var toString = {}.toString; var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; }; exports.default = isType; },{}],834:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var isUndefined = function (value) { return value === undefined; }; exports.default = isUndefined; },{}],835:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); var is_function_1 = require("./is-function"); var keys = Object.keys ? function (obj) { return Object.keys(obj); } : function (obj) { var result = []; each_1.default(obj, function (value, key) { if (!(is_function_1.default(obj) && key === 'prototype')) { result.push(key); } }); return result; }; exports.default = keys; },{"./each":778,"./is-function":817}],836:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); function last(o) { if (is_array_like_1.default(o)) { var arr = o; return arr[arr.length - 1]; } return undefined; } exports.default = last; },{"./is-array-like":805}],837:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var to_string_1 = require("./to-string"); var lowerCase = function (str) { return to_string_1.default(str).toLowerCase(); }; exports.default = lowerCase; },{"./to-string":866}],838:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var to_string_1 = require("./to-string"); var lowerFirst = function (value) { var str = to_string_1.default(value); return str.charAt(0).toLowerCase() + str.substring(1); }; exports.default = lowerFirst; },{"./to-string":866}],839:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_nil_1 = require("./is-nil"); var is_object_1 = require("./is-object"); var identity = function (v) { return v; }; exports.default = (function (object, func) { if (func === void 0) { func = identity; } var r = {}; if (is_object_1.default(object) && !is_nil_1.default(object)) { Object.keys(object).forEach(function (key) { // @ts-ignore r[key] = func(object[key], key); }); } return r; }); },{"./is-nil":821,"./is-object":826}],840:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); var map = function (arr, func) { if (!is_array_like_1.default(arr)) { // @ts-ignore return arr; } var result = []; for (var index = 0; index < arr.length; index++) { var value = arr[index]; result.push(func(value, index)); } return result; }; exports.default = map; },{"./is-array-like":805}],841:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); var is_array_1 = require("./is-array"); var is_function_1 = require("./is-function"); /** * @param {Array} arr The array to iterate over. * @param {Function} [fn] The iteratee invoked per element. * @return {*} Returns the maximum value. * @example * * var objects = [{ 'n': 1 }, { 'n': 2 }]; * * maxBy(objects, function(o) { return o.n; }); * // => { 'n': 2 } * * maxBy(objects, 'n'); * // => { 'n': 2 } */ exports.default = (function (arr, fn) { if (!is_array_1.default(arr)) { return undefined; } var max = arr[0]; var maxData; if (is_function_1.default(fn)) { maxData = fn(arr[0]); } else { maxData = arr[0][fn]; } var data; each_1.default(arr, function (val) { if (is_function_1.default(fn)) { data = fn(val); } else { data = val[fn]; } if (data > maxData) { max = val; maxData = data; } }); return max; }); },{"./each":778,"./is-array":806,"./is-function":817}],842:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_function_1 = require("./is-function"); /** * _.memoize(calColor); * _.memoize(calColor, (...args) => args[0]); * @param f * @param resolver */ exports.default = (function (f, resolver) { if (!is_function_1.default(f)) { throw new TypeError('Expected a function'); } var memoized = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } // 使用方法构造 key,如果不存在 resolver,则直接取第一个参数作为 key var key = resolver ? resolver.apply(this, args) : args[0]; var cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = f.apply(this, args); // 缓存起来 cache.set(key, result); return result; }; memoized.cache = new Map(); return memoized; }); },{"./is-function":817}],843:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); var is_array_1 = require("./is-array"); var is_function_1 = require("./is-function"); /** * @param {Array} arr The array to iterate over. * @param {Function} [fn] The iteratee invoked per element. * @return {*} Returns the minimum value. * @example * * var objects = [{ 'n': 1 }, { 'n': 2 }]; * * minBy(objects, function(o) { return o.n; }); * // => { 'n': 1 } * * minBy(objects, 'n'); * // => { 'n': 1 } */ exports.default = (function (arr, fn) { if (!is_array_1.default(arr)) { return undefined; } var min = arr[0]; var minData; if (is_function_1.default(fn)) { minData = fn(arr[0]); } else { minData = arr[0][fn]; } var data; each_1.default(arr, function (val) { if (is_function_1.default(fn)) { data = fn(val); } else { data = val[fn]; } if (data < minData) { min = val; minData = data; } }); return min; }); },{"./each":778,"./is-array":806,"./is-function":817}],844:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // FIXME: Mutable param should be forbidden in static lang. function _mix(dist, obj) { for (var key in obj) { if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) { dist[key] = obj[key]; } } } function mix(dist, src1, src2, src3) { if (src1) _mix(dist, src1); if (src2) _mix(dist, src2); if (src3) _mix(dist, src3); return dist; } exports.default = mix; },{}],845:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var mod = function (n, m) { return ((n % m) + m) % m; }; exports.default = mod; },{}],846:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = (function () { }); },{}],847:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var numColorCache = {}; function numberToColor(num) { // 增加缓存 var color = numColorCache[num]; if (!color) { var str = num.toString(16); for (var i = str.length; i < 6; i++) { str = '0' + str; } color = '#' + str; numColorCache[num] = color; } return color; } exports.default = numberToColor; },{}],848:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); function parseRadius(radius) { var r1 = 0, r2 = 0, r3 = 0, r4 = 0; if (is_array_1.default(radius)) { if (radius.length === 1) { r1 = r2 = r3 = r4 = radius[0]; } else if (radius.length === 2) { r1 = r3 = radius[0]; r2 = r4 = radius[1]; } else if (radius.length === 3) { r1 = radius[0]; r2 = r4 = radius[1]; r3 = radius[2]; } else { r1 = radius[0]; r2 = radius[1]; r3 = radius[2]; r4 = radius[3]; } } else { r1 = r2 = r3 = r4 = radius; } return { r1: r1, r2: r2, r3: r3, r4: r4 }; } exports.default = parseRadius; },{"./is-array":806}],849:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); var is_plain_object_1 = require("./is-plain-object"); var hasOwnProperty = Object.prototype.hasOwnProperty; exports.default = (function (object, keys) { if (object === null || !is_plain_object_1.default(object)) { return {}; } var result = {}; each_1.default(keys, function (key) { if (hasOwnProperty.call(object, key)) { result[key] = object[key]; } }); return result; }); },{"./each":778,"./is-plain-object":828}],850:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); var splice = Array.prototype.splice; var pullAt = function pullAt(arr, indexes) { if (!is_array_like_1.default(arr)) { return []; } var length = arr ? indexes.length : 0; var last = length - 1; while (length--) { var previous = void 0; var index = indexes[length]; if (length === last || index !== previous) { previous = index; splice.call(arr, index, 1); } } return arr; }; exports.default = pullAt; },{"./is-array-like":805}],851:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var arrPrototype = Array.prototype; var splice = arrPrototype.splice; var indexOf = arrPrototype.indexOf; var pull = function (arr) { var values = []; for (var _i = 1; _i < arguments.length; _i++) { values[_i - 1] = arguments[_i]; } for (var i = 0; i < values.length; i++) { var value = values[i]; var fromIndex = -1; while ((fromIndex = indexOf.call(arr, value)) > -1) { splice.call(arr, fromIndex, 1); } } return arr; }; exports.default = pull; },{}],852:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); var is_array_1 = require("./is-array"); var is_plain_object_1 = require("./is-plain-object"); var reduce = function (arr, fn, init) { if (!is_array_1.default(arr) && !is_plain_object_1.default(arr)) { return arr; } var result = init; each_1.default(arr, function (data, i) { result = fn(result, data, i); }); return result; }; exports.default = reduce; },{"./each":778,"./is-array":806,"./is-plain-object":828}],853:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); var pull_at_1 = require("./pull-at"); var remove = function (arr, predicate) { /** * const arr = [1, 2, 3, 4] * const evens = remove(arr, n => n % 2 == 0) * console.log(arr) // => [1, 3] * console.log(evens) // => [2, 4] */ var result = []; if (!is_array_like_1.default(arr)) { return result; } var i = -1; var indexes = []; var length = arr.length; while (++i < length) { var value = arr[i]; if (predicate(value, i, arr)) { result.push(value); indexes.push(i); } } pull_at_1.default(arr, indexes); return result; }; exports.default = remove; },{"./is-array-like":805,"./pull-at":850}],854:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function requestAnimationFrame(fn) { var method = window.requestAnimationFrame || window.webkitRequestAnimationFrame || // @ts-ignore window.mozRequestAnimationFrame || // @ts-ignore window.msRequestAnimationFrame || function (f) { return setTimeout(f, 16); }; return method(fn); } exports.default = requestAnimationFrame; ; },{}],855:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_object_1 = require("./is-object"); var is_string_1 = require("./is-string"); var is_number_1 = require("./is-number"); /** * https://github.com/developit/dlv/blob/master/index.js * @param obj * @param path * @param value */ exports.default = (function (obj, path, value) { var o = obj; var keyArr = is_string_1.default(path) ? path.split('.') : path; keyArr.forEach(function (key, idx) { // 不是最后一个 if (idx < keyArr.length - 1) { if (!is_object_1.default(o[key])) { o[key] = is_number_1.default(keyArr[idx + 1]) ? [] : {}; } o = o[key]; } else { o[key] = value; } }); return obj; }); },{"./is-number":824,"./is-object":826,"./is-string":832}],856:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_nil_1 = require("./is-nil"); var is_array_like_1 = require("./is-array-like"); function size(o) { if (is_nil_1.default(o)) { return 0; } if (is_array_like_1.default(o)) { return o.length; } return Object.keys(o).length; } exports.default = size; },{"./is-array-like":805,"./is-nil":821}],857:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 只要有一个满足条件就返回 true * @param arr * @param func */ var some = function (arr, func) { for (var i = 0; i < arr.length; i++) { if (func(arr[i], i)) return true; } return false; }; exports.default = some; },{}],858:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_string_1 = require("./is-string"); var is_function_1 = require("./is-function"); function sortBy(arr, key) { var comparer; if (is_function_1.default(key)) { comparer = function (a, b) { return key(a) - key(b); }; } else { var keys_1 = []; if (is_string_1.default(key)) { keys_1.push(key); } else if (is_array_1.default(key)) { keys_1 = key; } comparer = function (a, b) { for (var i = 0; i < keys_1.length; i += 1) { var prop = keys_1[i]; if (a[prop] > b[prop]) { return 1; } if (a[prop] < b[prop]) { return -1; } } return 0; }; } arr.sort(comparer); return arr; } exports.default = sortBy; },{"./is-array":806,"./is-function":817,"./is-string":832}],859:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_string_1 = require("./is-string"); function startsWith(arr, e) { return (is_array_1.default(arr) || is_string_1.default(arr)) ? arr[0] === e : false; } exports.default = startsWith; },{"./is-array":806,"./is-string":832}],860:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function substitute(str, o) { if (!str || !o) { return str; } return str.replace(/\\?\{([^{}]+)\}/g, function (match, name) { if (match.charAt(0) === '\\') { return match.slice(1); } return (o[name] === undefined) ? '' : o[name]; }); } exports.default = substitute; },{}],861:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = (function (func, wait, options) { var timeout, context, args, result; var previous = 0; if (!options) options = {}; var later = function () { previous = options.leading === false ? 0 : Date.now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; var throttled = function () { var now = Date.now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; throttled.cancel = function () { clearTimeout(timeout); previous = 0; timeout = context = args = null; }; return throttled; }); },{}],862:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_like_1 = require("./is-array-like"); exports.default = (function (value) { return is_array_like_1.default(value) ? Array.prototype.slice.call(value) : []; }); },{"./is-array-like":805}],863:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var DEGREE = 180 / Math.PI; var toDegree = function (radian) { return DEGREE * radian; }; exports.default = toDegree; },{}],864:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = parseInt; },{}],865:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var RADIAN = Math.PI / 180; var toRadian = function (degree) { return RADIAN * degree; }; exports.default = toRadian; },{}],866:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_nil_1 = require("./is-nil"); exports.default = (function (value) { if (is_nil_1.default(value)) return ''; return value.toString(); }); },{"./is-nil":821}],867:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var uniq_1 = require("./uniq"); var union = function () { var sources = []; for (var _i = 0; _i < arguments.length; _i++) { sources[_i] = arguments[_i]; } return uniq_1.default([].concat.apply([], sources)); }; exports.default = union; },{"./uniq":868}],868:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var contains_1 = require("./contains"); var each_1 = require("./each"); var uniq = function (arr) { var resultArr = []; each_1.default(arr, function (item) { if (!contains_1.default(resultArr, item)) { resultArr.push(item); } }); return resultArr; }; exports.default = uniq; },{"./contains":774,"./each":778}],869:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var map = {}; exports.default = (function (prefix) { prefix = prefix || 'g'; if (!map[prefix]) { map[prefix] = 1; } else { map[prefix] += 1; } return prefix + map[prefix]; }); },{}],870:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var to_string_1 = require("./to-string"); var upperCase = function (str) { return to_string_1.default(str).toUpperCase(); }; exports.default = upperCase; },{"./to-string":866}],871:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var to_string_1 = require("./to-string"); var upperFirst = function (value) { var str = to_string_1.default(value); return str.charAt(0).toUpperCase() + str.substring(1); }; exports.default = upperFirst; },{"./to-string":866}],872:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var is_array_1 = require("./is-array"); var is_nil_1 = require("./is-nil"); exports.default = (function (data, name) { var rst = []; var tmpMap = {}; for (var i = 0; i < data.length; i++) { var obj = data[i]; var value = obj[name]; if (!is_nil_1.default(value)) { // flatten if (!is_array_1.default(value)) { value = [value]; } for (var j = 0; j < value.length; j++) { var val = value[j]; // unique if (!tmpMap[val]) { rst.push(val); tmpMap[val] = true; } } } } return rst; }); },{"./is-array":806,"./is-nil":821}],873:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var each_1 = require("./each"); var is_function_1 = require("./is-function"); // @ts-ignore var values = Object.values ? function (obj) { return Object.values(obj); } : function (obj) { var result = []; each_1.default(obj, function (value, key) { if (!(is_function_1.default(obj) && key === 'prototype')) { result.push(value); } }); return result; }; exports.default = values; },{"./each":778,"./is-function":817}],874:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 封装事件,便于使用上下文this,和便于解除事件时使用 * @protected * @param {Object} obj 对象 * @param {String} action 事件名称 * @return {Function} 返回事件处理函数 */ function wrapBehavior(obj, action) { if (obj['_wrap_' + action]) { return obj['_wrap_' + action]; } var method = function (e) { obj[action](e); }; obj['_wrap_' + action] = method; return method; } exports.default = wrapBehavior; },{}],875:[function(require,module,exports){ // https://d3js.org/d3-color/ v1.4.1 Copyright 2020 Mike Bostock (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.d3 = global.d3 || {})); }(this, function (exports) { 'use strict'; function define(constructor, factory, prototype) { constructor.prototype = factory.prototype = prototype; prototype.constructor = constructor; } function extend(parent, definition) { var prototype = Object.create(parent.prototype); for (var key in definition) prototype[key] = definition[key]; return prototype; } function Color() {} var darker = 0.7; var brighter = 1 / darker; var reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", reHex = /^#([0-9a-f]{3,8})$/, reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); var named = { aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4, azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000, blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a, burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e, coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c, cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b, darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b, darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc, darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b, darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3, deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969, dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22, fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700, goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f, grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c, indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa, lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6, lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3, lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a, lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899, lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32, linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa, mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371, mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585, midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5, navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000, olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6, palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093, papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb, plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399, red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513, salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee, sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd, slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f, steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8, tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3, white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32 }; define(Color, color, { copy: function(channels) { return Object.assign(new this.constructor, this, channels); }, displayable: function() { return this.rgb().displayable(); }, hex: color_formatHex, // Deprecated! Use color.formatHex. formatHex: color_formatHex, formatHsl: color_formatHsl, formatRgb: color_formatRgb, toString: color_formatRgb }); function color_formatHex() { return this.rgb().formatHex(); } function color_formatHsl() { return hslConvert(this).formatHsl(); } function color_formatRgb() { return this.rgb().formatRgb(); } function color(format) { var m, l; format = (format + "").trim().toLowerCase(); return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 : null) // invalid hex : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null; } function rgbn(n) { return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); } function rgba(r, g, b, a) { if (a <= 0) r = g = b = NaN; return new Rgb(r, g, b, a); } function rgbConvert(o) { if (!(o instanceof Color)) o = color(o); if (!o) return new Rgb; o = o.rgb(); return new Rgb(o.r, o.g, o.b, o.opacity); } function rgb(r, g, b, opacity) { return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); } function Rgb(r, g, b, opacity) { this.r = +r; this.g = +g; this.b = +b; this.opacity = +opacity; } define(Rgb, rgb, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); }, rgb: function() { return this; }, displayable: function() { return (-0.5 <= this.r && this.r < 255.5) && (-0.5 <= this.g && this.g < 255.5) && (-0.5 <= this.b && this.b < 255.5) && (0 <= this.opacity && this.opacity <= 1); }, hex: rgb_formatHex, // Deprecated! Use color.formatHex. formatHex: rgb_formatHex, formatRgb: rgb_formatRgb, toString: rgb_formatRgb })); function rgb_formatHex() { return "#" + hex(this.r) + hex(this.g) + hex(this.b); } function rgb_formatRgb() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")"); } function hex(value) { value = Math.max(0, Math.min(255, Math.round(value) || 0)); return (value < 16 ? "0" : "") + value.toString(16); } function hsla(h, s, l, a) { if (a <= 0) h = s = l = NaN; else if (l <= 0 || l >= 1) h = s = NaN; else if (s <= 0) h = NaN; return new Hsl(h, s, l, a); } function hslConvert(o) { if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); if (!(o instanceof Color)) o = color(o); if (!o) return new Hsl; if (o instanceof Hsl) return o; o = o.rgb(); var r = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r, g, b), max = Math.max(r, g, b), h = NaN, s = max - min, l = (max + min) / 2; if (s) { if (r === max) h = (g - b) / s + (g < b) * 6; else if (g === max) h = (b - r) / s + 2; else h = (r - g) / s + 4; s /= l < 0.5 ? max + min : 2 - max - min; h *= 60; } else { s = l > 0 && l < 1 ? 0 : h; } return new Hsl(h, s, l, o.opacity); } function hsl(h, s, l, opacity) { return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); } function Hsl(h, s, l, opacity) { this.h = +h; this.s = +s; this.l = +l; this.opacity = +opacity; } define(Hsl, hsl, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Hsl(this.h, this.s, this.l * k, this.opacity); }, rgb: function() { var h = this.h % 360 + (this.h < 0) * 360, s = isNaN(h) || isNaN(this.s) ? 0 : this.s, l = this.l, m2 = l + (l < 0.5 ? l : 1 - l) * s, m1 = 2 * l - m2; return new Rgb( hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity ); }, displayable: function() { return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && (0 <= this.l && this.l <= 1) && (0 <= this.opacity && this.opacity <= 1); }, formatHsl: function() { var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); return (a === 1 ? "hsl(" : "hsla(") + (this.h || 0) + ", " + (this.s || 0) * 100 + "%, " + (this.l || 0) * 100 + "%" + (a === 1 ? ")" : ", " + a + ")"); } })); /* From FvD 13.37, CSS Color Module Level 3 */ function hsl2rgb(h, m1, m2) { return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255; } var deg2rad = Math.PI / 180; var rad2deg = 180 / Math.PI; // https://observablehq.com/@mbostock/lab-and-rgb var K = 18, Xn = 0.96422, Yn = 1, Zn = 0.82521, t0 = 4 / 29, t1 = 6 / 29, t2 = 3 * t1 * t1, t3 = t1 * t1 * t1; function labConvert(o) { if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); if (o instanceof Hcl) return hcl2lab(o); if (!(o instanceof Rgb)) o = rgbConvert(o); var r = rgb2lrgb(o.r), g = rgb2lrgb(o.g), b = rgb2lrgb(o.b), y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z; if (r === g && g === b) x = z = y; else { x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn); z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn); } return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); } function gray(l, opacity) { return new Lab(l, 0, 0, opacity == null ? 1 : opacity); } function lab(l, a, b, opacity) { return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); } function Lab(l, a, b, opacity) { this.l = +l; this.a = +a; this.b = +b; this.opacity = +opacity; } define(Lab, lab, extend(Color, { brighter: function(k) { return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity); }, darker: function(k) { return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity); }, rgb: function() { var y = (this.l + 16) / 116, x = isNaN(this.a) ? y : y + this.a / 500, z = isNaN(this.b) ? y : y - this.b / 200; x = Xn * lab2xyz(x); y = Yn * lab2xyz(y); z = Zn * lab2xyz(z); return new Rgb( lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z), lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z), lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z), this.opacity ); } })); function xyz2lab(t) { return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; } function lab2xyz(t) { return t > t1 ? t * t * t : t2 * (t - t0); } function lrgb2rgb(x) { return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); } function rgb2lrgb(x) { return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); } function hclConvert(o) { if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); if (!(o instanceof Lab)) o = labConvert(o); if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0 < o.l && o.l < 100 ? 0 : NaN, o.l, o.opacity); var h = Math.atan2(o.b, o.a) * rad2deg; return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); } function lch(l, c, h, opacity) { return arguments.length === 1 ? hclConvert(l) : new Hcl(h, c, l, opacity == null ? 1 : opacity); } function hcl(h, c, l, opacity) { return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); } function Hcl(h, c, l, opacity) { this.h = +h; this.c = +c; this.l = +l; this.opacity = +opacity; } function hcl2lab(o) { if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity); var h = o.h * deg2rad; return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); } define(Hcl, hcl, extend(Color, { brighter: function(k) { return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity); }, darker: function(k) { return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity); }, rgb: function() { return hcl2lab(this).rgb(); } })); var A = -0.14861, B = +1.78277, C = -0.29227, D = -0.90649, E = +1.97294, ED = E * D, EB = E * B, BC_DA = B * C - D * A; function cubehelixConvert(o) { if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); if (!(o instanceof Rgb)) o = rgbConvert(o); var r = o.r / 255, g = o.g / 255, b = o.b / 255, l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), bl = b - l, k = (E * (g - l) - C * bl) / D, s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); } function cubehelix(h, s, l, opacity) { return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); } function Cubehelix(h, s, l, opacity) { this.h = +h; this.s = +s; this.l = +l; this.opacity = +opacity; } define(Cubehelix, cubehelix, extend(Color, { brighter: function(k) { k = k == null ? brighter : Math.pow(brighter, k); return new Cubehelix(this.h, this.s, this.l * k, this.opacity); }, darker: function(k) { k = k == null ? darker : Math.pow(darker, k); return new Cubehelix(this.h, this.s, this.l * k, this.opacity); }, rgb: function() { var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, l = +this.l, a = isNaN(this.s) ? 0 : this.s * l * (1 - l), cosh = Math.cos(h), sinh = Math.sin(h); return new Rgb( 255 * (l + a * (A * cosh + B * sinh)), 255 * (l + a * (C * cosh + D * sinh)), 255 * (l + a * (E * cosh)), this.opacity ); } })); exports.color = color; exports.cubehelix = cubehelix; exports.gray = gray; exports.hcl = hcl; exports.hsl = hsl; exports.lab = lab; exports.lch = lch; exports.rgb = rgb; Object.defineProperty(exports, '__esModule', { value: true }); })); },{}],876:[function(require,module,exports){ // https://d3js.org/d3-ease/ v1.0.7 Copyright 2020 Mike Bostock (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.d3 = global.d3 || {})); }(this, function (exports) { 'use strict'; function linear(t) { return +t; } function quadIn(t) { return t * t; } function quadOut(t) { return t * (2 - t); } function quadInOut(t) { return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2; } function cubicIn(t) { return t * t * t; } function cubicOut(t) { return --t * t * t + 1; } function cubicInOut(t) { return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; } var exponent = 3; var polyIn = (function custom(e) { e = +e; function polyIn(t) { return Math.pow(t, e); } polyIn.exponent = custom; return polyIn; })(exponent); var polyOut = (function custom(e) { e = +e; function polyOut(t) { return 1 - Math.pow(1 - t, e); } polyOut.exponent = custom; return polyOut; })(exponent); var polyInOut = (function custom(e) { e = +e; function polyInOut(t) { return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2; } polyInOut.exponent = custom; return polyInOut; })(exponent); var pi = Math.PI, halfPi = pi / 2; function sinIn(t) { return (+t === 1) ? 1 : 1 - Math.cos(t * halfPi); } function sinOut(t) { return Math.sin(t * halfPi); } function sinInOut(t) { return (1 - Math.cos(pi * t)) / 2; } // tpmt is two power minus ten times t scaled to [0,1] function tpmt(x) { return (Math.pow(2, -10 * x) - 0.0009765625) * 1.0009775171065494; } function expIn(t) { return tpmt(1 - +t); } function expOut(t) { return 1 - tpmt(t); } function expInOut(t) { return ((t *= 2) <= 1 ? tpmt(1 - t) : 2 - tpmt(t - 1)) / 2; } function circleIn(t) { return 1 - Math.sqrt(1 - t * t); } function circleOut(t) { return Math.sqrt(1 - --t * t); } function circleInOut(t) { return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2; } var b1 = 4 / 11, b2 = 6 / 11, b3 = 8 / 11, b4 = 3 / 4, b5 = 9 / 11, b6 = 10 / 11, b7 = 15 / 16, b8 = 21 / 22, b9 = 63 / 64, b0 = 1 / b1 / b1; function bounceIn(t) { return 1 - bounceOut(1 - t); } function bounceOut(t) { return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9; } function bounceInOut(t) { return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2; } var overshoot = 1.70158; var backIn = (function custom(s) { s = +s; function backIn(t) { return (t = +t) * t * (s * (t - 1) + t); } backIn.overshoot = custom; return backIn; })(overshoot); var backOut = (function custom(s) { s = +s; function backOut(t) { return --t * t * ((t + 1) * s + t) + 1; } backOut.overshoot = custom; return backOut; })(overshoot); var backInOut = (function custom(s) { s = +s; function backInOut(t) { return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2; } backInOut.overshoot = custom; return backInOut; })(overshoot); var tau = 2 * Math.PI, amplitude = 1, period = 0.3; var elasticIn = (function custom(a, p) { var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); function elasticIn(t) { return a * tpmt(-(--t)) * Math.sin((s - t) / p); } elasticIn.amplitude = function(a) { return custom(a, p * tau); }; elasticIn.period = function(p) { return custom(a, p); }; return elasticIn; })(amplitude, period); var elasticOut = (function custom(a, p) { var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); function elasticOut(t) { return 1 - a * tpmt(t = +t) * Math.sin((t + s) / p); } elasticOut.amplitude = function(a) { return custom(a, p * tau); }; elasticOut.period = function(p) { return custom(a, p); }; return elasticOut; })(amplitude, period); var elasticInOut = (function custom(a, p) { var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau); function elasticInOut(t) { return ((t = t * 2 - 1) < 0 ? a * tpmt(-t) * Math.sin((s - t) / p) : 2 - a * tpmt(t) * Math.sin((s + t) / p)) / 2; } elasticInOut.amplitude = function(a) { return custom(a, p * tau); }; elasticInOut.period = function(p) { return custom(a, p); }; return elasticInOut; })(amplitude, period); exports.easeBack = backInOut; exports.easeBackIn = backIn; exports.easeBackInOut = backInOut; exports.easeBackOut = backOut; exports.easeBounce = bounceOut; exports.easeBounceIn = bounceIn; exports.easeBounceInOut = bounceInOut; exports.easeBounceOut = bounceOut; exports.easeCircle = circleInOut; exports.easeCircleIn = circleIn; exports.easeCircleInOut = circleInOut; exports.easeCircleOut = circleOut; exports.easeCubic = cubicInOut; exports.easeCubicIn = cubicIn; exports.easeCubicInOut = cubicInOut; exports.easeCubicOut = cubicOut; exports.easeElastic = elasticOut; exports.easeElasticIn = elasticIn; exports.easeElasticInOut = elasticInOut; exports.easeElasticOut = elasticOut; exports.easeExp = expInOut; exports.easeExpIn = expIn; exports.easeExpInOut = expInOut; exports.easeExpOut = expOut; exports.easeLinear = linear; exports.easePoly = polyInOut; exports.easePolyIn = polyIn; exports.easePolyInOut = polyInOut; exports.easePolyOut = polyOut; exports.easeQuad = quadInOut; exports.easeQuadIn = quadIn; exports.easeQuadInOut = quadInOut; exports.easeQuadOut = quadOut; exports.easeSin = sinInOut; exports.easeSinIn = sinIn; exports.easeSinInOut = sinInOut; exports.easeSinOut = sinOut; Object.defineProperty(exports, '__esModule', { value: true }); })); },{}],877:[function(require,module,exports){ // https://d3js.org/d3-interpolate/ v1.4.0 Copyright 2019 Mike Bostock (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-color')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-color'], factory) : (global = global || self, factory(global.d3 = global.d3 || {}, global.d3)); }(this, function (exports, d3Color) { 'use strict'; function basis(t1, v0, v1, v2, v3) { var t2 = t1 * t1, t3 = t2 * t1; return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + (4 - 6 * t2 + 3 * t3) * v1 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + t3 * v3) / 6; } function basis$1(values) { var n = values.length - 1; return function(t) { var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), v1 = values[i], v2 = values[i + 1], v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; return basis((t - i / n) * n, v0, v1, v2, v3); }; } function basisClosed(values) { var n = values.length; return function(t) { var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), v0 = values[(i + n - 1) % n], v1 = values[i % n], v2 = values[(i + 1) % n], v3 = values[(i + 2) % n]; return basis((t - i / n) * n, v0, v1, v2, v3); }; } function constant(x) { return function() { return x; }; } function linear(a, d) { return function(t) { return a + t * d; }; } function exponential(a, b, y) { return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { return Math.pow(a + t * b, y); }; } function hue(a, b) { var d = b - a; return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a); } function gamma(y) { return (y = +y) === 1 ? nogamma : function(a, b) { return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a); }; } function nogamma(a, b) { var d = b - a; return d ? linear(a, d) : constant(isNaN(a) ? b : a); } var rgb = (function rgbGamma(y) { var color = gamma(y); function rgb(start, end) { var r = color((start = d3Color.rgb(start)).r, (end = d3Color.rgb(end)).r), g = color(start.g, end.g), b = color(start.b, end.b), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.r = r(t); start.g = g(t); start.b = b(t); start.opacity = opacity(t); return start + ""; }; } rgb.gamma = rgbGamma; return rgb; })(1); function rgbSpline(spline) { return function(colors) { var n = colors.length, r = new Array(n), g = new Array(n), b = new Array(n), i, color; for (i = 0; i < n; ++i) { color = d3Color.rgb(colors[i]); r[i] = color.r || 0; g[i] = color.g || 0; b[i] = color.b || 0; } r = spline(r); g = spline(g); b = spline(b); color.opacity = 1; return function(t) { color.r = r(t); color.g = g(t); color.b = b(t); return color + ""; }; }; } var rgbBasis = rgbSpline(basis$1); var rgbBasisClosed = rgbSpline(basisClosed); function numberArray(a, b) { if (!b) b = []; var n = a ? Math.min(b.length, a.length) : 0, c = b.slice(), i; return function(t) { for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t; return c; }; } function isNumberArray(x) { return ArrayBuffer.isView(x) && !(x instanceof DataView); } function array(a, b) { return (isNumberArray(b) ? numberArray : genericArray)(a, b); } function genericArray(a, b) { var nb = b ? b.length : 0, na = a ? Math.min(nb, a.length) : 0, x = new Array(na), c = new Array(nb), i; for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]); for (; i < nb; ++i) c[i] = b[i]; return function(t) { for (i = 0; i < na; ++i) c[i] = x[i](t); return c; }; } function date(a, b) { var d = new Date; return a = +a, b = +b, function(t) { return d.setTime(a * (1 - t) + b * t), d; }; } function number(a, b) { return a = +a, b = +b, function(t) { return a * (1 - t) + b * t; }; } function object(a, b) { var i = {}, c = {}, k; if (a === null || typeof a !== "object") a = {}; if (b === null || typeof b !== "object") b = {}; for (k in b) { if (k in a) { i[k] = value(a[k], b[k]); } else { c[k] = b[k]; } } return function(t) { for (k in i) c[k] = i[k](t); return c; }; } var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, reB = new RegExp(reA.source, "g"); function zero(b) { return function() { return b; }; } function one(b) { return function(t) { return b(t) + ""; }; } function string(a, b) { var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b am, // current match in a bm, // current match in b bs, // string preceding current number in b, if any i = -1, // index in s s = [], // string constants and placeholders q = []; // number interpolators // Coerce inputs to strings. a = a + "", b = b + ""; // Interpolate pairs of numbers in a & b. while ((am = reA.exec(a)) && (bm = reB.exec(b))) { if ((bs = bm.index) > bi) { // a string precedes the next number in b bs = b.slice(bi, bs); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match if (s[i]) s[i] += bm; // coalesce with previous string else s[++i] = bm; } else { // interpolate non-matching numbers s[++i] = null; q.push({i: i, x: number(am, bm)}); } bi = reB.lastIndex; } // Add remains of b. if (bi < b.length) { bs = b.slice(bi); if (s[i]) s[i] += bs; // coalesce with previous string else s[++i] = bs; } // Special optimization for only a single match. // Otherwise, interpolate each of the numbers and rejoin the string. return s.length < 2 ? (q[0] ? one(q[0].x) : zero(b)) : (b = q.length, function(t) { for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); return s.join(""); }); } function value(a, b) { var t = typeof b, c; return b == null || t === "boolean" ? constant(b) : (t === "number" ? number : t === "string" ? ((c = d3Color.color(b)) ? (b = c, rgb) : string) : b instanceof d3Color.color ? rgb : b instanceof Date ? date : isNumberArray(b) ? numberArray : Array.isArray(b) ? genericArray : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object : number)(a, b); } function discrete(range) { var n = range.length; return function(t) { return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; }; } function hue$1(a, b) { var i = hue(+a, +b); return function(t) { var x = i(t); return x - 360 * Math.floor(x / 360); }; } function round(a, b) { return a = +a, b = +b, function(t) { return Math.round(a * (1 - t) + b * t); }; } var degrees = 180 / Math.PI; var identity = { translateX: 0, translateY: 0, rotate: 0, skewX: 0, scaleX: 1, scaleY: 1 }; function decompose(a, b, c, d, e, f) { var scaleX, scaleY, skewX; if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; return { translateX: e, translateY: f, rotate: Math.atan2(b, a) * degrees, skewX: Math.atan(skewX) * degrees, scaleX: scaleX, scaleY: scaleY }; } var cssNode, cssRoot, cssView, svgNode; function parseCss(value) { if (value === "none") return identity; if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; cssNode.style.transform = value; value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); cssRoot.removeChild(cssNode); value = value.slice(7, -1).split(","); return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); } function parseSvg(value) { if (value == null) return identity; if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); svgNode.setAttribute("transform", value); if (!(value = svgNode.transform.baseVal.consolidate())) return identity; value = value.matrix; return decompose(value.a, value.b, value.c, value.d, value.e, value.f); } function interpolateTransform(parse, pxComma, pxParen, degParen) { function pop(s) { return s.length ? s.pop() + " " : ""; } function translate(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push("translate(", null, pxComma, null, pxParen); q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); } else if (xb || yb) { s.push("translate(" + xb + pxComma + yb + pxParen); } } function rotate(a, b, s, q) { if (a !== b) { if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)}); } else if (b) { s.push(pop(s) + "rotate(" + b + degParen); } } function skewX(a, b, s, q) { if (a !== b) { q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)}); } else if (b) { s.push(pop(s) + "skewX(" + b + degParen); } } function scale(xa, ya, xb, yb, s, q) { if (xa !== xb || ya !== yb) { var i = s.push(pop(s) + "scale(", null, ",", null, ")"); q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); } else if (xb !== 1 || yb !== 1) { s.push(pop(s) + "scale(" + xb + "," + yb + ")"); } } return function(a, b) { var s = [], // string constants and placeholders q = []; // number interpolators a = parse(a), b = parse(b); translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); rotate(a.rotate, b.rotate, s, q); skewX(a.skewX, b.skewX, s, q); scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); a = b = null; // gc return function(t) { var i = -1, n = q.length, o; while (++i < n) s[(o = q[i]).i] = o.x(t); return s.join(""); }; }; } var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); var rho = Math.SQRT2, rho2 = 2, rho4 = 4, epsilon2 = 1e-12; function cosh(x) { return ((x = Math.exp(x)) + 1 / x) / 2; } function sinh(x) { return ((x = Math.exp(x)) - 1 / x) / 2; } function tanh(x) { return ((x = Math.exp(2 * x)) - 1) / (x + 1); } // p0 = [ux0, uy0, w0] // p1 = [ux1, uy1, w1] function zoom(p0, p1) { var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S; // Special case for u0 ≅ u1. if (d2 < epsilon2) { S = Math.log(w1 / w0) / rho; i = function(t) { return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(rho * t * S) ]; }; } // General case. else { var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); S = (r1 - r0) / rho; i = function(t) { var s = t * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / cosh(rho * s + r0) ]; }; } i.duration = S * 1000; return i; } function hsl(hue) { return function(start, end) { var h = hue((start = d3Color.hsl(start)).h, (end = d3Color.hsl(end)).h), s = nogamma(start.s, end.s), l = nogamma(start.l, end.l), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.h = h(t); start.s = s(t); start.l = l(t); start.opacity = opacity(t); return start + ""; }; } } var hsl$1 = hsl(hue); var hslLong = hsl(nogamma); function lab(start, end) { var l = nogamma((start = d3Color.lab(start)).l, (end = d3Color.lab(end)).l), a = nogamma(start.a, end.a), b = nogamma(start.b, end.b), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.l = l(t); start.a = a(t); start.b = b(t); start.opacity = opacity(t); return start + ""; }; } function hcl(hue) { return function(start, end) { var h = hue((start = d3Color.hcl(start)).h, (end = d3Color.hcl(end)).h), c = nogamma(start.c, end.c), l = nogamma(start.l, end.l), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.h = h(t); start.c = c(t); start.l = l(t); start.opacity = opacity(t); return start + ""; }; } } var hcl$1 = hcl(hue); var hclLong = hcl(nogamma); function cubehelix(hue) { return (function cubehelixGamma(y) { y = +y; function cubehelix(start, end) { var h = hue((start = d3Color.cubehelix(start)).h, (end = d3Color.cubehelix(end)).h), s = nogamma(start.s, end.s), l = nogamma(start.l, end.l), opacity = nogamma(start.opacity, end.opacity); return function(t) { start.h = h(t); start.s = s(t); start.l = l(Math.pow(t, y)); start.opacity = opacity(t); return start + ""; }; } cubehelix.gamma = cubehelixGamma; return cubehelix; })(1); } var cubehelix$1 = cubehelix(hue); var cubehelixLong = cubehelix(nogamma); function piecewise(interpolate, values) { var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n); while (i < n) I[i] = interpolate(v, v = values[++i]); return function(t) { var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n))); return I[i](t - i); }; } function quantize(interpolator, n) { var samples = new Array(n); for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); return samples; } exports.interpolate = value; exports.interpolateArray = array; exports.interpolateBasis = basis$1; exports.interpolateBasisClosed = basisClosed; exports.interpolateCubehelix = cubehelix$1; exports.interpolateCubehelixLong = cubehelixLong; exports.interpolateDate = date; exports.interpolateDiscrete = discrete; exports.interpolateHcl = hcl$1; exports.interpolateHclLong = hclLong; exports.interpolateHsl = hsl$1; exports.interpolateHslLong = hslLong; exports.interpolateHue = hue$1; exports.interpolateLab = lab; exports.interpolateNumber = number; exports.interpolateNumberArray = numberArray; exports.interpolateObject = object; exports.interpolateRgb = rgb; exports.interpolateRgbBasis = rgbBasis; exports.interpolateRgbBasisClosed = rgbBasisClosed; exports.interpolateRound = round; exports.interpolateString = string; exports.interpolateTransformCss = interpolateTransformCss; exports.interpolateTransformSvg = interpolateTransformSvg; exports.interpolateZoom = zoom; exports.piecewise = piecewise; exports.quantize = quantize; Object.defineProperty(exports, '__esModule', { value: true }); })); },{"d3-color":875}],878:[function(require,module,exports){ // https://github.com/HarryStevens/d3-regression#readme Version 1.3.5. Copyright 2020 Harry Stevens. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.d3 = global.d3 || {})); }(this, function (exports) { 'use strict'; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } // Adapted from vega-statistics by Jeffrey Heer // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE // Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js function points(data, x, y, sort) { data = data.filter(function (d) { var u = x(d), v = y(d); return u != null && isFinite(u) && v != null && isFinite(v); }); if (sort) { data.sort(function (a, b) { return x(a) - x(b); }); } var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); // extract values, calculate means var ux = 0, uy = 0, xv, yv, d; for (var i = 0; i < n;) { d = data[i]; X[i] = xv = +x(d); Y[i] = yv = +y(d); ++i; ux += (xv - ux) / i; uy += (yv - uy) / i; } // mean center the data for (var _i = 0; _i < n; ++_i) { X[_i] -= ux; Y[_i] -= uy; } return [X, Y, ux, uy]; } function visitPoints(data, x, y, cb) { var iterations = 0; for (var i = 0, n = data.length; i < n; i++) { var d = data[i], dx = +x(d), dy = +y(d); if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { cb(dx, dy, iterations++); } } } // return the coefficient of determination, or R squared. function determination(data, x, y, uY, predict) { var SSE = 0, SST = 0; visitPoints(data, x, y, function (dx, dy) { var sse = dy - predict(dx), sst = dy - uY; SSE += sse * sse; SST += sst * sst; }); return 1 - SSE / SST; } // Returns the angle of a line in degrees. function angle(line) { return Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * 180 / Math.PI; } // Returns the midpoint of a line. function midpoint(line) { return [(line[0][0] + line[1][0]) / 2, (line[0][1] + line[1][1]) / 2]; } // returns a smooth line. function interpose(xmin, xmax, predict) { var l = Math.log(xmax - xmin) * Math.LOG10E + 1 | 0; var precision = 1 * Math.pow(10, -l / 2 - 1), maxIter = 1e4; var points = [px(xmin), px(xmax)], iter = 0; while (find(points) && iter < maxIter) { } return points; function px(x) { return [x, predict(x)]; } function find(points) { iter++; var n = points.length; var found = false; for (var i = 0; i < n - 1; i++) { var p0 = points[i], p1 = points[i + 1], m = midpoint([p0, p1]), mp = px(m[0]), a0 = angle([p0, m]), a1 = angle([p0, mp]), a = Math.abs(a0 - a1); if (a > precision) { points.splice(i + 1, 0, mp); found = true; } } return found; } } // Ordinary Least Squares from vega-statistics by Jeffrey Heer // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE // Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js function ols(uX, uY, uXY, uX2) { var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; return [intercept, slope]; } function exponential () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, domain; function exponential(data) { var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { var ly = Math.log(dy), xy = dx * dy; ++n; Y += (dy - Y) / n; XY += (xy - XY) / n; X2Y += (dx * xy - X2Y) / n; YL += (dy * ly - YL) / n; XYL += (xy * ly - XYL) / n; if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); var _ols = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), _ols2 = _slicedToArray(_ols, 2), a = _ols2[0], b = _ols2[1]; a = Math.exp(a); var fn = function fn(x) { return a * Math.exp(b * x); }, out = interpose(xmin, xmax, fn); out.a = a; out.b = b; out.predict = fn; out.rSquared = determination(data, x, y, Y, fn); return out; } exponential.domain = function (arr) { return arguments.length ? (domain = arr, exponential) : domain; }; exponential.x = function (fn) { return arguments.length ? (x = fn, exponential) : x; }; exponential.y = function (fn) { return arguments.length ? (y = fn, exponential) : y; }; return exponential; } function linear () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, domain; function linear(data) { var n = 0, X = 0, // sum of x Y = 0, // sum of y XY = 0, // sum of x * y X2 = 0, // sum of x * x xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { ++n; X += (dx - X) / n; Y += (dy - Y) / n; XY += (dx * dy - XY) / n; X2 += (dx * dx - X2) / n; if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); var _ols = ols(X, Y, XY, X2), _ols2 = _slicedToArray(_ols, 2), intercept = _ols2[0], slope = _ols2[1], fn = function fn(x) { return slope * x + intercept; }, out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; out.a = slope; out.b = intercept; out.predict = fn; out.rSquared = determination(data, x, y, Y, fn); return out; } linear.domain = function (arr) { return arguments.length ? (domain = arr, linear) : domain; }; linear.x = function (fn) { return arguments.length ? (x = fn, linear) : x; }; linear.y = function (fn) { return arguments.length ? (y = fn, linear) : y; }; return linear; } // Returns the medium value of an array of numbers. function median(arr) { arr.sort(function (a, b) { return a - b; }); var i = arr.length / 2; return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } var maxiters = 2, epsilon = 1e-12; function loess () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, bandwidth = .3; function loess(data) { var _points = points(data, x, y, true), _points2 = _slicedToArray(_points, 4), xv = _points2[0], yv = _points2[1], ux = _points2[2], uy = _points2[3], n = xv.length, bw = Math.max(2, ~~(bandwidth * n)), yhat = new Float64Array(n), residuals = new Float64Array(n), robustWeights = new Float64Array(n).fill(1); for (var iter = -1; ++iter <= maxiters;) { var interval = [0, bw - 1]; for (var i = 0; i < n; ++i) { var dx = xv[i], i0 = interval[0], i1 = interval[1], edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; var W = 0, X = 0, Y = 0, XY = 0, X2 = 0, denom = 1 / Math.abs(xv[edge] - dx || 1); // Avoid singularity for (var k = i0; k <= i1; ++k) { var xk = xv[k], yk = yv[k], w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], xkw = xk * w; W += w; X += xkw; Y += yk * w; XY += yk * xkw; X2 += xk * xkw; } // Linear regression fit var _ols = ols(X / W, Y / W, XY / W, X2 / W), _ols2 = _slicedToArray(_ols, 2), a = _ols2[0], b = _ols2[1]; yhat[i] = a + b * dx; residuals[i] = Math.abs(yv[i] - yhat[i]); updateInterval(xv, i + 1, interval); } if (iter === maxiters) { break; } var medianResidual = median(residuals); if (Math.abs(medianResidual) < epsilon) break; for (var _i = 0, arg, _w; _i < n; ++_i) { arg = residuals[_i] / (6 * medianResidual); // Default to epsilon (rather than zero) for large deviations // Keeping weights tiny but non-zero prevents singularites robustWeights[_i] = arg >= 1 ? epsilon : (_w = 1 - arg * arg) * _w; } } return output(xv, yhat, ux, uy); } loess.bandwidth = function (bw) { return arguments.length ? (bandwidth = bw, loess) : bandwidth; }; loess.x = function (fn) { return arguments.length ? (x = fn, loess) : x; }; loess.y = function (fn) { return arguments.length ? (y = fn, loess) : y; }; return loess; } // Weighting kernel for local regression function tricube(x) { return (x = 1 - x * x * x) * x * x; } // Advance sliding window interval of nearest neighbors function updateInterval(xv, i, interval) { var val = xv[i], left = interval[0], right = interval[1] + 1; if (right >= xv.length) return; // Step right if distance to new right edge is <= distance to old left edge // Step when distance is equal to ensure movement over duplicate x values while (i > left && xv[right] - val <= val - xv[left]) { interval[0] = ++left; interval[1] = right; ++right; } } // Generate smoothed output points // Average points with repeated x values function output(xv, yhat, ux, uy) { var n = xv.length, out = []; var i = 0, cnt = 0, prev = [], v; for (; i < n; ++i) { v = xv[i] + ux; if (prev[0] === v) { // Average output values via online update prev[1] += (yhat[i] - prev[1]) / ++cnt; } else { // Add new output point cnt = 0; prev[1] += uy; prev = [v, yhat[i]]; out.push(prev); } } prev[1] += uy; return out; } function logarithmic () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, domain; function logarithmic(data) { var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { var lx = Math.log(dx); ++n; X += (lx - X) / n; Y += (dy - Y) / n; XY += (lx * dy - XY) / n; X2 += (lx * lx - X2) / n; if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); var _ols = ols(X, Y, XY, X2), _ols2 = _slicedToArray(_ols, 2), intercept = _ols2[0], slope = _ols2[1], fn = function fn(x) { return slope * Math.log(x) + intercept; }, out = interpose(xmin, xmax, fn); out.a = slope; out.b = intercept; out.predict = fn; out.rSquared = determination(data, x, y, Y, fn); return out; } logarithmic.domain = function (arr) { return arguments.length ? (domain = arr, logarithmic) : domain; }; logarithmic.x = function (fn) { return arguments.length ? (x = fn, logarithmic) : x; }; logarithmic.y = function (fn) { return arguments.length ? (y = fn, logarithmic) : y; }; return logarithmic; } function quad () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, domain; function quadratic(data) { var _points = points(data, x, y), _points2 = _slicedToArray(_points, 4), xv = _points2[0], yv = _points2[1], ux = _points2[2], uy = _points2[3], n = xv.length; var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; for (i = 0; i < n;) { dx = xv[i]; dy = yv[i++]; x2 = dx * dx; X2 += (x2 - X2) / i; X3 += (x2 * dx - X3) / i; X4 += (x2 * x2 - X4) / i; XY += (dx * dy - XY) / i; X2Y += (x2 * dy - X2Y) / i; } var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { n0++; Y += (dy - Y) / n0; if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); var X2X2 = X4 - X2 * X2, d = X2 * X2X2 - X3 * X3, a = (X2Y * X2 - XY * X3) / d, b = (XY * X2X2 - X2Y * X3) / d, c = -a * X2, fn = function fn(x) { x = x - ux; return a * x * x + b * x + c + uy; }; var out = interpose(xmin, xmax, fn); out.a = a; out.b = b - 2 * a * ux; out.c = c - b * ux + a * ux * ux + uy; out.predict = fn; out.rSquared = determination(data, x, y, Y, fn); return out; } quadratic.domain = function (arr) { return arguments.length ? (domain = arr, quadratic) : domain; }; quadratic.x = function (fn) { return arguments.length ? (x = fn, quadratic) : x; }; quadratic.y = function (fn) { return arguments.length ? (y = fn, quadratic) : y; }; return quadratic; } // Source: https://github.com/Tom-Alexander/regression-js/blob/master/src/regression.js#L246 // License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE // ...with ideas from vega-statistics by Jeffrey Heer // Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE function polynomial () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, order = 3, domain; function polynomial(data) { // Use more efficient methods for lower orders if (order === 1) { var o = linear().x(x).y(y).domain(domain)(data); o.coefficients = [o.b, o.a]; delete o.a; delete o.b; return o; } if (order === 2) { var _o = quad().x(x).y(y).domain(domain)(data); _o.coefficients = [_o.c, _o.b, _o.a]; delete _o.a; delete _o.b; delete _o.c; return _o; } var _points = points(data, x, y), _points2 = _slicedToArray(_points, 4), xv = _points2[0], yv = _points2[1], ux = _points2[2], uy = _points2[3], n = xv.length, lhs = [], rhs = [], k = order + 1; var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { ++n0; Y += (dy - Y) / n0; if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); var i, j, l, v, c; for (i = 0; i < k; ++i) { for (l = 0, v = 0; l < n; ++l) { v += Math.pow(xv[l], i) * yv[l]; } lhs.push(v); c = new Float64Array(k); for (j = 0; j < k; ++j) { for (l = 0, v = 0; l < n; ++l) { v += Math.pow(xv[l], i + j); } c[j] = v; } rhs.push(c); } rhs.push(lhs); var coef = gaussianElimination(rhs), fn = function fn(x) { x -= ux; var y = uy + coef[0] + coef[1] * x + coef[2] * x * x; for (i = 3; i < k; ++i) { y += coef[i] * Math.pow(x, i); } return y; }, out = interpose(xmin, xmax, fn); out.coefficients = uncenter(k, coef, -ux, uy); out.predict = fn; out.rSquared = determination(data, x, y, Y, fn); return out; } polynomial.domain = function (arr) { return arguments.length ? (domain = arr, polynomial) : domain; }; polynomial.x = function (fn) { return arguments.length ? (x = fn, polynomial) : x; }; polynomial.y = function (fn) { return arguments.length ? (y = fn, polynomial) : y; }; polynomial.order = function (n) { return arguments.length ? (order = n, polynomial) : order; }; return polynomial; } function uncenter(k, a, x, y) { var z = Array(k); var i, j, v, c; // initialize to zero for (i = 0; i < k; ++i) { z[i] = 0; } // polynomial expansion for (i = k - 1; i >= 0; --i) { v = a[i]; c = 1; z[i] += v; for (j = 1; j <= i; ++j) { c *= (i + 1 - j) / j; // binomial coefficent z[i - j] += v * Math.pow(x, j) * c; } } // bias term z[0] += y; return z; } // Given an array for a two-dimensional matrix and the polynomial order, // solve A * x = b using Gaussian elimination. function gaussianElimination(matrix) { var n = matrix.length - 1, coef = []; var i, j, k, r, t; for (i = 0; i < n; ++i) { r = i; // max row for (j = i + 1; j < n; ++j) { if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { r = j; } } for (k = i; k < n + 1; ++k) { t = matrix[k][i]; matrix[k][i] = matrix[k][r]; matrix[k][r] = t; } for (j = i + 1; j < n; ++j) { for (k = n; k >= i; k--) { matrix[k][j] -= matrix[k][i] * matrix[i][j] / matrix[i][i]; } } } for (j = n - 1; j >= 0; --j) { t = 0; for (k = j + 1; k < n; ++k) { t += matrix[k][j] * coef[k]; } coef[j] = (matrix[n][j] - t) / matrix[j][j]; } return coef; } function power () { var x = function x(d) { return d[0]; }, y = function y(d) { return d[1]; }, domain; function power(data) { var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { var lx = Math.log(dx), ly = Math.log(dy); ++n; X += (lx - X) / n; Y += (ly - Y) / n; XY += (lx * ly - XY) / n; X2 += (lx * lx - X2) / n; YS += (dy - YS) / n; if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); var _ols = ols(X, Y, XY, X2), _ols2 = _slicedToArray(_ols, 2), a = _ols2[0], b = _ols2[1]; a = Math.exp(a); var fn = function fn(x) { return a * Math.pow(x, b); }, out = interpose(xmin, xmax, fn); out.a = a; out.b = b; out.predict = fn; out.rSquared = determination(data, x, y, YS, fn); return out; } power.domain = function (arr) { return arguments.length ? (domain = arr, power) : domain; }; power.x = function (fn) { return arguments.length ? (x = fn, power) : x; }; power.y = function (fn) { return arguments.length ? (y = fn, power) : y; }; return power; } exports.regressionExp = exponential; exports.regressionLinear = linear; exports.regressionLoess = loess; exports.regressionLog = logarithmic; exports.regressionPoly = polynomial; exports.regressionPow = power; exports.regressionQuad = quad; Object.defineProperty(exports, '__esModule', { value: true }); })); },{}],879:[function(require,module,exports){ // https://d3js.org/d3-timer/ v1.0.10 Copyright 2019 Mike Bostock (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.d3 = global.d3 || {})); }(this, function (exports) { 'use strict'; var frame = 0, // is an animation frame pending? timeout = 0, // is a timeout pending? interval = 0, // are any timers active? pokeDelay = 1000, // how frequently we check for clock skew taskHead, taskTail, clockLast = 0, clockNow = 0, clockSkew = 0, clock = typeof performance === "object" && performance.now ? performance : Date, setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; function now() { return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); } function clearNow() { clockNow = 0; } function Timer() { this._call = this._time = this._next = null; } Timer.prototype = timer.prototype = { constructor: Timer, restart: function(callback, delay, time) { if (typeof callback !== "function") throw new TypeError("callback is not a function"); time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); if (!this._next && taskTail !== this) { if (taskTail) taskTail._next = this; else taskHead = this; taskTail = this; } this._call = callback; this._time = time; sleep(); }, stop: function() { if (this._call) { this._call = null; this._time = Infinity; sleep(); } } }; function timer(callback, delay, time) { var t = new Timer; t.restart(callback, delay, time); return t; } function timerFlush() { now(); // Get the current time, if not already set. ++frame; // Pretend we’ve set an alarm, if we haven’t already. var t = taskHead, e; while (t) { if ((e = clockNow - t._time) >= 0) t._call.call(null, e); t = t._next; } --frame; } function wake() { clockNow = (clockLast = clock.now()) + clockSkew; frame = timeout = 0; try { timerFlush(); } finally { frame = 0; nap(); clockNow = 0; } } function poke() { var now = clock.now(), delay = now - clockLast; if (delay > pokeDelay) clockSkew -= delay, clockLast = now; } function nap() { var t0, t1 = taskHead, t2, time = Infinity; while (t1) { if (t1._call) { if (time > t1._time) time = t1._time; t0 = t1, t1 = t1._next; } else { t2 = t1._next, t1._next = null; t1 = t0 ? t0._next = t2 : taskHead = t2; } } taskTail = t0; sleep(time); } function sleep(time) { if (frame) return; // Soonest alarm already set, or will be. if (timeout) timeout = clearTimeout(timeout); var delay = time - clockNow; // Strictly less than if we recomputed clockNow. if (delay > 24) { if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); if (interval) interval = clearInterval(interval); } else { if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); frame = 1, setFrame(wake); } } function timeout$1(callback, delay, time) { var t = new Timer; delay = delay == null ? 0 : +delay; t.restart(function(elapsed) { t.stop(); callback(elapsed + delay); }, delay, time); return t; } function interval$1(callback, delay, time) { var t = new Timer, total = delay; if (delay == null) return t.restart(callback, delay, time), t; delay = +delay, time = time == null ? now() : +time; t.restart(function tick(elapsed) { elapsed += total; t.restart(tick, total += delay, time); callback(elapsed); }, delay, time); return t; } exports.interval = interval$1; exports.now = now; exports.timeout = timeout$1; exports.timer = timer; exports.timerFlush = timerFlush; Object.defineProperty(exports, '__esModule', { value: true }); })); },{}],880:[function(require,module,exports){ (function (process){ "use strict"; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); var BrowserInfo = /** @class */ (function () { function BrowserInfo(name, version, os) { this.name = name; this.version = version; this.os = os; this.type = 'browser'; } return BrowserInfo; }()); exports.BrowserInfo = BrowserInfo; var NodeInfo = /** @class */ (function () { function NodeInfo(version) { this.version = version; this.type = 'node'; this.name = 'node'; this.os = process.platform; } return NodeInfo; }()); exports.NodeInfo = NodeInfo; var SearchBotDeviceInfo = /** @class */ (function () { function SearchBotDeviceInfo(name, version, os, bot) { this.name = name; this.version = version; this.os = os; this.bot = bot; this.type = 'bot-device'; } return SearchBotDeviceInfo; }()); exports.SearchBotDeviceInfo = SearchBotDeviceInfo; var BotInfo = /** @class */ (function () { function BotInfo() { this.type = 'bot'; this.bot = true; // NOTE: deprecated test name instead this.name = 'bot'; this.version = null; this.os = null; } return BotInfo; }()); exports.BotInfo = BotInfo; var ReactNativeInfo = /** @class */ (function () { function ReactNativeInfo() { this.type = 'react-native'; this.name = 'react-native'; this.version = null; this.os = null; } return ReactNativeInfo; }()); exports.ReactNativeInfo = ReactNativeInfo; // tslint:disable-next-line:max-line-length var SEARCHBOX_UA_REGEX = /alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/; var SEARCHBOT_OS_REGEX = /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask\ Jeeves\/Teoma|ia_archiver)/; var REQUIRED_VERSION_PARTS = 3; var userAgentRules = [ ['aol', /AOLShield\/([0-9\._]+)/], ['edge', /Edge\/([0-9\._]+)/], ['edge-ios', /EdgiOS\/([0-9\._]+)/], ['yandexbrowser', /YaBrowser\/([0-9\._]+)/], ['kakaotalk', /KAKAOTALK\s([0-9\.]+)/], ['samsung', /SamsungBrowser\/([0-9\.]+)/], ['silk', /\bSilk\/([0-9._-]+)\b/], ['miui', /MiuiBrowser\/([0-9\.]+)$/], ['beaker', /BeakerBrowser\/([0-9\.]+)/], ['edge-chromium', /Edg\/([0-9\.]+)/], [ 'chromium-webview', /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/, ], ['chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/], ['phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/], ['crios', /CriOS\/([0-9\.]+)(:?\s|$)/], ['firefox', /Firefox\/([0-9\.]+)(?:\s|$)/], ['fxios', /FxiOS\/([0-9\.]+)/], ['opera-mini', /Opera Mini.*Version\/([0-9\.]+)/], ['opera', /Opera\/([0-9\.]+)(?:\s|$)/], ['opera', /OPR\/([0-9\.]+)(:?\s|$)/], ['ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/], ['ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/], ['ie', /MSIE\s(7\.0)/], ['bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/], ['android', /Android\s([0-9\.]+)/], ['ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/], ['safari', /Version\/([0-9\._]+).*Safari/], ['facebook', /FBAV\/([0-9\.]+)/], ['instagram', /Instagram\s([0-9\.]+)/], ['ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/], ['ios-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/], ['searchbot', SEARCHBOX_UA_REGEX], ]; var operatingSystemRules = [ ['iOS', /iP(hone|od|ad)/], ['Android OS', /Android/], ['BlackBerry OS', /BlackBerry|BB10/], ['Windows Mobile', /IEMobile/], ['Amazon OS', /Kindle/], ['Windows 3.11', /Win16/], ['Windows 95', /(Windows 95)|(Win95)|(Windows_95)/], ['Windows 98', /(Windows 98)|(Win98)/], ['Windows 2000', /(Windows NT 5.0)|(Windows 2000)/], ['Windows XP', /(Windows NT 5.1)|(Windows XP)/], ['Windows Server 2003', /(Windows NT 5.2)/], ['Windows Vista', /(Windows NT 6.0)/], ['Windows 7', /(Windows NT 6.1)/], ['Windows 8', /(Windows NT 6.2)/], ['Windows 8.1', /(Windows NT 6.3)/], ['Windows 10', /(Windows NT 10.0)/], ['Windows ME', /Windows ME/], ['Open BSD', /OpenBSD/], ['Sun OS', /SunOS/], ['Chrome OS', /CrOS/], ['Linux', /(Linux)|(X11)/], ['Mac OS', /(Mac_PowerPC)|(Macintosh)/], ['QNX', /QNX/], ['BeOS', /BeOS/], ['OS/2', /OS\/2/], ]; function detect(userAgent) { if (!!userAgent) { return parseUserAgent(userAgent); } if (typeof document === 'undefined' && typeof navigator !== 'undefined' && navigator.product === 'ReactNative') { return new ReactNativeInfo(); } if (typeof navigator !== 'undefined') { return parseUserAgent(navigator.userAgent); } return getNodeVersion(); } exports.detect = detect; function matchUserAgent(ua) { // opted for using reduce here rather than Array#first with a regex.test call // this is primarily because using the reduce we only perform the regex // execution once rather than once for the test and for the exec again below // probably something that needs to be benchmarked though return (ua !== '' && userAgentRules.reduce(function (matched, _a) { var browser = _a[0], regex = _a[1]; if (matched) { return matched; } var uaMatch = regex.exec(ua); return !!uaMatch && [browser, uaMatch]; }, false)); } function browserName(ua) { var data = matchUserAgent(ua); return data ? data[0] : null; } exports.browserName = browserName; function parseUserAgent(ua) { var matchedRule = matchUserAgent(ua); if (!matchedRule) { return null; } var name = matchedRule[0], match = matchedRule[1]; if (name === 'searchbot') { return new BotInfo(); } var versionParts = match[1] && match[1].split(/[._]/).slice(0, 3); if (versionParts) { if (versionParts.length < REQUIRED_VERSION_PARTS) { versionParts = __spreadArrays(versionParts, createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length)); } } else { versionParts = []; } var version = versionParts.join('.'); var os = detectOS(ua); var searchBotMatch = SEARCHBOT_OS_REGEX.exec(ua); if (searchBotMatch && searchBotMatch[1]) { return new SearchBotDeviceInfo(name, version, os, searchBotMatch[1]); } return new BrowserInfo(name, version, os); } exports.parseUserAgent = parseUserAgent; function detectOS(ua) { for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) { var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1]; var match = regex.exec(ua); if (match) { return os; } } return null; } exports.detectOS = detectOS; function getNodeVersion() { var isNode = typeof process !== 'undefined' && process.version; return isNode ? new NodeInfo(process.version.slice(1)) : null; } exports.getNodeVersion = getNodeVersion; function createVersionParts(count) { var output = []; for (var ii = 0; ii < count; ii++) { output.push('0'); } return output; } }).call(this,require('_process')) },{"_process":1}],881:[function(require,module,exports){ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.fecha = {}))); }(this, (function (exports) { 'use strict'; var token = /d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|Z|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g; var twoDigitsOptional = "[1-9]\\d?"; var twoDigits = "\\d\\d"; var threeDigits = "\\d{3}"; var fourDigits = "\\d{4}"; var word = "[^\\s]+"; var literal = /\[([^]*?)\]/gm; function shorten(arr, sLen) { var newArr = []; for (var i = 0, len = arr.length; i < len; i++) { newArr.push(arr[i].substr(0, sLen)); } return newArr; } var monthUpdate = function (arrName) { return function (v, i18n) { var lowerCaseArr = i18n[arrName].map(function (v) { return v.toLowerCase(); }); var index = lowerCaseArr.indexOf(v.toLowerCase()); if (index > -1) { return index; } return null; }; }; function assign(origObj) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } for (var _a = 0, args_1 = args; _a < args_1.length; _a++) { var obj = args_1[_a]; for (var key in obj) { // @ts-ignore ex origObj[key] = obj[key]; } } return origObj; } var dayNames = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var monthNamesShort = shorten(monthNames, 3); var dayNamesShort = shorten(dayNames, 3); var defaultI18n = { dayNamesShort: dayNamesShort, dayNames: dayNames, monthNamesShort: monthNamesShort, monthNames: monthNames, amPm: ["am", "pm"], DoFn: function (dayOfMonth) { return (dayOfMonth + ["th", "st", "nd", "rd"][dayOfMonth % 10 > 3 ? 0 : ((dayOfMonth - (dayOfMonth % 10) !== 10 ? 1 : 0) * dayOfMonth) % 10]); } }; var globalI18n = assign({}, defaultI18n); var setGlobalDateI18n = function (i18n) { return (globalI18n = assign(globalI18n, i18n)); }; var regexEscape = function (str) { return str.replace(/[|\\{()[^$+*?.-]/g, "\\$&"); }; var pad = function (val, len) { if (len === void 0) { len = 2; } val = String(val); while (val.length < len) { val = "0" + val; } return val; }; var formatFlags = { D: function (dateObj) { return String(dateObj.getDate()); }, DD: function (dateObj) { return pad(dateObj.getDate()); }, Do: function (dateObj, i18n) { return i18n.DoFn(dateObj.getDate()); }, d: function (dateObj) { return String(dateObj.getDay()); }, dd: function (dateObj) { return pad(dateObj.getDay()); }, ddd: function (dateObj, i18n) { return i18n.dayNamesShort[dateObj.getDay()]; }, dddd: function (dateObj, i18n) { return i18n.dayNames[dateObj.getDay()]; }, M: function (dateObj) { return String(dateObj.getMonth() + 1); }, MM: function (dateObj) { return pad(dateObj.getMonth() + 1); }, MMM: function (dateObj, i18n) { return i18n.monthNamesShort[dateObj.getMonth()]; }, MMMM: function (dateObj, i18n) { return i18n.monthNames[dateObj.getMonth()]; }, YY: function (dateObj) { return pad(String(dateObj.getFullYear()), 4).substr(2); }, YYYY: function (dateObj) { return pad(dateObj.getFullYear(), 4); }, h: function (dateObj) { return String(dateObj.getHours() % 12 || 12); }, hh: function (dateObj) { return pad(dateObj.getHours() % 12 || 12); }, H: function (dateObj) { return String(dateObj.getHours()); }, HH: function (dateObj) { return pad(dateObj.getHours()); }, m: function (dateObj) { return String(dateObj.getMinutes()); }, mm: function (dateObj) { return pad(dateObj.getMinutes()); }, s: function (dateObj) { return String(dateObj.getSeconds()); }, ss: function (dateObj) { return pad(dateObj.getSeconds()); }, S: function (dateObj) { return String(Math.round(dateObj.getMilliseconds() / 100)); }, SS: function (dateObj) { return pad(Math.round(dateObj.getMilliseconds() / 10), 2); }, SSS: function (dateObj) { return pad(dateObj.getMilliseconds(), 3); }, a: function (dateObj, i18n) { return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1]; }, A: function (dateObj, i18n) { return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase(); }, ZZ: function (dateObj) { var offset = dateObj.getTimezoneOffset(); return ((offset > 0 ? "-" : "+") + pad(Math.floor(Math.abs(offset) / 60) * 100 + (Math.abs(offset) % 60), 4)); }, Z: function (dateObj) { var offset = dateObj.getTimezoneOffset(); return ((offset > 0 ? "-" : "+") + pad(Math.floor(Math.abs(offset) / 60), 2) + ":" + pad(Math.abs(offset) % 60, 2)); } }; var monthParse = function (v) { return +v - 1; }; var emptyDigits = [null, twoDigitsOptional]; var emptyWord = [null, word]; var amPm = [ "isPm", word, function (v, i18n) { var val = v.toLowerCase(); if (val === i18n.amPm[0]) { return 0; } else if (val === i18n.amPm[1]) { return 1; } return null; } ]; var timezoneOffset = [ "timezoneOffset", "[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z?", function (v) { var parts = (v + "").match(/([+-]|\d\d)/gi); if (parts) { var minutes = +parts[1] * 60 + parseInt(parts[2], 10); return parts[0] === "+" ? minutes : -minutes; } return 0; } ]; var parseFlags = { D: ["day", twoDigitsOptional], DD: ["day", twoDigits], Do: ["day", twoDigitsOptional + word, function (v) { return parseInt(v, 10); }], M: ["month", twoDigitsOptional, monthParse], MM: ["month", twoDigits, monthParse], YY: [ "year", twoDigits, function (v) { var now = new Date(); var cent = +("" + now.getFullYear()).substr(0, 2); return +("" + (+v > 68 ? cent - 1 : cent) + v); } ], h: ["hour", twoDigitsOptional, undefined, "isPm"], hh: ["hour", twoDigits, undefined, "isPm"], H: ["hour", twoDigitsOptional], HH: ["hour", twoDigits], m: ["minute", twoDigitsOptional], mm: ["minute", twoDigits], s: ["second", twoDigitsOptional], ss: ["second", twoDigits], YYYY: ["year", fourDigits], S: ["millisecond", "\\d", function (v) { return +v * 100; }], SS: ["millisecond", twoDigits, function (v) { return +v * 10; }], SSS: ["millisecond", threeDigits], d: emptyDigits, dd: emptyDigits, ddd: emptyWord, dddd: emptyWord, MMM: ["month", word, monthUpdate("monthNamesShort")], MMMM: ["month", word, monthUpdate("monthNames")], a: amPm, A: amPm, ZZ: timezoneOffset, Z: timezoneOffset }; // Some common format strings var globalMasks = { default: "ddd MMM DD YYYY HH:mm:ss", shortDate: "M/D/YY", mediumDate: "MMM D, YYYY", longDate: "MMMM D, YYYY", fullDate: "dddd, MMMM D, YYYY", isoDate: "YYYY-MM-DD", isoDateTime: "YYYY-MM-DDTHH:mm:ssZ", shortTime: "HH:mm", mediumTime: "HH:mm:ss", longTime: "HH:mm:ss.SSS" }; var setGlobalDateMasks = function (masks) { return assign(globalMasks, masks); }; /*** * Format a date * @method format * @param {Date|number} dateObj * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate' * @returns {string} Formatted date string */ var format = function (dateObj, mask, i18n) { if (mask === void 0) { mask = globalMasks["default"]; } if (i18n === void 0) { i18n = {}; } if (typeof dateObj === "number") { dateObj = new Date(dateObj); } if (Object.prototype.toString.call(dateObj) !== "[object Date]" || isNaN(dateObj.getTime())) { throw new Error("Invalid Date pass to format"); } mask = globalMasks[mask] || mask; var literals = []; // Make literals inactive by replacing them with @@@ mask = mask.replace(literal, function ($0, $1) { literals.push($1); return "@@@"; }); var combinedI18nSettings = assign(assign({}, globalI18n), i18n); // Apply formatting rules mask = mask.replace(token, function ($0) { return formatFlags[$0](dateObj, combinedI18nSettings); }); // Inline literal values back into the formatted value return mask.replace(/@@@/g, function () { return literals.shift(); }); }; /** * Parse a date string into a Javascript Date object / * @method parse * @param {string} dateStr Date string * @param {string} format Date parse format * @param {i18n} I18nSettingsOptional Full or subset of I18N settings * @returns {Date|null} Returns Date object. Returns null what date string is invalid or doesn't match format */ function parse(dateStr, format, i18n) { if (i18n === void 0) { i18n = {}; } if (typeof format !== "string") { throw new Error("Invalid format in fecha parse"); } // Check to see if the format is actually a mask format = globalMasks[format] || format; // Avoid regular expression denial of service, fail early for really long strings // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS if (dateStr.length > 1000) { return null; } // Default to the beginning of the year. var today = new Date(); var dateInfo = { year: today.getFullYear(), month: 0, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0, isPm: null, timezoneOffset: null }; var parseInfo = []; var literals = []; // Replace all the literals with @@@. Hopefully a string that won't exist in the format var newFormat = format.replace(literal, function ($0, $1) { literals.push(regexEscape($1)); return "@@@"; }); var specifiedFields = {}; var requiredFields = {}; // Change every token that we find into the correct regex newFormat = regexEscape(newFormat).replace(token, function ($0) { var info = parseFlags[$0]; var field = info[0], regex = info[1], requiredField = info[3]; // Check if the person has specified the same field twice. This will lead to confusing results. if (specifiedFields[field]) { throw new Error("Invalid format. " + field + " specified twice in format"); } specifiedFields[field] = true; // Check if there are any required fields. For instance, 12 hour time requires AM/PM specified if (requiredField) { requiredFields[requiredField] = true; } parseInfo.push(info); return "(" + regex + ")"; }); // Check all the required fields are present Object.keys(requiredFields).forEach(function (field) { if (!specifiedFields[field]) { throw new Error("Invalid format. " + field + " is required in specified format"); } }); // Add back all the literals after newFormat = newFormat.replace(/@@@/g, function () { return literals.shift(); }); // Check if the date string matches the format. If it doesn't return null var matches = dateStr.match(new RegExp(newFormat, "i")); if (!matches) { return null; } var combinedI18nSettings = assign(assign({}, globalI18n), i18n); // For each match, call the parser function for that date part for (var i = 1; i < matches.length; i++) { var _a = parseInfo[i - 1], field = _a[0], parser = _a[2]; var value = parser ? parser(matches[i], combinedI18nSettings) : +matches[i]; // If the parser can't make sense of the value, return null if (value == null) { return null; } dateInfo[field] = value; } if (dateInfo.isPm === 1 && dateInfo.hour != null && +dateInfo.hour !== 12) { dateInfo.hour = +dateInfo.hour + 12; } else if (dateInfo.isPm === 0 && +dateInfo.hour === 12) { dateInfo.hour = 0; } var dateWithoutTZ = new Date(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute, dateInfo.second, dateInfo.millisecond); var validateFields = [ ["month", "getMonth"], ["day", "getDate"], ["hour", "getHours"], ["minute", "getMinutes"], ["second", "getSeconds"] ]; for (var i = 0, len = validateFields.length; i < len; i++) { // Check to make sure the date field is within the allowed range. Javascript dates allows values // outside the allowed range. If the values don't match the value was invalid if (specifiedFields[validateFields[i][0]] && dateInfo[validateFields[i][0]] !== dateWithoutTZ[validateFields[i][1]]()) { return null; } } if (dateInfo.timezoneOffset == null) { return dateWithoutTZ; } return new Date(Date.UTC(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute - dateInfo.timezoneOffset, dateInfo.second, dateInfo.millisecond)); } var fecha = { format: format, parse: parse, defaultI18n: defaultI18n, setGlobalDateI18n: setGlobalDateI18n, setGlobalDateMasks: setGlobalDateMasks }; exports.assign = assign; exports.default = fecha; exports.format = format; exports.parse = parse; exports.defaultI18n = defaultI18n; exports.setGlobalDateI18n = setGlobalDateI18n; exports.setGlobalDateMasks = setGlobalDateMasks; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],882:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setMatrixArrayType = setMatrixArrayType; exports.toRadian = toRadian; exports.equals = equals; exports.RANDOM = exports.ARRAY_TYPE = exports.EPSILON = void 0; /** * Common utilities * @module glMatrix */ // Configuration Constants var EPSILON = 0.000001; exports.EPSILON = EPSILON; var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; exports.ARRAY_TYPE = ARRAY_TYPE; var RANDOM = Math.random; /** * Sets the type of array used when creating new vectors and matrices * * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array */ exports.RANDOM = RANDOM; function setMatrixArrayType(type) { exports.ARRAY_TYPE = ARRAY_TYPE = type; } var degree = Math.PI / 180; /** * Convert Degree To Radian * * @param {Number} a Angle in Degrees */ function toRadian(a) { return a * degree; } /** * Tests whether or not the arguments have approximately the same value, within an absolute * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less * than or equal to 1.0, and a relative tolerance is used for larger values) * * @param {Number} a The first number to test. * @param {Number} b The second number to test. * @returns {Boolean} True if the numbers are approximately equal, false otherwise. */ function equals(a, b) { return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b)); } if (!Math.hypot) Math.hypot = function () { var y = 0, i = arguments.length; while (i--) { y += arguments[i] * arguments[i]; } return Math.sqrt(y); }; },{}],883:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.vec4 = exports.vec3 = exports.vec2 = exports.quat2 = exports.quat = exports.mat4 = exports.mat3 = exports.mat2d = exports.mat2 = exports.glMatrix = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); exports.glMatrix = glMatrix; var mat2 = _interopRequireWildcard(require("./mat2.js")); exports.mat2 = mat2; var mat2d = _interopRequireWildcard(require("./mat2d.js")); exports.mat2d = mat2d; var mat3 = _interopRequireWildcard(require("./mat3.js")); exports.mat3 = mat3; var mat4 = _interopRequireWildcard(require("./mat4.js")); exports.mat4 = mat4; var quat = _interopRequireWildcard(require("./quat.js")); exports.quat = quat; var quat2 = _interopRequireWildcard(require("./quat2.js")); exports.quat2 = quat2; var vec2 = _interopRequireWildcard(require("./vec2.js")); exports.vec2 = vec2; var vec3 = _interopRequireWildcard(require("./vec3.js")); exports.vec3 = vec3; var vec4 = _interopRequireWildcard(require("./vec4.js")); exports.vec4 = vec4; function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } },{"./common.js":882,"./mat2.js":884,"./mat2d.js":885,"./mat3.js":886,"./mat4.js":887,"./quat.js":888,"./quat2.js":889,"./vec2.js":890,"./vec3.js":891,"./vec4.js":892}],884:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.copy = copy; exports.identity = identity; exports.fromValues = fromValues; exports.set = set; exports.transpose = transpose; exports.invert = invert; exports.adjoint = adjoint; exports.determinant = determinant; exports.multiply = multiply; exports.rotate = rotate; exports.scale = scale; exports.fromRotation = fromRotation; exports.fromScaling = fromScaling; exports.str = str; exports.frob = frob; exports.LDU = LDU; exports.add = add; exports.subtract = subtract; exports.exactEquals = exactEquals; exports.equals = equals; exports.multiplyScalar = multiplyScalar; exports.multiplyScalarAndAdd = multiplyScalarAndAdd; exports.sub = exports.mul = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 2x2 Matrix * @module mat2 */ /** * Creates a new identity mat2 * * @returns {mat2} a new 2x2 matrix */ function create() { var out = new glMatrix.ARRAY_TYPE(4); if (glMatrix.ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; } out[0] = 1; out[3] = 1; return out; } /** * Creates a new mat2 initialized with values from an existing matrix * * @param {ReadonlyMat2} a matrix to clone * @returns {mat2} a new 2x2 matrix */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } /** * Copy the values from one mat2 to another * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } /** * Set a mat2 to the identity matrix * * @param {mat2} out the receiving matrix * @returns {mat2} out */ function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; return out; } /** * Create a new mat2 with the given values * * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m10 Component in column 1, row 0 position (index 2) * @param {Number} m11 Component in column 1, row 1 position (index 3) * @returns {mat2} out A new 2x2 matrix */ function fromValues(m00, m01, m10, m11) { var out = new glMatrix.ARRAY_TYPE(4); out[0] = m00; out[1] = m01; out[2] = m10; out[3] = m11; return out; } /** * Set the components of a mat2 to the given values * * @param {mat2} out the receiving matrix * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m10 Component in column 1, row 0 position (index 2) * @param {Number} m11 Component in column 1, row 1 position (index 3) * @returns {mat2} out */ function set(out, m00, m01, m10, m11) { out[0] = m00; out[1] = m01; out[2] = m10; out[3] = m11; return out; } /** * Transpose the values of a mat2 * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ function transpose(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache // some values if (out === a) { var a1 = a[1]; out[1] = a[2]; out[2] = a1; } else { out[0] = a[0]; out[1] = a[2]; out[2] = a[1]; out[3] = a[3]; } return out; } /** * Inverts a mat2 * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ function invert(out, a) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; // Calculate the determinant var det = a0 * a3 - a2 * a1; if (!det) { return null; } det = 1.0 / det; out[0] = a3 * det; out[1] = -a1 * det; out[2] = -a2 * det; out[3] = a0 * det; return out; } /** * Calculates the adjugate of a mat2 * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ function adjoint(out, a) { // Caching this value is nessecary if out == a var a0 = a[0]; out[0] = a[3]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a0; return out; } /** * Calculates the determinant of a mat2 * * @param {ReadonlyMat2} a the source matrix * @returns {Number} determinant of a */ function determinant(a) { return a[0] * a[3] - a[2] * a[1]; } /** * Multiplies two mat2's * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the first operand * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ function multiply(out, a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; out[0] = a0 * b0 + a2 * b1; out[1] = a1 * b0 + a3 * b1; out[2] = a0 * b2 + a2 * b3; out[3] = a1 * b2 + a3 * b3; return out; } /** * Rotates a mat2 by the given angle * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat2} out */ function rotate(out, a, rad) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var s = Math.sin(rad); var c = Math.cos(rad); out[0] = a0 * c + a2 * s; out[1] = a1 * c + a3 * s; out[2] = a0 * -s + a2 * c; out[3] = a1 * -s + a3 * c; return out; } /** * Scales the mat2 by the dimensions in the given vec2 * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the matrix to rotate * @param {ReadonlyVec2} v the vec2 to scale the matrix by * @returns {mat2} out **/ function scale(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var v0 = v[0], v1 = v[1]; out[0] = a0 * v0; out[1] = a1 * v0; out[2] = a2 * v1; out[3] = a3 * v1; return out; } /** * Creates a matrix from a given angle * This is equivalent to (but much faster than): * * mat2.identity(dest); * mat2.rotate(dest, dest, rad); * * @param {mat2} out mat2 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat2} out */ function fromRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); out[0] = c; out[1] = s; out[2] = -s; out[3] = c; return out; } /** * Creates a matrix from a vector scaling * This is equivalent to (but much faster than): * * mat2.identity(dest); * mat2.scale(dest, dest, vec); * * @param {mat2} out mat2 receiving operation result * @param {ReadonlyVec2} v Scaling vector * @returns {mat2} out */ function fromScaling(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; out[3] = v[1]; return out; } /** * Returns a string representation of a mat2 * * @param {ReadonlyMat2} a matrix to represent as a string * @returns {String} string representation of the matrix */ function str(a) { return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Returns Frobenius norm of a mat2 * * @param {ReadonlyMat2} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ function frob(a) { return Math.hypot(a[0], a[1], a[2], a[3]); } /** * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix * @param {ReadonlyMat2} L the lower triangular matrix * @param {ReadonlyMat2} D the diagonal matrix * @param {ReadonlyMat2} U the upper triangular matrix * @param {ReadonlyMat2} a the input matrix to factorize */ function LDU(L, D, U, a) { L[2] = a[2] / a[0]; U[0] = a[0]; U[1] = a[1]; U[3] = a[3] - L[2] * U[1]; return [L, D, U]; } /** * Adds two mat2's * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the first operand * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; return out; } /** * Subtracts matrix b from matrix a * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the first operand * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; return out; } /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyMat2} a The first matrix. * @param {ReadonlyMat2} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; } /** * Returns whether or not the matrices have approximately the same elements in the same position. * * @param {ReadonlyMat2} a The first matrix. * @param {ReadonlyMat2} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); } /** * Multiply each element of the matrix by a scalar. * * @param {mat2} out the receiving matrix * @param {ReadonlyMat2} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat2} out */ function multiplyScalar(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; return out; } /** * Adds two mat2's after multiplying each element of the second operand by a scalar value. * * @param {mat2} out the receiving vector * @param {ReadonlyMat2} a the first operand * @param {ReadonlyMat2} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat2} out */ function multiplyScalarAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; out[3] = a[3] + b[3] * scale; return out; } /** * Alias for {@link mat2.multiply} * @function */ var mul = multiply; /** * Alias for {@link mat2.subtract} * @function */ exports.mul = mul; var sub = subtract; exports.sub = sub; },{"./common.js":882}],885:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.copy = copy; exports.identity = identity; exports.fromValues = fromValues; exports.set = set; exports.invert = invert; exports.determinant = determinant; exports.multiply = multiply; exports.rotate = rotate; exports.scale = scale; exports.translate = translate; exports.fromRotation = fromRotation; exports.fromScaling = fromScaling; exports.fromTranslation = fromTranslation; exports.str = str; exports.frob = frob; exports.add = add; exports.subtract = subtract; exports.multiplyScalar = multiplyScalar; exports.multiplyScalarAndAdd = multiplyScalarAndAdd; exports.exactEquals = exactEquals; exports.equals = equals; exports.sub = exports.mul = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 2x3 Matrix * @module mat2d * @description * A mat2d contains six elements defined as: *
       * [a, b,
       *  c, d,
       *  tx, ty]
       * 
      * This is a short form for the 3x3 matrix: *
       * [a, b, 0,
       *  c, d, 0,
       *  tx, ty, 1]
       * 
      * The last column is ignored so the array is shorter and operations are faster. */ /** * Creates a new identity mat2d * * @returns {mat2d} a new 2x3 matrix */ function create() { var out = new glMatrix.ARRAY_TYPE(6); if (glMatrix.ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[4] = 0; out[5] = 0; } out[0] = 1; out[3] = 1; return out; } /** * Creates a new mat2d initialized with values from an existing matrix * * @param {ReadonlyMat2d} a matrix to clone * @returns {mat2d} a new 2x3 matrix */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(6); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; return out; } /** * Copy the values from one mat2d to another * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the source matrix * @returns {mat2d} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; return out; } /** * Set a mat2d to the identity matrix * * @param {mat2d} out the receiving matrix * @returns {mat2d} out */ function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = 0; out[5] = 0; return out; } /** * Create a new mat2d with the given values * * @param {Number} a Component A (index 0) * @param {Number} b Component B (index 1) * @param {Number} c Component C (index 2) * @param {Number} d Component D (index 3) * @param {Number} tx Component TX (index 4) * @param {Number} ty Component TY (index 5) * @returns {mat2d} A new mat2d */ function fromValues(a, b, c, d, tx, ty) { var out = new glMatrix.ARRAY_TYPE(6); out[0] = a; out[1] = b; out[2] = c; out[3] = d; out[4] = tx; out[5] = ty; return out; } /** * Set the components of a mat2d to the given values * * @param {mat2d} out the receiving matrix * @param {Number} a Component A (index 0) * @param {Number} b Component B (index 1) * @param {Number} c Component C (index 2) * @param {Number} d Component D (index 3) * @param {Number} tx Component TX (index 4) * @param {Number} ty Component TY (index 5) * @returns {mat2d} out */ function set(out, a, b, c, d, tx, ty) { out[0] = a; out[1] = b; out[2] = c; out[3] = d; out[4] = tx; out[5] = ty; return out; } /** * Inverts a mat2d * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the source matrix * @returns {mat2d} out */ function invert(out, a) { var aa = a[0], ab = a[1], ac = a[2], ad = a[3]; var atx = a[4], aty = a[5]; var det = aa * ad - ab * ac; if (!det) { return null; } det = 1.0 / det; out[0] = ad * det; out[1] = -ab * det; out[2] = -ac * det; out[3] = aa * det; out[4] = (ac * aty - ad * atx) * det; out[5] = (ab * atx - aa * aty) * det; return out; } /** * Calculates the determinant of a mat2d * * @param {ReadonlyMat2d} a the source matrix * @returns {Number} determinant of a */ function determinant(a) { return a[0] * a[3] - a[1] * a[2]; } /** * Multiplies two mat2d's * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the first operand * @param {ReadonlyMat2d} b the second operand * @returns {mat2d} out */ function multiply(out, a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; out[0] = a0 * b0 + a2 * b1; out[1] = a1 * b0 + a3 * b1; out[2] = a0 * b2 + a2 * b3; out[3] = a1 * b2 + a3 * b3; out[4] = a0 * b4 + a2 * b5 + a4; out[5] = a1 * b4 + a3 * b5 + a5; return out; } /** * Rotates a mat2d by the given angle * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat2d} out */ function rotate(out, a, rad) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; var s = Math.sin(rad); var c = Math.cos(rad); out[0] = a0 * c + a2 * s; out[1] = a1 * c + a3 * s; out[2] = a0 * -s + a2 * c; out[3] = a1 * -s + a3 * c; out[4] = a4; out[5] = a5; return out; } /** * Scales the mat2d by the dimensions in the given vec2 * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the matrix to translate * @param {ReadonlyVec2} v the vec2 to scale the matrix by * @returns {mat2d} out **/ function scale(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; var v0 = v[0], v1 = v[1]; out[0] = a0 * v0; out[1] = a1 * v0; out[2] = a2 * v1; out[3] = a3 * v1; out[4] = a4; out[5] = a5; return out; } /** * Translates the mat2d by the dimensions in the given vec2 * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the matrix to translate * @param {ReadonlyVec2} v the vec2 to translate the matrix by * @returns {mat2d} out **/ function translate(out, a, v) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; var v0 = v[0], v1 = v[1]; out[0] = a0; out[1] = a1; out[2] = a2; out[3] = a3; out[4] = a0 * v0 + a2 * v1 + a4; out[5] = a1 * v0 + a3 * v1 + a5; return out; } /** * Creates a matrix from a given angle * This is equivalent to (but much faster than): * * mat2d.identity(dest); * mat2d.rotate(dest, dest, rad); * * @param {mat2d} out mat2d receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat2d} out */ function fromRotation(out, rad) { var s = Math.sin(rad), c = Math.cos(rad); out[0] = c; out[1] = s; out[2] = -s; out[3] = c; out[4] = 0; out[5] = 0; return out; } /** * Creates a matrix from a vector scaling * This is equivalent to (but much faster than): * * mat2d.identity(dest); * mat2d.scale(dest, dest, vec); * * @param {mat2d} out mat2d receiving operation result * @param {ReadonlyVec2} v Scaling vector * @returns {mat2d} out */ function fromScaling(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; out[3] = v[1]; out[4] = 0; out[5] = 0; return out; } /** * Creates a matrix from a vector translation * This is equivalent to (but much faster than): * * mat2d.identity(dest); * mat2d.translate(dest, dest, vec); * * @param {mat2d} out mat2d receiving operation result * @param {ReadonlyVec2} v Translation vector * @returns {mat2d} out */ function fromTranslation(out, v) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = v[0]; out[5] = v[1]; return out; } /** * Returns a string representation of a mat2d * * @param {ReadonlyMat2d} a matrix to represent as a string * @returns {String} string representation of the matrix */ function str(a) { return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")"; } /** * Returns Frobenius norm of a mat2d * * @param {ReadonlyMat2d} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ function frob(a) { return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1); } /** * Adds two mat2d's * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the first operand * @param {ReadonlyMat2d} b the second operand * @returns {mat2d} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; return out; } /** * Subtracts matrix b from matrix a * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the first operand * @param {ReadonlyMat2d} b the second operand * @returns {mat2d} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; out[4] = a[4] - b[4]; out[5] = a[5] - b[5]; return out; } /** * Multiply each element of the matrix by a scalar. * * @param {mat2d} out the receiving matrix * @param {ReadonlyMat2d} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat2d} out */ function multiplyScalar(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; out[4] = a[4] * b; out[5] = a[5] * b; return out; } /** * Adds two mat2d's after multiplying each element of the second operand by a scalar value. * * @param {mat2d} out the receiving vector * @param {ReadonlyMat2d} a the first operand * @param {ReadonlyMat2d} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat2d} out */ function multiplyScalarAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; out[3] = a[3] + b[3] * scale; out[4] = a[4] + b[4] * scale; out[5] = a[5] + b[5] * scale; return out; } /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyMat2d} a The first matrix. * @param {ReadonlyMat2d} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; } /** * Returns whether or not the matrices have approximately the same elements in the same position. * * @param {ReadonlyMat2d} a The first matrix. * @param {ReadonlyMat2d} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)); } /** * Alias for {@link mat2d.multiply} * @function */ var mul = multiply; /** * Alias for {@link mat2d.subtract} * @function */ exports.mul = mul; var sub = subtract; exports.sub = sub; },{"./common.js":882}],886:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.fromMat4 = fromMat4; exports.clone = clone; exports.copy = copy; exports.fromValues = fromValues; exports.set = set; exports.identity = identity; exports.transpose = transpose; exports.invert = invert; exports.adjoint = adjoint; exports.determinant = determinant; exports.multiply = multiply; exports.translate = translate; exports.rotate = rotate; exports.scale = scale; exports.fromTranslation = fromTranslation; exports.fromRotation = fromRotation; exports.fromScaling = fromScaling; exports.fromMat2d = fromMat2d; exports.fromQuat = fromQuat; exports.normalFromMat4 = normalFromMat4; exports.projection = projection; exports.str = str; exports.frob = frob; exports.add = add; exports.subtract = subtract; exports.multiplyScalar = multiplyScalar; exports.multiplyScalarAndAdd = multiplyScalarAndAdd; exports.exactEquals = exactEquals; exports.equals = equals; exports.sub = exports.mul = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 3x3 Matrix * @module mat3 */ /** * Creates a new identity mat3 * * @returns {mat3} a new 3x3 matrix */ function create() { var out = new glMatrix.ARRAY_TYPE(9); if (glMatrix.ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[5] = 0; out[6] = 0; out[7] = 0; } out[0] = 1; out[4] = 1; out[8] = 1; return out; } /** * Copies the upper-left 3x3 values into the given mat3. * * @param {mat3} out the receiving 3x3 matrix * @param {ReadonlyMat4} a the source 4x4 matrix * @returns {mat3} out */ function fromMat4(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[4]; out[4] = a[5]; out[5] = a[6]; out[6] = a[8]; out[7] = a[9]; out[8] = a[10]; return out; } /** * Creates a new mat3 initialized with values from an existing matrix * * @param {ReadonlyMat3} a matrix to clone * @returns {mat3} a new 3x3 matrix */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(9); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; } /** * Copy the values from one mat3 to another * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the source matrix * @returns {mat3} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; } /** * Create a new mat3 with the given values * * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m10 Component in column 1, row 0 position (index 3) * @param {Number} m11 Component in column 1, row 1 position (index 4) * @param {Number} m12 Component in column 1, row 2 position (index 5) * @param {Number} m20 Component in column 2, row 0 position (index 6) * @param {Number} m21 Component in column 2, row 1 position (index 7) * @param {Number} m22 Component in column 2, row 2 position (index 8) * @returns {mat3} A new mat3 */ function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) { var out = new glMatrix.ARRAY_TYPE(9); out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m10; out[4] = m11; out[5] = m12; out[6] = m20; out[7] = m21; out[8] = m22; return out; } /** * Set the components of a mat3 to the given values * * @param {mat3} out the receiving matrix * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m10 Component in column 1, row 0 position (index 3) * @param {Number} m11 Component in column 1, row 1 position (index 4) * @param {Number} m12 Component in column 1, row 2 position (index 5) * @param {Number} m20 Component in column 2, row 0 position (index 6) * @param {Number} m21 Component in column 2, row 1 position (index 7) * @param {Number} m22 Component in column 2, row 2 position (index 8) * @returns {mat3} out */ function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) { out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m10; out[4] = m11; out[5] = m12; out[6] = m20; out[7] = m21; out[8] = m22; return out; } /** * Set a mat3 to the identity matrix * * @param {mat3} out the receiving matrix * @returns {mat3} out */ function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 1; out[5] = 0; out[6] = 0; out[7] = 0; out[8] = 1; return out; } /** * Transpose the values of a mat3 * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the source matrix * @returns {mat3} out */ function transpose(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { var a01 = a[1], a02 = a[2], a12 = a[5]; out[1] = a[3]; out[2] = a[6]; out[3] = a01; out[5] = a[7]; out[6] = a02; out[7] = a12; } else { out[0] = a[0]; out[1] = a[3]; out[2] = a[6]; out[3] = a[1]; out[4] = a[4]; out[5] = a[7]; out[6] = a[2]; out[7] = a[5]; out[8] = a[8]; } return out; } /** * Inverts a mat3 * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the source matrix * @returns {mat3} out */ function invert(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2]; var a10 = a[3], a11 = a[4], a12 = a[5]; var a20 = a[6], a21 = a[7], a22 = a[8]; var b01 = a22 * a11 - a12 * a21; var b11 = -a22 * a10 + a12 * a20; var b21 = a21 * a10 - a11 * a20; // Calculate the determinant var det = a00 * b01 + a01 * b11 + a02 * b21; if (!det) { return null; } det = 1.0 / det; out[0] = b01 * det; out[1] = (-a22 * a01 + a02 * a21) * det; out[2] = (a12 * a01 - a02 * a11) * det; out[3] = b11 * det; out[4] = (a22 * a00 - a02 * a20) * det; out[5] = (-a12 * a00 + a02 * a10) * det; out[6] = b21 * det; out[7] = (-a21 * a00 + a01 * a20) * det; out[8] = (a11 * a00 - a01 * a10) * det; return out; } /** * Calculates the adjugate of a mat3 * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the source matrix * @returns {mat3} out */ function adjoint(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2]; var a10 = a[3], a11 = a[4], a12 = a[5]; var a20 = a[6], a21 = a[7], a22 = a[8]; out[0] = a11 * a22 - a12 * a21; out[1] = a02 * a21 - a01 * a22; out[2] = a01 * a12 - a02 * a11; out[3] = a12 * a20 - a10 * a22; out[4] = a00 * a22 - a02 * a20; out[5] = a02 * a10 - a00 * a12; out[6] = a10 * a21 - a11 * a20; out[7] = a01 * a20 - a00 * a21; out[8] = a00 * a11 - a01 * a10; return out; } /** * Calculates the determinant of a mat3 * * @param {ReadonlyMat3} a the source matrix * @returns {Number} determinant of a */ function determinant(a) { var a00 = a[0], a01 = a[1], a02 = a[2]; var a10 = a[3], a11 = a[4], a12 = a[5]; var a20 = a[6], a21 = a[7], a22 = a[8]; return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); } /** * Multiplies two mat3's * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the first operand * @param {ReadonlyMat3} b the second operand * @returns {mat3} out */ function multiply(out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2]; var a10 = a[3], a11 = a[4], a12 = a[5]; var a20 = a[6], a21 = a[7], a22 = a[8]; var b00 = b[0], b01 = b[1], b02 = b[2]; var b10 = b[3], b11 = b[4], b12 = b[5]; var b20 = b[6], b21 = b[7], b22 = b[8]; out[0] = b00 * a00 + b01 * a10 + b02 * a20; out[1] = b00 * a01 + b01 * a11 + b02 * a21; out[2] = b00 * a02 + b01 * a12 + b02 * a22; out[3] = b10 * a00 + b11 * a10 + b12 * a20; out[4] = b10 * a01 + b11 * a11 + b12 * a21; out[5] = b10 * a02 + b11 * a12 + b12 * a22; out[6] = b20 * a00 + b21 * a10 + b22 * a20; out[7] = b20 * a01 + b21 * a11 + b22 * a21; out[8] = b20 * a02 + b21 * a12 + b22 * a22; return out; } /** * Translate a mat3 by the given vector * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the matrix to translate * @param {ReadonlyVec2} v vector to translate by * @returns {mat3} out */ function translate(out, a, v) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8], x = v[0], y = v[1]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a10; out[4] = a11; out[5] = a12; out[6] = x * a00 + y * a10 + a20; out[7] = x * a01 + y * a11 + a21; out[8] = x * a02 + y * a12 + a22; return out; } /** * Rotates a mat3 by the given angle * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat3} out */ function rotate(out, a, rad) { var a00 = a[0], a01 = a[1], a02 = a[2], a10 = a[3], a11 = a[4], a12 = a[5], a20 = a[6], a21 = a[7], a22 = a[8], s = Math.sin(rad), c = Math.cos(rad); out[0] = c * a00 + s * a10; out[1] = c * a01 + s * a11; out[2] = c * a02 + s * a12; out[3] = c * a10 - s * a00; out[4] = c * a11 - s * a01; out[5] = c * a12 - s * a02; out[6] = a20; out[7] = a21; out[8] = a22; return out; } /** * Scales the mat3 by the dimensions in the given vec2 * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the matrix to rotate * @param {ReadonlyVec2} v the vec2 to scale the matrix by * @returns {mat3} out **/ function scale(out, a, v) { var x = v[0], y = v[1]; out[0] = x * a[0]; out[1] = x * a[1]; out[2] = x * a[2]; out[3] = y * a[3]; out[4] = y * a[4]; out[5] = y * a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; } /** * Creates a matrix from a vector translation * This is equivalent to (but much faster than): * * mat3.identity(dest); * mat3.translate(dest, dest, vec); * * @param {mat3} out mat3 receiving operation result * @param {ReadonlyVec2} v Translation vector * @returns {mat3} out */ function fromTranslation(out, v) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 1; out[5] = 0; out[6] = v[0]; out[7] = v[1]; out[8] = 1; return out; } /** * Creates a matrix from a given angle * This is equivalent to (but much faster than): * * mat3.identity(dest); * mat3.rotate(dest, dest, rad); * * @param {mat3} out mat3 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat3} out */ function fromRotation(out, rad) { var s = Math.sin(rad), c = Math.cos(rad); out[0] = c; out[1] = s; out[2] = 0; out[3] = -s; out[4] = c; out[5] = 0; out[6] = 0; out[7] = 0; out[8] = 1; return out; } /** * Creates a matrix from a vector scaling * This is equivalent to (but much faster than): * * mat3.identity(dest); * mat3.scale(dest, dest, vec); * * @param {mat3} out mat3 receiving operation result * @param {ReadonlyVec2} v Scaling vector * @returns {mat3} out */ function fromScaling(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = v[1]; out[5] = 0; out[6] = 0; out[7] = 0; out[8] = 1; return out; } /** * Copies the values from a mat2d into a mat3 * * @param {mat3} out the receiving matrix * @param {ReadonlyMat2d} a the matrix to copy * @returns {mat3} out **/ function fromMat2d(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = 0; out[3] = a[2]; out[4] = a[3]; out[5] = 0; out[6] = a[4]; out[7] = a[5]; out[8] = 1; return out; } /** * Calculates a 3x3 matrix from the given quaternion * * @param {mat3} out mat3 receiving operation result * @param {ReadonlyQuat} q Quaternion to create matrix from * * @returns {mat3} out */ function fromQuat(out, q) { var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var yx = y * x2; var yy = y * y2; var zx = z * x2; var zy = z * y2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; out[0] = 1 - yy - zz; out[3] = yx - wz; out[6] = zx + wy; out[1] = yx + wz; out[4] = 1 - xx - zz; out[7] = zy - wx; out[2] = zx - wy; out[5] = zy + wx; out[8] = 1 - xx - yy; return out; } /** * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix * * @param {mat3} out mat3 receiving operation result * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from * * @returns {mat3} out */ function normalFromMat4(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b00 = a00 * a11 - a01 * a10; var b01 = a00 * a12 - a02 * a10; var b02 = a00 * a13 - a03 * a10; var b03 = a01 * a12 - a02 * a11; var b04 = a01 * a13 - a03 * a11; var b05 = a02 * a13 - a03 * a12; var b06 = a20 * a31 - a21 * a30; var b07 = a20 * a32 - a22 * a30; var b08 = a20 * a33 - a23 * a30; var b09 = a21 * a32 - a22 * a31; var b10 = a21 * a33 - a23 * a31; var b11 = a22 * a33 - a23 * a32; // Calculate the determinant var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1.0 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; return out; } /** * Generates a 2D projection matrix with the given bounds * * @param {mat3} out mat3 frustum matrix will be written into * @param {number} width Width of your gl context * @param {number} height Height of gl context * @returns {mat3} out */ function projection(out, width, height) { out[0] = 2 / width; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = -2 / height; out[5] = 0; out[6] = -1; out[7] = 1; out[8] = 1; return out; } /** * Returns a string representation of a mat3 * * @param {ReadonlyMat3} a matrix to represent as a string * @returns {String} string representation of the matrix */ function str(a) { return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")"; } /** * Returns Frobenius norm of a mat3 * * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ function frob(a) { return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); } /** * Adds two mat3's * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the first operand * @param {ReadonlyMat3} b the second operand * @returns {mat3} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; out[8] = a[8] + b[8]; return out; } /** * Subtracts matrix b from matrix a * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the first operand * @param {ReadonlyMat3} b the second operand * @returns {mat3} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; out[4] = a[4] - b[4]; out[5] = a[5] - b[5]; out[6] = a[6] - b[6]; out[7] = a[7] - b[7]; out[8] = a[8] - b[8]; return out; } /** * Multiply each element of the matrix by a scalar. * * @param {mat3} out the receiving matrix * @param {ReadonlyMat3} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat3} out */ function multiplyScalar(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; out[4] = a[4] * b; out[5] = a[5] * b; out[6] = a[6] * b; out[7] = a[7] * b; out[8] = a[8] * b; return out; } /** * Adds two mat3's after multiplying each element of the second operand by a scalar value. * * @param {mat3} out the receiving vector * @param {ReadonlyMat3} a the first operand * @param {ReadonlyMat3} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat3} out */ function multiplyScalarAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; out[3] = a[3] + b[3] * scale; out[4] = a[4] + b[4] * scale; out[5] = a[5] + b[5] * scale; out[6] = a[6] + b[6] * scale; out[7] = a[7] + b[7] * scale; out[8] = a[8] + b[8] * scale; return out; } /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyMat3} a The first matrix. * @param {ReadonlyMat3} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8]; } /** * Returns whether or not the matrices have approximately the same elements in the same position. * * @param {ReadonlyMat3} a The first matrix. * @param {ReadonlyMat3} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7], a8 = a[8]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)); } /** * Alias for {@link mat3.multiply} * @function */ var mul = multiply; /** * Alias for {@link mat3.subtract} * @function */ exports.mul = mul; var sub = subtract; exports.sub = sub; },{"./common.js":882}],887:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.copy = copy; exports.fromValues = fromValues; exports.set = set; exports.identity = identity; exports.transpose = transpose; exports.invert = invert; exports.adjoint = adjoint; exports.determinant = determinant; exports.multiply = multiply; exports.translate = translate; exports.scale = scale; exports.rotate = rotate; exports.rotateX = rotateX; exports.rotateY = rotateY; exports.rotateZ = rotateZ; exports.fromTranslation = fromTranslation; exports.fromScaling = fromScaling; exports.fromRotation = fromRotation; exports.fromXRotation = fromXRotation; exports.fromYRotation = fromYRotation; exports.fromZRotation = fromZRotation; exports.fromRotationTranslation = fromRotationTranslation; exports.fromQuat2 = fromQuat2; exports.getTranslation = getTranslation; exports.getScaling = getScaling; exports.getRotation = getRotation; exports.fromRotationTranslationScale = fromRotationTranslationScale; exports.fromRotationTranslationScaleOrigin = fromRotationTranslationScaleOrigin; exports.fromQuat = fromQuat; exports.frustum = frustum; exports.perspective = perspective; exports.perspectiveFromFieldOfView = perspectiveFromFieldOfView; exports.ortho = ortho; exports.lookAt = lookAt; exports.targetTo = targetTo; exports.str = str; exports.frob = frob; exports.add = add; exports.subtract = subtract; exports.multiplyScalar = multiplyScalar; exports.multiplyScalarAndAdd = multiplyScalarAndAdd; exports.exactEquals = exactEquals; exports.equals = equals; exports.sub = exports.mul = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 4x4 Matrix
      Format: column-major, when typed out it looks like row-major
      The matrices are being post multiplied. * @module mat4 */ /** * Creates a new identity mat4 * * @returns {mat4} a new 4x4 matrix */ function create() { var out = new glMatrix.ARRAY_TYPE(16); if (glMatrix.ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; } out[0] = 1; out[5] = 1; out[10] = 1; out[15] = 1; return out; } /** * Creates a new mat4 initialized with values from an existing matrix * * @param {ReadonlyMat4} a matrix to clone * @returns {mat4} a new 4x4 matrix */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(16); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } /** * Copy the values from one mat4 to another * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } /** * Create a new mat4 with the given values * * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m03 Component in column 0, row 3 position (index 3) * @param {Number} m10 Component in column 1, row 0 position (index 4) * @param {Number} m11 Component in column 1, row 1 position (index 5) * @param {Number} m12 Component in column 1, row 2 position (index 6) * @param {Number} m13 Component in column 1, row 3 position (index 7) * @param {Number} m20 Component in column 2, row 0 position (index 8) * @param {Number} m21 Component in column 2, row 1 position (index 9) * @param {Number} m22 Component in column 2, row 2 position (index 10) * @param {Number} m23 Component in column 2, row 3 position (index 11) * @param {Number} m30 Component in column 3, row 0 position (index 12) * @param {Number} m31 Component in column 3, row 1 position (index 13) * @param {Number} m32 Component in column 3, row 2 position (index 14) * @param {Number} m33 Component in column 3, row 3 position (index 15) * @returns {mat4} A new mat4 */ function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { var out = new glMatrix.ARRAY_TYPE(16); out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m03; out[4] = m10; out[5] = m11; out[6] = m12; out[7] = m13; out[8] = m20; out[9] = m21; out[10] = m22; out[11] = m23; out[12] = m30; out[13] = m31; out[14] = m32; out[15] = m33; return out; } /** * Set the components of a mat4 to the given values * * @param {mat4} out the receiving matrix * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m03 Component in column 0, row 3 position (index 3) * @param {Number} m10 Component in column 1, row 0 position (index 4) * @param {Number} m11 Component in column 1, row 1 position (index 5) * @param {Number} m12 Component in column 1, row 2 position (index 6) * @param {Number} m13 Component in column 1, row 3 position (index 7) * @param {Number} m20 Component in column 2, row 0 position (index 8) * @param {Number} m21 Component in column 2, row 1 position (index 9) * @param {Number} m22 Component in column 2, row 2 position (index 10) * @param {Number} m23 Component in column 2, row 3 position (index 11) * @param {Number} m30 Component in column 3, row 0 position (index 12) * @param {Number} m31 Component in column 3, row 1 position (index 13) * @param {Number} m32 Component in column 3, row 2 position (index 14) * @param {Number} m33 Component in column 3, row 3 position (index 15) * @returns {mat4} out */ function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m03; out[4] = m10; out[5] = m11; out[6] = m12; out[7] = m13; out[8] = m20; out[9] = m21; out[10] = m22; out[11] = m23; out[12] = m30; out[13] = m31; out[14] = m32; out[15] = m33; return out; } /** * Set a mat4 to the identity matrix * * @param {mat4} out the receiving matrix * @returns {mat4} out */ function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Transpose the values of a mat4 * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function transpose(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { var a01 = a[1], a02 = a[2], a03 = a[3]; var a12 = a[6], a13 = a[7]; var a23 = a[11]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a01; out[6] = a[9]; out[7] = a[13]; out[8] = a02; out[9] = a12; out[11] = a[14]; out[12] = a03; out[13] = a13; out[14] = a23; } else { out[0] = a[0]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a[1]; out[5] = a[5]; out[6] = a[9]; out[7] = a[13]; out[8] = a[2]; out[9] = a[6]; out[10] = a[10]; out[11] = a[14]; out[12] = a[3]; out[13] = a[7]; out[14] = a[11]; out[15] = a[15]; } return out; } /** * Inverts a mat4 * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function invert(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b00 = a00 * a11 - a01 * a10; var b01 = a00 * a12 - a02 * a10; var b02 = a00 * a13 - a03 * a10; var b03 = a01 * a12 - a02 * a11; var b04 = a01 * a13 - a03 * a11; var b05 = a02 * a13 - a03 * a12; var b06 = a20 * a31 - a21 * a30; var b07 = a20 * a32 - a22 * a30; var b08 = a20 * a33 - a23 * a30; var b09 = a21 * a32 - a22 * a31; var b10 = a21 * a33 - a23 * a31; var b11 = a22 * a33 - a23 * a32; // Calculate the determinant var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1.0 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; return out; } /** * Calculates the adjugate of a mat4 * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function adjoint(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22); out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12); out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22); out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12); out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21); out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11); out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21); out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11); return out; } /** * Calculates the determinant of a mat4 * * @param {ReadonlyMat4} a the source matrix * @returns {Number} determinant of a */ function determinant(a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b00 = a00 * a11 - a01 * a10; var b01 = a00 * a12 - a02 * a10; var b02 = a00 * a13 - a03 * a10; var b03 = a01 * a12 - a02 * a11; var b04 = a01 * a13 - a03 * a11; var b05 = a02 * a13 - a03 * a12; var b06 = a20 * a31 - a21 * a30; var b07 = a20 * a32 - a22 * a30; var b08 = a20 * a33 - a23 * a30; var b09 = a21 * a32 - a22 * a31; var b10 = a21 * a33 - a23 * a31; var b11 = a22 * a33 - a23 * a32; // Calculate the determinant return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; } /** * Multiplies two mat4s * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ function multiply(out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; // Cache only the current line of the second matrix var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; return out; } /** * Translate a mat4 by the given vector * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to translate * @param {ReadonlyVec3} v vector to translate by * @returns {mat4} out */ function translate(out, a, v) { var x = v[0], y = v[1], z = v[2]; var a00, a01, a02, a03; var a10, a11, a12, a13; var a20, a21, a22, a23; if (a === out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + a[12]; out[13] = a01 * x + a11 * y + a21 * z + a[13]; out[14] = a02 * x + a12 * y + a22 * z + a[14]; out[15] = a03 * x + a13 * y + a23 * z + a[15]; } return out; } /** * Scales the mat4 by the dimensions in the given vec3 not using vectorization * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to scale * @param {ReadonlyVec3} v the vec3 to scale the matrix by * @returns {mat4} out **/ function scale(out, a, v) { var x = v[0], y = v[1], z = v[2]; out[0] = a[0] * x; out[1] = a[1] * x; out[2] = a[2] * x; out[3] = a[3] * x; out[4] = a[4] * y; out[5] = a[5] * y; out[6] = a[6] * y; out[7] = a[7] * y; out[8] = a[8] * z; out[9] = a[9] * z; out[10] = a[10] * z; out[11] = a[11] * z; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } /** * Rotates a mat4 by the given angle around the given axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @param {ReadonlyVec3} axis the axis to rotate around * @returns {mat4} out */ function rotate(out, a, rad, axis) { var x = axis[0], y = axis[1], z = axis[2]; var len = Math.hypot(x, y, z); var s, c, t; var a00, a01, a02, a03; var a10, a11, a12, a13; var a20, a21, a22, a23; var b00, b01, b02; var b10, b11, b12; var b20, b21, b22; if (len < glMatrix.EPSILON) { return null; } len = 1 / len; x *= len; y *= len; z *= len; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication out[0] = a00 * b00 + a10 * b01 + a20 * b02; out[1] = a01 * b00 + a11 * b01 + a21 * b02; out[2] = a02 * b00 + a12 * b01 + a22 * b02; out[3] = a03 * b00 + a13 * b01 + a23 * b02; out[4] = a00 * b10 + a10 * b11 + a20 * b12; out[5] = a01 * b10 + a11 * b11 + a21 * b12; out[6] = a02 * b10 + a12 * b11 + a22 * b12; out[7] = a03 * b10 + a13 * b11 + a23 * b12; out[8] = a00 * b20 + a10 * b21 + a20 * b22; out[9] = a01 * b20 + a11 * b21 + a21 * b22; out[10] = a02 * b20 + a12 * b21 + a22 * b22; out[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a !== out) { // If the source and destination differ, copy the unchanged last row out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } return out; } /** * Rotates a matrix by the given angle around the X axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function rotateX(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a10 = a[4]; var a11 = a[5]; var a12 = a[6]; var a13 = a[7]; var a20 = a[8]; var a21 = a[9]; var a22 = a[10]; var a23 = a[11]; if (a !== out) { // If the source and destination differ, copy the unchanged rows out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[4] = a10 * c + a20 * s; out[5] = a11 * c + a21 * s; out[6] = a12 * c + a22 * s; out[7] = a13 * c + a23 * s; out[8] = a20 * c - a10 * s; out[9] = a21 * c - a11 * s; out[10] = a22 * c - a12 * s; out[11] = a23 * c - a13 * s; return out; } /** * Rotates a matrix by the given angle around the Y axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function rotateY(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a03 = a[3]; var a20 = a[8]; var a21 = a[9]; var a22 = a[10]; var a23 = a[11]; if (a !== out) { // If the source and destination differ, copy the unchanged rows out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[0] = a00 * c - a20 * s; out[1] = a01 * c - a21 * s; out[2] = a02 * c - a22 * s; out[3] = a03 * c - a23 * s; out[8] = a00 * s + a20 * c; out[9] = a01 * s + a21 * c; out[10] = a02 * s + a22 * c; out[11] = a03 * s + a23 * c; return out; } /** * Rotates a matrix by the given angle around the Z axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function rotateZ(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a03 = a[3]; var a10 = a[4]; var a11 = a[5]; var a12 = a[6]; var a13 = a[7]; if (a !== out) { // If the source and destination differ, copy the unchanged last row out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[0] = a00 * c + a10 * s; out[1] = a01 * c + a11 * s; out[2] = a02 * c + a12 * s; out[3] = a03 * c + a13 * s; out[4] = a10 * c - a00 * s; out[5] = a11 * c - a01 * s; out[6] = a12 * c - a02 * s; out[7] = a13 * c - a03 * s; return out; } /** * Creates a matrix from a vector translation * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, dest, vec); * * @param {mat4} out mat4 receiving operation result * @param {ReadonlyVec3} v Translation vector * @returns {mat4} out */ function fromTranslation(out, v) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } /** * Creates a matrix from a vector scaling * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.scale(dest, dest, vec); * * @param {mat4} out mat4 receiving operation result * @param {ReadonlyVec3} v Scaling vector * @returns {mat4} out */ function fromScaling(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = v[1]; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = v[2]; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from a given angle around a given axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotate(dest, dest, rad, axis); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @param {ReadonlyVec3} axis the axis to rotate around * @returns {mat4} out */ function fromRotation(out, rad, axis) { var x = axis[0], y = axis[1], z = axis[2]; var len = Math.hypot(x, y, z); var s, c, t; if (len < glMatrix.EPSILON) { return null; } len = 1 / len; x *= len; y *= len; z *= len; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; // Perform rotation-specific matrix multiplication out[0] = x * x * t + c; out[1] = y * x * t + z * s; out[2] = z * x * t - y * s; out[3] = 0; out[4] = x * y * t - z * s; out[5] = y * y * t + c; out[6] = z * y * t + x * s; out[7] = 0; out[8] = x * z * t + y * s; out[9] = y * z * t - x * s; out[10] = z * z * t + c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from the given angle around the X axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotateX(dest, dest, rad); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function fromXRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); // Perform axis-specific matrix multiplication out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = c; out[6] = s; out[7] = 0; out[8] = 0; out[9] = -s; out[10] = c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from the given angle around the Y axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotateY(dest, dest, rad); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function fromYRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); // Perform axis-specific matrix multiplication out[0] = c; out[1] = 0; out[2] = -s; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = s; out[9] = 0; out[10] = c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from the given angle around the Z axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotateZ(dest, dest, rad); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function fromZRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); // Perform axis-specific matrix multiplication out[0] = c; out[1] = s; out[2] = 0; out[3] = 0; out[4] = -s; out[5] = c; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from a quaternion rotation and vector translation * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * let quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {ReadonlyVec3} v Translation vector * @returns {mat4} out */ function fromRotationTranslation(out, q, v) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; out[0] = 1 - (yy + zz); out[1] = xy + wz; out[2] = xz - wy; out[3] = 0; out[4] = xy - wz; out[5] = 1 - (xx + zz); out[6] = yz + wx; out[7] = 0; out[8] = xz + wy; out[9] = yz - wx; out[10] = 1 - (xx + yy); out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } /** * Creates a new mat4 from a dual quat. * * @param {mat4} out Matrix * @param {ReadonlyQuat2} a Dual Quaternion * @returns {mat4} mat4 receiving operation result */ function fromQuat2(out, a) { var translation = new glMatrix.ARRAY_TYPE(3); var bx = -a[0], by = -a[1], bz = -a[2], bw = a[3], ax = a[4], ay = a[5], az = a[6], aw = a[7]; var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense if (magnitude > 0) { translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude; translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude; translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude; } else { translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; } fromRotationTranslation(out, a, translation); return out; } /** * Returns the translation vector component of a transformation * matrix. If a matrix is built with fromRotationTranslation, * the returned vector will be the same as the translation vector * originally supplied. * @param {vec3} out Vector to receive translation component * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {vec3} out */ function getTranslation(out, mat) { out[0] = mat[12]; out[1] = mat[13]; out[2] = mat[14]; return out; } /** * Returns the scaling factor component of a transformation * matrix. If a matrix is built with fromRotationTranslationScale * with a normalized Quaternion paramter, the returned vector will be * the same as the scaling vector * originally supplied. * @param {vec3} out Vector to receive scaling factor component * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {vec3} out */ function getScaling(out, mat) { var m11 = mat[0]; var m12 = mat[1]; var m13 = mat[2]; var m21 = mat[4]; var m22 = mat[5]; var m23 = mat[6]; var m31 = mat[8]; var m32 = mat[9]; var m33 = mat[10]; out[0] = Math.hypot(m11, m12, m13); out[1] = Math.hypot(m21, m22, m23); out[2] = Math.hypot(m31, m32, m33); return out; } /** * Returns a quaternion representing the rotational component * of a transformation matrix. If a matrix is built with * fromRotationTranslation, the returned quaternion will be the * same as the quaternion originally supplied. * @param {quat} out Quaternion to receive the rotation component * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {quat} out */ function getRotation(out, mat) { var scaling = new glMatrix.ARRAY_TYPE(3); getScaling(scaling, mat); var is1 = 1 / scaling[0]; var is2 = 1 / scaling[1]; var is3 = 1 / scaling[2]; var sm11 = mat[0] * is1; var sm12 = mat[1] * is2; var sm13 = mat[2] * is3; var sm21 = mat[4] * is1; var sm22 = mat[5] * is2; var sm23 = mat[6] * is3; var sm31 = mat[8] * is1; var sm32 = mat[9] * is2; var sm33 = mat[10] * is3; var trace = sm11 + sm22 + sm33; var S = 0; if (trace > 0) { S = Math.sqrt(trace + 1.0) * 2; out[3] = 0.25 * S; out[0] = (sm23 - sm32) / S; out[1] = (sm31 - sm13) / S; out[2] = (sm12 - sm21) / S; } else if (sm11 > sm22 && sm11 > sm33) { S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; out[3] = (sm23 - sm32) / S; out[0] = 0.25 * S; out[1] = (sm12 + sm21) / S; out[2] = (sm31 + sm13) / S; } else if (sm22 > sm33) { S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; out[3] = (sm31 - sm13) / S; out[0] = (sm12 + sm21) / S; out[1] = 0.25 * S; out[2] = (sm23 + sm32) / S; } else { S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; out[3] = (sm12 - sm21) / S; out[0] = (sm31 + sm13) / S; out[1] = (sm23 + sm32) / S; out[2] = 0.25 * S; } return out; } /** * Creates a matrix from a quaternion rotation, vector translation and vector scale * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * let quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * mat4.scale(dest, scale) * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {ReadonlyVec3} v Translation vector * @param {ReadonlyVec3} s Scaling vector * @returns {mat4} out */ function fromRotationTranslationScale(out, q, v, s) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; var sx = s[0]; var sy = s[1]; var sz = s[2]; out[0] = (1 - (yy + zz)) * sx; out[1] = (xy + wz) * sx; out[2] = (xz - wy) * sx; out[3] = 0; out[4] = (xy - wz) * sy; out[5] = (1 - (xx + zz)) * sy; out[6] = (yz + wx) * sy; out[7] = 0; out[8] = (xz + wy) * sz; out[9] = (yz - wx) * sz; out[10] = (1 - (xx + yy)) * sz; out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } /** * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * mat4.translate(dest, origin); * let quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * mat4.scale(dest, scale) * mat4.translate(dest, negativeOrigin); * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {ReadonlyVec3} v Translation vector * @param {ReadonlyVec3} s Scaling vector * @param {ReadonlyVec3} o The origin vector around which to scale and rotate * @returns {mat4} out */ function fromRotationTranslationScaleOrigin(out, q, v, s, o) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; var sx = s[0]; var sy = s[1]; var sz = s[2]; var ox = o[0]; var oy = o[1]; var oz = o[2]; var out0 = (1 - (yy + zz)) * sx; var out1 = (xy + wz) * sx; var out2 = (xz - wy) * sx; var out4 = (xy - wz) * sy; var out5 = (1 - (xx + zz)) * sy; var out6 = (yz + wx) * sy; var out8 = (xz + wy) * sz; var out9 = (yz - wx) * sz; var out10 = (1 - (xx + yy)) * sz; out[0] = out0; out[1] = out1; out[2] = out2; out[3] = 0; out[4] = out4; out[5] = out5; out[6] = out6; out[7] = 0; out[8] = out8; out[9] = out9; out[10] = out10; out[11] = 0; out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz); out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz); out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz); out[15] = 1; return out; } /** * Calculates a 4x4 matrix from the given quaternion * * @param {mat4} out mat4 receiving operation result * @param {ReadonlyQuat} q Quaternion to create matrix from * * @returns {mat4} out */ function fromQuat(out, q) { var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var yx = y * x2; var yy = y * y2; var zx = z * x2; var zy = z * y2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; out[0] = 1 - yy - zz; out[1] = yx + wz; out[2] = zx - wy; out[3] = 0; out[4] = yx - wz; out[5] = 1 - xx - zz; out[6] = zy + wx; out[7] = 0; out[8] = zx + wy; out[9] = zy - wx; out[10] = 1 - xx - yy; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Generates a frustum matrix with the given bounds * * @param {mat4} out mat4 frustum matrix will be written into * @param {Number} left Left bound of the frustum * @param {Number} right Right bound of the frustum * @param {Number} bottom Bottom bound of the frustum * @param {Number} top Top bound of the frustum * @param {Number} near Near bound of the frustum * @param {Number} far Far bound of the frustum * @returns {mat4} out */ function frustum(out, left, right, bottom, top, near, far) { var rl = 1 / (right - left); var tb = 1 / (top - bottom); var nf = 1 / (near - far); out[0] = near * 2 * rl; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = near * 2 * tb; out[6] = 0; out[7] = 0; out[8] = (right + left) * rl; out[9] = (top + bottom) * tb; out[10] = (far + near) * nf; out[11] = -1; out[12] = 0; out[13] = 0; out[14] = far * near * 2 * nf; out[15] = 0; return out; } /** * Generates a perspective projection matrix with the given bounds. * Passing null/undefined/no value for far will generate infinite projection matrix. * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} fovy Vertical field of view in radians * @param {number} aspect Aspect ratio. typically viewport width/height * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum, can be null or Infinity * @returns {mat4} out */ function perspective(out, fovy, aspect, near, far) { var f = 1.0 / Math.tan(fovy / 2), nf; out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { nf = 1 / (near - far); out[10] = (far + near) * nf; out[14] = 2 * far * near * nf; } else { out[10] = -1; out[14] = -2 * near; } return out; } /** * Generates a perspective projection matrix with the given field of view. * This is primarily useful for generating projection matrices to be used * with the still experiemental WebVR API. * * @param {mat4} out mat4 frustum matrix will be written into * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ function perspectiveFromFieldOfView(out, fov, near, far) { var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0); var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0); var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0); var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0); var xScale = 2.0 / (leftTan + rightTan); var yScale = 2.0 / (upTan + downTan); out[0] = xScale; out[1] = 0.0; out[2] = 0.0; out[3] = 0.0; out[4] = 0.0; out[5] = yScale; out[6] = 0.0; out[7] = 0.0; out[8] = -((leftTan - rightTan) * xScale * 0.5); out[9] = (upTan - downTan) * yScale * 0.5; out[10] = far / (near - far); out[11] = -1.0; out[12] = 0.0; out[13] = 0.0; out[14] = far * near / (near - far); out[15] = 0.0; return out; } /** * Generates a orthogonal projection matrix with the given bounds * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} left Left bound of the frustum * @param {number} right Right bound of the frustum * @param {number} bottom Bottom bound of the frustum * @param {number} top Top bound of the frustum * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ function ortho(out, left, right, bottom, top, near, far) { var lr = 1 / (left - right); var bt = 1 / (bottom - top); var nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; } /** * Generates a look-at matrix with the given eye position, focal point, and up axis. * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. * * @param {mat4} out mat4 frustum matrix will be written into * @param {ReadonlyVec3} eye Position of the viewer * @param {ReadonlyVec3} center Point the viewer is looking at * @param {ReadonlyVec3} up vec3 pointing up * @returns {mat4} out */ function lookAt(out, eye, center, up) { var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; var eyex = eye[0]; var eyey = eye[1]; var eyez = eye[2]; var upx = up[0]; var upy = up[1]; var upz = up[2]; var centerx = center[0]; var centery = center[1]; var centerz = center[2]; if (Math.abs(eyex - centerx) < glMatrix.EPSILON && Math.abs(eyey - centery) < glMatrix.EPSILON && Math.abs(eyez - centerz) < glMatrix.EPSILON) { return identity(out); } z0 = eyex - centerx; z1 = eyey - centery; z2 = eyez - centerz; len = 1 / Math.hypot(z0, z1, z2); z0 *= len; z1 *= len; z2 *= len; x0 = upy * z2 - upz * z1; x1 = upz * z0 - upx * z2; x2 = upx * z1 - upy * z0; len = Math.hypot(x0, x1, x2); if (!len) { x0 = 0; x1 = 0; x2 = 0; } else { len = 1 / len; x0 *= len; x1 *= len; x2 *= len; } y0 = z1 * x2 - z2 * x1; y1 = z2 * x0 - z0 * x2; y2 = z0 * x1 - z1 * x0; len = Math.hypot(y0, y1, y2); if (!len) { y0 = 0; y1 = 0; y2 = 0; } else { len = 1 / len; y0 *= len; y1 *= len; y2 *= len; } out[0] = x0; out[1] = y0; out[2] = z0; out[3] = 0; out[4] = x1; out[5] = y1; out[6] = z1; out[7] = 0; out[8] = x2; out[9] = y2; out[10] = z2; out[11] = 0; out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); out[15] = 1; return out; } /** * Generates a matrix that makes something look at something else. * * @param {mat4} out mat4 frustum matrix will be written into * @param {ReadonlyVec3} eye Position of the viewer * @param {ReadonlyVec3} center Point the viewer is looking at * @param {ReadonlyVec3} up vec3 pointing up * @returns {mat4} out */ function targetTo(out, eye, target, up) { var eyex = eye[0], eyey = eye[1], eyez = eye[2], upx = up[0], upy = up[1], upz = up[2]; var z0 = eyex - target[0], z1 = eyey - target[1], z2 = eyez - target[2]; var len = z0 * z0 + z1 * z1 + z2 * z2; if (len > 0) { len = 1 / Math.sqrt(len); z0 *= len; z1 *= len; z2 *= len; } var x0 = upy * z2 - upz * z1, x1 = upz * z0 - upx * z2, x2 = upx * z1 - upy * z0; len = x0 * x0 + x1 * x1 + x2 * x2; if (len > 0) { len = 1 / Math.sqrt(len); x0 *= len; x1 *= len; x2 *= len; } out[0] = x0; out[1] = x1; out[2] = x2; out[3] = 0; out[4] = z1 * x2 - z2 * x1; out[5] = z2 * x0 - z0 * x2; out[6] = z0 * x1 - z1 * x0; out[7] = 0; out[8] = z0; out[9] = z1; out[10] = z2; out[11] = 0; out[12] = eyex; out[13] = eyey; out[14] = eyez; out[15] = 1; return out; } /** * Returns a string representation of a mat4 * * @param {ReadonlyMat4} a matrix to represent as a string * @returns {String} string representation of the matrix */ function str(a) { return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"; } /** * Returns Frobenius norm of a mat4 * * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ function frob(a) { return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); } /** * Adds two mat4's * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; out[8] = a[8] + b[8]; out[9] = a[9] + b[9]; out[10] = a[10] + b[10]; out[11] = a[11] + b[11]; out[12] = a[12] + b[12]; out[13] = a[13] + b[13]; out[14] = a[14] + b[14]; out[15] = a[15] + b[15]; return out; } /** * Subtracts matrix b from matrix a * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; out[4] = a[4] - b[4]; out[5] = a[5] - b[5]; out[6] = a[6] - b[6]; out[7] = a[7] - b[7]; out[8] = a[8] - b[8]; out[9] = a[9] - b[9]; out[10] = a[10] - b[10]; out[11] = a[11] - b[11]; out[12] = a[12] - b[12]; out[13] = a[13] - b[13]; out[14] = a[14] - b[14]; out[15] = a[15] - b[15]; return out; } /** * Multiply each element of the matrix by a scalar. * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat4} out */ function multiplyScalar(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; out[4] = a[4] * b; out[5] = a[5] * b; out[6] = a[6] * b; out[7] = a[7] * b; out[8] = a[8] * b; out[9] = a[9] * b; out[10] = a[10] * b; out[11] = a[11] * b; out[12] = a[12] * b; out[13] = a[13] * b; out[14] = a[14] * b; out[15] = a[15] * b; return out; } /** * Adds two mat4's after multiplying each element of the second operand by a scalar value. * * @param {mat4} out the receiving vector * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat4} out */ function multiplyScalarAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; out[3] = a[3] + b[3] * scale; out[4] = a[4] + b[4] * scale; out[5] = a[5] + b[5] * scale; out[6] = a[6] + b[6] * scale; out[7] = a[7] + b[7] * scale; out[8] = a[8] + b[8] * scale; out[9] = a[9] + b[9] * scale; out[10] = a[10] + b[10] * scale; out[11] = a[11] + b[11] * scale; out[12] = a[12] + b[12] * scale; out[13] = a[13] + b[13] * scale; out[14] = a[14] + b[14] * scale; out[15] = a[15] + b[15] * scale; return out; } /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyMat4} a The first matrix. * @param {ReadonlyMat4} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; } /** * Returns whether or not the matrices have approximately the same elements in the same position. * * @param {ReadonlyMat4} a The first matrix. * @param {ReadonlyMat4} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7]; var a8 = a[8], a9 = a[9], a10 = a[10], a11 = a[11]; var a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; var b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7]; var b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11]; var b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15)); } /** * Alias for {@link mat4.multiply} * @function */ var mul = multiply; /** * Alias for {@link mat4.subtract} * @function */ exports.mul = mul; var sub = subtract; exports.sub = sub; },{"./common.js":882}],888:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.identity = identity; exports.setAxisAngle = setAxisAngle; exports.getAxisAngle = getAxisAngle; exports.getAngle = getAngle; exports.multiply = multiply; exports.rotateX = rotateX; exports.rotateY = rotateY; exports.rotateZ = rotateZ; exports.calculateW = calculateW; exports.exp = exp; exports.ln = ln; exports.pow = pow; exports.slerp = slerp; exports.random = random; exports.invert = invert; exports.conjugate = conjugate; exports.fromMat3 = fromMat3; exports.fromEuler = fromEuler; exports.str = str; exports.setAxes = exports.sqlerp = exports.rotationTo = exports.equals = exports.exactEquals = exports.normalize = exports.sqrLen = exports.squaredLength = exports.len = exports.length = exports.lerp = exports.dot = exports.scale = exports.mul = exports.add = exports.set = exports.copy = exports.fromValues = exports.clone = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); var mat3 = _interopRequireWildcard(require("./mat3.js")); var vec3 = _interopRequireWildcard(require("./vec3.js")); var vec4 = _interopRequireWildcard(require("./vec4.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * Quaternion * @module quat */ /** * Creates a new identity quat * * @returns {quat} a new quaternion */ function create() { var out = new glMatrix.ARRAY_TYPE(4); if (glMatrix.ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } out[3] = 1; return out; } /** * Set a quat to the identity quaternion * * @param {quat} out the receiving quaternion * @returns {quat} out */ function identity(out) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } /** * Sets a quat from the given angle and rotation axis, * then returns it. * * @param {quat} out the receiving quaternion * @param {ReadonlyVec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/ function setAxisAngle(out, axis, rad) { rad = rad * 0.5; var s = Math.sin(rad); out[0] = s * axis[0]; out[1] = s * axis[1]; out[2] = s * axis[2]; out[3] = Math.cos(rad); return out; } /** * Gets the rotation axis and angle for a given * quaternion. If a quaternion is created with * setAxisAngle, this method will return the same * values as providied in the original parameter list * OR functionally equivalent values. * Example: The quaternion formed by axis [0, 0, 1] and * angle -90 is the same as the quaternion formed by * [0, 0, 1] and 270. This method favors the latter. * @param {vec3} out_axis Vector receiving the axis of rotation * @param {ReadonlyQuat} q Quaternion to be decomposed * @return {Number} Angle, in radians, of the rotation */ function getAxisAngle(out_axis, q) { var rad = Math.acos(q[3]) * 2.0; var s = Math.sin(rad / 2.0); if (s > glMatrix.EPSILON) { out_axis[0] = q[0] / s; out_axis[1] = q[1] / s; out_axis[2] = q[2] / s; } else { // If s is zero, return any axis (no rotation - axis does not matter) out_axis[0] = 1; out_axis[1] = 0; out_axis[2] = 0; } return rad; } /** * Gets the angular distance between two unit quaternions * * @param {ReadonlyQuat} a Origin unit quaternion * @param {ReadonlyQuat} b Destination unit quaternion * @return {Number} Angle, in radians, between the two quaternions */ function getAngle(a, b) { var dotproduct = dot(a, b); return Math.acos(2 * dotproduct * dotproduct - 1); } /** * Multiplies two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {quat} out */ function multiply(out, a, b) { var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var bx = b[0], by = b[1], bz = b[2], bw = b[3]; out[0] = ax * bw + aw * bx + ay * bz - az * by; out[1] = ay * bw + aw * by + az * bx - ax * bz; out[2] = az * bw + aw * bz + ax * by - ay * bx; out[3] = aw * bw - ax * bx - ay * by - az * bz; return out; } /** * Rotates a quaternion by the given angle about the X axis * * @param {quat} out quat receiving operation result * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ function rotateX(out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var bx = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + aw * bx; out[1] = ay * bw + az * bx; out[2] = az * bw - ay * bx; out[3] = aw * bw - ax * bx; return out; } /** * Rotates a quaternion by the given angle about the Y axis * * @param {quat} out quat receiving operation result * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ function rotateY(out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var by = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw - az * by; out[1] = ay * bw + aw * by; out[2] = az * bw + ax * by; out[3] = aw * bw - ay * by; return out; } /** * Rotates a quaternion by the given angle about the Z axis * * @param {quat} out quat receiving operation result * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ function rotateZ(out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var bz = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + ay * bz; out[1] = ay * bw - ax * bz; out[2] = az * bw + aw * bz; out[3] = aw * bw - az * bz; return out; } /** * Calculates the W component of a quat from the X, Y, and Z components. * Assumes that quaternion is 1 unit in length. * Any existing W component will be ignored. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate W component of * @returns {quat} out */ function calculateW(out, a) { var x = a[0], y = a[1], z = a[2]; out[0] = x; out[1] = y; out[2] = z; out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); return out; } /** * Calculate the exponential of a unit quaternion. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate the exponential of * @returns {quat} out */ function exp(out, a) { var x = a[0], y = a[1], z = a[2], w = a[3]; var r = Math.sqrt(x * x + y * y + z * z); var et = Math.exp(w); var s = r > 0 ? et * Math.sin(r) / r : 0; out[0] = x * s; out[1] = y * s; out[2] = z * s; out[3] = et * Math.cos(r); return out; } /** * Calculate the natural logarithm of a unit quaternion. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate the exponential of * @returns {quat} out */ function ln(out, a) { var x = a[0], y = a[1], z = a[2], w = a[3]; var r = Math.sqrt(x * x + y * y + z * z); var t = r > 0 ? Math.atan2(r, w) / r : 0; out[0] = x * t; out[1] = y * t; out[2] = z * t; out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w); return out; } /** * Calculate the scalar power of a unit quaternion. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate the exponential of * @param {Number} b amount to scale the quaternion by * @returns {quat} out */ function pow(out, a, b) { ln(out, a); scale(out, out, b); exp(out, out); return out; } /** * Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ function slerp(out, a, b, t) { // benchmarks: // http://jsperf.com/quaternion-slerp-implementations var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var bx = b[0], by = b[1], bz = b[2], bw = b[3]; var omega, cosom, sinom, scale0, scale1; // calc cosine cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) if (cosom < 0.0) { cosom = -cosom; bx = -bx; by = -by; bz = -bz; bw = -bw; } // calculate coefficients if (1.0 - cosom > glMatrix.EPSILON) { // standard case (slerp) omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1.0 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0 = 1.0 - t; scale1 = t; } // calculate final values out[0] = scale0 * ax + scale1 * bx; out[1] = scale0 * ay + scale1 * by; out[2] = scale0 * az + scale1 * bz; out[3] = scale0 * aw + scale1 * bw; return out; } /** * Generates a random unit quaternion * * @param {quat} out the receiving quaternion * @returns {quat} out */ function random(out) { // Implementation of http://planning.cs.uiuc.edu/node198.html // TODO: Calling random 3 times is probably not the fastest solution var u1 = glMatrix.RANDOM(); var u2 = glMatrix.RANDOM(); var u3 = glMatrix.RANDOM(); var sqrt1MinusU1 = Math.sqrt(1 - u1); var sqrtU1 = Math.sqrt(u1); out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2); out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2); out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3); out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3); return out; } /** * Calculates the inverse of a quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate inverse of * @returns {quat} out */ function invert(out, a) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 out[0] = -a0 * invDot; out[1] = -a1 * invDot; out[2] = -a2 * invDot; out[3] = a3 * invDot; return out; } /** * Calculates the conjugate of a quat * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate conjugate of * @returns {quat} out */ function conjugate(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a[3]; return out; } /** * Creates a quaternion from the given 3x3 rotation matrix. * * NOTE: The resultant quaternion is not normalized, so you should be sure * to renormalize the quaternion yourself where necessary. * * @param {quat} out the receiving quaternion * @param {ReadonlyMat3} m rotation matrix * @returns {quat} out * @function */ function fromMat3(out, m) { // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes // article "Quaternion Calculus and Fast Animation". var fTrace = m[0] + m[4] + m[8]; var fRoot; if (fTrace > 0.0) { // |w| > 1/2, may as well choose w > 1/2 fRoot = Math.sqrt(fTrace + 1.0); // 2w out[3] = 0.5 * fRoot; fRoot = 0.5 / fRoot; // 1/(4w) out[0] = (m[5] - m[7]) * fRoot; out[1] = (m[6] - m[2]) * fRoot; out[2] = (m[1] - m[3]) * fRoot; } else { // |w| <= 1/2 var i = 0; if (m[4] > m[0]) i = 1; if (m[8] > m[i * 3 + i]) i = 2; var j = (i + 1) % 3; var k = (i + 2) % 3; fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); out[i] = 0.5 * fRoot; fRoot = 0.5 / fRoot; out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; } return out; } /** * Creates a quaternion from the given euler angle x, y, z. * * @param {quat} out the receiving quaternion * @param {x} Angle to rotate around X axis in degrees. * @param {y} Angle to rotate around Y axis in degrees. * @param {z} Angle to rotate around Z axis in degrees. * @returns {quat} out * @function */ function fromEuler(out, x, y, z) { var halfToRad = 0.5 * Math.PI / 180.0; x *= halfToRad; y *= halfToRad; z *= halfToRad; var sx = Math.sin(x); var cx = Math.cos(x); var sy = Math.sin(y); var cy = Math.cos(y); var sz = Math.sin(z); var cz = Math.cos(z); out[0] = sx * cy * cz - cx * sy * sz; out[1] = cx * sy * cz + sx * cy * sz; out[2] = cx * cy * sz - sx * sy * cz; out[3] = cx * cy * cz + sx * sy * sz; return out; } /** * Returns a string representation of a quatenion * * @param {ReadonlyQuat} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Creates a new quat initialized with values from an existing quaternion * * @param {ReadonlyQuat} a quaternion to clone * @returns {quat} a new quaternion * @function */ var clone = vec4.clone; /** * Creates a new quat initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} a new quaternion * @function */ exports.clone = clone; var fromValues = vec4.fromValues; /** * Copy the values from one quat to another * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the source quaternion * @returns {quat} out * @function */ exports.fromValues = fromValues; var copy = vec4.copy; /** * Set the components of a quat to the given values * * @param {quat} out the receiving quaternion * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} out * @function */ exports.copy = copy; var set = vec4.set; /** * Adds two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {quat} out * @function */ exports.set = set; var add = vec4.add; /** * Alias for {@link quat.multiply} * @function */ exports.add = add; var mul = multiply; /** * Scales a quat by a scalar number * * @param {quat} out the receiving vector * @param {ReadonlyQuat} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {quat} out * @function */ exports.mul = mul; var scale = vec4.scale; /** * Calculates the dot product of two quat's * * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {Number} dot product of a and b * @function */ exports.scale = scale; var dot = vec4.dot; /** * Performs a linear interpolation between two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out * @function */ exports.dot = dot; var lerp = vec4.lerp; /** * Calculates the length of a quat * * @param {ReadonlyQuat} a vector to calculate length of * @returns {Number} length of a */ exports.lerp = lerp; var length = vec4.length; /** * Alias for {@link quat.length} * @function */ exports.length = length; var len = length; /** * Calculates the squared length of a quat * * @param {ReadonlyQuat} a vector to calculate squared length of * @returns {Number} squared length of a * @function */ exports.len = len; var squaredLength = vec4.squaredLength; /** * Alias for {@link quat.squaredLength} * @function */ exports.squaredLength = squaredLength; var sqrLen = squaredLength; /** * Normalize a quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quaternion to normalize * @returns {quat} out * @function */ exports.sqrLen = sqrLen; var normalize = vec4.normalize; /** * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyQuat} a The first quaternion. * @param {ReadonlyQuat} b The second quaternion. * @returns {Boolean} True if the vectors are equal, false otherwise. */ exports.normalize = normalize; var exactEquals = vec4.exactEquals; /** * Returns whether or not the quaternions have approximately the same elements in the same position. * * @param {ReadonlyQuat} a The first vector. * @param {ReadonlyQuat} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ exports.exactEquals = exactEquals; var equals = vec4.equals; /** * Sets a quaternion to represent the shortest rotation from one * vector to another. * * Both vectors are assumed to be unit length. * * @param {quat} out the receiving quaternion. * @param {ReadonlyVec3} a the initial vector * @param {ReadonlyVec3} b the destination vector * @returns {quat} out */ exports.equals = equals; var rotationTo = function () { var tmpvec3 = vec3.create(); var xUnitVec3 = vec3.fromValues(1, 0, 0); var yUnitVec3 = vec3.fromValues(0, 1, 0); return function (out, a, b) { var dot = vec3.dot(a, b); if (dot < -0.999999) { vec3.cross(tmpvec3, xUnitVec3, a); if (vec3.len(tmpvec3) < 0.000001) vec3.cross(tmpvec3, yUnitVec3, a); vec3.normalize(tmpvec3, tmpvec3); setAxisAngle(out, tmpvec3, Math.PI); return out; } else if (dot > 0.999999) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } else { vec3.cross(tmpvec3, a, b); out[0] = tmpvec3[0]; out[1] = tmpvec3[1]; out[2] = tmpvec3[2]; out[3] = 1 + dot; return normalize(out, out); } }; }(); /** * Performs a spherical linear interpolation with two control points * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {ReadonlyQuat} c the third operand * @param {ReadonlyQuat} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ exports.rotationTo = rotationTo; var sqlerp = function () { var temp1 = create(); var temp2 = create(); return function (out, a, b, c, d, t) { slerp(temp1, a, d, t); slerp(temp2, b, c, t); slerp(out, temp1, temp2, 2 * t * (1 - t)); return out; }; }(); /** * Sets the specified quaternion with values corresponding to the given * axes. Each axis is a vec3 and is expected to be unit length and * perpendicular to all other specified axes. * * @param {ReadonlyVec3} view the vector representing the viewing direction * @param {ReadonlyVec3} right the vector representing the local "right" direction * @param {ReadonlyVec3} up the vector representing the local "up" direction * @returns {quat} out */ exports.sqlerp = sqlerp; var setAxes = function () { var matr = mat3.create(); return function (out, view, right, up) { matr[0] = right[0]; matr[3] = right[1]; matr[6] = right[2]; matr[1] = up[0]; matr[4] = up[1]; matr[7] = up[2]; matr[2] = -view[0]; matr[5] = -view[1]; matr[8] = -view[2]; return normalize(out, fromMat3(out, matr)); }; }(); exports.setAxes = setAxes; },{"./common.js":882,"./mat3.js":886,"./vec3.js":891,"./vec4.js":892}],889:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.fromValues = fromValues; exports.fromRotationTranslationValues = fromRotationTranslationValues; exports.fromRotationTranslation = fromRotationTranslation; exports.fromTranslation = fromTranslation; exports.fromRotation = fromRotation; exports.fromMat4 = fromMat4; exports.copy = copy; exports.identity = identity; exports.set = set; exports.getDual = getDual; exports.setDual = setDual; exports.getTranslation = getTranslation; exports.translate = translate; exports.rotateX = rotateX; exports.rotateY = rotateY; exports.rotateZ = rotateZ; exports.rotateByQuatAppend = rotateByQuatAppend; exports.rotateByQuatPrepend = rotateByQuatPrepend; exports.rotateAroundAxis = rotateAroundAxis; exports.add = add; exports.multiply = multiply; exports.scale = scale; exports.lerp = lerp; exports.invert = invert; exports.conjugate = conjugate; exports.normalize = normalize; exports.str = str; exports.exactEquals = exactEquals; exports.equals = equals; exports.sqrLen = exports.squaredLength = exports.len = exports.length = exports.dot = exports.mul = exports.setReal = exports.getReal = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); var quat = _interopRequireWildcard(require("./quat.js")); var mat4 = _interopRequireWildcard(require("./mat4.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * Dual Quaternion
      * Format: [real, dual]
      * Quaternion format: XYZW
      * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.
      * @module quat2 */ /** * Creates a new identity dual quat * * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation] */ function create() { var dq = new glMatrix.ARRAY_TYPE(8); if (glMatrix.ARRAY_TYPE != Float32Array) { dq[0] = 0; dq[1] = 0; dq[2] = 0; dq[4] = 0; dq[5] = 0; dq[6] = 0; dq[7] = 0; } dq[3] = 1; return dq; } /** * Creates a new quat initialized with values from an existing quaternion * * @param {ReadonlyQuat2} a dual quaternion to clone * @returns {quat2} new dual quaternion * @function */ function clone(a) { var dq = new glMatrix.ARRAY_TYPE(8); dq[0] = a[0]; dq[1] = a[1]; dq[2] = a[2]; dq[3] = a[3]; dq[4] = a[4]; dq[5] = a[5]; dq[6] = a[6]; dq[7] = a[7]; return dq; } /** * Creates a new dual quat initialized with the given values * * @param {Number} x1 X component * @param {Number} y1 Y component * @param {Number} z1 Z component * @param {Number} w1 W component * @param {Number} x2 X component * @param {Number} y2 Y component * @param {Number} z2 Z component * @param {Number} w2 W component * @returns {quat2} new dual quaternion * @function */ function fromValues(x1, y1, z1, w1, x2, y2, z2, w2) { var dq = new glMatrix.ARRAY_TYPE(8); dq[0] = x1; dq[1] = y1; dq[2] = z1; dq[3] = w1; dq[4] = x2; dq[5] = y2; dq[6] = z2; dq[7] = w2; return dq; } /** * Creates a new dual quat from the given values (quat and translation) * * @param {Number} x1 X component * @param {Number} y1 Y component * @param {Number} z1 Z component * @param {Number} w1 W component * @param {Number} x2 X component (translation) * @param {Number} y2 Y component (translation) * @param {Number} z2 Z component (translation) * @returns {quat2} new dual quaternion * @function */ function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) { var dq = new glMatrix.ARRAY_TYPE(8); dq[0] = x1; dq[1] = y1; dq[2] = z1; dq[3] = w1; var ax = x2 * 0.5, ay = y2 * 0.5, az = z2 * 0.5; dq[4] = ax * w1 + ay * z1 - az * y1; dq[5] = ay * w1 + az * x1 - ax * z1; dq[6] = az * w1 + ax * y1 - ay * x1; dq[7] = -ax * x1 - ay * y1 - az * z1; return dq; } /** * Creates a dual quat from a quaternion and a translation * * @param {ReadonlyQuat2} dual quaternion receiving operation result * @param {ReadonlyQuat} q a normalized quaternion * @param {ReadonlyVec3} t tranlation vector * @returns {quat2} dual quaternion receiving operation result * @function */ function fromRotationTranslation(out, q, t) { var ax = t[0] * 0.5, ay = t[1] * 0.5, az = t[2] * 0.5, bx = q[0], by = q[1], bz = q[2], bw = q[3]; out[0] = bx; out[1] = by; out[2] = bz; out[3] = bw; out[4] = ax * bw + ay * bz - az * by; out[5] = ay * bw + az * bx - ax * bz; out[6] = az * bw + ax * by - ay * bx; out[7] = -ax * bx - ay * by - az * bz; return out; } /** * Creates a dual quat from a translation * * @param {ReadonlyQuat2} dual quaternion receiving operation result * @param {ReadonlyVec3} t translation vector * @returns {quat2} dual quaternion receiving operation result * @function */ function fromTranslation(out, t) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = t[0] * 0.5; out[5] = t[1] * 0.5; out[6] = t[2] * 0.5; out[7] = 0; return out; } /** * Creates a dual quat from a quaternion * * @param {ReadonlyQuat2} dual quaternion receiving operation result * @param {ReadonlyQuat} q the quaternion * @returns {quat2} dual quaternion receiving operation result * @function */ function fromRotation(out, q) { out[0] = q[0]; out[1] = q[1]; out[2] = q[2]; out[3] = q[3]; out[4] = 0; out[5] = 0; out[6] = 0; out[7] = 0; return out; } /** * Creates a new dual quat from a matrix (4x4) * * @param {quat2} out the dual quaternion * @param {ReadonlyMat4} a the matrix * @returns {quat2} dual quat receiving operation result * @function */ function fromMat4(out, a) { //TODO Optimize this var outer = quat.create(); mat4.getRotation(outer, a); var t = new glMatrix.ARRAY_TYPE(3); mat4.getTranslation(t, a); fromRotationTranslation(out, outer, t); return out; } /** * Copy the values from one dual quat to another * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the source dual quaternion * @returns {quat2} out * @function */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; return out; } /** * Set a dual quat to the identity dual quaternion * * @param {quat2} out the receiving quaternion * @returns {quat2} out */ function identity(out) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; out[4] = 0; out[5] = 0; out[6] = 0; out[7] = 0; return out; } /** * Set the components of a dual quat to the given values * * @param {quat2} out the receiving quaternion * @param {Number} x1 X component * @param {Number} y1 Y component * @param {Number} z1 Z component * @param {Number} w1 W component * @param {Number} x2 X component * @param {Number} y2 Y component * @param {Number} z2 Z component * @param {Number} w2 W component * @returns {quat2} out * @function */ function set(out, x1, y1, z1, w1, x2, y2, z2, w2) { out[0] = x1; out[1] = y1; out[2] = z1; out[3] = w1; out[4] = x2; out[5] = y2; out[6] = z2; out[7] = w2; return out; } /** * Gets the real part of a dual quat * @param {quat} out real part * @param {ReadonlyQuat2} a Dual Quaternion * @return {quat} real part */ var getReal = quat.copy; /** * Gets the dual part of a dual quat * @param {quat} out dual part * @param {ReadonlyQuat2} a Dual Quaternion * @return {quat} dual part */ exports.getReal = getReal; function getDual(out, a) { out[0] = a[4]; out[1] = a[5]; out[2] = a[6]; out[3] = a[7]; return out; } /** * Set the real component of a dual quat to the given quaternion * * @param {quat2} out the receiving quaternion * @param {ReadonlyQuat} q a quaternion representing the real part * @returns {quat2} out * @function */ var setReal = quat.copy; /** * Set the dual component of a dual quat to the given quaternion * * @param {quat2} out the receiving quaternion * @param {ReadonlyQuat} q a quaternion representing the dual part * @returns {quat2} out * @function */ exports.setReal = setReal; function setDual(out, q) { out[4] = q[0]; out[5] = q[1]; out[6] = q[2]; out[7] = q[3]; return out; } /** * Gets the translation of a normalized dual quat * @param {vec3} out translation * @param {ReadonlyQuat2} a Dual Quaternion to be decomposed * @return {vec3} translation */ function getTranslation(out, a) { var ax = a[4], ay = a[5], az = a[6], aw = a[7], bx = -a[0], by = -a[1], bz = -a[2], bw = a[3]; out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; return out; } /** * Translates a dual quat by the given vector * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the dual quaternion to translate * @param {ReadonlyVec3} v vector to translate by * @returns {quat2} out */ function translate(out, a, v) { var ax1 = a[0], ay1 = a[1], az1 = a[2], aw1 = a[3], bx1 = v[0] * 0.5, by1 = v[1] * 0.5, bz1 = v[2] * 0.5, ax2 = a[4], ay2 = a[5], az2 = a[6], aw2 = a[7]; out[0] = ax1; out[1] = ay1; out[2] = az1; out[3] = aw1; out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2; out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2; out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2; out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2; return out; } /** * Rotates a dual quat around the X axis * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {number} rad how far should the rotation be * @returns {quat2} out */ function rotateX(out, a, rad) { var bx = -a[0], by = -a[1], bz = -a[2], bw = a[3], ax = a[4], ay = a[5], az = a[6], aw = a[7], ax1 = ax * bw + aw * bx + ay * bz - az * by, ay1 = ay * bw + aw * by + az * bx - ax * bz, az1 = az * bw + aw * bz + ax * by - ay * bx, aw1 = aw * bw - ax * bx - ay * by - az * bz; quat.rotateX(out, a, rad); bx = out[0]; by = out[1]; bz = out[2]; bw = out[3]; out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; return out; } /** * Rotates a dual quat around the Y axis * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {number} rad how far should the rotation be * @returns {quat2} out */ function rotateY(out, a, rad) { var bx = -a[0], by = -a[1], bz = -a[2], bw = a[3], ax = a[4], ay = a[5], az = a[6], aw = a[7], ax1 = ax * bw + aw * bx + ay * bz - az * by, ay1 = ay * bw + aw * by + az * bx - ax * bz, az1 = az * bw + aw * bz + ax * by - ay * bx, aw1 = aw * bw - ax * bx - ay * by - az * bz; quat.rotateY(out, a, rad); bx = out[0]; by = out[1]; bz = out[2]; bw = out[3]; out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; return out; } /** * Rotates a dual quat around the Z axis * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {number} rad how far should the rotation be * @returns {quat2} out */ function rotateZ(out, a, rad) { var bx = -a[0], by = -a[1], bz = -a[2], bw = a[3], ax = a[4], ay = a[5], az = a[6], aw = a[7], ax1 = ax * bw + aw * bx + ay * bz - az * by, ay1 = ay * bw + aw * by + az * bx - ax * bz, az1 = az * bw + aw * bz + ax * by - ay * bx, aw1 = aw * bw - ax * bx - ay * by - az * bz; quat.rotateZ(out, a, rad); bx = out[0]; by = out[1]; bz = out[2]; bw = out[3]; out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; return out; } /** * Rotates a dual quat by a given quaternion (a * q) * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {ReadonlyQuat} q quaternion to rotate by * @returns {quat2} out */ function rotateByQuatAppend(out, a, q) { var qx = q[0], qy = q[1], qz = q[2], qw = q[3], ax = a[0], ay = a[1], az = a[2], aw = a[3]; out[0] = ax * qw + aw * qx + ay * qz - az * qy; out[1] = ay * qw + aw * qy + az * qx - ax * qz; out[2] = az * qw + aw * qz + ax * qy - ay * qx; out[3] = aw * qw - ax * qx - ay * qy - az * qz; ax = a[4]; ay = a[5]; az = a[6]; aw = a[7]; out[4] = ax * qw + aw * qx + ay * qz - az * qy; out[5] = ay * qw + aw * qy + az * qx - ax * qz; out[6] = az * qw + aw * qz + ax * qy - ay * qx; out[7] = aw * qw - ax * qx - ay * qy - az * qz; return out; } /** * Rotates a dual quat by a given quaternion (q * a) * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat} q quaternion to rotate by * @param {ReadonlyQuat2} a the dual quaternion to rotate * @returns {quat2} out */ function rotateByQuatPrepend(out, q, a) { var qx = q[0], qy = q[1], qz = q[2], qw = q[3], bx = a[0], by = a[1], bz = a[2], bw = a[3]; out[0] = qx * bw + qw * bx + qy * bz - qz * by; out[1] = qy * bw + qw * by + qz * bx - qx * bz; out[2] = qz * bw + qw * bz + qx * by - qy * bx; out[3] = qw * bw - qx * bx - qy * by - qz * bz; bx = a[4]; by = a[5]; bz = a[6]; bw = a[7]; out[4] = qx * bw + qw * bx + qy * bz - qz * by; out[5] = qy * bw + qw * by + qz * bx - qx * bz; out[6] = qz * bw + qw * bz + qx * by - qy * bx; out[7] = qw * bw - qx * bx - qy * by - qz * bz; return out; } /** * Rotates a dual quat around a given axis. Does the normalisation automatically * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {ReadonlyVec3} axis the axis to rotate around * @param {Number} rad how far the rotation should be * @returns {quat2} out */ function rotateAroundAxis(out, a, axis, rad) { //Special case for rad = 0 if (Math.abs(rad) < glMatrix.EPSILON) { return copy(out, a); } var axisLength = Math.hypot(axis[0], axis[1], axis[2]); rad = rad * 0.5; var s = Math.sin(rad); var bx = s * axis[0] / axisLength; var by = s * axis[1] / axisLength; var bz = s * axis[2] / axisLength; var bw = Math.cos(rad); var ax1 = a[0], ay1 = a[1], az1 = a[2], aw1 = a[3]; out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; var ax = a[4], ay = a[5], az = a[6], aw = a[7]; out[4] = ax * bw + aw * bx + ay * bz - az * by; out[5] = ay * bw + aw * by + az * bx - ax * bz; out[6] = az * bw + aw * bz + ax * by - ay * bx; out[7] = aw * bw - ax * bx - ay * by - az * bz; return out; } /** * Adds two dual quat's * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the first operand * @param {ReadonlyQuat2} b the second operand * @returns {quat2} out * @function */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; return out; } /** * Multiplies two dual quat's * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a the first operand * @param {ReadonlyQuat2} b the second operand * @returns {quat2} out */ function multiply(out, a, b) { var ax0 = a[0], ay0 = a[1], az0 = a[2], aw0 = a[3], bx1 = b[4], by1 = b[5], bz1 = b[6], bw1 = b[7], ax1 = a[4], ay1 = a[5], az1 = a[6], aw1 = a[7], bx0 = b[0], by0 = b[1], bz0 = b[2], bw0 = b[3]; out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0; out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0; out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0; out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0; out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0; out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0; out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0; out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0; return out; } /** * Alias for {@link quat2.multiply} * @function */ var mul = multiply; /** * Scales a dual quat by a scalar number * * @param {quat2} out the receiving dual quat * @param {ReadonlyQuat2} a the dual quat to scale * @param {Number} b amount to scale the dual quat by * @returns {quat2} out * @function */ exports.mul = mul; function scale(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; out[4] = a[4] * b; out[5] = a[5] * b; out[6] = a[6] * b; out[7] = a[7] * b; return out; } /** * Calculates the dot product of two dual quat's (The dot product of the real parts) * * @param {ReadonlyQuat2} a the first operand * @param {ReadonlyQuat2} b the second operand * @returns {Number} dot product of a and b * @function */ var dot = quat.dot; /** * Performs a linear interpolation between two dual quats's * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5) * * @param {quat2} out the receiving dual quat * @param {ReadonlyQuat2} a the first operand * @param {ReadonlyQuat2} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat2} out */ exports.dot = dot; function lerp(out, a, b, t) { var mt = 1 - t; if (dot(a, b) < 0) t = -t; out[0] = a[0] * mt + b[0] * t; out[1] = a[1] * mt + b[1] * t; out[2] = a[2] * mt + b[2] * t; out[3] = a[3] * mt + b[3] * t; out[4] = a[4] * mt + b[4] * t; out[5] = a[5] * mt + b[5] * t; out[6] = a[6] * mt + b[6] * t; out[7] = a[7] * mt + b[7] * t; return out; } /** * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a dual quat to calculate inverse of * @returns {quat2} out */ function invert(out, a) { var sqlen = squaredLength(a); out[0] = -a[0] / sqlen; out[1] = -a[1] / sqlen; out[2] = -a[2] / sqlen; out[3] = a[3] / sqlen; out[4] = -a[4] / sqlen; out[5] = -a[5] / sqlen; out[6] = -a[6] / sqlen; out[7] = a[7] / sqlen; return out; } /** * Calculates the conjugate of a dual quat * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result. * * @param {quat2} out the receiving quaternion * @param {ReadonlyQuat2} a quat to calculate conjugate of * @returns {quat2} out */ function conjugate(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a[3]; out[4] = -a[4]; out[5] = -a[5]; out[6] = -a[6]; out[7] = a[7]; return out; } /** * Calculates the length of a dual quat * * @param {ReadonlyQuat2} a dual quat to calculate length of * @returns {Number} length of a * @function */ var length = quat.length; /** * Alias for {@link quat2.length} * @function */ exports.length = length; var len = length; /** * Calculates the squared length of a dual quat * * @param {ReadonlyQuat2} a dual quat to calculate squared length of * @returns {Number} squared length of a * @function */ exports.len = len; var squaredLength = quat.squaredLength; /** * Alias for {@link quat2.squaredLength} * @function */ exports.squaredLength = squaredLength; var sqrLen = squaredLength; /** * Normalize a dual quat * * @param {quat2} out the receiving dual quaternion * @param {ReadonlyQuat2} a dual quaternion to normalize * @returns {quat2} out * @function */ exports.sqrLen = sqrLen; function normalize(out, a) { var magnitude = squaredLength(a); if (magnitude > 0) { magnitude = Math.sqrt(magnitude); var a0 = a[0] / magnitude; var a1 = a[1] / magnitude; var a2 = a[2] / magnitude; var a3 = a[3] / magnitude; var b0 = a[4]; var b1 = a[5]; var b2 = a[6]; var b3 = a[7]; var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3; out[0] = a0; out[1] = a1; out[2] = a2; out[3] = a3; out[4] = (b0 - a0 * a_dot_b) / magnitude; out[5] = (b1 - a1 * a_dot_b) / magnitude; out[6] = (b2 - a2 * a_dot_b) / magnitude; out[7] = (b3 - a3 * a_dot_b) / magnitude; } return out; } /** * Returns a string representation of a dual quatenion * * @param {ReadonlyQuat2} a dual quaternion to represent as a string * @returns {String} string representation of the dual quat */ function str(a) { return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")"; } /** * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyQuat2} a the first dual quaternion. * @param {ReadonlyQuat2} b the second dual quaternion. * @returns {Boolean} true if the dual quaternions are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7]; } /** * Returns whether or not the dual quaternions have approximately the same elements in the same position. * * @param {ReadonlyQuat2} a the first dual quat. * @param {ReadonlyQuat2} b the second dual quat. * @returns {Boolean} true if the dual quats are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)); } },{"./common.js":882,"./mat4.js":887,"./quat.js":888}],890:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.fromValues = fromValues; exports.copy = copy; exports.set = set; exports.add = add; exports.subtract = subtract; exports.multiply = multiply; exports.divide = divide; exports.ceil = ceil; exports.floor = floor; exports.min = min; exports.max = max; exports.round = round; exports.scale = scale; exports.scaleAndAdd = scaleAndAdd; exports.distance = distance; exports.squaredDistance = squaredDistance; exports.length = length; exports.squaredLength = squaredLength; exports.negate = negate; exports.inverse = inverse; exports.normalize = normalize; exports.dot = dot; exports.cross = cross; exports.lerp = lerp; exports.random = random; exports.transformMat2 = transformMat2; exports.transformMat2d = transformMat2d; exports.transformMat3 = transformMat3; exports.transformMat4 = transformMat4; exports.rotate = rotate; exports.angle = angle; exports.zero = zero; exports.str = str; exports.exactEquals = exactEquals; exports.equals = equals; exports.forEach = exports.sqrLen = exports.sqrDist = exports.dist = exports.div = exports.mul = exports.sub = exports.len = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 2 Dimensional Vector * @module vec2 */ /** * Creates a new, empty vec2 * * @returns {vec2} a new 2D vector */ function create() { var out = new glMatrix.ARRAY_TYPE(2); if (glMatrix.ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; } return out; } /** * Creates a new vec2 initialized with values from an existing vector * * @param {ReadonlyVec2} a vector to clone * @returns {vec2} a new 2D vector */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(2); out[0] = a[0]; out[1] = a[1]; return out; } /** * Creates a new vec2 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @returns {vec2} a new 2D vector */ function fromValues(x, y) { var out = new glMatrix.ARRAY_TYPE(2); out[0] = x; out[1] = y; return out; } /** * Copy the values from one vec2 to another * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the source vector * @returns {vec2} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; return out; } /** * Set the components of a vec2 to the given values * * @param {vec2} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @returns {vec2} out */ function set(out, x, y) { out[0] = x; out[1] = y; return out; } /** * Adds two vec2's * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; return out; } /** * Subtracts vector b from vector a * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; return out; } /** * Multiplies two vec2's * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ function multiply(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; return out; } /** * Divides two vec2's * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ function divide(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; return out; } /** * Math.ceil the components of a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to ceil * @returns {vec2} out */ function ceil(out, a) { out[0] = Math.ceil(a[0]); out[1] = Math.ceil(a[1]); return out; } /** * Math.floor the components of a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to floor * @returns {vec2} out */ function floor(out, a) { out[0] = Math.floor(a[0]); out[1] = Math.floor(a[1]); return out; } /** * Returns the minimum of two vec2's * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ function min(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); return out; } /** * Returns the maximum of two vec2's * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ function max(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); return out; } /** * Math.round the components of a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to round * @returns {vec2} out */ function round(out, a) { out[0] = Math.round(a[0]); out[1] = Math.round(a[1]); return out; } /** * Scales a vec2 by a scalar number * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec2} out */ function scale(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; return out; } /** * Adds two vec2's after scaling the second operand by a scalar value * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec2} out */ function scaleAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; return out; } /** * Calculates the euclidian distance between two vec2's * * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {Number} distance between a and b */ function distance(a, b) { var x = b[0] - a[0], y = b[1] - a[1]; return Math.hypot(x, y); } /** * Calculates the squared euclidian distance between two vec2's * * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {Number} squared distance between a and b */ function squaredDistance(a, b) { var x = b[0] - a[0], y = b[1] - a[1]; return x * x + y * y; } /** * Calculates the length of a vec2 * * @param {ReadonlyVec2} a vector to calculate length of * @returns {Number} length of a */ function length(a) { var x = a[0], y = a[1]; return Math.hypot(x, y); } /** * Calculates the squared length of a vec2 * * @param {ReadonlyVec2} a vector to calculate squared length of * @returns {Number} squared length of a */ function squaredLength(a) { var x = a[0], y = a[1]; return x * x + y * y; } /** * Negates the components of a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to negate * @returns {vec2} out */ function negate(out, a) { out[0] = -a[0]; out[1] = -a[1]; return out; } /** * Returns the inverse of the components of a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to invert * @returns {vec2} out */ function inverse(out, a) { out[0] = 1.0 / a[0]; out[1] = 1.0 / a[1]; return out; } /** * Normalize a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to normalize * @returns {vec2} out */ function normalize(out, a) { var x = a[0], y = a[1]; var len = x * x + y * y; if (len > 0) { //TODO: evaluate use of glm_invsqrt here? len = 1 / Math.sqrt(len); } out[0] = a[0] * len; out[1] = a[1] * len; return out; } /** * Calculates the dot product of two vec2's * * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {Number} dot product of a and b */ function dot(a, b) { return a[0] * b[0] + a[1] * b[1]; } /** * Computes the cross product of two vec2's * Note that the cross product must by definition produce a 3D vector * * @param {vec3} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {vec3} out */ function cross(out, a, b) { var z = a[0] * b[1] - a[1] * b[0]; out[0] = out[1] = 0; out[2] = z; return out; } /** * Performs a linear interpolation between two vec2's * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec2} out */ function lerp(out, a, b, t) { var ax = a[0], ay = a[1]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); return out; } /** * Generates a random vector with the given scale * * @param {vec2} out the receiving vector * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned * @returns {vec2} out */ function random(out, scale) { scale = scale || 1.0; var r = glMatrix.RANDOM() * 2.0 * Math.PI; out[0] = Math.cos(r) * scale; out[1] = Math.sin(r) * scale; return out; } /** * Transforms the vec2 with a mat2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the vector to transform * @param {ReadonlyMat2} m matrix to transform with * @returns {vec2} out */ function transformMat2(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[2] * y; out[1] = m[1] * x + m[3] * y; return out; } /** * Transforms the vec2 with a mat2d * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the vector to transform * @param {ReadonlyMat2d} m matrix to transform with * @returns {vec2} out */ function transformMat2d(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[2] * y + m[4]; out[1] = m[1] * x + m[3] * y + m[5]; return out; } /** * Transforms the vec2 with a mat3 * 3rd vector component is implicitly '1' * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the vector to transform * @param {ReadonlyMat3} m matrix to transform with * @returns {vec2} out */ function transformMat3(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[3] * y + m[6]; out[1] = m[1] * x + m[4] * y + m[7]; return out; } /** * Transforms the vec2 with a mat4 * 3rd vector component is implicitly '0' * 4th vector component is implicitly '1' * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec2} out */ function transformMat4(out, a, m) { var x = a[0]; var y = a[1]; out[0] = m[0] * x + m[4] * y + m[12]; out[1] = m[1] * x + m[5] * y + m[13]; return out; } /** * Rotate a 2D vector * @param {vec2} out The receiving vec2 * @param {ReadonlyVec2} a The vec2 point to rotate * @param {ReadonlyVec2} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec2} out */ function rotate(out, a, b, rad) { //Translate point to the origin var p0 = a[0] - b[0], p1 = a[1] - b[1], sinC = Math.sin(rad), cosC = Math.cos(rad); //perform rotation and translate to correct position out[0] = p0 * cosC - p1 * sinC + b[0]; out[1] = p0 * sinC + p1 * cosC + b[1]; return out; } /** * Get the angle between two 2D vectors * @param {ReadonlyVec2} a The first operand * @param {ReadonlyVec2} b The second operand * @returns {Number} The angle in radians */ function angle(a, b) { var x1 = a[0], y1 = a[1], x2 = b[0], y2 = b[1], // mag is the product of the magnitudes of a and b mag = Math.sqrt(x1 * x1 + y1 * y1) * Math.sqrt(x2 * x2 + y2 * y2), // mag &&.. short circuits if mag == 0 cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1 return Math.acos(Math.min(Math.max(cosine, -1), 1)); } /** * Set the components of a vec2 to zero * * @param {vec2} out the receiving vector * @returns {vec2} out */ function zero(out) { out[0] = 0.0; out[1] = 0.0; return out; } /** * Returns a string representation of a vector * * @param {ReadonlyVec2} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { return "vec2(" + a[0] + ", " + a[1] + ")"; } /** * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) * * @param {ReadonlyVec2} a The first vector. * @param {ReadonlyVec2} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1]; } /** * Returns whether or not the vectors have approximately the same elements in the same position. * * @param {ReadonlyVec2} a The first vector. * @param {ReadonlyVec2} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1]; var b0 = b[0], b1 = b[1]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)); } /** * Alias for {@link vec2.length} * @function */ var len = length; /** * Alias for {@link vec2.subtract} * @function */ exports.len = len; var sub = subtract; /** * Alias for {@link vec2.multiply} * @function */ exports.sub = sub; var mul = multiply; /** * Alias for {@link vec2.divide} * @function */ exports.mul = mul; var div = divide; /** * Alias for {@link vec2.distance} * @function */ exports.div = div; var dist = distance; /** * Alias for {@link vec2.squaredDistance} * @function */ exports.dist = dist; var sqrDist = squaredDistance; /** * Alias for {@link vec2.squaredLength} * @function */ exports.sqrDist = sqrDist; var sqrLen = squaredLength; /** * Perform some operation over an array of vec2s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ exports.sqrLen = sqrLen; var forEach = function () { var vec = create(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 2; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; } return a; }; }(); exports.forEach = forEach; },{"./common.js":882}],891:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.length = length; exports.fromValues = fromValues; exports.copy = copy; exports.set = set; exports.add = add; exports.subtract = subtract; exports.multiply = multiply; exports.divide = divide; exports.ceil = ceil; exports.floor = floor; exports.min = min; exports.max = max; exports.round = round; exports.scale = scale; exports.scaleAndAdd = scaleAndAdd; exports.distance = distance; exports.squaredDistance = squaredDistance; exports.squaredLength = squaredLength; exports.negate = negate; exports.inverse = inverse; exports.normalize = normalize; exports.dot = dot; exports.cross = cross; exports.lerp = lerp; exports.hermite = hermite; exports.bezier = bezier; exports.random = random; exports.transformMat4 = transformMat4; exports.transformMat3 = transformMat3; exports.transformQuat = transformQuat; exports.rotateX = rotateX; exports.rotateY = rotateY; exports.rotateZ = rotateZ; exports.angle = angle; exports.zero = zero; exports.str = str; exports.exactEquals = exactEquals; exports.equals = equals; exports.forEach = exports.sqrLen = exports.len = exports.sqrDist = exports.dist = exports.div = exports.mul = exports.sub = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 3 Dimensional Vector * @module vec3 */ /** * Creates a new, empty vec3 * * @returns {vec3} a new 3D vector */ function create() { var out = new glMatrix.ARRAY_TYPE(3); if (glMatrix.ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } return out; } /** * Creates a new vec3 initialized with values from an existing vector * * @param {ReadonlyVec3} a vector to clone * @returns {vec3} a new 3D vector */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(3); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } /** * Calculates the length of a vec3 * * @param {ReadonlyVec3} a vector to calculate length of * @returns {Number} length of a */ function length(a) { var x = a[0]; var y = a[1]; var z = a[2]; return Math.hypot(x, y, z); } /** * Creates a new vec3 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} a new 3D vector */ function fromValues(x, y, z) { var out = new glMatrix.ARRAY_TYPE(3); out[0] = x; out[1] = y; out[2] = z; return out; } /** * Copy the values from one vec3 to another * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the source vector * @returns {vec3} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } /** * Set the components of a vec3 to the given values * * @param {vec3} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} out */ function set(out, x, y, z) { out[0] = x; out[1] = y; out[2] = z; return out; } /** * Adds two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; return out; } /** * Subtracts vector b from vector a * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; return out; } /** * Multiplies two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function multiply(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; return out; } /** * Divides two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function divide(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; out[2] = a[2] / b[2]; return out; } /** * Math.ceil the components of a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to ceil * @returns {vec3} out */ function ceil(out, a) { out[0] = Math.ceil(a[0]); out[1] = Math.ceil(a[1]); out[2] = Math.ceil(a[2]); return out; } /** * Math.floor the components of a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to floor * @returns {vec3} out */ function floor(out, a) { out[0] = Math.floor(a[0]); out[1] = Math.floor(a[1]); out[2] = Math.floor(a[2]); return out; } /** * Returns the minimum of two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function min(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); out[2] = Math.min(a[2], b[2]); return out; } /** * Returns the maximum of two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function max(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); out[2] = Math.max(a[2], b[2]); return out; } /** * Math.round the components of a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to round * @returns {vec3} out */ function round(out, a) { out[0] = Math.round(a[0]); out[1] = Math.round(a[1]); out[2] = Math.round(a[2]); return out; } /** * Scales a vec3 by a scalar number * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec3} out */ function scale(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; return out; } /** * Adds two vec3's after scaling the second operand by a scalar value * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec3} out */ function scaleAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; return out; } /** * Calculates the euclidian distance between two vec3's * * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {Number} distance between a and b */ function distance(a, b) { var x = b[0] - a[0]; var y = b[1] - a[1]; var z = b[2] - a[2]; return Math.hypot(x, y, z); } /** * Calculates the squared euclidian distance between two vec3's * * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {Number} squared distance between a and b */ function squaredDistance(a, b) { var x = b[0] - a[0]; var y = b[1] - a[1]; var z = b[2] - a[2]; return x * x + y * y + z * z; } /** * Calculates the squared length of a vec3 * * @param {ReadonlyVec3} a vector to calculate squared length of * @returns {Number} squared length of a */ function squaredLength(a) { var x = a[0]; var y = a[1]; var z = a[2]; return x * x + y * y + z * z; } /** * Negates the components of a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to negate * @returns {vec3} out */ function negate(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; return out; } /** * Returns the inverse of the components of a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to invert * @returns {vec3} out */ function inverse(out, a) { out[0] = 1.0 / a[0]; out[1] = 1.0 / a[1]; out[2] = 1.0 / a[2]; return out; } /** * Normalize a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to normalize * @returns {vec3} out */ function normalize(out, a) { var x = a[0]; var y = a[1]; var z = a[2]; var len = x * x + y * y + z * z; if (len > 0) { //TODO: evaluate use of glm_invsqrt here? len = 1 / Math.sqrt(len); } out[0] = a[0] * len; out[1] = a[1] * len; out[2] = a[2] * len; return out; } /** * Calculates the dot product of two vec3's * * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {Number} dot product of a and b */ function dot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } /** * Computes the cross product of two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function cross(out, a, b) { var ax = a[0], ay = a[1], az = a[2]; var bx = b[0], by = b[1], bz = b[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } /** * Performs a linear interpolation between two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ function lerp(out, a, b, t) { var ax = a[0]; var ay = a[1]; var az = a[2]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); return out; } /** * Performs a hermite interpolation with two control points * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @param {ReadonlyVec3} c the third operand * @param {ReadonlyVec3} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ function hermite(out, a, b, c, d, t) { var factorTimes2 = t * t; var factor1 = factorTimes2 * (2 * t - 3) + 1; var factor2 = factorTimes2 * (t - 2) + t; var factor3 = factorTimes2 * (t - 1); var factor4 = factorTimes2 * (3 - 2 * t); out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; return out; } /** * Performs a bezier interpolation with two control points * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @param {ReadonlyVec3} c the third operand * @param {ReadonlyVec3} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ function bezier(out, a, b, c, d, t) { var inverseFactor = 1 - t; var inverseFactorTimesTwo = inverseFactor * inverseFactor; var factorTimes2 = t * t; var factor1 = inverseFactorTimesTwo * inverseFactor; var factor2 = 3 * t * inverseFactorTimesTwo; var factor3 = 3 * factorTimes2 * inverseFactor; var factor4 = factorTimes2 * t; out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; return out; } /** * Generates a random vector with the given scale * * @param {vec3} out the receiving vector * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned * @returns {vec3} out */ function random(out, scale) { scale = scale || 1.0; var r = glMatrix.RANDOM() * 2.0 * Math.PI; var z = glMatrix.RANDOM() * 2.0 - 1.0; var zScale = Math.sqrt(1.0 - z * z) * scale; out[0] = Math.cos(r) * zScale; out[1] = Math.sin(r) * zScale; out[2] = z * scale; return out; } /** * Transforms the vec3 with a mat4. * 4th vector component is implicitly '1' * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec3} out */ function transformMat4(out, a, m) { var x = a[0], y = a[1], z = a[2]; var w = m[3] * x + m[7] * y + m[11] * z + m[15]; w = w || 1.0; out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; return out; } /** * Transforms the vec3 with a mat3. * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyMat3} m the 3x3 matrix to transform with * @returns {vec3} out */ function transformMat3(out, a, m) { var x = a[0], y = a[1], z = a[2]; out[0] = x * m[0] + y * m[3] + z * m[6]; out[1] = x * m[1] + y * m[4] + z * m[7]; out[2] = x * m[2] + y * m[5] + z * m[8]; return out; } /** * Transforms the vec3 with a quat * Can also be used for dual quaternions. (Multiply it with the real part) * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec3} out */ function transformQuat(out, a, q) { // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; var x = a[0], y = a[1], z = a[2]; // var qvec = [qx, qy, qz]; // var uv = vec3.cross([], qvec, a); var uvx = qy * z - qz * y, uvy = qz * x - qx * z, uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); var uuvx = qy * uvz - qz * uvy, uuvy = qz * uvx - qx * uvz, uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); var w2 = qw * 2; uvx *= w2; uvy *= w2; uvz *= w2; // vec3.scale(uuv, uuv, 2); uuvx *= 2; uuvy *= 2; uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); out[0] = x + uvx + uuvx; out[1] = y + uvy + uuvy; out[2] = z + uvz + uuvz; return out; } /** * Rotate a 3D vector around the x-axis * @param {vec3} out The receiving vec3 * @param {ReadonlyVec3} a The vec3 point to rotate * @param {ReadonlyVec3} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */ function rotateX(out, a, b, rad) { var p = [], r = []; //Translate point to the origin p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation r[0] = p[0]; r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad); r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } /** * Rotate a 3D vector around the y-axis * @param {vec3} out The receiving vec3 * @param {ReadonlyVec3} a The vec3 point to rotate * @param {ReadonlyVec3} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */ function rotateY(out, a, b, rad) { var p = [], r = []; //Translate point to the origin p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad); r[1] = p[1]; r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } /** * Rotate a 3D vector around the z-axis * @param {vec3} out The receiving vec3 * @param {ReadonlyVec3} a The vec3 point to rotate * @param {ReadonlyVec3} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */ function rotateZ(out, a, b, rad) { var p = [], r = []; //Translate point to the origin p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad); r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad); r[2] = p[2]; //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } /** * Get the angle between two 3D vectors * @param {ReadonlyVec3} a The first operand * @param {ReadonlyVec3} b The second operand * @returns {Number} The angle in radians */ function angle(a, b) { var ax = a[0], ay = a[1], az = a[2], bx = b[0], by = b[1], bz = b[2], mag1 = Math.sqrt(ax * ax + ay * ay + az * az), mag2 = Math.sqrt(bx * bx + by * by + bz * bz), mag = mag1 * mag2, cosine = mag && dot(a, b) / mag; return Math.acos(Math.min(Math.max(cosine, -1), 1)); } /** * Set the components of a vec3 to zero * * @param {vec3} out the receiving vector * @returns {vec3} out */ function zero(out) { out[0] = 0.0; out[1] = 0.0; out[2] = 0.0; return out; } /** * Returns a string representation of a vector * * @param {ReadonlyVec3} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")"; } /** * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyVec3} a The first vector. * @param {ReadonlyVec3} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; } /** * Returns whether or not the vectors have approximately the same elements in the same position. * * @param {ReadonlyVec3} a The first vector. * @param {ReadonlyVec3} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2]; var b0 = b[0], b1 = b[1], b2 = b[2]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)); } /** * Alias for {@link vec3.subtract} * @function */ var sub = subtract; /** * Alias for {@link vec3.multiply} * @function */ exports.sub = sub; var mul = multiply; /** * Alias for {@link vec3.divide} * @function */ exports.mul = mul; var div = divide; /** * Alias for {@link vec3.distance} * @function */ exports.div = div; var dist = distance; /** * Alias for {@link vec3.squaredDistance} * @function */ exports.dist = dist; var sqrDist = squaredDistance; /** * Alias for {@link vec3.length} * @function */ exports.sqrDist = sqrDist; var len = length; /** * Alias for {@link vec3.squaredLength} * @function */ exports.len = len; var sqrLen = squaredLength; /** * Perform some operation over an array of vec3s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ exports.sqrLen = sqrLen; var forEach = function () { var vec = create(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 3; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; } return a; }; }(); exports.forEach = forEach; },{"./common.js":882}],892:[function(require,module,exports){ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.clone = clone; exports.fromValues = fromValues; exports.copy = copy; exports.set = set; exports.add = add; exports.subtract = subtract; exports.multiply = multiply; exports.divide = divide; exports.ceil = ceil; exports.floor = floor; exports.min = min; exports.max = max; exports.round = round; exports.scale = scale; exports.scaleAndAdd = scaleAndAdd; exports.distance = distance; exports.squaredDistance = squaredDistance; exports.length = length; exports.squaredLength = squaredLength; exports.negate = negate; exports.inverse = inverse; exports.normalize = normalize; exports.dot = dot; exports.cross = cross; exports.lerp = lerp; exports.random = random; exports.transformMat4 = transformMat4; exports.transformQuat = transformQuat; exports.zero = zero; exports.str = str; exports.exactEquals = exactEquals; exports.equals = equals; exports.forEach = exports.sqrLen = exports.len = exports.sqrDist = exports.dist = exports.div = exports.mul = exports.sub = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 4 Dimensional Vector * @module vec4 */ /** * Creates a new, empty vec4 * * @returns {vec4} a new 4D vector */ function create() { var out = new glMatrix.ARRAY_TYPE(4); if (glMatrix.ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; } return out; } /** * Creates a new vec4 initialized with values from an existing vector * * @param {ReadonlyVec4} a vector to clone * @returns {vec4} a new 4D vector */ function clone(a) { var out = new glMatrix.ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } /** * Creates a new vec4 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {vec4} a new 4D vector */ function fromValues(x, y, z, w) { var out = new glMatrix.ARRAY_TYPE(4); out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; } /** * Copy the values from one vec4 to another * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the source vector * @returns {vec4} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } /** * Set the components of a vec4 to the given values * * @param {vec4} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {vec4} out */ function set(out, x, y, z, w) { out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; } /** * Adds two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; return out; } /** * Subtracts vector b from vector a * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; return out; } /** * Multiplies two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ function multiply(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; out[3] = a[3] * b[3]; return out; } /** * Divides two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ function divide(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; out[2] = a[2] / b[2]; out[3] = a[3] / b[3]; return out; } /** * Math.ceil the components of a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to ceil * @returns {vec4} out */ function ceil(out, a) { out[0] = Math.ceil(a[0]); out[1] = Math.ceil(a[1]); out[2] = Math.ceil(a[2]); out[3] = Math.ceil(a[3]); return out; } /** * Math.floor the components of a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to floor * @returns {vec4} out */ function floor(out, a) { out[0] = Math.floor(a[0]); out[1] = Math.floor(a[1]); out[2] = Math.floor(a[2]); out[3] = Math.floor(a[3]); return out; } /** * Returns the minimum of two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ function min(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); out[2] = Math.min(a[2], b[2]); out[3] = Math.min(a[3], b[3]); return out; } /** * Returns the maximum of two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ function max(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); out[2] = Math.max(a[2], b[2]); out[3] = Math.max(a[3], b[3]); return out; } /** * Math.round the components of a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to round * @returns {vec4} out */ function round(out, a) { out[0] = Math.round(a[0]); out[1] = Math.round(a[1]); out[2] = Math.round(a[2]); out[3] = Math.round(a[3]); return out; } /** * Scales a vec4 by a scalar number * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec4} out */ function scale(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; return out; } /** * Adds two vec4's after scaling the second operand by a scalar value * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec4} out */ function scaleAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; out[3] = a[3] + b[3] * scale; return out; } /** * Calculates the euclidian distance between two vec4's * * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {Number} distance between a and b */ function distance(a, b) { var x = b[0] - a[0]; var y = b[1] - a[1]; var z = b[2] - a[2]; var w = b[3] - a[3]; return Math.hypot(x, y, z, w); } /** * Calculates the squared euclidian distance between two vec4's * * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {Number} squared distance between a and b */ function squaredDistance(a, b) { var x = b[0] - a[0]; var y = b[1] - a[1]; var z = b[2] - a[2]; var w = b[3] - a[3]; return x * x + y * y + z * z + w * w; } /** * Calculates the length of a vec4 * * @param {ReadonlyVec4} a vector to calculate length of * @returns {Number} length of a */ function length(a) { var x = a[0]; var y = a[1]; var z = a[2]; var w = a[3]; return Math.hypot(x, y, z, w); } /** * Calculates the squared length of a vec4 * * @param {ReadonlyVec4} a vector to calculate squared length of * @returns {Number} squared length of a */ function squaredLength(a) { var x = a[0]; var y = a[1]; var z = a[2]; var w = a[3]; return x * x + y * y + z * z + w * w; } /** * Negates the components of a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to negate * @returns {vec4} out */ function negate(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = -a[3]; return out; } /** * Returns the inverse of the components of a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to invert * @returns {vec4} out */ function inverse(out, a) { out[0] = 1.0 / a[0]; out[1] = 1.0 / a[1]; out[2] = 1.0 / a[2]; out[3] = 1.0 / a[3]; return out; } /** * Normalize a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to normalize * @returns {vec4} out */ function normalize(out, a) { var x = a[0]; var y = a[1]; var z = a[2]; var w = a[3]; var len = x * x + y * y + z * z + w * w; if (len > 0) { len = 1 / Math.sqrt(len); } out[0] = x * len; out[1] = y * len; out[2] = z * len; out[3] = w * len; return out; } /** * Calculates the dot product of two vec4's * * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {Number} dot product of a and b */ function dot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; } /** * Returns the cross-product of three vectors in a 4-dimensional space * * @param {ReadonlyVec4} result the receiving vector * @param {ReadonlyVec4} U the first vector * @param {ReadonlyVec4} V the second vector * @param {ReadonlyVec4} W the third vector * @returns {vec4} result */ function cross(out, u, v, w) { var A = v[0] * w[1] - v[1] * w[0], B = v[0] * w[2] - v[2] * w[0], C = v[0] * w[3] - v[3] * w[0], D = v[1] * w[2] - v[2] * w[1], E = v[1] * w[3] - v[3] * w[1], F = v[2] * w[3] - v[3] * w[2]; var G = u[0]; var H = u[1]; var I = u[2]; var J = u[3]; out[0] = H * F - I * E + J * D; out[1] = -(G * F) + I * C - J * B; out[2] = G * E - H * C + J * A; out[3] = -(G * D) + H * B - I * A; return out; } /** * Performs a linear interpolation between two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec4} out */ function lerp(out, a, b, t) { var ax = a[0]; var ay = a[1]; var az = a[2]; var aw = a[3]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); out[3] = aw + t * (b[3] - aw); return out; } /** * Generates a random vector with the given scale * * @param {vec4} out the receiving vector * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned * @returns {vec4} out */ function random(out, scale) { scale = scale || 1.0; // Marsaglia, George. Choosing a Point from the Surface of a // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646. // http://projecteuclid.org/euclid.aoms/1177692644; var v1, v2, v3, v4; var s1, s2; do { v1 = glMatrix.RANDOM() * 2 - 1; v2 = glMatrix.RANDOM() * 2 - 1; s1 = v1 * v1 + v2 * v2; } while (s1 >= 1); do { v3 = glMatrix.RANDOM() * 2 - 1; v4 = glMatrix.RANDOM() * 2 - 1; s2 = v3 * v3 + v4 * v4; } while (s2 >= 1); var d = Math.sqrt((1 - s1) / s2); out[0] = scale * v1; out[1] = scale * v2; out[2] = scale * v3 * d; out[3] = scale * v4 * d; return out; } /** * Transforms the vec4 with a mat4. * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec4} out */ function transformMat4(out, a, m) { var x = a[0], y = a[1], z = a[2], w = a[3]; out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; return out; } /** * Transforms the vec4 with a quat * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the vector to transform * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec4} out */ function transformQuat(out, a, q) { var x = a[0], y = a[1], z = a[2]; var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; // calculate quat * vec var ix = qw * x + qy * z - qz * y; var iy = qw * y + qz * x - qx * z; var iz = qw * z + qx * y - qy * x; var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; out[3] = a[3]; return out; } /** * Set the components of a vec4 to zero * * @param {vec4} out the receiving vector * @returns {vec4} out */ function zero(out) { out[0] = 0.0; out[1] = 0.0; out[2] = 0.0; out[3] = 0.0; return out; } /** * Returns a string representation of a vector * * @param {ReadonlyVec4} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyVec4} a The first vector. * @param {ReadonlyVec4} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; } /** * Returns whether or not the vectors have approximately the same elements in the same position. * * @param {ReadonlyVec4} a The first vector. * @param {ReadonlyVec4} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); } /** * Alias for {@link vec4.subtract} * @function */ var sub = subtract; /** * Alias for {@link vec4.multiply} * @function */ exports.sub = sub; var mul = multiply; /** * Alias for {@link vec4.divide} * @function */ exports.mul = mul; var div = divide; /** * Alias for {@link vec4.distance} * @function */ exports.div = div; var dist = distance; /** * Alias for {@link vec4.squaredDistance} * @function */ exports.dist = dist; var sqrDist = squaredDistance; /** * Alias for {@link vec4.length} * @function */ exports.sqrDist = sqrDist; var len = length; /** * Alias for {@link vec4.squaredLength} * @function */ exports.len = len; var sqrLen = squaredLength; /** * Perform some operation over an array of vec4s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ exports.sqrLen = sqrLen; var forEach = function () { var vec = create(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 4; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; vec[3] = a[i + 3]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; a[i + 3] = vec[3]; } return a; }; }(); exports.forEach = forEach; },{"./common.js":882}],893:[function(require,module,exports){ (function (global){ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.ResizeObserver = factory()); }(this, (function () { 'use strict'; /** * A collection of shims that provide minimal functionality of the ES6 collections. * * These implementations are not meant to be used outside of the ResizeObserver * modules as they cover only a limited range of use cases. */ /* eslint-disable require-jsdoc, valid-jsdoc */ var MapShim = (function () { if (typeof Map !== 'undefined') { return Map; } /** * Returns index in provided array that matches the specified key. * * @param {Array} arr * @param {*} key * @returns {number} */ function getIndex(arr, key) { var result = -1; arr.some(function (entry, index) { if (entry[0] === key) { result = index; return true; } return false; }); return result; } return /** @class */ (function () { function class_1() { this.__entries__ = []; } Object.defineProperty(class_1.prototype, "size", { /** * @returns {boolean} */ get: function () { return this.__entries__.length; }, enumerable: true, configurable: true }); /** * @param {*} key * @returns {*} */ class_1.prototype.get = function (key) { var index = getIndex(this.__entries__, key); var entry = this.__entries__[index]; return entry && entry[1]; }; /** * @param {*} key * @param {*} value * @returns {void} */ class_1.prototype.set = function (key, value) { var index = getIndex(this.__entries__, key); if (~index) { this.__entries__[index][1] = value; } else { this.__entries__.push([key, value]); } }; /** * @param {*} key * @returns {void} */ class_1.prototype.delete = function (key) { var entries = this.__entries__; var index = getIndex(entries, key); if (~index) { entries.splice(index, 1); } }; /** * @param {*} key * @returns {void} */ class_1.prototype.has = function (key) { return !!~getIndex(this.__entries__, key); }; /** * @returns {void} */ class_1.prototype.clear = function () { this.__entries__.splice(0); }; /** * @param {Function} callback * @param {*} [ctx=null] * @returns {void} */ class_1.prototype.forEach = function (callback, ctx) { if (ctx === void 0) { ctx = null; } for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) { var entry = _a[_i]; callback.call(ctx, entry[1], entry[0]); } }; return class_1; }()); })(); /** * Detects whether window and document objects are available in current environment. */ var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document; // Returns global object of a current environment. var global$1 = (function () { if (typeof global !== 'undefined' && global.Math === Math) { return global; } if (typeof self !== 'undefined' && self.Math === Math) { return self; } if (typeof window !== 'undefined' && window.Math === Math) { return window; } // eslint-disable-next-line no-new-func return Function('return this')(); })(); /** * A shim for the requestAnimationFrame which falls back to the setTimeout if * first one is not supported. * * @returns {number} Requests' identifier. */ var requestAnimationFrame$1 = (function () { if (typeof requestAnimationFrame === 'function') { // It's required to use a bounded function because IE sometimes throws // an "Invalid calling object" error if rAF is invoked without the global // object on the left hand side. return requestAnimationFrame.bind(global$1); } return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); }; })(); // Defines minimum timeout before adding a trailing call. var trailingTimeout = 2; /** * Creates a wrapper function which ensures that provided callback will be * invoked only once during the specified delay period. * * @param {Function} callback - Function to be invoked after the delay period. * @param {number} delay - Delay after which to invoke callback. * @returns {Function} */ function throttle (callback, delay) { var leadingCall = false, trailingCall = false, lastCallTime = 0; /** * Invokes the original callback function and schedules new invocation if * the "proxy" was called during current request. * * @returns {void} */ function resolvePending() { if (leadingCall) { leadingCall = false; callback(); } if (trailingCall) { proxy(); } } /** * Callback invoked after the specified delay. It will further postpone * invocation of the original function delegating it to the * requestAnimationFrame. * * @returns {void} */ function timeoutCallback() { requestAnimationFrame$1(resolvePending); } /** * Schedules invocation of the original function. * * @returns {void} */ function proxy() { var timeStamp = Date.now(); if (leadingCall) { // Reject immediately following calls. if (timeStamp - lastCallTime < trailingTimeout) { return; } // Schedule new call to be in invoked when the pending one is resolved. // This is important for "transitions" which never actually start // immediately so there is a chance that we might miss one if change // happens amids the pending invocation. trailingCall = true; } else { leadingCall = true; trailingCall = false; setTimeout(timeoutCallback, delay); } lastCallTime = timeStamp; } return proxy; } // Minimum delay before invoking the update of observers. var REFRESH_DELAY = 20; // A list of substrings of CSS properties used to find transition events that // might affect dimensions of observed elements. var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight']; // Check if MutationObserver is available. var mutationObserverSupported = typeof MutationObserver !== 'undefined'; /** * Singleton controller class which handles updates of ResizeObserver instances. */ var ResizeObserverController = /** @class */ (function () { /** * Creates a new instance of ResizeObserverController. * * @private */ function ResizeObserverController() { /** * Indicates whether DOM listeners have been added. * * @private {boolean} */ this.connected_ = false; /** * Tells that controller has subscribed for Mutation Events. * * @private {boolean} */ this.mutationEventsAdded_ = false; /** * Keeps reference to the instance of MutationObserver. * * @private {MutationObserver} */ this.mutationsObserver_ = null; /** * A list of connected observers. * * @private {Array} */ this.observers_ = []; this.onTransitionEnd_ = this.onTransitionEnd_.bind(this); this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY); } /** * Adds observer to observers list. * * @param {ResizeObserverSPI} observer - Observer to be added. * @returns {void} */ ResizeObserverController.prototype.addObserver = function (observer) { if (!~this.observers_.indexOf(observer)) { this.observers_.push(observer); } // Add listeners if they haven't been added yet. if (!this.connected_) { this.connect_(); } }; /** * Removes observer from observers list. * * @param {ResizeObserverSPI} observer - Observer to be removed. * @returns {void} */ ResizeObserverController.prototype.removeObserver = function (observer) { var observers = this.observers_; var index = observers.indexOf(observer); // Remove observer if it's present in registry. if (~index) { observers.splice(index, 1); } // Remove listeners if controller has no connected observers. if (!observers.length && this.connected_) { this.disconnect_(); } }; /** * Invokes the update of observers. It will continue running updates insofar * it detects changes. * * @returns {void} */ ResizeObserverController.prototype.refresh = function () { var changesDetected = this.updateObservers_(); // Continue running updates if changes have been detected as there might // be future ones caused by CSS transitions. if (changesDetected) { this.refresh(); } }; /** * Updates every observer from observers list and notifies them of queued * entries. * * @private * @returns {boolean} Returns "true" if any observer has detected changes in * dimensions of it's elements. */ ResizeObserverController.prototype.updateObservers_ = function () { // Collect observers that have active observations. var activeObservers = this.observers_.filter(function (observer) { return observer.gatherActive(), observer.hasActive(); }); // Deliver notifications in a separate cycle in order to avoid any // collisions between observers, e.g. when multiple instances of // ResizeObserver are tracking the same element and the callback of one // of them changes content dimensions of the observed target. Sometimes // this may result in notifications being blocked for the rest of observers. activeObservers.forEach(function (observer) { return observer.broadcastActive(); }); return activeObservers.length > 0; }; /** * Initializes DOM listeners. * * @private * @returns {void} */ ResizeObserverController.prototype.connect_ = function () { // Do nothing if running in a non-browser environment or if listeners // have been already added. if (!isBrowser || this.connected_) { return; } // Subscription to the "Transitionend" event is used as a workaround for // delayed transitions. This way it's possible to capture at least the // final state of an element. document.addEventListener('transitionend', this.onTransitionEnd_); window.addEventListener('resize', this.refresh); if (mutationObserverSupported) { this.mutationsObserver_ = new MutationObserver(this.refresh); this.mutationsObserver_.observe(document, { attributes: true, childList: true, characterData: true, subtree: true }); } else { document.addEventListener('DOMSubtreeModified', this.refresh); this.mutationEventsAdded_ = true; } this.connected_ = true; }; /** * Removes DOM listeners. * * @private * @returns {void} */ ResizeObserverController.prototype.disconnect_ = function () { // Do nothing if running in a non-browser environment or if listeners // have been already removed. if (!isBrowser || !this.connected_) { return; } document.removeEventListener('transitionend', this.onTransitionEnd_); window.removeEventListener('resize', this.refresh); if (this.mutationsObserver_) { this.mutationsObserver_.disconnect(); } if (this.mutationEventsAdded_) { document.removeEventListener('DOMSubtreeModified', this.refresh); } this.mutationsObserver_ = null; this.mutationEventsAdded_ = false; this.connected_ = false; }; /** * "Transitionend" event handler. * * @private * @param {TransitionEvent} event * @returns {void} */ ResizeObserverController.prototype.onTransitionEnd_ = function (_a) { var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b; // Detect whether transition may affect dimensions of an element. var isReflowProperty = transitionKeys.some(function (key) { return !!~propertyName.indexOf(key); }); if (isReflowProperty) { this.refresh(); } }; /** * Returns instance of the ResizeObserverController. * * @returns {ResizeObserverController} */ ResizeObserverController.getInstance = function () { if (!this.instance_) { this.instance_ = new ResizeObserverController(); } return this.instance_; }; /** * Holds reference to the controller's instance. * * @private {ResizeObserverController} */ ResizeObserverController.instance_ = null; return ResizeObserverController; }()); /** * Defines non-writable/enumerable properties of the provided target object. * * @param {Object} target - Object for which to define properties. * @param {Object} props - Properties to be defined. * @returns {Object} Target object. */ var defineConfigurable = (function (target, props) { for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) { var key = _a[_i]; Object.defineProperty(target, key, { value: props[key], enumerable: false, writable: false, configurable: true }); } return target; }); /** * Returns the global object associated with provided element. * * @param {Object} target * @returns {Object} */ var getWindowOf = (function (target) { // Assume that the element is an instance of Node, which means that it // has the "ownerDocument" property from which we can retrieve a // corresponding global object. var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView; // Return the local global object if it's not possible extract one from // provided element. return ownerGlobal || global$1; }); // Placeholder of an empty content rectangle. var emptyRect = createRectInit(0, 0, 0, 0); /** * Converts provided string to a number. * * @param {number|string} value * @returns {number} */ function toFloat(value) { return parseFloat(value) || 0; } /** * Extracts borders size from provided styles. * * @param {CSSStyleDeclaration} styles * @param {...string} positions - Borders positions (top, right, ...) * @returns {number} */ function getBordersSize(styles) { var positions = []; for (var _i = 1; _i < arguments.length; _i++) { positions[_i - 1] = arguments[_i]; } return positions.reduce(function (size, position) { var value = styles['border-' + position + '-width']; return size + toFloat(value); }, 0); } /** * Extracts paddings sizes from provided styles. * * @param {CSSStyleDeclaration} styles * @returns {Object} Paddings box. */ function getPaddings(styles) { var positions = ['top', 'right', 'bottom', 'left']; var paddings = {}; for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) { var position = positions_1[_i]; var value = styles['padding-' + position]; paddings[position] = toFloat(value); } return paddings; } /** * Calculates content rectangle of provided SVG element. * * @param {SVGGraphicsElement} target - Element content rectangle of which needs * to be calculated. * @returns {DOMRectInit} */ function getSVGContentRect(target) { var bbox = target.getBBox(); return createRectInit(0, 0, bbox.width, bbox.height); } /** * Calculates content rectangle of provided HTMLElement. * * @param {HTMLElement} target - Element for which to calculate the content rectangle. * @returns {DOMRectInit} */ function getHTMLElementContentRect(target) { // Client width & height properties can't be // used exclusively as they provide rounded values. var clientWidth = target.clientWidth, clientHeight = target.clientHeight; // By this condition we can catch all non-replaced inline, hidden and // detached elements. Though elements with width & height properties less // than 0.5 will be discarded as well. // // Without it we would need to implement separate methods for each of // those cases and it's not possible to perform a precise and performance // effective test for hidden elements. E.g. even jQuery's ':visible' filter // gives wrong results for elements with width & height less than 0.5. if (!clientWidth && !clientHeight) { return emptyRect; } var styles = getWindowOf(target).getComputedStyle(target); var paddings = getPaddings(styles); var horizPad = paddings.left + paddings.right; var vertPad = paddings.top + paddings.bottom; // Computed styles of width & height are being used because they are the // only dimensions available to JS that contain non-rounded values. It could // be possible to utilize the getBoundingClientRect if only it's data wasn't // affected by CSS transformations let alone paddings, borders and scroll bars. var width = toFloat(styles.width), height = toFloat(styles.height); // Width & height include paddings and borders when the 'border-box' box // model is applied (except for IE). if (styles.boxSizing === 'border-box') { // Following conditions are required to handle Internet Explorer which // doesn't include paddings and borders to computed CSS dimensions. // // We can say that if CSS dimensions + paddings are equal to the "client" // properties then it's either IE, and thus we don't need to subtract // anything, or an element merely doesn't have paddings/borders styles. if (Math.round(width + horizPad) !== clientWidth) { width -= getBordersSize(styles, 'left', 'right') + horizPad; } if (Math.round(height + vertPad) !== clientHeight) { height -= getBordersSize(styles, 'top', 'bottom') + vertPad; } } // Following steps can't be applied to the document's root element as its // client[Width/Height] properties represent viewport area of the window. // Besides, it's as well not necessary as the itself neither has // rendered scroll bars nor it can be clipped. if (!isDocumentElement(target)) { // In some browsers (only in Firefox, actually) CSS width & height // include scroll bars size which can be removed at this step as scroll // bars are the only difference between rounded dimensions + paddings // and "client" properties, though that is not always true in Chrome. var vertScrollbar = Math.round(width + horizPad) - clientWidth; var horizScrollbar = Math.round(height + vertPad) - clientHeight; // Chrome has a rather weird rounding of "client" properties. // E.g. for an element with content width of 314.2px it sometimes gives // the client width of 315px and for the width of 314.7px it may give // 314px. And it doesn't happen all the time. So just ignore this delta // as a non-relevant. if (Math.abs(vertScrollbar) !== 1) { width -= vertScrollbar; } if (Math.abs(horizScrollbar) !== 1) { height -= horizScrollbar; } } return createRectInit(paddings.left, paddings.top, width, height); } /** * Checks whether provided element is an instance of the SVGGraphicsElement. * * @param {Element} target - Element to be checked. * @returns {boolean} */ var isSVGGraphicsElement = (function () { // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement // interface. if (typeof SVGGraphicsElement !== 'undefined') { return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; }; } // If it's so, then check that element is at least an instance of the // SVGElement and that it has the "getBBox" method. // eslint-disable-next-line no-extra-parens return function (target) { return (target instanceof getWindowOf(target).SVGElement && typeof target.getBBox === 'function'); }; })(); /** * Checks whether provided element is a document element (). * * @param {Element} target - Element to be checked. * @returns {boolean} */ function isDocumentElement(target) { return target === getWindowOf(target).document.documentElement; } /** * Calculates an appropriate content rectangle for provided html or svg element. * * @param {Element} target - Element content rectangle of which needs to be calculated. * @returns {DOMRectInit} */ function getContentRect(target) { if (!isBrowser) { return emptyRect; } if (isSVGGraphicsElement(target)) { return getSVGContentRect(target); } return getHTMLElementContentRect(target); } /** * Creates rectangle with an interface of the DOMRectReadOnly. * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly * * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions. * @returns {DOMRectReadOnly} */ function createReadOnlyRect(_a) { var x = _a.x, y = _a.y, width = _a.width, height = _a.height; // If DOMRectReadOnly is available use it as a prototype for the rectangle. var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object; var rect = Object.create(Constr.prototype); // Rectangle's properties are not writable and non-enumerable. defineConfigurable(rect, { x: x, y: y, width: width, height: height, top: y, right: x + width, bottom: height + y, left: x }); return rect; } /** * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates. * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit * * @param {number} x - X coordinate. * @param {number} y - Y coordinate. * @param {number} width - Rectangle's width. * @param {number} height - Rectangle's height. * @returns {DOMRectInit} */ function createRectInit(x, y, width, height) { return { x: x, y: y, width: width, height: height }; } /** * Class that is responsible for computations of the content rectangle of * provided DOM element and for keeping track of it's changes. */ var ResizeObservation = /** @class */ (function () { /** * Creates an instance of ResizeObservation. * * @param {Element} target - Element to be observed. */ function ResizeObservation(target) { /** * Broadcasted width of content rectangle. * * @type {number} */ this.broadcastWidth = 0; /** * Broadcasted height of content rectangle. * * @type {number} */ this.broadcastHeight = 0; /** * Reference to the last observed content rectangle. * * @private {DOMRectInit} */ this.contentRect_ = createRectInit(0, 0, 0, 0); this.target = target; } /** * Updates content rectangle and tells whether it's width or height properties * have changed since the last broadcast. * * @returns {boolean} */ ResizeObservation.prototype.isActive = function () { var rect = getContentRect(this.target); this.contentRect_ = rect; return (rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight); }; /** * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data * from the corresponding properties of the last observed content rectangle. * * @returns {DOMRectInit} Last observed content rectangle. */ ResizeObservation.prototype.broadcastRect = function () { var rect = this.contentRect_; this.broadcastWidth = rect.width; this.broadcastHeight = rect.height; return rect; }; return ResizeObservation; }()); var ResizeObserverEntry = /** @class */ (function () { /** * Creates an instance of ResizeObserverEntry. * * @param {Element} target - Element that is being observed. * @param {DOMRectInit} rectInit - Data of the element's content rectangle. */ function ResizeObserverEntry(target, rectInit) { var contentRect = createReadOnlyRect(rectInit); // According to the specification following properties are not writable // and are also not enumerable in the native implementation. // // Property accessors are not being used as they'd require to define a // private WeakMap storage which may cause memory leaks in browsers that // don't support this type of collections. defineConfigurable(this, { target: target, contentRect: contentRect }); } return ResizeObserverEntry; }()); var ResizeObserverSPI = /** @class */ (function () { /** * Creates a new instance of ResizeObserver. * * @param {ResizeObserverCallback} callback - Callback function that is invoked * when one of the observed elements changes it's content dimensions. * @param {ResizeObserverController} controller - Controller instance which * is responsible for the updates of observer. * @param {ResizeObserver} callbackCtx - Reference to the public * ResizeObserver instance which will be passed to callback function. */ function ResizeObserverSPI(callback, controller, callbackCtx) { /** * Collection of resize observations that have detected changes in dimensions * of elements. * * @private {Array} */ this.activeObservations_ = []; /** * Registry of the ResizeObservation instances. * * @private {Map} */ this.observations_ = new MapShim(); if (typeof callback !== 'function') { throw new TypeError('The callback provided as parameter 1 is not a function.'); } this.callback_ = callback; this.controller_ = controller; this.callbackCtx_ = callbackCtx; } /** * Starts observing provided element. * * @param {Element} target - Element to be observed. * @returns {void} */ ResizeObserverSPI.prototype.observe = function (target) { if (!arguments.length) { throw new TypeError('1 argument required, but only 0 present.'); } // Do nothing if current environment doesn't have the Element interface. if (typeof Element === 'undefined' || !(Element instanceof Object)) { return; } if (!(target instanceof getWindowOf(target).Element)) { throw new TypeError('parameter 1 is not of type "Element".'); } var observations = this.observations_; // Do nothing if element is already being observed. if (observations.has(target)) { return; } observations.set(target, new ResizeObservation(target)); this.controller_.addObserver(this); // Force the update of observations. this.controller_.refresh(); }; /** * Stops observing provided element. * * @param {Element} target - Element to stop observing. * @returns {void} */ ResizeObserverSPI.prototype.unobserve = function (target) { if (!arguments.length) { throw new TypeError('1 argument required, but only 0 present.'); } // Do nothing if current environment doesn't have the Element interface. if (typeof Element === 'undefined' || !(Element instanceof Object)) { return; } if (!(target instanceof getWindowOf(target).Element)) { throw new TypeError('parameter 1 is not of type "Element".'); } var observations = this.observations_; // Do nothing if element is not being observed. if (!observations.has(target)) { return; } observations.delete(target); if (!observations.size) { this.controller_.removeObserver(this); } }; /** * Stops observing all elements. * * @returns {void} */ ResizeObserverSPI.prototype.disconnect = function () { this.clearActive(); this.observations_.clear(); this.controller_.removeObserver(this); }; /** * Collects observation instances the associated element of which has changed * it's content rectangle. * * @returns {void} */ ResizeObserverSPI.prototype.gatherActive = function () { var _this = this; this.clearActive(); this.observations_.forEach(function (observation) { if (observation.isActive()) { _this.activeObservations_.push(observation); } }); }; /** * Invokes initial callback function with a list of ResizeObserverEntry * instances collected from active resize observations. * * @returns {void} */ ResizeObserverSPI.prototype.broadcastActive = function () { // Do nothing if observer doesn't have active observations. if (!this.hasActive()) { return; } var ctx = this.callbackCtx_; // Create ResizeObserverEntry instance for every active observation. var entries = this.activeObservations_.map(function (observation) { return new ResizeObserverEntry(observation.target, observation.broadcastRect()); }); this.callback_.call(ctx, entries, ctx); this.clearActive(); }; /** * Clears the collection of active observations. * * @returns {void} */ ResizeObserverSPI.prototype.clearActive = function () { this.activeObservations_.splice(0); }; /** * Tells whether observer has active observations. * * @returns {boolean} */ ResizeObserverSPI.prototype.hasActive = function () { return this.activeObservations_.length > 0; }; return ResizeObserverSPI; }()); // Registry of internal observers. If WeakMap is not available use current shim // for the Map collection as it has all required methods and because WeakMap // can't be fully polyfilled anyway. var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim(); /** * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation * exposing only those methods and properties that are defined in the spec. */ var ResizeObserver = /** @class */ (function () { /** * Creates a new instance of ResizeObserver. * * @param {ResizeObserverCallback} callback - Callback that is invoked when * dimensions of the observed elements change. */ function ResizeObserver(callback) { if (!(this instanceof ResizeObserver)) { throw new TypeError('Cannot call a class as a function.'); } if (!arguments.length) { throw new TypeError('1 argument required, but only 0 present.'); } var controller = ResizeObserverController.getInstance(); var observer = new ResizeObserverSPI(callback, controller, this); observers.set(this, observer); } return ResizeObserver; }()); // Expose public methods of ResizeObserver. [ 'observe', 'unobserve', 'disconnect' ].forEach(function (method) { ResizeObserver.prototype[method] = function () { var _a; return (_a = observers.get(this))[method].apply(_a, arguments); }; }); var index = (function () { // Export existing implementation if available. if (typeof global$1.ResizeObserver !== 'undefined') { return global$1.ResizeObserver; } return ResizeObserver; })(); return index; }))); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],894:[function(require,module,exports){ (function (global){ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global global, define, System, Reflect, Promise */ var __extends; var __assign; var __rest; var __decorate; var __param; var __metadata; var __awaiter; var __generator; var __exportStar; var __values; var __read; var __spread; var __spreadArrays; var __await; var __asyncGenerator; var __asyncDelegator; var __asyncValues; var __makeTemplateObject; var __importStar; var __importDefault; var __classPrivateFieldGet; var __classPrivateFieldSet; var __createBinding; (function (factory) { var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; if (typeof define === "function" && define.amd) { define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); } else if (typeof module === "object" && typeof module.exports === "object") { factory(createExporter(root, createExporter(module.exports))); } else { factory(createExporter(root)); } function createExporter(exports, previous) { if (exports !== root) { if (typeof Object.create === "function") { Object.defineProperty(exports, "__esModule", { value: true }); } else { exports.__esModule = true; } } return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; } }) (function (exporter) { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; __extends = function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; __assign = Object.assign || function (t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; __rest = function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; __decorate = function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; __param = function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; __metadata = function (metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); }; __awaiter = function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; __generator = function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; __createBinding = function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }; __exportStar = function (m, exports) { for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) exports[p] = m[p]; }; __values = function (o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; __read = function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; __spread = function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; __spreadArrays = function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; __await = function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }; __asyncGenerator = function (thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; __asyncDelegator = function (o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } }; __asyncValues = function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; __makeTemplateObject = function (cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; __importStar = function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; __importDefault = function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; __classPrivateFieldGet = function (receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); }; __classPrivateFieldSet = function (receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; }; exporter("__extends", __extends); exporter("__assign", __assign); exporter("__rest", __rest); exporter("__decorate", __decorate); exporter("__param", __param); exporter("__metadata", __metadata); exporter("__awaiter", __awaiter); exporter("__generator", __generator); exporter("__exportStar", __exportStar); exporter("__createBinding", __createBinding); exporter("__values", __values); exporter("__read", __read); exporter("__spread", __spread); exporter("__spreadArrays", __spreadArrays); exporter("__await", __await); exporter("__asyncGenerator", __asyncGenerator); exporter("__asyncDelegator", __asyncDelegator); exporter("__asyncValues", __asyncValues); exporter("__makeTemplateObject", __makeTemplateObject); exporter("__importStar", __importStar); exporter("__importDefault", __importDefault); exporter("__classPrivateFieldGet", __classPrivateFieldGet); exporter("__classPrivateFieldSet", __classPrivateFieldSet); }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],895:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; /** * Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */ var __DEV__ = process.env.NODE_ENV !== 'production'; var warning = function() {}; if (__DEV__) { var printWarning = function printWarning(format, args) { var len = arguments.length; args = new Array(len > 1 ? len - 1 : 0); for (var key = 1; key < len; key++) { args[key - 1] = arguments[key]; } var argIndex = 0; var message = 'Warning: ' + format.replace(/%s/g, function() { return args[argIndex++]; }); if (typeof console !== 'undefined') { console.error(message); } try { // --- Welcome to debugging React --- // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this warning to fire. throw new Error(message); } catch (x) {} } warning = function(condition, format, args) { var len = arguments.length; args = new Array(len > 2 ? len - 2 : 0); for (var key = 2; key < len; key++) { args[key - 2] = arguments[key]; } if (format === undefined) { throw new Error( '`warning(condition, format, ...args)` requires a warning ' + 'message argument' ); } if (!condition) { printWarning.apply(null, [format].concat(args)); } }; } module.exports = warning; }).call(this,require('_process')) },{"_process":1}]},{},[]) //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9AYW50di9nMnBsb3QiLCIuLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2FkanVzdC9saWIvYWRqdXN0cy9hZGp1c3QuanMiLCJub2RlX21vZHVsZXMvQGFudHYvYWRqdXN0L2xpYi9hZGp1c3RzL2RvZGdlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2FkanVzdC9saWIvYWRqdXN0cy9qaXR0ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvYWRqdXN0L2xpYi9hZGp1c3RzL3N0YWNrLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2FkanVzdC9saWIvYWRqdXN0cy9zeW1tZXRyaWMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvYWRqdXN0L2xpYi9jb25zdGFudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9hZGp1c3QvbGliL2ZhY3RvcnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvYWRqdXN0L2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9hdHRyL2xpYi9hdHRyaWJ1dGVzL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvYXR0ci9saWIvYXR0cmlidXRlcy9jb2xvci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9hdHRyL2xpYi9hdHRyaWJ1dGVzL29wYWNpdHkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvYXR0ci9saWIvYXR0cmlidXRlcy9wb3NpdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9hdHRyL2xpYi9hdHRyaWJ1dGVzL3NoYXBlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2F0dHIvbGliL2F0dHJpYnV0ZXMvc2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9hdHRyL2xpYi9mYWN0b3J5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2F0dHIvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2F0dHIvbGliL2ludGVyZmFjZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb2xvci11dGlsL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Fic3RyYWN0L2NvbXBvbmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Fic3RyYWN0L2h0bWwtY29tcG9uZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvYW5ub3RhdGlvbi9hcmMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9hbm5vdGF0aW9uL2RhdGEtbWFya2VyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvYW5ub3RhdGlvbi9kYXRhLXJlZ2lvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Fubm90YXRpb24vaW1hZ2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9hbm5vdGF0aW9uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvYW5ub3RhdGlvbi9saW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvYW5ub3RhdGlvbi9yZWdpb24tZmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvYW5ub3RhdGlvbi9yZWdpb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9hbm5vdGF0aW9uL3RleHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9heGlzL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9heGlzL2NpcmNsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2F4aXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9heGlzL2xpbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9heGlzL292ZXJsYXAvYXV0by1lbGxpcHNpcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2F4aXMvb3ZlcmxhcC9hdXRvLWhpZGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9heGlzL292ZXJsYXAvYXV0by1yb3RhdGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9heGlzL292ZXJsYXAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9jcm9zc2hhaXIvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Nyb3NzaGFpci9jaXJjbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9jcm9zc2hhaXIvY3NzLWNvbnN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvY3Jvc3NoYWlyL2h0bWwtdGhlbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9jcm9zc2hhaXIvaHRtbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Nyb3NzaGFpci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2Nyb3NzaGFpci9saW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvZ3JpZC9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvZ3JpZC9jaXJjbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9ncmlkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvZ3JpZC9saW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi9sZWdlbmQvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2xlZ2VuZC9jYXRlZ29yeS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL2xlZ2VuZC9jb250aW51b3VzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvbGVnZW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvc2Nyb2xsYmFyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvc2Nyb2xsYmFyL3Njcm9sbGJhci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3NsaWRlci9jb25zdGFudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3NsaWRlci9oYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvc2xpZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvc2xpZGVyL3NsaWRlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3Rvb2x0aXAvY3NzLWNvbnN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdG9vbHRpcC9odG1sLXRoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdG9vbHRpcC9odG1sLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdG9vbHRpcC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3RyZW5kL2NvbnN0YW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdHJlbmQvcGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3RyZW5kL3RyZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdXRpbC9hbGlnbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3V0aWwvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi91dGlsL2dyYXBoaWMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi91dGlsL2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdXRpbC9tYXRyaXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29tcG9uZW50L2xpYi91dGlsL3N0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdXRpbC90ZXh0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2NvbXBvbmVudC9saWIvdXRpbC90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb21wb25lbnQvbGliL3V0aWwvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb29yZC9saWIvY29vcmQvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb29yZC9saWIvY29vcmQvY2FydGVzaWFuLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2Nvb3JkL2xpYi9jb29yZC9oZWxpeC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9jb29yZC9saWIvY29vcmQvcG9sYXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29vcmQvbGliL2ZhY3RvcnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvY29vcmQvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2RvbS11dGlsL2xpYi9hZGQtZXZlbnQtbGlzdGVuZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZG9tLXV0aWwvbGliL2NyZWF0ZS1kb20uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZG9tLXV0aWwvbGliL2dldC1oZWlnaHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZG9tLXV0aWwvbGliL2dldC1vdXRlci1oZWlnaHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZG9tLXV0aWwvbGliL2dldC1vdXRlci13aWR0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9kb20tdXRpbC9saWIvZ2V0LXJhdGlvLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2RvbS11dGlsL2xpYi9nZXQtc3R5bGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZG9tLXV0aWwvbGliL2dldC13aWR0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9kb20tdXRpbC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZG9tLXV0aWwvbGliL21vZGlmeS1jc3MuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZXZlbnQtZW1pdHRlci9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9hYnN0cmFjdC9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYWJzdHJhY3QvY2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYWJzdHJhY3QvY29udGFpbmVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYWJzdHJhY3QvZWxlbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWJhc2UvbGliL2Fic3RyYWN0L2dyb3VwLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYWJzdHJhY3Qvc2hhcGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9hbmltYXRlL3RpbWVsaW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYmJveC9jaXJjbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9iYm94L2VsbGlwc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9iYm94L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYmJveC9saW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYmJveC9wYXRoLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYmJveC9wb2x5Z29uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvYmJveC9wb2x5bGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWJhc2UvbGliL2Jib3gvcmVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWJhc2UvbGliL2Jib3gvcmVnaXN0ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9iYm94L3RleHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9iYm94L3V0aWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9ldmVudC9ldmVudC1jb250b2xsZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi9ldmVudC9ncmFwaC1ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWJhc2UvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvaW50ZXJmYWNlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWJhc2UvbGliL3R5cGVzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvdXRpbC9jb2xvci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWJhc2UvbGliL3V0aWwvbWF0cml4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctYmFzZS9saWIvdXRpbC9vZmZzY3JlZW4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi91dGlsL3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi91dGlsL3RleHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2xpYi91dGlsL3V0aWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvY2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi9ncm91cC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL2ludGVyZmFjZXMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3NoYXBlL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3NoYXBlL2NpcmNsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvc2hhcGUvZWxsaXBzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvc2hhcGUvaW1hZ2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3NoYXBlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi9zaGFwZS9saW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi9zaGFwZS9tYXJrZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3NoYXBlL3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3NoYXBlL3BvbHlnb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3NoYXBlL3BvbHlsaW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi9zaGFwZS9yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi9zaGFwZS90ZXh0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi90eXBlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvdXRpbC9hcmMtcGFyYW1zLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi91dGlsL2Fycm93LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi91dGlsL2RyYXcuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3V0aWwvaGl0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi91dGlsL2luLXBhdGgvcG9pbnQtaW4tcGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvdXRpbC9pbi1wYXRoL3BvbHlnb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3V0aWwvaW4tc3Ryb2tlL2FyYy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvdXRpbC9pbi1zdHJva2UvbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9saWIvdXRpbC9pbi1zdHJva2UvcG9seWxpbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3V0aWwvaW4tc3Ryb2tlL3JlY3QtcmFkaXVzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi91dGlsL2luLXN0cm9rZS9yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi91dGlsL3BhcnNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctY2FudmFzL2xpYi91dGlsL3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvbGliL3V0aWwvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWNhbnZhcy9wYWNrYWdlLmpzb24iLCJub2RlX21vZHVsZXMvQGFudHYvZy1nZXN0dXJlL2xpYi9ldmVudC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWdlc3R1cmUvbGliL2V2ZW50L3doZWVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctZ2VzdHVyZS9saWIvZ2VzdHVyZXMvZ2VzdHVyZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWdlc3R1cmUvbGliL2dlc3R1cmVzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctZ2VzdHVyZS9saWIvZ2VzdHVyZXMvcGFuLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctZ2VzdHVyZS9saWIvZ2VzdHVyZXMvcHJlc3MuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1nZXN0dXJlL2xpYi9nZXN0dXJlcy9zd2lwZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWdlc3R1cmUvbGliL2dlc3R1cmVzL3RhcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLWdlc3R1cmUvbGliL2dtLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctZ2VzdHVyZS9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1nZXN0dXJlL2xpYi91dGlscy9jbG9jay5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvbGliL2FyYy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvbGliL2Jlemllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvbGliL2N1YmljLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctbWF0aC9saWIvZWxsaXBzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvbGliL2xpbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1tYXRoL2xpYi9wb2x5bGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvbGliL3F1YWRyYXRpYy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvbGliL3NlZ21lbnRzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctbWF0aC9saWIvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvY2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9jb25zdGFudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvZGVmcy9hcnJvdy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvZGVmcy9jbGlwLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9kZWZzL2dyYWRpZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9kZWZzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9kZWZzL3BhdHRlcm4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL2RlZnMvc2hhZG93LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9ncm91cC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL2NpcmNsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvc2hhcGUvZG9tLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9zaGFwZS9lbGxpcHNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9zaGFwZS9pbWFnZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvc2hhcGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL2xpbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL21hcmtlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvc2hhcGUvbWFya2VyL3N5bWJvbHMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL3BvbHlnb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbGliL3NoYXBlL3BvbHlsaW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9zaGFwZS9yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi9zaGFwZS90ZXh0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi91dGlsL2RvbS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvdXRpbC9kcmF3LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL2xpYi91dGlsL2Zvcm1hdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nLXN2Zy9saWIvdXRpbC9zdmcuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvbm9kZV9tb2R1bGVzL2RldGVjdC1icm93c2VyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2ctc3ZnL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vZmFkZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vZ3Jvdy1pbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2FuaW1hdGUvYW5pbWF0aW9uL3BhdGgtaW4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2FuaW1hdGUvYW5pbWF0aW9uL3Bvc2l0aW9uLXVwZGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vc2NhbGUtaW4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2FuaW1hdGUvYW5pbWF0aW9uL3NlY3Rvci1wYXRoLXVwZGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vd2F2ZS1pbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9hbmltYXRpb24vem9vbS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYW5pbWF0ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvY2hhcnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2NoYXJ0L2NvbnRyb2xsZXIvYW5ub3RhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvY29udHJvbGxlci9heGlzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9jaGFydC9jb250cm9sbGVyL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2NoYXJ0L2NvbnRyb2xsZXIvY29vcmRpbmF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvY29udHJvbGxlci9nZXN0dXJlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9jaGFydC9jb250cm9sbGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9jaGFydC9jb250cm9sbGVyL2xlZ2VuZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvY29udHJvbGxlci9zbGlkZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2NoYXJ0L2NvbnRyb2xsZXIvdG9vbHRpcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2NoYXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9jaGFydC9sYXlvdXQvYXV0by5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvbGF5b3V0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9jaGFydC9sYXlvdXQvcGFkZGluZy1jYWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2NoYXJ0L3V0aWwvc2NhbGUtcG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY2hhcnQvdmlldy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY29tcG9uZW50L2xhYmVscy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvY29uc3RhbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2NvcmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2RlcGVuZGVudHMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2VuZ2luZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZmFjZXQvY2lyY2xlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9mYWNldC9mYWNldC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZmFjZXQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ZhY2V0L2xpc3QuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ZhY2V0L21hdHJpeC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZmFjZXQvbWlycm9yLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9mYWNldC9yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9mYWNldC90cmVlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9hcmVhLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9lZGdlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9lbGVtZW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9oZWF0bWFwLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9pbnRlcnZhbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvbGFiZWwvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvbGFiZWwvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L2xhYmVsL2ludGVydmFsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9sYWJlbC9sYXlvdXQvbGltaXQtaW4tY2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9sYWJlbC9sYXlvdXQvbGltaXQtaW4tc2hhcGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L2xhYmVsL2xheW91dC9vdmVybGFwLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9sYWJlbC9sYXlvdXQvcGllL2Rpc3RyaWJ1dGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L2xhYmVsL2xheW91dC9waWUvb3V0ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L2xhYmVsL3BpZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvbGFiZWwvcG9sYXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L2xpbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3BvaW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9wb2x5Z29uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zY2hlbWEuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2FyZWEvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2FyZWEvbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvYXJlYS9zbW9vdGgtbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvYXJlYS9zbW9vdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2FyZWEvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvZWRnZS9hcmMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2VkZ2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2VkZ2Uvc21vb3RoLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS9lZGdlL3V0aWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2VkZ2Uvdmh2LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS9pbnRlcnZhbC9mdW5uZWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL2ludGVydmFsL2hvbGxvdy1yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS9pbnRlcnZhbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvcHlyYW1pZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvdGljay5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvbGluZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvbGluZS9zdGVwLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS9saW5lL3V0aWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3BvaW50L2hvbGxvdy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvcG9pbnQvaW1hZ2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3BvaW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS9wb2ludC9zb2xpZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvcG9pbnQvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvcG9seWdvbi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvcG9seWdvbi9zcXVhcmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3NjaGVtYS9ib3guanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3NjaGVtYS9jYW5kbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3NjaGVtYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvc2hhcGUvdXRpbC9nZXQtcGF0aC1wb2ludHMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3V0aWwvZ2V0LXN0eWxlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS91dGlsL3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3V0aWwvc3BsaXQtcG9pbnRzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS91dGlsL2dyb3VwLWRhdGEuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2dlb21ldHJ5L3V0aWwvaXMtbW9kZWwtY2hhbmdlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9nZW9tZXRyeS91dGlsL3BhcnNlLWZpZWxkcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvZ2VvbWV0cnkvdXRpbC9zaGFwZS1zaXplLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2FjdGl2ZS1yZWdpb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vY2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvbGlzdC1hY3RpdmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvbGlzdC1oaWdobGlnaHQtdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2NvbXBvbmVudC9saXN0LWhpZ2hsaWdodC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2NvbXBvbmVudC9saXN0LXNlbGVjdGVkLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vY29tcG9uZW50L2xpc3Qtc3RhdGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvbGlzdC11bmNoZWNrZWQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvdG9vbHRpcC9lbGxpcHNpcy10ZXh0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vY29tcG9uZW50L3Rvb2x0aXAvZ2VvbWV0cnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvdG9vbHRpcC9zaWJsaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vY3Vyc29yLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZGF0YS9maWx0ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9kYXRhL3JhbmdlLWZpbHRlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2RhdGEvc2libGluZy1maWx0ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L2FjdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvZmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9oaWdobGlnaHQtYnktY29sb3IuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L2hpZ2hsaWdodC1ieS14LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9oaWdobGlnaHQtdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvaGlnaGxpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9saW5rLWJ5LWNvbG9yLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9yYW5nZS1hY3RpdmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3JhbmdlLWhpZ2hsaWdodC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvcmFuZ2Utc2VsZWN0ZWQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3JhbmdlLXN0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9zZWxlY3RlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvc2libGluZy1maWx0ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3NpbmdsZS1hY3RpdmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3NpbmdsZS1oaWdobGlnaHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3NpbmdsZS1zZWxlY3RlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvc2luZ2xlLXN0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9zdGF0ZS1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9zdGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vbWFzay9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vbWFzay9jaXJjbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi9tYXNrL2RpbS1yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vbWFzay9wYXRoLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vbWFzay9yZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vbWFzay9zbW9vdGgtcGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL3JlZ2lzdGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL3ZpZXcvYnV0dG9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vdmlldy9kcmFnLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vdmlldy9tb3ZlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vdmlldy9zY2FsZS10cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2FjdGlvbi92aWV3L3NjYWxlLXRyYW5zbGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vYWN0aW9uL3ZpZXcvc2NhbGUtem9vbS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vY29udGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vZ3JhbW1hci1pbnRlcmFjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvaW50ZXJhY3Rpb24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2ludGVyYWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi9pbnRlcmZhY2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3RoZW1lL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi90aGVtZS9zdHlsZS1zaGVldC9kYXJrLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi90aGVtZS9zdHlsZS1zaGVldC9saWdodC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvdXRpbC9hdHRyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi91dGlsL2F4aXMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3V0aWwvYmJveC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvdXRpbC9jb29yZGluYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi91dGlsL2RpcmVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvdXRpbC9kb20uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3V0aWwvZmFjZXQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3V0aWwvZ3JhcGhpY3MuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3V0aWwvZ3JpZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvdXRpbC9oZWxwZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3V0aWwvbGVnZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi91dGlsL21hcmtlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMi9saWIvdXRpbC9wYWRkaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi91dGlsL3NjYWxlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi91dGlsL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL2xpYi91dGlsL3Rvb2x0aXAuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzIvbGliL3V0aWwvdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cyL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2Jhc2UvY29uc3RhbnRzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvYmFzZS9jb250cm9sbGVyL2NhbnZhcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2Jhc2UvY29udHJvbGxlci9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2Jhc2UvY29udHJvbGxlci9wYWRkaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvYmFzZS9jb250cm9sbGVyL3N0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvYmFzZS9jb250cm9sbGVyL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvYmFzZS9nbG9iYWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9iYXNlL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvYmFzZS9wbG90LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvYmFzZS92aWV3LWxheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tYm8vYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2NvbWJvL2NvbHVtbi1saW5lL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tYm8vY29sdW1uLWxpbmUvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21iby9kdWFsLWxpbmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21iby9kdWFsLWxpbmUvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21iby9ncm91cGVkQ29sdW1uLWxpbmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21iby9ncm91cGVkQ29sdW1uLWxpbmUvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21iby9zdGFja2VkQ29sdW1uLWxpbmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21iby9zdGFja2VkQ29sdW1uLWxpbmUvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21wb25lbnRzL2F4aXMvcGFyc2VyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9heGlzL3N0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9icmVhZGNydW1iLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9jb25uZWN0ZWQtYXJlYS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2NvbXBvbmVudHMvY29udmVyc2lvbi10YWcuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21wb25lbnRzL2Rlc2NyaXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9mYWN0b3J5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9ndWlkZS1saW5lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9sYWJlbC9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9sYWJlbC9wYXJzZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21wb25lbnRzL2xhYmVsL3BvaW50LWF1dG8uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21wb25lbnRzL2xhYmVsL3BvaW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9sYWJlbC9zdGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2NvbXBvbmVudHMvbWFya2VyLXBvaW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy9zdGF0aXN0aWMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21wb25lbnRzL3RpbWVsaW5lL2J1dHRvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2NvbXBvbmVudHMvdGltZWxpbmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9jb21wb25lbnRzL3Rvb2x0aXAtaW5kaWNhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvY29tcG9uZW50cy90b29sdGlwL3N0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvZGVwZW5kZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2dlb21zL2FyZWEvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9hcmVhL21haW4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9hcmVhL21pbmkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvZ2VvbXMvZmFjdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2dlb21zL2hlYXRtYXAvbGluZWFyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvZ2VvbXMvaW50ZXJ2YWwvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9pbnRlcnZhbC9tYWluLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvZ2VvbXMvbGluZS9ndWlkZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2dlb21zL2xpbmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9saW5lL21haW4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9saW5lL21pbmkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9wb2ludC9jaXJjbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9nZW9tcy9wb2ludC9ndWlkZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2dlb21zL3BvaW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvaW50ZXJhY3Rpb24vYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2ludGVyYWN0aW9uL2NvcmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9pbnRlcmFjdGlvbi9oZWxwZXIvZGF0YS1yYW5nZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2ludGVyYWN0aW9uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvaW50ZXJhY3Rpb24vc2Nyb2xsYmFyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvaW50ZXJhY3Rpb24vc2xpZGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvaW50ZXJhY3Rpb24vdGltZWxpbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9pbnRlcmFjdGlvbi90b29sdGlwLWluZGljYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL2ludGVyZmFjZS9jb25maWcuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9hcmVhL2FwcGx5LXJlc3BvbnNpdmUvYXhpcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2FyZWEvYXBwbHktcmVzcG9uc2l2ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2FyZWEvY29tcG9uZW50L2xhYmVsL2FyZWEtcG9pbnQtYXV0by5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2FyZWEvY29tcG9uZW50L2xhYmVsL2FyZWEtcG9pbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9hcmVhL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYXJlYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2FyZWEvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9hcmVhL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYmFyL2NvbXBvbmVudC9sYWJlbC1hdXRvLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYmFyL2NvbXBvbmVudC9sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Jhci9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Jhci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Jhci9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Jhci90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2J1YmJsZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2J1YmJsZS9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2J1YmJsZS9zaGFwZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2J1YmJsZS90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2J1bGxldC9jb21wb25lbnQvYnVsbGV0UmVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2J1bGxldC9jb21wb25lbnQvYnVsbGV0VGFyZ2V0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYnVsbGV0L2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYnVsbGV0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYnVsbGV0L2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvYnVsbGV0L3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY2FsZW5kYXIvY29uc3RhbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jYWxlbmRhci9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2NhbGVuZGFyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY2FsZW5kYXIvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jYWxlbmRhci9zaGFwZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2NhbGVuZGFyL3V0aWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb2x1bW4vYXBwbHktcmVzcG9uc2l2ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2NvbHVtbi9hcHBseS1yZXNwb25zaXZlL2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29sdW1uL2FwcGx5LXJlc3BvbnNpdmUvdGhlbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb2x1bW4vY29tcG9uZW50L2xhYmVsLWF1dG8uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb2x1bW4vY29tcG9uZW50L2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29sdW1uL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29sdW1uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29sdW1uL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29sdW1uL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29tcGF0aWJsZVBsb3RzL2dyb3VwLWJhci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2NvbXBhdGlibGVQbG90cy9ncm91cC1jb2x1bW4vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb21wYXRpYmxlUGxvdHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb21wYXRpYmxlUGxvdHMvcGVyY2VudGFnZS1zdGFjay1hcmVhL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29tcGF0aWJsZVBsb3RzL3BlcmNlbnRhZ2Utc3RhY2stYmFyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29tcGF0aWJsZVBsb3RzL3BlcmNlbnRhZ2Utc3RhY2stY29sdW1uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvY29tcGF0aWJsZVBsb3RzL3JpbmcvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb21wYXRpYmxlUGxvdHMvc3RhY2stYXJlYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2NvbXBhdGlibGVQbG90cy9zdGFjay1iYXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9jb21wYXRpYmxlUGxvdHMvc3RhY2stY29sdW1uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZGVuc2l0eS1oZWF0bWFwL2NvbXBvbmVudHMvYmFja2dyb3VuZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2RlbnNpdHktaGVhdG1hcC9jb21wb25lbnRzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZGVuc2l0eS1oZWF0bWFwL2NvbXBvbmVudHMvbGVnZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZGVuc2l0eS1oZWF0bWFwL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZGVuc2l0eS1oZWF0bWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZGVuc2l0eS1oZWF0bWFwL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZGVuc2l0eS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2RlbnNpdHkvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9kb251dC9jb21wb25lbnQvcmluZy1zdGF0aXN0aWMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9kb251dC9jb21wb25lbnQvc3RhdGlzdGljLXRlbXBsYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZG9udXQvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9kb251dC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2RvbnV0L2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZmFuLWdhdWdlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZmFuLWdhdWdlL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZnVubmVsL2FuaW1hdGlvbi9mdW5uZWwtc2NhbGUtaW4teC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Z1bm5lbC9hbmltYXRpb24vZnVubmVsLXNjYWxlLWluLXkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9mdW5uZWwvZ2VvbWV0cnkvc2hhcGUvZnVubmVsLWJhc2ljLXJlY3QuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9mdW5uZWwvZ2VvbWV0cnkvc2hhcGUvZnVubmVsLWR5bmFtaWMtcmVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Z1bm5lbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Z1bm5lbC9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2Z1bm5lbC90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2dhdWdlL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZ2F1Z2UvZ2VvbWV0cnkvc2hhcGUvZ2F1Z2Utc2hhcGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9nYXVnZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2dhdWdlL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZ3JvdXBlZC1iYXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9ncm91cGVkLWJhci9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2dyb3VwZWQtYmFyL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZ3JvdXBlZC1jb2x1bW4vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9ncm91cGVkLWNvbHVtbi9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2dyb3VwZWQtY29sdW1uL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZ3JvdXBlZC1yb3NlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvZ3JvdXBlZC1yb3NlL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvaGVhdG1hcC9jb21wb25lbnQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9oZWF0bWFwL2NvbXBvbmVudC9sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2hlYXRtYXAvY29tcG9uZW50L2xlZ2VuZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2hlYXRtYXAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9oZWF0bWFwL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvaGVhdG1hcC9zaGFwZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2hpc3RvZ3JhbS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2hpc3RvZ3JhbS9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbGluZS9hbmltYXRpb24vY2xpcEluLXdpdGgtZGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvYXBwbHktcmVzcG9uc2l2ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvYXBwbHktcmVzcG9uc2l2ZS9sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvYXBwbHktcmVzcG9uc2l2ZS90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvY29tcG9uZW50L2xhYmVsL2xpbmUtbGFiZWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9saW5lL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbGluZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvaW50ZXJhY3Rpb24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9saW5lL2ludGVyYWN0aW9uL2xpbmUtYWN0aXZlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbGluZS9pbnRlcmFjdGlvbi9saW5lLXNlbGVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvaW50ZXJhY3Rpb24vbWFya2VyLWFjdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvaW50ZXJhY3Rpb24vc2VsZWN0ZWQtdG9vbHRpcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpbmUvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9saW5lL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbGlxdWlkL2FuaW1hdGlvbi9saXF1aWQtbW92ZS1pbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpcXVpZC9jb21wb25lbnQvbGlxdWlkLXN0YXRpc3RpYy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpcXVpZC9jb21wb25lbnQvc3RhdGlzdGljLXRlbXBsYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbGlxdWlkL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbGlxdWlkL2dlb21ldHJ5L3NoYXBlL2xpcXVpZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpcXVpZC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL2xpcXVpZC9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL21ldGVyLWdhdWdlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvbWV0ZXItZ2F1Z2UvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9wZXJjZW50LXN0YWNrZWQtYXJlYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3BlcmNlbnQtc3RhY2tlZC1hcmVhL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGVyY2VudC1zdGFja2VkLWJhci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3BlcmNlbnQtc3RhY2tlZC1iYXIvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9wZXJjZW50LXN0YWNrZWQtY29sdW1uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGVyY2VudC1zdGFja2VkLWNvbHVtbi9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3BpZS9jb21wb25lbnQvbGFiZWwvYmFzZS1sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3BpZS9jb21wb25lbnQvbGFiZWwvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9waWUvY29tcG9uZW50L2xhYmVsL2lubmVyLWxhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGllL2NvbXBvbmVudC9sYWJlbC9vdXRlci1jZW50ZXItbGFiZWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9waWUvY29tcG9uZW50L2xhYmVsL291dGVyLWxhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGllL2NvbXBvbmVudC9sYWJlbC9zcGlkZXItbGFiZWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9waWUvY29tcG9uZW50L2xhYmVsL3V0aWxzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGllL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGllL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGllL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcGllL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcmFkYXIvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9yYWRhci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3JhZGFyL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcmFkYXIvdGhlbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9yYW5nZS1iYXIvYW5pbWF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcmFuZ2UtYmFyL2NvbXBvbmVudC9sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3JhbmdlLWJhci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3JhbmdlLWJhci9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3JhbmdlLWNvbHVtbi9hbmltYXRpb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9yYW5nZS1jb2x1bW4vY29tcG9uZW50L2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcmFuZ2UtY29sdW1uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcmFuZ2UtY29sdW1uL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvcm9zZS9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3Jvc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9yb3NlL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc2NhdHRlci9jb21wb25lbnRzL3F1YWRyYW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc2NhdHRlci9jb21wb25lbnRzL3RyZW5kbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3NjYXR0ZXIvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zY2F0dGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc2NhdHRlci9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3NjYXR0ZXIvdGhlbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWFyZWEvY29tcG9uZW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1hcmVhL2NvbXBvbmVudC9sYWJlbC9hcmVhLWxhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1hcmVhL2NvbXBvbmVudC9sYWJlbC9hcmVhLXBvaW50LWF1dG8uanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWFyZWEvY29tcG9uZW50L2xhYmVsL2FyZWEtcG9pbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWFyZWEvY29tcG9uZW50L2xhYmVsL2xpbmUtbGFiZWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWFyZWEvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWFyZWEvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWFyZWEvdGhlbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWJhci9jb21wb25lbnQvbGFiZWwtYXV0by5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3N0YWNrZWQtYmFyL2NvbXBvbmVudC9sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3N0YWNrZWQtYmFyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1iYXIvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWJhci90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3N0YWNrZWQtY29sdW1uL2NvbXBvbmVudC9sYWJlbC1hdXRvLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1jb2x1bW4vY29tcG9uZW50L2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1jb2x1bW4vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy9zdGFja2VkLWNvbHVtbi9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3N0YWNrZWQtY29sdW1uL3RoZW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1yb3NlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RhY2tlZC1yb3NlL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RlcC1saW5lL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvc3RlcC1saW5lL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvdHJlZW1hcC9jb21wb25lbnRzL2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvdHJlZW1hcC9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3RyZWVtYXAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy90cmVlbWFwL2ludGVyYWN0aW9uL2FuaW1hdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3RyZWVtYXAvaW50ZXJhY3Rpb24vZHJpbGxEb3duLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvdHJlZW1hcC9pbnRlcmFjdGlvbi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3RyZWVtYXAvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy90cmVlbWFwL2xheW91dC9kaWNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvdHJlZW1hcC9sYXlvdXQvc2xpY2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy90cmVlbWFwL2xheW91dC9zcXVhcmlmeS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3dhdGVyZmFsbC9jb21wb25lbnQvbGFiZWwvZGlmZi1sYWJlbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3dhdGVyZmFsbC9jb21wb25lbnQvbGFiZWwvd2F0ZXJmYWxsLWxhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvd2F0ZXJmYWxsL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvd2F0ZXJmYWxsL2dlb21ldHJ5L3NoYXBlL3dhdGVyZmFsbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3dhdGVyZmFsbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3dhdGVyZmFsbC9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3Bsb3RzL3dvcmQtY2xvdWQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9wbG90cy93b3JkLWNsb3VkL2xheWVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvd29yZC1jbG91ZC93b3JkLWNsb3VkLXRvb2x0aXBzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvcGxvdHMvd29yZC1jbG91ZC93b3JkY2xvdWQyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvc3BhcmtsaW5lL3Byb2dyZXNzL2NvbXBvbmVudC9tYXJrZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvcHJvZ3Jlc3MvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvcHJvZ3Jlc3MvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvcHJvZ3Jlc3MvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvcmluZy1wcm9ncmVzcy9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3NwYXJrbGluZS9yaW5nLXByb2dyZXNzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvc3BhcmtsaW5lL3JpbmctcHJvZ3Jlc3MvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvdGlueS1hcmVhL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvc3BhcmtsaW5lL3RpbnktYXJlYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3NwYXJrbGluZS90aW55LWFyZWEvbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvdGlueS1jb2x1bW4vZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvdGlueS1jb2x1bW4vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvdGlueS1jb2x1bW4vbGF5ZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvdGlueS1sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3NwYXJrbGluZS90aW55LWxpbmUvZXZlbnQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi9zcGFya2xpbmUvdGlueS1saW5lL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvc3BhcmtsaW5lL3RpbnktbGluZS9sYXllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3RoZW1lL2RhcmsuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi90aGVtZS9kZWZhdWx0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdGhlbWUvZ2xvYmFsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdGhlbWUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi90aGVtZS90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3RoZW1lL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9iYm94LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9jb2xvci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9kYXRhLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9kYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9ldmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvZm9ybWF0dGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9nLXV0aWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL21hdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3BhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvYXBwbHkvYXhpcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9hcHBseS9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL2FwcGx5L2xhYmVsLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL2NvbnN0cmFpbnRzL2NvbHVtbi13aWR0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9jb25zdHJhaW50cy9lbGVtZW50LWNvbGxpc2lvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9jb25zdHJhaW50cy9lbGVtZW50LWRpc3QtdmVydGljYWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvY29uc3RyYWludHMvZWxlbWVudC1kaXN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL2NvbnN0cmFpbnRzL2VsZW1lbnQtd2lkdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvY29uc3RyYWludHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvY29uc3RyYWludHMvbWluLXJpbmctdGhpY2tuZXNzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL2NvbnN0cmFpbnRzL3JpbmctdGhpY2tuZXNzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL2RlZmF1bHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvbm9kZS9zaGFwZS1ub2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9yZXNwb25zaXZlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL2NsZWFyLW92ZXJsYXBwaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL2RhdGV0aW1lLXN0cmluZy1hYmJyZXZhaXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL2RpZ2l0cy1hYmJyZXZpYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL25vZGUtaml0dGVyLXVwd2FyZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9ydWxlcy9ub2RlLWppdHRlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9ydWxlcy9ub2Rlcy1yZXNhbXBsaW5nLWJ5LWFiYnJldmF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9ydWxlcy9ub2Rlcy1yZXNhbXBsaW5nLWJ5LWNoYW5nZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9ydWxlcy9ub2Rlcy1yZXNhbXBsaW5nLWJ5LXN0YXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL25vZGVzLXJlc2FtcGxpbmcuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvcnVsZXMvcm9idXN0LWFiYnJldmFpdGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3Jlc3BvbnNpdmUvcnVsZXMvdGV4dC1hYmJyZXZpYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL3RleHQtaGlkZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS9ydWxlcy90ZXh0LXJvdGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L2cycGxvdC9saWIvdXRpbC9yZXNwb25zaXZlL3J1bGVzL3RleHQtd3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvcmVzcG9uc2l2ZS90aGVtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9nMnBsb3QvbGliL3V0aWwvc2NhbGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3N0YXRlLW1hbmFnZXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3RleHQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvZzJwbG90L2xpYi91dGlsL3ZpZXcuanMiLCJub2RlX21vZHVsZXMvQGFudHYvbWF0cml4LXV0aWwvbGliL2V4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9tYXRyaXgtdXRpbC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvcGF0aC11dGlsL2xpYi9jYXRtdWxsLXJvbS0yLWJlemllci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL2ZpbGwtcGF0aC1ieS1kaWZmLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9saWIvZmlsbC1wYXRoLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9saWIvZm9ybWF0LXBhdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvcGF0aC11dGlsL2xpYi9nZXQtYXJjLXBhcmFtcy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL2dldC1saW5lLWludGVyc2VjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9saWIvaXMtcG9seWdvbnMtaW50ZXJzZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9saWIvcGFyc2UtcGF0aC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL3BhcnNlLXBhdGgtc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9saWIvcGFyc2UtcGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL3BhdGgtMi1hYnNvbHV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL3BhdGgtMi1jdXJ2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL3BhdGgtMi1zZWdtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL3BhdGgtaW50ZXJzZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9saWIvcG9pbnQtaW4tcG9seWdvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbGliL3JlY3QtcGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvY2F0ZWdvcnkvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvY2F0ZWdvcnkvdGltZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvY29udGludW91cy9iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi9jb250aW51b3VzL2xpbmVhci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvY29udGludW91cy9sb2cuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL2NvbnRpbnVvdXMvcG93LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi9jb250aW51b3VzL3F1YW50aWxlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi9jb250aW51b3VzL3F1YW50aXplLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi9jb250aW51b3VzL3RpbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL2ZhY3RvcnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL2lkZW50aXR5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdGljay1tZXRob2QvY2F0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi90aWNrLW1ldGhvZC9kMy1saW5lYXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL3RpY2stbWV0aG9kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi90aWNrLW1ldGhvZC9saW5lYXIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL3RpY2stbWV0aG9kL2xvZy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdGljay1tZXRob2QvcG93LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi90aWNrLW1ldGhvZC9xdWFudGlsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdGljay1tZXRob2Qvci1wcmV0dHJ5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi90aWNrLW1ldGhvZC9yZWdpc3Rlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdGljay1tZXRob2QvdGltZS1jYXQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL3RpY2stbWV0aG9kL3RpbWUtcHJldHR5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi90aWNrLW1ldGhvZC90aW1lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi91dGlsL2Jpc2VjdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi91dGlsL2QzLWxpbmVhci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdXRpbC9leHRlbmRlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdXRpbC9pbnRlcnZhbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdXRpbC9tYXRoLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3NjYWxlL2xpYi91dGlsL3ByZXR0eS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9saWIvdXRpbC9zdHJpY3QtbGltaXQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvc2NhbGUvbGliL3V0aWwvdGltZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di9zY2FsZS9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvYXVnbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9jYWNoZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9jbGFtcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9jbGVhci1hbmltYXRpb24tZnJhbWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvY2xvbmUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvY29udGFpbnMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZGVib3VuY2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZGVlcC1taXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZGlmZmVyZW5jZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9lYWNoLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2VuZHMtd2l0aC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9ldmVyeS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9leHRlbmQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2ZpbmQtaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZmluZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9maXJzdC12YWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9maXhlZC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2ZsYXR0ZW4tZGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9mbGF0dGVuLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2Zvci1pbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9nZXQtcmFuZ2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZ2V0LXR5cGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZ2V0LXdyYXAtYmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvZ2V0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2dyb3VwLWJ5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2dyb3VwLXRvLW1hcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9ncm91cC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9oYXMta2V5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2hhcy12YWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9oYXMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaGVhZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pbmRleC1vZi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1hcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtYXJyYXktbGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1ib29sZWFuLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLWRhdGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtZGVjaW1hbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1lbGVtZW50LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLWVtcHR5LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLWVxdWFsLXdpdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtZXF1YWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtZXJyb3IuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtZXZlbi5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1maW5pdGUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtaW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1tYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1uZWdhdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1uaWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtbnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1udW1iZXItZXF1YWwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtbnVtYmVyLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLW9iamVjdC1saWtlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1vZGQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvaXMtcGxhaW4tb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLXBvc2l0aXZlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLXByb3RvdHlwZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy1yZWctZXhwLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLXN0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9pcy10eXBlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2lzLXVuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL2xhc3QuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvbG93ZXItY2FzZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9sb3dlci1maXJzdC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9tYXAtdmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL21hcC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9tYXgtYnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvbWVtb2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9taW4tYnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvbWl4LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL21vZC5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9ub29wLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL251bWJlcjJjb2xvci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9wYXJzZS1yYWRpdXMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvcGljay5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9wdWxsLWF0LmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL3B1bGwuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvcmVkdWNlLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL3JlbW92ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9yZXF1ZXN0LWFuaW1hdGlvbi1mcmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9zZXQuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvc2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi9zb21lLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL3NvcnQtYnkuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvc3RhcnRzLXdpdGguanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvc3Vic3RpdHV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi90aHJvdHRsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi90by1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi90by1kZWdyZWUuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvdG8taW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi90by1yYWRpYW4uanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvdG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL3VuaW9uLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL3VuaXEuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvdW5pcXVlLWlkLmpzIiwibm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvbGliL3VwcGVyLWNhc2UuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvdXBwZXItZmlyc3QuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvdmFsdWVzLW9mLWtleS5qcyIsIm5vZGVfbW9kdWxlcy9AYW50di91dGlsL2xpYi92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvQGFudHYvdXRpbC9saWIvd3JhcC1iZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9kMy1jb2xvci9kaXN0L2QzLWNvbG9yLmpzIiwibm9kZV9tb2R1bGVzL2QzLWVhc2UvZGlzdC9kMy1lYXNlLmpzIiwibm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL2Rpc3QvZDMtaW50ZXJwb2xhdGUuanMiLCJub2RlX21vZHVsZXMvZDMtcmVncmVzc2lvbi9kaXN0L2QzLXJlZ3Jlc3Npb24uanMiLCJub2RlX21vZHVsZXMvZDMtdGltZXIvZGlzdC9kMy10aW1lci5qcyIsIm5vZGVfbW9kdWxlcy9kZXRlY3QtYnJvd3Nlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9mZWNoYS9saWIvZmVjaGEudW1kLmpzIiwibm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9janMvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9janMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ2wtbWF0cml4L2Nqcy9tYXQyLmpzIiwibm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9janMvbWF0MmQuanMiLCJub2RlX21vZHVsZXMvZ2wtbWF0cml4L2Nqcy9tYXQzLmpzIiwibm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9janMvbWF0NC5qcyIsIm5vZGVfbW9kdWxlcy9nbC1tYXRyaXgvY2pzL3F1YXQuanMiLCJub2RlX21vZHVsZXMvZ2wtbWF0cml4L2Nqcy9xdWF0Mi5qcyIsIm5vZGVfbW9kdWxlcy9nbC1tYXRyaXgvY2pzL3ZlYzIuanMiLCJub2RlX21vZHVsZXMvZ2wtbWF0cml4L2Nqcy92ZWMzLmpzIiwibm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9janMvdmVjNC5qcyIsIm5vZGVfbW9kdWxlcy9yZXNpemUtb2JzZXJ2ZXItcG9seWZpbGwvZGlzdC9SZXNpemVPYnNlcnZlci5qcyIsIm5vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5qcyIsIm5vZGVfbW9kdWxlcy93YXJuaW5nL3dhcm5pbmcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0ZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNW9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5VUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvc0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzl6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDampCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3akJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdG9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5K0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDalNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbDBDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25aQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3poQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbk1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3dENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6VUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNwU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3ckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25RQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbFdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2dDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL1NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3BTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNya0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamxCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvMkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDckpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDck5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOWVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xpQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcDFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzkzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0eEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2h0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6M0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQy91QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeDZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDNVJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5HMiA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLy8g6YCa55So6YWN572uXG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiLi9pbnRlcmZhY2UvY29uZmlnXCIpLCBleHBvcnRzKTtcbnZhciBsYXllcl8xID0gcmVxdWlyZShcIi4vYmFzZS9sYXllclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxheWVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsYXllcl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgdmlld19sYXllcl8xID0gcmVxdWlyZShcIi4vYmFzZS92aWV3LWxheWVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVmlld0xheWVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB2aWV3X2xheWVyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBwbG90XzEgPSByZXF1aXJlKFwiLi9iYXNlL3Bsb3RcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCYXNlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBwbG90XzEuZGVmYXVsdDsgfSB9KTtcbi8vIOWbvuW9olxudHNsaWJfMS5fX2V4cG9ydFN0YXIocmVxdWlyZShcIi4vcGxvdHNcIiksIGV4cG9ydHMpO1xudmFyIHByb2dyZXNzXzEgPSByZXF1aXJlKFwiLi9zcGFya2xpbmUvcHJvZ3Jlc3NcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJQcm9ncmVzc1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJvZ3Jlc3NfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHJpbmdfcHJvZ3Jlc3NfMSA9IHJlcXVpcmUoXCIuL3NwYXJrbGluZS9yaW5nLXByb2dyZXNzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUmluZ1Byb2dyZXNzXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiByaW5nX3Byb2dyZXNzXzEuZGVmYXVsdDsgfSB9KTtcbnZhciB0aW55X2NvbHVtbl8xID0gcmVxdWlyZShcIi4vc3BhcmtsaW5lL3RpbnktY29sdW1uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVGlueUNvbHVtblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGlueV9jb2x1bW5fMS5kZWZhdWx0OyB9IH0pO1xudmFyIHRpbnlfYXJlYV8xID0gcmVxdWlyZShcIi4vc3BhcmtsaW5lL3RpbnktYXJlYVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRpbnlBcmVhXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aW55X2FyZWFfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHRpbnlfbGluZV8xID0gcmVxdWlyZShcIi4vc3BhcmtsaW5lL3RpbnktbGluZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRpbnlMaW5lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aW55X2xpbmVfMS5kZWZhdWx0OyB9IH0pO1xuLy8g5re35ZCI5Zu+5b2iXG52YXIgZHVhbF9saW5lXzEgPSByZXF1aXJlKFwiLi9jb21iby9kdWFsLWxpbmVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJEdWFsTGluZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZHVhbF9saW5lXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBjb2x1bW5fbGluZV8xID0gcmVxdWlyZShcIi4vY29tYm8vY29sdW1uLWxpbmVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDb2x1bW5MaW5lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb2x1bW5fbGluZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZ3JvdXBlZENvbHVtbl9saW5lXzEgPSByZXF1aXJlKFwiLi9jb21iby9ncm91cGVkQ29sdW1uLWxpbmVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcm91cGVkQ29sdW1uTGluZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZ3JvdXBlZENvbHVtbl9saW5lXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBzdGFja2VkQ29sdW1uX2xpbmVfMSA9IHJlcXVpcmUoXCIuL2NvbWJvL3N0YWNrZWRDb2x1bW4tbGluZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0YWNrZWRDb2x1bW5MaW5lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzdGFja2VkQ29sdW1uX2xpbmVfMS5kZWZhdWx0OyB9IH0pO1xuLy8g5Li76aKYXG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuL3RoZW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJUaGVtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhlbWVfMS5yZWdpc3RlclRoZW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJHbG9iYWxUaGVtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhlbWVfMS5yZWdpc3Rlckdsb2JhbFRoZW1lOyB9IH0pO1xudmFyIGNvbnN0cmFpbnRzXzEgPSByZXF1aXJlKFwiLi91dGlsL3Jlc3BvbnNpdmUvY29uc3RyYWludHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlclJlc3BvbnNpdmVDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50c18xLnJlZ2lzdGVyUmVzcG9uc2l2ZUNvbnN0cmFpbnQ7IH0gfSk7XG52YXIgcnVsZXNfMSA9IHJlcXVpcmUoXCIuL3V0aWwvcmVzcG9uc2l2ZS9ydWxlc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyUmVzcG9uc2l2ZVJ1bGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJ1bGVzXzEucmVnaXN0ZXJSZXNwb25zaXZlUnVsZTsgfSB9KTtcbnZhciB0aGVtZV8yID0gcmVxdWlyZShcIi4vdXRpbC9yZXNwb25zaXZlL3RoZW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJSZXNwb25zaXZlVGhlbWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoZW1lXzIucmVnaXN0ZXJSZXNwb25zaXZlVGhlbWU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRSZXNwb25zaXZlVGhlbWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoZW1lXzIuZ2V0UmVzcG9uc2l2ZVRoZW1lOyB9IH0pO1xudmFyIHN0YXRlX21hbmFnZXJfMSA9IHJlcXVpcmUoXCIuL3V0aWwvc3RhdGUtbWFuYWdlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0YXRlTWFuYWdlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc3RhdGVfbWFuYWdlcl8xLmRlZmF1bHQ7IH0gfSk7XG4vLyDlr7zlh7ogZzIg5LiK5bGC6ZyA6KaB5L2/55SoXG52YXIgRzIgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiQGFudHYvZzJcIikpO1xuZXhwb3J0cy5HMiA9IEcyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIF8gPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIEFkanVzdCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBBZGp1c3QoY2ZnKSB7XG4gICAgICAgIHZhciB4RmllbGQgPSBjZmcueEZpZWxkLCB5RmllbGQgPSBjZmcueUZpZWxkLCBfYSA9IGNmZy5hZGp1c3ROYW1lcywgYWRqdXN0TmFtZXMgPSBfYSA9PT0gdm9pZCAwID8gWyd4JywgJ3knXSA6IF9hO1xuICAgICAgICB0aGlzLmFkanVzdE5hbWVzID0gYWRqdXN0TmFtZXM7XG4gICAgICAgIHRoaXMueEZpZWxkID0geEZpZWxkO1xuICAgICAgICB0aGlzLnlGaWVsZCA9IHlGaWVsZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICog5p+l55yL57u05bqm5piv5ZCm5pivIGFkanVzdCDlrZfmrrVcbiAgICAgKiBAcGFyYW0gZGltXG4gICAgICovXG4gICAgQWRqdXN0LnByb3RvdHlwZS5pc0FkanVzdCA9IGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRqdXN0TmFtZXMuaW5kZXhPZihkaW0pID49IDA7XG4gICAgfTtcbiAgICBBZGp1c3QucHJvdG90eXBlLmdldEFkanVzdFJhbmdlID0gZnVuY3Rpb24gKGRpbSwgZGltVmFsdWUsIHZhbHVlcykge1xuICAgICAgICB2YXIgeUZpZWxkID0gdGhpcy55RmllbGQ7XG4gICAgICAgIHZhciBpbmRleCA9IHZhbHVlcy5pbmRleE9mKGRpbVZhbHVlKTtcbiAgICAgICAgdmFyIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGg7XG4gICAgICAgIHZhciBwcmU7XG4gICAgICAgIHZhciBuZXh0O1xuICAgICAgICAvLyDmsqHmnIkgeSDlrZfmrrXvvIzkvYbmmK/pnIDopoHmoLnmja4geSDosIPmlbRcbiAgICAgICAgaWYgKCF5RmllbGQgJiYgdGhpcy5pc0FkanVzdCgneScpKSB7XG4gICAgICAgICAgICBwcmUgPSAwO1xuICAgICAgICAgICAgbmV4dCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgLy8g5aaC5p6c5Lul5YW25byA5aS077yM5YiZ5Y+W5LmL77yM5ZCm5YiZ5Y+W5LuW5YmN6Z2i5LiA5LiqXG4gICAgICAgICAgICBwcmUgPSB2YWx1ZXNbaW5kZXggPT09IDAgPyAwIDogaW5kZXggLSAxXTtcbiAgICAgICAgICAgIC8vIOWmguaenOS7peWFtue7k+Wwvu+8jOWImeWPluS5i++8jOWQpuWImeWPluS7luWQjumdouS4gOS4qlxuICAgICAgICAgICAgbmV4dCA9IHZhbHVlc1tpbmRleCA9PT0gbGVuZ3RoIC0gMSA/IGxlbmd0aCAtIDEgOiBpbmRleCArIDFdO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcHJlICs9IChkaW1WYWx1ZSAtIHByZSkgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcHJlIC09IChuZXh0IC0gZGltVmFsdWUpIC8gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gbGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIG5leHQgLT0gKG5leHQgLSBkaW1WYWx1ZSkgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dCArPSAoZGltVmFsdWUgLSB2YWx1ZXNbbGVuZ3RoIC0gMl0pIC8gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHByZSA9IGRpbVZhbHVlID09PSAwID8gMCA6IGRpbVZhbHVlIC0gMC41O1xuICAgICAgICAgICAgbmV4dCA9IGRpbVZhbHVlID09PSAwID8gMSA6IGRpbVZhbHVlICsgMC41O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwcmU6IHByZSxcbiAgICAgICAgICAgIG5leHQ6IG5leHQsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBBZGp1c3QucHJvdG90eXBlLmFkanVzdERhdGEgPSBmdW5jdGlvbiAoZ3JvdXBlZERhdGFBcnJheSwgbWVyZ2VkRGF0YSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAvLyDmiYDmnInosIPmlbTnu7TluqbnmoTlgLzmlbDnu4RcbiAgICAgICAgdmFyIGRpbVZhbHVlc01hcCA9IHRoaXMuZ2V0RGltVmFsdWVzKG1lcmdlZERhdGEpO1xuICAgICAgICAvLyDmjInnhafmr4/kuIDkuKrliIbnu4TmnaXov5vooYzosIPmlbRcbiAgICAgICAgXy5lYWNoKGdyb3VwZWREYXRhQXJyYXksIGZ1bmN0aW9uIChkYXRhQXJyYXksIGluZGV4KSB7XG4gICAgICAgICAgICAvLyDpgY3ljobmiYDmnInmlbDmja7pm4blkIhcbiAgICAgICAgICAgIC8vIOavj+S4quWIhue7hOS4re+8jOWIhuWIq+aMieeFp+S4jeWQjOeahCBkaW0g6L+b6KGM6LCD5pW0XG4gICAgICAgICAgICBfLmVhY2goZGltVmFsdWVzTWFwLCBmdW5jdGlvbiAodmFsdWVzLCBkaW0pIHtcbiAgICAgICAgICAgICAgICAvLyDmoLnmja7kuI3lkIznmoTluqbph4/liIbliKvosIPmlbTkvY3nva5cbiAgICAgICAgICAgICAgICBfdGhpcy5hZGp1c3REaW0oZGltLCB2YWx1ZXMsIGRhdGFBcnJheSwgaW5kZXgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5a+55pWw5o2u6L+b6KGM5YiG57uEYWRqdXN0RGF0YVxuICAgICAqIEBwYXJhbSBkYXRhIOaVsOaNrlxuICAgICAqIEBwYXJhbSBkaW0g5YiG57uE55qE5a2X5q61XG4gICAgICogQHJldHVybiDliIbnu4Tnu5PmnpxcbiAgICAgKi9cbiAgICBBZGp1c3QucHJvdG90eXBlLmdyb3VwRGF0YSA9IGZ1bmN0aW9uIChkYXRhLCBkaW0pIHtcbiAgICAgICAgLy8g6KGl6b2Q5pWw5o2u56m65pWw5o2u5Li66buY6K6k5YC8XG4gICAgICAgIF8uZWFjaChkYXRhLCBmdW5jdGlvbiAocmVjb3JkKSB7XG4gICAgICAgICAgICBpZiAocmVjb3JkW2RpbV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJlY29yZFtkaW1dID0gY29uc3RhbnRfMS5ERUZBVUxUX1k7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDmjInnhacgZGltIOe7tOW6puWIhue7hFxuICAgICAgICByZXR1cm4gXy5ncm91cEJ5KGRhdGEsIGRpbSk7XG4gICAgfTtcbiAgICAvKiogQG92ZXJyaWRlICovXG4gICAgQWRqdXN0LnByb3RvdHlwZS5hZGp1c3REaW0gPSBmdW5jdGlvbiAoZGltLCB2YWx1ZXMsIGRhdGEsIGluZGV4KSB7IH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5Y+v6LCD5pW05bqm6YeP5a+55bqU55qE5YC8XG4gICAgICogQHBhcmFtIG1lcmdlZERhdGEg5pWw5o2uXG4gICAgICogQHJldHVybiDlgLznmoTmmKDlsIRcbiAgICAgKi9cbiAgICBBZGp1c3QucHJvdG90eXBlLmdldERpbVZhbHVlcyA9IGZ1bmN0aW9uIChtZXJnZWREYXRhKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIHhGaWVsZCA9IF9hLnhGaWVsZCwgeUZpZWxkID0gX2EueUZpZWxkO1xuICAgICAgICB2YXIgZGltVmFsdWVzTWFwID0ge307XG4gICAgICAgIC8vIOaJgOacieeahOe7tOW6plxuICAgICAgICB2YXIgZGltcyA9IFtdO1xuICAgICAgICBpZiAoeEZpZWxkICYmIHRoaXMuaXNBZGp1c3QoJ3gnKSkge1xuICAgICAgICAgICAgZGltcy5wdXNoKHhGaWVsZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHlGaWVsZCAmJiB0aGlzLmlzQWRqdXN0KCd5JykpIHtcbiAgICAgICAgICAgIGRpbXMucHVzaCh5RmllbGQpO1xuICAgICAgICB9XG4gICAgICAgIGRpbXMuZm9yRWFjaChmdW5jdGlvbiAoZGltKSB7XG4gICAgICAgICAgICAvLyDlnKjmr4/kuKrnu7TluqbkuIrvvIzmiYDmnInnmoTlgLxcbiAgICAgICAgICAgIGRpbVZhbHVlc01hcFtkaW1dID0gXy52YWx1ZXNPZktleShtZXJnZWREYXRhLCBkaW0pLnNvcnQoZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gdjEgLSB2MjsgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDlj6rmnInkuIDnu7TnmoTmg4XlhrXkuIvvvIzlkIzml7bosIPmlbQgee+8jOi1i+S6iOm7mOiupOWAvFxuICAgICAgICBpZiAoIXlGaWVsZCAmJiB0aGlzLmlzQWRqdXN0KCd5JykpIHtcbiAgICAgICAgICAgIHZhciBkaW0gPSAneSc7XG4gICAgICAgICAgICBkaW1WYWx1ZXNNYXBbZGltXSA9IFtjb25zdGFudF8xLkRFRkFVTFRfWSwgMV07IC8vIOm7mOiupOWIhuW4g+WcqCB5IOi9tOeahCAwIOS4jiAxIOS5i+mXtFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkaW1WYWx1ZXNNYXA7XG4gICAgfTtcbiAgICByZXR1cm4gQWRqdXN0O1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEFkanVzdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkanVzdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIF8gPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGFkanVzdF8xID0gcmVxdWlyZShcIi4vYWRqdXN0XCIpO1xudmFyIERvZGdlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERvZGdlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERvZGdlKGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjZmcpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmNhY2hlTWFwID0ge307XG4gICAgICAgIF90aGlzLmFkanVzdERhdGFBcnJheSA9IFtdO1xuICAgICAgICBfdGhpcy5tZXJnZURhdGEgPSBbXTtcbiAgICAgICAgdmFyIF9hID0gY2ZnLm1hcmdpblJhdGlvLCBtYXJnaW5SYXRpbyA9IF9hID09PSB2b2lkIDAgPyBjb25zdGFudF8xLk1BUkdJTl9SQVRJTyA6IF9hLCBfYiA9IGNmZy5kb2RnZVJhdGlvLCBkb2RnZVJhdGlvID0gX2IgPT09IHZvaWQgMCA/IGNvbnN0YW50XzEuRE9ER0VfUkFUSU8gOiBfYiwgZG9kZ2VCeSA9IGNmZy5kb2RnZUJ5O1xuICAgICAgICBfdGhpcy5tYXJnaW5SYXRpbyA9IG1hcmdpblJhdGlvO1xuICAgICAgICBfdGhpcy5kb2RnZVJhdGlvID0gZG9kZ2VSYXRpbztcbiAgICAgICAgX3RoaXMuZG9kZ2VCeSA9IGRvZGdlQnk7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgRG9kZ2UucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbiAoZ3JvdXBEYXRhQXJyYXkpIHtcbiAgICAgICAgdmFyIGdyb3VwZWREYXRhQXJyYXkgPSBfLmNsb25lKGdyb3VwRGF0YUFycmF5KTtcbiAgICAgICAgLy8g5bCG5pWw5o2u5pWw57uE5bGV5byA5LiA5bGCXG4gICAgICAgIHZhciBtZXJnZURhdGEgPSBfLmZsYXR0ZW4oZ3JvdXBlZERhdGFBcnJheSk7XG4gICAgICAgIHZhciBkb2RnZUJ5ID0gdGhpcy5kb2RnZUJ5O1xuICAgICAgICAvLyDlpoLmnpzmjIflrprkuobliIbnu4QgZGltIOeahOWtl+autVxuICAgICAgICB2YXIgYWRqdXN0RGF0YUFycmF5ID0gZG9kZ2VCeSA/IF8uZ3JvdXAobWVyZ2VEYXRhLCBkb2RnZUJ5KSA6IGdyb3VwZWREYXRhQXJyYXk7XG4gICAgICAgIHRoaXMuY2FjaGVNYXAgPSB7fTtcbiAgICAgICAgdGhpcy5hZGp1c3REYXRhQXJyYXkgPSBhZGp1c3REYXRhQXJyYXk7XG4gICAgICAgIHRoaXMubWVyZ2VEYXRhID0gbWVyZ2VEYXRhO1xuICAgICAgICB0aGlzLmFkanVzdERhdGEoYWRqdXN0RGF0YUFycmF5LCBtZXJnZURhdGEpO1xuICAgICAgICB0aGlzLmFkanVzdERhdGFBcnJheSA9IFtdO1xuICAgICAgICB0aGlzLm1lcmdlRGF0YSA9IFtdO1xuICAgICAgICByZXR1cm4gZ3JvdXBlZERhdGFBcnJheTtcbiAgICB9O1xuICAgIERvZGdlLnByb3RvdHlwZS5hZGp1c3REaW0gPSBmdW5jdGlvbiAoZGltLCB2YWx1ZXMsIGRhdGEsIGZyYW1lSW5kZXgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1hcCA9IHRoaXMuZ2V0RGlzdHJpYnV0aW9uKGRpbSk7XG4gICAgICAgIHZhciBncm91cERhdGEgPSB0aGlzLmdyb3VwRGF0YShkYXRhLCBkaW0pOyAvLyDmoLnmja7lgLzliIbnu4RcbiAgICAgICAgXy5lYWNoKGdyb3VwRGF0YSwgZnVuY3Rpb24gKGdyb3VwLCBrZXkpIHtcbiAgICAgICAgICAgIHZhciByYW5nZTtcbiAgICAgICAgICAgIC8vIHhGaWVsZCDkuK3lj6rmnInkuIDkuKrlgLzvvIzkuI3pnIDopoHlgZogZG9kZ2VcbiAgICAgICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgcmFuZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgIHByZTogdmFsdWVzWzBdIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgbmV4dDogdmFsdWVzWzBdICsgMSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5pyJ5aSa5Liq77yM5YiZ6ZyA6KaB6I635Y+W6LCD5pW055qE6IyD5Zu0XG4gICAgICAgICAgICAgICAgcmFuZ2UgPSBfdGhpcy5nZXRBZGp1c3RSYW5nZShkaW0sIHBhcnNlRmxvYXQoa2V5KSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF8uZWFjaChncm91cCwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBkW2RpbV07XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlQXJyID0gbWFwW3ZhbHVlXTtcbiAgICAgICAgICAgICAgICB2YXIgdmFsSW5kZXggPSB2YWx1ZUFyci5pbmRleE9mKGZyYW1lSW5kZXgpO1xuICAgICAgICAgICAgICAgIGRbZGltXSA9IF90aGlzLmdldERvZGdlT2Zmc2V0KHJhbmdlLCB2YWxJbmRleCwgdmFsdWVBcnIubGVuZ3RoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH07XG4gICAgRG9kZ2UucHJvdG90eXBlLmdldERvZGdlT2Zmc2V0ID0gZnVuY3Rpb24gKHJhbmdlLCBpZHgsIGxlbikge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBkb2RnZVJhdGlvID0gX2EuZG9kZ2VSYXRpbywgbWFyZ2luUmF0aW8gPSBfYS5tYXJnaW5SYXRpbztcbiAgICAgICAgdmFyIHByZSA9IHJhbmdlLnByZSwgbmV4dCA9IHJhbmdlLm5leHQ7XG4gICAgICAgIHZhciB0aWNrTGVuZ3RoID0gbmV4dCAtIHByZTtcbiAgICAgICAgdmFyIHdpZHRoID0gKHRpY2tMZW5ndGggKiBkb2RnZVJhdGlvKSAvIGxlbjtcbiAgICAgICAgdmFyIG1hcmdpbiA9IG1hcmdpblJhdGlvICogd2lkdGg7XG4gICAgICAgIHZhciBvZmZzZXQgPSAoMSAvIDIpICogKHRpY2tMZW5ndGggLSBsZW4gKiB3aWR0aCAtIChsZW4gLSAxKSAqIG1hcmdpbikgK1xuICAgICAgICAgICAgKChpZHggKyAxKSAqIHdpZHRoICsgaWR4ICogbWFyZ2luKSAtXG4gICAgICAgICAgICAoMSAvIDIpICogd2lkdGggLVxuICAgICAgICAgICAgKDEgLyAyKSAqIHRpY2tMZW5ndGg7XG4gICAgICAgIHJldHVybiAocHJlICsgbmV4dCkgLyAyICsgb2Zmc2V0O1xuICAgIH07XG4gICAgRG9kZ2UucHJvdG90eXBlLmdldERpc3RyaWJ1dGlvbiA9IGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgdmFyIGdyb3VwZWREYXRhQXJyYXkgPSB0aGlzLmFkanVzdERhdGFBcnJheTtcbiAgICAgICAgdmFyIGNhY2hlTWFwID0gdGhpcy5jYWNoZU1hcDtcbiAgICAgICAgdmFyIG1hcCA9IGNhY2hlTWFwW2RpbV07XG4gICAgICAgIGlmICghbWFwKSB7XG4gICAgICAgICAgICBtYXAgPSB7fTtcbiAgICAgICAgICAgIF8uZWFjaChncm91cGVkRGF0YUFycmF5LCBmdW5jdGlvbiAoZGF0YSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gXy52YWx1ZXNPZktleShkYXRhLCBkaW0pO1xuICAgICAgICAgICAgICAgIGlmICghdmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXy5lYWNoKHZhbHVlcywgZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW1hcFt2YWxdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXBbdmFsXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG1hcFt2YWxdLnB1c2goaW5kZXgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjYWNoZU1hcFtkaW1dID0gbWFwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgfTtcbiAgICByZXR1cm4gRG9kZ2U7XG59KGFkanVzdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IERvZGdlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZG9kZ2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBfID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBhZGp1c3RfMSA9IHJlcXVpcmUoXCIuL2FkanVzdFwiKTtcbmZ1bmN0aW9uIHJhbmRvbU51bWJlcihtaW4sIG1heCkge1xuICAgIHJldHVybiAobWF4IC0gbWluKSAqIE1hdGgucmFuZG9tKCkgKyBtaW47XG59XG52YXIgSml0dGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEppdHRlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBKaXR0ZXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgSml0dGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24gKGdyb3VwRGF0YUFycmF5KSB7XG4gICAgICAgIHZhciBncm91cGVkRGF0YUFycmF5ID0gXy5jbG9uZShncm91cERhdGFBcnJheSk7XG4gICAgICAgIC8vIOS5i+WJjeWIhue7hOS5i+WQjueahOaVsOaNru+8jOeEtuWQjuacieWQiOW5tuWbnuWOu++8iOWSjOWIhue7hOWJjeWPr+S7peeQhuino+aIkOaYr+S4gOagt+eahO+8iVxuICAgICAgICB2YXIgbWVyZ2VEYXRhID0gXy5mbGF0dGVuKGdyb3VwZWREYXRhQXJyYXkpO1xuICAgICAgICAvLyDov5Tlm57lgLxcbiAgICAgICAgdGhpcy5hZGp1c3REYXRhKGdyb3VwZWREYXRhQXJyYXksIG1lcmdlRGF0YSk7XG4gICAgICAgIHJldHVybiBncm91cGVkRGF0YUFycmF5O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5b2T5YmN5pWw5o2u5YiG57uE77yIaW5kZXjvvInkuK3vvIzmjInnhafnu7TluqYgZGltIOi/m+ihjCBqaXR0ZXIg6LCD5pW0XG4gICAgICogQHBhcmFtIGRpbVxuICAgICAqIEBwYXJhbSB2YWx1ZXNcbiAgICAgKiBAcGFyYW0gZGF0YUFycmF5XG4gICAgICovXG4gICAgSml0dGVyLnByb3RvdHlwZS5hZGp1c3REaW0gPSBmdW5jdGlvbiAoZGltLCB2YWx1ZXMsIGRhdGFBcnJheSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAvLyDlnKjmr4/kuIDkuKrliIbnu4TkuK3vvIzlsIbmlbDmja7lho3mjInnhacgZGltIOWIhue7hO+8jOeUqOS6juaVo+WIl1xuICAgICAgICB2YXIgZ3JvdXBEYXRhQXJyYXkgPSB0aGlzLmdyb3VwRGF0YShkYXRhQXJyYXksIGRpbSk7XG4gICAgICAgIHJldHVybiBfLmVhY2goZ3JvdXBEYXRhQXJyYXksIGZ1bmN0aW9uIChkYXRhLCBkaW1WYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmFkanVzdEdyb3VwKGRhdGEsIGRpbSwgcGFyc2VGbG9hdChkaW1WYWx1ZSksIHZhbHVlcyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g6ZqP5py65Ye65p2l55qE5a2X5q615YC8XG4gICAgSml0dGVyLnByb3RvdHlwZS5nZXRBZGp1c3RPZmZzZXQgPSBmdW5jdGlvbiAocmFuZ2UpIHtcbiAgICAgICAgdmFyIHByZSA9IHJhbmdlLnByZSwgbmV4dCA9IHJhbmdlLm5leHQ7XG4gICAgICAgIC8vIOmaj+acuueahOiMg+WbtFxuICAgICAgICB2YXIgbWFyZ2luID0gKG5leHQgLSBwcmUpICogY29uc3RhbnRfMS5HQVA7XG4gICAgICAgIHJldHVybiByYW5kb21OdW1iZXIocHJlICsgbWFyZ2luLCBuZXh0IC0gbWFyZ2luKTtcbiAgICB9O1xuICAgIC8vIGFkanVzdCBncm91cCBkYXRhXG4gICAgSml0dGVyLnByb3RvdHlwZS5hZGp1c3RHcm91cCA9IGZ1bmN0aW9uIChncm91cCwgZGltLCBkaW1WYWx1ZSwgdmFsdWVzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIC8vIOiwg+aVtOiMg+WbtFxuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdldEFkanVzdFJhbmdlKGRpbSwgZGltVmFsdWUsIHZhbHVlcyk7XG4gICAgICAgIF8uZWFjaChncm91cCwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIGRhdGFbZGltXSA9IF90aGlzLmdldEFkanVzdE9mZnNldChyYW5nZSk7IC8vIOiOt+WPluiwg+aVtOeahOS9jee9rlxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGdyb3VwO1xuICAgIH07XG4gICAgcmV0dXJuIEppdHRlcjtcbn0oYWRqdXN0XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSml0dGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aml0dGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgXyA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGFkanVzdF8xID0gcmVxdWlyZShcIi4vYWRqdXN0XCIpO1xudmFyIENhY2hlID0gXy5DYWNoZTtcbnZhciBTdGFjayA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTdGFjaywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFjayhjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICB2YXIgX2EgPSBjZmcuYWRqdXN0TmFtZXMsIGFkanVzdE5hbWVzID0gX2EgPT09IHZvaWQgMCA/IFsneSddIDogX2EsIF9iID0gY2ZnLmhlaWdodCwgaGVpZ2h0ID0gX2IgPT09IHZvaWQgMCA/IE5hTiA6IF9iLCBfYyA9IGNmZy5zaXplLCBzaXplID0gX2MgPT09IHZvaWQgMCA/IDEwIDogX2MsIF9kID0gY2ZnLnJldmVyc2VPcmRlciwgcmV2ZXJzZU9yZGVyID0gX2QgPT09IHZvaWQgMCA/IGZhbHNlIDogX2Q7XG4gICAgICAgIF90aGlzLmFkanVzdE5hbWVzID0gYWRqdXN0TmFtZXM7XG4gICAgICAgIF90aGlzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgX3RoaXMuc2l6ZSA9IHNpemU7XG4gICAgICAgIF90aGlzLnJldmVyc2VPcmRlciA9IHJldmVyc2VPcmRlcjtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDmlrnms5XlhaXlj4LmmK/nu4/ov4fmlbDmja7liIbnu4TjgIHmlbDmja7mlbDlrZfljJbkuYvlkI7nmoTkuoznu7TmlbDnu4RcbiAgICAgKiBAcGFyYW0gZ3JvdXBEYXRhQXJyYXkg5YiG57uE5LmL5ZCO55qE5pWw5o2uXG4gICAgICovXG4gICAgU3RhY2sucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbiAoZ3JvdXBEYXRhQXJyYXkpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcywgeUZpZWxkID0gX2EueUZpZWxkLCByZXZlcnNlT3JkZXIgPSBfYS5yZXZlcnNlT3JkZXI7XG4gICAgICAgIC8vIOWmguaenOacieaMh+WumiB5IOWtl+aute+8jOmCo+S5iOaMieeFpyB5IOWtl+auteadpSBzdGFja1xuICAgICAgICAvLyDlkKbliJnvvIzmjInnhafpq5jluqblnYfliIZcbiAgICAgICAgdmFyIGQgPSB5RmllbGQgPyB0aGlzLnByb2Nlc3NTdGFjayhncm91cERhdGFBcnJheSkgOiB0aGlzLnByb2Nlc3NPbmVEaW1TdGFjayhncm91cERhdGFBcnJheSk7XG4gICAgICAgIHJldHVybiByZXZlcnNlT3JkZXIgPyB0aGlzLnJldmVyc2UoZCkgOiBkO1xuICAgIH07XG4gICAgU3RhY2sucHJvdG90eXBlLnJldmVyc2UgPSBmdW5jdGlvbiAoZ3JvdXBlZERhdGFBcnJheSkge1xuICAgICAgICByZXR1cm4gZ3JvdXBlZERhdGFBcnJheS5zbGljZSgwKS5yZXZlcnNlKCk7XG4gICAgfTtcbiAgICBTdGFjay5wcm90b3R5cGUucHJvY2Vzc1N0YWNrID0gZnVuY3Rpb24gKGdyb3VwRGF0YUFycmF5KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIHhGaWVsZCA9IF9hLnhGaWVsZCwgeUZpZWxkID0gX2EueUZpZWxkLCByZXZlcnNlT3JkZXIgPSBfYS5yZXZlcnNlT3JkZXI7XG4gICAgICAgIC8vIOWxguWPoOmhuuW6j+e/u+i9rFxuICAgICAgICB2YXIgZ3JvdXBlZERhdGFBcnJheSA9IHJldmVyc2VPcmRlciA/IHRoaXMucmV2ZXJzZShncm91cERhdGFBcnJheSkgOiBncm91cERhdGFBcnJheTtcbiAgICAgICAgLy8g55So5p2l57yT5a2Y77yM5q2j5pWw5ZKM6LSf5pWw55qE5aCG5Y+g6Zeu6aKYXG4gICAgICAgIHZhciBwb3NpdGl2ZSA9IG5ldyBDYWNoZSgpO1xuICAgICAgICB2YXIgbmVnYXRpdmUgPSBuZXcgQ2FjaGUoKTtcbiAgICAgICAgcmV0dXJuIGdyb3VwZWREYXRhQXJyYXkubWFwKGZ1bmN0aW9uIChkYXRhQXJyYXkpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhQXJyYXkubWFwKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgICAgIHZhciB4ID0gXy5nZXQoZGF0YSwgeEZpZWxkLCAwKTtcbiAgICAgICAgICAgICAgICB2YXIgeSA9IF8uZ2V0KGRhdGEsIHlGaWVsZCk7XG4gICAgICAgICAgICAgICAgdmFyIHhLZXkgPSB4LnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgLy8gdG9kbyDmmK/lkKblupTor6Xlj5YgX29yaWdpbu+8n+WboOS4uiB5IOWPr+iDveWPluWIsOeahOWAvOS4jeato+ehru+8jOavlOWmguWFiCBzeW1tZXRyaWPvvIzlho0gc3RhY2vvvIFcbiAgICAgICAgICAgICAgICB5ID0gXy5pc0FycmF5KHkpID8geVsxXSA6IHk7XG4gICAgICAgICAgICAgICAgaWYgKCFfLmlzTmlsKHkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWNoZSA9IHkgPj0gMCA/IHBvc2l0aXZlIDogbmVnYXRpdmU7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FjaGUuaGFzKHhLZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5zZXQoeEtleSwgMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhWYWx1ZSA9IGNhY2hlLmdldCh4S2V5KTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1hWYWx1ZSA9IHkgKyB4VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIOWtmOi1t+adpVxuICAgICAgICAgICAgICAgICAgICBjYWNoZS5zZXQoeEtleSwgbmV3WFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgZGF0YSksIChfYSA9IHt9LCBfYVt5RmllbGRdID0gW3hWYWx1ZSwgbmV3WFZhbHVlXSwgX2EpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g5rKh5pyJ5L+u5pS577yM5YiZ55u05o6l6L+U5ZueXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBTdGFjay5wcm90b3R5cGUucHJvY2Vzc09uZURpbVN0YWNrID0gZnVuY3Rpb24gKGdyb3VwRGF0YUFycmF5KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIHhGaWVsZCA9IF9hLnhGaWVsZCwgaGVpZ2h0ID0gX2EuaGVpZ2h0LCByZXZlcnNlT3JkZXIgPSBfYS5yZXZlcnNlT3JkZXI7XG4gICAgICAgIHZhciB5RmllbGQgPSAneSc7XG4gICAgICAgIC8vIOWmguaenOWxguWPoOeahOmhuuW6j+e/u+i9rFxuICAgICAgICB2YXIgZ3JvdXBlZERhdGFBcnJheSA9IHJldmVyc2VPcmRlciA/IHRoaXMucmV2ZXJzZShncm91cERhdGFBcnJheSkgOiBncm91cERhdGFBcnJheTtcbiAgICAgICAgLy8g57yT5a2Y57Sv5Yqg5pWw5o2uXG4gICAgICAgIHZhciBjYWNoZSA9IG5ldyBDYWNoZSgpO1xuICAgICAgICByZXR1cm4gZ3JvdXBlZERhdGFBcnJheS5tYXAoZnVuY3Rpb24gKGRhdGFBcnJheSkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGFBcnJheS5tYXAoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgdmFyIHNpemUgPSBfdGhpcy5zaXplO1xuICAgICAgICAgICAgICAgIHZhciB4VmFsdWUgPSBkYXRhW3hGaWVsZF07XG4gICAgICAgICAgICAgICAgLy8gdG9kbyDmsqHmnInnnIvliLDov5nkuKogc3RhY2sg6K6h566X5Y6f55CGXG4gICAgICAgICAgICAgICAgdmFyIHN0YWNrSGVpZ2h0ID0gKHNpemUgKiAyKSAvIGhlaWdodDtcbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlLmhhcyh4VmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhY2hlLnNldCh4VmFsdWUsIHN0YWNrSGVpZ2h0IC8gMik7IC8vIOWIneWni+WAvOWkp+Wwj1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgc3RhY2tWYWx1ZSA9IGNhY2hlLmdldCh4VmFsdWUpO1xuICAgICAgICAgICAgICAgIC8vIOWinuWKoOS4gOWxgiBzdGFja0hlaWdodFxuICAgICAgICAgICAgICAgIGNhY2hlLnNldCh4VmFsdWUsIHN0YWNrVmFsdWUgKyBzdGFja0hlaWdodCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgZGF0YSksIChfYSA9IHt9LCBfYVt5RmllbGRdID0gc3RhY2tWYWx1ZSwgX2EpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTdGFjaztcbn0oYWRqdXN0XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2s7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGFjay5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIF8gPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBhZGp1c3RfMSA9IHJlcXVpcmUoXCIuL2FkanVzdFwiKTtcbnZhciBTeW1tZXRyaWMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3ltbWV0cmljLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFN5bW1ldHJpYygpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBTeW1tZXRyaWMucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbiAoZ3JvdXBEYXRhQXJyYXkpIHtcbiAgICAgICAgdmFyIG1lcmdlRGF0YSA9IF8uZmxhdHRlbihncm91cERhdGFBcnJheSk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIHhGaWVsZCA9IF9hLnhGaWVsZCwgeUZpZWxkID0gX2EueUZpZWxkO1xuICAgICAgICAvLyDmr4/kuKogeCDlgLzlr7nlupTnmoQg5pyA5aSn5YC8XG4gICAgICAgIHZhciBjYWNoZSA9IHRoaXMuZ2V0WFZhbHVlc01heE1hcChtZXJnZURhdGEpO1xuICAgICAgICAvLyDmiYDmnInmlbDmja7nmoTmnIDlpKfnmoTlgLxcbiAgICAgICAgdmFyIG1heCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIE9iamVjdC5rZXlzKGNhY2hlKS5tYXAoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gY2FjaGVba2V5XTsgfSkpO1xuICAgICAgICByZXR1cm4gXy5tYXAoZ3JvdXBEYXRhQXJyYXksIGZ1bmN0aW9uIChkYXRhQXJyYXkpIHtcbiAgICAgICAgICAgIHJldHVybiBfLm1hcChkYXRhQXJyYXksIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgICAgICAgICB2YXIgeVZhbHVlID0gZGF0YVt5RmllbGRdO1xuICAgICAgICAgICAgICAgIHZhciB4VmFsdWUgPSBkYXRhW3hGaWVsZF07XG4gICAgICAgICAgICAgICAgLy8g5pWw57uE5aSE55CG6YC76L6RXG4gICAgICAgICAgICAgICAgaWYgKF8uaXNBcnJheSh5VmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBvZmZfMSA9IChtYXggLSBjYWNoZVt4VmFsdWVdKSAvIDI7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGRhdGEpLCAoX2EgPSB7fSwgX2FbeUZpZWxkXSA9IF8ubWFwKHlWYWx1ZSwgZnVuY3Rpb24gKHkpIHsgcmV0dXJuIG9mZl8xICsgeTsgfSksIF9hKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOmdnuaVsOe7hOWkhOeQhumAu+i+kVxuICAgICAgICAgICAgICAgIHZhciBvZmZzZXQgPSAobWF4IC0geVZhbHVlKSAvIDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgZGF0YSksIChfYiA9IHt9LCBfYlt5RmllbGRdID0gW29mZnNldCwgeVZhbHVlICsgb2Zmc2V0XSwgX2IpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOiOt+WPluavj+S4qiB4IOWvueW6lOeahOacgOWkp+eahOWAvFxuICAgIFN5bW1ldHJpYy5wcm90b3R5cGUuZ2V0WFZhbHVlc01heE1hcCA9IGZ1bmN0aW9uIChtZXJnZURhdGEpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcywgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQ7XG4gICAgICAgIC8vIOagueaNriB4RmllbGQg55qE5YC86L+b6KGM5YiG57uEXG4gICAgICAgIHZhciBncm91cERhdGFBcnJheSA9IF8uZ3JvdXBCeShtZXJnZURhdGEsIGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhW3hGaWVsZF07IH0pO1xuICAgICAgICAvLyDojrflj5bmr4/kuKogeEZpZWxkIOWAvOS4reeahOacgOWkp+WAvFxuICAgICAgICByZXR1cm4gXy5tYXBWYWx1ZXMoZ3JvdXBEYXRhQXJyYXksIGZ1bmN0aW9uIChkYXRhQXJyYXkpIHsgcmV0dXJuIF90aGlzLmdldERpbU1heFZhbHVlKGRhdGFBcnJheSwgeUZpZWxkKTsgfSk7XG4gICAgfTtcbiAgICBTeW1tZXRyaWMucHJvdG90eXBlLmdldERpbU1heFZhbHVlID0gZnVuY3Rpb24gKG1lcmdlRGF0YSwgZGltKSB7XG4gICAgICAgIC8vIOaJgOacieeahCB2YWx1ZSDlgLxcbiAgICAgICAgdmFyIGRpbVZhbHVlcyA9IF8ubWFwKG1lcmdlRGF0YSwgZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIF8uZ2V0KGRhdGEsIGRpbSwgW10pOyB9KTtcbiAgICAgICAgLy8g5bCG5pWw57uE5omT5bmz77yIZGltIHZhbHVlIOacieWPr+iDveaYr+aVsOe7hO+8jOavlOWmgiBzdGFjayDkuYvlkI7nmoTvvIlcbiAgICAgICAgdmFyIGZsYXR0ZW5WYWx1ZXMgPSBfLmZsYXR0ZW4oZGltVmFsdWVzKTtcbiAgICAgICAgLy8g5rGC5Ye65pWw57uE55qE5pyA5aSn5YC8XG4gICAgICAgIHJldHVybiBNYXRoLm1heC5hcHBseShNYXRoLCBmbGF0dGVuVmFsdWVzKTtcbiAgICB9O1xuICAgIHJldHVybiBTeW1tZXRyaWM7XG59KGFkanVzdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN5bW1ldHJpYztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN5bW1ldHJpYy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuREVGQVVMVF9ZID0gMDsgLy8g6buY6K6k55qEIHkg55qE5YC8XG4vLyDlgY/np7vkuYvlkI7vvIzpl7Tot51cbmV4cG9ydHMuTUFSR0lOX1JBVElPID0gMSAvIDI7XG5leHBvcnRzLkRPREdFX1JBVElPID0gMSAvIDI7XG4vLyDmlaPngrnliIblvIDkuYvlkI7vvIzot53nprvovrnnlYznmoTot53nprtcbmV4cG9ydHMuR0FQID0gMC4wNTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGFkanVzdF8xID0gcmVxdWlyZShcIi4vYWRqdXN0cy9hZGp1c3RcIik7XG5leHBvcnRzLkFkanVzdCA9IGFkanVzdF8xLmRlZmF1bHQ7XG52YXIgQURKVVNUX01BUCA9IHt9O1xuLyoqXG4gKiDmoLnmja7nsbvlnovojrflj5YgQWRqdXN0IOexu1xuICogQHBhcmFtIHR5cGVcbiAqL1xudmFyIGdldEFkanVzdCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgcmV0dXJuIEFESlVTVF9NQVBbdHlwZS50b0xvd2VyQ2FzZSgpXTtcbn07XG5leHBvcnRzLmdldEFkanVzdCA9IGdldEFkanVzdDtcbi8qKlxuICog5rOo5YaM6Ieq5a6a5LmJIEFkanVzdFxuICogQHBhcmFtIHR5cGVcbiAqIEBwYXJhbSBjdG9yXG4gKi9cbnZhciByZWdpc3RlckFkanVzdCA9IGZ1bmN0aW9uICh0eXBlLCBjdG9yKSB7XG4gICAgLy8g5rOo5YaM55qE5pe25YCZ77yM6ZyA6KaB5qCh6aqMIHR5cGUg6YeN5ZCN77yM5LiN5Yy65YiG5aSn5bCP5YaZXG4gICAgaWYgKGdldEFkanVzdCh0eXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBZGp1c3QgdHlwZSAnXCIgKyB0eXBlICsgXCInIGV4aXN0ZWQuXCIpO1xuICAgIH1cbiAgICAvLyDlrZjlgqjliLAgbWFwIOS4rVxuICAgIEFESlVTVF9NQVBbdHlwZS50b0xvd2VyQ2FzZSgpXSA9IGN0b3I7XG59O1xuZXhwb3J0cy5yZWdpc3RlckFkanVzdCA9IHJlZ2lzdGVyQWRqdXN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmFjdG9yeS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi9mYWN0b3J5XCIpO1xuZXhwb3J0cy5nZXRBZGp1c3QgPSBmYWN0b3J5XzEuZ2V0QWRqdXN0O1xuZXhwb3J0cy5yZWdpc3RlckFkanVzdCA9IGZhY3RvcnlfMS5yZWdpc3RlckFkanVzdDtcbnZhciBhZGp1c3RfMSA9IHJlcXVpcmUoXCIuL2FkanVzdHMvYWRqdXN0XCIpO1xuZXhwb3J0cy5BZGp1c3QgPSBhZGp1c3RfMS5kZWZhdWx0O1xudmFyIGRvZGdlXzEgPSByZXF1aXJlKFwiLi9hZGp1c3RzL2RvZGdlXCIpO1xudmFyIGppdHRlcl8xID0gcmVxdWlyZShcIi4vYWRqdXN0cy9qaXR0ZXJcIik7XG52YXIgc3RhY2tfMSA9IHJlcXVpcmUoXCIuL2FkanVzdHMvc3RhY2tcIik7XG52YXIgc3ltbWV0cmljXzEgPSByZXF1aXJlKFwiLi9hZGp1c3RzL3N5bW1ldHJpY1wiKTtcbi8vIOazqOWGjOWGhee9rueahCBhZGp1c3RcbmZhY3RvcnlfMS5yZWdpc3RlckFkanVzdCgnRG9kZ2UnLCBkb2RnZV8xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyQWRqdXN0KCdKaXR0ZXInLCBqaXR0ZXJfMS5kZWZhdWx0KTtcbmZhY3RvcnlfMS5yZWdpc3RlckFkanVzdCgnU3RhY2snLCBzdGFja18xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyQWRqdXN0KCdTeW1tZXRyaWMnLCBzeW1tZXRyaWNfMS5kZWZhdWx0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLy8gdG9kbyDov5nkuKrliLDlupXnm67nmoTmmK/ku4DkuYjvvJ9cbnZhciB0b1NjYWxlU3RyaW5nID0gZnVuY3Rpb24gKHNjYWxlLCB2YWx1ZSkge1xuICAgIGlmICh1dGlsXzEuaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHNjYWxlLmludmVydChzY2FsZS5zY2FsZSh2YWx1ZSkpO1xufTtcbi8qKlxuICog5omA5pyJ6KeG6KeJ6YCa6YGT5bGe5oCn55qE5Z+657G7XG4gKiBAY2xhc3MgQmFzZVxuICovXG52YXIgQXR0cmlidXRlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEF0dHJpYnV0ZShjZmcpIHtcbiAgICAgICAgdGhpcy5uYW1lcyA9IFtdO1xuICAgICAgICB0aGlzLnNjYWxlcyA9IFtdO1xuICAgICAgICB0aGlzLmxpbmVhciA9IGZhbHNlO1xuICAgICAgICB0aGlzLnZhbHVlcyA9IFtdO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gW107IH07XG4gICAgICAgIC8vIOino+aekOmFjee9rlxuICAgICAgICB0aGlzLl9wYXJzZUNmZyhjZmcpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDmmKDlsITnmoTlgLznu4TmiJDnmoTmlbDnu4RcbiAgICAgKiBAcGFyYW0gcGFyYW1zIOWvueW6lCBzY2FsZSDpobrluo/nmoTlgLzkvKDlhaVcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGUucHJvdG90eXBlLm1hcHBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwYXJhbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHBhcmFtc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2YWx1ZXMgPSBwYXJhbXMubWFwKGZ1bmN0aW9uIChwYXJhbSwgaWR4KSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuX3RvT3JpZ2luUGFyYW0ocGFyYW0sIF90aGlzLnNjYWxlc1tpZHhdKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGxiYWNrLmFwcGx5KHRoaXMsIHZhbHVlcyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlpoLmnpzov5vooYznur/mgKfmmKDlsITvvIzov5Tlm57lr7nlupTnmoTmmKDlsITlgLxcbiAgICAgKiBAcGFyYW0gcGVyY2VudFxuICAgICAqL1xuICAgIEF0dHJpYnV0ZS5wcm90b3R5cGUuZ2V0TGluZWFyVmFsdWUgPSBmdW5jdGlvbiAocGVyY2VudCkge1xuICAgICAgICAvLyDliIbmrrXmlbDph49cbiAgICAgICAgdmFyIHN0ZXBzID0gdGhpcy52YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICAgICAgdmFyIHN0ZXAgPSBNYXRoLmZsb29yKHN0ZXBzICogcGVyY2VudCk7XG4gICAgICAgIHZhciBsZWZ0UGVyY2VudCA9IHN0ZXBzICogcGVyY2VudCAtIHN0ZXA7XG4gICAgICAgIC8vIHRvZG8g5LiN5oeC6L+Z5Liq6YC76L6RXG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMudmFsdWVzW3N0ZXBdO1xuICAgICAgICB2YXIgZW5kID0gc3RlcCA9PT0gc3RlcHMgPyBzdGFydCA6IHRoaXMudmFsdWVzW3N0ZXAgKyAxXTtcbiAgICAgICAgLy8g57q/5oCn5pa556iLXG4gICAgICAgIHJldHVybiBzdGFydCArIChlbmQgLSBzdGFydCkgKiBsZWZ0UGVyY2VudDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNruW6pumHj+iOt+WPluWxnuaAp+WQjVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZS5wcm90b3R5cGUuZ2V0TmFtZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLnNjYWxlcztcbiAgICAgICAgdmFyIG5hbWVzID0gdGhpcy5uYW1lcztcbiAgICAgICAgdmFyIGxlbmd0aCA9IE1hdGgubWluKHNjYWxlcy5sZW5ndGgsIG5hbWVzLmxlbmd0aCk7XG4gICAgICAgIHZhciByc3QgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgcnN0LnB1c2gobmFtZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmiYDmnInnmoTnu7TluqblkI1cbiAgICAgKi9cbiAgICBBdHRyaWJ1dGUucHJvdG90eXBlLmdldEZpZWxkcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2NhbGVzLm1hcChmdW5jdGlvbiAoc2NhbGUpIHsgcmV0dXJuIHNjYWxlLmZpZWxkOyB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNruWQjeensOiOt+WPluW6pumHj1xuICAgICAqIEBwYXJhbSBuYW1lXG4gICAgICovXG4gICAgQXR0cmlidXRlLnByb3RvdHlwZS5nZXRTY2FsZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNjYWxlc1t0aGlzLm5hbWVzLmluZGV4T2YobmFtZSldO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6buY6K6k55qE5Zue6LCD5Ye95pWw77yI55So5oi35rKh5pyJ6Ieq5a6a5LmJIGNhbGxiYWNr77yM5oiW6ICF55So5oi36Ieq5a6a5LmJIGNhbGxiYWNrIOi/lOWbnuepuueahOaXtuWAme+8jOS9v+eUqCB2YWx1ZXMg5pig5bCE77yJXG4gICAgICogQHBhcmFtIHBhcmFtc1xuICAgICAqL1xuICAgIEF0dHJpYnV0ZS5wcm90b3R5cGUuZGVmYXVsdENhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgcGFyYW1zID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBwYXJhbXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICAvLyDmsqHmnIkgcGFyYW1zIOeahOaDheWGte+8jOaYr+aMh+ayoeacieaMh+WumiBmaWVsZHPvvIznm7TmjqXov5Tlm57phY3nva7nmoQgdmFsdWVzIOW4uOmHj1xuICAgICAgICBpZiAocGFyYW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJhbXMubWFwKGZ1bmN0aW9uIChwYXJhbSwgaWR4KSB7XG4gICAgICAgICAgICB2YXIgc2NhbGUgPSBfdGhpcy5zY2FsZXNbaWR4XTtcbiAgICAgICAgICAgIHJldHVybiBzY2FsZS50eXBlID09PSAnaWRlbnRpdHknID8gc2NhbGUudmFsdWVzWzBdIDogX3RoaXMuX2dldEF0dHJpYnV0ZVZhbHVlKHNjYWxlLCBwYXJhbSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g6Kej5p6Q6YWN572uXG4gICAgQXR0cmlidXRlLnByb3RvdHlwZS5fcGFyc2VDZmcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IGNmZy50eXBlLCB0eXBlID0gX2EgPT09IHZvaWQgMCA/ICdiYXNlJyA6IF9hLCBfYiA9IGNmZy5uYW1lcywgbmFtZXMgPSBfYiA9PT0gdm9pZCAwID8gW10gOiBfYiwgX2MgPSBjZmcuc2NhbGVzLCBzY2FsZXMgPSBfYyA9PT0gdm9pZCAwID8gW10gOiBfYywgX2QgPSBjZmcudmFsdWVzLCB2YWx1ZXMgPSBfZCA9PT0gdm9pZCAwID8gW10gOiBfZCwgY2FsbGJhY2sgPSBjZmcuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuc2NhbGVzID0gc2NhbGVzO1xuICAgICAgICB0aGlzLnZhbHVlcyA9IHZhbHVlcztcbiAgICAgICAgdGhpcy5uYW1lcyA9IG5hbWVzO1xuICAgICAgICAvLyDmnoTpgKAgY2FsbGJhY2sg5pa55rOVXG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHBhcmFtc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDlvZPnlKjmiLforr7nva7nmoQgY2FsbGJhY2sg6L+U5ZueIG51bGwg5pe2LCDlupTor6Xov5Tlm57pu5jorqQgY2FsbGJhY2sg5Lit55qE5YC8XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIC8vIOS9v+eUqOeUqOaIt+i/lOWbnueahOWAvOWkhOeQhlxuICAgICAgICAgICAgICAgIHZhciByZXQgPSBjYWxsYmFjay5hcHBseSh2b2lkIDAsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwocmV0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW3JldF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5rKh5pyJIGNhbGxiYWNrIOaIluiAheeUqOaItyBjYWxsYmFjayDov5Tlm57lgLzkuLrnqbrvvIzliJnkvb/nlKjpu5jorqTnmoTpgLvovpHlpITnkIZcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5kZWZhdWx0Q2FsbGJhY2suYXBwbHkoX3RoaXMsIHBhcmFtcyk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvLyDojrflj5blsZ7mgKflgLzvvIzlsIblgLzmmKDlsITliLDop4bop4npgJrpgZNcbiAgICBBdHRyaWJ1dGUucHJvdG90eXBlLl9nZXRBdHRyaWJ1dGVWYWx1ZSA9IGZ1bmN0aW9uIChzY2FsZSwgdmFsdWUpIHtcbiAgICAgICAgLy8g5aaC5p6c5piv6Z2e57q/5oCn55qE5a2X5q6177yM55u05o6l5LuOIHZhbHVlcyDkuK3lj5blgLzljbPlj69cbiAgICAgICAgaWYgKHNjYWxlLmlzQ2F0ZWdvcnkgJiYgIXRoaXMubGluZWFyKSB7XG4gICAgICAgICAgICAvLyDnprvmlaMgc2NhbGUg5Y+Y5o2i5oiQ57Si5byVXG4gICAgICAgICAgICB2YXIgaWR4ID0gc2NhbGUudHJhbnNsYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlc1tpZHggJSB0aGlzLnZhbHVlcy5sZW5ndGhdO1xuICAgICAgICB9XG4gICAgICAgIC8vIOe6v+aAp+WImeS9v+eUqOe6v+aAp+WAvFxuICAgICAgICB2YXIgcGVyY2VudCA9IHNjYWxlLnNjYWxlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZWFyVmFsdWUocGVyY2VudCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpgJrov4cgc2NhbGUg5ou/5Yiw5pWw5o2u5a+55bqU55qE5Y6f5aeL55qE5Y+C5pWwXG4gICAgICogQHBhcmFtIHBhcmFtXG4gICAgICogQHBhcmFtIHNjYWxlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGUucHJvdG90eXBlLl90b09yaWdpblBhcmFtID0gZnVuY3Rpb24gKHBhcmFtLCBzY2FsZSkge1xuICAgICAgICAvLyDmmK/nur/mgKfvvIznm7TmjqXov5Tlm55cbiAgICAgICAgLy8g6Z2e57q/5oCn77yM5L2/55SoIHNjYWxlIOWPmOaNolxuICAgICAgICByZXR1cm4gIXNjYWxlLmlzTGluZWFyXG4gICAgICAgICAgICA/IHV0aWxfMS5pc0FycmF5KHBhcmFtKVxuICAgICAgICAgICAgICAgID8gcGFyYW0ubWFwKGZ1bmN0aW9uIChwKSB7IHJldHVybiB0b1NjYWxlU3RyaW5nKHNjYWxlLCBwKTsgfSlcbiAgICAgICAgICAgICAgICA6IHRvU2NhbGVTdHJpbmcoc2NhbGUsIHBhcmFtKVxuICAgICAgICAgICAgOiBwYXJhbTtcbiAgICB9O1xuICAgIHJldHVybiBBdHRyaWJ1dGU7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXR0cmlidXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGNvbG9yX3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9jb2xvci11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgQ29sb3IgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ29sb3IsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ29sb3IoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdjb2xvcic7XG4gICAgICAgIF90aGlzLm5hbWVzID0gWydjb2xvciddO1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKF90aGlzLnZhbHVlcykpIHtcbiAgICAgICAgICAgIF90aGlzLmxpbmVhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgX3RoaXMuZ3JhZGllbnQgPSBjb2xvcl91dGlsXzEuZGVmYXVsdC5ncmFkaWVudChfdGhpcy52YWx1ZXMpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIENvbG9yLnByb3RvdHlwZS5nZXRMaW5lYXJWYWx1ZSA9IGZ1bmN0aW9uIChwZXJjZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyYWRpZW50KHBlcmNlbnQpO1xuICAgIH07XG4gICAgcmV0dXJuIENvbG9yO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sb3I7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb2xvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgT3BhY2l0eSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhPcGFjaXR5LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIE9wYWNpdHkoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdvcGFjaXR5JztcbiAgICAgICAgX3RoaXMubmFtZXMgPSBbJ29wYWNpdHknXTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICByZXR1cm4gT3BhY2l0eTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE9wYWNpdHk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vcGFjaXR5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBQb3NpdGlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQb3NpdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQb3NpdGlvbihjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5uYW1lcyA9IFsneCcsICd5J107XG4gICAgICAgIF90aGlzLnR5cGUgPSAncG9zaXRpb24nO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFBvc2l0aW9uLnByb3RvdHlwZS5tYXBwaW5nID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5zY2FsZXMsIHNjYWxlWCA9IF9hWzBdLCBzY2FsZVkgPSBfYVsxXTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc05pbCh4KSB8fCB1dGlsXzEuaXNOaWwoeSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgdXRpbF8xLmlzQXJyYXkoeCkgPyB4Lm1hcChmdW5jdGlvbiAoeGkpIHsgcmV0dXJuIHNjYWxlWC5zY2FsZSh4aSk7IH0pIDogc2NhbGVYLnNjYWxlKHgpLFxuICAgICAgICAgICAgdXRpbF8xLmlzQXJyYXkoeSkgPyB5Lm1hcChmdW5jdGlvbiAoeWkpIHsgcmV0dXJuIHNjYWxlWS5zY2FsZSh5aSk7IH0pIDogc2NhbGVZLnNjYWxlKHkpLFxuICAgICAgICBdO1xuICAgIH07XG4gICAgcmV0dXJuIFBvc2l0aW9uO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG9zaXRpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb3NpdGlvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgU2hhcGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2hhcGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2hhcGUoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdzaGFwZSc7XG4gICAgICAgIF90aGlzLm5hbWVzID0gWydzaGFwZSddO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIFNoYXBlLnByb3RvdHlwZS5nZXRMaW5lYXJWYWx1ZSA9IGZ1bmN0aW9uIChwZXJjZW50KSB7XG4gICAgICAgIHZhciBpZHggPSBNYXRoLnJvdW5kKCh0aGlzLnZhbHVlcy5sZW5ndGggLSAxKSAqIHBlcmNlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZXNbaWR4XTtcbiAgICB9O1xuICAgIHJldHVybiBTaGFwZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNoYXBlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2hhcGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIFNpemUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2l6ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTaXplKGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjZmcpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnc2l6ZSc7XG4gICAgICAgIF90aGlzLm5hbWVzID0gWydzaXplJ107XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgcmV0dXJuIFNpemU7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTaXplO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2l6ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2F0dHJpYnV0ZXMvYmFzZVwiKTtcbmV4cG9ydHMuQXR0cmlidXRlID0gYmFzZV8xLmRlZmF1bHQ7XG4vLyDmiYDmnInnmoQgYXR0cmlidXRlIG1hcFxudmFyIEFUVFJJQlVURV9NQVAgPSB7fTtcbi8qKlxuICog6YCa6L+H57G75Z6L6I635b6XIEF0dHJpYnV0ZSDnsbtcbiAqIEBwYXJhbSB0eXBlXG4gKi9cbnZhciBnZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgIHJldHVybiBBVFRSSUJVVEVfTUFQW3R5cGUudG9Mb3dlckNhc2UoKV07XG59O1xuZXhwb3J0cy5nZXRBdHRyaWJ1dGUgPSBnZXRBdHRyaWJ1dGU7XG52YXIgcmVnaXN0ZXJBdHRyaWJ1dGUgPSBmdW5jdGlvbiAodHlwZSwgY3Rvcikge1xuICAgIC8vIOazqOWGjOeahOaXtuWAme+8jOmcgOimgeagoemqjCB0eXBlIOmHjeWQje+8jOS4jeWMuuWIhuWkp+Wwj+WGmVxuICAgIGlmIChnZXRBdHRyaWJ1dGUodHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXR0cmlidXRlIHR5cGUgJ1wiICsgdHlwZSArIFwiJyBleGlzdGVkLlwiKTtcbiAgICB9XG4gICAgLy8g5a2Y5YKo5YiwIG1hcCDkuK1cbiAgICBBVFRSSUJVVEVfTUFQW3R5cGUudG9Mb3dlckNhc2UoKV0gPSBjdG9yO1xufTtcbmV4cG9ydHMucmVnaXN0ZXJBdHRyaWJ1dGUgPSByZWdpc3RlckF0dHJpYnV0ZTtcbnRzbGliXzEuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2ludGVyZmFjZVwiKSwgZXhwb3J0cyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mYWN0b3J5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYXR0cmlidXRlcy9iYXNlXCIpO1xuZXhwb3J0cy5BdHRyaWJ1dGUgPSBiYXNlXzEuZGVmYXVsdDtcbnZhciBjb2xvcl8xID0gcmVxdWlyZShcIi4vYXR0cmlidXRlcy9jb2xvclwiKTtcbmV4cG9ydHMuQ29sb3IgPSBjb2xvcl8xLmRlZmF1bHQ7XG52YXIgb3BhY2l0eV8xID0gcmVxdWlyZShcIi4vYXR0cmlidXRlcy9vcGFjaXR5XCIpO1xuZXhwb3J0cy5PcGFjaXR5ID0gb3BhY2l0eV8xLmRlZmF1bHQ7XG52YXIgcG9zaXRpb25fMSA9IHJlcXVpcmUoXCIuL2F0dHJpYnV0ZXMvcG9zaXRpb25cIik7XG5leHBvcnRzLlBvc2l0aW9uID0gcG9zaXRpb25fMS5kZWZhdWx0O1xudmFyIHNoYXBlXzEgPSByZXF1aXJlKFwiLi9hdHRyaWJ1dGVzL3NoYXBlXCIpO1xuZXhwb3J0cy5TaGFwZSA9IHNoYXBlXzEuZGVmYXVsdDtcbnZhciBzaXplXzEgPSByZXF1aXJlKFwiLi9hdHRyaWJ1dGVzL3NpemVcIik7XG5leHBvcnRzLlNpemUgPSBzaXplXzEuZGVmYXVsdDtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi9mYWN0b3J5XCIpO1xuZXhwb3J0cy5nZXRBdHRyaWJ1dGUgPSBmYWN0b3J5XzEuZ2V0QXR0cmlidXRlO1xuZXhwb3J0cy5yZWdpc3RlckF0dHJpYnV0ZSA9IGZhY3RvcnlfMS5yZWdpc3RlckF0dHJpYnV0ZTtcbmZhY3RvcnlfMS5yZWdpc3RlckF0dHJpYnV0ZSgnQ29sb3InLCBjb2xvcl8xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyQXR0cmlidXRlKCdPcGFjaXR5Jywgb3BhY2l0eV8xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyQXR0cmlidXRlKCdQb3NpdGlvbicsIHBvc2l0aW9uXzEuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJBdHRyaWJ1dGUoJ1NoYXBlJywgc2hhcGVfMS5kZWZhdWx0KTtcbmZhY3RvcnlfMS5yZWdpc3RlckF0dHJpYnV0ZSgnU2l6ZScsIHNpemVfMS5kZWZhdWx0KTtcbnRzbGliXzEuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2ludGVyZmFjZVwiKSwgZXhwb3J0cyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIkBhbnR2L3NjYWxlXCIpO1xuZXhwb3J0cy5TY2FsZSA9IHNjYWxlXzEuU2NhbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnRlcmZhY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgUkdCX1JFRyA9IC9yZ2JhP1xcKChbXFxzLiwwLTldKylcXCkvO1xudmFyIHJlZ2V4TEcgPSAvXmxcXHMqXFwoXFxzKihbXFxkLl0rKVxccypcXClcXHMqKC4qKS9pO1xudmFyIHJlZ2V4UkcgPSAvXnJcXHMqXFwoXFxzKihbXFxkLl0rKVxccyosXFxzKihbXFxkLl0rKVxccyosXFxzKihbXFxkLl0rKVxccypcXClcXHMqKC4qKS9pO1xudmFyIHJlZ2V4Q29sb3JTdG9wID0gL1tcXGQuXSs6KCNbXlxcc10rfFteXFwpXStcXCkpL2dpO1xudmFyIGlzR3JhZGllbnRDb2xvciA9IGZ1bmN0aW9uICh2YWwpIHsgcmV0dXJuIC9eW3IsUixMLGxdezF9W1xcc10qXFwoLy50ZXN0KHZhbCk7IH07XG4vLyDliJvlu7rovoXliqkgdGFnIOWPluminOiJslxudmFyIGNyZWF0ZVRtcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2knKTtcbiAgICBpLnRpdGxlID0gJ1dlYiBDb2xvdXIgUGlja2VyJztcbiAgICBpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpKTtcbiAgICByZXR1cm4gaTtcbn07XG4vLyDojrflj5bpopzoibLkuYvpl7TnmoTmj5LlgLxcbnZhciBnZXRWYWx1ZSA9IGZ1bmN0aW9uIChzdGFydCwgZW5kLCBwZXJjZW50LCBpbmRleCkge1xuICAgIHJldHVybiBzdGFydFtpbmRleF0gKyAoZW5kW2luZGV4XSAtIHN0YXJ0W2luZGV4XSkgKiBwZXJjZW50O1xufTtcbi8vIOaVsOe7hOi9rOaNouaIkOminOiJslxuZnVuY3Rpb24gYXJyMnJnYihhcnIpIHtcbiAgICByZXR1cm4gXCIjXCIgKyB0b0hleChhcnJbMF0pICsgdG9IZXgoYXJyWzFdKSArIHRvSGV4KGFyclsyXSk7XG59XG4vLyByZ2Ig6aKc6Imy6L2s5o2i5oiQ5pWw57uEXG52YXIgcmdiMmFyciA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gW1xuICAgICAgICBwYXJzZUludChzdHIuc3Vic3RyKDEsIDIpLCAxNiksXG4gICAgICAgIHBhcnNlSW50KHN0ci5zdWJzdHIoMywgMiksIDE2KSxcbiAgICAgICAgcGFyc2VJbnQoc3RyLnN1YnN0cig1LCAyKSwgMTYpLFxuICAgIF07XG59O1xuLy8g5bCG5pWw5YC85LuOIDAtMjU1IOi9rOaNouaIkDE26L+b5Yi25a2X56ym5LiyXG52YXIgdG9IZXggPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgeDE2VmFsdWUgPSBNYXRoLnJvdW5kKHZhbHVlKS50b1N0cmluZygxNik7XG4gICAgcmV0dXJuIHgxNlZhbHVlLmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgeDE2VmFsdWUgOiB4MTZWYWx1ZTtcbn07XG4vLyDorqHnrpfpopzoibJcbnZhciBjYWxDb2xvciA9IGZ1bmN0aW9uIChwb2ludHMsIHBlcmNlbnQpIHtcbiAgICB2YXIgZml4ZWRQZXJjZW50ID0gaXNOYU4oTnVtYmVyKHBlcmNlbnQpKSB8fCBwZXJjZW50IDwgMCA/IDAgOlxuICAgICAgICBwZXJjZW50ID4gMSA/IDEgOlxuICAgICAgICAgICAgTnVtYmVyKHBlcmNlbnQpO1xuICAgIHZhciBzdGVwcyA9IHBvaW50cy5sZW5ndGggLSAxO1xuICAgIHZhciBzdGVwID0gTWF0aC5mbG9vcihzdGVwcyAqIGZpeGVkUGVyY2VudCk7XG4gICAgdmFyIGxlZnQgPSBzdGVwcyAqIGZpeGVkUGVyY2VudCAtIHN0ZXA7XG4gICAgdmFyIHN0YXJ0ID0gcG9pbnRzW3N0ZXBdO1xuICAgIHZhciBlbmQgPSBzdGVwID09PSBzdGVwcyA/IHN0YXJ0IDogcG9pbnRzW3N0ZXAgKyAxXTtcbiAgICByZXR1cm4gYXJyMnJnYihbXG4gICAgICAgIGdldFZhbHVlKHN0YXJ0LCBlbmQsIGxlZnQsIDApLFxuICAgICAgICBnZXRWYWx1ZShzdGFydCwgZW5kLCBsZWZ0LCAxKSxcbiAgICAgICAgZ2V0VmFsdWUoc3RhcnQsIGVuZCwgbGVmdCwgMiksXG4gICAgXSk7XG59O1xuLy8g55So5LqO57uZIHRvUkdCIOeahOe8k+WtmO+8iOS9v+eUqCBtZW1vaXplIOaWueazleabv+aNou+8iVxuLy8gY29uc3QgY29sb3JDYWNoZSA9IHt9O1xudmFyIGlFbDtcbi8qKlxuICog5bCG6aKc6Imy6L2s5o2i5YiwIHJnYiDnmoTmoLzlvI9cbiAqIEBwYXJhbSB7Y29sb3J9IGNvbG9yIOminOiJslxuICogQHJldHVybiDlsIbpopzoibLovazmjaLliLAgJyNmZmZmZmYnIOeahOagvOW8j1xuICovXG52YXIgdG9SR0IgPSBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAvLyDlpoLmnpzlt7Lnu4/mmK8gcmdi55qE5qC85byPXG4gICAgaWYgKGNvbG9yWzBdID09PSAnIycgJiYgY29sb3IubGVuZ3RoID09PSA3KSB7XG4gICAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9XG4gICAgaWYgKCFpRWwpIHtcbiAgICAgICAgLy8g6Ziy5q2i6Ziy5q2i5Zyo6aG15aS05oql6ZSZXG4gICAgICAgIGlFbCA9IGNyZWF0ZVRtcCgpO1xuICAgIH1cbiAgICBpRWwuc3R5bGUuY29sb3IgPSBjb2xvcjtcbiAgICB2YXIgcnN0ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShpRWwsICcnKS5nZXRQcm9wZXJ0eVZhbHVlKCdjb2xvcicpO1xuICAgIHZhciBtYXRjaGVzID0gUkdCX1JFRy5leGVjKHJzdCk7XG4gICAgdmFyIGNBcnJheSA9IG1hdGNoZXNbMV0uc3BsaXQoL1xccyosXFxzKi8pLm1hcChmdW5jdGlvbiAocykgeyByZXR1cm4gTnVtYmVyKHMpOyB9KTtcbiAgICByc3QgPSBhcnIycmdiKGNBcnJheSk7XG4gICAgcmV0dXJuIHJzdDtcbn07XG4vKipcbiAqIOiOt+WPlua4kOWPmOWHveaVsFxuICogQHBhcmFtIGNvbG9ycyDlpJrkuKrpopzoibJcbiAqIEByZXR1cm4g6aKc6Imy5YC8XG4gKi9cbnZhciBncmFkaWVudCA9IGZ1bmN0aW9uIChjb2xvcnMpIHtcbiAgICB2YXIgY29sb3JBcnJheSA9IHV0aWxfMS5pc1N0cmluZyhjb2xvcnMpID8gY29sb3JzLnNwbGl0KCctJykgOiBjb2xvcnM7XG4gICAgdmFyIHBvaW50cyA9IHV0aWxfMS5tYXAoY29sb3JBcnJheSwgZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgIHJldHVybiByZ2IyYXJyKGNvbG9yLmluZGV4T2YoJyMnKSA9PT0gLTEgPyB0b1JHQihjb2xvcikgOiBjb2xvcik7XG4gICAgfSk7XG4gICAgLy8g6L+U5Zue5LiA5Liq5Ye95pWwXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChwZXJjZW50KSB7XG4gICAgICAgIHJldHVybiBjYWxDb2xvcihwb2ludHMsIHBlcmNlbnQpO1xuICAgIH07XG59O1xudmFyIHRvQ1NTR3JhZGllbnQgPSBmdW5jdGlvbiAoZ3JhZGllbnRDb2xvcikge1xuICAgIGlmIChpc0dyYWRpZW50Q29sb3IoZ3JhZGllbnRDb2xvcikpIHtcbiAgICAgICAgdmFyIGNzc0NvbG9yXzE7XG4gICAgICAgIHZhciBzdGVwcyA9IHZvaWQgMDtcbiAgICAgICAgaWYgKGdyYWRpZW50Q29sb3JbMF0gPT09ICdsJykge1xuICAgICAgICAgICAgLy8g57q/5oCn5riQ5Y+YXG4gICAgICAgICAgICB2YXIgYXJyID0gcmVnZXhMRy5leGVjKGdyYWRpZW50Q29sb3IpO1xuICAgICAgICAgICAgdmFyIGFuZ2xlID0gK2FyclsxXSArIDkwOyAvLyBjc3Mg5ZKMIGcg55qE5riQ5Y+Y6LW35aeL6KeS5bqm5LiN5ZCMXG4gICAgICAgICAgICBzdGVwcyA9IGFyclsyXTtcbiAgICAgICAgICAgIGNzc0NvbG9yXzEgPSBcImxpbmVhci1ncmFkaWVudChcIiArIGFuZ2xlICsgXCJkZWcsIFwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGdyYWRpZW50Q29sb3JbMF0gPT09ICdyJykge1xuICAgICAgICAgICAgLy8g5b6E5ZCR5riQ5Y+YXG4gICAgICAgICAgICBjc3NDb2xvcl8xID0gJ3JhZGlhbC1ncmFkaWVudCgnO1xuICAgICAgICAgICAgdmFyIGFyciA9IHJlZ2V4UkcuZXhlYyhncmFkaWVudENvbG9yKTtcbiAgICAgICAgICAgIHN0ZXBzID0gYXJyWzRdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb2xvclN0b3BzXzEgPSBzdGVwcy5tYXRjaChyZWdleENvbG9yU3RvcCk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbG9yU3RvcHNfMSwgZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgaXRlbUFyciA9IGl0ZW0uc3BsaXQoJzonKTtcbiAgICAgICAgICAgIGNzc0NvbG9yXzEgKz0gaXRlbUFyclsxXSArIFwiIFwiICsgaXRlbUFyclswXSAqIDEwMCArIFwiJVwiO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAoY29sb3JTdG9wc18xLmxlbmd0aCAtIDEpKSB7XG4gICAgICAgICAgICAgICAgY3NzQ29sb3JfMSArPSAnLCAnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY3NzQ29sb3JfMSArPSAnKSc7XG4gICAgICAgIHJldHVybiBjc3NDb2xvcl8xO1xuICAgIH1cbiAgICByZXR1cm4gZ3JhZGllbnRDb2xvcjtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgcmdiMmFycjogcmdiMmFycixcbiAgICBncmFkaWVudDogZ3JhZGllbnQsXG4gICAgdG9SR0I6IHV0aWxfMS5tZW1vaXplKHRvUkdCKSxcbiAgICB0b0NTU0dyYWRpZW50OiB0b0NTU0dyYWRpZW50LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ19iYXNlXzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIExPQ0FUSU9OX0ZJRUxEX01BUCA9IHtcbiAgICBub25lOiBbXSxcbiAgICBwb2ludDogWyd4JywgJ3knXSxcbiAgICByZWdpb246IFsnc3RhcnQnLCAnZW5kJ10sXG4gICAgcG9pbnRzOiBbJ3BvaW50cyddLFxuICAgIGNpcmNsZTogWydjZW50ZXInLCAncmFkaXVzJywgJ3N0YXJ0QW5nbGUnLCAnZW5kQW5nbGUnXSxcbn07XG52YXIgQ29tcG9uZW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbXBvbmVudCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDb21wb25lbnQoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuaW5pdENmZygpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDpu5jorqTnmoTphY3nva7poblcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSDpu5jorqTnmoTphY3nva7poblcbiAgICAgKi9cbiAgICBDb21wb25lbnQucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICBuYW1lOiAnJyxcbiAgICAgICAgICAgIHR5cGU6ICcnLFxuICAgICAgICAgICAgbG9jYXRpb25UeXBlOiAnbm9uZScsXG4gICAgICAgICAgICBvZmZzZXRYOiAwLFxuICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIGFuaW1hdGU6IGZhbHNlLFxuICAgICAgICAgICAgY2FwdHVyZTogdHJ1ZSxcbiAgICAgICAgICAgIHVwZGF0ZUF1dG9SZW5kZXI6IGZhbHNlLFxuICAgICAgICAgICAgYW5pbWF0ZU9wdGlvbjoge1xuICAgICAgICAgICAgICAgIGFwcGVhcjogbnVsbCxcbiAgICAgICAgICAgICAgICB1cGRhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDQwMCxcbiAgICAgICAgICAgICAgICAgICAgZWFzaW5nOiAnZWFzZVF1YWRJbk91dCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnRlcjoge1xuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogNDAwLFxuICAgICAgICAgICAgICAgICAgICBlYXNpbmc6ICdlYXNlUXVhZEluT3V0JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxlYXZlOiB7XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAzNTAsXG4gICAgICAgICAgICAgICAgICAgIGVhc2luZzogJ2Vhc2VRdWFkSW4nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnRzOiBudWxsLFxuICAgICAgICAgICAgZGVmYXVsdENmZzoge30sXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF55CG57uE5Lu255qE5YaF5a6577yM5LiA6Iis6YWN5ZCIIHJlbmRlciDkvb/nlKhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGF4aXMuY2xlYXIoKTtcbiAgICAgKiBheGlzLnJlbmRlcigpO1xuICAgICAqL1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgLyoqXG4gICAgICog5pu05paw57uE5Lu2XG4gICAgICogQHBhcmFtIHtvYmplY3R9IGNmZyDmm7TmlrDlsZ7mgKdcbiAgICAgKi9cbiAgICBDb21wb25lbnQucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGRlZmF1bHRDZmcgPSB0aGlzLmdldCgnZGVmYXVsdENmZycpO1xuICAgICAgICB1dGlsXzEuZWFjaChjZmcsIGZ1bmN0aW9uICh2YWx1ZSwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIG9yaWdpbkNmZyA9IF90aGlzLmdldChuYW1lKTtcbiAgICAgICAgICAgIHZhciBuZXdDZmcgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmIChvcmlnaW5DZmcgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8g5Yik5pat5Lik6ICF5piv5ZCm55u4562J77yM5Li76KaB5piv6L+b6KGMIG51bGwg55qE5Yik5a6aXG4gICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc09iamVjdCh2YWx1ZSkgJiYgZGVmYXVsdENmZ1tuYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDmlrDorr7nva7nmoTlsZ7mgKfkuI7pu5jorqTlgLzov5vooYzlkIjlubZcbiAgICAgICAgICAgICAgICAgICAgbmV3Q2ZnID0gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRDZmdbbmFtZV0sIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0KG5hbWUsIG5ld0NmZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwZGF0ZUlubmVyKGNmZyk7XG4gICAgICAgIHRoaXMuYWZ0ZXJVcGRhdGUoY2ZnKTtcbiAgICB9O1xuICAgIC8vIOabtOaWsOWGhemDqFxuICAgIENvbXBvbmVudC5wcm90b3R5cGUudXBkYXRlSW5uZXIgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgfTtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmFmdGVyVXBkYXRlID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICAvLyDmm7TmlrDml7bogIPomZHmmL7npLrjgIHpmpDol49cbiAgICAgICAgaWYgKHV0aWxfMS5oYXNLZXkoY2ZnLCAndmlzaWJsZScpKSB7XG4gICAgICAgICAgICBpZiAoY2ZnLnZpc2libGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOabtOaWsOaXtuiAg+iZkWNhcHR1cmVcbiAgICAgICAgaWYgKHV0aWxfMS5oYXNLZXkoY2ZnLCAnY2FwdHVyZScpKSB7XG4gICAgICAgICAgICB0aGlzLnNldENhcHR1cmUoY2ZnLmNhcHR1cmUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmdldExheW91dEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJCb3goKTsgLy8g6buY6K6k6L+U5ZueIGdldEJCb3jvvIzkuI3lkIznmoTnu4Tku7blhoXpg6jljZXni6zlrp7njrBcbiAgICB9O1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZ2V0TG9jYXRpb25UeXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoJ2xvY2F0aW9uVHlwZScpO1xuICAgIH07XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5nZXRPZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvZmZzZXRYOiB0aGlzLmdldCgnb2Zmc2V0WCcpLFxuICAgICAgICAgICAgb2Zmc2V0WTogdGhpcy5nZXQoJ29mZnNldFknKSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8vIOm7mOiupOS9v+eUqCB1cGRhdGVcbiAgICBDb21wb25lbnQucHJvdG90eXBlLnNldE9mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXRYLCBvZmZzZXRZKSB7XG4gICAgICAgIHRoaXMudXBkYXRlKHtcbiAgICAgICAgICAgIG9mZnNldFg6IG9mZnNldFgsXG4gICAgICAgICAgICBvZmZzZXRZOiBvZmZzZXRZLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuc2V0TG9jYXRpb24gPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHZhciBsb2NhdGlvbiA9IHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyk7XG4gICAgICAgIHRoaXMudXBkYXRlKGxvY2F0aW9uKTtcbiAgICB9O1xuICAgIC8vIOWunueOsCBJTG9jYXRpb24g5o6l5Y+j55qEIGdldExvY2F0aW9uXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5nZXRMb2NhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGxvY2F0aW9uID0ge307XG4gICAgICAgIHZhciBsb2NhdGlvblR5cGUgPSB0aGlzLmdldCgnbG9jYXRpb25UeXBlJyk7XG4gICAgICAgIHZhciBmaWVsZHMgPSBMT0NBVElPTl9GSUVMRF9NQVBbbG9jYXRpb25UeXBlXTtcbiAgICAgICAgdXRpbF8xLmVhY2goZmllbGRzLCBmdW5jdGlvbiAoZmllbGQpIHtcbiAgICAgICAgICAgIGxvY2F0aW9uW2ZpZWxkXSA9IF90aGlzLmdldChmaWVsZCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbG9jYXRpb247XG4gICAgfTtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmlzTGlzdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pc1NsaWRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOWIneWni+WMlu+8jOeUqOS6juWFt+S9k+eahOe7hOS7tue7p+aJv1xuICAgICAqL1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICAvLyDlsIbnu4Tku7bpu5jorqTnmoTphY3nva7pobnorr7nva7lkIjlubbliLDkvKDlhaXnmoTphY3nva7poblcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBkZWZhdWx0Q2ZnID0gdGhpcy5nZXQoJ2RlZmF1bHRDZmcnKTtcbiAgICAgICAgdXRpbF8xLmVhY2goZGVmYXVsdENmZywgZnVuY3Rpb24gKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgICAgICB2YXIgY2ZnID0gX3RoaXMuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc09iamVjdChjZmcpKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5ld0NmZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCB2YWx1ZSwgY2ZnKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXQobmFtZSwgbmV3Q2ZnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQ29tcG9uZW50O1xufShnX2Jhc2VfMS5CYXNlKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDb21wb25lbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb21wb25lbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uL3V0aWwvZXZlbnRcIik7XG52YXIgbWF0cml4XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9tYXRyaXhcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcbnZhciBTVEFUVVNfVVBEQVRFID0gJ3VwZGF0ZV9zdGF0dXMnO1xudmFyIENPUFlfUFJPUEVSVElFUyA9IFsndmlzaWJsZScsICd0aXAnLCAnZGVsZWdhdGVPYmplY3QnXTsgLy8g5pu05paw5a+56LGh5pe26ZyA6KaB5aSN5Yi255qE5bGe5oCnXG52YXIgQ09QWV9QUk9QRVJUSUVTX0VYQ0xVREVTID0gWydjb250YWluZXInLCAnZ3JvdXAnLCAnc2hhcGVzTWFwJywgJ2lzUmVnaXN0ZXInLCAnaXNVcGRhdGluZycsICdkZXN0cm95ZWQnXTsgLy8g5pu05paw5a2Q57uE5Lu25pe25o6S6Zmk55qE5bGe5oCnXG52YXIgR3JvdXBDb21wb25lbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR3JvdXBDb21wb25lbnQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR3JvdXBDb21wb25lbnQoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBjb250YWluZXI6IG51bGwsIFxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgICAgICog57yT5a2Y5Zu+5b2i55qEIE1hcFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBzaGFwZXNNYXA6IHt9LCBncm91cDogbnVsbCwgY2FwdHVyZTogdHJ1ZSwgXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEBwcml2YXRlIOe7hOS7tuaIluiAheWbvuW9ouaYr+WQpuWFgeiuuOazqOWGjFxuICAgICAgICAgICAgICogQHR5cGUge2ZhbHNlfVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpc1JlZ2lzdGVyOiBmYWxzZSwgXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEBwcml2YXRlIOaYr+WQpuato+WcqOabtOaWsFxuICAgICAgICAgICAgICogQHR5cGUge2ZhbHNlfVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpc1VwZGF0aW5nOiBmYWxzZSwgXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAgICAgKiDmmK/lkKbliJ3lp4vnirbmgIHvvIzkuIDml6YgcmVuZGVy77yMdXBkYXRlIOWQju+8jOi/meS4queKtuaAgeWwseWPmOaIkCBmYWxzZSwgY2xlYXIg5ZCO5oGi5aSNXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlzSW5pdDogdHJ1ZSB9KTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIGdyb3VwLnJlbW92ZSgpO1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgZ3JvdXAuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zZXQoJ3NoYXBlc01hcCcsIHt9KTtcbiAgICAgICAgdGhpcy5jbGVhck9mZlNjcmVlbkNhY2hlKCk7XG4gICAgICAgIHRoaXMuc2V0KCdpc0luaXQnLCB0cnVlKTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5nZXRDaGlsZENvbXBvbmVudEJ5SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIHZhciBpbnN0ID0gZ3JvdXAgJiYgZ3JvdXAuZ2V0KCdjb21wb25lbnQnKTtcbiAgICAgICAgcmV0dXJuIGluc3Q7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuZ2V0RWxlbWVudEJ5SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCdzaGFwZXNNYXAnKVtpZF07XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuZ2V0RWxlbWVudEJ5TG9jYWxJZCA9IGZ1bmN0aW9uIChsb2NhbElkKSB7XG4gICAgICAgIHZhciBpZCA9IHRoaXMuZ2V0RWxlbWVudElkKGxvY2FsSWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuZ2V0RWxlbWVudHNCeU5hbWUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB2YXIgcnN0ID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZ2V0KCdzaGFwZXNNYXAnKSwgZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgICAgIGlmIChlbGVtLmdldCgnbmFtZScpID09PSBuYW1lKSB7XG4gICAgICAgICAgICAgICAgcnN0LnB1c2goZWxlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmdldENvbnRhaW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCdjb250YWluZXInKTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS51cGRhdGVJbm5lciA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgLy8gdGhpcy51cGRhdGVJbm5lcigpO1xuICAgICAgICAvLyB0aGlzLnNldCgnaXNVcGRhdGluZycsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5vZmZTY3JlZW5SZW5kZXIoKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCd1cGRhdGVBdXRvUmVuZGVyJykpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvZmZTY3JlZW5Hcm91cCA9IHRoaXMuZ2V0KCdvZmZTY3JlZW5Hcm91cCcpO1xuICAgICAgICBpZiAoIW9mZlNjcmVlbkdyb3VwKSB7XG4gICAgICAgICAgICBvZmZTY3JlZW5Hcm91cCA9IHRoaXMub2ZmU2NyZWVuUmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudHMob2ZmU2NyZWVuR3JvdXAsIGdyb3VwKTtcbiAgICAgICAgdGhpcy5kZWxldGVFbGVtZW50cygpO1xuICAgICAgICB0aGlzLmFwcGx5T2Zmc2V0KCk7XG4gICAgICAgIGlmICghdGhpcy5nZXQoJ2V2ZW50SW5pdHRlZCcpKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRFdmVudCgpO1xuICAgICAgICAgICAgdGhpcy5zZXQoJ2V2ZW50SW5pdHRlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0KCdpc0luaXQnLCBmYWxzZSk7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIGdyb3VwLnNob3coKTtcbiAgICAgICAgdGhpcy5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgZ3JvdXAuaGlkZSgpO1xuICAgICAgICB0aGlzLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5zZXRDYXB0dXJlID0gZnVuY3Rpb24gKGNhcHR1cmUpIHtcbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIGdyb3VwLnNldCgnY2FwdHVyZScsIGNhcHR1cmUpO1xuICAgICAgICB0aGlzLnNldCgnY2FwdHVyZScsIGNhcHR1cmUpO1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnQoKTtcbiAgICAgICAgdGhpcy5yZW1vdmUoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuZ2V0QkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCdncm91cCcpLmdldENhbnZhc0JCb3goKTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5nZXRMYXlvdXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgLy8g6Ziy5q2i6KKrIGNsZWFyIOS6hu+8jG9mZlNjcmVlbkJCb3gg5LiN5a2Y5ZyoXG4gICAgICAgIHZhciBiYm94ID0gdGhpcy5nZXRJbm5lckxheW91dEJCb3goKTtcbiAgICAgICAgdmFyIG1hdHJpeCA9IGdyb3VwLmdldFRvdGFsTWF0cml4KCk7XG4gICAgICAgIGlmIChtYXRyaXgpIHtcbiAgICAgICAgICAgIGJib3ggPSBtYXRyaXhfMS5hcHBseU1hdHJpeDJCQm94KG1hdHJpeCwgYmJveCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJib3g7IC8vIOm7mOiupOi/lOWbniBnZXRCQm9477yM5LiN5ZCM55qE57uE5Lu25YaF6YOo5Y2V54us5a6e546wXG4gICAgfTtcbiAgICAvLyDlpI3lhpkgb24sIG9mZiwgZW1pdCDpgI/kvKDliLAgZ3JvdXBcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXZ0LCBjYWxsYmFjaywgb25jZSkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgZ3JvdXAub24oZXZ0LCBjYWxsYmFjaywgb25jZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2V0KCdncm91cCcpO1xuICAgICAgICBncm91cCAmJiBncm91cC5vZmYoZXZ0LCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBldmVudE9iamVjdCkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgZ3JvdXAuZW1pdChldmVudE5hbWUsIGV2ZW50T2JqZWN0KTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKCF0aGlzLmdldCgnZ3JvdXAnKSkge1xuICAgICAgICAgICAgdGhpcy5pbml0R3JvdXAoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9mZlNjcmVlblJlbmRlcigpOyAvLyDnu5jliLbnprvlsY8gZ3JvdXBcbiAgICB9O1xuICAgIC8vIOiOt+WPlue7hOS7tuWGhemDqOW4g+WxgOWNoOeahOWMheWbtOebklxuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5nZXRJbm5lckxheW91dEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnb2ZmU2NyZWVuQkJveCcpIHx8IHRoaXMuZ2V0KCdncm91cCcpLmdldEJCb3goKTtcbiAgICB9O1xuICAgIC8vIOaKm+WHuuWnlOaJmOWvueixoVxuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5kZWxlZ2F0ZUVtaXQgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBldmVudE9iamVjdCkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgZXZlbnRPYmplY3QudGFyZ2V0ID0gZ3JvdXA7XG4gICAgICAgIGdyb3VwLmVtaXQoZXZlbnROYW1lLCBldmVudE9iamVjdCk7XG4gICAgICAgIGV2ZW50XzEucHJvcGFnYXRpb25EZWxlZ2F0ZShncm91cCwgZXZlbnROYW1lLCBldmVudE9iamVjdCk7XG4gICAgfTtcbiAgICAvLyDliJvlu7rnprvlsY/nmoQgZ3JvdXAgLOS4jea3u+WKoOWcqCBjYW52YXMg5LitXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmNyZWF0ZU9mZlNjcmVlbkdyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ3JvdXAgPSB0aGlzLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgdmFyIEdyb3VwQ2xhc3MgPSBncm91cC5nZXRHcm91cEJhc2UoKTsgLy8g6I635Y+W5YiG57uE55qE5p6E6YCg5Ye95pWwXG4gICAgICAgIHZhciBuZXdHcm91cCA9IG5ldyBHcm91cENsYXNzKHtcbiAgICAgICAgICAgIGRlbGVnYXRlT2JqZWN0OiB0aGlzLmdldERlbGVnYXRlT2JqZWN0KCksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3R3JvdXA7XG4gICAgfTtcbiAgICAvLyDlupTnlKggb2Zmc2V0XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmFwcGx5T2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb2Zmc2V0WCA9IHRoaXMuZ2V0KCdvZmZzZXRYJyk7XG4gICAgICAgIHZhciBvZmZzZXRZID0gdGhpcy5nZXQoJ29mZnNldFknKTtcbiAgICAgICAgdGhpcy5tb3ZlRWxlbWVudFRvKHRoaXMuZ2V0KCdncm91cCcpLCB7XG4gICAgICAgICAgICB4OiBvZmZzZXRYLFxuICAgICAgICAgICAgeTogb2Zmc2V0WSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuaW5pdEdyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXQoJ2NvbnRhaW5lcicpO1xuICAgICAgICB0aGlzLnNldCgnZ3JvdXAnLCBjb250YWluZXIuYWRkR3JvdXAoe1xuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0KCdpZCcpLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5nZXQoJ25hbWUnKSxcbiAgICAgICAgICAgIGNhcHR1cmU6IHRoaXMuZ2V0KCdjYXB0dXJlJyksXG4gICAgICAgICAgICB2aXNpYmxlOiB0aGlzLmdldCgndmlzaWJsZScpLFxuICAgICAgICAgICAgaXNDb21wb25lbnQ6IHRydWUsXG4gICAgICAgICAgICBjb21wb25lbnQ6IHRoaXMsXG4gICAgICAgICAgICBkZWxlZ2F0ZU9iamVjdDogdGhpcy5nZXREZWxlZ2F0ZU9iamVjdCgpLFxuICAgICAgICB9KSk7XG4gICAgfTtcbiAgICAvLyDnprvlsY/muLLmn5NcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUub2ZmU2NyZWVuUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNsZWFyT2ZmU2NyZWVuQ2FjaGUoKTtcbiAgICAgICAgdmFyIG9mZlNjcmVlbkdyb3VwID0gdGhpcy5jcmVhdGVPZmZTY3JlZW5Hcm91cCgpO1xuICAgICAgICB0aGlzLnJlbmRlcklubmVyKG9mZlNjcmVlbkdyb3VwKTtcbiAgICAgICAgdGhpcy5zZXQoJ29mZlNjcmVlbkdyb3VwJywgb2ZmU2NyZWVuR3JvdXApO1xuICAgICAgICAvLyDljIXlkKvljIXlm7Tnm5LnmoQgYmJveFxuICAgICAgICB0aGlzLnNldCgnb2ZmU2NyZWVuQkJveCcsIHV0aWxfMi5nZXRCQm94V2l0aENsaXAob2ZmU2NyZWVuR3JvdXApKTtcbiAgICAgICAgcmV0dXJuIG9mZlNjcmVlbkdyb3VwO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOWcqOe7hOS7tuS4iua3u+WKoOWIhue7hO+8jOS4u+imgeino+WGsyBpc1JlaWdldGVyIOeahOmXrumimFxuICAgICAqIEBwYXJhbSB7SUdyb3VwfSBwYXJlbnQg54i25YWD57SgXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGNmZyAgICDliIbnu4TnmoTphY3nva7poblcbiAgICAgKi9cbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuYWRkR3JvdXAgPSBmdW5jdGlvbiAocGFyZW50LCBjZmcpIHtcbiAgICAgICAgdGhpcy5hcHBlbmREZWxlZ2F0ZU9iamVjdChwYXJlbnQsIGNmZyk7XG4gICAgICAgIHZhciBncm91cCA9IHBhcmVudC5hZGRHcm91cChjZmcpO1xuICAgICAgICBpZiAodGhpcy5nZXQoJ2lzUmVnaXN0ZXInKSkge1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RlckVsZW1lbnQoZ3JvdXApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBncm91cDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDlnKjnu4Tku7bkuIrmt7vliqDlm77lvaLvvIzkuLvopoHop6PlhrMgaXNSZWlnZXRlciDnmoTpl67pophcbiAgICAgKiBAcGFyYW0ge0lHcm91cH0gcGFyZW50IOeItuWFg+e0oFxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBjZmcgICAg5YiG57uE55qE6YWN572u6aG5XG4gICAgICovXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmFkZFNoYXBlID0gZnVuY3Rpb24gKHBhcmVudCwgY2ZnKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kRGVsZWdhdGVPYmplY3QocGFyZW50LCBjZmcpO1xuICAgICAgICB2YXIgc2hhcGUgPSBwYXJlbnQuYWRkU2hhcGUoY2ZnKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdpc1JlZ2lzdGVyJykpIHtcbiAgICAgICAgICAgIHRoaXMucmVnaXN0ZXJFbGVtZW50KHNoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlnKjnu4Tku7bkuIrmt7vliqDlrZDnu4Tku7ZcbiAgICAgKlxuICAgICAqIEBwYXJhbSBwYXJlbnQg54i25YWD57SgXG4gICAgICogQHBhcmFtIGNmZyDlrZDnu4Tku7bphY3nva7poblcbiAgICAgKi9cbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuYWRkQ29tcG9uZW50ID0gZnVuY3Rpb24gKHBhcmVudCwgY2ZnKSB7XG4gICAgICAgIHZhciBpZCA9IGNmZy5pZCwgQ3RvciA9IGNmZy5jb21wb25lbnQsIHJlc3RDZmcgPSB0c2xpYl8xLl9fcmVzdChjZmcsIFtcImlkXCIsIFwiY29tcG9uZW50XCJdKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB2YXIgaW5zdCA9IG5ldyBDdG9yKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgcmVzdENmZyksIHsgaWQ6IGlkLCBjb250YWluZXI6IHBhcmVudCwgdXBkYXRlQXV0b1JlbmRlcjogdGhpcy5nZXQoJ3VwZGF0ZUF1dG9SZW5kZXInKSB9KSk7XG4gICAgICAgIGluc3QuaW5pdCgpO1xuICAgICAgICBpbnN0LnJlbmRlcigpO1xuICAgICAgICBpZiAodGhpcy5nZXQoJ2lzUmVnaXN0ZXInKSkge1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RlckVsZW1lbnQoaW5zdC5nZXQoJ2dyb3VwJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnN0O1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmluaXRFdmVudCA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2V0KCdncm91cCcpO1xuICAgICAgICBncm91cC5vZmYoKTtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5nZXRFbGVtZW50SWQgPSBmdW5jdGlvbiAobG9jYWxJZCkge1xuICAgICAgICB2YXIgaWQgPSB0aGlzLmdldCgnaWQnKTsgLy8g57uE5Lu255qEIElkXG4gICAgICAgIHZhciBuYW1lID0gdGhpcy5nZXQoJ25hbWUnKTsgLy8g57uE5Lu255qE5ZCN56ewXG4gICAgICAgIHJldHVybiBpZCArIFwiLVwiICsgbmFtZSArIFwiLVwiICsgbG9jYWxJZDtcbiAgICB9O1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5yZWdpc3RlckVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgaWQgPSBlbGVtZW50LmdldCgnaWQnKTtcbiAgICAgICAgdGhpcy5nZXQoJ3NoYXBlc01hcCcpW2lkXSA9IGVsZW1lbnQ7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUudW5yZWdpc3RlckVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgaWQgPSBlbGVtZW50LmdldCgnaWQnKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuZ2V0KCdzaGFwZXNNYXAnKVtpZF07XG4gICAgfTtcbiAgICAvLyDnp7vliqjlhYPntKBcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUubW92ZUVsZW1lbnRUbyA9IGZ1bmN0aW9uIChlbGVtZW50LCBwb2ludCkge1xuICAgICAgICB2YXIgbWF0cml4ID0gbWF0cml4XzEuZ2V0TWF0cml4QnlUcmFuc2xhdGUocG9pbnQpO1xuICAgICAgICBlbGVtZW50LmF0dHIoJ21hdHJpeCcsIG1hdHJpeCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlm77lvaLlhYPntKDmlrDlh7rnjrDml7bnmoTliqjnlLvvvIzpu5jorqTlm77lvaLku47pgI/mmI7luqYgMCDliLDlvZPliY3pgI/mmI7luqZcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVsbWVudE5hbWUg5Zu+5b2i5YWD57Sg5ZCN56ewXG4gICAgICogQHBhcmFtIHtJRWxlbWVudH0gbmV3RWxlbWVudCAg5paw55qE5Zu+5b2i5YWD57SgXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGFuaW1hdGVDZmcg5Yqo55S755qE6YWN572u6aG5XG4gICAgICovXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmFkZEFuaW1hdGlvbiA9IGZ1bmN0aW9uIChlbG1lbnROYW1lLCBuZXdFbGVtZW50LCBhbmltYXRlQ2ZnKSB7XG4gICAgICAgIC8vIOe8k+WtmOmAj+aYjuW6plxuICAgICAgICB2YXIgb3JpZ2luT3BhY2l0eSA9IG5ld0VsZW1lbnQuYXR0cignb3BhY2l0eScpO1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKG9yaWdpbk9wYWNpdHkpKSB7XG4gICAgICAgICAgICBvcmlnaW5PcGFjaXR5ID0gMTtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LmF0dHIoJ29wYWNpdHknLCAwKTtcbiAgICAgICAgbmV3RWxlbWVudC5hbmltYXRlKHsgb3BhY2l0eTogb3JpZ2luT3BhY2l0eSB9LCBhbmltYXRlQ2ZnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWbvuW9ouWFg+e0oOaWsOWHuueOsOaXtueahOWKqOeUu++8jOm7mOiupOWbvuW9ouS7jumAj+aYjuW6piAwIOWIsOW9k+WJjemAj+aYjuW6plxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZWxtZW50TmFtZSDlm77lvaLlhYPntKDlkI3np7BcbiAgICAgKiBAcGFyYW0ge0lFbGVtZW50fSBvcmlnaW5FbGVtZW50IOimgeWIoOmZpOeahOWbvuW9ouWFg+e0oFxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBhbmltYXRlQ2ZnIOWKqOeUu+eahOmFjee9rumhuVxuICAgICAqL1xuICAgIEdyb3VwQ29tcG9uZW50LnByb3RvdHlwZS5yZW1vdmVBbmltYXRpb24gPSBmdW5jdGlvbiAoZWxlbWVudE5hbWUsIG9yaWdpbkVsZW1lbnQsIGFuaW1hdGVDZmcpIHtcbiAgICAgICAgb3JpZ2luRWxlbWVudC5hbmltYXRlKHsgb3BhY2l0eTogMCB9LCBhbmltYXRlQ2ZnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWbvuW9ouWFg+e0oOeahOabtOaWsOWKqOeUu1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBlbG1lbnROYW1lIOWbvuW9ouWFg+e0oOWQjeensFxuICAgICAqIEBwYXJhbSB7SUVsZW1lbnR9IG9yaWdpbkVsZW1lbnQg546w5pyJ55qE5Zu+5b2i5YWD57SgXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG5ld0F0dHJzICDmlrDnmoTlm77lvaLlhYPntKBcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYW5pbWF0ZUNmZyDliqjnlLvnmoTphY3nva7poblcbiAgICAgKi9cbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUudXBkYXRlQW5pbWF0aW9uID0gZnVuY3Rpb24gKGVsZW1lbnROYW1lLCBvcmlnaW5FbGVtZW50LCBuZXdBdHRycywgYW5pbWF0ZUNmZykge1xuICAgICAgICBvcmlnaW5FbGVtZW50LmFuaW1hdGUobmV3QXR0cnMsIGFuaW1hdGVDZmcpO1xuICAgIH07XG4gICAgLy8g5pu05paw57uE5Lu255qE5Zu+5b2iXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLnVwZGF0ZUVsZW1lbnRzID0gZnVuY3Rpb24gKG5ld0dyb3VwLCBvcmlnaW5Hcm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgYW5pbWF0ZSA9IHRoaXMuZ2V0KCdhbmltYXRlJyk7XG4gICAgICAgIHZhciBhbmltYXRlT3B0aW9uID0gdGhpcy5nZXQoJ2FuaW1hdGVPcHRpb24nKTtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gbmV3R3JvdXAuZ2V0Q2hpbGRyZW4oKS5zbGljZSgwKTsgLy8g5Yib5bu65LiA5Liq5paw5pWw57uE77yM6Ziy5q2i5re75Yqg5YiwIG9yaWdpbkdyb3VwIOaXtu+8jCBjaGlsZHJlbiDlj5jliqhcbiAgICAgICAgdmFyIHByZUVsZW1lbnQ7IC8vIOWJjemdouW3sue7j+WMuemFjeWIsOeahOWbvuW9ouWFg+e0oO+8jOeUqOS6jlxuICAgICAgICB1dGlsXzEuZWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHZhciBlbGVtZW50SWQgPSBlbGVtZW50LmdldCgnaWQnKTtcbiAgICAgICAgICAgIHZhciBvcmlnaW5FbGVtZW50ID0gX3RoaXMuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcbiAgICAgICAgICAgIHZhciBlbGVtZW50TmFtZSA9IGVsZW1lbnQuZ2V0KCduYW1lJyk7XG4gICAgICAgICAgICBpZiAob3JpZ2luRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmdldCgnaXNDb21wb25lbnQnKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDltYzlpZflrZDnu4Tku7bmm7TmlrBcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkQ29tcG9uZW50ID0gZWxlbWVudC5nZXQoJ2NvbXBvbmVudCcpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ0NoaWxkQ29tcG9uZW50ID0gb3JpZ2luRWxlbWVudC5nZXQoJ2NvbXBvbmVudCcpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Q2ZnID0gdXRpbF8xLnBpY2soY2hpbGRDb21wb25lbnQuY2ZnLCB1dGlsXzEuZGlmZmVyZW5jZSh1dGlsXzEua2V5cyhjaGlsZENvbXBvbmVudC5jZmcpLCBDT1BZX1BST1BFUlRJRVNfRVhDTFVERVMpKTtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ0NoaWxkQ29tcG9uZW50LnVwZGF0ZShuZXdDZmcpO1xuICAgICAgICAgICAgICAgICAgICBvcmlnaW5FbGVtZW50LnNldChTVEFUVVNfVVBEQVRFLCAndXBkYXRlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVwbGFjZUF0dHJzID0gX3RoaXMuZ2V0UmVwbGFjZUF0dHJzKG9yaWdpbkVsZW1lbnQsIGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAvLyDmm7TmlrBcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGUgJiYgYW5pbWF0ZU9wdGlvbi51cGRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOayoeacieWKqOeUu1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlQW5pbWF0aW9uKGVsZW1lbnROYW1lLCBvcmlnaW5FbGVtZW50LCByZXBsYWNlQXR0cnMsIGFuaW1hdGVPcHRpb24udXBkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbkVsZW1lbnQuYXR0cnMgPSByZXBsYWNlQXR0cnM7IC8vIOebtOaOpeabv+aNolxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luRWxlbWVudC5hdHRyKHJlcGxhY2VBdHRycyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5piv5YiG57uE77yM5YiZ57un57ut5omn6KGMXG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlRWxlbWVudHMoZWxlbWVudCwgb3JpZ2luRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8g5aSN5Yi25bGe5oCnXG4gICAgICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKENPUFlfUFJPUEVSVElFUywgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbkVsZW1lbnQuc2V0KG5hbWUsIGVsZW1lbnQuZ2V0KG5hbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHV0aWxfMi51cGRhdGVDbGlwKG9yaWdpbkVsZW1lbnQsIGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICBwcmVFbGVtZW50ID0gb3JpZ2luRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgLy8g5omn6KGM5a6M5pu05paw5ZCO6K6+572u54q25oCB5L2N5Li65pu05pawXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbkVsZW1lbnQuc2V0KFNUQVRVU19VUERBVEUsICd1cGRhdGUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyDmsqHmnInlr7nlupTnmoTlm77lvaLvvIzliJnmj5LlhaXlvZPliY3lm77lvaJcbiAgICAgICAgICAgICAgICBvcmlnaW5Hcm91cC5hZGQoZWxlbWVudCk7IC8vIOW6lOivpeWcqCBncm91cCDliqDkuKogaW5zZXJ0QXQg55qE5pa55rOVXG4gICAgICAgICAgICAgICAgdmFyIHNpYmxpbmdzID0gb3JpZ2luR3JvdXAuZ2V0Q2hpbGRyZW4oKTsgLy8g5YWE5byf6IqC54K5XG4gICAgICAgICAgICAgICAgc2libGluZ3Muc3BsaWNlKHNpYmxpbmdzLmxlbmd0aCAtIDEsIDEpOyAvLyDlhYjku47mlbDnu4TkuK3np7vpmaTvvIznhLblkI7mlL7liLDlkIjpgILnmoTkvY3nva5cbiAgICAgICAgICAgICAgICBpZiAocHJlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDliY3pnaLlt7Lnu4/mnInmm7TmlrDnmoTlm77lvaLmiJbogIXmj5LlhaXnmoTlm77lvaLvvIzliJnlnKjov5nkuKrlm77lvaLlkI7pnaLmj5LlhaVcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gc2libGluZ3MuaW5kZXhPZihwcmVFbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgc2libGluZ3Muc3BsaWNlKGluZGV4ICsgMSwgMCwgZWxlbWVudCk7IC8vIOWcqOW3sue7j+abtOaWsOeahOWbvuW9ouWFg+e0oOWQjumdouaPkuWFpVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2libGluZ3MudW5zaGlmdChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgX3RoaXMucmVnaXN0ZXJFbGVtZW50KGVsZW1lbnQpOyAvLyDms6jlhozoioLngrlcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNldChTVEFUVVNfVVBEQVRFLCAnYWRkJyk7IC8vIOaJp+ihjOWujOabtOaWsOWQjuiuvue9rueKtuaAgeS9jeS4uua3u+WKoFxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmdldCgnaXNDb21wb25lbnQnKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDnm7TmjqXmlrDlop7lrZDnu4Tku7Zjb250YWluZXLlsZ7mgKfvvIzlrp7kvovkuI3lj5hcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkQ29tcG9uZW50ID0gZWxlbWVudC5nZXQoJ2NvbXBvbmVudCcpO1xuICAgICAgICAgICAgICAgICAgICBjaGlsZENvbXBvbmVudC5zZXQoJ2NvbnRhaW5lcicsIG9yaWdpbkdyb3VwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZWxlbWVudC5pc0dyb3VwKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5YWD57Sg5piv5paw5aKe5Yqg55qE5YWD57Sg77yM5YiZ6YGN5Y6G5rOo5YaM5omA5pyJ55qE5a2Q6IqC54K5XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnJlZ2lzdGVyTmV3R3JvdXAoZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHByZUVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgICAgICAgIGlmIChhbmltYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhbmltYXRlQ2ZnID0gX3RoaXMuZ2V0KCdpc0luaXQnKSA/IGFuaW1hdGVPcHRpb24uYXBwZWFyIDogYW5pbWF0ZU9wdGlvbi5lbnRlcjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGVDZmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmFkZEFuaW1hdGlvbihlbGVtZW50TmFtZSwgZWxlbWVudCwgYW5pbWF0ZUNmZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmNsZWFyVXBkYXRlU3RhdHVzID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IGdyb3VwLmdldENoaWxkcmVuKCk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGNoaWxkcmVuLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgIGVsLnNldChTVEFUVVNfVVBEQVRFLCBudWxsKTsgLy8g5riF55CG5o6J5pu05paw54q25oCBXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g5riF55CG56a75bGP57yT5a2YXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmNsZWFyT2ZmU2NyZWVuQ2FjaGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvZmZTY3JlZW5Hcm91cCA9IHRoaXMuZ2V0KCdvZmZTY3JlZW5Hcm91cCcpO1xuICAgICAgICBpZiAob2ZmU2NyZWVuR3JvdXApIHtcbiAgICAgICAgICAgIC8vIOmUgOavgeWOn+WFiOeahOemu+e6vyBHcm91cFxuICAgICAgICAgICAgb2ZmU2NyZWVuR3JvdXAuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0KCdvZmZTY3JlZW5Hcm91cCcsIG51bGwpO1xuICAgICAgICB0aGlzLnNldCgnb2ZmU2NyZWVuQkJveCcsIG51bGwpO1xuICAgIH07XG4gICAgLy8gcHJpdmF0ZSB1cGRhdGVJbm5lcigpIHtcbiAgICAvLyAgIGNvbnN0IGdyb3VwID0gdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgLy8gICBjb25zdCBuZXdHcm91cCA9IHRoaXMuY3JlYXRlT2ZmU2NyZWVuR3JvdXAoKTtcbiAgICAvLyAgIHRoaXMucmVuZGVySW5uZXIobmV3R3JvdXApO1xuICAgIC8vICAgdGhpcy5hcHBseU9mZnNldCgpO1xuICAgIC8vICAgdGhpcy51cGRhdGVFbGVtZW50cyhuZXdHcm91cCwgZ3JvdXApO1xuICAgIC8vICAgdGhpcy5kZWxldGVFbGVtZW50cygpO1xuICAgIC8vICAgbmV3R3JvdXAuZGVzdHJveSgpOyAvLyDplIDmr4HomZrmi5/liIbnu4RcbiAgICAvLyB9XG4gICAgLy8g6I635Y+W5Y+R55Sf5aeU5omY5pe255qE5a+56LGh77yM5Zyo5LqL5Lu25Lit5oqb5Ye6XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmdldERlbGVnYXRlT2JqZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHZhciBuYW1lID0gdGhpcy5nZXQoJ25hbWUnKTtcbiAgICAgICAgdmFyIGRlbGVnYXRlT2JqZWN0ID0gKF9hID0ge30sXG4gICAgICAgICAgICBfYVtuYW1lXSA9IHRoaXMsXG4gICAgICAgICAgICBfYS5jb21wb25lbnQgPSB0aGlzLFxuICAgICAgICAgICAgX2EpO1xuICAgICAgICByZXR1cm4gZGVsZWdhdGVPYmplY3Q7XG4gICAgfTtcbiAgICAvLyDpmYTliqDlp5TmiZjkv6Hmga/vvIznlKjkuo7kuovku7ZcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUuYXBwZW5kRGVsZWdhdGVPYmplY3QgPSBmdW5jdGlvbiAocGFyZW50LCBjZmcpIHtcbiAgICAgICAgdmFyIHBhcmVudE9iamVjdCA9IHBhcmVudC5nZXQoJ2RlbGVnYXRlT2JqZWN0Jyk7XG4gICAgICAgIGlmICghY2ZnLmRlbGVnYXRlT2JqZWN0KSB7XG4gICAgICAgICAgICBjZmcuZGVsZWdhdGVPYmplY3QgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICB1dGlsXzEubWl4KGNmZy5kZWxlZ2F0ZU9iamVjdCwgcGFyZW50T2JqZWN0KTsgLy8g5bCG54i25YWD57Sg5LiK55qE5aeU5omY5L+h5oGv5aSN5Yi25Yiw6Ieq6LqrXG4gICAgfTtcbiAgICAvLyDojrflj5bpnIDopoHmm7/mjaLnmoTlsZ7mgKfvvIzlpoLmnpzljp/lhYjlm77lvaLlhYPntKDlrZjlnKjvvIzogIzmlrDlm77lvaLkuI3lrZjlnKjvvIzliJnorr7nva4gdW5kZWZpbmVkXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmdldFJlcGxhY2VBdHRycyA9IGZ1bmN0aW9uIChvcmlnaW5FbGVtZW50LCBuZXdFbGVtZW50KSB7XG4gICAgICAgIHZhciBvcmlnaW5BdHRycyA9IG9yaWdpbkVsZW1lbnQuYXR0cigpO1xuICAgICAgICB2YXIgbmV3QXR0cnMgPSBuZXdFbGVtZW50LmF0dHIoKTtcbiAgICAgICAgdXRpbF8xLmVhY2gob3JpZ2luQXR0cnMsIGZ1bmN0aW9uICh2LCBrKSB7XG4gICAgICAgICAgICBpZiAobmV3QXR0cnNba10gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG5ld0F0dHJzW2tdID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ld0F0dHJzO1xuICAgIH07XG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLnJlZ2lzdGVyTmV3R3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gZ3JvdXAuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgdXRpbF8xLmVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgICAgICBfdGhpcy5yZWdpc3RlckVsZW1lbnQoZWxlbWVudCk7IC8vIOazqOWGjOiKgueCuVxuICAgICAgICAgICAgZWxlbWVudC5zZXQoU1RBVFVTX1VQREFURSwgJ2FkZCcpOyAvLyDmiafooYzlrozmm7TmlrDlkI7orr7nva7nirbmgIHkvY3kuLrmt7vliqBcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgICAgIF90aGlzLnJlZ2lzdGVyTmV3R3JvdXAoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g56e76Zmk5aSa5L2Z55qE5YWD57SgXG4gICAgR3JvdXBDb21wb25lbnQucHJvdG90eXBlLmRlbGV0ZUVsZW1lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2hhcGVzTWFwID0gdGhpcy5nZXQoJ3NoYXBlc01hcCcpO1xuICAgICAgICB2YXIgZGVsZXRlQXJyYXkgPSBbXTtcbiAgICAgICAgLy8g6YGN5Y6G6I635Y+W6ZyA6KaB5Yig6Zmk55qE5Zu+5b2i5YWD57SgXG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlc01hcCwgZnVuY3Rpb24gKGVsZW1lbnQsIGlkKSB7XG4gICAgICAgICAgICBpZiAoIWVsZW1lbnQuZ2V0KFNUQVRVU19VUERBVEUpIHx8IGVsZW1lbnQuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlQXJyYXkucHVzaChbaWQsIGVsZW1lbnRdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0KFNUQVRVU19VUERBVEUsIG51bGwpOyAvLyDmuIXnkIbmjonmm7TmlrDnirbmgIFcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBhbmltYXRlID0gdGhpcy5nZXQoJ2FuaW1hdGUnKTtcbiAgICAgICAgdmFyIGFuaW1hdGVPcHRpb24gPSB0aGlzLmdldCgnYW5pbWF0ZU9wdGlvbicpO1xuICAgICAgICAvLyDliKDpmaTlm77lvaLlhYPntKBcbiAgICAgICAgdXRpbF8xLmVhY2goZGVsZXRlQXJyYXksIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgaWQgPSBpdGVtWzBdLCBlbGVtZW50ID0gaXRlbVsxXTtcbiAgICAgICAgICAgIGlmICghZWxlbWVudC5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldCgnbmFtZScpO1xuICAgICAgICAgICAgICAgIGlmIChhbmltYXRlICYmIGFuaW1hdGVPcHRpb24ubGVhdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g6ZyA6KaB5Yqo55S757uT5p2f5pe256e76Zmk5Zu+5b2iXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFja0FuaW1DZmcgPSB1dGlsXzEubWl4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMucmVtb3ZlRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sIGFuaW1hdGVPcHRpb24ubGVhdmUpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5yZW1vdmVBbmltYXRpb24oZWxlbWVudE5hbWUsIGVsZW1lbnQsIGNhbGxiYWNrQW5pbUNmZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5yZW1vdmVFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBzaGFwZXNNYXBbaWRdOyAvLyDku47nvJPlrZjkuK3np7vpmaRcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBHcm91cENvbXBvbmVudC5wcm90b3R5cGUucmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGlmIChlbGVtZW50LmdldCgnaXNHcm91cCcpKSB7XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gZWxlbWVudC5nZXQoJ2NvbXBvbmVudCcpO1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxlbWVudC5yZW1vdmUoKTtcbiAgICB9O1xuICAgIHJldHVybiBHcm91cENvbXBvbmVudDtcbn0oY29tcG9uZW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JvdXBDb21wb25lbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncm91cC1jb21wb25lbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBkb21fdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L2RvbS11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XG52YXIgSHRtbENvbXBvbmVudCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhIdG1sQ29tcG9uZW50LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEh0bWxDb21wb25lbnQoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IGNvbnRhaW5lcjogbnVsbCwgY29udGFpbmVyVHBsOiAnPGRpdj48L2Rpdj4nLCB1cGRhdGVBdXRvUmVuZGVyOiB0cnVlLCBjb250YWluZXJDbGFzc05hbWU6ICcnLCBwYXJlbnQ6IG51bGwgfSk7XG4gICAgICAgIHJldHVybiBjZmc7XG4gICAgfTtcbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5nZXRDb250YWluZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnY29udGFpbmVyJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmmL7npLrnu4Tku7ZcbiAgICAgKi9cbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXQoJ2NvbnRhaW5lcicpO1xuICAgICAgICBjb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgICB0aGlzLnNldCgndmlzaWJsZScsIHRydWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZqQ6JeP57uE5Lu2XG4gICAgICovXG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHRoaXMuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm5YWB6K645o2V5o2J5LqL5Lu2XG4gICAgICogQHBhcmFtIGNhcHR1cmUg5LqL5Lu25o2V5o2JXG4gICAgICovXG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuc2V0Q2FwdHVyZSA9IGZ1bmN0aW9uIChjYXB0dXJlKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldENvbnRhaW5lcigpO1xuICAgICAgICB2YXIgdmFsdWUgPSBjYXB0dXJlID8gJ2F1dG8nIDogJ25vbmUnO1xuICAgICAgICBjb250YWluZXIuc3R5bGUucG9pbnRlckV2ZW50cyA9IHZhbHVlO1xuICAgICAgICB0aGlzLnNldCgnY2FwdHVyZScsIGNhcHR1cmUpO1xuICAgIH07XG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuZ2V0QkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0Q29udGFpbmVyKCk7XG4gICAgICAgIHZhciB4ID0gcGFyc2VGbG9hdChjb250YWluZXIuc3R5bGUubGVmdCkgfHwgMDtcbiAgICAgICAgdmFyIHkgPSBwYXJzZUZsb2F0KGNvbnRhaW5lci5zdHlsZS50b3ApIHx8IDA7XG4gICAgICAgIHJldHVybiB1dGlsXzIuY3JlYXRlQkJveCh4LCB5LCBjb250YWluZXIuY2xpZW50V2lkdGgsIGNvbnRhaW5lci5jbGllbnRIZWlnaHQpO1xuICAgIH07XG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgIHV0aWxfMi5jbGVhckRvbShjb250YWluZXIpO1xuICAgIH07XG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVFdmVudCgpO1xuICAgICAgICB0aGlzLnJlbW92ZURvbSgpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWkjeWGmSBpbml077yM5Li76KaB5piv5Yid5aeL5YyWIERPTSDlkozkuovku7ZcbiAgICAgKi9cbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5pbml0Q29udGFpbmVyKCk7XG4gICAgICAgIHRoaXMuaW5pdERvbSgpO1xuICAgICAgICB0aGlzLnJlc2V0U3R5bGVzKCk7IC8vIOWIneWni+WMluagt+W8j1xuICAgICAgICB0aGlzLmFwcGx5U3R5bGVzKCk7IC8vIOW6lOeUqOagt+W8j1xuICAgICAgICB0aGlzLmluaXRFdmVudCgpO1xuICAgICAgICB0aGlzLmluaXRDYXB0dXJlKCk7XG4gICAgICAgIHRoaXMuaW5pdFZpc2libGUoKTtcbiAgICB9O1xuICAgIEh0bWxDb21wb25lbnQucHJvdG90eXBlLmluaXRDYXB0dXJlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldENhcHR1cmUodGhpcy5nZXQoJ2NhcHR1cmUnKSk7XG4gICAgfTtcbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5pbml0VmlzaWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmdldCgndmlzaWJsZScpKSB7XG4gICAgICAgICAgICAvLyDorr7nva7liJ3lp4vmmL7npLrnirbmgIFcbiAgICAgICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zaG93KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEh0bWxDb21wb25lbnQucHJvdG90eXBlLmluaXREb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5pbml0Q29udGFpbmVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXQoJ2NvbnRhaW5lcicpO1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKGNvbnRhaW5lcikpIHtcbiAgICAgICAgICAgIC8vIOacquaMh+WumiBjb250YWluZXIg5YiZ5Yib5bu6XG4gICAgICAgICAgICBjb250YWluZXIgPSB0aGlzLmNyZWF0ZURvbSgpO1xuICAgICAgICAgICAgdmFyIHBhcmVudF8xID0gdGhpcy5nZXQoJ3BhcmVudCcpO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc1N0cmluZyhwYXJlbnRfMSkpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRfMSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudF8xKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldCgncGFyZW50JywgcGFyZW50XzEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGFyZW50XzEuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICAgICAgICAgIHRoaXMuc2V0KCdjb250YWluZXInLCBjb250YWluZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc1N0cmluZyhjb250YWluZXIpKSB7XG4gICAgICAgICAgICAvLyDnlKjmiLfkvKDlhaXnmoQgaWQsIOS9nOS4uiBjb250YWluZXJcbiAgICAgICAgICAgIGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNvbnRhaW5lcik7XG4gICAgICAgICAgICB0aGlzLnNldCgnY29udGFpbmVyJywgY29udGFpbmVyKTtcbiAgICAgICAgfSAvLyBlbHNlIGNvbnRhaW5lciDmmK8gRE9NXG4gICAgICAgIGlmICghdGhpcy5nZXQoJ3BhcmVudCcpKSB7XG4gICAgICAgICAgICB0aGlzLnNldCgncGFyZW50JywgY29udGFpbmVyLnBhcmVudE5vZGUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmoLflvI/pnIDopoHov5vooYzlkIjlubbvvIzkuI3og73ljZXnuq/nmoTmm7/mjaLvvIzlkKbliJnkvb/nlKjpnZ7luLjkuI3mlrnkvr9cbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5yZXNldFN0eWxlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5nZXQoJ2RvbVN0eWxlcycpO1xuICAgICAgICB2YXIgZGVmYXVsdFN0eWxlcyA9IHRoaXMuZ2V0KCdkZWZhdWx0U3R5bGVzJyk7XG4gICAgICAgIGlmICghc3R5bGUpIHtcbiAgICAgICAgICAgIHN0eWxlID0gZGVmYXVsdFN0eWxlcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0eWxlID0gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRTdHlsZXMsIHN0eWxlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldCgnZG9tU3R5bGVzJywgc3R5bGUpO1xuICAgIH07XG4gICAgLy8g5bqU55So5omA5pyJ55qE5qC35byPXG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuYXBwbHlTdHlsZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkb21TdHlsZXMgPSB0aGlzLmdldCgnZG9tU3R5bGVzJyk7XG4gICAgICAgIGlmICghZG9tU3R5bGVzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0Q29udGFpbmVyKCk7XG4gICAgICAgIHRoaXMuYXBwbHlDaGlsZHJlblN0eWxlcyhjb250YWluZXIsIGRvbVN0eWxlcyk7XG4gICAgICAgIHZhciBjb250YWluZXJDbGFzc05hbWUgPSB0aGlzLmdldCgnY29udGFpbmVyQ2xhc3NOYW1lJyk7XG4gICAgICAgIGlmIChjb250YWluZXJDbGFzc05hbWUgJiYgdXRpbF8yLmhhc0NsYXNzKGNvbnRhaW5lciwgY29udGFpbmVyQ2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lckNzcyA9IGRvbVN0eWxlc1tjb250YWluZXJDbGFzc05hbWVdO1xuICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoY29udGFpbmVyLCBjb250YWluZXJDc3MpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5hcHBseUNoaWxkcmVuU3R5bGVzID0gZnVuY3Rpb24gKGVsZW1lbnQsIHN0eWxlcykge1xuICAgICAgICB1dGlsXzEuZWFjaChzdHlsZXMsIGZ1bmN0aW9uIChzdHlsZSwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRzID0gZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKG5hbWUpO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGVsLCBzdHlsZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDlupTnlKjliLDljZXkuKogRE9NXG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuYXBwbHlTdHlsZSA9IGZ1bmN0aW9uIChjc3NOYW1lLCBkb20pIHtcbiAgICAgICAgdmFyIGRvbVN0eWxlcyA9IHRoaXMuZ2V0KCdkb21TdHlsZXMnKTtcbiAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoZG9tLCBkb21TdHlsZXNbY3NzTmFtZV0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuICAgIEh0bWxDb21wb25lbnQucHJvdG90eXBlLmNyZWF0ZURvbSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lclRwbCA9IHRoaXMuZ2V0KCdjb250YWluZXJUcGwnKTtcbiAgICAgICAgcmV0dXJuIGRvbV91dGlsXzEuY3JlYXRlRG9tKGNvbnRhaW5lclRwbCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog5Yid5aeL5YyW5LqL5Lu2XG4gICAgICovXG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUuaW5pdEV2ZW50ID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDmuIXnkIYgRE9NXG4gICAgICovXG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUucmVtb3ZlRG9tID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXQoJ2NvbnRhaW5lcicpO1xuICAgICAgICBjb250YWluZXIgJiYgY29udGFpbmVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDmuIXnkIbkuovku7ZcbiAgICAgKi9cbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICBIdG1sQ29tcG9uZW50LnByb3RvdHlwZS51cGRhdGVJbm5lciA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgLy8g5pu05paw5qC35byPXG4gICAgICAgIGlmICh1dGlsXzEuaGFzS2V5KGNmZywgJ2RvbVN0eWxlcycpKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0U3R5bGVzKCk7XG4gICAgICAgICAgICB0aGlzLmFwcGx5U3R5bGVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Y+q6KaB5bGe5oCn5Y+R55Sf5Y+Y5YyW77yM6YO96LCD5pW05LiA5Lqb5L2N572uXG4gICAgICAgIHRoaXMucmVzZXRQb3NpdGlvbigpO1xuICAgIH07XG4gICAgSHRtbENvbXBvbmVudC5wcm90b3R5cGUucmVzZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICA7XG4gICAgcmV0dXJuIEh0bWxDb21wb25lbnQ7XG59KGNvbXBvbmVudF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEh0bWxDb21wb25lbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1odG1sLWNvbXBvbmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdyb3VwX2NvbXBvbmVudF8xID0gcmVxdWlyZShcIi4uL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbC91dGlsXCIpO1xudmFyIEFyY0Fubm90YXRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQXJjQW5ub3RhdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBcmNBbm5vdGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDpu5jorqTnmoTphY3nva7poblcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSDpu5jorqTnmoTphY3nva7poblcbiAgICAgKi9cbiAgICBBcmNBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ2Fubm90YXRpb24nLCB0eXBlOiAnYXJjJywgbG9jYXRpb25UeXBlOiAnY2lyY2xlJywgY2VudGVyOiBudWxsLCByYWRpdXM6IDEwMCwgc3RhcnRBbmdsZTogLU1hdGguUEkgLyAyLCBlbmRBbmdsZTogKE1hdGguUEkgKiAzKSAvIDIsIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAnIzk5OScsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgfSB9KTtcbiAgICB9O1xuICAgIEFyY0Fubm90YXRpb24ucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHRoaXMucmVuZGVyQXJjKGdyb3VwKTtcbiAgICB9O1xuICAgIEFyY0Fubm90YXRpb24ucHJvdG90eXBlLmdldEFyY1BhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0TG9jYXRpb24oKSwgY2VudGVyID0gX2EuY2VudGVyLCByYWRpdXMgPSBfYS5yYWRpdXMsIHN0YXJ0QW5nbGUgPSBfYS5zdGFydEFuZ2xlLCBlbmRBbmdsZSA9IF9hLmVuZEFuZ2xlO1xuICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHV0aWxfMS5nZXRDaXJjbGVQb2ludChjZW50ZXIsIHJhZGl1cywgc3RhcnRBbmdsZSk7XG4gICAgICAgIHZhciBlbmRQb2ludCA9IHV0aWxfMS5nZXRDaXJjbGVQb2ludChjZW50ZXIsIHJhZGl1cywgZW5kQW5nbGUpO1xuICAgICAgICB2YXIgbGFyZ2VGbGFnID0gZW5kQW5nbGUgLSBzdGFydEFuZ2xlID4gTWF0aC5QSSA/IDEgOiAwO1xuICAgICAgICB2YXIgcGF0aCA9IFtbJ00nLCBzdGFydFBvaW50LngsIHN0YXJ0UG9pbnQueV1dO1xuICAgICAgICBpZiAoZW5kQW5nbGUgLSBzdGFydEFuZ2xlID09PSBNYXRoLlBJICogMikge1xuICAgICAgICAgICAgLy8g5pW05Liq5ZyG5piv5YiG5Ymy5oiQ5Lik5Liq5ZyGXG4gICAgICAgICAgICB2YXIgbWlkZGxlUG9pbnQgPSB1dGlsXzEuZ2V0Q2lyY2xlUG9pbnQoY2VudGVyLCByYWRpdXMsIHN0YXJ0QW5nbGUgKyBNYXRoLlBJKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgbGFyZ2VGbGFnLCAxLCBtaWRkbGVQb2ludC54LCBtaWRkbGVQb2ludC55XSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydBJywgcmFkaXVzLCByYWRpdXMsIDAsIGxhcmdlRmxhZywgMSwgZW5kUG9pbnQueCwgZW5kUG9pbnQueV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnQScsIHJhZGl1cywgcmFkaXVzLCAwLCBsYXJnZUZsYWcsIDEsIGVuZFBvaW50LngsIGVuZFBvaW50LnldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIC8vIOe7mOWItiBhcmNcbiAgICBBcmNBbm5vdGF0aW9uLnByb3RvdHlwZS5yZW5kZXJBcmMgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgLy8g5Lmf5Y+v5LulIOmAmui/hyBnZXQoJ2NlbnRlcicpIOexu+S8vOeahOaWueW8j+mAkOS4quiOt+WPllxuICAgICAgICB2YXIgcGF0aCA9IHRoaXMuZ2V0QXJjUGF0aCgpO1xuICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLmdldCgnc3R5bGUnKTtcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdhcmMnKSxcbiAgICAgICAgICAgIG5hbWU6ICdhbm5vdGF0aW9uLWFyYycsXG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IHBhdGggfSwgc3R5bGUpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBBcmNBbm5vdGF0aW9uO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBcmNBbm5vdGF0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXJjLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ3JvdXBfY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi4vYWJzdHJhY3QvZ3JvdXAtY29tcG9uZW50XCIpO1xudmFyIGdyYXBoaWNfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2dyYXBoaWNcIik7XG52YXIgbWF0cml4XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9tYXRyaXhcIik7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3RoZW1lXCIpO1xudmFyIERhdGFNYXJrZXJBbm5vdGF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERhdGFNYXJrZXJBbm5vdGF0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERhdGFNYXJrZXJBbm5vdGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOm7mOiupOeahOmFjee9rumhuVxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IOm7mOiupOeahOmFjee9rumhuVxuICAgICAqL1xuICAgIERhdGFNYXJrZXJBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ2Fubm90YXRpb24nLCB0eXBlOiAnZGF0YU1hcmtlcicsIGxvY2F0aW9uVHlwZTogJ3BvaW50JywgeDogMCwgeTogMCwgcG9pbnQ6IHt9LCBsaW5lOiB7fSwgdGV4dDoge30sIGRpcmVjdGlvbjogJ3Vwd2FyZCcsIGF1dG9BZGp1c3Q6IHRydWUsIGNvb3JkaW5hdGVCQm94OiBudWxsLCBkZWZhdWx0Q2ZnOiB7XG4gICAgICAgICAgICAgICAgcG9pbnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHI6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiAnI0ZGRkZGRicsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjMTg5MEZGJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiAyMCxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogdGhlbWVfMS5kZWZhdWx0LmxpbmVDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogJycsXG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMC42NSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6IHRoZW1lXzEuZGVmYXVsdC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9IH0pO1xuICAgIH07XG4gICAgRGF0YU1hcmtlckFubm90YXRpb24ucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIGlmICh1dGlsXzEuZ2V0KHRoaXMuZ2V0KCdsaW5lJyksICdkaXNwbGF5JykpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyTGluZShncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHV0aWxfMS5nZXQodGhpcy5nZXQoJ3RleHQnKSwgJ2Rpc3BsYXknKSkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJUZXh0KGdyb3VwKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmdldCh0aGlzLmdldCgncG9pbnQnKSwgJ2Rpc3BsYXknKSkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJQb2ludChncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdhdXRvQWRqdXN0JykpIHtcbiAgICAgICAgICAgIHRoaXMuYXV0b0FkanVzdChncm91cCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERhdGFNYXJrZXJBbm5vdGF0aW9uLnByb3RvdHlwZS5hcHBseU9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5tb3ZlRWxlbWVudFRvKHRoaXMuZ2V0KCdncm91cCcpLCB7XG4gICAgICAgICAgICB4OiB0aGlzLmdldCgneCcpICsgdGhpcy5nZXQoJ29mZnNldFgnKSxcbiAgICAgICAgICAgIHk6IHRoaXMuZ2V0KCd5JykgKyB0aGlzLmdldCgnb2Zmc2V0WScpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIERhdGFNYXJrZXJBbm5vdGF0aW9uLnByb3RvdHlwZS5yZW5kZXJQb2ludCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgcG9pbnQgPSB0aGlzLmdldFNoYXBlQXR0cnMoKS5wb2ludDtcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgdHlwZTogJ2NpcmNsZScsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3BvaW50JyksXG4gICAgICAgICAgICBuYW1lOiAnYW5ub3RhdGlvbi1wb2ludCcsXG4gICAgICAgICAgICBhdHRyczogcG9pbnQsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRGF0YU1hcmtlckFubm90YXRpb24ucHJvdG90eXBlLnJlbmRlckxpbmUgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIGxpbmUgPSB0aGlzLmdldFNoYXBlQXR0cnMoKS5saW5lO1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ2xpbmUnKSxcbiAgICAgICAgICAgIG5hbWU6ICdhbm5vdGF0aW9uLWxpbmUnLFxuICAgICAgICAgICAgYXR0cnM6IGxpbmUsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRGF0YU1hcmtlckFubm90YXRpb24ucHJvdG90eXBlLnJlbmRlclRleHQgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHRleHRBdHRycyA9IHRoaXMuZ2V0U2hhcGVBdHRycygpLnRleHQ7XG4gICAgICAgIHZhciB4ID0gdGV4dEF0dHJzLngsIHkgPSB0ZXh0QXR0cnMueSwgdGV4dCA9IHRleHRBdHRycy50ZXh0LCBzdHlsZSA9IHRzbGliXzEuX19yZXN0KHRleHRBdHRycywgW1wieFwiLCBcInlcIiwgXCJ0ZXh0XCJdKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXQoJ3RleHQnKSwgYmFja2dyb3VuZCA9IF9hLmJhY2tncm91bmQsIG1heExlbmd0aCA9IF9hLm1heExlbmd0aCwgYXV0b0VsbGlwc2lzID0gX2EuYXV0b0VsbGlwc2lzLCBpc1ZlcnRpdmFsID0gX2EuaXNWZXJ0aXZhbCwgZWxsaXBzaXNQb3NpdGlvbiA9IF9hLmVsbGlwc2lzUG9zaXRpb247XG4gICAgICAgIHZhciB0YWdDZmcgPSB7XG4gICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgndGV4dCcpLFxuICAgICAgICAgICAgbmFtZTogJ2Fubm90YXRpb24tdGV4dCcsXG4gICAgICAgICAgICBjb250ZW50OiB0ZXh0LFxuICAgICAgICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgICAgICAgYmFja2dyb3VuZDogYmFja2dyb3VuZCxcbiAgICAgICAgICAgIG1heExlbmd0aDogbWF4TGVuZ3RoLFxuICAgICAgICAgICAgYXV0b0VsbGlwc2lzOiBhdXRvRWxsaXBzaXMsXG4gICAgICAgICAgICBpc1ZlcnRpdmFsOiBpc1ZlcnRpdmFsLFxuICAgICAgICAgICAgZWxsaXBzaXNQb3NpdGlvbjogZWxsaXBzaXNQb3NpdGlvbixcbiAgICAgICAgfTtcbiAgICAgICAgZ3JhcGhpY18xLnJlbmRlclRhZyhncm91cCwgdGFnQ2ZnKTtcbiAgICB9O1xuICAgIERhdGFNYXJrZXJBbm5vdGF0aW9uLnByb3RvdHlwZS5hdXRvQWRqdXN0ID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSB0aGlzLmdldCgnZGlyZWN0aW9uJyk7XG4gICAgICAgIHZhciB4ID0gdGhpcy5nZXQoJ3gnKTtcbiAgICAgICAgdmFyIHkgPSB0aGlzLmdldCgneScpO1xuICAgICAgICB2YXIgbGluZUxlbmd0aCA9IHV0aWxfMS5nZXQodGhpcy5nZXQoJ2xpbmUnKSwgJ2xlbmd0aCcsIDApO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZUJCb3ggPSB0aGlzLmdldCgnY29vcmRpbmF0ZUJCb3gnKTtcbiAgICAgICAgdmFyIF9hID0gZ3JvdXAuZ2V0QkJveCgpLCBtaW5YID0gX2EubWluWCwgbWF4WCA9IF9hLm1heFgsIG1pblkgPSBfYS5taW5ZLCBtYXhZID0gX2EubWF4WTtcbiAgICAgICAgdmFyIHRleHRHcm91cCA9IGdyb3VwLmZpbmRCeUlkKHRoaXMuZ2V0RWxlbWVudElkKCd0ZXh0LWdyb3VwJykpO1xuICAgICAgICB2YXIgdGV4dFNoYXBlID0gZ3JvdXAuZmluZEJ5SWQodGhpcy5nZXRFbGVtZW50SWQoJ3RleHQnKSk7XG4gICAgICAgIHZhciBsaW5lU2hhcGUgPSBncm91cC5maW5kQnlJZCh0aGlzLmdldEVsZW1lbnRJZCgnbGluZScpKTtcbiAgICAgICAgaWYgKCFjb29yZGluYXRlQkJveCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0ZXh0R3JvdXApIHtcbiAgICAgICAgICAgIGlmICh4ICsgbWluWCA8PSBjb29yZGluYXRlQkJveC5taW5YKSB7XG4gICAgICAgICAgICAgICAgLy8g5bem5L6n6LaF5Ye6XG4gICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93ID0gY29vcmRpbmF0ZUJCb3gubWluWCAtICh4ICsgbWluWCk7XG4gICAgICAgICAgICAgICAgbWF0cml4XzEuYXBwbHlUcmFuc2xhdGUodGV4dEdyb3VwLCB0ZXh0R3JvdXAuYXR0cigneCcpICsgb3ZlcmZsb3csIHRleHRHcm91cC5hdHRyKCd5JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHggKyBtYXhYID49IGNvb3JkaW5hdGVCQm94Lm1heFgpIHtcbiAgICAgICAgICAgICAgICAvLyDlj7PkvqfotoXlh7pcbiAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3cgPSB4ICsgbWF4WCAtIGNvb3JkaW5hdGVCQm94Lm1heFg7XG4gICAgICAgICAgICAgICAgbWF0cml4XzEuYXBwbHlUcmFuc2xhdGUodGV4dEdyb3VwLCB0ZXh0R3JvdXAuYXR0cigneCcpIC0gb3ZlcmZsb3csIHRleHRHcm91cC5hdHRyKCd5JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICgoZGlyZWN0aW9uID09PSAndXB3YXJkJyAmJiB5ICsgbWluWSA8PSBjb29yZGluYXRlQkJveC5taW5ZKSB8fFxuICAgICAgICAgICAgKGRpcmVjdGlvbiAhPT0gJ3Vwd2FyZCcgJiYgeSArIG1heFkgPj0gY29vcmRpbmF0ZUJCb3gubWF4WSkpIHtcbiAgICAgICAgICAgIC8vIOS4iuaWueaIluiAheS4i+aWuei2heWHulxuICAgICAgICAgICAgdmFyIHRleHRCYXNlbGluZSA9IHZvaWQgMDtcbiAgICAgICAgICAgIHZhciBmYWN0b3IgPSB2b2lkIDA7XG4gICAgICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAndXB3YXJkJyAmJiB5ICsgbWluWSA8PSBjb29yZGluYXRlQkJveC5taW5ZKSB7XG4gICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICAgICAgICAgICAgZmFjdG9yID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZSA9ICdib3R0b20nO1xuICAgICAgICAgICAgICAgIGZhY3RvciA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGV4dFNoYXBlLmF0dHIoJ3RleHRCYXNlbGluZScsIHRleHRCYXNlbGluZSk7XG4gICAgICAgICAgICBpZiAobGluZVNoYXBlKSB7XG4gICAgICAgICAgICAgICAgbGluZVNoYXBlLmF0dHIoJ3BhdGgnLCBbXG4gICAgICAgICAgICAgICAgICAgIFsnTScsIDAsIDBdLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCAwLCBsaW5lTGVuZ3RoICogZmFjdG9yXSxcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdHJpeF8xLmFwcGx5VHJhbnNsYXRlKHRleHRHcm91cCwgdGV4dEdyb3VwLmF0dHIoJ3gnKSwgKGxpbmVMZW5ndGggKyAyKSAqIGZhY3Rvcik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERhdGFNYXJrZXJBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRTaGFwZUF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGluZURpc3BsYXkgPSB1dGlsXzEuZ2V0KHRoaXMuZ2V0KCdsaW5lJyksICdkaXNwbGF5Jyk7XG4gICAgICAgIHZhciBwb2ludFN0eWxlID0gdXRpbF8xLmdldCh0aGlzLmdldCgncG9pbnQnKSwgJ3N0eWxlJywge30pO1xuICAgICAgICB2YXIgbGluZVN0eWxlID0gdXRpbF8xLmdldCh0aGlzLmdldCgnbGluZScpLCAnc3R5bGUnLCB7fSk7XG4gICAgICAgIHZhciB0ZXh0U3R5bGUgPSB1dGlsXzEuZ2V0KHRoaXMuZ2V0KCd0ZXh0JyksICdzdHlsZScsIHt9KTtcbiAgICAgICAgdmFyIGRpcmVjdGlvbiA9IHRoaXMuZ2V0KCdkaXJlY3Rpb24nKTtcbiAgICAgICAgdmFyIGxpbmVMZW5ndGggPSBsaW5lRGlzcGxheSA/IHV0aWxfMS5nZXQodGhpcy5nZXQoJ2xpbmUnKSwgJ2xlbmd0aCcsIDApIDogMDtcbiAgICAgICAgdmFyIGZhY3RvciA9IGRpcmVjdGlvbiA9PT0gJ3Vwd2FyZCcgPyAtMSA6IDE7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb2ludDogdHNsaWJfMS5fX2Fzc2lnbih7IHg6IDAsIHk6IDAgfSwgcG9pbnRTdHlsZSksXG4gICAgICAgICAgICBsaW5lOiB0c2xpYl8xLl9fYXNzaWduKHsgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICBbJ00nLCAwLCAwXSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgMCwgbGluZUxlbmd0aCAqIGZhY3Rvcl0sXG4gICAgICAgICAgICAgICAgXSB9LCBsaW5lU3R5bGUpLFxuICAgICAgICAgICAgdGV4dDogdHNsaWJfMS5fX2Fzc2lnbih7IHg6IDAsIHk6IChsaW5lTGVuZ3RoICsgMikgKiBmYWN0b3IsIHRleHQ6IHV0aWxfMS5nZXQodGhpcy5nZXQoJ3RleHQnKSwgJ2NvbnRlbnQnLCAnJyksIHRleHRCYXNlbGluZTogZGlyZWN0aW9uID09PSAndXB3YXJkJyA/ICdib3R0b20nIDogJ3RvcCcgfSwgdGV4dFN0eWxlKSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBEYXRhTWFya2VyQW5ub3RhdGlvbjtcbn0oZ3JvdXBfY29tcG9uZW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRGF0YU1hcmtlckFubm90YXRpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhLW1hcmtlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdyb3VwX2NvbXBvbmVudF8xID0gcmVxdWlyZShcIi4uL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvdGhlbWVcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBncmFwaGljXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9ncmFwaGljXCIpO1xudmFyIERhdGFSZWdpb25Bbm5vdGF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERhdGFSZWdpb25Bbm5vdGF0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERhdGFSZWdpb25Bbm5vdGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOm7mOiupOeahOmFjee9rumhuVxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IOm7mOiupOeahOmFjee9rumhuVxuICAgICAqL1xuICAgIERhdGFSZWdpb25Bbm5vdGF0aW9uLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ2Fubm90YXRpb24nLCB0eXBlOiAnZGF0YVJlZ2lvbicsIGxvY2F0aW9uVHlwZTogJ3BvaW50cycsIHBvaW50czogW10sIGxpbmVMZW5ndGg6IDAsIHJlZ2lvbjoge30sIHRleHQ6IHt9LCBkZWZhdWx0Q2ZnOiB7XG4gICAgICAgICAgICAgICAgcmVnaW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQucmVnaW9uQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6ICcnLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ2JvdHRvbScsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogdGhlbWVfMS5kZWZhdWx0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0gfSk7XG4gICAgfTtcbiAgICBEYXRhUmVnaW9uQW5ub3RhdGlvbi5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHJlZ2lvblN0eWxlID0gdXRpbF8xLmdldCh0aGlzLmdldCgncmVnaW9uJyksICdzdHlsZScsIHt9KTtcbiAgICAgICAgdmFyIHRleHRTdHlsZSA9IHV0aWxfMS5nZXQodGhpcy5nZXQoJ3RleHQnKSwgJ3N0eWxlJywge30pO1xuICAgICAgICB2YXIgbGluZUxlbmd0aCA9IHRoaXMuZ2V0KCdsaW5lTGVuZ3RoJykgfHwgMDtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMuZ2V0KCdwb2ludHMnKTtcbiAgICAgICAgaWYgKCFwb2ludHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJib3ggPSB1dGlsXzIucG9pbnRzVG9CQm94KHBvaW50cyk7XG4gICAgICAgIC8vIHJlbmRlciByZWdpb25cbiAgICAgICAgdmFyIHBhdGggPSBbXTtcbiAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50c1swXS54LCBiYm94Lm1pblkgLSBsaW5lTGVuZ3RoXSk7XG4gICAgICAgIHBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHBvaW50LngsIHBvaW50LnldKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHBhdGgucHVzaChbJ0wnLCBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdLngsIHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV0ueSAtIGxpbmVMZW5ndGhdKTtcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdyZWdpb24nKSxcbiAgICAgICAgICAgIG5hbWU6ICdhbm5vdGF0aW9uLXJlZ2lvbicsXG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IHBhdGggfSwgcmVnaW9uU3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gcmVuZGVyIHRleHRcbiAgICAgICAgdmFyIHRleHRDZmcgPSB0c2xpYl8xLl9fYXNzaWduKHsgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCd0ZXh0JyksIG5hbWU6ICdhbm5vdGF0aW9uLXRleHQnLCB4OiAoYmJveC5taW5YICsgYmJveC5tYXhYKSAvIDIsIHk6IGJib3gubWluWSAtIGxpbmVMZW5ndGggfSwgdGhpcy5nZXQoJ3RleHQnKSk7XG4gICAgICAgIGdyYXBoaWNfMS5yZW5kZXJUYWcoZ3JvdXAsIHRleHRDZmcpO1xuICAgIH07XG4gICAgcmV0dXJuIERhdGFSZWdpb25Bbm5vdGF0aW9uO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEYXRhUmVnaW9uQW5ub3RhdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGEtcmVnaW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ3JvdXBfY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi4vYWJzdHJhY3QvZ3JvdXAtY29tcG9uZW50XCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgSW1hZ2VBbm5vdGF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEltYWdlQW5ub3RhdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBJbWFnZUFubm90YXRpb24oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOm7mOiupOeahOmFjee9rumhuVxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IOm7mOiupOeahOmFjee9rumhuVxuICAgICAqL1xuICAgIEltYWdlQW5ub3RhdGlvbi5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IG5hbWU6ICdhbm5vdGF0aW9uJywgdHlwZTogJ2ltYWdlJywgbG9jYXRpb25UeXBlOiAncmVnaW9uJywgc3RhcnQ6IG51bGwsIGVuZDogbnVsbCwgc3JjOiBudWxsLCBzdHlsZToge30gfSk7XG4gICAgfTtcbiAgICBJbWFnZUFubm90YXRpb24ucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHRoaXMucmVuZGVySW1hZ2UoZ3JvdXApO1xuICAgIH07XG4gICAgSW1hZ2VBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRJbWFnZUF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmdldCgnc3RhcnQnKTtcbiAgICAgICAgdmFyIGVuZCA9IHRoaXMuZ2V0KCdlbmQnKTtcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5nZXQoJ3N0eWxlJyk7XG4gICAgICAgIHZhciBiYm94ID0gdXRpbF8xLnJlZ2lvblRvQkJveCh7IHN0YXJ0OiBzdGFydCwgZW5kOiBlbmQgfSk7XG4gICAgICAgIHZhciBzcmMgPSB0aGlzLmdldCgnc3JjJyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHsgeDogYmJveC54LCB5OiBiYm94LnksIGltZzogc3JjLCB3aWR0aDogYmJveC53aWR0aCwgaGVpZ2h0OiBiYm94LmhlaWdodCB9LCBzdHlsZSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLblm77niYdcbiAgICBJbWFnZUFubm90YXRpb24ucHJvdG90eXBlLnJlbmRlckltYWdlID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIHR5cGU6ICdpbWFnZScsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ2ltYWdlJyksXG4gICAgICAgICAgICBuYW1lOiAnYW5ub3RhdGlvbi1pbWFnZScsXG4gICAgICAgICAgICBhdHRyczogdGhpcy5nZXRJbWFnZUF0dHJzKCksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEltYWdlQW5ub3RhdGlvbjtcbn0oZ3JvdXBfY29tcG9uZW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSW1hZ2VBbm5vdGF0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW1hZ2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIi4vbGluZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxpbmVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxpbmVfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHRleHRfMSA9IHJlcXVpcmUoXCIuL3RleHRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUZXh0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0ZXh0XzEuZGVmYXVsdDsgfSB9KTtcbnZhciBhcmNfMSA9IHJlcXVpcmUoXCIuL2FyY1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkFyY1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYXJjXzEuZGVmYXVsdDsgfSB9KTtcbnZhciByZWdpb25fMSA9IHJlcXVpcmUoXCIuL3JlZ2lvblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlJlZ2lvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVnaW9uXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBpbWFnZV8xID0gcmVxdWlyZShcIi4vaW1hZ2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJJbWFnZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaW1hZ2VfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGRhdGFfbWFya2VyXzEgPSByZXF1aXJlKFwiLi9kYXRhLW1hcmtlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkRhdGFNYXJrZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRhdGFfbWFya2VyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBkYXRhX3JlZ2lvbl8xID0gcmVxdWlyZShcIi4vZGF0YS1yZWdpb25cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJEYXRhUmVnaW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBkYXRhX3JlZ2lvbl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcmVnaW9uX2ZpbHRlcl8xID0gcmVxdWlyZShcIi4vcmVnaW9uLWZpbHRlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlJlZ2lvbkZpbHRlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVnaW9uX2ZpbHRlcl8xLmRlZmF1bHQ7IH0gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdyb3VwX2NvbXBvbmVudF8xID0gcmVxdWlyZShcIi4uL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbnZhciBncmFwaGljXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9ncmFwaGljXCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbC91dGlsXCIpO1xudmFyIExpbmVBbm5vdGF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmVBbm5vdGF0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIExpbmVBbm5vdGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDpu5jorqTnmoTphY3nva7poblcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSDpu5jorqTnmoTphY3nva7poblcbiAgICAgKi9cbiAgICBMaW5lQW5ub3RhdGlvbi5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IG5hbWU6ICdhbm5vdGF0aW9uJywgdHlwZTogJ2xpbmUnLCBsb2NhdGlvblR5cGU6ICdyZWdpb24nLCBzdGFydDogbnVsbCwgZW5kOiBudWxsLCBzdHlsZToge30sIHRleHQ6IG51bGwsIGRlZmF1bHRDZmc6IHtcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ2JvdHRvbScsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6IHRoZW1lXzEuZGVmYXVsdC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGV4dDoge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldFg6IDAsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldFk6IDAsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoZW1lXzEuZGVmYXVsdC5saW5lQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0gfSk7XG4gICAgfTtcbiAgICBMaW5lQW5ub3RhdGlvbi5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdGhpcy5yZW5kZXJMaW5lKGdyb3VwKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCd0ZXh0JykpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyTGFiZWwoZ3JvdXApO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDnu5jliLbnur9cbiAgICBMaW5lQW5ub3RhdGlvbi5wcm90b3R5cGUucmVuZGVyTGluZSA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmdldCgnc3RhcnQnKTtcbiAgICAgICAgdmFyIGVuZCA9IHRoaXMuZ2V0KCdlbmQnKTtcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5nZXQoJ3N0eWxlJyk7XG4gICAgICAgIHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbGluZScpLFxuICAgICAgICAgICAgbmFtZTogJ2Fubm90YXRpb24tbGluZScsXG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHgxOiBzdGFydC54LCB5MTogc3RhcnQueSwgeDI6IGVuZC54LCB5MjogZW5kLnkgfSwgc3R5bGUpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOiOt+WPliBsYWJlbCDnmoTkvY3nva5cbiAgICBMaW5lQW5ub3RhdGlvbi5wcm90b3R5cGUuZ2V0TGFiZWxQb2ludCA9IGZ1bmN0aW9uIChzdGFydCwgZW5kLCBwb3NpdGlvbikge1xuICAgICAgICB2YXIgcGVyY2VudDtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnc3RhcnQnKSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIHBlcmNlbnQgPSAwLjU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzU3RyaW5nKHBvc2l0aW9uKSAmJiBwb3NpdGlvbi5pbmRleE9mKCclJykgIT09IC0xKSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gcGFyc2VJbnQocG9zaXRpb24sIDEwKSAvIDEwMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNOdW1iZXIocG9zaXRpb24pKSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gcG9zaXRpb247XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGVyY2VudCA+IDEgfHwgcGVyY2VudCA8IDApIHtcbiAgICAgICAgICAgIHBlcmNlbnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB1dGlsXzIuZ2V0VmFsdWVCeVBlcmNlbnQoc3RhcnQueCwgZW5kLngsIHBlcmNlbnQpLFxuICAgICAgICAgICAgeTogdXRpbF8yLmdldFZhbHVlQnlQZXJjZW50KHN0YXJ0LnksIGVuZC55LCBwZXJjZW50KSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8vIOe7mOWItiBsYWJlbFxuICAgIExpbmVBbm5vdGF0aW9uLnByb3RvdHlwZS5yZW5kZXJMYWJlbCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgdGV4dCA9IHRoaXMuZ2V0KCd0ZXh0Jyk7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuZ2V0KCdzdGFydCcpO1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5nZXQoJ2VuZCcpO1xuICAgICAgICB2YXIgcG9zaXRpb24gPSB0ZXh0LnBvc2l0aW9uLCBjb250ZW50ID0gdGV4dC5jb250ZW50LCBzdHlsZSA9IHRleHQuc3R5bGUsIG9mZnNldFggPSB0ZXh0Lm9mZnNldFgsIG9mZnNldFkgPSB0ZXh0Lm9mZnNldFksIGF1dG9Sb3RhdGUgPSB0ZXh0LmF1dG9Sb3RhdGUsIG1heExlbmd0aCA9IHRleHQubWF4TGVuZ3RoLCBhdXRvRWxsaXBzaXMgPSB0ZXh0LmF1dG9FbGxpcHNpcywgZWxsaXBzaXNQb3NpdGlvbiA9IHRleHQuZWxsaXBzaXNQb3NpdGlvbiwgYmFja2dyb3VuZCA9IHRleHQuYmFja2dyb3VuZCwgX2EgPSB0ZXh0LmlzVmVydGljYWwsIGlzVmVydGljYWwgPSBfYSA9PT0gdm9pZCAwID8gZmFsc2UgOiBfYTtcbiAgICAgICAgdmFyIHBvaW50ID0gdGhpcy5nZXRMYWJlbFBvaW50KHN0YXJ0LCBlbmQsIHBvc2l0aW9uKTtcbiAgICAgICAgdmFyIHggPSBwb2ludC54ICsgb2Zmc2V0WDtcbiAgICAgICAgdmFyIHkgPSBwb2ludC55ICsgb2Zmc2V0WTtcbiAgICAgICAgdmFyIGNmZyA9IHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbGluZS10ZXh0JyksXG4gICAgICAgICAgICBuYW1lOiAnYW5ub3RhdGlvbi1saW5lLXRleHQnLFxuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICBjb250ZW50OiBjb250ZW50LFxuICAgICAgICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgICAgICAgbWF4TGVuZ3RoOiBtYXhMZW5ndGgsXG4gICAgICAgICAgICBhdXRvRWxsaXBzaXM6IGF1dG9FbGxpcHNpcyxcbiAgICAgICAgICAgIGVsbGlwc2lzUG9zaXRpb246IGVsbGlwc2lzUG9zaXRpb24sXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBiYWNrZ3JvdW5kLFxuICAgICAgICAgICAgaXNWZXJ0aWNhbDogaXNWZXJ0aWNhbCxcbiAgICAgICAgfTtcbiAgICAgICAgLy8g5aaC5p6c6Ieq5Yqo5peL6L2sXG4gICAgICAgIGlmIChhdXRvUm90YXRlKSB7XG4gICAgICAgICAgICB2YXIgdmVjdG9yID0gW2VuZC54IC0gc3RhcnQueCwgZW5kLnkgLSBzdGFydC55XTtcbiAgICAgICAgICAgIGNmZy5yb3RhdGUgPSBNYXRoLmF0YW4yKHZlY3RvclsxXSwgdmVjdG9yWzBdKTtcbiAgICAgICAgfVxuICAgICAgICBncmFwaGljXzEucmVuZGVyVGFnKGdyb3VwLCBjZmcpO1xuICAgIH07XG4gICAgcmV0dXJuIExpbmVBbm5vdGF0aW9uO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMaW5lQW5ub3RhdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBncm91cF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9ncm91cC1jb21wb25lbnRcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBSZWdpb25GaWx0ZXJBbm5vdGF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJlZ2lvbkZpbHRlckFubm90YXRpb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmVnaW9uRmlsdGVyQW5ub3RhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDpu5jorqTnmoTphY3nva7poblcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSDpu5jorqTnmoTphY3nva7poblcbiAgICAgKi9cbiAgICBSZWdpb25GaWx0ZXJBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ2Fubm90YXRpb24nLCB0eXBlOiAncmVnaW9uRmlsdGVyJywgbG9jYXRpb25UeXBlOiAncmVnaW9uJywgc3RhcnQ6IG51bGwsIGVuZDogbnVsbCwgY29sb3I6IG51bGwsIHNoYXBlOiBbXSB9KTtcbiAgICB9O1xuICAgIFJlZ2lvbkZpbHRlckFubm90YXRpb24ucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuZ2V0KCdzdGFydCcpO1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5nZXQoJ2VuZCcpO1xuICAgICAgICAvLyAxLiBhZGQgcmVnaW9uIGxheWVyXG4gICAgICAgIHZhciBsYXllciA9IHRoaXMuYWRkR3JvdXAoZ3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgncmVnaW9uLWZpbHRlcicpLFxuICAgICAgICAgICAgY2FwdHVyZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyAyLiBjbG9uZSBzaGFwZSAmIGNvbG9yIGl0XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZ2V0KCdzaGFwZXMnKSwgZnVuY3Rpb24gKHNoYXBlLCBzaGFwZUlkeCkge1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBzaGFwZS5nZXQoJ3R5cGUnKTtcbiAgICAgICAgICAgIHZhciBhdHRycyA9IHV0aWxfMS5jbG9uZShzaGFwZS5hdHRyKCkpO1xuICAgICAgICAgICAgX3RoaXMuYWRqdXN0U2hhcGVBdHRycyhhdHRycyk7XG4gICAgICAgICAgICBfdGhpcy5hZGRTaGFwZShsYXllciwge1xuICAgICAgICAgICAgICAgIGlkOiBfdGhpcy5nZXRFbGVtZW50SWQoXCJzaGFwZS1cIiArIHR5cGUgKyBcIi1cIiArIHNoYXBlSWR4KSxcbiAgICAgICAgICAgICAgICBjYXB0dXJlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gMy4gY2xpcFxuICAgICAgICB2YXIgY2xpcEJCb3ggPSB1dGlsXzIucmVnaW9uVG9CQm94KHsgc3RhcnQ6IHN0YXJ0LCBlbmQ6IGVuZCB9KTtcbiAgICAgICAgbGF5ZXIuc2V0Q2xpcCh7XG4gICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHg6IGNsaXBCQm94Lm1pblgsXG4gICAgICAgICAgICAgICAgeTogY2xpcEJCb3gubWluWSxcbiAgICAgICAgICAgICAgICB3aWR0aDogY2xpcEJCb3gud2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBjbGlwQkJveC5oZWlnaHQsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFJlZ2lvbkZpbHRlckFubm90YXRpb24ucHJvdG90eXBlLmFkanVzdFNoYXBlQXR0cnMgPSBmdW5jdGlvbiAoYXR0cikge1xuICAgICAgICB2YXIgY29sb3IgPSB0aGlzLmdldCgnY29sb3InKTtcbiAgICAgICAgaWYgKGF0dHIuZmlsbCkge1xuICAgICAgICAgICAgYXR0ci5maWxsID0gYXR0ci5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICAgICAgfVxuICAgICAgICBhdHRyLnN0cm9rZSA9IGF0dHIuc3Ryb2tlU3R5bGUgPSBjb2xvcjtcbiAgICB9O1xuICAgIHJldHVybiBSZWdpb25GaWx0ZXJBbm5vdGF0aW9uO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSZWdpb25GaWx0ZXJBbm5vdGF0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVnaW9uLWZpbHRlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdyb3VwX2NvbXBvbmVudF8xID0gcmVxdWlyZShcIi4uL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvdGhlbWVcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBSZWdpb25Bbm5vdGF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJlZ2lvbkFubm90YXRpb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmVnaW9uQW5ub3RhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog6buY6K6k55qE6YWN572u6aG5XG4gICAgICogQHJldHVybnMge29iamVjdH0g6buY6K6k55qE6YWN572u6aG5XG4gICAgICovXG4gICAgUmVnaW9uQW5ub3RhdGlvbi5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IG5hbWU6ICdhbm5vdGF0aW9uJywgdHlwZTogJ3JlZ2lvbicsIGxvY2F0aW9uVHlwZTogJ3JlZ2lvbicsIHN0YXJ0OiBudWxsLCBlbmQ6IG51bGwsIHN0eWxlOiB7fSwgZGVmYXVsdENmZzoge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogdGhlbWVfMS5kZWZhdWx0LnJlZ2lvbkNvbG9yLFxuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0gfSk7XG4gICAgfTtcbiAgICBSZWdpb25Bbm5vdGF0aW9uLnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB0aGlzLnJlbmRlclJlZ2lvbihncm91cCk7XG4gICAgfTtcbiAgICBSZWdpb25Bbm5vdGF0aW9uLnByb3RvdHlwZS5yZW5kZXJSZWdpb24gPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5nZXQoJ3N0YXJ0Jyk7XG4gICAgICAgIHZhciBlbmQgPSB0aGlzLmdldCgnZW5kJyk7XG4gICAgICAgIHZhciBzdHlsZSA9IHRoaXMuZ2V0KCdzdHlsZScpO1xuICAgICAgICB2YXIgYmJveCA9IHV0aWxfMS5yZWdpb25Ub0JCb3goeyBzdGFydDogc3RhcnQsIGVuZDogZW5kIH0pO1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3JlZ2lvbicpLFxuICAgICAgICAgICAgbmFtZTogJ2Fubm90YXRpb24tcmVnaW9uJyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogYmJveC54LCB5OiBiYm94LnksIHdpZHRoOiBiYm94LndpZHRoLCBoZWlnaHQ6IGJib3guaGVpZ2h0IH0sIHN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gUmVnaW9uQW5ub3RhdGlvbjtcbn0oZ3JvdXBfY29tcG9uZW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmVnaW9uQW5ub3RhdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlZ2lvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdyb3VwX2NvbXBvbmVudF8xID0gcmVxdWlyZShcIi4uL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbnZhciBncmFwaGljXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9ncmFwaGljXCIpO1xudmFyIG1hdHJpeF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0cml4XCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciBUZXh0QW5ub3RhdGlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUZXh0QW5ub3RhdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUZXh0QW5ub3RhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog6buY6K6k55qE6YWN572u6aG5XG4gICAgICogQHJldHVybnMge29iamVjdH0g6buY6K6k55qE6YWN572u6aG5XG4gICAgICovXG4gICAgVGV4dEFubm90YXRpb24ucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBuYW1lOiAnYW5ub3RhdGlvbicsIHR5cGU6ICd0ZXh0JywgbG9jYXRpb25UeXBlOiAncG9pbnQnLCB4OiAwLCB5OiAwLCBjb250ZW50OiAnJywgcm90YXRlOiBudWxsLCBzdHlsZToge30sIGJhY2tncm91bmQ6IG51bGwsIG1heExlbmd0aDogbnVsbCwgYXV0b0VsbGlwc2lzOiB0cnVlLCBpc1ZlcnRpY2FsOiBmYWxzZSwgZWxsaXBzaXNQb3NpdGlvbjogJ3RhaWwnLCBkZWZhdWx0Q2ZnOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogdGhlbWVfMS5kZWZhdWx0LnRleHRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiB0aGVtZV8xLmRlZmF1bHQuZm9udEZhbWlseSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSB9KTtcbiAgICB9O1xuICAgIC8vIOWkjeWGmSBzZXRMb2NhdGlvbiDmlrnms5XvvIzkuI3pnIDopoHph43mlrDliJvlu7ogdGV4dFxuICAgIFRleHRBbm5vdGF0aW9uLnByb3RvdHlwZS5zZXRMb2NhdGlvbiA9IGZ1bmN0aW9uIChsb2NhdGlvbikge1xuICAgICAgICB0aGlzLnNldCgneCcsIGxvY2F0aW9uLngpO1xuICAgICAgICB0aGlzLnNldCgneScsIGxvY2F0aW9uLnkpO1xuICAgICAgICB0aGlzLnJlc2V0TG9jYXRpb24oKTtcbiAgICB9O1xuICAgIFRleHRBbm5vdGF0aW9uLnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldExvY2F0aW9uKCksIHggPSBfYS54LCB5ID0gX2EueTtcbiAgICAgICAgdmFyIGNvbnRlbnQgPSB0aGlzLmdldCgnY29udGVudCcpO1xuICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLmdldCgnc3R5bGUnKTtcbiAgICAgICAgdmFyIGlkID0gdGhpcy5nZXRFbGVtZW50SWQoJ3RleHQnKTtcbiAgICAgICAgdmFyIG5hbWUgPSB0aGlzLmdldCgnbmFtZScpICsgXCItdGV4dFwiO1xuICAgICAgICB2YXIgbWF4TGVuZ3RoID0gdGhpcy5nZXQoJ21heExlbmd0aCcpO1xuICAgICAgICB2YXIgYXV0b0VsbGlwc2lzID0gdGhpcy5nZXQoJ2F1dG9FbGxpcHNpcycpO1xuICAgICAgICB2YXIgaXNWZXJ0aWNhbCA9IHRoaXMuZ2V0KCdpc1ZlcnRpY2FsJyk7XG4gICAgICAgIHZhciBlbGxpcHNpc1Bvc2l0aW9uID0gdGhpcy5nZXQoJ2VsbGlwc2lzUG9zaXRpb24nKTtcbiAgICAgICAgdmFyIGJhY2tncm91bmQgPSB0aGlzLmdldCgnYmFja2dyb3VuZCcpO1xuICAgICAgICB2YXIgcm90YXRlID0gdGhpcy5nZXQoJ3JvdGF0ZScpO1xuICAgICAgICB2YXIgY2ZnID0ge1xuICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgY29udGVudDogY29udGVudCxcbiAgICAgICAgICAgIHN0eWxlOiBzdHlsZSxcbiAgICAgICAgICAgIG1heExlbmd0aDogbWF4TGVuZ3RoLFxuICAgICAgICAgICAgYXV0b0VsbGlwc2lzOiBhdXRvRWxsaXBzaXMsXG4gICAgICAgICAgICBpc1ZlcnRpY2FsOiBpc1ZlcnRpY2FsLFxuICAgICAgICAgICAgZWxsaXBzaXNQb3NpdGlvbjogZWxsaXBzaXNQb3NpdGlvbixcbiAgICAgICAgICAgIGJhY2tncm91bmQ6IGJhY2tncm91bmQsXG4gICAgICAgICAgICByb3RhdGU6IHJvdGF0ZSxcbiAgICAgICAgfTtcbiAgICAgICAgZ3JhcGhpY18xLnJlbmRlclRhZyhncm91cCwgY2ZnKTtcbiAgICB9O1xuICAgIFRleHRBbm5vdGF0aW9uLnByb3RvdHlwZS5yZXNldExvY2F0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGV4dEdyb3VwID0gdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCd0ZXh0LWdyb3VwJyk7XG4gICAgICAgIGlmICh0ZXh0R3JvdXApIHtcbiAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0TG9jYXRpb24oKSwgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgICAgICAgICAgdmFyIHJvdGF0ZSA9IHRoaXMuZ2V0KCdyb3RhdGUnKTtcbiAgICAgICAgICAgIG1hdHJpeF8xLmFwcGx5VHJhbnNsYXRlKHRleHRHcm91cCwgeCwgeSk7XG4gICAgICAgICAgICBtYXRyaXhfMS5hcHBseVJvdGF0ZSh0ZXh0R3JvdXAsIHJvdGF0ZSwgeCwgeSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBUZXh0QW5ub3RhdGlvbjtcbn0oZ3JvdXBfY29tcG9uZW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGV4dEFubm90YXRpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXh0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbWF0cml4X3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9tYXRyaXgtdXRpbFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBncm91cF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9ncm91cC1jb21wb25lbnRcIik7XG52YXIgbWF0cml4XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9tYXRyaXhcIik7XG52YXIgc3RhdGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3N0YXRlXCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciBBeGlzQmFzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhBeGlzQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBeGlzQmFzZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IG5hbWU6ICdheGlzJywgdGlja3M6IFtdLCBsaW5lOiB7fSwgdGlja0xpbmU6IHt9LCBzdWJUaWNrTGluZTogbnVsbCwgdGl0bGU6IG51bGwsIFxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDmlofmnKzmoIfnrb7nmoTphY3nva7poblcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgbGFiZWw6IHt9LCBcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICog5Z6C55u05LqO5Z2Q5qCH6L205pa55ZCR55qE5Zug5a2Q77yM5Yaz5a6a5paH5pys44CBdGl0bGXjgIF0aWNrTGluZSDlnKjlnZDmoIfovbTnmoTlk6rkuIDkvqdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdmVydGljYWxGYWN0b3I6IDEsIFxuICAgICAgICAgICAgLy8g5Z6C55u05pa55ZCR6ZmQ5Yi255qE6ZW/5bqm77yM5a+55paH5pys6Ieq6YCC5bqU5pyJ5b6I5aSn5b2x5ZONXG4gICAgICAgICAgICB2ZXJ0aWNhbExpbWl0TGVuZ3RoOiBudWxsLCBvdmVybGFwT3JkZXI6IFsnYXV0b1JvdGF0ZScsICdhdXRvRWxsaXBzaXMnLCAnYXV0b0hpZGUnXSwgdGlja1N0YXRlczoge30sIGRlZmF1bHRDZmc6IHtcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0eXBlIHtBdHRyc30g5Z2Q5qCH6L2057q/55qE5Zu+5b2i5bGe5oCnLOWmguaenOiuvue9ruaIkG51bGzvvIzliJnkuI3mmL7npLrovbTnur9cbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogdGhlbWVfMS5kZWZhdWx0LmxpbmVDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0eXBlIHtBdHRyc30g5qCH5rOo5Z2Q5qCH57q/55qE5Zu+5b2i5bGe5oCnXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoZW1lXzEuZGVmYXVsdC5saW5lQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFsaWduVGljazogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiA1LFxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5V2l0aExhYmVsOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3ViVGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHR5cGUge0F0dHJzfSDmoIfms6jlnZDmoIfnur/nmoTlm77lvaLlsZ7mgKdcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogdGhlbWVfMS5kZWZhdWx0LmxpbmVDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgY291bnQ6IDQsXG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aDogMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9IaWRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0VsbGlwc2lzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHRoZW1lXzEuZGVmYXVsdC50ZXh0Q29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogdGhlbWVfMS5kZWZhdWx0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiAnbm9ybWFsJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiAxMCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHRoZW1lXzEuZGVmYXVsdC50ZXh0Q29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogdGhlbWVfMS5kZWZhdWx0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja1N0YXRlczoge1xuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsU3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiA1MDAsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGlja0xpbmVTdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogdGhlbWVfMS5kZWZhdWx0LnVuY2hlY2tlZENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe7mOWItue7hOS7tlxuICAgICAqL1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICBpZiAodGhpcy5nZXQoJ2xpbmUnKSkge1xuICAgICAgICAgICAgdGhpcy5kcmF3TGluZShncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZHJhd1RpY2tzIOWMheaLrCBkcmF3TGFiZWxzIOWSjCBkcmF3VGlja0xpbmVzXG4gICAgICAgIHRoaXMuZHJhd1RpY2tzKGdyb3VwKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCd0aXRsZScpKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdUaXRsZShncm91cCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOWunueOsCBJTGlzdCDmjqXlj6NcbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuaXNMaXN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluWbvuS+i+mhuVxuICAgICAqIEByZXR1cm4ge0xpc3RJdGVtW119IOWIl+ihqOmhuembhuWQiFxuICAgICAqL1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5nZXRJdGVtcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCd0aWNrcycpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572u5YiX6KGo6aG5XG4gICAgICogQHBhcmFtIHtMaXN0SXRlbVtdfSBpdGVtcyDliJfooajpobnpm4blkIhcbiAgICAgKi9cbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuc2V0SXRlbXMgPSBmdW5jdGlvbiAoaXRlbXMpIHtcbiAgICAgICAgdGhpcy51cGRhdGUoe1xuICAgICAgICAgICAgdGlja3M6IGl0ZW1zLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOabtOaWsOWIl+ihqOmhuVxuICAgICAqIEBwYXJhbSB7TGlzdEl0ZW19IGl0ZW0g5YiX6KGo6aG5XG4gICAgICogQHBhcmFtIHtvYmplY3R9ICAgY2ZnICDliJfooajpoblcbiAgICAgKi9cbiAgICBBeGlzQmFzZS5wcm90b3R5cGUudXBkYXRlSXRlbSA9IGZ1bmN0aW9uIChpdGVtLCBjZmcpIHtcbiAgICAgICAgdXRpbF8xLm1peChpdGVtLCBjZmcpO1xuICAgICAgICB0aGlzLmNsZWFyKCk7IC8vIOeUseS6juWNleS4quWbvuS+i+mhueWPmOWMlu+8jOS8muW8lei1t+WFqOWxgOWPmOWMlu+8jOaJgOS7peWFqOmDqOabtOaWsFxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF56m65YiX6KGoXG4gICAgICovXG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmNsZWFySXRlbXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpdGVtR3JvdXAgPSB0aGlzLmdldEVsZW1lbnRCeUxvY2FsSWQoJ2xhYmVsLWdyb3VwJyk7XG4gICAgICAgIGl0ZW1Hcm91cCAmJiBpdGVtR3JvdXAuY2xlYXIoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiuvue9ruWIl+ihqOmhueeahOeKtuaAgVxuICAgICAqIEBwYXJhbSB7TGlzdEl0ZW19IGl0ZW0gIOWIl+ihqOmhuVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSAgIHN0YXRlIOeKtuaAgeWQjVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gIHZhbHVlIOeKtuaAgeWAvCwgdHJ1ZSwgZmFsc2VcbiAgICAgKi9cbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuc2V0SXRlbVN0YXRlID0gZnVuY3Rpb24gKGl0ZW0sIHN0YXRlLCB2YWx1ZSkge1xuICAgICAgICBpdGVtW3N0YXRlXSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnVwZGF0ZVRpY2tTdGF0ZXMoaXRlbSk7IC8vIOW6lOeUqOeKtuaAgeagt+W8j1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm5a2Y5Zyo5oyH5a6a55qE54q25oCBXG4gICAgICogQHBhcmFtIHtMaXN0SXRlbX0gaXRlbSAg5YiX6KGo6aG5XG4gICAgICogQHBhcmFtIHtib29sZWFufSBzdGF0ZSDnirbmgIHlkI1cbiAgICAgKi9cbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuaGFzU3RhdGUgPSBmdW5jdGlvbiAoaXRlbSwgc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuICEhaXRlbVtzdGF0ZV07XG4gICAgfTtcbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuZ2V0SXRlbVN0YXRlcyA9IGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHZhciB0aWNrU3RhdGVzID0gdGhpcy5nZXQoJ3RpY2tTdGF0ZXMnKTtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aWNrU3RhdGVzLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgaWYgKGl0ZW1ba10pIHtcbiAgICAgICAgICAgICAgICAvLyBpdGVtLnNlbGVjdGVkXG4gICAgICAgICAgICAgICAgcnN0LnB1c2goayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF5qWa5omA5pyJ5YiX6KGo6aG555qE54q25oCBXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlIOeKtuaAgeWAvFxuICAgICAqL1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5jbGVhckl0ZW1zU3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5nZXRJdGVtc0J5U3RhdGUoc3RhdGUpO1xuICAgICAgICB1dGlsXzEuZWFjaChpdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIF90aGlzLnNldEl0ZW1TdGF0ZShpdGVtLCBzdGF0ZSwgZmFsc2UpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNrueKtuaAgeiOt+WPluWbvuS+i+mhuVxuICAgICAqIEBwYXJhbSAge3N0cmluZ30gICAgIHN0YXRlIFtkZXNjcmlwdGlvbl1cbiAgICAgKiBAcmV0dXJuIHtMaXN0SXRlbVtdfSAgICAgICBbZGVzY3JpcHRpb25dXG4gICAgICovXG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmdldEl0ZW1zQnlTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLmdldEl0ZW1zKCk7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmlsdGVyKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmhhc1N0YXRlKGl0ZW0sIHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuZ2V0U2lkZVBvaW50ID0gZnVuY3Rpb24gKHBvaW50LCBvZmZzZXQpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgdmVjdG9yID0gc2VsZi5nZXRTaWRlVmVjdG9yKG9mZnNldCwgcG9pbnQpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogcG9pbnQueCArIHZlY3RvclswXSxcbiAgICAgICAgICAgIHk6IHBvaW50LnkgKyB2ZWN0b3JbMV0sXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuZ2V0VGV4dEFuY2hvciA9IGZ1bmN0aW9uICh2ZWN0b3IpIHtcbiAgICAgICAgdmFyIGFsaWduO1xuICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyRXF1YWwodmVjdG9yWzBdLCAwKSkge1xuICAgICAgICAgICAgYWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh2ZWN0b3JbMF0gPiAwKSB7XG4gICAgICAgICAgICBhbGlnbiA9ICdzdGFydCc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodmVjdG9yWzBdIDwgMCkge1xuICAgICAgICAgICAgYWxpZ24gPSAnZW5kJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWxpZ247XG4gICAgfTtcbiAgICBBeGlzQmFzZS5wcm90b3R5cGUucHJvY2Vzc092ZXJsYXAgPSBmdW5jdGlvbiAobGFiZWxHcm91cCkgeyB9O1xuICAgIC8vIOe7mOWItuWdkOagh+i9tOe6v1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5kcmF3TGluZSA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgcGF0aCA9IHRoaXMuZ2V0TGluZVBhdGgoKTtcbiAgICAgICAgdmFyIGxpbmUgPSB0aGlzLmdldCgnbGluZScpOyAvLyBsaW5lIOeahOWIpOepuuWcqOiwg+eUqCBkcmF3TGluZSDkuYvliY3vvIzkuI3lnKjov5nph4zliKTlrppcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdsaW5lJyksXG4gICAgICAgICAgICBuYW1lOiAnYXhpcy1saW5lJyxcbiAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEubWl4KHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgfSwgbGluZS5zdHlsZSksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmdldFRpY2tMaW5lSXRlbXMgPSBmdW5jdGlvbiAodGlja3MpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHRpY2tMaW5lSXRlbXMgPSBbXTtcbiAgICAgICAgdmFyIHRpY2tMaW5lID0gdGhpcy5nZXQoJ3RpY2tMaW5lJyk7XG4gICAgICAgIHZhciBhbGlnblRpY2sgPSB0aWNrTGluZS5hbGlnblRpY2s7XG4gICAgICAgIHZhciB0aWNrTGluZUxlbmd0aCA9IHRpY2tMaW5lLmxlbmd0aDtcbiAgICAgICAgdmFyIHRpY2tTZWdtZW50ID0gMTtcbiAgICAgICAgdmFyIHRpY2tDb3VudCA9IHRpY2tzLmxlbmd0aDtcbiAgICAgICAgaWYgKHRpY2tDb3VudCA+PSAyKSB7XG4gICAgICAgICAgICB0aWNrU2VnbWVudCA9IHRpY2tzWzFdLnZhbHVlIC0gdGlja3NbMF0udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLmVhY2godGlja3MsIGZ1bmN0aW9uICh0aWNrKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSB0aWNrLnBvaW50O1xuICAgICAgICAgICAgaWYgKCFhbGlnblRpY2spIHtcbiAgICAgICAgICAgICAgICAvLyB0aWNrTGluZSDkuI3lkIwgdGljayDlr7npvZDml7bpnIDopoHosIPmlbQgcG9pbnRcbiAgICAgICAgICAgICAgICBwb2ludCA9IF90aGlzLmdldFRpY2tQb2ludCh0aWNrLnZhbHVlIC0gdGlja1NlZ21lbnQgLyAyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBlbmRQb2ludCA9IF90aGlzLmdldFNpZGVQb2ludChwb2ludCwgdGlja0xpbmVMZW5ndGgpO1xuICAgICAgICAgICAgdGlja0xpbmVJdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBzdGFydFBvaW50OiBwb2ludCxcbiAgICAgICAgICAgICAgICB0aWNrVmFsdWU6IHRpY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgZW5kUG9pbnQ6IGVuZFBvaW50LFxuICAgICAgICAgICAgICAgIHRpY2tJZDogdGljay5pZCxcbiAgICAgICAgICAgICAgICBpZDogXCJ0aWNrbGluZS1cIiArIHRpY2suaWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOWmguaenCB0aWNrTGluZSDkuI3lsYXkuK3lr7npvZDvvIzliJnpnIDopoHlnKjmnIDlkI7pnaLooaXlhYXkuIDkuKogdGlja0xpbmVcbiAgICAgICAgLy8gaWYgKCFhbGlnblRpY2sgJiYgdGlja0NvdW50ID4gMCkge1xuICAgICAgICAvLyAgIGNvbnN0IHRpY2sgPSB0aWNrc1t0aWNrQ291bnQgLSAxXTtcbiAgICAgICAgLy8gICBjb25zdCBwb2ludCA9IHRoaXMuZ2V0VGlja1BvaW50KHRpY2sudmFsdWUgKyB0aWNrU2VnbWVudCAvIDIpO1xuICAgICAgICAvLyB9XG4gICAgICAgIHJldHVybiB0aWNrTGluZUl0ZW1zO1xuICAgIH07XG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmdldFN1YlRpY2tMaW5lSXRlbXMgPSBmdW5jdGlvbiAodGlja0xpbmVJdGVtcykge1xuICAgICAgICB2YXIgc3ViVGlja0xpbmVJdGVtcyA9IFtdO1xuICAgICAgICB2YXIgc3ViVGlja0xpbmUgPSB0aGlzLmdldCgnc3ViVGlja0xpbmUnKTtcbiAgICAgICAgdmFyIHN1YkNvdW50ID0gc3ViVGlja0xpbmUuY291bnQ7XG4gICAgICAgIHZhciB0aWNrTGluZUNvdW50ID0gdGlja0xpbmVJdGVtcy5sZW5ndGg7XG4gICAgICAgIC8vIOWIu+W6pue6v+eahOaVsOmHj+Wkp+S6jiAyIOaXtu+8jOaJjee7mOWItuWtkOWIu+W6plxuICAgICAgICBpZiAodGlja0xpbmVDb3VudCA+PSAyKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRpY2tMaW5lQ291bnQgLSAxOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJlID0gdGlja0xpbmVJdGVtc1tpXTtcbiAgICAgICAgICAgICAgICB2YXIgbmV4dCA9IHRpY2tMaW5lSXRlbXNbaSArIDFdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3ViQ291bnQ7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGVyY2VudCA9IChqICsgMSkgLyAoc3ViQ291bnQgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRpY2tWYWx1ZSA9ICgxIC0gcGVyY2VudCkgKiBwcmUudGlja1ZhbHVlICsgcGVyY2VudCAqIG5leHQudGlja1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcG9pbnQgPSB0aGlzLmdldFRpY2tQb2ludCh0aWNrVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZW5kUG9pbnQgPSB0aGlzLmdldFNpZGVQb2ludChwb2ludCwgc3ViVGlja0xpbmUubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgc3ViVGlja0xpbmVJdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UG9pbnQ6IHBvaW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgZW5kUG9pbnQ6IGVuZFBvaW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGlja1ZhbHVlOiB0aWNrVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogXCJzdWItXCIgKyBwcmUuaWQgKyBcIi1cIiArIGosXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3ViVGlja0xpbmVJdGVtcztcbiAgICB9O1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5nZXRUaWNrTGluZUF0dHJzID0gZnVuY3Rpb24gKHRpY2tJdGVtLCB0eXBlKSB7XG4gICAgICAgIHZhciB0aWNrTGluZVN0eWxlID0gdGhpcy5nZXQodHlwZSkuc3R5bGU7XG4gICAgICAgIHZhciBzdGFydFBvaW50ID0gdGlja0l0ZW0uc3RhcnRQb2ludCwgZW5kUG9pbnQgPSB0aWNrSXRlbS5lbmRQb2ludDtcbiAgICAgICAgdmFyIGF0dHJzID0gdXRpbF8xLm1peCh7XG4gICAgICAgICAgICB4MTogc3RhcnRQb2ludC54LFxuICAgICAgICAgICAgeTE6IHN0YXJ0UG9pbnQueSxcbiAgICAgICAgICAgIHgyOiBlbmRQb2ludC54LFxuICAgICAgICAgICAgeTI6IGVuZFBvaW50LnksXG4gICAgICAgIH0sIHRpY2tMaW5lU3R5bGUpO1xuICAgICAgICByZXR1cm4gYXR0cnM7XG4gICAgfTtcbiAgICAvLyDnu5jliLblnZDmoIfovbTliLvluqbnur9cbiAgICBBeGlzQmFzZS5wcm90b3R5cGUuZHJhd1RpY2sgPSBmdW5jdGlvbiAodGlja0l0ZW0sIHRpY2tMaW5lR3JvdXAsIHR5cGUpIHtcbiAgICAgICAgdGhpcy5hZGRTaGFwZSh0aWNrTGluZUdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQodGlja0l0ZW0uaWQpLFxuICAgICAgICAgICAgbmFtZTogXCJheGlzLVwiICsgdHlwZSxcbiAgICAgICAgICAgIGF0dHJzOiB0aGlzLmdldFRpY2tMaW5lQXR0cnModGlja0l0ZW0sIHR5cGUpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOe7mOWItuWdkOagh+i9tOWIu+W6pue6v++8jOWMheaLrOWtkOWIu+W6pue6v1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5kcmF3VGlja0xpbmVzID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMuZ2V0KCd0aWNrcycpO1xuICAgICAgICB2YXIgc3ViVGlja0xpbmUgPSB0aGlzLmdldCgnc3ViVGlja0xpbmUnKTtcbiAgICAgICAgdmFyIHRpY2tMaW5lSXRlbXMgPSB0aGlzLmdldFRpY2tMaW5lSXRlbXModGlja3MpO1xuICAgICAgICB2YXIgdGlja0xpbmVHcm91cCA9IHRoaXMuYWRkR3JvdXAoZ3JvdXAsIHtcbiAgICAgICAgICAgIG5hbWU6ICdheGlzLXRpY2tsaW5lLWdyb3VwJyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgndGlja2xpbmUtZ3JvdXAnKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB0aWNrQ2ZnID0gdGhpcy5nZXQoJ3RpY2tMaW5lJyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRpY2tMaW5lSXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBpZiAodGlja0NmZy5kaXNwbGF5V2l0aExhYmVsKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c6Lef6ZqPIGxhYmVsIOaYvuekuu+8jOWImeajgOa1i+aYr+WQpuWtmOWcqOWvueW6lOeahCBsYWJlbFxuICAgICAgICAgICAgICAgIHZhciBsYWJlbElkID0gX3RoaXMuZ2V0RWxlbWVudElkKFwibGFiZWwtXCIgKyBpdGVtLnRpY2tJZCk7XG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwLmZpbmRCeUlkKGxhYmVsSWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmRyYXdUaWNrKGl0ZW0sIHRpY2tMaW5lR3JvdXAsICd0aWNrTGluZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIF90aGlzLmRyYXdUaWNrKGl0ZW0sIHRpY2tMaW5lR3JvdXAsICd0aWNrTGluZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHN1YlRpY2tMaW5lKSB7XG4gICAgICAgICAgICB2YXIgc3ViVGlja0xpbmVJdGVtcyA9IHRoaXMuZ2V0U3ViVGlja0xpbmVJdGVtcyh0aWNrTGluZUl0ZW1zKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHN1YlRpY2tMaW5lSXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuZHJhd1RpY2soaXRlbSwgdGlja0xpbmVHcm91cCwgJ3N1YlRpY2tMaW5lJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g6aKE5aSE55CGIHRpY2tzIOehruWumuS9jee9ruWSjOihpeWFhSBpZFxuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5wcm9jZXNzVGlja3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMuZ2V0KCd0aWNrcycpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aWNrcywgZnVuY3Rpb24gKHRpY2spIHtcbiAgICAgICAgICAgIHRpY2sucG9pbnQgPSBfdGhpcy5nZXRUaWNrUG9pbnQodGljay52YWx1ZSk7XG4gICAgICAgICAgICAvLyDooaXlhYUgdGljayDnmoQgaWTvvIzkuLrliqjnlLvlkozmm7TmlrDlgZrlh4blpIdcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNOaWwodGljay5pZCkpIHtcbiAgICAgICAgICAgICAgICAvLyDpu5jorqTkvb/nlKggdGljay5uYW1lIOS9nOS4umlkXG4gICAgICAgICAgICAgICAgdGljay5pZCA9IHRpY2submFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLYgdGlja3Mg5YyF5ous5paH5pys5ZKMIHRpY2tMaW5lXG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmRyYXdUaWNrcyA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLnByb2Nlc3NUaWNrcygpO1xuICAgICAgICBpZiAodGhpcy5nZXQoJ2xhYmVsJykpIHtcbiAgICAgICAgICAgIHRoaXMuZHJhd0xhYmVscyhncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZ2V0KCd0aWNrTGluZScpKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdUaWNrTGluZXMoZ3JvdXApO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMuZ2V0KCd0aWNrcycpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aWNrcywgZnVuY3Rpb24gKHRpY2spIHtcbiAgICAgICAgICAgIF90aGlzLmFwcGx5VGlja1N0YXRlcyh0aWNrLCBncm91cCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g6I635Y+WIGxhYmVsIOeahOmFjee9rumhuVxuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5nZXRMYWJlbEF0dHJzID0gZnVuY3Rpb24gKHRpY2ssIGluZGV4KSB7XG4gICAgICAgIHZhciBsYWJlbENmZyA9IHRoaXMuZ2V0KCdsYWJlbCcpO1xuICAgICAgICB2YXIgb2Zmc2V0ID0gbGFiZWxDZmcub2Zmc2V0LCBzdHlsZSA9IGxhYmVsQ2ZnLnN0eWxlLCByb3RhdGUgPSBsYWJlbENmZy5yb3RhdGUsIGZvcm1hdHRlciA9IGxhYmVsQ2ZnLmZvcm1hdHRlcjtcbiAgICAgICAgdmFyIHBvaW50ID0gdGhpcy5nZXRTaWRlUG9pbnQodGljay5wb2ludCwgb2Zmc2V0KTtcbiAgICAgICAgdmFyIHZlY3RvciA9IHRoaXMuZ2V0U2lkZVZlY3RvcihvZmZzZXQsIHBvaW50KTtcbiAgICAgICAgdmFyIHRleHQgPSBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIodGljay5uYW1lLCB0aWNrLCBpbmRleCkgOiB0aWNrLm5hbWU7XG4gICAgICAgIHZhciBhdHRycyA9IHV0aWxfMS5taXgoe1xuICAgICAgICAgICAgeDogcG9pbnQueCxcbiAgICAgICAgICAgIHk6IHBvaW50LnksXG4gICAgICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICAgICAgdGV4dEFsaWduOiB0aGlzLmdldFRleHRBbmNob3IodmVjdG9yKSxcbiAgICAgICAgfSwgc3R5bGUpO1xuICAgICAgICBpZiAocm90YXRlKSB7XG4gICAgICAgICAgICBhdHRycy5tYXRyaXggPSBtYXRyaXhfMS5nZXRNYXRyaXhCeUFuZ2xlKHBvaW50LCByb3RhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhdHRycztcbiAgICB9O1xuICAgIC8vIOe7mOWItuaWh+acrFxuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5kcmF3TGFiZWxzID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMuZ2V0KCd0aWNrcycpO1xuICAgICAgICB2YXIgbGFiZWxHcm91cCA9IHRoaXMuYWRkR3JvdXAoZ3JvdXAsIHtcbiAgICAgICAgICAgIG5hbWU6ICdheGlzLWxhYmVsLWdyb3VwJyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbGFiZWwtZ3JvdXAnKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRpY2tzLCBmdW5jdGlvbiAodGljaywgaW5kZXgpIHtcbiAgICAgICAgICAgIF90aGlzLmFkZFNoYXBlKGxhYmVsR3JvdXAsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ2F4aXMtbGFiZWwnLFxuICAgICAgICAgICAgICAgIGlkOiBfdGhpcy5nZXRFbGVtZW50SWQoXCJsYWJlbC1cIiArIHRpY2suaWQpLFxuICAgICAgICAgICAgICAgIGF0dHJzOiBfdGhpcy5nZXRMYWJlbEF0dHJzKHRpY2ssIGluZGV4KSxcbiAgICAgICAgICAgICAgICBkZWxlZ2F0ZU9iamVjdDoge1xuICAgICAgICAgICAgICAgICAgICB0aWNrOiB0aWNrLFxuICAgICAgICAgICAgICAgICAgICBpdGVtOiB0aWNrLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wcm9jZXNzT3ZlcmxhcChsYWJlbEdyb3VwKTtcbiAgICB9O1xuICAgIC8vIOagh+mimOeahOWxnuaAp1xuICAgIEF4aXNCYXNlLnByb3RvdHlwZS5nZXRUaXRsZUF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGl0bGVDZmcgPSB0aGlzLmdldCgndGl0bGUnKTtcbiAgICAgICAgdmFyIHN0eWxlID0gdGl0bGVDZmcuc3R5bGUsIHBvc2l0aW9uID0gdGl0bGVDZmcucG9zaXRpb24sIG9mZnNldCA9IHRpdGxlQ2ZnLm9mZnNldCwgX2EgPSB0aXRsZUNmZy5zcGFjaW5nLCBzcGFjaW5nID0gX2EgPT09IHZvaWQgMCA/IDAgOiBfYSwgYXV0b1JvdGF0ZSA9IHRpdGxlQ2ZnLmF1dG9Sb3RhdGU7XG4gICAgICAgIHZhciB0aXRsZUhlaWdodCA9IHN0eWxlLmZvbnRTaXplO1xuICAgICAgICB2YXIgcGVyY2VudCA9IDAuNTtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnc3RhcnQnKSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2VuZCcpIHtcbiAgICAgICAgICAgIHBlcmNlbnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwb2ludCA9IHRoaXMuZ2V0VGlja1BvaW50KHBlcmNlbnQpOyAvLyDmoIfpopjlr7nlupTnmoTlnZDmoIfovbTkuIrnmoTngrlcbiAgICAgICAgLy8g5aaC5p6c5rKh5pyJ5oyH5a6aIHRpdGxlT2Zmc2V0IOS5n+ayoeaciea4suafkyBsYWJlbO+8jOi/memHjOmcgOimgeiHquWKqOiuoeeulyBvZmZzZXRcbiAgICAgICAgdmFyIHRpdGxlUG9pbnQgPSB0aGlzLmdldFNpZGVQb2ludChwb2ludCwgb2Zmc2V0IHx8IHNwYWNpbmcgKyB0aXRsZUhlaWdodCAvIDIpOyAvLyDmoIfpopjnmoTngrlcbiAgICAgICAgdmFyIGF0dHJzID0gdXRpbF8xLm1peCh7XG4gICAgICAgICAgICB4OiB0aXRsZVBvaW50LngsXG4gICAgICAgICAgICB5OiB0aXRsZVBvaW50LnksXG4gICAgICAgICAgICB0ZXh0OiB0aXRsZUNmZy50ZXh0LFxuICAgICAgICB9LCBzdHlsZSk7XG4gICAgICAgIHZhciByb3RhdGUgPSB0aXRsZUNmZy5yb3RhdGU7IC8vIHJvdGF0ZSDmmK/op5LluqblgLxcbiAgICAgICAgdmFyIGFuZ2xlID0gcm90YXRlO1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKHJvdGF0ZSkgJiYgYXV0b1JvdGF0ZSkge1xuICAgICAgICAgICAgLy8g55So5oi35rKh5pyJ6K6+5a6a5peL6L2s6KeS5bqm77yM5ZCM5pe26K6+572u6Ieq5Yqo5peL6L2sXG4gICAgICAgICAgICB2YXIgdmVjdG9yID0gdGhpcy5nZXRBeGlzVmVjdG9yKHBvaW50KTtcbiAgICAgICAgICAgIHZhciB2MSA9IFsxLCAwXTsgLy8g5rC05bmz5pa55ZCR55qE5ZCR6YePXG4gICAgICAgICAgICBhbmdsZSA9IG1hdHJpeF91dGlsXzEuZXh0LmFuZ2xlVG8odmVjdG9yLCB2MSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFuZ2xlKSB7XG4gICAgICAgICAgICB2YXIgbWF0cml4ID0gbWF0cml4XzEuZ2V0TWF0cml4QnlBbmdsZSh0aXRsZVBvaW50LCBhbmdsZSk7XG4gICAgICAgICAgICBhdHRycy5tYXRyaXggPSBtYXRyaXg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF0dHJzO1xuICAgIH07XG4gICAgLy8g57uY5Yi25qCH6aKYXG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmRyYXdUaXRsZSA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3RpdGxlJyksXG4gICAgICAgICAgICBuYW1lOiAnYXhpcy10aXRsZScsXG4gICAgICAgICAgICBhdHRyczogdGhpcy5nZXRUaXRsZUF0dHJzKCksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLmFwcGx5VGlja1N0YXRlcyA9IGZ1bmN0aW9uICh0aWNrLCBncm91cCkge1xuICAgICAgICB2YXIgc3RhdGVzID0gdGhpcy5nZXRJdGVtU3RhdGVzKHRpY2spO1xuICAgICAgICBpZiAoc3RhdGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIHRpY2tTdGF0ZXMgPSB0aGlzLmdldCgndGlja1N0YXRlcycpO1xuICAgICAgICAgICAgLy8g5YiG5Yir5pu05pawIGxhYmVsIOWSjCB0aWNrTGluZVxuICAgICAgICAgICAgdmFyIGxhYmVsSWQgPSB0aGlzLmdldEVsZW1lbnRJZChcImxhYmVsLVwiICsgdGljay5pZCk7XG4gICAgICAgICAgICB2YXIgbGFiZWxTaGFwZSA9IGdyb3VwLmZpbmRCeUlkKGxhYmVsSWQpO1xuICAgICAgICAgICAgaWYgKGxhYmVsU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWxTdGF0ZVN0eWxlID0gc3RhdGVfMS5nZXRTdGF0ZXNTdHlsZSh0aWNrLCAnbGFiZWwnLCB0aWNrU3RhdGVzKTtcbiAgICAgICAgICAgICAgICBsYWJlbFN0YXRlU3R5bGUgJiYgbGFiZWxTaGFwZS5hdHRyKGxhYmVsU3RhdGVTdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdGlja0xpbmVJZCA9IHRoaXMuZ2V0RWxlbWVudElkKFwidGlja2xpbmUtXCIgKyB0aWNrLmlkKTtcbiAgICAgICAgICAgIHZhciB0aWNrTGluZVNoYXBlID0gZ3JvdXAuZmluZEJ5SWQodGlja0xpbmVJZCk7XG4gICAgICAgICAgICBpZiAodGlja0xpbmVTaGFwZSkge1xuICAgICAgICAgICAgICAgIHZhciB0aWNrTGluZVN0YXRlU3R5bGUgPSBzdGF0ZV8xLmdldFN0YXRlc1N0eWxlKHRpY2ssICd0aWNrTGluZScsIHRpY2tTdGF0ZXMpO1xuICAgICAgICAgICAgICAgIHRpY2tMaW5lU3RhdGVTdHlsZSAmJiB0aWNrTGluZVNoYXBlLmF0dHIodGlja0xpbmVTdGF0ZVN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgQXhpc0Jhc2UucHJvdG90eXBlLnVwZGF0ZVRpY2tTdGF0ZXMgPSBmdW5jdGlvbiAodGljaykge1xuICAgICAgICB2YXIgc3RhdGVzID0gdGhpcy5nZXRJdGVtU3RhdGVzKHRpY2spO1xuICAgICAgICB2YXIgdGlja1N0YXRlcyA9IHRoaXMuZ2V0KCd0aWNrU3RhdGVzJyk7XG4gICAgICAgIHZhciBsYWJlbENmZyA9IHRoaXMuZ2V0KCdsYWJlbCcpO1xuICAgICAgICB2YXIgbGFiZWxTaGFwZSA9IHRoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZChcImxhYmVsLVwiICsgdGljay5pZCk7XG4gICAgICAgIHZhciB0aWNrTGluZUNmZyA9IHRoaXMuZ2V0KCd0aWNrTGluZScpO1xuICAgICAgICB2YXIgdGlja0xpbmVTaGFwZSA9IHRoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZChcInRpY2tsaW5lLVwiICsgdGljay5pZCk7XG4gICAgICAgIGlmIChzdGF0ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAobGFiZWxTaGFwZSkge1xuICAgICAgICAgICAgICAgIHZhciBsYWJlbFN0YXRlU3R5bGUgPSBzdGF0ZV8xLmdldFN0YXRlc1N0eWxlKHRpY2ssICdsYWJlbCcsIHRpY2tTdGF0ZXMpO1xuICAgICAgICAgICAgICAgIGxhYmVsU3RhdGVTdHlsZSAmJiBsYWJlbFNoYXBlLmF0dHIobGFiZWxTdGF0ZVN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aWNrTGluZVNoYXBlKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRpY2tMaW5lU3RhdGVTdHlsZSA9IHN0YXRlXzEuZ2V0U3RhdGVzU3R5bGUodGljaywgJ3RpY2tMaW5lJywgdGlja1N0YXRlcyk7XG4gICAgICAgICAgICAgICAgdGlja0xpbmVTdGF0ZVN0eWxlICYmIHRpY2tMaW5lU2hhcGUuYXR0cih0aWNrTGluZVN0YXRlU3R5bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGxhYmVsU2hhcGUpIHtcbiAgICAgICAgICAgICAgICBsYWJlbFNoYXBlLmF0dHIobGFiZWxDZmcuc3R5bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRpY2tMaW5lU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB0aWNrTGluZVNoYXBlLmF0dHIodGlja0xpbmVDZmcuc3R5bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gQXhpc0Jhc2U7XG59KGdyb3VwX2NvbXBvbmVudF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEF4aXNCYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBDaXJjbGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2lyY2xlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENpcmNsZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBDaXJjbGUucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyB0eXBlOiAnY2lyY2xlJywgbG9jYXRpb25UeXBlOiAnY2lyY2xlJywgY2VudGVyOiBudWxsLCByYWRpdXM6IG51bGwsIHN0YXJ0QW5nbGU6IC1NYXRoLlBJIC8gMiwgZW5kQW5nbGU6IChNYXRoLlBJICogMykgLyAyIH0pO1xuICAgIH07XG4gICAgQ2lyY2xlLnByb3RvdHlwZS5nZXRMaW5lUGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNlbnRlciA9IHRoaXMuZ2V0KCdjZW50ZXInKTtcbiAgICAgICAgdmFyIHggPSBjZW50ZXIueDtcbiAgICAgICAgdmFyIHkgPSBjZW50ZXIueTtcbiAgICAgICAgdmFyIHJ4ID0gdGhpcy5nZXQoJ3JhZGl1cycpO1xuICAgICAgICB2YXIgcnkgPSByeDtcbiAgICAgICAgdmFyIHN0YXJ0QW5nbGUgPSB0aGlzLmdldCgnc3RhcnRBbmdsZScpO1xuICAgICAgICB2YXIgZW5kQW5nbGUgPSB0aGlzLmdldCgnZW5kQW5nbGUnKTtcbiAgICAgICAgdmFyIHBhdGggPSBbXTtcbiAgICAgICAgaWYgKE1hdGguYWJzKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSkgPT09IE1hdGguUEkgKiAyKSB7XG4gICAgICAgICAgICBwYXRoID0gW1snTScsIHgsIHkgLSByeV0sIFsnQScsIHJ4LCByeSwgMCwgMSwgMSwgeCwgeSArIHJ5XSwgWydBJywgcngsIHJ5LCAwLCAxLCAxLCB4LCB5IC0gcnldLCBbJ1onXV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHRoaXMuZ2V0Q2lyY2xlUG9pbnQoc3RhcnRBbmdsZSk7XG4gICAgICAgICAgICB2YXIgZW5kUG9pbnQgPSB0aGlzLmdldENpcmNsZVBvaW50KGVuZEFuZ2xlKTtcbiAgICAgICAgICAgIHZhciBsYXJnZSA9IE1hdGguYWJzKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSkgPiBNYXRoLlBJID8gMSA6IDA7XG4gICAgICAgICAgICB2YXIgc3dlZXAgPSBzdGFydEFuZ2xlID4gZW5kQW5nbGUgPyAwIDogMTtcbiAgICAgICAgICAgIHBhdGggPSBbXG4gICAgICAgICAgICAgICAgWydNJywgeCwgeV0sXG4gICAgICAgICAgICAgICAgWydMJywgc3RhcnRQb2ludC54LCBzdGFydFBvaW50LnldLFxuICAgICAgICAgICAgICAgIFsnQScsIHJ4LCByeSwgMCwgbGFyZ2UsIHN3ZWVwLCBlbmRQb2ludC54LCBlbmRQb2ludC55XSxcbiAgICAgICAgICAgICAgICBbJ0wnLCB4LCB5XSxcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfTtcbiAgICBDaXJjbGUucHJvdG90eXBlLmdldFRpY2tQb2ludCA9IGZ1bmN0aW9uICh0aWNrVmFsdWUpIHtcbiAgICAgICAgdmFyIHN0YXJ0QW5nbGUgPSB0aGlzLmdldCgnc3RhcnRBbmdsZScpO1xuICAgICAgICB2YXIgZW5kQW5nbGUgPSB0aGlzLmdldCgnZW5kQW5nbGUnKTtcbiAgICAgICAgdmFyIGFuZ2xlID0gc3RhcnRBbmdsZSArIChlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpICogdGlja1ZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDaXJjbGVQb2ludChhbmdsZSk7XG4gICAgfTtcbiAgICAvLyDojrflj5blnoLnm7Tkuo7lnZDmoIfovbTnmoTlkJHph49cbiAgICBDaXJjbGUucHJvdG90eXBlLmdldFNpZGVWZWN0b3IgPSBmdW5jdGlvbiAob2Zmc2V0LCBwb2ludCkge1xuICAgICAgICB2YXIgY2VudGVyID0gdGhpcy5nZXQoJ2NlbnRlcicpO1xuICAgICAgICB2YXIgdmVjdG9yID0gW3BvaW50LnggLSBjZW50ZXIueCwgcG9pbnQueSAtIGNlbnRlci55XTtcbiAgICAgICAgdmFyIGZhY3RvciA9IHRoaXMuZ2V0KCd2ZXJ0aWNhbEZhY3RvcicpO1xuICAgICAgICB2YXIgdmVjTGVuID0gbWF0cml4X3V0aWxfMS52ZWMyLmxlbmd0aCh2ZWN0b3IpO1xuICAgICAgICBtYXRyaXhfdXRpbF8xLnZlYzIuc2NhbGUodmVjdG9yLCB2ZWN0b3IsIChmYWN0b3IgKiBvZmZzZXQpIC8gdmVjTGVuKTtcbiAgICAgICAgcmV0dXJuIHZlY3RvcjtcbiAgICB9O1xuICAgIC8vIOiOt+WPluayv+WdkOagh+i9tOaWueWQkeeahOWQkemHj1xuICAgIENpcmNsZS5wcm90b3R5cGUuZ2V0QXhpc1ZlY3RvciA9IGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICB2YXIgY2VudGVyID0gdGhpcy5nZXQoJ2NlbnRlcicpO1xuICAgICAgICB2YXIgdmVjdG9yID0gW3BvaW50LnggLSBjZW50ZXIueCwgcG9pbnQueSAtIGNlbnRlci55XTtcbiAgICAgICAgcmV0dXJuIFt2ZWN0b3JbMV0sIC0xICogdmVjdG9yWzBdXTsgLy8g6I635Y+W6aG65pe26ZKI5pa55ZCR55qE5ZCR6YePXG4gICAgfTtcbiAgICAvLyDmoLnmja7lnIblv4PlkozljYrlvoTojrflj5bngrlcbiAgICBDaXJjbGUucHJvdG90eXBlLmdldENpcmNsZVBvaW50ID0gZnVuY3Rpb24gKGFuZ2xlLCByYWRpdXMpIHtcbiAgICAgICAgdmFyIGNlbnRlciA9IHRoaXMuZ2V0KCdjZW50ZXInKTtcbiAgICAgICAgcmFkaXVzID0gcmFkaXVzIHx8IHRoaXMuZ2V0KCdyYWRpdXMnKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGNlbnRlci54ICsgTWF0aC5jb3MoYW5nbGUpICogcmFkaXVzLFxuICAgICAgICAgICAgeTogY2VudGVyLnkgKyBNYXRoLnNpbihhbmdsZSkgKiByYWRpdXMsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gQ2lyY2xlO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2lyY2xlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2lyY2xlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGxpbmVfMSA9IHJlcXVpcmUoXCIuL2xpbmVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJMaW5lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaW5lXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBjaXJjbGVfMSA9IHJlcXVpcmUoXCIuL2NpcmNsZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNpcmNsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY2lyY2xlXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQmFzZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYmFzZV8xLmRlZmF1bHQ7IH0gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBPdmVybGFwVXRpbCA9IHJlcXVpcmUoXCIuL292ZXJsYXBcIik7XG52YXIgTGluZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaW5lLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIExpbmUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTGluZS5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IHR5cGU6ICdsaW5lJywgbG9jYXRpb25UeXBlOiAncmVnaW9uJywgXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIOi1t+Wni+eCuSwgeCwgeVxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgc3RhcnQ6IG51bGwsIFxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDnu5PmnZ/ngrksIHgsIHlcbiAgICAgICAgICAgICAqIEB0eXBlIHtvYmplY3R9XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGVuZDogbnVsbCB9KTtcbiAgICB9O1xuICAgIC8vIOiOt+WPluWdkOagh+i9tOe6v+eahCBwYXRoXG4gICAgTGluZS5wcm90b3R5cGUuZ2V0TGluZVBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuZ2V0KCdzdGFydCcpO1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5nZXQoJ2VuZCcpO1xuICAgICAgICB2YXIgcGF0aCA9IFtdO1xuICAgICAgICBwYXRoLnB1c2goWydNJywgc3RhcnQueCwgc3RhcnQueV0pO1xuICAgICAgICBwYXRoLnB1c2goWydMJywgZW5kLngsIGVuZC55XSk7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH07XG4gICAgLy8g6YeN5paw6K6h566XIGxheW91dCBiYm9477yM6ICD6JmR5YiwIGxpbmUg5LiN5pi+56S6XG4gICAgTGluZS5wcm90b3R5cGUuZ2V0SW5uZXJMYXlvdXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmdldCgnc3RhcnQnKTtcbiAgICAgICAgdmFyIGVuZCA9IHRoaXMuZ2V0KCdlbmQnKTtcbiAgICAgICAgdmFyIGJib3ggPSBfc3VwZXIucHJvdG90eXBlLmdldElubmVyTGF5b3V0QkJveC5jYWxsKHRoaXMpO1xuICAgICAgICB2YXIgbWluWCA9IE1hdGgubWluKHN0YXJ0LngsIGVuZC54LCBiYm94LngpO1xuICAgICAgICB2YXIgbWluWSA9IE1hdGgubWluKHN0YXJ0LnksIGVuZC55LCBiYm94LnkpO1xuICAgICAgICB2YXIgbWF4WCA9IE1hdGgubWF4KHN0YXJ0LngsIGVuZC54LCBiYm94Lm1heFgpO1xuICAgICAgICB2YXIgbWF4WSA9IE1hdGgubWF4KHN0YXJ0LnksIGVuZC55LCBiYm94Lm1heFkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogbWluWCxcbiAgICAgICAgICAgIHk6IG1pblksXG4gICAgICAgICAgICBtaW5YOiBtaW5YLFxuICAgICAgICAgICAgbWluWTogbWluWSxcbiAgICAgICAgICAgIG1heFg6IG1heFgsXG4gICAgICAgICAgICBtYXhZOiBtYXhZLFxuICAgICAgICAgICAgd2lkdGg6IG1heFggLSBtaW5YLFxuICAgICAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIExpbmUucHJvdG90eXBlLmlzVmVydGljYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuZ2V0KCdzdGFydCcpO1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5nZXQoJ2VuZCcpO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmlzTnVtYmVyRXF1YWwoc3RhcnQueCwgZW5kLngpO1xuICAgIH07XG4gICAgTGluZS5wcm90b3R5cGUuaXNIb3Jpem9udGFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmdldCgnc3RhcnQnKTtcbiAgICAgICAgdmFyIGVuZCA9IHRoaXMuZ2V0KCdlbmQnKTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5pc051bWJlckVxdWFsKHN0YXJ0LnksIGVuZC55KTtcbiAgICB9O1xuICAgIExpbmUucHJvdG90eXBlLmdldFRpY2tQb2ludCA9IGZ1bmN0aW9uICh0aWNrVmFsdWUpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgc3RhcnQgPSBzZWxmLmdldCgnc3RhcnQnKTtcbiAgICAgICAgdmFyIGVuZCA9IHNlbGYuZ2V0KCdlbmQnKTtcbiAgICAgICAgdmFyIHJlZ2lvblggPSBlbmQueCAtIHN0YXJ0Lng7XG4gICAgICAgIHZhciByZWdpb25ZID0gZW5kLnkgLSBzdGFydC55O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogc3RhcnQueCArIHJlZ2lvblggKiB0aWNrVmFsdWUsXG4gICAgICAgICAgICB5OiBzdGFydC55ICsgcmVnaW9uWSAqIHRpY2tWYWx1ZSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8vIOebtOe6v+WdkOagh+i9tOS4i+S7u+S4gOeCueeahOWQkemHj+aWueWQkemDveebuOWQjFxuICAgIExpbmUucHJvdG90eXBlLmdldFNpZGVWZWN0b3IgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gICAgICAgIHZhciBheGlzVmVjdG9yID0gdGhpcy5nZXRBeGlzVmVjdG9yKCk7XG4gICAgICAgIHZhciBub3JtYWwgPSBtYXRyaXhfdXRpbF8xLnZlYzIubm9ybWFsaXplKFswLCAwXSwgYXhpc1ZlY3Rvcik7XG4gICAgICAgIHZhciBmYWN0b3IgPSB0aGlzLmdldCgndmVydGljYWxGYWN0b3InKTtcbiAgICAgICAgdmFyIHZlcnRpY2FsVmVjdG9yID0gW25vcm1hbFsxXSwgbm9ybWFsWzBdICogLTFdOyAvLyDlnoLnm7TmlrnlkJHvvIzpgIbml7bpkojmlrnlkJFcbiAgICAgICAgcmV0dXJuIG1hdHJpeF91dGlsXzEudmVjMi5zY2FsZShbMCwgMF0sIHZlcnRpY2FsVmVjdG9yLCBvZmZzZXQgKiBmYWN0b3IpO1xuICAgIH07XG4gICAgLy8g6I635Y+W5Z2Q5qCH6L2055qE5ZCR6YePXG4gICAgTGluZS5wcm90b3R5cGUuZ2V0QXhpc1ZlY3RvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5nZXQoJ3N0YXJ0Jyk7XG4gICAgICAgIHZhciBlbmQgPSB0aGlzLmdldCgnZW5kJyk7XG4gICAgICAgIHJldHVybiBbZW5kLnggLSBzdGFydC54LCBlbmQueSAtIHN0YXJ0LnldO1xuICAgIH07XG4gICAgTGluZS5wcm90b3R5cGUucHJvY2Vzc092ZXJsYXAgPSBmdW5jdGlvbiAobGFiZWxHcm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXNWZXJ0aWNhbCA9IHRoaXMuaXNWZXJ0aWNhbCgpO1xuICAgICAgICB2YXIgaXNIb3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcbiAgICAgICAgLy8g6Z2e5Z6C55u077yM5oiW6ICF6Z2e5rC05bmz5pe25LiN5aSE55CG6YGu5oyh6Zeu6aKYXG4gICAgICAgIGlmICghaXNWZXJ0aWNhbCAmJiAhaXNIb3Jpem9udGFsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGxhYmVsQ2ZnID0gdGhpcy5nZXQoJ2xhYmVsJyk7XG4gICAgICAgIHZhciB0aXRsZUNmZyA9IHRoaXMuZ2V0KCd0aXRsZScpO1xuICAgICAgICB2YXIgdmVydGljYWxMaW1pdExlbmd0aCA9IHRoaXMuZ2V0KCd2ZXJ0aWNhbExpbWl0TGVuZ3RoJyk7XG4gICAgICAgIHZhciBsYWJlbE9mZnNldCA9IGxhYmVsQ2ZnLm9mZnNldDtcbiAgICAgICAgdmFyIGxpbWl0TGVuZ3RoID0gdmVydGljYWxMaW1pdExlbmd0aDtcbiAgICAgICAgdmFyIHRpdGxlSGVpZ2h0ID0gMDtcbiAgICAgICAgdmFyIHRpdGxlU3BhY2luZyA9IDA7XG4gICAgICAgIGlmICh0aXRsZUNmZykge1xuICAgICAgICAgICAgdGl0bGVIZWlnaHQgPSB0aXRsZUNmZy5zdHlsZS5mb250U2l6ZTtcbiAgICAgICAgICAgIHRpdGxlU3BhY2luZyA9IHRpdGxlQ2ZnLnNwYWNpbmc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxpbWl0TGVuZ3RoKSB7XG4gICAgICAgICAgICBsaW1pdExlbmd0aCA9IGxpbWl0TGVuZ3RoIC0gbGFiZWxPZmZzZXQgLSB0aXRsZVNwYWNpbmcgLSB0aXRsZUhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb3ZlcmxhcE9yZGVyID0gdGhpcy5nZXQoJ292ZXJsYXBPcmRlcicpO1xuICAgICAgICB1dGlsXzEuZWFjaChvdmVybGFwT3JkZXIsIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICBpZiAobGFiZWxDZmdbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5hdXRvUHJvY2Vzc092ZXJsYXAobmFtZSwgbGFiZWxDZmdbbmFtZV0sIGxhYmVsR3JvdXAsIGxpbWl0TGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aXRsZUNmZykge1xuICAgICAgICAgICAgLy8g6LCD5pW0IHRpdGxlIOeahCBvZmZzZXRcbiAgICAgICAgICAgIHZhciBiYm94ID0gbGFiZWxHcm91cC5nZXRCQm94KCk7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoXzEgPSBpc1ZlcnRpY2FsID8gYmJveC53aWR0aCA6IGJib3guaGVpZ2h0O1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc05pbCh0aXRsZUNmZy5vZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c55So5oi35rKh5pyJ6K6+572uIG9mZnNldO+8jOWImeiHquWKqOiuoeeul1xuICAgICAgICAgICAgICAgIHRpdGxlQ2ZnLm9mZnNldCA9IGxhYmVsT2Zmc2V0ICsgbGVuZ3RoXzEgKyB0aXRsZVNwYWNpbmcgKyB0aXRsZUhlaWdodCAvIDI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExpbmUucHJvdG90eXBlLmF1dG9Qcm9jZXNzT3ZlcmxhcCA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgbGFiZWxHcm91cCwgbGltaXRMZW5ndGgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGlzVmVydGljYWwgPSB0aGlzLmlzVmVydGljYWwoKTtcbiAgICAgICAgdmFyIGhhc0FkanVzdGVkID0gZmFsc2U7XG4gICAgICAgIHZhciB1dGlsID0gT3ZlcmxhcFV0aWxbbmFtZV07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8g6buY6K6k5L2/55So5Zu65a6a6KeS5bqm55qE5peL6L2s5pa55qGIXG4gICAgICAgICAgICBoYXNBZGp1c3RlZCA9IHV0aWwuZ2V0RGVmYXVsdCgpKGlzVmVydGljYWwsIGxhYmVsR3JvdXAsIGxpbWl0TGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIOeUqOaIt+WPr+S7peS8oOWFpeWbnuiwg+WHveaVsFxuICAgICAgICAgICAgaGFzQWRqdXN0ZWQgPSB2YWx1ZShpc1ZlcnRpY2FsLCBsYWJlbEdyb3VwLCBsaW1pdExlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodXRpbFt2YWx1ZV0pIHtcbiAgICAgICAgICAgIC8vIOaMieeFp+WQjeensOaJp+ihjOaXi+i9rOWHveaVsFxuICAgICAgICAgICAgaGFzQWRqdXN0ZWQgPSB1dGlsW3ZhbHVlXShpc1ZlcnRpY2FsLCBsYWJlbEdyb3VwLCBsaW1pdExlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hbWUgPT09ICdhdXRvUm90YXRlJykge1xuICAgICAgICAgICAgLy8g5paH5pys5peL6L2s5ZCO77yM5paH5pys55qE5a+56b2Q5pa55byP5Y+v6IO95bCx5LiN5ZCI6YCC5LqGXG4gICAgICAgICAgICBpZiAoaGFzQWRqdXN0ZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWxzID0gbGFiZWxHcm91cC5nZXRDaGlsZHJlbigpO1xuICAgICAgICAgICAgICAgIHZhciB2ZXJ0aWNhbEZhY3Rvcl8xID0gdGhpcy5nZXQoJ3ZlcnRpY2FsRmFjdG9yJyk7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRBbGlnbiA9IGxhYmVsLmF0dHIoJ3RleHRBbGlnbicpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGV4dEFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5bGF5Lit55qE5paH5pys6ZyA6KaB6LCD5pW05peL6L2s5bqmXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3QWxpZ24gPSB2ZXJ0aWNhbEZhY3Rvcl8xID4gMCA/ICdlbmQnIDogJ3N0YXJ0JztcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3RleHRBbGlnbicsIG5ld0FsaWduKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdhdXRvSGlkZScpIHtcbiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IGxhYmVsR3JvdXAuZ2V0Q2hpbGRyZW4oKS5zbGljZSgwKTsgLy8g5aSN5Yi25pWw57uE77yM5Yig6Zmk5pe25LiN5Lya5Ye66ZSZXG4gICAgICAgICAgICB1dGlsXzEuZWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsYWJlbC5nZXQoJ3Zpc2libGUnKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuZ2V0KCdpc1JlZ2lzdGVyJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOW3sue7j+azqOWGjOi/h+S6hu+8jOWImeWIoOmZpFxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudW5yZWdpc3RlckVsZW1lbnQobGFiZWwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLnJlbW92ZSgpOyAvLyDpmLLmraIgbGFiZWwg5pWw6YeP5aSq5aSa77yM5omA5Lul57uf5LiA5Yig6ZmkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBMaW5lO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmVsbGlwc2lzTWlkZGxlID0gZXhwb3J0cy5lbGxpcHNpc1RhaWwgPSBleHBvcnRzLmVsbGlwc2lzSGVhZCA9IGV4cG9ydHMuZ2V0RGVmYXVsdCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvbGFiZWxcIik7XG5mdW5jdGlvbiBlbGxpcHNlTGFiZWxzKGlzVmVydGljYWwsIGxhYmVsR3JvdXAsIGxpbWl0TGVuZ3RoLCBwb3NpdGlvbikge1xuICAgIHZhciBjaGlsZHJlbiA9IGxhYmVsR3JvdXAuZ2V0Q2hpbGRyZW4oKTtcbiAgICB2YXIgZWxsaXBzaXNlZCA9IGZhbHNlO1xuICAgIHV0aWxfMS5lYWNoKGNoaWxkcmVuLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgdmFyIHJzdCA9IGxhYmVsXzEuZWxsaXBzaXNMYWJlbChpc1ZlcnRpY2FsLCBsYWJlbCwgbGltaXRMZW5ndGgsIHBvc2l0aW9uKTtcbiAgICAgICAgZWxsaXBzaXNlZCA9IGVsbGlwc2lzZWQgfHwgcnN0O1xuICAgIH0pO1xuICAgIHJldHVybiBlbGxpcHNpc2VkO1xufVxuZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHtcbiAgICByZXR1cm4gZWxsaXBzaXNUYWlsO1xufVxuZXhwb3J0cy5nZXREZWZhdWx0ID0gZ2V0RGVmYXVsdDtcbmZ1bmN0aW9uIGVsbGlwc2lzSGVhZChpc1ZlcnRpY2FsLCBsYWJlbEdyb3VwLCBsaW1pdExlbmd0aCkge1xuICAgIHJldHVybiBlbGxpcHNlTGFiZWxzKGlzVmVydGljYWwsIGxhYmVsR3JvdXAsIGxpbWl0TGVuZ3RoLCAnaGVhZCcpO1xufVxuZXhwb3J0cy5lbGxpcHNpc0hlYWQgPSBlbGxpcHNpc0hlYWQ7XG5mdW5jdGlvbiBlbGxpcHNpc1RhaWwoaXNWZXJ0aWNhbCwgbGFiZWxHcm91cCwgbGltaXRMZW5ndGgpIHtcbiAgICByZXR1cm4gZWxsaXBzZUxhYmVscyhpc1ZlcnRpY2FsLCBsYWJlbEdyb3VwLCBsaW1pdExlbmd0aCwgJ3RhaWwnKTtcbn1cbmV4cG9ydHMuZWxsaXBzaXNUYWlsID0gZWxsaXBzaXNUYWlsO1xuZnVuY3Rpb24gZWxsaXBzaXNNaWRkbGUoaXNWZXJ0aWNhbCwgbGFiZWxHcm91cCwgbGltaXRMZW5ndGgpIHtcbiAgICByZXR1cm4gZWxsaXBzZUxhYmVscyhpc1ZlcnRpY2FsLCBsYWJlbEdyb3VwLCBsaW1pdExlbmd0aCwgJ21pZGRsZScpO1xufVxuZXhwb3J0cy5lbGxpcHNpc01pZGRsZSA9IGVsbGlwc2lzTWlkZGxlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXV0by1lbGxpcHNpcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZXF1aWRpc3RhbmNlID0gZXhwb3J0cy5yZXNlcnZlQm90aCA9IGV4cG9ydHMucmVzZXJ2ZUxhc3QgPSBleHBvcnRzLnJlc2VydmVGaXJzdCA9IGV4cG9ydHMuZ2V0RGVmYXVsdCA9IHZvaWQgMDtcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvbGFiZWxcIik7XG4vLyDmlofmnKzmmK/lkKbml4vovaxcbmZ1bmN0aW9uIGlzUm90YXRlKGxhYmVsKSB7XG4gICAgdmFyIG1hdHJpeCA9IGxhYmVsLmF0dHIoJ21hdHJpeCcpO1xuICAgIHJldHVybiBtYXRyaXggJiYgbWF0cml4WzBdICE9PSAxOyAvLyDku4XlnKjov5nkuKrlnLrmma/kuIvliKTlrppcbn1cbi8vIGF1dG9oaWRlIOS4jeWGjeiAg+iZkei2heWHuumZkOWItlxuLy8gZnVuY3Rpb24gaXNPdXRMaW1pdChpc1ZlcnRpY2FsOiBib29sZWFuLCBsYWJlbDogSUVsZW1lbnQsIGxpbWl0TGVuZ3RoOiBudW1iZXIpIHtcbi8vICAgaWYgKCFsaW1pdExlbmd0aCkge1xuLy8gICAgIC8vIOWmguaenOayoemZkOWItiBsaW1pdExlbmd0aCDliJnnm7TmjqXov5Tlm54gZmFsc2Vcbi8vICAgICByZXR1cm4gZmFsc2U7XG4vLyAgIH1cbi8vICAgY29uc3QgY2FudmFzQkJveCA9IGxhYmVsLmdldENhbnZhc0JCb3goKTtcbi8vICAgbGV0IGlzT3V0ID0gZmFsc2U7XG4vLyAgIGlmIChpc1ZlcnRpY2FsKSB7XG4vLyAgICAgaXNPdXQgPSBjYW52YXNCQm94LndpZHRoID4gbGltaXRMZW5ndGg7XG4vLyAgIH0gZWxzZSB7XG4vLyAgICAgaXNPdXQgPSBjYW52YXNCQm94LmhlaWdodCA+IGxpbWl0TGVuZ3RoO1xuLy8gICB9XG4vLyAgIHJldHVybiBpc091dDtcbi8vIH1cbi8vIOaYr+WQpumHjeWPoFxuZnVuY3Rpb24gaXNPdmVybGFwKGlzVmVydGljYWwsIHJvdGF0ZWQsIHByZUJveCwgY3VyQm94LCByZXZlcnNlZCkge1xuICAgIGlmIChyZXZlcnNlZCA9PT0gdm9pZCAwKSB7IHJldmVyc2VkID0gZmFsc2U7IH1cbiAgICB2YXIgb3ZlcmxhcCA9IGZhbHNlO1xuICAgIGlmIChpc1ZlcnRpY2FsKSB7XG4gICAgICAgIC8vIOWeguebtOaXtuajgOa1i+i+uemrmFxuICAgICAgICBvdmVybGFwID0gTWF0aC5hYnMocHJlQm94LnkgLSBjdXJCb3gueSkgPCBwcmVCb3guaGVpZ2h0O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g5rC05bmz5pe25qOA5rWLXG4gICAgICAgIGlmIChyb3RhdGVkKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzml4vovazkuobvvIzliJnmo4DmtYvkuKTogIUgeCDkuYvpl7TnmoTpl7Tot53mmK/lkKblsI/kuo7liY3kuIDkuKrnmoTpq5jluqZcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSByZXZlcnNlZCA/IGN1ckJveC5oZWlnaHQgOiBwcmVCb3guaGVpZ2h0O1xuICAgICAgICAgICAgb3ZlcmxhcCA9IE1hdGguYWJzKHByZUJveC54IC0gY3VyQm94LngpIDwgaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5qOA5rWL5Lik6ICF5piv5ZCmIHgg5pa55ZCR6YeN5ZCIXG4gICAgICAgICAgICB2YXIgd2lkdGggPSByZXZlcnNlZCA/IGN1ckJveC53aWR0aCA6IHByZUJveC53aWR0aDtcbiAgICAgICAgICAgIG92ZXJsYXAgPSBNYXRoLmFicyhwcmVCb3gueCAtIGN1ckJveC54KSA8IHdpZHRoO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdmVybGFwO1xufVxuLy8g5L+d55WZ56ys5LiA5Liq5oiW6ICF5pyA5ZCO5LiA5LiqXG5mdW5jdGlvbiByZXNlcnZlT25lKGlzVmVydGljYWwsIGxhYmVsc0dyb3VwLCByZXZlcnNlZCkge1xuICAgIHZhciBsYWJlbHMgPSBsYWJlbHNHcm91cC5nZXRDaGlsZHJlbigpLnNsaWNlKCk7IC8vIOWkjeWItuaVsOe7hFxuICAgIGlmICghbGFiZWxzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBoYXNIaWRlID0gZmFsc2U7XG4gICAgaWYgKHJldmVyc2VkKSB7XG4gICAgICAgIC8vIOe/u+i9rFxuICAgICAgICBsYWJlbHMucmV2ZXJzZSgpO1xuICAgIH1cbiAgICB2YXIgY291bnQgPSBsYWJlbHMubGVuZ3RoO1xuICAgIHZhciBmaXJzdCA9IGxhYmVsc1swXTtcbiAgICB2YXIgcm90YXRlZCA9IGlzUm90YXRlKGZpcnN0KTtcbiAgICB2YXIgcHJlQm94ID0gZmlyc3QuZ2V0QkJveCgpO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICB2YXIgbGFiZWwgPSBsYWJlbHNbaV07XG4gICAgICAgIHZhciBjdXJCQm94ID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICAvLyDkuI3lho3ogIPomZHotoXlh7rpmZDliLbvvIzogIzku4Xku4XmoLnmja7mmK/lkKbph43lj6Dov5vooYzpmpDol48gaXNPdXRMaW1pdChpc1ZlcnRpY2FsLCBsYWJlbCwgbGltaXRMZW5ndGgpIHx8XG4gICAgICAgIHZhciBpc0hpZGUgPSBpc092ZXJsYXAoaXNWZXJ0aWNhbCwgcm90YXRlZCwgcHJlQm94LCBjdXJCQm94LCByZXZlcnNlZCk7XG4gICAgICAgIGlmIChpc0hpZGUpIHtcbiAgICAgICAgICAgIGxhYmVsLmhpZGUoKTtcbiAgICAgICAgICAgIGhhc0hpZGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHJlQm94ID0gY3VyQkJveDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGFzSGlkZTtcbn1cbmZ1bmN0aW9uIGdldERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIGVxdWlkaXN0YW5jZTtcbn1cbmV4cG9ydHMuZ2V0RGVmYXVsdCA9IGdldERlZmF1bHQ7XG4vKipcbiAqIOS/neivgemmluS4qiBsYWJlbCDlj6/op4HvvIzljbPkvb/otoXov4cgbGltaXRMZW5ndGgg5Lmf5LiN6ZqQ6JePXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzVmVydGljYWwgIOaYr+WQpuWeguebtFxuICogQHBhcmFtIHtJR3JvdXB9ICBsYWJlbHNHcm91cCBsYWJlbCDnmoTliIbnu4RcbiAqL1xuZnVuY3Rpb24gcmVzZXJ2ZUZpcnN0KGlzVmVydGljYWwsIGxhYmVsc0dyb3VwKSB7XG4gICAgcmV0dXJuIHJlc2VydmVPbmUoaXNWZXJ0aWNhbCwgbGFiZWxzR3JvdXAsIGZhbHNlKTtcbn1cbmV4cG9ydHMucmVzZXJ2ZUZpcnN0ID0gcmVzZXJ2ZUZpcnN0O1xuLyoqXG4gKiDkv53or4HmnIDlkI7kuIDkuKogbGFiZWwg5Y+v6KeB77yM5Y2z5L2/6LaF6L+HIGxpbWl0TGVuZ3RoIOS5n+S4jemakOiXj1xuICogQHBhcmFtIHtib29sZWFufSBpc1ZlcnRpY2FsICDmmK/lkKblnoLnm7RcbiAqIEBwYXJhbSB7SUdyb3VwfSAgbGFiZWxzR3JvdXAgbGFiZWwg55qE5YiG57uEXG4gKi9cbmZ1bmN0aW9uIHJlc2VydmVMYXN0KGlzVmVydGljYWwsIGxhYmVsc0dyb3VwKSB7XG4gICAgcmV0dXJuIHJlc2VydmVPbmUoaXNWZXJ0aWNhbCwgbGFiZWxzR3JvdXAsIHRydWUpO1xufVxuZXhwb3J0cy5yZXNlcnZlTGFzdCA9IHJlc2VydmVMYXN0O1xuLyoqXG4gKiDkv53or4HnrKzkuIDkuKrmnIDlkI7kuIDkuKogbGFiZWwg5Y+v6KeB77yM5Y2z5L2/6LaF6L+HIGxpbWl0TGVuZ3RoIOS5n+S4jemakOiXj1xuICogQHBhcmFtIHtib29sZWFufSBpc1ZlcnRpY2FsICDmmK/lkKblnoLnm7RcbiAqIEBwYXJhbSB7SUdyb3VwfSAgbGFiZWxzR3JvdXAgbGFiZWwg55qE5YiG57uEXG4gKi9cbmZ1bmN0aW9uIHJlc2VydmVCb3RoKGlzVmVydGljYWwsIGxhYmVsc0dyb3VwKSB7XG4gICAgdmFyIGxhYmVscyA9IGxhYmVsc0dyb3VwLmdldENoaWxkcmVuKCkuc2xpY2UoKTsgLy8g5aSN5Yi25pWw57uEXG4gICAgaWYgKGxhYmVscy5sZW5ndGggPD0gMikge1xuICAgICAgICAvLyDlpoLmnpzmlbDph4/lsI/kuo7miJbnrYnkuo4gMiDliJnnm7TmjqXov5Tlm55cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgaGFzSGlkZSA9IGZhbHNlO1xuICAgIHZhciBjb3VudCA9IGxhYmVscy5sZW5ndGg7XG4gICAgdmFyIGZpcnN0ID0gbGFiZWxzWzBdO1xuICAgIHZhciBsYXN0ID0gbGFiZWxzW2NvdW50IC0gMV07XG4gICAgdmFyIHJvdGF0ZWQgPSBpc1JvdGF0ZShmaXJzdCk7XG4gICAgdmFyIHByZUJveCA9IGZpcnN0LmdldEJCb3goKTtcbiAgICB2YXIgcHJlTGFiZWwgPSBmaXJzdDtcbiAgICAvLyDmjInnhaflhYjkv53lrZjnrKzkuIDkuKrnmoTpgLvovpHlvqrnjq/kuIDpgY3vvIzmnIDlkI7kuIDkuKrkuI3lj4LkuI7lvqrnjq9cbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IGNvdW50IC0gMTsgaSsrKSB7XG4gICAgICAgIHZhciBsYWJlbCA9IGxhYmVsc1tpXTtcbiAgICAgICAgdmFyIGN1ckJCb3ggPSBsYWJlbC5nZXRCQm94KCk7XG4gICAgICAgIC8vIOW6n+W8gyBpc091dExpbWl0KGlzVmVydGljYWwsIGxhYmVsLCBsaW1pdExlbmd0aCkgfHxcbiAgICAgICAgdmFyIGlzSGlkZSA9IGlzT3ZlcmxhcChpc1ZlcnRpY2FsLCByb3RhdGVkLCBwcmVCb3gsIGN1ckJCb3gpO1xuICAgICAgICBpZiAoaXNIaWRlKSB7XG4gICAgICAgICAgICBsYWJlbC5oaWRlKCk7XG4gICAgICAgICAgICBoYXNIaWRlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHByZUJveCA9IGN1ckJCb3g7XG4gICAgICAgICAgICBwcmVMYWJlbCA9IGxhYmVsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciBsYXN0QkJveCA9IGxhc3QuZ2V0QkJveCgpO1xuICAgIHZhciBvdmVybGFwID0gaXNPdmVybGFwKGlzVmVydGljYWwsIHJvdGF0ZWQsIHByZUJveCwgbGFzdEJCb3gpOyAvLyDkuI3mo4DmtYvotoXlh7ogbGltaXRcbiAgICBpZiAob3ZlcmxhcCkge1xuICAgICAgICAvLyDlj5HnlJ/lhrLnqoHvvIzliJnpmpDol4/liY3kuIDkuKrkv53nlZnlkI7kuIDkuKpcbiAgICAgICAgcHJlTGFiZWwuaGlkZSgpO1xuICAgICAgICBoYXNIaWRlID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0hpZGU7XG59XG5leHBvcnRzLnJlc2VydmVCb3RoID0gcmVzZXJ2ZUJvdGg7XG4vKipcbiAqIOS/neivgSBsYWJlbCDlnYfljIDmmL7npLrvvIzkuLvopoHop6PlhrPmlofmnKzlsYLlj6DnmoTpl67popjvvIzlr7nkuo4gbGltaXRMZW5ndGgg5LiN5aSE55CGXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzVmVydGljYWwgIOaYr+WQpuWeguebtFxuICogQHBhcmFtIHtJR3JvdXB9ICBsYWJlbHNHcm91cCBsYWJlbCDnmoTliIbnu4RcbiAqL1xuZnVuY3Rpb24gZXF1aWRpc3RhbmNlKGlzVmVydGljYWwsIGxhYmVsc0dyb3VwKSB7XG4gICAgdmFyIGxhYmVscyA9IGxhYmVsc0dyb3VwLmdldENoaWxkcmVuKCkuc2xpY2UoKTsgLy8g5aSN5Yi25pWw57uEXG4gICAgaWYgKGxhYmVscy5sZW5ndGggPCAyKSB7XG4gICAgICAgIC8vIOWmguaenOaVsOmHj+Wwj+S6jiAyIOWImeebtOaOpei/lOWbnu+8jOetieS6jiAyIOaXtuWPr+iDveS5n+S8mumHjeWQiFxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBoYXNIaWRlID0gZmFsc2U7XG4gICAgdmFyIGZpcnN0ID0gbGFiZWxzWzBdO1xuICAgIHZhciBmaXJzdEJCb3ggPSBmaXJzdC5nZXRCQm94KCk7XG4gICAgdmFyIHNlY29uZCA9IGxhYmVsc1sxXTtcbiAgICB2YXIgcm90YXRlZCA9IGlzUm90YXRlKGZpcnN0KTtcbiAgICB2YXIgY291bnQgPSBsYWJlbHMubGVuZ3RoO1xuICAgIHZhciBpbnRlcnZhbCA9IDA7IC8vIOS4jemHjeWPoOeahOWdkOagh+aWh+acrOmXtOi3neS4quaVsFxuICAgIGlmIChpc1ZlcnRpY2FsKSB7XG4gICAgICAgIC8vIOWeguebtOeahOWdkOagh+i9tOiuoeeul+WeguebtOaWueWQkeeahOmXtOi3nVxuICAgICAgICB2YXIgZGlzdGFuY2UgPSBNYXRoLmFicyhzZWNvbmQuYXR0cigneScpIC0gZmlyc3QuYXR0cigneScpKTtcbiAgICAgICAgaW50ZXJ2YWwgPSBmaXJzdEJCb3guaGVpZ2h0IC8gZGlzdGFuY2U7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyDmsLTlubPlnZDmoIfovbRcbiAgICAgICAgaWYgKHJvdGF0ZWQpIHtcbiAgICAgICAgICAgIHZhciBkaXN0YW5jZSA9IE1hdGguYWJzKHNlY29uZC5hdHRyKCd4JykgLSBmaXJzdC5hdHRyKCd4JykpO1xuICAgICAgICAgICAgaW50ZXJ2YWwgPSBmaXJzdEJCb3gud2lkdGggLyBkaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBtYXhXaWR0aCA9IGxhYmVsXzEuZ2V0TWF4TGFiZWxXaWR0aChsYWJlbHMpO1xuICAgICAgICAgICAgdmFyIGRpc3RhbmNlID0gTWF0aC5hYnMoc2Vjb25kLmF0dHIoJ3gnKSAtIGZpcnN0LmF0dHIoJ3gnKSk7XG4gICAgICAgICAgICBpbnRlcnZhbCA9IG1heFdpZHRoIC8gZGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gaW50ZXJ2YWwgPiAxIOaXtumcgOimgeWvuSBsYWJlbCDov5vooYzpmpDol49cbiAgICBpZiAoaW50ZXJ2YWwgPiAxKSB7XG4gICAgICAgIGludGVydmFsID0gTWF0aC5jZWlsKGludGVydmFsKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaSAlIGludGVydmFsICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8g5LuF5L+d55WZ6KKr5pW06Zmk55qEIGxhYmVsXG4gICAgICAgICAgICAgICAgbGFiZWxzW2ldLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBoYXNIaWRlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGFzSGlkZTtcbn1cbmV4cG9ydHMuZXF1aWRpc3RhbmNlID0gZXF1aWRpc3RhbmNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXV0by1oaWRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy51bmZpeGVkQW5nbGUgPSBleHBvcnRzLmZpeGVkQW5nbGUgPSBleHBvcnRzLmdldERlZmF1bHQgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2xhYmVsXCIpO1xudmFyIG1hdHJpeF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvbWF0cml4XCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC90aGVtZVwiKTtcbi8vIOe7n+S4gOiuvue9ruaWh+acrOeahOinkuW6plxuZnVuY3Rpb24gc2V0TGFiZWxzQW5nbGUobGFiZWxzLCBhbmdsZSkge1xuICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgIHZhciB4ID0gbGFiZWwuYXR0cigneCcpO1xuICAgICAgICB2YXIgeSA9IGxhYmVsLmF0dHIoJ3knKTtcbiAgICAgICAgdmFyIG1hdHJpeCA9IG1hdHJpeF8xLmdldE1hdHJpeEJ5QW5nbGUoeyB4OiB4LCB5OiB5IH0sIGFuZ2xlKTtcbiAgICAgICAgbGFiZWwuYXR0cignbWF0cml4JywgbWF0cml4KTtcbiAgICB9KTtcbn1cbi8vIOaXi+i9rOaWh+acrFxuZnVuY3Rpb24gbGFiZWxSb3RhdGUoaXNWZXJ0aWNhbCwgbGFiZWxzR3JvdXAsIGxpbWl0TGVuZ3RoLCBnZXRBbmdsZSkge1xuICAgIHZhciBsYWJlbHMgPSBsYWJlbHNHcm91cC5nZXRDaGlsZHJlbigpO1xuICAgIGlmICghbGFiZWxzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghaXNWZXJ0aWNhbCAmJiBsYWJlbHMubGVuZ3RoIDwgMikge1xuICAgICAgICAvLyDmsLTlubPml7boh7PlsJHmnInkuKTkuKrml7bmiY3ml4vovaxcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgbWF4V2lkdGggPSBsYWJlbF8xLmdldE1heExhYmVsV2lkdGgobGFiZWxzKTtcbiAgICB2YXIgaXNPdmVybGFwID0gZmFsc2U7XG4gICAgaWYgKGlzVmVydGljYWwpIHtcbiAgICAgICAgLy8gbGltaXRMZW5ndGgg5Li6IDAg5oiW6ICFIG51bGwg5pe25LiN55Sf5pWIXG4gICAgICAgIGlzT3ZlcmxhcCA9ICEhbGltaXRMZW5ndGggJiYgbWF4V2lkdGggPiBsaW1pdExlbmd0aDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIOWQjCBsaW1pdExlbmd0aCDml6DlhbNcbiAgICAgICAgdmFyIHRpY2tXaWR0aCA9IE1hdGguYWJzKGxhYmVsc1sxXS5hdHRyKCd4JykgLSBsYWJlbHNbMF0uYXR0cigneCcpKTtcbiAgICAgICAgaXNPdmVybGFwID0gbWF4V2lkdGggPiB0aWNrV2lkdGg7XG4gICAgfVxuICAgIGlmIChpc092ZXJsYXApIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gZ2V0QW5nbGUobGltaXRMZW5ndGgsIG1heFdpZHRoKTtcbiAgICAgICAgc2V0TGFiZWxzQW5nbGUobGFiZWxzLCBhbmdsZSk7XG4gICAgfVxuICAgIHJldHVybiBpc092ZXJsYXA7XG59XG5mdW5jdGlvbiBnZXREZWZhdWx0KCkge1xuICAgIHJldHVybiBmaXhlZEFuZ2xlO1xufVxuZXhwb3J0cy5nZXREZWZhdWx0ID0gZ2V0RGVmYXVsdDtcbi8qKlxuICog5Zu65a6a6KeS5bqm5peL6L2s5paH5pysXG4gKiBAcGFyYW0gIHtib29sZWFufSBpc1ZlcnRpY2FsICDmmK/lkKblnoLnm7TmlrnlkJFcbiAqIEBwYXJhbSAge0lHcm91cH0gIGxhYmVsc0dyb3VwIOaWh+acrOeahCBncm91cFxuICogQHBhcmFtICB7bnVtYmVyfSAgbGltaXRMZW5ndGgg6ZmQ5a6a6ZW/5bqmXG4gKiBAcmV0dXJuIHtib29sZWFufSAgICAgICAgICAgICDmmK/lkKblj5HnlJ/kuobml4vovaxcbiAqL1xuZnVuY3Rpb24gZml4ZWRBbmdsZShpc1ZlcnRpY2FsLCBsYWJlbHNHcm91cCwgbGltaXRMZW5ndGgpIHtcbiAgICByZXR1cm4gbGFiZWxSb3RhdGUoaXNWZXJ0aWNhbCwgbGFiZWxzR3JvdXAsIGxpbWl0TGVuZ3RoLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBpc1ZlcnRpY2FsID8gdGhlbWVfMS5kZWZhdWx0LnZlcnRpY2FsQXhpc1JvdGF0ZSA6IHRoZW1lXzEuZGVmYXVsdC5ob3Jpem9udGFsQXhpc1JvdGF0ZTtcbiAgICB9KTtcbn1cbmV4cG9ydHMuZml4ZWRBbmdsZSA9IGZpeGVkQW5nbGU7XG4vKipcbiAqIOmdnuWbuuWumuinkuW6puaXi+i9rOaWh+acrFxuICogQHBhcmFtICB7Ym9vbGVhbn0gaXNWZXJ0aWNhbCAg5piv5ZCm5Z6C55u05pa55ZCRXG4gKiBAcGFyYW0gIHtJR3JvdXB9ICBsYWJlbHNHcm91cCDmlofmnKznmoQgZ3JvdXBcbiAqIEBwYXJhbSAge251bWJlcn0gIGxpbWl0TGVuZ3RoIOmZkOWumumVv+W6plxuICogQHJldHVybiB7Ym9vbGVhbn0gICAgICAgICAgICAg5piv5ZCm5Y+R55Sf5LqG5peL6L2sXG4gKi9cbmZ1bmN0aW9uIHVuZml4ZWRBbmdsZShpc1ZlcnRpY2FsLCBsYWJlbHNHcm91cCwgbGltaXRMZW5ndGgpIHtcbiAgICByZXR1cm4gbGFiZWxSb3RhdGUoaXNWZXJ0aWNhbCwgbGFiZWxzR3JvdXAsIGxpbWl0TGVuZ3RoLCBmdW5jdGlvbiAobGVuZ3RoLCBtYXhXaWR0aCkge1xuICAgICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICAgICAgLy8g5aaC5p6c5rKh5pyJ6K6+572uIGxpbWl0TGVuZ3Ro77yM5YiZ5L2/55So5Zu65a6a55qE6KeS5bqm5peL6L2sXG4gICAgICAgICAgICByZXR1cm4gaXNWZXJ0aWNhbCA/IHRoZW1lXzEuZGVmYXVsdC52ZXJ0aWNhbEF4aXNSb3RhdGUgOiB0aGVtZV8xLmRlZmF1bHQuaG9yaXpvbnRhbEF4aXNSb3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVmVydGljYWwpIHtcbiAgICAgICAgICAgIC8vIOWeguebtOaXtuS4jemcgOimgeWIpOWumiBsaW1pdExlbmd0aCA+IG1heFdpZHRoIO+8jOWboOS4uuatpOaXtuS4jeS8miBvdmVybGFwXG4gICAgICAgICAgICByZXR1cm4gLU1hdGguYWNvcyhsZW5ndGggLyBtYXhXaWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgYW5nbGUgPSAwO1xuICAgICAgICAgICAgaWYgKGxlbmd0aCA+IG1heFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgLy8g6ZyA6KaB5Yik5a6a77yMYXNpbiDnmoTlj4LmlbAgLTHvvIwgMVxuICAgICAgICAgICAgICAgIGFuZ2xlID0gTWF0aC5QSSAvIDQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbmdsZSA9IE1hdGguYXNpbihsZW5ndGggLyBtYXhXaWR0aCk7XG4gICAgICAgICAgICAgICAgaWYgKGFuZ2xlID4gTWF0aC5QSSAvIDQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5aSn5LqOIE1hdGguUEkgLyA0IOaXtuayoeaEj+S5iVxuICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IE1hdGguUEkgLyA0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhbmdsZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy51bmZpeGVkQW5nbGUgPSB1bmZpeGVkQW5nbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdXRvLXJvdGF0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuYXV0b0VsbGlwc2lzID0gZXhwb3J0cy5hdXRvUm90YXRlID0gZXhwb3J0cy5hdXRvSGlkZSA9IHZvaWQgMDtcbnZhciBhdXRvRWxsaXBzaXMgPSByZXF1aXJlKFwiLi9hdXRvLWVsbGlwc2lzXCIpO1xuZXhwb3J0cy5hdXRvRWxsaXBzaXMgPSBhdXRvRWxsaXBzaXM7XG52YXIgYXV0b0hpZGUgPSByZXF1aXJlKFwiLi9hdXRvLWhpZGVcIik7XG5leHBvcnRzLmF1dG9IaWRlID0gYXV0b0hpZGU7XG52YXIgYXV0b1JvdGF0ZSA9IHJlcXVpcmUoXCIuL2F1dG8tcm90YXRlXCIpO1xuZXhwb3J0cy5hdXRvUm90YXRlID0gYXV0b1JvdGF0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ3JvdXBfY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi4vYWJzdHJhY3QvZ3JvdXAtY29tcG9uZW50XCIpO1xudmFyIG1hdHJpeF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0cml4XCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbC91dGlsXCIpO1xudmFyIENyb3NzaGFpckJhc2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ3Jvc3NoYWlyQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDcm9zc2hhaXJCYXNlKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIENyb3NzaGFpckJhc2UucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBuYW1lOiAnY3Jvc3NoYWlyJywgdHlwZTogJ2Jhc2UnLCBsaW5lOiB7fSwgdGV4dDogbnVsbCwgdGV4dEJhY2tncm91bmQ6IHt9LCBjYXB0dXJlOiBmYWxzZSwgZGVmYXVsdENmZzoge1xuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogdGhlbWVfMS5kZWZhdWx0LmxpbmVDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdzdGFydCcsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogMTAsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogdGhlbWVfMS5kZWZhdWx0LnRleHRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogdGhlbWVfMS5kZWZhdWx0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0ZXh0QmFja2dyb3VuZDoge1xuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiA1LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiB0aGVtZV8xLmRlZmF1bHQubGluZUNvbG9yLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9IH0pO1xuICAgIH07XG4gICAgQ3Jvc3NoYWlyQmFzZS5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdsaW5lJykpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyTGluZShncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZ2V0KCd0ZXh0JykpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyVGV4dChncm91cCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckJhY2tncm91bmQoZ3JvdXApO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDcm9zc2hhaXJCYXNlLnByb3RvdHlwZS5yZW5kZXJUZXh0ID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gdGhpcy5nZXQoJ3RleHQnKTtcbiAgICAgICAgdmFyIHN0eWxlID0gdGV4dC5zdHlsZSwgYXV0b1JvdGF0ZSA9IHRleHQuYXV0b1JvdGF0ZSwgY29udGVudCA9IHRleHQuY29udGVudDtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoY29udGVudCkpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0UG9pbnQgPSB0aGlzLmdldFRleHRQb2ludCgpO1xuICAgICAgICAgICAgdmFyIG1hdHJpeCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoYXV0b1JvdGF0ZSkge1xuICAgICAgICAgICAgICAgIHZhciBhbmdsZSA9IHRoaXMuZ2V0Um90YXRlQW5nbGUoKTtcbiAgICAgICAgICAgICAgICBtYXRyaXggPSBtYXRyaXhfMS5nZXRNYXRyaXhCeUFuZ2xlKHRleHRQb2ludCwgYW5nbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnY3Jvc3NoYWlyLXRleHQnLFxuICAgICAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgndGV4dCcpLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgdGV4dFBvaW50KSwgeyB0ZXh0OiBjb250ZW50LCBtYXRyaXg6IG1hdHJpeCB9KSwgc3R5bGUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENyb3NzaGFpckJhc2UucHJvdG90eXBlLnJlbmRlckxpbmUgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldExpbmVQYXRoKCk7XG4gICAgICAgIHZhciBsaW5lID0gdGhpcy5nZXQoJ2xpbmUnKTtcbiAgICAgICAgdmFyIHN0eWxlID0gbGluZS5zdHlsZTtcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgbmFtZTogJ2Nyb3NzaGFpci1saW5lJyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbGluZScpLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBwYXRoOiBwYXRoIH0sIHN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLbmlofmnKznmoTog4zmma9cbiAgICBDcm9zc2hhaXJCYXNlLnByb3RvdHlwZS5yZW5kZXJCYWNrZ3JvdW5kID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciB0ZXh0SWQgPSB0aGlzLmdldEVsZW1lbnRJZCgndGV4dCcpO1xuICAgICAgICB2YXIgdGV4dFNoYXBlID0gZ3JvdXAuZmluZEJ5SWQodGV4dElkKTsgLy8g5p+l5om+5paH5pysXG4gICAgICAgIHZhciB0ZXh0QmFja2dyb3VuZCA9IHRoaXMuZ2V0KCd0ZXh0QmFja2dyb3VuZCcpO1xuICAgICAgICBpZiAodGV4dEJhY2tncm91bmQgJiYgdGV4dFNoYXBlKSB7XG4gICAgICAgICAgICB2YXIgdGV4dEJCb3ggPSB0ZXh0U2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSB1dGlsXzIuZm9ybWF0UGFkZGluZyh0ZXh0QmFja2dyb3VuZC5wYWRkaW5nKTsgLy8g55So5oi35Lyg5YWl55qEIHBhZGRpbmcg5qC85byP5LiN5a6aXG4gICAgICAgICAgICB2YXIgc3R5bGUgPSB0ZXh0QmFja2dyb3VuZC5zdHlsZTtcbiAgICAgICAgICAgIHZhciBiYWNrZ3JvdW5kU2hhcGUgPSB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdjcm9zc2hhaXItdGV4dC1iYWNrZ3JvdW5kJyxcbiAgICAgICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3RleHQtYmFja2dyb3VuZCcpLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogdGV4dEJCb3gueCAtIHBhZGRpbmdbM10sIHk6IHRleHRCQm94LnkgLSBwYWRkaW5nWzBdLCB3aWR0aDogdGV4dEJCb3gud2lkdGggKyBwYWRkaW5nWzFdICsgcGFkZGluZ1szXSwgaGVpZ2h0OiB0ZXh0QkJveC5oZWlnaHQgKyBwYWRkaW5nWzBdICsgcGFkZGluZ1syXSwgbWF0cml4OiB0ZXh0U2hhcGUuYXR0cignbWF0cml4JykgfSwgc3R5bGUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kU2hhcGUudG9CYWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBDcm9zc2hhaXJCYXNlO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDcm9zc2hhaXJCYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBMaW5lQ3Jvc3NoYWlyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmVDcm9zc2hhaXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZUNyb3NzaGFpcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBMaW5lQ3Jvc3NoYWlyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgdHlwZTogJ2NpcmNsZScsIGxvY2F0aW9uVHlwZTogJ2NpcmNsZScsIGNlbnRlcjogbnVsbCwgcmFkaXVzOiAxMDAsIHN0YXJ0QW5nbGU6IC1NYXRoLlBJIC8gMiwgZW5kQW5nbGU6IChNYXRoLlBJICogMykgLyAyIH0pO1xuICAgIH07XG4gICAgTGluZUNyb3NzaGFpci5wcm90b3R5cGUuZ2V0Um90YXRlQW5nbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0TG9jYXRpb24oKSwgc3RhcnRBbmdsZSA9IF9hLnN0YXJ0QW5nbGUsIGVuZEFuZ2xlID0gX2EuZW5kQW5nbGU7XG4gICAgICAgIHZhciBwb3NpdGlvbiA9IHRoaXMuZ2V0KCd0ZXh0JykucG9zaXRpb247XG4gICAgICAgIHZhciB0YW5nZW50QW5nbGUgPSBwb3NpdGlvbiA9PT0gJ3N0YXJ0JyA/IHN0YXJ0QW5nbGUgKyBNYXRoLlBJIC8gMiA6IGVuZEFuZ2xlIC0gTWF0aC5QSSAvIDI7XG4gICAgICAgIHJldHVybiB0YW5nZW50QW5nbGU7XG4gICAgfTtcbiAgICBMaW5lQ3Jvc3NoYWlyLnByb3RvdHlwZS5nZXRUZXh0UG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gdGhpcy5nZXQoJ3RleHQnKTtcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gdGV4dC5wb3NpdGlvbiwgb2Zmc2V0ID0gdGV4dC5vZmZzZXQ7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0TG9jYXRpb24oKSwgY2VudGVyID0gX2EuY2VudGVyLCByYWRpdXMgPSBfYS5yYWRpdXMsIHN0YXJ0QW5nbGUgPSBfYS5zdGFydEFuZ2xlLCBlbmRBbmdsZSA9IF9hLmVuZEFuZ2xlO1xuICAgICAgICB2YXIgYW5nbGUgPSBwb3NpdGlvbiA9PT0gJ3N0YXJ0JyA/IHN0YXJ0QW5nbGUgOiBlbmRBbmdsZTtcbiAgICAgICAgdmFyIHRhbmdlbnRBbmdsZSA9IHRoaXMuZ2V0Um90YXRlQW5nbGUoKSAtIE1hdGguUEk7XG4gICAgICAgIHZhciBwb2ludCA9IHV0aWxfMS5nZXRDaXJjbGVQb2ludChjZW50ZXIsIHJhZGl1cywgYW5nbGUpO1xuICAgICAgICAvLyDov5nkuKrlnLDmlrnlhbblrp7lupTor6XmsYLliIfnur/lkJHph4/nhLblkI7lnKjkuZjku6Ugb2Zmc2V077yM5L2G5piv5aSq5ZWw5Zem5LqG77yM55u05o6l57uZ5Ye657uT5p6cXG4gICAgICAgIC8vIGNvbnN0IHRhbmdlbnQgPSBbTWF0aC5jb3ModGFuZ2VudEFuZ2xlKSwgTWF0aC5zaW4odGFuZ2VudEFuZ2xlKV07XG4gICAgICAgIC8vIGNvbnN0IG9mZnNldFZlY3RvciA9IHZlYzIuc2NhbGUoW10sIHRhbmdlbnQsIG9mZnNldCk7XG4gICAgICAgIHZhciBvZmZzZXRYID0gTWF0aC5jb3ModGFuZ2VudEFuZ2xlKSAqIG9mZnNldDtcbiAgICAgICAgdmFyIG9mZnNldFkgPSBNYXRoLnNpbih0YW5nZW50QW5nbGUpICogb2Zmc2V0O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogcG9pbnQueCArIG9mZnNldFgsXG4gICAgICAgICAgICB5OiBwb2ludC55ICsgb2Zmc2V0WSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIExpbmVDcm9zc2hhaXIucHJvdG90eXBlLmdldExpbmVQYXRoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldExvY2F0aW9uKCksIGNlbnRlciA9IF9hLmNlbnRlciwgcmFkaXVzID0gX2EucmFkaXVzLCBzdGFydEFuZ2xlID0gX2Euc3RhcnRBbmdsZSwgZW5kQW5nbGUgPSBfYS5lbmRBbmdsZTtcbiAgICAgICAgdmFyIHBhdGggPSBudWxsO1xuICAgICAgICBpZiAoZW5kQW5nbGUgLSBzdGFydEFuZ2xlID09PSBNYXRoLlBJICogMikge1xuICAgICAgICAgICAgLy8g5pW05ZyGXG4gICAgICAgICAgICB2YXIgeCA9IGNlbnRlci54LCB5ID0gY2VudGVyLnk7XG4gICAgICAgICAgICBwYXRoID0gW1xuICAgICAgICAgICAgICAgIFsnTScsIHgsIHkgLSByYWRpdXNdLFxuICAgICAgICAgICAgICAgIFsnQScsIHJhZGl1cywgcmFkaXVzLCAwLCAxLCAxLCB4LCB5ICsgcmFkaXVzXSxcbiAgICAgICAgICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgMSwgMSwgeCwgeSAtIHJhZGl1c10sXG4gICAgICAgICAgICAgICAgWydaJ10sXG4gICAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHN0YXJ0UG9pbnQgPSB1dGlsXzEuZ2V0Q2lyY2xlUG9pbnQoY2VudGVyLCByYWRpdXMsIHN0YXJ0QW5nbGUpO1xuICAgICAgICAgICAgdmFyIGVuZFBvaW50ID0gdXRpbF8xLmdldENpcmNsZVBvaW50KGNlbnRlciwgcmFkaXVzLCBlbmRBbmdsZSk7XG4gICAgICAgICAgICB2YXIgbGFyZ2UgPSBNYXRoLmFicyhlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpID4gTWF0aC5QSSA/IDEgOiAwO1xuICAgICAgICAgICAgdmFyIHN3ZWVwID0gc3RhcnRBbmdsZSA+IGVuZEFuZ2xlID8gMCA6IDE7XG4gICAgICAgICAgICBwYXRoID0gW1xuICAgICAgICAgICAgICAgIFsnTScsIHN0YXJ0UG9pbnQueCwgc3RhcnRQb2ludC55XSxcbiAgICAgICAgICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgbGFyZ2UsIHN3ZWVwLCBlbmRQb2ludC54LCBlbmRQb2ludC55XSxcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfTtcbiAgICByZXR1cm4gTGluZUNyb3NzaGFpcjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmVDcm9zc2hhaXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaXJjbGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNST1NTSEFJUl9URVhUID0gZXhwb3J0cy5DUk9TU0hBSVJfTElORSA9IGV4cG9ydHMuQ09OVEFJTkVSX0NMQVNTID0gdm9pZCAwO1xuZXhwb3J0cy5DT05UQUlORVJfQ0xBU1MgPSAnZzItY3Jvc3NoYWlyJztcbmV4cG9ydHMuQ1JPU1NIQUlSX0xJTkUgPSBleHBvcnRzLkNPTlRBSU5FUl9DTEFTUyArIFwiLWxpbmVcIjtcbmV4cG9ydHMuQ1JPU1NIQUlSX1RFWFQgPSBleHBvcnRzLkNPTlRBSU5FUl9DTEFTUyArIFwiLXRleHRcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNzcy1jb25zdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfYTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvdGhlbWVcIik7XG4vLyB0b29sdGlwIOebuOWFsyBkb20g55qEIGNzcyDnsbvlkI1cbnZhciBDc3NDb25zdCA9IHJlcXVpcmUoXCIuL2Nzcy1jb25zdFwiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IChfYSA9IHt9LFxuICAgIC8vIGNzcyBzdHlsZSBmb3IgdG9vbHRpcFxuICAgIF9hW1wiXCIgKyBDc3NDb25zdC5DT05UQUlORVJfQ0xBU1NdID0ge1xuICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJ1xuICAgIH0sXG4gICAgX2FbXCJcIiArIENzc0NvbnN0LkNST1NTSEFJUl9MSU5FXSA9IHtcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC4yNSknLFxuICAgIH0sXG4gICAgX2FbXCJcIiArIENzc0NvbnN0LkNST1NTSEFJUl9URVhUXSA9IHtcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIGNvbG9yOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICBmb250RmFtaWx5OiB0aGVtZV8xLmRlZmF1bHQuZm9udEZhbWlseSxcbiAgICB9LFxuICAgIF9hKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWh0bWwtdGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBkb21fdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L2RvbS11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgaHRtbF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9odG1sLWNvbXBvbmVudFwiKTtcbnZhciBDc3NDb25zdCA9IHJlcXVpcmUoXCIuL2Nzcy1jb25zdFwiKTtcbnZhciBodG1sX3RoZW1lXzEgPSByZXF1aXJlKFwiLi9odG1sLXRoZW1lXCIpO1xudmFyIEh0bWxDcm9zc2hhaXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSHRtbENyb3NzaGFpciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIdG1sQ3Jvc3NoYWlyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEh0bWxDcm9zc2hhaXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBuYW1lOiAnY3Jvc3NoYWlyJywgdHlwZTogJ2h0bWwnLCBsb2NhdGlvblR5cGU6ICdyZWdpb24nLCBzdGFydDogeyB4OiAwLCB5OiAwIH0sIGVuZDogeyB4OiAwLCB5OiAwIH0sIGNhcHR1cmU6IGZhbHNlLCB0ZXh0OiBudWxsLCBjb250YWluZXJUcGw6IFwiPGRpdiBjbGFzcz1cXFwiXCIgKyBDc3NDb25zdC5DT05UQUlORVJfQ0xBU1MgKyBcIlxcXCI+PC9kaXY+XCIsIGNyb3NzaGFpclRwbDogXCI8ZGl2IGNsYXNzPVxcXCJcIiArIENzc0NvbnN0LkNST1NTSEFJUl9MSU5FICsgXCJcXFwiPjwvZGl2PlwiLCB0ZXh0VHBsOiBcIjxzcGFuIGNsYXNzPVxcXCJcIiArIENzc0NvbnN0LkNST1NTSEFJUl9URVhUICsgXCJcXFwiPntjb250ZW50fTwvc3Bhbj5cIiwgZG9tU3R5bGVzOiBudWxsLCBjb250YWluZXJDbGFzc05hbWU6IENzc0NvbnN0LkNPTlRBSU5FUl9DTEFTUywgZGVmYXVsdFN0eWxlczogaHRtbF90aGVtZV8xLmRlZmF1bHQsIGRlZmF1bHRDZmc6IHtcbiAgICAgICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogMTBcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IH0pO1xuICAgIH07XG4gICAgSHRtbENyb3NzaGFpci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlc2V0VGV4dCgpO1xuICAgICAgICB0aGlzLnJlc2V0UG9zaXRpb24oKTtcbiAgICB9O1xuICAgIC8vIOe7mOWItiBjcm9zc2hhaXJcbiAgICBIdG1sQ3Jvc3NoYWlyLnByb3RvdHlwZS5pbml0Q3Jvc3NIYWlyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXRDb250YWluZXIoKTtcbiAgICAgICAgdmFyIGNyb3NzaGFpclRwbCA9IHRoaXMuZ2V0KCdjcm9zc2hhaXJUcGwnKTtcbiAgICAgICAgdmFyIGNyb3NzaGFpckVsID0gZG9tX3V0aWxfMS5jcmVhdGVEb20oY3Jvc3NoYWlyVHBsKTtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNyb3NzaGFpckVsKTtcbiAgICAgICAgdGhpcy5hcHBseVN0eWxlKENzc0NvbnN0LkNST1NTSEFJUl9MSU5FLCBjcm9zc2hhaXJFbCk7XG4gICAgICAgIHRoaXMuc2V0KCdjcm9zc2hhaXJFbCcsIGNyb3NzaGFpckVsKTtcbiAgICB9O1xuICAgIC8vIOiOt+WPluaWh+acrOeahOS9jee9rlxuICAgIEh0bWxDcm9zc2hhaXIucHJvdG90eXBlLmdldFRleHRQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRMb2NhdGlvbigpLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIHZhciBfYiA9IHRoaXMuZ2V0KCd0ZXh0JyksIHBvc2l0aW9uID0gX2IucG9zaXRpb24sIG9mZnNldCA9IF9iLm9mZnNldDtcbiAgICAgICAgcmV0dXJuIHV0aWxfMi5nZXRUZXh0UG9pbnQoc3RhcnQsIGVuZCwgcG9zaXRpb24sIG9mZnNldCk7XG4gICAgfTtcbiAgICAvLyDorr7nva4gdGV4dFxuICAgIEh0bWxDcm9zc2hhaXIucHJvdG90eXBlLnJlc2V0VGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRleHQgPSB0aGlzLmdldCgndGV4dCcpO1xuICAgICAgICB2YXIgdGV4dEVsID0gdGhpcy5nZXQoJ3RleHRFbCcpO1xuICAgICAgICBpZiAodGV4dCkge1xuICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSB0ZXh0LmNvbnRlbnQ7XG4gICAgICAgICAgICBpZiAoIXRleHRFbCkge1xuICAgICAgICAgICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldENvbnRhaW5lcigpO1xuICAgICAgICAgICAgICAgIHZhciB0ZXh0VHBsID0gdXRpbF8xLnN1YnN0aXR1dGUodGhpcy5nZXQoJ3RleHRUcGwnKSwgdGV4dCk7XG4gICAgICAgICAgICAgICAgdGV4dEVsID0gZG9tX3V0aWxfMS5jcmVhdGVEb20odGV4dFRwbCk7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHRleHRFbCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseVN0eWxlKENzc0NvbnN0LkNST1NTSEFJUl9URVhULCB0ZXh0RWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0KCd0ZXh0RWwnLCB0ZXh0RWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGV4dEVsLmlubmVySFRNTCA9IGNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGV4dEVsKSB7XG4gICAgICAgICAgICB0ZXh0RWwucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOaYr+WQpuWeguebtFxuICAgIEh0bWxDcm9zc2hhaXIucHJvdG90eXBlLmlzVmVydGljYWwgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICAgICAgICByZXR1cm4gc3RhcnQueCA9PT0gZW5kLng7XG4gICAgfTtcbiAgICAvLyDph43mlrDosIPmlbTkvY3nva5cbiAgICBIdG1sQ3Jvc3NoYWlyLnByb3RvdHlwZS5yZXNldFBvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3Jvc3NoYWlyRWwgPSB0aGlzLmdldCgnY3Jvc3NoYWlyRWwnKTtcbiAgICAgICAgaWYgKCFjcm9zc2hhaXJFbCkge1xuICAgICAgICAgICAgdGhpcy5pbml0Q3Jvc3NIYWlyKCk7XG4gICAgICAgICAgICBjcm9zc2hhaXJFbCA9IHRoaXMuZ2V0KCdjcm9zc2hhaXJFbCcpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuZ2V0KCdzdGFydCcpO1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5nZXQoJ2VuZCcpO1xuICAgICAgICB2YXIgbWluWCA9IE1hdGgubWluKHN0YXJ0LngsIGVuZC54KTtcbiAgICAgICAgdmFyIG1pblkgPSBNYXRoLm1pbihzdGFydC55LCBlbmQueSk7XG4gICAgICAgIGlmICh0aGlzLmlzVmVydGljYWwoc3RhcnQsIGVuZCkpIHtcbiAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGNyb3NzaGFpckVsLCB7XG4gICAgICAgICAgICAgICAgd2lkdGg6ICcxcHgnLFxuICAgICAgICAgICAgICAgIGhlaWdodDogdXRpbF8yLnRvUHgoTWF0aC5hYnMoZW5kLnkgLSBzdGFydC55KSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoY3Jvc3NoYWlyRWwsIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6ICcxcHgnLFxuICAgICAgICAgICAgICAgIHdpZHRoOiB1dGlsXzIudG9QeChNYXRoLmFicyhlbmQueCAtIHN0YXJ0LngpKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoY3Jvc3NoYWlyRWwsIHtcbiAgICAgICAgICAgIHRvcDogdXRpbF8yLnRvUHgobWluWSksXG4gICAgICAgICAgICBsZWZ0OiB1dGlsXzIudG9QeChtaW5YKVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hbGlnblRleHQoKTtcbiAgICB9O1xuICAgIEh0bWxDcm9zc2hhaXIucHJvdG90eXBlLmFsaWduVGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g6YeN5paw6K6+572uIHRleHQg5L2N572uXG4gICAgICAgIHZhciB0ZXh0RWwgPSB0aGlzLmdldCgndGV4dEVsJyk7XG4gICAgICAgIGlmICh0ZXh0RWwpIHtcbiAgICAgICAgICAgIHZhciBhbGlnbiA9IHRoaXMuZ2V0KCd0ZXh0JykuYWxpZ247XG4gICAgICAgICAgICB2YXIgY2xpZW50V2lkdGggPSB0ZXh0RWwuY2xpZW50V2lkdGg7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSB0aGlzLmdldFRleHRQb2ludCgpO1xuICAgICAgICAgICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICAgICAgICAgICAgICAgIHBvaW50LnggPSBwb2ludC54IC0gY2xpZW50V2lkdGggLyAyO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgICAgIHBvaW50LnggPSBwb2ludC54IC0gY2xpZW50V2lkdGg7XG4gICAgICAgICAgICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1ModGV4dEVsLCB7XG4gICAgICAgICAgICAgICAgdG9wOiB1dGlsXzIudG9QeChwb2ludC55KSxcbiAgICAgICAgICAgICAgICBsZWZ0OiB1dGlsXzIudG9QeChwb2ludC54KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEh0bWxDcm9zc2hhaXIucHJvdG90eXBlLnVwZGF0ZUlubmVyID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICBpZiAodXRpbF8xLmhhc0tleShjZmcsICd0ZXh0JykpIHtcbiAgICAgICAgICAgIHRoaXMucmVzZXRUZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS51cGRhdGVJbm5lci5jYWxsKHRoaXMsIGNmZyk7XG4gICAgfTtcbiAgICByZXR1cm4gSHRtbENyb3NzaGFpcjtcbn0oaHRtbF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIdG1sQ3Jvc3NoYWlyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aHRtbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBsaW5lXzEgPSByZXF1aXJlKFwiLi9saW5lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTGluZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGluZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgY2lyY2xlXzEgPSByZXF1aXJlKFwiLi9jaXJjbGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDaXJjbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNpcmNsZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJhc2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGh0bWxfMSA9IHJlcXVpcmUoXCIuL2h0bWxcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJIdG1sXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBodG1sXzEuZGVmYXVsdDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIExpbmVDcm9zc2hhaXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTGluZUNyb3NzaGFpciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaW5lQ3Jvc3NoYWlyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIExpbmVDcm9zc2hhaXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyB0eXBlOiAnbGluZScsIGxvY2F0aW9uVHlwZTogJ3JlZ2lvbicsIHN0YXJ0OiBudWxsLCBlbmQ6IG51bGwgfSk7XG4gICAgfTtcbiAgICAvLyDnm7Tnur/nmoTmlofmnKzpnIDopoHlkIznm7Tnur/lnoLnm7RcbiAgICBMaW5lQ3Jvc3NoYWlyLnByb3RvdHlwZS5nZXRSb3RhdGVBbmdsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRMb2NhdGlvbigpLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIHZhciBwb3NpdGlvbiA9IHRoaXMuZ2V0KCd0ZXh0JykucG9zaXRpb247XG4gICAgICAgIHZhciBhbmdsZSA9IE1hdGguYXRhbjIoZW5kLnkgLSBzdGFydC55LCBlbmQueCAtIHN0YXJ0LngpO1xuICAgICAgICB2YXIgdGFuZ2VudEFuZ2xlID0gcG9zaXRpb24gPT09ICdzdGFydCcgPyBhbmdsZSAtIE1hdGguUEkgLyAyIDogYW5nbGUgKyBNYXRoLlBJIC8gMjtcbiAgICAgICAgcmV0dXJuIHRhbmdlbnRBbmdsZTtcbiAgICB9O1xuICAgIExpbmVDcm9zc2hhaXIucHJvdG90eXBlLmdldFRleHRQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRMb2NhdGlvbigpLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIHZhciBfYiA9IHRoaXMuZ2V0KCd0ZXh0JyksIHBvc2l0aW9uID0gX2IucG9zaXRpb24sIG9mZnNldCA9IF9iLm9mZnNldDtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5nZXRUZXh0UG9pbnQoc3RhcnQsIGVuZCwgcG9zaXRpb24sIG9mZnNldCk7XG4gICAgfTtcbiAgICBMaW5lQ3Jvc3NoYWlyLnByb3RvdHlwZS5nZXRMaW5lUGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRMb2NhdGlvbigpLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCBzdGFydC54LCBzdGFydC55XSxcbiAgICAgICAgICAgIFsnTCcsIGVuZC54LCBlbmQueV0sXG4gICAgICAgIF07XG4gICAgfTtcbiAgICByZXR1cm4gTGluZUNyb3NzaGFpcjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmVDcm9zc2hhaXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ3JvdXBfY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi4vYWJzdHJhY3QvZ3JvdXAtY29tcG9uZW50XCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciBHcmlkQmFzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcmlkQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBHcmlkQmFzZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBHcmlkQmFzZS5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IG5hbWU6ICdncmlkJywgbGluZToge30sIGFsdGVybmF0ZUNvbG9yOiBudWxsLCBjYXB0dXJlOiBmYWxzZSwgaXRlbXM6IFtdLCBjbG9zZWQ6IGZhbHNlLCBkZWZhdWx0Q2ZnOiB7XG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoZW1lXzEuZGVmYXVsdC5saW5lQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0gfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmoIXmoLznur/nmoTnsbvlnotcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IOagheagvOe6v+exu+Wei1xuICAgICAqL1xuICAgIEdyaWRCYXNlLnByb3RvdHlwZS5nZXRMaW5lVHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxpbmUgPSB0aGlzLmdldCgnbGluZScpIHx8IHRoaXMuZ2V0KCdkZWZhdWx0Q2ZnJykubGluZTtcbiAgICAgICAgcmV0dXJuIGxpbmUudHlwZTtcbiAgICB9O1xuICAgIEdyaWRCYXNlLnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB0aGlzLmRyYXdHcmlkKGdyb3VwKTtcbiAgICB9O1xuICAgIEdyaWRCYXNlLnByb3RvdHlwZS5nZXRBbHRlcm5hdGVQYXRoID0gZnVuY3Rpb24gKHByZVBvaW50cywgcG9pbnRzKSB7XG4gICAgICAgIHZhciByZWdpb25QYXRoID0gdGhpcy5nZXRHcmlkUGF0aChwcmVQb2ludHMpO1xuICAgICAgICB2YXIgcmV2ZXJzZVBvaW50cyA9IHBvaW50cy5zbGljZSgwKS5yZXZlcnNlKCk7XG4gICAgICAgIHZhciBuZXh0UGF0aCA9IHRoaXMuZ2V0R3JpZFBhdGgocmV2ZXJzZVBvaW50cywgdHJ1ZSk7XG4gICAgICAgIHZhciBjbG9zZWQgPSB0aGlzLmdldCgnY2xvc2VkJyk7XG4gICAgICAgIGlmIChjbG9zZWQpIHtcbiAgICAgICAgICAgIHJlZ2lvblBhdGggPSByZWdpb25QYXRoLmNvbmNhdChuZXh0UGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBuZXh0UGF0aFswXVswXSA9ICdMJzsgLy8g5pu05paw56ys5LiA5Liq6IqC54K5XG4gICAgICAgICAgICByZWdpb25QYXRoID0gcmVnaW9uUGF0aC5jb25jYXQobmV4dFBhdGgpO1xuICAgICAgICAgICAgcmVnaW9uUGF0aC5wdXNoKFsnWiddKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVnaW9uUGF0aDtcbiAgICB9O1xuICAgIC8vIOiOt+WPlui3r+W+hOeahOmFjee9rumhuVxuICAgIEdyaWRCYXNlLnByb3RvdHlwZS5nZXRQYXRoU3R5bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnbGluZScpLnN0eWxlO1xuICAgIH07XG4gICAgLy8g57uY5Yi25qCF5qC8XG4gICAgR3JpZEJhc2UucHJvdG90eXBlLmRyYXdHcmlkID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBsaW5lID0gdGhpcy5nZXQoJ2xpbmUnKTtcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5nZXQoJ2l0ZW1zJyk7XG4gICAgICAgIHZhciBhbHRlcm5hdGVDb2xvciA9IHRoaXMuZ2V0KCdhbHRlcm5hdGVDb2xvcicpO1xuICAgICAgICB2YXIgcHJlSXRlbSA9IG51bGw7XG4gICAgICAgIHV0aWxfMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBpZCA9IGl0ZW0uaWQgfHwgaW5kZXg7XG4gICAgICAgICAgICAvLyDnu5jliLbmoIXmoLznur9cbiAgICAgICAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gX3RoaXMuZ2V0UGF0aFN0eWxlKCk7XG4gICAgICAgICAgICAgICAgdmFyIGxpbmVJZCA9IF90aGlzLmdldEVsZW1lbnRJZChcImxpbmUtXCIgKyBpZCk7XG4gICAgICAgICAgICAgICAgdmFyIGdyaWRQYXRoID0gX3RoaXMuZ2V0R3JpZFBhdGgoaXRlbS5wb2ludHMpO1xuICAgICAgICAgICAgICAgIF90aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2dyaWQtbGluZScsXG4gICAgICAgICAgICAgICAgICAgIGlkOiBsaW5lSWQsXG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEubWl4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IGdyaWRQYXRoLFxuICAgICAgICAgICAgICAgICAgICB9LCBzdHlsZSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDlpoLmnpzlrZjlnKggYWx0ZXJuYXRlQ29sb3Ig5YiZ57uY5Yi255+p5b2iXG4gICAgICAgICAgICAvLyDku47nrKzkuozkuKrmoIXmoLznur/lvIDlp4vnu5jliLZcbiAgICAgICAgICAgIGlmIChhbHRlcm5hdGVDb2xvciAmJiBpbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVnaW9uSWQgPSBfdGhpcy5nZXRFbGVtZW50SWQoXCJyZWdpb24tXCIgKyBpZCk7XG4gICAgICAgICAgICAgICAgdmFyIGlzRXZlbiA9IGluZGV4ICUgMiA9PT0gMDtcbiAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGFsdGVybmF0ZUNvbG9yKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzpopzoibLmmK/ljZXlgLzvvIzliJnmmK/ku4Xnu5jliLblgbbmlbDml7bnmoTljLrln59cbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRXZlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuZHJhd0FsdGVybmF0ZVJlZ2lvbihyZWdpb25JZCwgZ3JvdXAsIHByZUl0ZW0ucG9pbnRzLCBpdGVtLnBvaW50cywgYWx0ZXJuYXRlQ29sb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSBpc0V2ZW4gPyBhbHRlcm5hdGVDb2xvclsxXSA6IGFsdGVybmF0ZUNvbG9yWzBdO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5kcmF3QWx0ZXJuYXRlUmVnaW9uKHJlZ2lvbklkLCBncm91cCwgcHJlSXRlbS5wb2ludHMsIGl0ZW0ucG9pbnRzLCBjb2xvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJlSXRlbSA9IGl0ZW07XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g57uY5Yi25qCF5qC857q/6Ze055qE6Ze06ZqUXG4gICAgR3JpZEJhc2UucHJvdG90eXBlLmRyYXdBbHRlcm5hdGVSZWdpb24gPSBmdW5jdGlvbiAoaWQsIGdyb3VwLCBwcmVQb2ludHMsIHBvaW50cywgY29sb3IpIHtcbiAgICAgICAgdmFyIHJlZ2lvblBhdGggPSB0aGlzLmdldEFsdGVybmF0ZVBhdGgocHJlUG9pbnRzLCBwb2ludHMpO1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICBuYW1lOiAnZ3JpZC1yZWdpb24nLFxuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICBwYXRoOiByZWdpb25QYXRoLFxuICAgICAgICAgICAgICAgIGZpbGw6IGNvbG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gR3JpZEJhc2U7XG59KGdyb3VwX2NvbXBvbmVudF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdyaWRCYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG5mdW5jdGlvbiBkaXN0YW5jZSh4MSwgeTEsIHgyLCB5Mikge1xuICAgIHZhciBkeCA9IHgyIC0geDE7XG4gICAgdmFyIGR5ID0geTIgLSB5MTtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbn1cbnZhciBDaXJjbGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2lyY2xlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENpcmNsZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBDaXJjbGUucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyB0eXBlOiAnY2lyY2xlJywgXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIOS4reW/g+eCuVxuICAgICAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY2VudGVyOiBudWxsLCBcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICog5qCF5qC857q/5piv5ZCm5bCB6ZetXG4gICAgICAgICAgICAgKiBAdHlwZSB7dHJ1ZX1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY2xvc2VkOiB0cnVlIH0pO1xuICAgIH07XG4gICAgQ2lyY2xlLnByb3RvdHlwZS5nZXRHcmlkUGF0aCA9IGZ1bmN0aW9uIChwb2ludHMsIHJldmVyc2VkKSB7XG4gICAgICAgIHZhciBsaW5lVHlwZSA9IHRoaXMuZ2V0TGluZVR5cGUoKTtcbiAgICAgICAgdmFyIGNsb3NlZCA9IHRoaXMuZ2V0KCdjbG9zZWQnKTtcbiAgICAgICAgdmFyIHBhdGggPSBbXTtcbiAgICAgICAgaWYgKHBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIOmYsuatouWHuumUmVxuICAgICAgICAgICAgaWYgKGxpbmVUeXBlID09PSAnY2lyY2xlJykge1xuICAgICAgICAgICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLmdldCgnY2VudGVyJyk7XG4gICAgICAgICAgICAgICAgdmFyIGZpcnN0UG9pbnQgPSBwb2ludHNbMF07XG4gICAgICAgICAgICAgICAgdmFyIHJhZGl1c18xID0gZGlzdGFuY2UoY2VudGVyLngsIGNlbnRlci55LCBmaXJzdFBvaW50LngsIGZpcnN0UG9pbnQueSk7XG4gICAgICAgICAgICAgICAgdmFyIHN3ZWVwRmxhZ18xID0gcmV2ZXJzZWQgPyAwIDogMTsgLy8g6aG65pe26ZKI6L+Y5piv6YCG5pe26ZKIXG4gICAgICAgICAgICAgICAgaWYgKGNsb3NlZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlsIHpl63ml7bvvIznu5jliLbmlbTkuKrlnIZcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIGNlbnRlci54LCBjZW50ZXIueSAtIHJhZGl1c18xXSk7XG4gICAgICAgICAgICAgICAgICAgIHBhdGgucHVzaChbJ0EnLCByYWRpdXNfMSwgcmFkaXVzXzEsIDAsIDAsIHN3ZWVwRmxhZ18xLCBjZW50ZXIueCwgY2VudGVyLnkgKyByYWRpdXNfMV0pO1xuICAgICAgICAgICAgICAgICAgICBwYXRoLnB1c2goWydBJywgcmFkaXVzXzEsIHJhZGl1c18xLCAwLCAwLCBzd2VlcEZsYWdfMSwgY2VudGVyLngsIGNlbnRlci55IC0gcmFkaXVzXzFdKTtcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKFsnWiddKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50LngsIHBvaW50LnldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgucHVzaChbJ0EnLCByYWRpdXNfMSwgcmFkaXVzXzEsIDAsIDAsIHN3ZWVwRmxhZ18xLCBwb2ludC54LCBwb2ludC55XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCBwb2ludC54LCBwb2ludC55XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoLnB1c2goWydMJywgcG9pbnQueCwgcG9pbnQueV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGNsb3NlZCkge1xuICAgICAgICAgICAgICAgICAgICBwYXRoLnB1c2goWydaJ10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIHJldHVybiBDaXJjbGU7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDaXJjbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaXJjbGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJhc2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGNpcmNsZV8xID0gcmVxdWlyZShcIi4vY2lyY2xlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ2lyY2xlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjaXJjbGVfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGxpbmVfMSA9IHJlcXVpcmUoXCIuL2xpbmVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJMaW5lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaW5lXzEuZGVmYXVsdDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBMaW5lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBMaW5lLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgdHlwZTogJ2xpbmUnIH0pO1xuICAgIH07XG4gICAgTGluZS5wcm90b3R5cGUuZ2V0R3JpZFBhdGggPSBmdW5jdGlvbiAocG9pbnRzKSB7XG4gICAgICAgIHZhciBwYXRoID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50LngsIHBvaW50LnldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCBwb2ludC54LCBwb2ludC55XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIHJldHVybiBMaW5lO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNyb3NzaGFpciA9IGV4cG9ydHMuVG9vbHRpcCA9IGV4cG9ydHMuTGVnZW5kID0gZXhwb3J0cy5HcmlkID0gZXhwb3J0cy5Bbm5vdGF0aW9uID0gZXhwb3J0cy5BeGlzID0gdm9pZCAwO1xudmFyIEFubm90YXRpb24gPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uXCIpO1xuZXhwb3J0cy5Bbm5vdGF0aW9uID0gQW5ub3RhdGlvbjtcbnZhciBBeGlzID0gcmVxdWlyZShcIi4vYXhpc1wiKTtcbmV4cG9ydHMuQXhpcyA9IEF4aXM7XG52YXIgQ3Jvc3NoYWlyID0gcmVxdWlyZShcIi4vY3Jvc3NoYWlyXCIpO1xuZXhwb3J0cy5Dcm9zc2hhaXIgPSBDcm9zc2hhaXI7XG52YXIgR3JpZCA9IHJlcXVpcmUoXCIuL2dyaWRcIik7XG5leHBvcnRzLkdyaWQgPSBHcmlkO1xudmFyIExlZ2VuZCA9IHJlcXVpcmUoXCIuL2xlZ2VuZFwiKTtcbmV4cG9ydHMuTGVnZW5kID0gTGVnZW5kO1xudmFyIFRvb2x0aXAgPSByZXF1aXJlKFwiLi90b29sdGlwXCIpO1xuZXhwb3J0cy5Ub29sdGlwID0gVG9vbHRpcDtcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2Fic3RyYWN0L2NvbXBvbmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbXBvbmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29tcG9uZW50XzEuZGVmYXVsdDsgfSB9KTtcbnZhciBncm91cF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkdyb3VwQ29tcG9uZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBncm91cF9jb21wb25lbnRfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGh0bWxfY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9hYnN0cmFjdC9odG1sLWNvbXBvbmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkh0bWxDb21wb25lbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGh0bWxfY29tcG9uZW50XzEuZGVmYXVsdDsgfSB9KTtcbnZhciBzbGlkZXJfMSA9IHJlcXVpcmUoXCIuL3NsaWRlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNsaWRlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2xpZGVyXzEuU2xpZGVyOyB9IH0pO1xudmFyIHNjcm9sbGJhcl8xID0gcmVxdWlyZShcIi4vc2Nyb2xsYmFyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU2Nyb2xsYmFyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzY3JvbGxiYXJfMS5TY3JvbGxiYXI7IH0gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdyb3VwX2NvbXBvbmVudF8xID0gcmVxdWlyZShcIi4uL2Fic3RyYWN0L2dyb3VwLWNvbXBvbmVudFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbC91dGlsXCIpO1xudmFyIExlZ2VuZEJhc2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTGVnZW5kQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMZWdlbmRCYXNlKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIExlZ2VuZEJhc2UucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBuYW1lOiAnbGVnZW5kJywgXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIOW4g+WxgOaWueW8j++8miBob3Jpem9udGFs77yMdmVydGljYWxcbiAgICAgICAgICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGxheW91dDogJ2hvcml6b250YWwnLCBsb2NhdGlvblR5cGU6ICdwb2ludCcsIHg6IDAsIHk6IDAsIG9mZnNldFg6IDAsIG9mZnNldFk6IDAsIHRpdGxlOiBudWxsLCBiYWNrZ3JvdW5kOiBudWxsIH0pO1xuICAgIH07XG4gICAgTGVnZW5kQmFzZS5wcm90b3R5cGUuZ2V0TGF5b3V0QkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGJib3ggPSBfc3VwZXIucHJvdG90eXBlLmdldExheW91dEJCb3guY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIHggPSB0aGlzLmdldCgneCcpO1xuICAgICAgICB2YXIgeSA9IHRoaXMuZ2V0KCd5Jyk7XG4gICAgICAgIHZhciBvZmZzZXRYID0gdGhpcy5nZXQoJ29mZnNldFgnKTtcbiAgICAgICAgdmFyIG9mZnNldFkgPSB0aGlzLmdldCgnb2Zmc2V0WScpO1xuICAgICAgICB2YXIgbWF4V2lkdGggPSB0aGlzLmdldCgnbWF4V2lkdGgnKTtcbiAgICAgICAgdmFyIG1heEhlaWdodCA9IHRoaXMuZ2V0KCdtYXhIZWlnaHQnKTtcbiAgICAgICAgdmFyIG1pblggPSB4ICsgb2Zmc2V0WDtcbiAgICAgICAgdmFyIG1pblkgPSB5ICsgb2Zmc2V0WTtcbiAgICAgICAgdmFyIHdpZHRoID0gYmJveC5tYXhYIC0gbWluWDtcbiAgICAgICAgdmFyIGhlaWdodCA9IGJib3gubWF4WSAtIG1pblk7XG4gICAgICAgIGlmIChtYXhXaWR0aCkge1xuICAgICAgICAgICAgd2lkdGggPSBNYXRoLm1pbih3aWR0aCwgbWF4V2lkdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXhIZWlnaHQpIHtcbiAgICAgICAgICAgIGhlaWdodCA9IE1hdGgubWluKGhlaWdodCwgbWF4SGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXRpbF8xLmNyZWF0ZUJCb3gobWluWCwgbWluWSwgd2lkdGgsIGhlaWdodCk7XG4gICAgfTtcbiAgICBMZWdlbmRCYXNlLnByb3RvdHlwZS5zZXRMb2NhdGlvbiA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgdGhpcy5zZXQoJ3gnLCBjZmcueCk7XG4gICAgICAgIHRoaXMuc2V0KCd5JywgY2ZnLnkpO1xuICAgICAgICB0aGlzLnJlc2V0TG9jYXRpb24oKTtcbiAgICB9O1xuICAgIExlZ2VuZEJhc2UucHJvdG90eXBlLnJlc2V0TG9jYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4ID0gdGhpcy5nZXQoJ3gnKTtcbiAgICAgICAgdmFyIHkgPSB0aGlzLmdldCgneScpO1xuICAgICAgICB2YXIgb2Zmc2V0WCA9IHRoaXMuZ2V0KCdvZmZzZXRYJyk7XG4gICAgICAgIHZhciBvZmZzZXRZID0gdGhpcy5nZXQoJ29mZnNldFknKTtcbiAgICAgICAgdGhpcy5tb3ZlRWxlbWVudFRvKHRoaXMuZ2V0KCdncm91cCcpLCB7XG4gICAgICAgICAgICB4OiB4ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgIHk6IHkgKyBvZmZzZXRZLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExlZ2VuZEJhc2UucHJvdG90eXBlLmFwcGx5T2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlc2V0TG9jYXRpb24oKTtcbiAgICB9O1xuICAgIC8vIOiOt+WPluW9k+WJjee7mOWItueahOeCuVxuICAgIExlZ2VuZEJhc2UucHJvdG90eXBlLmdldERyYXdQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCdjdXJyZW50UG9pbnQnKTtcbiAgICB9O1xuICAgIExlZ2VuZEJhc2UucHJvdG90eXBlLnNldERyYXdQb2ludCA9IGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXQoJ2N1cnJlbnRQb2ludCcsIHBvaW50KTtcbiAgICB9O1xuICAgIC8vIOWkjeWGmeeItuexu+WumuS5ieeahOe7mOWItuaWueazlVxuICAgIExlZ2VuZEJhc2UucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHRoaXMucmVzZXREcmF3KCk7XG4gICAgICAgIGlmICh0aGlzLmdldCgndGl0bGUnKSkge1xuICAgICAgICAgICAgdGhpcy5kcmF3VGl0bGUoZ3JvdXApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZHJhd0xlZ2VuZENvbnRlbnQoZ3JvdXApO1xuICAgICAgICBpZiAodGhpcy5nZXQoJ2JhY2tncm91bmQnKSkge1xuICAgICAgICAgICAgdGhpcy5kcmF3QmFja2dyb3VuZChncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhpcy5yZXNldExvY2F0aW9uKCk7IC8vIOWcqOmhtuWxguW3sue7j+WcqOWkhOeQhuWBj+enu+aXtuS4gOi1t+WkhOeQhuS6hlxuICAgIH07XG4gICAgLy8g57uY5Yi26IOM5pmvXG4gICAgTGVnZW5kQmFzZS5wcm90b3R5cGUuZHJhd0JhY2tncm91bmQgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIGJhY2tncm91bmQgPSB0aGlzLmdldCgnYmFja2dyb3VuZCcpO1xuICAgICAgICB2YXIgYmJveCA9IGdyb3VwLmdldEJCb3goKTtcbiAgICAgICAgdmFyIHBhZGRpbmcgPSB1dGlsXzEuZm9ybWF0UGFkZGluZyhiYWNrZ3JvdW5kLnBhZGRpbmcpO1xuICAgICAgICB2YXIgYXR0cnMgPSB0c2xpYl8xLl9fYXNzaWduKHsgXG4gICAgICAgICAgICAvLyDog4zmma/ku44gKDAsMCkg5byA5aeL57uY5Yi2XG4gICAgICAgICAgICB4OiAwLCB5OiAwLCB3aWR0aDogYmJveC53aWR0aCArIHBhZGRpbmdbMV0gKyBwYWRkaW5nWzNdLCBoZWlnaHQ6IGJib3guaGVpZ2h0ICsgcGFkZGluZ1swXSArIHBhZGRpbmdbMl0gfSwgYmFja2dyb3VuZC5zdHlsZSk7XG4gICAgICAgIHZhciBiYWNrZ3JvdW5kU2hhcGUgPSB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ2JhY2tncm91bmQnKSxcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtYmFja2dyb3VuZCcsXG4gICAgICAgICAgICBhdHRyczogYXR0cnMsXG4gICAgICAgIH0pO1xuICAgICAgICBiYWNrZ3JvdW5kU2hhcGUudG9CYWNrKCk7XG4gICAgfTtcbiAgICAvLyDnu5jliLbmoIfpopjvvIzmoIfpopjlnKjlm77kvovpobnnmoTkuIrpnaJcbiAgICBMZWdlbmRCYXNlLnByb3RvdHlwZS5kcmF3VGl0bGUgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIGN1cnJlbnRQb2ludCA9IHRoaXMuZ2V0KCdjdXJyZW50UG9pbnQnKTtcbiAgICAgICAgdmFyIHRpdGxlQ2ZnID0gdGhpcy5nZXQoJ3RpdGxlJyk7XG4gICAgICAgIHZhciBzcGFjaW5nID0gdGl0bGVDZmcuc3BhY2luZywgc3R5bGUgPSB0aXRsZUNmZy5zdHlsZSwgdGV4dCA9IHRpdGxlQ2ZnLnRleHQ7XG4gICAgICAgIHZhciBzaGFwZSA9IHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgndGl0bGUnKSxcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtdGl0bGUnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB0ZXh0OiB0ZXh0LCB4OiBjdXJyZW50UG9pbnQueCwgeTogY3VycmVudFBvaW50LnkgfSwgc3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGJib3ggPSBzaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIC8vIOagh+mimOWNleeLrOWcqOS4gOihjFxuICAgICAgICB0aGlzLnNldCgnY3VycmVudFBvaW50JywgeyB4OiBjdXJyZW50UG9pbnQueCwgeTogYmJveC5tYXhZICsgc3BhY2luZyB9KTtcbiAgICB9O1xuICAgIC8vIOmHjee9rue7mOWItuaXtuW8gOWni+eahOS9jee9ru+8jOWmguaenOe7mOWItui+ueahhu+8jOiAg+iZkei+ueahhueahCBwYWRkaW5nXG4gICAgTGVnZW5kQmFzZS5wcm90b3R5cGUucmVzZXREcmF3ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYmFja2dyb3VuZCA9IHRoaXMuZ2V0KCdiYWNrZ3JvdW5kJyk7XG4gICAgICAgIHZhciBjdXJyZW50UG9pbnQgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgaWYgKGJhY2tncm91bmQpIHtcbiAgICAgICAgICAgIHZhciBwYWRkaW5nID0gdXRpbF8xLmZvcm1hdFBhZGRpbmcoYmFja2dyb3VuZC5wYWRkaW5nKTtcbiAgICAgICAgICAgIGN1cnJlbnRQb2ludC54ID0gcGFkZGluZ1szXTsgLy8g5bem6L65IHBhZGRpbmdcbiAgICAgICAgICAgIGN1cnJlbnRQb2ludC55ID0gcGFkZGluZ1swXTsgLy8g5LiK6Z2iIHBhZGRpbmdcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldCgnY3VycmVudFBvaW50JywgY3VycmVudFBvaW50KTsgLy8g6K6+572u57uY5Yi255qE5Yid5aeL5L2N572uXG4gICAgfTtcbiAgICByZXR1cm4gTGVnZW5kQmFzZTtcbn0oZ3JvdXBfY29tcG9uZW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGVnZW5kQmFzZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbGFiZWxcIik7XG52YXIgbWF0cml4XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9tYXRyaXhcIik7XG52YXIgc3RhdGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3N0YXRlXCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIENhdGVnb3J5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENhdGVnb3J5LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENhdGVnb3J5KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuY3VycmVudFBhZ2VJbmRleCA9IDE7XG4gICAgICAgIF90aGlzLnRvdGFsUGFnZXNDbnQgPSAxO1xuICAgICAgICBfdGhpcy5wYWdlV2lkdGggPSAwO1xuICAgICAgICBfdGhpcy5wYWdlSGVpZ2h0ID0gMDtcbiAgICAgICAgX3RoaXMuc3RhcnRYID0gMDtcbiAgICAgICAgX3RoaXMuc3RhcnRZID0gMDtcbiAgICAgICAgX3RoaXMub25OYXZpZ2F0aW9uQmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpdGVtR3JvdXAgPSBfdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCdpdGVtLWdyb3VwJyk7XG4gICAgICAgICAgICBpZiAoX3RoaXMuY3VycmVudFBhZ2VJbmRleCA+IDEpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50UGFnZUluZGV4IC09IDE7XG4gICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlTmF2aWdhdGlvbigpO1xuICAgICAgICAgICAgICAgIHZhciBtYXRyaXggPSBfdGhpcy5nZXRDdXJyZW50TmF2aWdhdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5nZXQoJ2FuaW1hdGUnKSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtR3JvdXAuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXg6IG1hdHJpeCxcbiAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1Hcm91cC5hdHRyKHsgbWF0cml4OiBtYXRyaXggfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5vbk5hdmlnYXRpb25BZnRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpdGVtR3JvdXAgPSBfdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCdpdGVtLWdyb3VwJyk7XG4gICAgICAgICAgICBpZiAoX3RoaXMuY3VycmVudFBhZ2VJbmRleCA8IF90aGlzLnRvdGFsUGFnZXNDbnQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50UGFnZUluZGV4ICs9IDE7XG4gICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlTmF2aWdhdGlvbigpO1xuICAgICAgICAgICAgICAgIHZhciBtYXRyaXggPSBfdGhpcy5nZXRDdXJyZW50TmF2aWdhdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5nZXQoJ2FuaW1hdGUnKSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtR3JvdXAuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXg6IG1hdHJpeCxcbiAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1Hcm91cC5hdHRyKHsgbWF0cml4OiBtYXRyaXggfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIENhdGVnb3J5LnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ2xlZ2VuZCcsIHR5cGU6ICdjYXRlZ29yeScsIGl0ZW1TcGFjaW5nOiAyNCwgbWF4SXRlbVdpZHRoOiBudWxsLCBpdGVtV2lkdGg6IG51bGwsIGl0ZW1IZWlnaHQ6IG51bGwsIGl0ZW1OYW1lOiB7fSwgaXRlbVZhbHVlOiBudWxsLCBtYXhXaWR0aDogbnVsbCwgbWF4SGVpZ2h0OiBudWxsLCBtYXJrZXI6IHt9LCBpdGVtczogW10sIGl0ZW1TdGF0ZXM6IHt9LCBpdGVtQmFja2dyb3VuZDoge30sIGRlZmF1bHRDZmc6IHtcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICBzcGFjaW5nOiA1LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogdGhlbWVfMS5kZWZhdWx0LnRleHRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ3RvcCcsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiB7XG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmc6IDUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoZW1lXzEuZGVmYXVsdC5saW5lQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpdGVtQmFja2dyb3VuZDoge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGl0ZW1OYW1lOiB7XG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDE2LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogdGhlbWVfMS5kZWZhdWx0LnRleHRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZScsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBtYXJrZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogOCxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHI6IDYsXG4gICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaXRlbVZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgIGFsaWduUmlnaHQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGl0ZW1TdGF0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lU3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjgsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1bmNoZWNrZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVTdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHRoZW1lXzEuZGVmYXVsdC51bmNoZWNrZWRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJrZXJTdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHRoZW1lXzEuZGVmYXVsdC51bmNoZWNrZWRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoZW1lXzEuZGVmYXVsdC51bmNoZWNrZWRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lU3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudW5jaGVja2VkQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyU3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9IH0pO1xuICAgIH07XG4gICAgLy8g5a6e546wIElMaXN0IOaOpeWPo1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5pc0xpc3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5Zu+5L6L6aG5XG4gICAgICogQHJldHVybiB7TGlzdEl0ZW1bXX0g5YiX6KGo6aG56ZuG5ZCIXG4gICAgICovXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmdldEl0ZW1zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoJ2l0ZW1zJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7liJfooajpoblcbiAgICAgKiBAcGFyYW0ge0xpc3RJdGVtW119IGl0ZW1zIOWIl+ihqOmhuembhuWQiFxuICAgICAqL1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5zZXRJdGVtcyA9IGZ1bmN0aW9uIChpdGVtcykge1xuICAgICAgICB0aGlzLnVwZGF0ZSh7XG4gICAgICAgICAgICBpdGVtczogaXRlbXMsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5pu05paw5YiX6KGo6aG5XG4gICAgICogQHBhcmFtIHtMaXN0SXRlbX0gaXRlbSDliJfooajpoblcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gICBjZmcgIOWIl+ihqOmhuVxuICAgICAqL1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS51cGRhdGVJdGVtID0gZnVuY3Rpb24gKGl0ZW0sIGNmZykge1xuICAgICAgICB1dGlsXzEubWl4KGl0ZW0sIGNmZyk7XG4gICAgICAgIHRoaXMuY2xlYXIoKTsgLy8g55Sx5LqO5Y2V5Liq5Zu+5L6L6aG55Y+Y5YyW77yM5Lya5byV6LW35YWo5bGA5Y+Y5YyW77yM5omA5Lul5YWo6YOo5pu05pawXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuIXnqbrliJfooahcbiAgICAgKi9cbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuY2xlYXJJdGVtcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGl0ZW1Hcm91cCA9IHRoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgnaXRlbS1ncm91cCcpO1xuICAgICAgICBpdGVtR3JvdXAgJiYgaXRlbUdyb3VwLmNsZWFyKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7liJfooajpobnnmoTnirbmgIFcbiAgICAgKiBAcGFyYW0ge0xpc3RJdGVtfSBpdGVtICDliJfooajpoblcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gICBzdGF0ZSDnirbmgIHlkI1cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59ICB2YWx1ZSDnirbmgIHlgLwsIHRydWUsIGZhbHNlXG4gICAgICovXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLnNldEl0ZW1TdGF0ZSA9IGZ1bmN0aW9uIChpdGVtLCBzdGF0ZSwgdmFsdWUpIHtcbiAgICAgICAgaXRlbVtzdGF0ZV0gPSB2YWx1ZTtcbiAgICAgICAgdmFyIGl0ZW1FbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKFwiaXRlbS1cIiArIGl0ZW0uaWQpO1xuICAgICAgICBpZiAoaXRlbUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHZhciBpdGVtcyA9IHRoaXMuZ2V0SXRlbXMoKTtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGl0ZW1zLmluZGV4T2YoaXRlbSk7XG4gICAgICAgICAgICB2YXIgb2Zmc2V0R3JvdXAgPSB0aGlzLmNyZWF0ZU9mZlNjcmVlbkdyb3VwKCk7IC8vIOemu+Wxj+eahCBncm91cFxuICAgICAgICAgICAgdmFyIG5ld0VsZW1lbnQgPSB0aGlzLmRyYXdJdGVtKGl0ZW0sIGluZGV4LCB0aGlzLmdldEl0ZW1IZWlnaHQoKSwgb2Zmc2V0R3JvdXApO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50cyhuZXdFbGVtZW50LCBpdGVtRWxlbWVudCk7IC8vIOabtOaWsOaVtOS4quWIhue7hFxuICAgICAgICAgICAgdGhpcy5jbGVhclVwZGF0ZVN0YXR1cyhpdGVtRWxlbWVudCk7IC8vIOa4heeQhuabtOaWsOeKtuaAge+8jOmYsuatouWHuueOsCBidWdcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm5a2Y5Zyo5oyH5a6a55qE54q25oCBXG4gICAgICogQHBhcmFtIHtMaXN0SXRlbX0gaXRlbSAg5YiX6KGo6aG5XG4gICAgICogQHBhcmFtIHtib29sZWFufSBzdGF0ZSDnirbmgIHlkI1cbiAgICAgKi9cbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuaGFzU3RhdGUgPSBmdW5jdGlvbiAoaXRlbSwgc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuICEhaXRlbVtzdGF0ZV07XG4gICAgfTtcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuZ2V0SXRlbVN0YXRlcyA9IGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHZhciBpdGVtU3RhdGVzID0gdGhpcy5nZXQoJ2l0ZW1TdGF0ZXMnKTtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChpdGVtU3RhdGVzLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgaWYgKGl0ZW1ba10pIHtcbiAgICAgICAgICAgICAgICAvLyBpdGVtLnNlbGVjdGVkXG4gICAgICAgICAgICAgICAgcnN0LnB1c2goayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF5qWa5omA5pyJ5YiX6KGo6aG555qE54q25oCBXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlIOeKtuaAgeWAvFxuICAgICAqL1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5jbGVhckl0ZW1zU3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5nZXRJdGVtc0J5U3RhdGUoc3RhdGUpO1xuICAgICAgICB1dGlsXzEuZWFjaChpdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIF90aGlzLnNldEl0ZW1TdGF0ZShpdGVtLCBzdGF0ZSwgZmFsc2UpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNrueKtuaAgeiOt+WPluWbvuS+i+mhuVxuICAgICAqIEBwYXJhbSAge3N0cmluZ30gICAgIHN0YXRlIFtkZXNjcmlwdGlvbl1cbiAgICAgKiBAcmV0dXJuIHtMaXN0SXRlbVtdfSAgICAgICBbZGVzY3JpcHRpb25dXG4gICAgICovXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmdldEl0ZW1zQnlTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLmdldEl0ZW1zKCk7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmlsdGVyKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmhhc1N0YXRlKGl0ZW0sIHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLYgbGVnZW5kIOeahOmAiemhuVxuICAgIENhdGVnb3J5LnByb3RvdHlwZS5kcmF3TGVnZW5kQ29udGVudCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NJdGVtcygpO1xuICAgICAgICB0aGlzLmRyYXdJdGVtcyhncm91cCk7XG4gICAgfTtcbiAgICAvLyDpmLLmraLmnKrorr7nva4gaWRcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUucHJvY2Vzc0l0ZW1zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLmdldCgnaXRlbXMnKTtcbiAgICAgICAgdXRpbF8xLmVhY2goaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBpZiAoIWl0ZW0uaWQpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzmsqHmnInorr7nva4gaWTvvIzpu5jorqTkvb/nlKggbmFtZVxuICAgICAgICAgICAgICAgIGl0ZW0uaWQgPSBpdGVtLm5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g57uY5Yi25omA5pyJ55qE5Zu+5L6L6YCJ6aG5XG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmRyYXdJdGVtcyA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXRlbUNvbnRhaW5lckdyb3VwID0gdGhpcy5hZGRHcm91cChncm91cCwge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdpdGVtLWNvbnRhaW5lci1ncm91cCcpLFxuICAgICAgICAgICAgbmFtZTogJ2xlZ2VuZC1pdGVtLWNvbnRhaW5lci1ncm91cCcsXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgaXRlbUdyb3VwID0gdGhpcy5hZGRHcm91cChpdGVtQ29udGFpbmVyR3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnaXRlbS1ncm91cCcpLFxuICAgICAgICAgICAgbmFtZTogJ2xlZ2VuZC1pdGVtLWdyb3VwJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBpdGVtSGVpZ2h0ID0gdGhpcy5nZXRJdGVtSGVpZ2h0KCk7XG4gICAgICAgIHZhciBpdGVtV2lkdGggPSB0aGlzLmdldCgnaXRlbVdpZHRoJyk7XG4gICAgICAgIHZhciBpdGVtU3BhY2luZyA9IHRoaXMuZ2V0KCdpdGVtU3BhY2luZycpO1xuICAgICAgICB2YXIgY3VycmVudFBvaW50ID0gdGhpcy5nZXQoJ2N1cnJlbnRQb2ludCcpO1xuICAgICAgICB2YXIgc3RhcnRYID0gY3VycmVudFBvaW50Lng7XG4gICAgICAgIHZhciBzdGFydFkgPSBjdXJyZW50UG9pbnQueTtcbiAgICAgICAgdmFyIGxheW91dCA9IHRoaXMuZ2V0KCdsYXlvdXQnKTtcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5nZXQoJ2l0ZW1zJyk7XG4gICAgICAgIHZhciB3cmFwcGVkID0gZmFsc2U7XG4gICAgICAgIHZhciBwYWdlV2lkdGggPSAwO1xuICAgICAgICB2YXIgbWF4V2lkdGggPSB0aGlzLmdldCgnbWF4V2lkdGgnKTsgLy8g5pyA5aSn5a695bqm77yM5Lya5a+86Ie0IGxheW91dCA6ICdob3Jpem9udGFsJyDml7boh6rliqjmjaLooYxcbiAgICAgICAgdmFyIG1heEhlaWdodCA9IHRoaXMuZ2V0KCdtYXhIZWlnaHQnKTsgLy8g5pyA5aSn6auY5bqm77yM5Lya5a+86Ie05Ye6546w5YiG6aG1XG4gICAgICAgIC8vIOaaguaXtuS4jeiAg+iZkeWIhumhtVxuICAgICAgICB1dGlsXzEuZWFjaChpdGVtcywgZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc3ViR3JvdXAgPSBfdGhpcy5kcmF3SXRlbShpdGVtLCBpbmRleCwgaXRlbUhlaWdodCwgaXRlbUdyb3VwKTtcbiAgICAgICAgICAgIHZhciBiYm94ID0gc3ViR3JvdXAuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHdpZHRoID0gaXRlbVdpZHRoIHx8IGJib3gud2lkdGg7XG4gICAgICAgICAgICBpZiAod2lkdGggPiBwYWdlV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBwYWdlV2lkdGggPSB3aWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXlvdXQgPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOawtOW5s+W4g+WxgFxuICAgICAgICAgICAgICAgIGlmIChtYXhXaWR0aCAmJiBtYXhXaWR0aCA8IGN1cnJlbnRQb2ludC54ICsgd2lkdGggLSBzdGFydFgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5qOA5rWL5piv5ZCm5o2i6KGMXG4gICAgICAgICAgICAgICAgICAgIHdyYXBwZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UG9pbnQueCA9IHN0YXJ0WDtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFBvaW50LnkgKz0gaXRlbUhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgX3RoaXMubW92ZUVsZW1lbnRUbyhzdWJHcm91cCwgY3VycmVudFBvaW50KTtcbiAgICAgICAgICAgICAgICBjdXJyZW50UG9pbnQueCArPSB3aWR0aCArIGl0ZW1TcGFjaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5Z6C55u05biD5bGAXG4gICAgICAgICAgICAgICAgaWYgKG1heEhlaWdodCAmJiBtYXhIZWlnaHQgPCBjdXJyZW50UG9pbnQueSArIGl0ZW1IZWlnaHQgLSBzdGFydFkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5o2i6KGMXG4gICAgICAgICAgICAgICAgICAgIHdyYXBwZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UG9pbnQueCArPSBwYWdlV2lkdGggKyBpdGVtU3BhY2luZztcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFBvaW50LnkgPSBzdGFydFk7XG4gICAgICAgICAgICAgICAgICAgIHBhZ2VXaWR0aCA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF90aGlzLm1vdmVFbGVtZW50VG8oc3ViR3JvdXAsIGN1cnJlbnRQb2ludCk7XG4gICAgICAgICAgICAgICAgY3VycmVudFBvaW50LnkgKz0gaXRlbUhlaWdodDsgLy8gaXRlbVNwYWNpbmcg5LuF5b2x5ZON5rC05bmz6Ze06LedXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAod3JhcHBlZCAmJiB0aGlzLmdldCgnZmxpcFBhZ2UnKSkge1xuICAgICAgICAgICAgdGhpcy5wYWdlSGVpZ2h0ID0gMDtcbiAgICAgICAgICAgIHRoaXMucGFnZVdpZHRoID0gMDtcbiAgICAgICAgICAgIHRoaXMudG90YWxQYWdlc0NudCA9IDE7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0WCA9IHN0YXJ0WDtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRZID0gc3RhcnRZO1xuICAgICAgICAgICAgdGhpcy5hZGp1c3ROYXZpZ2F0aW9uKGdyb3VwLCBpdGVtR3JvdXApO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDojrflj5blm77kvovpobnnmoTpq5jluqbvvIzlpoLmnpzmnKrlrprkuYnvvIzliJnmjInnhacgbmFtZSDnmoTpq5jluqborqHnrpdcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuZ2V0SXRlbUhlaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGl0ZW1IZWlnaHQgPSB0aGlzLmdldCgnaXRlbUhlaWdodCcpO1xuICAgICAgICBpZiAoIWl0ZW1IZWlnaHQpIHtcbiAgICAgICAgICAgIHZhciBuYW1lQ2ZnID0gdGhpcy5nZXQoJ2l0ZW1OYW1lJyk7XG4gICAgICAgICAgICBpZiAobmFtZUNmZykge1xuICAgICAgICAgICAgICAgIGl0ZW1IZWlnaHQgPSBuYW1lQ2ZnLnN0eWxlLmZvbnRTaXplICsgODtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbUhlaWdodDtcbiAgICB9O1xuICAgIC8vIOe7mOWItiBtYXJrZXJcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuZHJhd01hcmtlciA9IGZ1bmN0aW9uIChjb250YWluZXIsIG1hcmtlckNmZywgaXRlbSwgaXRlbUhlaWdodCkge1xuICAgICAgICB2YXIgbWFya2VyQXR0cnMgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IHg6IDAsIHk6IGl0ZW1IZWlnaHQgLyAyIH0sIG1hcmtlckNmZy5zdHlsZSksIHsgc3ltYm9sOiB1dGlsXzEuZ2V0KGl0ZW0ubWFya2VyLCAnc3ltYm9sJywgJ2NpcmNsZScpIH0pLCB1dGlsXzEuZ2V0KGl0ZW0ubWFya2VyLCAnc3R5bGUnLCB7fSkpO1xuICAgICAgICB2YXIgc2hhcGUgPSB0aGlzLmFkZFNoYXBlKGNvbnRhaW5lciwge1xuICAgICAgICAgICAgdHlwZTogJ21hcmtlcicsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoXCJpdGVtLVwiICsgaXRlbS5pZCArIFwiLW1hcmtlclwiKSxcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtaXRlbS1tYXJrZXInLFxuICAgICAgICAgICAgYXR0cnM6IG1hcmtlckF0dHJzLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGJib3ggPSBzaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIHNoYXBlLmF0dHIoJ3gnLCBiYm94LndpZHRoIC8gMik7IC8vIG1hcmtlciDpnIDopoHlt6blr7npvZDvvIzmiYDku6XkuI3og73ljaDnlKjlt6bkvqfnmoTnqbrpl7RcbiAgICAgICAgdmFyIF9hID0gc2hhcGUuYXR0cigpLCBzdHJva2UgPSBfYS5zdHJva2UsIGZpbGwgPSBfYS5maWxsO1xuICAgICAgICBpZiAoc3Ryb2tlKSB7XG4gICAgICAgICAgICBzaGFwZS5zZXQoJ2lzU3Ryb2tlJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbGwpIHtcbiAgICAgICAgICAgIHNoYXBlLnNldCgnaXNGaWxsJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH07XG4gICAgLy8g57uY5Yi25paH5pysXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmRyYXdJdGVtVGV4dCA9IGZ1bmN0aW9uIChjb250YWluZXIsIHRleHROYW1lLCBjZmcsIGl0ZW0sIGl0ZW1IZWlnaHQsIHhQb3NpdGlvbiwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGZvcm1hdHRlciA9IGNmZy5mb3JtYXR0ZXI7XG4gICAgICAgIHZhciBhdHRycyA9IHRzbGliXzEuX19hc3NpZ24oeyB4OiB4UG9zaXRpb24sIHk6IGl0ZW1IZWlnaHQgLyAyLCB0ZXh0OiBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIoaXRlbVt0ZXh0TmFtZV0sIGl0ZW0sIGluZGV4KSA6IGl0ZW1bdGV4dE5hbWVdIH0sIGNmZy5zdHlsZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFNoYXBlKGNvbnRhaW5lciwge1xuICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKFwiaXRlbS1cIiArIGl0ZW0uaWQgKyBcIi1cIiArIHRleHROYW1lKSxcbiAgICAgICAgICAgIG5hbWU6IFwibGVnZW5kLWl0ZW0tXCIgKyB0ZXh0TmFtZSxcbiAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLblm77kvovpoblcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuZHJhd0l0ZW0gPSBmdW5jdGlvbiAoaXRlbSwgaW5kZXgsIGl0ZW1IZWlnaHQsIGl0ZW1Hcm91cCkge1xuICAgICAgICB2YXIgZ3JvdXBJZCA9IFwiaXRlbS1cIiArIGl0ZW0uaWQ7XG4gICAgICAgIC8vIOiuvue9ruWNleeLrOeahCBHcm91cCDnlKjkuo4gc2V0Q2xpcFxuICAgICAgICB2YXIgc3ViQ29udGFpbmVyID0gdGhpcy5hZGRHcm91cChpdGVtR3JvdXAsIHtcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtaXRlbS1jb250YWluZXInLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKFwiaXRlbS1jb250YWluZXItXCIgKyBncm91cElkKSxcbiAgICAgICAgICAgIGRlbGVnYXRlT2JqZWN0OiB7XG4gICAgICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHN1Ykdyb3VwID0gdGhpcy5hZGRHcm91cChzdWJDb250YWluZXIsIHtcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtaXRlbScsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoZ3JvdXBJZCksXG4gICAgICAgICAgICBkZWxlZ2F0ZU9iamVjdDoge1xuICAgICAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBtYXJrZXIgPSB0aGlzLmdldCgnbWFya2VyJyk7XG4gICAgICAgIHZhciBpdGVtTmFtZSA9IHRoaXMuZ2V0KCdpdGVtTmFtZScpO1xuICAgICAgICB2YXIgaXRlbVZhbHVlID0gdGhpcy5nZXQoJ2l0ZW1WYWx1ZScpO1xuICAgICAgICB2YXIgaXRlbUJhY2tncm91bmQgPSB0aGlzLmdldCgnaXRlbUJhY2tncm91bmQnKTtcbiAgICAgICAgdmFyIGl0ZW1XaWR0aCA9IHRoaXMuZ2V0TGltaXRJdGVtV2lkdGgoKTtcbiAgICAgICAgdmFyIGN1clggPSAwOyAvLyDorrDlvZXlvZPliY0geCDnmoTkvY3nva5cbiAgICAgICAgaWYgKG1hcmtlcikge1xuICAgICAgICAgICAgdmFyIG1hcmtlclNoYXBlID0gdGhpcy5kcmF3TWFya2VyKHN1Ykdyb3VwLCBtYXJrZXIsIGl0ZW0sIGl0ZW1IZWlnaHQpO1xuICAgICAgICAgICAgY3VyWCA9IG1hcmtlclNoYXBlLmdldEJCb3goKS5tYXhYICsgbWFya2VyLnNwYWNpbmc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW1OYW1lKSB7XG4gICAgICAgICAgICB2YXIgbmFtZVNoYXBlID0gdGhpcy5kcmF3SXRlbVRleHQoc3ViR3JvdXAsICduYW1lJywgaXRlbU5hbWUsIGl0ZW0sIGl0ZW1IZWlnaHQsIGN1clgsIGluZGV4KTtcbiAgICAgICAgICAgIGlmIChpdGVtV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAvLyDorr7nva7kuoYgaXRlbSDnmoTmnIDlpKflrr3luqbpmZDliLbvvIzlubbkuJTotoXlh7rkuobvvIzov5vooYznnIHnlaXlpITnkIZcbiAgICAgICAgICAgICAgICBsYWJlbF8xLmVsbGlwc2lzTGFiZWwodHJ1ZSwgbmFtZVNoYXBlLCB1dGlsXzEuY2xhbXAoaXRlbVdpZHRoIC0gY3VyWCwgMCwgaXRlbVdpZHRoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJYID0gbmFtZVNoYXBlLmdldEJCb3goKS5tYXhYICsgaXRlbU5hbWUuc3BhY2luZztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbVZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWVTaGFwZSA9IHRoaXMuZHJhd0l0ZW1UZXh0KHN1Ykdyb3VwLCAndmFsdWUnLCBpdGVtVmFsdWUsIGl0ZW0sIGl0ZW1IZWlnaHQsIGN1clgsIGluZGV4KTtcbiAgICAgICAgICAgIGlmIChpdGVtV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbVZhbHVlLmFsaWduUmlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVTaGFwZS5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ3JpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IGl0ZW1XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsXzEuZWxsaXBzaXNMYWJlbCh0cnVlLCB2YWx1ZVNoYXBlLCB1dGlsXzEuY2xhbXAoaXRlbVdpZHRoIC0gY3VyWCwgMCwgaXRlbVdpZHRoKSwgJ2hlYWQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsXzEuZWxsaXBzaXNMYWJlbCh0cnVlLCB2YWx1ZVNoYXBlLCB1dGlsXzEuY2xhbXAoaXRlbVdpZHRoIC0gY3VyWCwgMCwgaXRlbVdpZHRoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOa3u+WKoOmAj+aYjueahOiDjOaZr++8jOS+v+S6juaLvuWPluWSjOWMheWbtOebkuiuoeeul1xuICAgICAgICBpZiAoaXRlbUJhY2tncm91bmQpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gc3ViR3JvdXAuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIGJhY2tTaGFwZSA9IHRoaXMuYWRkU2hhcGUoc3ViR3JvdXAsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ2xlZ2VuZC1pdGVtLWJhY2tncm91bmQnLFxuICAgICAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZChncm91cElkICsgXCItYmFja2dyb3VuZFwiKSxcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHg6IDAsIHk6IDAsIHdpZHRoOiBiYm94LndpZHRoLCBoZWlnaHQ6IGl0ZW1IZWlnaHQgfSwgaXRlbUJhY2tncm91bmQuc3R5bGUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBiYWNrU2hhcGUudG9CYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hcHBseUl0ZW1TdGF0ZXMoaXRlbSwgc3ViR3JvdXApO1xuICAgICAgICByZXR1cm4gc3ViR3JvdXA7XG4gICAgfTtcbiAgICAvLyDliqDkuIrliIbpobXlmajlubbph43mlrDmjpLluo8gaXRlbXNcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuYWRqdXN0TmF2aWdhdGlvbiA9IGZ1bmN0aW9uIChjb250YWluZXIsIGl0ZW1Hcm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc3RhcnRYID0gdGhpcy5zdGFydFg7XG4gICAgICAgIHZhciBzdGFydFkgPSB0aGlzLnN0YXJ0WTtcbiAgICAgICAgdmFyIGxheW91dCA9IHRoaXMuZ2V0KCdsYXlvdXQnKTtcbiAgICAgICAgdmFyIHN1Ykdyb3VwcyA9IGl0ZW1Hcm91cC5maW5kQWxsKGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtLmdldCgnbmFtZScpID09PSAnbGVnZW5kLWl0ZW0nOyB9KTtcbiAgICAgICAgdmFyIG1heFdpZHRoID0gdGhpcy5nZXQoJ21heFdpZHRoJyk7XG4gICAgICAgIHZhciBtYXhIZWlnaHQgPSB0aGlzLmdldCgnbWF4SGVpZ2h0Jyk7XG4gICAgICAgIHZhciBpdGVtV2lkdGggPSB0aGlzLmdldCgnaXRlbVdpZHRoJyk7XG4gICAgICAgIHZhciBpdGVtU3BhY2luZyA9IHRoaXMuZ2V0KCdpdGVtU3BhY2luZycpO1xuICAgICAgICB2YXIgaXRlbUhlaWdodCA9IHRoaXMuZ2V0SXRlbUhlaWdodCgpO1xuICAgICAgICB2YXIgbmF2aWdhdGlvbiA9IHRoaXMuZHJhd05hdmlnYXRpb24oY29udGFpbmVyLCBsYXlvdXQsICcwMC8wMCcsIDEyKTtcbiAgICAgICAgdmFyIG5hdmlnYXRpb25CQm94ID0gbmF2aWdhdGlvbi5nZXRCQm94KCk7XG4gICAgICAgIHZhciBjdXJyZW50UG9pbnQgPSB7IHg6IHN0YXJ0WCwgeTogc3RhcnRZIH07XG4gICAgICAgIHZhciBwYWdlcyA9IDE7XG4gICAgICAgIHZhciB3aWR0aExpbWl0ID0gMDtcbiAgICAgICAgdmFyIHBhZ2VXaWR0aCA9IDA7XG4gICAgICAgIHZhciBtYXhJdGVtV2lkdGggPSAwO1xuICAgICAgICBpZiAobGF5b3V0ID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgIHRoaXMucGFnZUhlaWdodCA9IGl0ZW1IZWlnaHQ7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzdWJHcm91cHMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJib3ggPSBpdGVtLmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICB2YXIgd2lkdGggPSBpdGVtV2lkdGggfHwgYmJveC53aWR0aDtcbiAgICAgICAgICAgICAgICBpZiAoKHdpZHRoTGltaXQgJiYgd2lkdGhMaW1pdCA8IGN1cnJlbnRQb2ludC54ICsgd2lkdGggKyBpdGVtU3BhY2luZykgfHxcbiAgICAgICAgICAgICAgICAgICAgbWF4V2lkdGggPCBjdXJyZW50UG9pbnQueCArIHdpZHRoICsgaXRlbVNwYWNpbmcgKyBuYXZpZ2F0aW9uQkJveC53aWR0aCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFnZXMgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoTGltaXQgPSBjdXJyZW50UG9pbnQueCArIGl0ZW1TcGFjaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMucGFnZVdpZHRoID0gd2lkdGhMaW1pdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm1vdmVFbGVtZW50VG8obmF2aWdhdGlvbiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1heFdpZHRoIC0gaXRlbVNwYWNpbmcgLSBuYXZpZ2F0aW9uQkJveC53aWR0aCAtIG5hdmlnYXRpb25CQm94Lm1pblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogY3VycmVudFBvaW50LnkgKyBpdGVtSGVpZ2h0IC8gMiAtIG5hdmlnYXRpb25CQm94LmhlaWdodCAvIDIgLSBuYXZpZ2F0aW9uQkJveC5taW5ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFnZXMgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFBvaW50LnggPSBzdGFydFg7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQb2ludC55ICs9IGl0ZW1IZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF90aGlzLm1vdmVFbGVtZW50VG8oaXRlbSwgY3VycmVudFBvaW50KTtcbiAgICAgICAgICAgICAgICBpdGVtLmdldFBhcmVudCgpLnNldENsaXAoe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBjdXJyZW50UG9pbnQueCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IGN1cnJlbnRQb2ludC55LFxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoICsgaXRlbVNwYWNpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGl0ZW1IZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY3VycmVudFBvaW50LnggKz0gd2lkdGggKyBpdGVtU3BhY2luZztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goc3ViR3JvdXBzLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHZhciBiYm94ID0gaXRlbS5nZXRCQm94KCk7XG4gICAgICAgICAgICAgICAgaWYgKGJib3gud2lkdGggPiBwYWdlV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFnZVdpZHRoID0gYmJveC53aWR0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1heEl0ZW1XaWR0aCA9IHBhZ2VXaWR0aDtcbiAgICAgICAgICAgIHBhZ2VXaWR0aCArPSBpdGVtU3BhY2luZztcbiAgICAgICAgICAgIGlmIChtYXhXaWR0aCkge1xuICAgICAgICAgICAgICAgIC8vIG1heFdpZHRoIOmZkOWItuWKoOS4ilxuICAgICAgICAgICAgICAgIHBhZ2VXaWR0aCA9IE1hdGgubWluKG1heFdpZHRoLCBwYWdlV2lkdGgpO1xuICAgICAgICAgICAgICAgIG1heEl0ZW1XaWR0aCA9IE1hdGgubWluKG1heFdpZHRoLCBtYXhJdGVtV2lkdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wYWdlV2lkdGggPSBwYWdlV2lkdGg7XG4gICAgICAgICAgICB0aGlzLnBhZ2VIZWlnaHQgPSBtYXhIZWlnaHQgLSBNYXRoLm1heChuYXZpZ2F0aW9uQkJveC5oZWlnaHQsIGl0ZW1IZWlnaHQpO1xuICAgICAgICAgICAgdmFyIGNudFBlclBhZ2VfMSA9IE1hdGguZmxvb3IodGhpcy5wYWdlSGVpZ2h0IC8gaXRlbUhlaWdodCk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzdWJHcm91cHMsIGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gMCAmJiBpbmRleCAlIGNudFBlclBhZ2VfMSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBwYWdlcyArPSAxO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UG9pbnQueCArPSBwYWdlV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQb2ludC55ID0gc3RhcnRZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfdGhpcy5tb3ZlRWxlbWVudFRvKGl0ZW0sIGN1cnJlbnRQb2ludCk7XG4gICAgICAgICAgICAgICAgaXRlbS5nZXRQYXJlbnQoKS5zZXRDbGlwKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgeDogY3VycmVudFBvaW50LngsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBjdXJyZW50UG9pbnQueSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBwYWdlV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGl0ZW1IZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY3VycmVudFBvaW50LnkgKz0gaXRlbUhlaWdodDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy50b3RhbFBhZ2VzQ250ID0gcGFnZXM7XG4gICAgICAgICAgICB0aGlzLm1vdmVFbGVtZW50VG8obmF2aWdhdGlvbiwge1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0WCArIG1heEl0ZW1XaWR0aCAvIDIgLSBuYXZpZ2F0aW9uQkJveC53aWR0aCAvIDIgLSBuYXZpZ2F0aW9uQkJveC5taW5YLFxuICAgICAgICAgICAgICAgIHk6IG1heEhlaWdodCAtIG5hdmlnYXRpb25CQm94LmhlaWdodCAtIG5hdmlnYXRpb25CQm94Lm1pblksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYWdlSGVpZ2h0ICYmIHRoaXMucGFnZVdpZHRoKSB7XG4gICAgICAgICAgICAvLyDkuLrkuobkvb/lm7rlrprnmoQgY2xpcCDnlJ/mlYjvvIxjbGlwIOiuvue9ruWcqCBpdGVtQ29udGFpbmVyR3JvdXAg5LiK77yMaXRlbUdyb3VwIOmcgOimgeWcqOe/u+mhteaXtuS8muiuvue9riBtYXRyaXhcbiAgICAgICAgICAgIGl0ZW1Hcm91cC5nZXRQYXJlbnQoKS5zZXRDbGlwKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgeDogdGhpcy5zdGFydFgsXG4gICAgICAgICAgICAgICAgICAgIHk6IHRoaXMuc3RhcnRZLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy5wYWdlV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5wYWdlSGVpZ2h0LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRvdGFsUGFnZXNDbnQgPSBwYWdlcztcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFBhZ2VJbmRleCA+IHRoaXMudG90YWxQYWdlc0NudCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50UGFnZUluZGV4ID0gMTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZU5hdmlnYXRpb24obmF2aWdhdGlvbik7XG4gICAgICAgIC8vIHVwZGF0ZSBpbml0aWFsIG1hdHJpeFxuICAgICAgICBpdGVtR3JvdXAuYXR0cignbWF0cml4JywgdGhpcy5nZXRDdXJyZW50TmF2aWdhdGlvbk1hdHJpeCgpKTtcbiAgICB9O1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5kcmF3TmF2aWdhdGlvbiA9IGZ1bmN0aW9uIChncm91cCwgbGF5b3V0LCB0ZXh0LCBzaXplKSB7XG4gICAgICAgIHZhciBjdXJyZW50UG9pbnQgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgdmFyIHN1Ykdyb3VwID0gdGhpcy5hZGRHcm91cChncm91cCwge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCduYXZpZ2F0aW9uLWdyb3VwJyksXG4gICAgICAgICAgICBuYW1lOiAnbGVnZW5kLW5hdmlnYXRpb24nLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGxlZnRBcnJvdyA9IHRoaXMuZHJhd0Fycm93KHN1Ykdyb3VwLCBjdXJyZW50UG9pbnQsICduYXZpZ2F0aW9uLWFycm93LWxlZnQnLCBsYXlvdXQgPT09ICdob3Jpem9udGFsJyA/ICd1cCcgOiAnbGVmdCcsIHNpemUpO1xuICAgICAgICBsZWZ0QXJyb3cub24oJ2NsaWNrJywgdGhpcy5vbk5hdmlnYXRpb25CYWNrKTtcbiAgICAgICAgdmFyIGxlZnRBcnJvd0JCb3ggPSBsZWZ0QXJyb3cuZ2V0QkJveCgpO1xuICAgICAgICBjdXJyZW50UG9pbnQueCArPSBsZWZ0QXJyb3dCQm94LndpZHRoICsgMjtcbiAgICAgICAgdmFyIHRleHRTaGFwZSA9IHRoaXMuYWRkU2hhcGUoc3ViR3JvdXAsIHtcbiAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbmF2aWdhdGlvbi10ZXh0JyksXG4gICAgICAgICAgICBuYW1lOiAnbmF2aWdhdGlvbi10ZXh0JyxcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogY3VycmVudFBvaW50LngsXG4gICAgICAgICAgICAgICAgeTogY3VycmVudFBvaW50LnkgKyBzaXplIC8gMixcbiAgICAgICAgICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICBmaWxsOiAnI2NjYycsXG4gICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgdGV4dEJCb3ggPSB0ZXh0U2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICBjdXJyZW50UG9pbnQueCArPSB0ZXh0QkJveC53aWR0aCArIDI7XG4gICAgICAgIHZhciByaWdodEFycm93ID0gdGhpcy5kcmF3QXJyb3coc3ViR3JvdXAsIGN1cnJlbnRQb2ludCwgJ25hdmlnYXRpb24tYXJyb3ctcmlnaHQnLCBsYXlvdXQgPT09ICdob3Jpem9udGFsJyA/ICdkb3duJyA6ICdyaWdodCcsIHNpemUpO1xuICAgICAgICByaWdodEFycm93Lm9uKCdjbGljaycsIHRoaXMub25OYXZpZ2F0aW9uQWZ0ZXIpO1xuICAgICAgICByZXR1cm4gc3ViR3JvdXA7XG4gICAgfTtcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUudXBkYXRlTmF2aWdhdGlvbiA9IGZ1bmN0aW9uIChuYXZpZ2F0aW9uKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gdGhpcy5jdXJyZW50UGFnZUluZGV4ICsgXCIvXCIgKyB0aGlzLnRvdGFsUGFnZXNDbnQ7XG4gICAgICAgIHZhciB0ZXh0U2hhcGUgPSBuYXZpZ2F0aW9uID8gbmF2aWdhdGlvbi5nZXRDaGlsZHJlbigpWzFdIDogdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCduYXZpZ2F0aW9uLXRleHQnKTtcbiAgICAgICAgdmFyIGxlZnRBcnJvdyA9IG5hdmlnYXRpb25cbiAgICAgICAgICAgID8gbmF2aWdhdGlvbi5maW5kQnlJZCh0aGlzLmdldEVsZW1lbnRJZCgnbmF2aWdhdGlvbi1hcnJvdy1sZWZ0JykpXG4gICAgICAgICAgICA6IHRoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgnbmF2aWdhdGlvbi1hcnJvdy1sZWZ0Jyk7XG4gICAgICAgIHZhciByaWdodEFycm93ID0gbmF2aWdhdGlvblxuICAgICAgICAgICAgPyBuYXZpZ2F0aW9uLmZpbmRCeUlkKHRoaXMuZ2V0RWxlbWVudElkKCduYXZpZ2F0aW9uLWFycm93LXJpZ2h0JykpXG4gICAgICAgICAgICA6IHRoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgnbmF2aWdhdGlvbi1hcnJvdy1yaWdodCcpO1xuICAgICAgICB2YXIgb3JpZ0JCb3ggPSB0ZXh0U2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB0ZXh0U2hhcGUuYXR0cigndGV4dCcsIHRleHQpO1xuICAgICAgICB2YXIgbmV3QkJveCA9IHRleHRTaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIHRleHRTaGFwZS5hdHRyKCd4JywgdGV4dFNoYXBlLmF0dHIoJ3gnKSAtIChuZXdCQm94LndpZHRoIC0gb3JpZ0JCb3gud2lkdGgpIC8gMik7XG4gICAgICAgIGxlZnRBcnJvdy5hdHRyKCdvcGFjaXR5JywgdGhpcy5jdXJyZW50UGFnZUluZGV4ID09PSAxID8gMC40NSA6IDEpO1xuICAgICAgICBsZWZ0QXJyb3cuYXR0cignY3Vyc29yJywgdGhpcy5jdXJyZW50UGFnZUluZGV4ID09PSAxID8gJ25vdC1hbGxvd2VkJyA6ICdwb2ludGVyJyk7XG4gICAgICAgIHJpZ2h0QXJyb3cuYXR0cignb3BhY2l0eScsIHRoaXMuY3VycmVudFBhZ2VJbmRleCA9PT0gdGhpcy50b3RhbFBhZ2VzQ250ID8gMC40NSA6IDEpO1xuICAgICAgICByaWdodEFycm93LmF0dHIoJ2N1cnNvcicsIHRoaXMuY3VycmVudFBhZ2VJbmRleCA9PT0gdGhpcy50b3RhbFBhZ2VzQ250ID8gJ25vdC1hbGxvd2VkJyA6ICdwb2ludGVyJyk7XG4gICAgfTtcbiAgICBDYXRlZ29yeS5wcm90b3R5cGUuZHJhd0Fycm93ID0gZnVuY3Rpb24gKGdyb3VwLCBjdXJyZW50UG9pbnQsIG5hbWUsIGRpcmVjdGlvbiwgc2l6ZSkge1xuICAgICAgICB2YXIgeCA9IGN1cnJlbnRQb2ludC54LCB5ID0gY3VycmVudFBvaW50Lnk7XG4gICAgICAgIHZhciByb3RhdGVNYXAgPSB7XG4gICAgICAgICAgICByaWdodDogKDkwICogTWF0aC5QSSkgLyAxODAsXG4gICAgICAgICAgICBsZWZ0OiAoKDM2MCAtIDkwKSAqIE1hdGguUEkpIC8gMTgwLFxuICAgICAgICAgICAgdXA6IDAsXG4gICAgICAgICAgICBkb3duOiAoMTgwICogTWF0aC5QSSkgLyAxODAsXG4gICAgICAgIH07XG4gICAgICAgIHZhciBzaGFwZSA9IHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZChuYW1lKSxcbiAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHBhdGg6IFtbJ00nLCB4ICsgc2l6ZSAvIDIsIHldLCBbJ0wnLCB4LCB5ICsgc2l6ZV0sIFsnTCcsIHggKyBzaXplLCB5ICsgc2l6ZV0sIFsnWiddXSxcbiAgICAgICAgICAgICAgICBmaWxsOiAnIzAwMCcsXG4gICAgICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgc2hhcGUuYXR0cignbWF0cml4JywgbWF0cml4XzEuZ2V0TWF0cml4QnlBbmdsZSh7IHg6IHggKyBzaXplIC8gMiwgeTogeSArIHNpemUgLyAyIH0sIHJvdGF0ZU1hcFtkaXJlY3Rpb25dKSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9O1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5nZXRDdXJyZW50TmF2aWdhdGlvbk1hdHJpeCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcywgY3VycmVudFBhZ2VJbmRleCA9IF9hLmN1cnJlbnRQYWdlSW5kZXgsIHBhZ2VXaWR0aCA9IF9hLnBhZ2VXaWR0aCwgcGFnZUhlaWdodCA9IF9hLnBhZ2VIZWlnaHQ7XG4gICAgICAgIHZhciBsYXlvdXQgPSB0aGlzLmdldCgnbGF5b3V0Jyk7XG4gICAgICAgIHZhciB0cmFuc2xhdGUgPSBsYXlvdXQgPT09ICdob3Jpem9udGFsJ1xuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICB5OiBwYWdlSGVpZ2h0ICogKDEgLSBjdXJyZW50UGFnZUluZGV4KSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHg6IHBhZ2VXaWR0aCAqICgxIC0gY3VycmVudFBhZ2VJbmRleCksXG4gICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIHJldHVybiBtYXRyaXhfMS5nZXRNYXRyaXhCeVRyYW5zbGF0ZSh0cmFuc2xhdGUpO1xuICAgIH07XG4gICAgLy8g6ZmE5Yqg54q25oCB5a+55bqU55qE5qC35byPXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmFwcGx5SXRlbVN0YXRlcyA9IGZ1bmN0aW9uIChpdGVtLCBzdWJHcm91cCkge1xuICAgICAgICB2YXIgc3RhdGVzID0gdGhpcy5nZXRJdGVtU3RhdGVzKGl0ZW0pO1xuICAgICAgICB2YXIgaGFzU3RhdGVzID0gc3RhdGVzLmxlbmd0aCA+IDA7XG4gICAgICAgIGlmIChoYXNTdGF0ZXMpIHtcbiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHN1Ykdyb3VwLmdldENoaWxkcmVuKCk7XG4gICAgICAgICAgICB2YXIgaXRlbVN0YXRlc18xID0gdGhpcy5nZXQoJ2l0ZW1TdGF0ZXMnKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGNoaWxkcmVuLCBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZhciBuYW1lID0gZWxlbWVudC5nZXQoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICB2YXIgZWxOYW1lID0gbmFtZS5zcGxpdCgnLScpWzJdOyAvLyBtYXJrZXIsIG5hbWUsIHZhbHVlXG4gICAgICAgICAgICAgICAgdmFyIHN0YXRlc1N0eWxlID0gc3RhdGVfMS5nZXRTdGF0ZXNTdHlsZShpdGVtLCBlbE5hbWUsIGl0ZW1TdGF0ZXNfMSk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlc1N0eWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXR0cihzdGF0ZXNTdHlsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbE5hbWUgPT09ICdtYXJrZXInICYmICEoZWxlbWVudC5nZXQoJ2lzU3Ryb2tlJykgJiYgZWxlbWVudC5nZXQoJ2lzRmlsbCcpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6cIG1hcmtlciDmmK/ljZXloavlhYXmiJbogIXljZXmj4/ovrnnmoTor53vvIzlsLHkuI3opoHpop3lpJbmt7vliqAgc3Ryb2tlIOaIlui/mSBmaWxsIOWxnuaAp++8jOWQpuWImeS8muW9seWTjSB1bmNoZWNrZWQg5ZCO55qE5pi+56S6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5nZXQoJ2lzU3Ryb2tlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmF0dHIoJ2ZpbGwnLCBudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmdldCgnaXNGaWxsJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmF0dHIoJ3N0cm9rZScsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOiOt+WPliBpdGVtV2lkdGgg55qE5pyA57uI6K6+572uXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmdldExpbWl0SXRlbVdpZHRoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbVdpZHRoID0gdGhpcy5nZXQoJ2l0ZW1XaWR0aCcpO1xuICAgICAgICB2YXIgbWF4SXRlbVdpZHRoID0gdGhpcy5nZXQoJ21heEl0ZW1XaWR0aCcpO1xuICAgICAgICBpZiAobWF4SXRlbVdpZHRoKSB7XG4gICAgICAgICAgICAvLyDorr7nva7kuobmnIDlpKflrr3luqZcbiAgICAgICAgICAgIGlmIChpdGVtV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBtYXhJdGVtV2lkdGggPSBpdGVtV2lkdGggPD0gbWF4SXRlbVdpZHRoID8gaXRlbVdpZHRoIDogbWF4SXRlbVdpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGl0ZW1XaWR0aCkge1xuICAgICAgICAgICAgbWF4SXRlbVdpZHRoID0gaXRlbVdpZHRoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXhJdGVtV2lkdGg7XG4gICAgfTtcbiAgICByZXR1cm4gQ2F0ZWdvcnk7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDYXRlZ29yeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNhdGVnb3J5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3RoZW1lXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBIQU5ETEVSX0hFSUdIVF9SQVRJTyA9IDEuNDtcbnZhciBIQU5ETEVSX1RSSUFOR0xFX1JBVElPID0gMC40O1xudmFyIENvbnRpbnVlTGVnZW5kID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbnRpbnVlTGVnZW5kLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENvbnRpbnVlTGVnZW5kKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgdHlwZTogJ2NvbnRpbnVlJywgbWluOiAwLCBtYXg6IDEwMCwgdmFsdWU6IG51bGwsIGNvbG9yczogW10sIHRyYWNrOiB7fSwgcmFpbDoge30sIGxhYmVsOiB7fSwgaGFuZGxlcjoge30sIHNsaWRhYmxlOiB0cnVlLCB0aXA6IG51bGwsIHN0ZXA6IG51bGwsIG1heFdpZHRoOiBudWxsLCBtYXhIZWlnaHQ6IG51bGwsIGRlZmF1bHRDZmc6IHtcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICBhbGlnbjogJ3JhaWwnLFxuICAgICAgICAgICAgICAgICAgICBzcGFjaW5nOiA1LFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6IHRoZW1lXzEuZGVmYXVsdC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaGFuZGxlcjoge1xuICAgICAgICAgICAgICAgICAgICBzaXplOiAxMCxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJyMzMzMnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdHJhY2s6IHt9LFxuICAgICAgICAgICAgICAgIHJhaWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbG9yJyxcbiAgICAgICAgICAgICAgICAgICAgc2l6ZTogMjAsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRMZW5ndGg6IDEwMCxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjRENERUUyJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiB0aGVtZV8xLmRlZmF1bHQudGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAndG9wJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSB9KTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5pc1NsaWRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICAvLyDlrp7njrAgSUxpc3Qg5o6l5Y+jXG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmdldFZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50VmFsdWUoKTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5nZXRSYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1pbjogdGhpcy5nZXQoJ21pbicpLFxuICAgICAgICAgICAgbWF4OiB0aGlzLmdldCgnbWF4JyksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvLyDmlLnlj5ggcmFuZ2VcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuc2V0UmFuZ2UgPSBmdW5jdGlvbiAobWluLCBtYXgpIHtcbiAgICAgICAgdGhpcy51cGRhdGUoe1xuICAgICAgICAgICAgbWluOiBtaW4sXG4gICAgICAgICAgICBtYXg6IG1heCxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuc2V0VmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIG9yaWdpblZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpO1xuICAgICAgICB0aGlzLnNldCgndmFsdWUnLCB2YWx1ZSk7XG4gICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2V0KCdncm91cCcpO1xuICAgICAgICB0aGlzLnJlc2V0VHJhY2tDbGlwKCk7XG4gICAgICAgIGlmICh0aGlzLmdldCgnc2xpZGFibGUnKSkge1xuICAgICAgICAgICAgdGhpcy5yZXNldEhhbmRsZXJzKGdyb3VwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlbGVnYXRlRW1pdCgndmFsdWVjaGFuZ2VkJywge1xuICAgICAgICAgICAgb3JpZ2luVmFsdWU6IG9yaWdpblZhbHVlLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5pbml0RXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2V0KCdncm91cCcpO1xuICAgICAgICB0aGlzLmJpbmRTbGlkZXJFdmVudChncm91cCk7XG4gICAgICAgIHRoaXMuYmluZFJhaWxFdmVudChncm91cCk7XG4gICAgICAgIHRoaXMuYmluZFRyYWNrRXZlbnQoZ3JvdXApO1xuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmRyYXdMZWdlbmRDb250ZW50ID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHRoaXMuZHJhd1JhaWwoZ3JvdXApO1xuICAgICAgICB0aGlzLmRyYXdMYWJlbHMoZ3JvdXApO1xuICAgICAgICB0aGlzLmZpeGVkRWxlbWVudHMoZ3JvdXApOyAvLyDosIPmlbTlkITkuKrlm77lvaLkvY3nva7vvIzpgILlupTlrr3pq5jnmoTpmZDliLZcbiAgICAgICAgdGhpcy5yZXNldFRyYWNrKGdyb3VwKTtcbiAgICAgICAgdGhpcy5yZXNldFRyYWNrQ2xpcChncm91cCk7XG4gICAgICAgIGlmICh0aGlzLmdldCgnc2xpZGFibGUnKSkge1xuICAgICAgICAgICAgdGhpcy5yZXNldEhhbmRsZXJzKGdyb3VwKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmJpbmRTbGlkZXJFdmVudCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB0aGlzLmJpbmRIYW5kbGVyc0V2ZW50KGdyb3VwKTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5iaW5kSGFuZGxlcnNFdmVudCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICBncm91cC5vbignbGVnZW5kLWhhbmRsZXItbWluOmRyYWcnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBtaW5WYWx1ZSA9IF90aGlzLmdldFZhbHVlQnlDYW52YXNQb2ludChldi54LCBldi55KTtcbiAgICAgICAgICAgIHZhciBjdXJyZW50VmFsdWUgPSBfdGhpcy5nZXRDdXJyZW50VmFsdWUoKTtcbiAgICAgICAgICAgIHZhciBtYXhWYWx1ZSA9IGN1cnJlbnRWYWx1ZVsxXTtcbiAgICAgICAgICAgIGlmIChtYXhWYWx1ZSA8IG1pblZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5bCP5LqO5pyA5bCP5YC877yM5YiZ6LCD5pW05pyA5bCP5YC8XG4gICAgICAgICAgICAgICAgbWF4VmFsdWUgPSBtaW5WYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF90aGlzLnNldFZhbHVlKFttaW5WYWx1ZSwgbWF4VmFsdWVdKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGdyb3VwLm9uKCdsZWdlbmQtaGFuZGxlci1tYXg6ZHJhZycsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgdmFyIG1heFZhbHVlID0gX3RoaXMuZ2V0VmFsdWVCeUNhbnZhc1BvaW50KGV2LngsIGV2LnkpO1xuICAgICAgICAgICAgdmFyIGN1cnJlbnRWYWx1ZSA9IF90aGlzLmdldEN1cnJlbnRWYWx1ZSgpO1xuICAgICAgICAgICAgdmFyIG1pblZhbHVlID0gY3VycmVudFZhbHVlWzBdO1xuICAgICAgICAgICAgaWYgKG1pblZhbHVlID4gbWF4VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzlsI/kuo7mnIDlsI/lgLzvvIzliJnosIPmlbTmnIDlsI/lgLxcbiAgICAgICAgICAgICAgICBtaW5WYWx1ZSA9IG1heFZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMuc2V0VmFsdWUoW21pblZhbHVlLCBtYXhWYWx1ZV0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5iaW5kUmFpbEV2ZW50ID0gZnVuY3Rpb24gKGdyb3VwKSB7IH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmJpbmRUcmFja0V2ZW50ID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwcmVQb2ludCA9IG51bGw7XG4gICAgICAgIGdyb3VwLm9uKCdsZWdlbmQtdHJhY2s6ZHJhZ3N0YXJ0JywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBwcmVQb2ludCA9IHtcbiAgICAgICAgICAgICAgICB4OiBldi54LFxuICAgICAgICAgICAgICAgIHk6IGV2LnksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgZ3JvdXAub24oJ2xlZ2VuZC10cmFjazpkcmFnJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBpZiAoIXByZVBvaW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHByZVZhbHVlID0gX3RoaXMuZ2V0VmFsdWVCeUNhbnZhc1BvaW50KHByZVBvaW50LngsIHByZVBvaW50LnkpO1xuICAgICAgICAgICAgdmFyIGN1clZhbHVlID0gX3RoaXMuZ2V0VmFsdWVCeUNhbnZhc1BvaW50KGV2LngsIGV2LnkpO1xuICAgICAgICAgICAgdmFyIGN1cnJlbnRWYWx1ZSA9IF90aGlzLmdldEN1cnJlbnRWYWx1ZSgpO1xuICAgICAgICAgICAgdmFyIGN1ckRpZmYgPSBjdXJyZW50VmFsdWVbMV0gLSBjdXJyZW50VmFsdWVbMF07XG4gICAgICAgICAgICB2YXIgcmFuZ2UgPSBfdGhpcy5nZXRSYW5nZSgpO1xuICAgICAgICAgICAgdmFyIGRWYWx1ZSA9IGN1clZhbHVlIC0gcHJlVmFsdWU7XG4gICAgICAgICAgICBpZiAoZFZhbHVlIDwgMCkge1xuICAgICAgICAgICAgICAgIC8vIOWHj+Wwjywg5ZCM5pe25pyq5Ye66L6555WMXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZVswXSArIGRWYWx1ZSA+IHJhbmdlLm1pbikge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRWYWx1ZShbY3VycmVudFZhbHVlWzBdICsgZFZhbHVlLCBjdXJyZW50VmFsdWVbMV0gKyBkVmFsdWVdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFZhbHVlKFtyYW5nZS5taW4sIHJhbmdlLm1pbiArIGN1ckRpZmZdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gICYmIHx8XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkVmFsdWUgPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRWYWx1ZSA+IDAgJiYgY3VycmVudFZhbHVlWzFdICsgZFZhbHVlIDwgcmFuZ2UubWF4KSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFZhbHVlKFtjdXJyZW50VmFsdWVbMF0gKyBkVmFsdWUsIGN1cnJlbnRWYWx1ZVsxXSArIGRWYWx1ZV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0VmFsdWUoW3JhbmdlLm1heCAtIGN1ckRpZmYsIHJhbmdlLm1heF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHByZVBvaW50ID0ge1xuICAgICAgICAgICAgICAgIHg6IGV2LngsXG4gICAgICAgICAgICAgICAgeTogZXYueSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICBncm91cC5vbignbGVnZW5kLXRyYWNrOmRyYWdlbmQnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHByZVBvaW50ID0gbnVsbDtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZHJhd0xhYmVscyA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB0aGlzLmRyYXdMYWJlbCgnbWluJywgZ3JvdXApO1xuICAgICAgICB0aGlzLmRyYXdMYWJlbCgnbWF4JywgZ3JvdXApO1xuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmRyYXdMYWJlbCA9IGZ1bmN0aW9uIChuYW1lLCBncm91cCkge1xuICAgICAgICB2YXIgbGFiZWxDZmcgPSB0aGlzLmdldCgnbGFiZWwnKTtcbiAgICAgICAgdmFyIHN0eWxlID0gbGFiZWxDZmcuc3R5bGU7XG4gICAgICAgIHZhciBsYWJlbEFsaWduID0gbGFiZWxDZmcuYWxpZ247XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KG5hbWUpO1xuICAgICAgICB2YXIgYWxpZ25BdHRycyA9IHRoaXMuZ2V0TGFiZWxBbGlnbkF0dHJzKG5hbWUsIGxhYmVsQWxpZ24pO1xuICAgICAgICB2YXIgbG9jYWxJZCA9IFwibGFiZWwtXCIgKyBuYW1lO1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQobG9jYWxJZCksXG4gICAgICAgICAgICBuYW1lOiBcImxlZ2VuZC1sYWJlbC1cIiArIG5hbWUsXG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHsgeDogMCwgeTogMCwgdGV4dDogdmFsdWUgfSwgc3R5bGUpLCBhbGlnbkF0dHJzKSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDojrflj5bmlofmnKznmoTlr7npvZDmlrnlvI/vvIzkuLrkuoboh6rpgILlupTnnJ/lrp7mk43noo7kuoblv4NcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZ2V0TGFiZWxBbGlnbkF0dHJzID0gZnVuY3Rpb24gKG5hbWUsIGFsaWduKSB7XG4gICAgICAgIHZhciBpc1ZlcnRpY2FsID0gdGhpcy5pc1ZlcnRpY2FsKCk7XG4gICAgICAgIHZhciB0ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgdmFyIHRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgICAgICBpZiAoaXNWZXJ0aWNhbCkge1xuICAgICAgICAgICAgLy8g5Z6C55u05biD5bGA55qE5omA5pyJ55qE5paH5pys6YO95bem5a+56b2QXG4gICAgICAgICAgICB0ZXh0QWxpZ24gPSAnc3RhcnQnO1xuICAgICAgICAgICAgaWYgKGFsaWduICE9PSAncmFpbCcpIHtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gJ21pbicpIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmUgPSAnYm90dG9tJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmUgPSAndG9wJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChhbGlnbiAhPT0gJ3JhaWwnKSB7XG4gICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdtaW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdzdGFydCc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ24gPSAnZW5kJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ZXh0QWxpZ24gPSAnc3RhcnQnO1xuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXh0QWxpZ246IHRleHRBbGlnbixcbiAgICAgICAgICAgIHRleHRCYXNlbGluZTogdGV4dEJhc2VsaW5lLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmdldFJhaWxQYXRoID0gZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcbiAgICAgICAgdmFyIHJhaWxDZmcgPSB0aGlzLmdldCgncmFpbCcpO1xuICAgICAgICB2YXIgc2l6ZSA9IHJhaWxDZmcuc2l6ZSwgZGVmYXVsdExlbmd0aCA9IHJhaWxDZmcuZGVmYXVsdExlbmd0aCwgdHlwZSA9IHJhaWxDZmcudHlwZTtcbiAgICAgICAgdmFyIGlzVmVydGljYWwgPSB0aGlzLmlzVmVydGljYWwoKTtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGRlZmF1bHRMZW5ndGg7XG4gICAgICAgIHZhciB3aWR0aCA9IHc7XG4gICAgICAgIHZhciBoZWlnaHQgPSBoO1xuICAgICAgICBpZiAoIXdpZHRoKSB7XG4gICAgICAgICAgICB3aWR0aCA9IGlzVmVydGljYWwgPyBzaXplIDogbGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaGVpZ2h0KSB7XG4gICAgICAgICAgICBoZWlnaHQgPSBpc1ZlcnRpY2FsID8gbGVuZ3RoIDogc2l6ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGF0aCA9IFtdO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2NvbG9yJykge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHgsIHldKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB4ICsgd2lkdGgsIHldKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB4ICsgd2lkdGgsIHkgKyBoZWlnaHRdKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB4LCB5ICsgaGVpZ2h0XSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydaJ10pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHggKyB3aWR0aCwgeV0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHggKyB3aWR0aCwgeSArIGhlaWdodF0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHgsIHkgKyBoZWlnaHRdKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ1onXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfTtcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZHJhd1JhaWwgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHJhaWxDZmcgPSB0aGlzLmdldCgncmFpbCcpO1xuICAgICAgICB2YXIgc3R5bGUgPSByYWlsQ2ZnLnN0eWxlO1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3JhaWwnKSxcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtcmFpbCcsXG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IHRoaXMuZ2V0UmFpbFBhdGgoMCwgMCkgfSwgc3R5bGUpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOWwhuS8oOWFpeeahOminOiJsui9rOaNouaIkOa4kOWPmOiJslxuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5nZXRUcmFja0NvbG9yID0gZnVuY3Rpb24gKGNvbG9ycykge1xuICAgICAgICB2YXIgY291bnQgPSBjb2xvcnMubGVuZ3RoO1xuICAgICAgICBpZiAoIWNvdW50KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBjb2xvcnNbMF07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbG9yOyAvLyDmnIDnu4jlvaLmgIEgbCgwKSAwOmNvbG9yc1swXSAwLjU6Y29sb3JzWzFdIDE6Y29sb3JzWzJdO1xuICAgICAgICBpZiAodGhpcy5pc1ZlcnRpY2FsKCkpIHtcbiAgICAgICAgICAgIC8vIOagueaNruaWueWQkeiuvue9rua4kOWPmOaWueWQkVxuICAgICAgICAgICAgY29sb3IgPSAnbCg5MCknO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29sb3IgPSAnbCgwKSc7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcGVyY2VudCA9IGkgLyAoY291bnQgLSAxKTtcbiAgICAgICAgICAgIGNvbG9yICs9IFwiIFwiICsgcGVyY2VudCArIFwiOlwiICsgY29sb3JzW2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5nZXRUcmFja1BhdGggPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHJhaWxTaGFwZSA9IHRoaXMuZ2V0UmFpbFNoYXBlKGdyb3VwKTtcbiAgICAgICAgdmFyIHBhdGggPSByYWlsU2hhcGUuYXR0cigncGF0aCcpO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmNsb25lKHBhdGgpO1xuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmdldENsaXBUcmFja0F0dHJzID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0Q3VycmVudFZhbHVlKCk7XG4gICAgICAgIHZhciBtaW4gPSB2YWx1ZVswXSwgbWF4ID0gdmFsdWVbMV07XG4gICAgICAgIHZhciByYWlsQkJveCA9IHRoaXMuZ2V0UmFpbEJCb3goZ3JvdXApO1xuICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHRoaXMuZ2V0UG9pbnRCeVZhbHVlKG1pbiwgZ3JvdXApO1xuICAgICAgICB2YXIgZW5kUG9pbnQgPSB0aGlzLmdldFBvaW50QnlWYWx1ZShtYXgsIGdyb3VwKTtcbiAgICAgICAgdmFyIGlzVmVydGljYWwgPSB0aGlzLmlzVmVydGljYWwoKTtcbiAgICAgICAgdmFyIHg7XG4gICAgICAgIHZhciB5O1xuICAgICAgICB2YXIgd2lkdGg7XG4gICAgICAgIHZhciBoZWlnaHQ7XG4gICAgICAgIGlmIChpc1ZlcnRpY2FsKSB7XG4gICAgICAgICAgICB4ID0gcmFpbEJCb3gubWluWDtcbiAgICAgICAgICAgIHkgPSBzdGFydFBvaW50Lnk7XG4gICAgICAgICAgICB3aWR0aCA9IHJhaWxCQm94LndpZHRoO1xuICAgICAgICAgICAgaGVpZ2h0ID0gZW5kUG9pbnQueSAtIHN0YXJ0UG9pbnQueTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHggPSBzdGFydFBvaW50Lng7XG4gICAgICAgICAgICB5ID0gcmFpbEJCb3gubWluWTtcbiAgICAgICAgICAgIHdpZHRoID0gZW5kUG9pbnQueCAtIHN0YXJ0UG9pbnQueDtcbiAgICAgICAgICAgIGhlaWdodCA9IHJhaWxCQm94LmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8vIOiOt+WPliB0cmFjayDnmoTlsZ7mgKfvvIznlLEgcGF0aCDlkowg6aKc6Imy5p6E5oiQXG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmdldFRyYWNrQXR0cnMgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHRyYWNrQ2ZnID0gdGhpcy5nZXQoJ3RyYWNrJyk7XG4gICAgICAgIHZhciBjb2xvcnMgPSB0aGlzLmdldCgnY29sb3JzJyk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5nZXRUcmFja1BhdGgoZ3JvdXApO1xuICAgICAgICByZXR1cm4gdXRpbF8xLm1peCh7XG4gICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgZmlsbDogdGhpcy5nZXRUcmFja0NvbG9yKGNvbG9ycyksXG4gICAgICAgIH0sIHRyYWNrQ2ZnLnN0eWxlKTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5yZXNldFRyYWNrQ2xpcCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gZ3JvdXAgfHwgdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIHZhciB0cmFja0lkID0gdGhpcy5nZXRFbGVtZW50SWQoJ3RyYWNrJyk7XG4gICAgICAgIHZhciB0cmFja1NoYXBlID0gY29udGFpbmVyLmZpbmRCeUlkKHRyYWNrSWQpO1xuICAgICAgICB2YXIgY2xpcFNoYXBlID0gdHJhY2tTaGFwZS5nZXRDbGlwKCk7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuZ2V0Q2xpcFRyYWNrQXR0cnMoZ3JvdXApO1xuICAgICAgICBpZiAoIWNsaXBTaGFwZSkge1xuICAgICAgICAgICAgdHJhY2tTaGFwZS5zZXRDbGlwKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICAgICAgYXR0cnM6IGF0dHJzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjbGlwU2hhcGUuYXR0cihhdHRycyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5yZXNldFRyYWNrID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciB0cmFja0lkID0gdGhpcy5nZXRFbGVtZW50SWQoJ3RyYWNrJyk7XG4gICAgICAgIHZhciB0cmFja1NoYXBlID0gZ3JvdXAuZmluZEJ5SWQodHJhY2tJZCk7XG4gICAgICAgIHZhciB0cmFja0F0dHJzID0gdGhpcy5nZXRUcmFja0F0dHJzKGdyb3VwKTtcbiAgICAgICAgaWYgKHRyYWNrU2hhcGUpIHtcbiAgICAgICAgICAgIHRyYWNrU2hhcGUuYXR0cih0cmFja0F0dHJzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgICAgICAgICAgaWQ6IHRyYWNrSWQsXG4gICAgICAgICAgICAgICAgZHJhZ2dhYmxlOiB0aGlzLmdldCgnc2xpZGFibGUnKSxcbiAgICAgICAgICAgICAgICBuYW1lOiAnbGVnZW5kLXRyYWNrJyxcbiAgICAgICAgICAgICAgICBhdHRyczogdHJhY2tBdHRycyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZ2V0UG9pbnRCeVZhbHVlID0gZnVuY3Rpb24gKHZhbHVlLCBncm91cCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldFJhbmdlKCksIG1pbiA9IF9hLm1pbiwgbWF4ID0gX2EubWF4O1xuICAgICAgICB2YXIgcGVyY2VudCA9ICh2YWx1ZSAtIG1pbikgLyAobWF4IC0gbWluKTtcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldFJhaWxCQm94KGdyb3VwKTtcbiAgICAgICAgdmFyIGlzVmVydGNhbCA9IHRoaXMuaXNWZXJ0aWNhbCgpO1xuICAgICAgICB2YXIgcG9pbnQgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgaWYgKGlzVmVydGNhbCkge1xuICAgICAgICAgICAgcG9pbnQueCA9IGJib3gubWluWCArIGJib3gud2lkdGggLyAyO1xuICAgICAgICAgICAgcG9pbnQueSA9IHV0aWxfMi5nZXRWYWx1ZUJ5UGVyY2VudChiYm94Lm1pblksIGJib3gubWF4WSwgcGVyY2VudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwb2ludC54ID0gdXRpbF8yLmdldFZhbHVlQnlQZXJjZW50KGJib3gubWluWCwgYmJveC5tYXhYLCBwZXJjZW50KTtcbiAgICAgICAgICAgIHBvaW50LnkgPSBiYm94Lm1pblkgKyBiYm94LmhlaWdodCAvIDI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBvaW50O1xuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmdldFJhaWxTaGFwZSA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gZ3JvdXAgfHwgdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIHJldHVybiBjb250YWluZXIuZmluZEJ5SWQodGhpcy5nZXRFbGVtZW50SWQoJ3JhaWwnKSk7XG4gICAgfTtcbiAgICAvLyDojrflj5bmu5HovajnmoTlrr3pq5jkv6Hmga9cbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZ2V0UmFpbEJCb3ggPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHJhaWxTaGFwZSA9IHRoaXMuZ2V0UmFpbFNoYXBlKGdyb3VwKTtcbiAgICAgICAgdmFyIGJib3ggPSByYWlsU2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICByZXR1cm4gYmJveDtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5nZXRSYWlsQ2FudmFzQkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0KCdncm91cCcpO1xuICAgICAgICB2YXIgcmFpbFNoYXBlID0gY29udGFpbmVyLmZpbmRCeUlkKHRoaXMuZ2V0RWxlbWVudElkKCdyYWlsJykpO1xuICAgICAgICB2YXIgYmJveCA9IHJhaWxTaGFwZS5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgIHJldHVybiBiYm94O1xuICAgIH07XG4gICAgLy8g5piv5ZCm5Z6C55u0XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmlzVmVydGljYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnbGF5b3V0JykgPT09ICd2ZXJ0aWNhbCc7XG4gICAgfTtcbiAgICAvLyDnlKjkuo7kuqTkupLml7ZcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZ2V0VmFsdWVCeUNhbnZhc1BvaW50ID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRSYW5nZSgpLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heDtcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldFJhaWxDYW52YXNCQm94KCk7IC8vIOWboOS4uiB4LCB5IOaYr+eUu+W4g+WdkOagh1xuICAgICAgICB2YXIgaXNWZXJ0Y2FsID0gdGhpcy5pc1ZlcnRpY2FsKCk7XG4gICAgICAgIHZhciBzdGVwID0gdGhpcy5nZXQoJ3N0ZXAnKTtcbiAgICAgICAgdmFyIHBlcmNlbnQ7XG4gICAgICAgIGlmIChpc1ZlcnRjYWwpIHtcbiAgICAgICAgICAgIC8vIOWeguebtOaXtuiuoeeulyB5XG4gICAgICAgICAgICBwZXJjZW50ID0gKHkgLSBiYm94Lm1pblkpIC8gYmJveC5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDmsLTlubPml7borqHnrpcgeFxuICAgICAgICAgICAgcGVyY2VudCA9ICh4IC0gYmJveC5taW5YKSAvIGJib3gud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHZhbHVlID0gdXRpbF8yLmdldFZhbHVlQnlQZXJjZW50KG1pbiwgbWF4LCBwZXJjZW50KTtcbiAgICAgICAgaWYgKHN0ZXApIHtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IE1hdGgucm91bmQoKHZhbHVlIC0gbWluKSAvIHN0ZXApO1xuICAgICAgICAgICAgdmFsdWUgPSBtaW4gKyBjb3VudCAqIHN0ZXA7IC8vIOenu+WKqOWIsOacgOi/keeahFxuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSA+IG1heCkge1xuICAgICAgICAgICAgdmFsdWUgPSBtYXg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlIDwgbWluKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG1pbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgICAvLyDlvZPliY3pgInkuK3nmoTojIPlm7RcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuZ2V0Q3VycmVudFZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmdldCgndmFsdWUnKTtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgLy8g5aaC5p6c5rKh5pyJ5a6a5LmJ77yM5Y+W5pyA5aSn6IyD5Zu0XG4gICAgICAgICAgICB2YWx1ZSA9IFt0aGlzLmdldCgnbWluJyksIHRoaXMuZ2V0KCdtYXgnKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgLy8g6YeN572u5ruR5Z2XIGhhbmRsZXJcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUucmVzZXRIYW5kbGVycyA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgY3VycmVudFZhbHVlID0gdGhpcy5nZXRDdXJyZW50VmFsdWUoKTtcbiAgICAgICAgdmFyIG1pbiA9IGN1cnJlbnRWYWx1ZVswXSwgbWF4ID0gY3VycmVudFZhbHVlWzFdO1xuICAgICAgICB0aGlzLnJlc2V0SGFuZGxlcihncm91cCwgJ21pbicsIG1pbik7XG4gICAgICAgIHRoaXMucmVzZXRIYW5kbGVyKGdyb3VwLCAnbWF4JywgbWF4KTtcbiAgICB9O1xuICAgIC8vIOiOt+WPlua7keWdl+eahCBwYXRoXG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmdldEhhbmRsZXJQYXRoID0gZnVuY3Rpb24gKGhhbmRsZXJDZmcsIHBvaW50KSB7XG4gICAgICAgIHZhciBpc1ZlcnRpY2FsID0gdGhpcy5pc1ZlcnRpY2FsKCk7XG4gICAgICAgIHZhciBwYXRoID0gW107XG4gICAgICAgIHZhciB3aWR0aCA9IGhhbmRsZXJDZmcuc2l6ZTtcbiAgICAgICAgdmFyIHggPSBwb2ludC54LCB5ID0gcG9pbnQueTtcbiAgICAgICAgdmFyIGhlaWdodCA9IHdpZHRoICogSEFORExFUl9IRUlHSFRfUkFUSU87XG4gICAgICAgIHZhciBoYWxmV2lkdGggPSB3aWR0aCAvIDI7XG4gICAgICAgIHZhciBvbmVTaXh0aFdpZHRoID0gd2lkdGggLyA2O1xuICAgICAgICBpZiAoaXNWZXJ0aWNhbCkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDnq5bnm7Tmg4XlhrXkuIvnmoTmu5HlnZcgaGFuZGxlcu+8jOW3puS+p+mhtueCueaYryB4LHlcbiAgICAgICAgICAgICAqICAvLS0tLXxcbiAgICAgICAgICAgICAqICAgIC0tIHxcbiAgICAgICAgICAgICAqICAgIC0tIHxcbiAgICAgICAgICAgICAqICBcXC0tLS18XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHZhciB0cmlhbmdsZVggPSB4ICsgaGVpZ2h0ICogSEFORExFUl9UUklBTkdMRV9SQVRJTztcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCB4LCB5XSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgdHJpYW5nbGVYLCB5ICsgaGFsZldpZHRoXSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgeCArIGhlaWdodCwgeSArIGhhbGZXaWR0aF0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHggKyBoZWlnaHQsIHkgLSBoYWxmV2lkdGhdKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB0cmlhbmdsZVgsIHkgLSBoYWxmV2lkdGhdKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ1onXSk7XG4gICAgICAgICAgICAvLyDnu5jliLbkuKTmnaHmqKrnur9cbiAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCB0cmlhbmdsZVgsIHkgKyBvbmVTaXh0aFdpZHRoXSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgeCArIGhlaWdodCAtIDIsIHkgKyBvbmVTaXh0aFdpZHRoXSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydNJywgdHJpYW5nbGVYLCB5IC0gb25lU2l4dGhXaWR0aF0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHggKyBoZWlnaHQgLSAyLCB5IC0gb25lU2l4dGhXaWR0aF0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDmsLTlubPmg4XlhrXkuIvnmoTmu5HlnZfvvIzkuIrpnaLpobbngrnlpITmmK8geCx5XG4gICAgICAgICAgICAgKiAgLyAgIFxcXG4gICAgICAgICAgICAgKiB8IHwgfCB8XG4gICAgICAgICAgICAgKiB8IHwgfCB8XG4gICAgICAgICAgICAgKiAgLS0tLS1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdmFyIHRyaWFuZ2xlWSA9IHkgKyBoZWlnaHQgKiBIQU5ETEVSX1RSSUFOR0xFX1JBVElPO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHgsIHldKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB4IC0gaGFsZldpZHRoLCB0cmlhbmdsZVldKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB4IC0gaGFsZldpZHRoLCB5ICsgaGVpZ2h0XSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgeCArIGhhbGZXaWR0aCwgeSArIGhlaWdodF0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHggKyBoYWxmV2lkdGgsIHRyaWFuZ2xlWV0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnWiddKTtcbiAgICAgICAgICAgIC8vIOe7mOWItuS4pOadoeerlue6v1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHggLSBvbmVTaXh0aFdpZHRoLCB0cmlhbmdsZVldKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCB4IC0gb25lU2l4dGhXaWR0aCwgeSArIGhlaWdodCAtIDJdKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCB4ICsgb25lU2l4dGhXaWR0aCwgdHJpYW5nbGVZXSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgeCArIG9uZVNpeHRoV2lkdGgsIHkgKyBoZWlnaHQgLSAyXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfTtcbiAgICAvLyDosIPmlbQgaGFuZGxlciDnmoTkvY3nva7vvIzlpoLmnpzmnKrlrZjlnKjliJnnu5jliLZcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUucmVzZXRIYW5kbGVyID0gZnVuY3Rpb24gKGdyb3VwLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICB2YXIgcG9pbnQgPSB0aGlzLmdldFBvaW50QnlWYWx1ZSh2YWx1ZSwgZ3JvdXApO1xuICAgICAgICB2YXIgaGFuZGxlckNmZyA9IHRoaXMuZ2V0KCdoYW5kbGVyJyk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5nZXRIYW5kbGVyUGF0aChoYW5kbGVyQ2ZnLCBwb2ludCk7XG4gICAgICAgIHZhciBpZCA9IHRoaXMuZ2V0RWxlbWVudElkKFwiaGFuZGxlci1cIiArIG5hbWUpO1xuICAgICAgICB2YXIgaGFuZGxlclNoYXBlID0gZ3JvdXAuZmluZEJ5SWQoaWQpO1xuICAgICAgICB2YXIgaXNWZXJ0aWNhbCA9IHRoaXMuaXNWZXJ0aWNhbCgpO1xuICAgICAgICBpZiAoaGFuZGxlclNoYXBlKSB7XG4gICAgICAgICAgICBoYW5kbGVyU2hhcGUuYXR0cigncGF0aCcsIHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgICAgICBuYW1lOiBcImxlZ2VuZC1oYW5kbGVyLVwiICsgbmFtZSxcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyBwYXRoOiBwYXRoIH0sIGhhbmRsZXJDZmcuc3R5bGUpLCB7IGN1cnNvcjogaXNWZXJ0aWNhbCA/ICducy1yZXNpemUnIDogJ2V3LXJlc2l6ZScgfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5b2T6K6+572u5LqGIG1heFdpZHRoLCBtYXhIZWlnaHQg5pe26LCD5pW0IHJhaWwg55qE5a695bqm77yMXG4gICAgLy8g5paH5pys55qE5L2N572uXG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmZpeGVkRWxlbWVudHMgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHJhaWxTaGFwZSA9IGdyb3VwLmZpbmRCeUlkKHRoaXMuZ2V0RWxlbWVudElkKCdyYWlsJykpO1xuICAgICAgICB2YXIgbWluTGFiZWwgPSBncm91cC5maW5kQnlJZCh0aGlzLmdldEVsZW1lbnRJZCgnbGFiZWwtbWluJykpO1xuICAgICAgICB2YXIgbWF4TGFiZWwgPSBncm91cC5maW5kQnlJZCh0aGlzLmdldEVsZW1lbnRJZCgnbGFiZWwtbWF4JykpO1xuICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHRoaXMuZ2V0RHJhd1BvaW50KCk7XG4gICAgICAgIGlmICh0aGlzLmlzVmVydGljYWwoKSkge1xuICAgICAgICAgICAgLy8g5qiq5ZCR5biD5bGAXG4gICAgICAgICAgICB0aGlzLmZpeGVkVmVydGFpbChtaW5MYWJlbCwgbWF4TGFiZWwsIHJhaWxTaGFwZSwgc3RhcnRQb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDmsLTlubPluIPlsYBcbiAgICAgICAgICAgIHRoaXMuZml4ZWRIb3Jpem9udGFsKG1pbkxhYmVsLCBtYXhMYWJlbCwgcmFpbFNoYXBlLCBzdGFydFBvaW50KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmZpdFJhaWxMZW5ndGggPSBmdW5jdGlvbiAobWluTGFiZWxCQm94LCBtYXhMYWJlbEJCb3gsIHJhaWxCQm94LCByYWlsU2hhcGUpIHtcbiAgICAgICAgdmFyIGlzVmVydGljYWwgPSB0aGlzLmlzVmVydGljYWwoKTtcbiAgICAgICAgdmFyIGxlbmd0aEZpZWxkID0gaXNWZXJ0aWNhbCA/ICdoZWlnaHQnIDogJ3dpZHRoJztcbiAgICAgICAgdmFyIGxhYmVsQ2ZnID0gdGhpcy5nZXQoJ2xhYmVsJyk7XG4gICAgICAgIHZhciBsYWJlbEFsaWduID0gbGFiZWxDZmcuYWxpZ247XG4gICAgICAgIHZhciBzcGFjaW5nID0gbGFiZWxDZmcuc3BhY2luZztcbiAgICAgICAgdmFyIG1heExlbmd0aCA9IHRoaXMuZ2V0KFwibWF4XCIgKyB1dGlsXzEudXBwZXJGaXJzdChsZW5ndGhGaWVsZCkpOyAvLyBnZXQoJ21heFdpZHRoJylcbiAgICAgICAgaWYgKG1heExlbmd0aCkge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRzTGVuZ3RoID0gbGFiZWxBbGlnbiA9PT0gJ3JhaWwnXG4gICAgICAgICAgICAgICAgPyByYWlsQkJveFtsZW5ndGhGaWVsZF0gKyBtaW5MYWJlbEJCb3hbbGVuZ3RoRmllbGRdICsgbWF4TGFiZWxCQm94W2xlbmd0aEZpZWxkXSArIHNwYWNpbmcgKiAyXG4gICAgICAgICAgICAgICAgOiByYWlsQkJveFtsZW5ndGhGaWVsZF07XG4gICAgICAgICAgICB2YXIgZGlmZiA9IGVsZW1lbnRzTGVuZ3RoIC0gbWF4TGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGRpZmYgPiAwKSB7XG4gICAgICAgICAgICAgICAgLy8g5aSn5LqO6ZmQ5Yi255qE6ZW/5bqmXG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VSYWlsTGVuZ3RoKHJhaWxTaGFwZSwgbGVuZ3RoRmllbGQsIHJhaWxCQm94W2xlbmd0aEZpZWxkXSAtIGRpZmYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBDb250aW51ZUxlZ2VuZC5wcm90b3R5cGUuY2hhbmdlUmFpbExlbmd0aCA9IGZ1bmN0aW9uIChyYWlsU2hhcGUsIGxlbmd0aEZpZWxkLCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGJib3ggPSByYWlsU2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgcGF0aDtcbiAgICAgICAgaWYgKGxlbmd0aEZpZWxkID09PSAnaGVpZ2h0Jykge1xuICAgICAgICAgICAgcGF0aCA9IHRoaXMuZ2V0UmFpbFBhdGgoYmJveC54LCBiYm94LnksIGJib3gud2lkdGgsIGxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwYXRoID0gdGhpcy5nZXRSYWlsUGF0aChiYm94LngsIGJib3gueSwgbGVuZ3RoLCBiYm94LmhlaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgcmFpbFNoYXBlLmF0dHIoJ3BhdGgnLCBwYXRoKTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5jaGFuZ2VSYWlsUG9zaXRpb24gPSBmdW5jdGlvbiAocmFpbFNoYXBlLCB4LCB5KSB7XG4gICAgICAgIHZhciBiYm94ID0gcmFpbFNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldFJhaWxQYXRoKHgsIHksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICAgICAgcmFpbFNoYXBlLmF0dHIoJ3BhdGgnLCBwYXRoKTtcbiAgICB9O1xuICAgIENvbnRpbnVlTGVnZW5kLnByb3RvdHlwZS5maXhlZEhvcml6b250YWwgPSBmdW5jdGlvbiAobWluTGFiZWwsIG1heExhYmVsLCByYWlsU2hhcGUsIHN0YXJ0UG9pbnQpIHtcbiAgICAgICAgdmFyIGxhYmVsQ2ZnID0gdGhpcy5nZXQoJ2xhYmVsJyk7XG4gICAgICAgIHZhciBsYWJlbEFsaWduID0gbGFiZWxDZmcuYWxpZ247XG4gICAgICAgIHZhciBzcGFjaW5nID0gbGFiZWxDZmcuc3BhY2luZztcbiAgICAgICAgdmFyIHJhaWxCQm94ID0gcmFpbFNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdmFyIG1pbkxhYmVsQkJveCA9IG1pbkxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgdmFyIG1heExhYmVsQkJveCA9IG1heExhYmVsLmdldEJCb3goKTtcbiAgICAgICAgdmFyIHJhaWxIZWlnaHQgPSByYWlsQkJveC5oZWlnaHQ7IC8vIOWPliByYWlsIOeahOmrmOW6pu+8jOS9nOS4uumrmOW6plxuICAgICAgICB0aGlzLmZpdFJhaWxMZW5ndGgobWluTGFiZWxCQm94LCBtYXhMYWJlbEJCb3gsIHJhaWxCQm94LCByYWlsU2hhcGUpO1xuICAgICAgICByYWlsQkJveCA9IHJhaWxTaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIGlmIChsYWJlbEFsaWduID09PSAncmFpbCcpIHtcbiAgICAgICAgICAgIC8vIOayv+edgCByYWlsIOaWueWQkVxuICAgICAgICAgICAgbWluTGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgeDogc3RhcnRQb2ludC54LFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSArIHJhaWxIZWlnaHQgLyAyLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZVJhaWxQb3NpdGlvbihyYWlsU2hhcGUsIHN0YXJ0UG9pbnQueCArIG1pbkxhYmVsQkJveC53aWR0aCArIHNwYWNpbmcsIHN0YXJ0UG9pbnQueSk7XG4gICAgICAgICAgICBtYXhMYWJlbC5hdHRyKHtcbiAgICAgICAgICAgICAgICB4OiBzdGFydFBvaW50LnggKyBtaW5MYWJlbEJCb3gud2lkdGggKyByYWlsQkJveC53aWR0aCArIHNwYWNpbmcgKiAyLFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSArIHJhaWxIZWlnaHQgLyAyLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobGFiZWxBbGlnbiA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgIG1pbkxhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0UG9pbnQueCxcbiAgICAgICAgICAgICAgICB5OiBzdGFydFBvaW50LnksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1heExhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0UG9pbnQueCArIHJhaWxCQm94LndpZHRoLFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VSYWlsUG9zaXRpb24ocmFpbFNoYXBlLCBzdGFydFBvaW50LngsIHN0YXJ0UG9pbnQueSArIG1pbkxhYmVsQkJveC5oZWlnaHQgKyBzcGFjaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlUmFpbFBvc2l0aW9uKHJhaWxTaGFwZSwgc3RhcnRQb2ludC54LCBzdGFydFBvaW50LnkpO1xuICAgICAgICAgICAgbWluTGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgeDogc3RhcnRQb2ludC54LFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSArIHJhaWxCQm94LmhlaWdodCArIHNwYWNpbmcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1heExhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0UG9pbnQueCArIHJhaWxCQm94LndpZHRoLFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSArIHJhaWxCQm94LmhlaWdodCArIHNwYWNpbmcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGludWVMZWdlbmQucHJvdG90eXBlLmZpeGVkVmVydGFpbCA9IGZ1bmN0aW9uIChtaW5MYWJlbCwgbWF4TGFiZWwsIHJhaWxTaGFwZSwgc3RhcnRQb2ludCkge1xuICAgICAgICB2YXIgbGFiZWxDZmcgPSB0aGlzLmdldCgnbGFiZWwnKTtcbiAgICAgICAgdmFyIGxhYmVsQWxpZ24gPSBsYWJlbENmZy5hbGlnbjtcbiAgICAgICAgdmFyIHNwYWNpbmcgPSBsYWJlbENmZy5zcGFjaW5nO1xuICAgICAgICB2YXIgcmFpbEJCb3ggPSByYWlsU2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgbWluTGFiZWxCQm94ID0gbWluTGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgbWF4TGFiZWxCQm94ID0gbWF4TGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICB0aGlzLmZpdFJhaWxMZW5ndGgobWluTGFiZWxCQm94LCBtYXhMYWJlbEJCb3gsIHJhaWxCQm94LCByYWlsU2hhcGUpO1xuICAgICAgICByYWlsQkJveCA9IHJhaWxTaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIGlmIChsYWJlbEFsaWduID09PSAncmFpbCcpIHtcbiAgICAgICAgICAgIC8vIOayv+edgCByYWlsIOaWueWQkVxuICAgICAgICAgICAgbWluTGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgeDogc3RhcnRQb2ludC54LFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VSYWlsUG9zaXRpb24ocmFpbFNoYXBlLCBzdGFydFBvaW50LngsIHN0YXJ0UG9pbnQueSArIG1pbkxhYmVsQkJveC5oZWlnaHQgKyBzcGFjaW5nKTtcbiAgICAgICAgICAgIG1heExhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0UG9pbnQueCxcbiAgICAgICAgICAgICAgICB5OiBzdGFydFBvaW50LnkgKyBtaW5MYWJlbEJCb3guaGVpZ2h0ICsgcmFpbEJCb3guaGVpZ2h0ICsgc3BhY2luZyAqIDIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChsYWJlbEFsaWduID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICBtaW5MYWJlbC5hdHRyKHtcbiAgICAgICAgICAgICAgICB4OiBzdGFydFBvaW50LnggKyByYWlsQkJveC53aWR0aCArIHNwYWNpbmcsXG4gICAgICAgICAgICAgICAgeTogc3RhcnRQb2ludC55LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZVJhaWxQb3NpdGlvbihyYWlsU2hhcGUsIHN0YXJ0UG9pbnQueCwgc3RhcnRQb2ludC55KTtcbiAgICAgICAgICAgIG1heExhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0UG9pbnQueCArIHJhaWxCQm94LndpZHRoICsgc3BhY2luZyxcbiAgICAgICAgICAgICAgICB5OiBzdGFydFBvaW50LnkgKyByYWlsQkJveC5oZWlnaHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGxlZnRcbiAgICAgICAgICAgIHZhciBtYXhMYWJlbFdpZHRoID0gTWF0aC5tYXgobWluTGFiZWxCQm94LndpZHRoLCBtYXhMYWJlbEJCb3gud2lkdGgpO1xuICAgICAgICAgICAgbWluTGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgeDogc3RhcnRQb2ludC54LFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0UG9pbnQueSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VSYWlsUG9zaXRpb24ocmFpbFNoYXBlLCBzdGFydFBvaW50LnggKyBtYXhMYWJlbFdpZHRoICsgc3BhY2luZywgc3RhcnRQb2ludC55KTtcbiAgICAgICAgICAgIG1heExhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgIHg6IHN0YXJ0UG9pbnQueCxcbiAgICAgICAgICAgICAgICB5OiBzdGFydFBvaW50LnkgKyByYWlsQkJveC5oZWlnaHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIENvbnRpbnVlTGVnZW5kO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29udGludWVMZWdlbmQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb250aW51b3VzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGNhdGVnb3J5XzEgPSByZXF1aXJlKFwiLi9jYXRlZ29yeVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNhdGVnb3J5XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjYXRlZ29yeV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgY29udGludW91c18xID0gcmVxdWlyZShcIi4vY29udGludW91c1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbnRpbnVvdXNcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnRpbnVvdXNfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCYXNlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBiYXNlXzEuZGVmYXVsdDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiLi9zY3JvbGxiYXJcIiksIGV4cG9ydHMpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlNjcm9sbGJhciA9IGV4cG9ydHMuREVGQVVMVF9USEVNRSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRvbV91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvZG9tLXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ3JvdXBfY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi4vYWJzdHJhY3QvZ3JvdXAtY29tcG9uZW50XCIpO1xudmFyIERFRkFVTFRfU1RZTEUgPSB7XG4gICAgdHJhY2tDb2xvcjogJ3JnYmEoMCwwLDAsMCknLFxuICAgIHRodW1iQ29sb3I6ICdyZ2JhKDAsMCwwLDAuMTUpJyxcbiAgICBzaXplOiA4LFxuICAgIGxpbmVDYXA6ICdyb3VuZCcsXG59O1xuZXhwb3J0cy5ERUZBVUxUX1RIRU1FID0ge1xuICAgIC8vIOm7mOiupOagt+W8j1xuICAgIGRlZmF1bHQ6IERFRkFVTFRfU1RZTEUsXG4gICAgLy8g6byg5qCHIGhvdmVyIOeahOagt+W8j1xuICAgIGhvdmVyOiB7XG4gICAgICAgIHRodW1iQ29sb3I6ICdyZ2JhKDAsMCwwLDAuMiknLFxuICAgIH0sXG59O1xudmFyIFNjcm9sbGJhciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTY3JvbGxiYXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2Nyb2xsYmFyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuY2xlYXJFdmVudHMgPSB1dGlsXzEubm9vcDtcbiAgICAgICAgX3RoaXMub25TdGFydEV2ZW50ID0gZnVuY3Rpb24gKGlzTW9iaWxlKSB7IHJldHVybiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgX3RoaXMuaXNNb2JpbGUgPSBpc01vYmlsZTtcbiAgICAgICAgICAgIGUub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIGNsaWVudFggPSBpc01vYmlsZSA/IHV0aWxfMS5nZXQoZS5vcmlnaW5hbEV2ZW50LCAndG91Y2hlcy4wLmNsaWVudFgnKSA6IGUuY2xpZW50WDtcbiAgICAgICAgICAgIHZhciBjbGllbnRZID0gaXNNb2JpbGUgPyB1dGlsXzEuZ2V0KGUub3JpZ2luYWxFdmVudCwgJ3RvdWNoZXMuMC5jbGllbnRZJykgOiBlLmNsaWVudFk7XG4gICAgICAgICAgICAvLyDlsIblvIDlp4vnmoTngrnorrDlvZXkuIvmnaVcbiAgICAgICAgICAgIF90aGlzLnN0YXJ0UG9zID0gX3RoaXMuY2ZnLmlzSG9yaXpvbnRhbCA/IGNsaWVudFggOiBjbGllbnRZO1xuICAgICAgICAgICAgX3RoaXMuYmluZExhdGVyRXZlbnQoKTtcbiAgICAgICAgfTsgfTtcbiAgICAgICAgX3RoaXMuYmluZExhdGVyRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyRE9NID0gX3RoaXMuZ2V0Q29udGFpbmVyRE9NKCk7XG4gICAgICAgICAgICB2YXIgZXZlbnRzID0gW107XG4gICAgICAgICAgICBpZiAoX3RoaXMuaXNNb2JpbGUpIHtcbiAgICAgICAgICAgICAgICBldmVudHMgPSBbXG4gICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEuYWRkRXZlbnRMaXN0ZW5lcihjb250YWluZXJET00sICd0b3VjaG1vdmUnLCBfdGhpcy5vbk1vdXNlTW92ZSksXG4gICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEuYWRkRXZlbnRMaXN0ZW5lcihjb250YWluZXJET00sICd0b3VjaGVuZCcsIF90aGlzLm9uTW91c2VVcCksXG4gICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEuYWRkRXZlbnRMaXN0ZW5lcihjb250YWluZXJET00sICd0b3VjaGNhbmNlbCcsIF90aGlzLm9uTW91c2VVcCksXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGV2ZW50cyA9IFtcbiAgICAgICAgICAgICAgICAgICAgZG9tX3V0aWxfMS5hZGRFdmVudExpc3RlbmVyKGNvbnRhaW5lckRPTSwgJ21vdXNlbW92ZScsIF90aGlzLm9uTW91c2VNb3ZlKSxcbiAgICAgICAgICAgICAgICAgICAgZG9tX3V0aWxfMS5hZGRFdmVudExpc3RlbmVyKGNvbnRhaW5lckRPTSwgJ21vdXNldXAnLCBfdGhpcy5vbk1vdXNlVXApLFxuICAgICAgICAgICAgICAgICAgICAvLyDkuLrkuobkv53or4HliJLlh7ogY2FudmFzIGNvbnRhaW5lckRvbSDml7bov5jmsqHop6blj5EgbW91c2V1cFxuICAgICAgICAgICAgICAgICAgICBkb21fdXRpbF8xLmFkZEV2ZW50TGlzdGVuZXIoY29udGFpbmVyRE9NLCAnbW91c2VsZWF2ZScsIF90aGlzLm9uTW91c2VVcCksXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF90aGlzLmNsZWFyRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICAvLyDmi5bmi73mu5HlnZfnmoTkuovku7blm57osINcbiAgICAgICAgLy8g6L+Z6YeM5pivIGRvbSDljp/nlJ/kuovku7bvvIznu5HlrprlnKggZG9tIOWFg+e0oOS4iueahFxuICAgICAgICBfdGhpcy5vbk1vdXNlTW92ZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB2YXIgX2EgPSBfdGhpcy5jZmcsIGlzSG9yaXpvbnRhbCA9IF9hLmlzSG9yaXpvbnRhbCwgdGh1bWJPZmZzZXQgPSBfYS50aHVtYk9mZnNldDtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHZhciBjbGllbnRYID0gX3RoaXMuaXNNb2JpbGUgPyB1dGlsXzEuZ2V0KGUsICd0b3VjaGVzLjAuY2xpZW50WCcpIDogZS5jbGllbnRYO1xuICAgICAgICAgICAgdmFyIGNsaWVudFkgPSBfdGhpcy5pc01vYmlsZSA/IHV0aWxfMS5nZXQoZSwgJ3RvdWNoZXMuMC5jbGllbnRZJykgOiBlLmNsaWVudFk7XG4gICAgICAgICAgICAvLyDpvKDmoIfmnb7lvIDnmoTkvY3nva5cbiAgICAgICAgICAgIHZhciBlbmRQb3MgPSBpc0hvcml6b250YWwgPyBjbGllbnRYIDogY2xpZW50WTtcbiAgICAgICAgICAgIC8vIOa7keWdl+mcgOimgeenu+WKqOeahOi3neemuywg55Sx5LqO6L+Z6YeM5piv5a+55ruR5Z2X55uR5ZCs77yM5omA5Lul56e75Yqo55qE6Led56a75bCx5pivIGRpZmZEaXMsIOWmguaenOebkeWQrOWvueixoeaYryBjb250YWluZXIgZG9t77yM5YiZ6ZyA6KaB566X5q+U5L6LXG4gICAgICAgICAgICB2YXIgZGlmZiA9IGVuZFBvcyAtIF90aGlzLnN0YXJ0UG9zO1xuICAgICAgICAgICAgLy8g5pu05pawIF9zdGFydFBvc1xuICAgICAgICAgICAgX3RoaXMuc3RhcnRQb3MgPSBlbmRQb3M7XG4gICAgICAgICAgICBfdGhpcy51cGRhdGVUaHVtYk9mZnNldCh0aHVtYk9mZnNldCArIGRpZmYpO1xuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5vbk1vdXNlVXAgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgX3RoaXMuY2xlYXJFdmVudHMoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8g54K55Ye75ruR6YGT55qE5LqL5Lu25Zue6LCDLOenu+WKqOa7keWdl+S9jee9rlxuICAgICAgICBfdGhpcy5vblRyYWNrQ2xpY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIF9hID0gX3RoaXMuY2ZnLCBpc0hvcml6b250YWwgPSBfYS5pc0hvcml6b250YWwsIHggPSBfYS54LCB5ID0gX2EueSwgdGh1bWJMZW4gPSBfYS50aHVtYkxlbjtcbiAgICAgICAgICAgIHZhciBjb250YWluZXJET00gPSBfdGhpcy5nZXRDb250YWluZXJET00oKTtcbiAgICAgICAgICAgIHZhciByZWN0ID0gY29udGFpbmVyRE9NLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgdmFyIGNsaWVudFggPSBlLmNsaWVudFgsIGNsaWVudFkgPSBlLmNsaWVudFk7XG4gICAgICAgICAgICB2YXIgb2Zmc2V0ID0gaXNIb3Jpem9udGFsID8gY2xpZW50WCAtIHJlY3QubGVmdCAtIHggLSB0aHVtYkxlbiAvIDIgOiBjbGllbnRZIC0gcmVjdC50b3AgLSB5IC0gdGh1bWJMZW4gLyAyO1xuICAgICAgICAgICAgdmFyIG5ld09mZnNldCA9IF90aGlzLnZhbGlkYXRlUmFuZ2Uob2Zmc2V0KTtcbiAgICAgICAgICAgIF90aGlzLnVwZGF0ZVRodW1iT2Zmc2V0KG5ld09mZnNldCk7XG4gICAgICAgIH07XG4gICAgICAgIF90aGlzLm9uVGh1bWJNb3VzZU92ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdGh1bWJDb2xvciA9IF90aGlzLmNmZy50aGVtZS5ob3Zlci50aHVtYkNvbG9yO1xuICAgICAgICAgICAgX3RoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgndGh1bWInKS5hdHRyKCdzdHJva2UnLCB0aHVtYkNvbG9yKTtcbiAgICAgICAgICAgIF90aGlzLmRyYXcoKTtcbiAgICAgICAgfTtcbiAgICAgICAgX3RoaXMub25UaHVtYk1vdXNlT3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHRodW1iQ29sb3IgPSBfdGhpcy5jZmcudGhlbWUuZGVmYXVsdC50aHVtYkNvbG9yO1xuICAgICAgICAgICAgX3RoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgndGh1bWInKS5hdHRyKCdzdHJva2UnLCB0aHVtYkNvbG9yKTtcbiAgICAgICAgICAgIF90aGlzLmRyYXcoKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBTY3JvbGxiYXIucHJvdG90eXBlLnNldFJhbmdlID0gZnVuY3Rpb24gKG1pbiwgbWF4KSB7XG4gICAgICAgIHRoaXMuc2V0KCdtaW5MaW1pdCcsIG1pbik7XG4gICAgICAgIHRoaXMuc2V0KCdtYXhMaW1pdCcsIG1heCk7XG4gICAgICAgIHZhciBjdXJWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gdXRpbF8xLmNsYW1wKGN1clZhbHVlLCBtaW4sIG1heCk7XG4gICAgICAgIGlmIChjdXJWYWx1ZSAhPT0gbmV3VmFsdWUgJiYgIXRoaXMuZ2V0KCdpc0luaXQnKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZShuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNjcm9sbGJhci5wcm90b3R5cGUuZ2V0UmFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtaW4gPSB0aGlzLmdldCgnbWluTGltaXQnKSB8fCAwO1xuICAgICAgICB2YXIgbWF4ID0gdGhpcy5nZXQoJ21heExpbWl0JykgfHwgMTtcbiAgICAgICAgcmV0dXJuIHsgbWluOiBtaW4sIG1heDogbWF4IH07XG4gICAgfTtcbiAgICBTY3JvbGxiYXIucHJvdG90eXBlLnNldFZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTtcbiAgICAgICAgdmFyIG9yaWdpbmFsVmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG4gICAgICAgIHRoaXMudXBkYXRlKHtcbiAgICAgICAgICAgIHRodW1iT2Zmc2V0OiAodGhpcy5nZXQoJ3RyYWNrTGVuJykgLSB0aGlzLmdldCgndGh1bWJMZW4nKSkgKiB1dGlsXzEuY2xhbXAodmFsdWUsIHJhbmdlLm1pbiwgcmFuZ2UubWF4KSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsZWdhdGVFbWl0KCd2YWx1ZWNoYW5nZScsIHtcbiAgICAgICAgICAgIG9yaWdpbmFsVmFsdWU6IG9yaWdpbmFsVmFsdWUsXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5nZXRWYWx1ZSgpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFNjcm9sbGJhci5wcm90b3R5cGUuZ2V0VmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuY2xhbXAodGhpcy5nZXQoJ3RodW1iT2Zmc2V0JykgLyAodGhpcy5nZXQoJ3RyYWNrTGVuJykgLSB0aGlzLmdldCgndGh1bWJMZW4nKSksIDAsIDEpO1xuICAgIH07XG4gICAgU2Nyb2xsYmFyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ3Njcm9sbGJhcicsIGlzSG9yaXpvbnRhbDogdHJ1ZSwgbWluVGh1bWJMZW46IDIwLCB0aHVtYk9mZnNldDogMCwgdGhlbWU6IGV4cG9ydHMuREVGQVVMVF9USEVNRSB9KTtcbiAgICB9O1xuICAgIFNjcm9sbGJhci5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdGhpcy5yZW5kZXJUcmFja1NoYXBlKGdyb3VwKTtcbiAgICAgICAgdGhpcy5yZW5kZXJUaHVtYlNoYXBlKGdyb3VwKTtcbiAgICB9O1xuICAgIFNjcm9sbGJhci5wcm90b3R5cGUuYXBwbHlPZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMubW92ZUVsZW1lbnRUbyh0aGlzLmdldCgnZ3JvdXAnKSwge1xuICAgICAgICAgICAgeDogdGhpcy5nZXQoJ3gnKSxcbiAgICAgICAgICAgIHk6IHRoaXMuZ2V0KCd5JyksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU2Nyb2xsYmFyLnByb3RvdHlwZS5pbml0RXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYmluZEV2ZW50cygpO1xuICAgIH07XG4gICAgLy8g5Yib5bu65ruR6YGT55qEIHNoYXBlXG4gICAgU2Nyb2xsYmFyLnByb3RvdHlwZS5yZW5kZXJUcmFja1NoYXBlID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCB0cmFja0xlbiA9IF9hLnRyYWNrTGVuLCBfYiA9IF9hLnRoZW1lLCB0aGVtZSA9IF9iID09PSB2b2lkIDAgPyB7IGRlZmF1bHQ6IHt9IH0gOiBfYjtcbiAgICAgICAgdmFyIF9jID0gdGhlbWUuZGVmYXVsdCwgbGluZUNhcCA9IF9jLmxpbmVDYXAsIHRyYWNrQ29sb3IgPSBfYy50cmFja0NvbG9yLCBzaXplID0gX2Muc2l6ZTtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5nZXQoJ2lzSG9yaXpvbnRhbCcpXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICB4MTogMCArIHNpemUgLyAyLFxuICAgICAgICAgICAgICAgIHkxOiBzaXplIC8gMixcbiAgICAgICAgICAgICAgICB4MjogdHJhY2tMZW4gLSBzaXplIC8gMixcbiAgICAgICAgICAgICAgICB5Mjogc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzaXplLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogdHJhY2tDb2xvcixcbiAgICAgICAgICAgICAgICBsaW5lQ2FwOiBsaW5lQ2FwLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgeDE6IHNpemUgLyAyLFxuICAgICAgICAgICAgICAgIHkxOiAwICsgc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgeDI6IHNpemUgLyAyLFxuICAgICAgICAgICAgICAgIHkyOiB0cmFja0xlbiAtIHNpemUgLyAyLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc2l6ZSxcbiAgICAgICAgICAgICAgICBzdHJva2U6IHRyYWNrQ29sb3IsXG4gICAgICAgICAgICAgICAgbGluZUNhcDogbGluZUNhcCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3RyYWNrJyksXG4gICAgICAgICAgICBuYW1lOiAndHJhY2snLFxuICAgICAgICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgYXR0cnM6IGF0dHJzLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOWIm+W7uua7keWdl+eahCBzaGFwZVxuICAgIFNjcm9sbGJhci5wcm90b3R5cGUucmVuZGVyVGh1bWJTaGFwZSA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmNmZywgdGh1bWJPZmZzZXQgPSBfYS50aHVtYk9mZnNldCwgdGh1bWJMZW4gPSBfYS50aHVtYkxlbiwgX2IgPSBfYS50aGVtZSwgdGhlbWUgPSBfYiA9PT0gdm9pZCAwID8geyBkZWZhdWx0OiB7fSB9IDogX2I7XG4gICAgICAgIHZhciBfYyA9IHRoZW1lLmRlZmF1bHQsIHNpemUgPSBfYy5zaXplLCBsaW5lQ2FwID0gX2MubGluZUNhcCwgdGh1bWJDb2xvciA9IF9jLnRodW1iQ29sb3I7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuZ2V0KCdpc0hvcml6b250YWwnKVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgeDE6IHRodW1iT2Zmc2V0ICsgc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgeTE6IHNpemUgLyAyLFxuICAgICAgICAgICAgICAgIHgyOiB0aHVtYk9mZnNldCArIHRodW1iTGVuIC0gc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgeTI6IHNpemUgLyAyLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc2l6ZSxcbiAgICAgICAgICAgICAgICBzdHJva2U6IHRodW1iQ29sb3IsXG4gICAgICAgICAgICAgICAgbGluZUNhcDogbGluZUNhcCxcbiAgICAgICAgICAgICAgICBjdXJzb3I6ICdkZWZhdWx0JyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHgxOiBzaXplIC8gMixcbiAgICAgICAgICAgICAgICB5MTogdGh1bWJPZmZzZXQgKyBzaXplIC8gMixcbiAgICAgICAgICAgICAgICB4Mjogc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgeTI6IHRodW1iT2Zmc2V0ICsgdGh1bWJMZW4gLSBzaXplIC8gMixcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHNpemUsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiB0aHVtYkNvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVDYXA6IGxpbmVDYXAsXG4gICAgICAgICAgICAgICAgY3Vyc29yOiAnZGVmYXVsdCcsXG4gICAgICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCd0aHVtYicpLFxuICAgICAgICAgICAgbmFtZTogJ3RodW1iJyxcbiAgICAgICAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBTY3JvbGxiYXIucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2V0KCdncm91cCcpO1xuICAgICAgICBncm91cC5vbignbW91c2Vkb3duJywgdGhpcy5vblN0YXJ0RXZlbnQoZmFsc2UpKTtcbiAgICAgICAgZ3JvdXAub24oJ21vdXNldXAnLCB0aGlzLm9uTW91c2VVcCk7XG4gICAgICAgIGdyb3VwLm9uKCd0b3VjaHN0YXJ0JywgdGhpcy5vblN0YXJ0RXZlbnQodHJ1ZSkpO1xuICAgICAgICBncm91cC5vbigndG91Y2hlbmQnLCB0aGlzLm9uTW91c2VVcCk7XG4gICAgICAgIHZhciB0cmFja1NoYXBlID0gZ3JvdXAuZmluZEJ5SWQodGhpcy5nZXRFbGVtZW50SWQoJ3RyYWNrJykpO1xuICAgICAgICB0cmFja1NoYXBlLm9uKCdjbGljaycsIHRoaXMub25UcmFja0NsaWNrKTtcbiAgICAgICAgdmFyIHRodW1iU2hhcGUgPSBncm91cC5maW5kQnlJZCh0aGlzLmdldEVsZW1lbnRJZCgndGh1bWInKSk7XG4gICAgICAgIHRodW1iU2hhcGUub24oJ21vdXNlb3ZlcicsIHRoaXMub25UaHVtYk1vdXNlT3Zlcik7XG4gICAgICAgIHRodW1iU2hhcGUub24oJ21vdXNlb3V0JywgdGhpcy5vblRodW1iTW91c2VPdXQpO1xuICAgIH07XG4gICAgU2Nyb2xsYmFyLnByb3RvdHlwZS5nZXRDb250YWluZXJET00gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgIHZhciBjYW52YXMgPSBjb250YWluZXIgJiYgY29udGFpbmVyLmdldCgnY2FudmFzJyk7XG4gICAgICAgIHJldHVybiBjYW52YXMgJiYgY2FudmFzLmdldCgnY29udGFpbmVyJyk7XG4gICAgfTtcbiAgICBTY3JvbGxiYXIucHJvdG90eXBlLnZhbGlkYXRlUmFuZ2UgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCB0aHVtYkxlbiA9IF9hLnRodW1iTGVuLCB0cmFja0xlbiA9IF9hLnRyYWNrTGVuO1xuICAgICAgICB2YXIgbmV3T2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICBpZiAob2Zmc2V0ICsgdGh1bWJMZW4gPiB0cmFja0xlbikge1xuICAgICAgICAgICAgbmV3T2Zmc2V0ID0gdHJhY2tMZW4gLSB0aHVtYkxlbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvZmZzZXQgKyB0aHVtYkxlbiA8IHRodW1iTGVuKSB7XG4gICAgICAgICAgICBuZXdPZmZzZXQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdPZmZzZXQ7XG4gICAgfTtcbiAgICBTY3JvbGxiYXIucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgIHZhciBjYW52YXMgPSBjb250YWluZXIgJiYgY29udGFpbmVyLmdldCgnY2FudmFzJyk7XG4gICAgICAgIGlmIChjYW52YXMpIHtcbiAgICAgICAgICAgIGNhbnZhcy5kcmF3KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNjcm9sbGJhci5wcm90b3R5cGUudXBkYXRlVGh1bWJPZmZzZXQgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCB0aHVtYk9mZnNldCA9IF9hLnRodW1iT2Zmc2V0LCBpc0hvcml6b250YWwgPSBfYS5pc0hvcml6b250YWwsIHRodW1iTGVuID0gX2EudGh1bWJMZW4sIHNpemUgPSBfYS5zaXplO1xuICAgICAgICB2YXIgbmV3T2Zmc2V0ID0gdGhpcy52YWxpZGF0ZVJhbmdlKG9mZnNldCk7XG4gICAgICAgIGlmIChuZXdPZmZzZXQgPT09IHRodW1iT2Zmc2V0KSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzmm7TmlrDlkI7nmoQgb2Zmc2V0IOS4juWOn+WAvOebuOWQjO+8jOWImeS4jeaUueWPmFxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aHVtYlNoYXBlID0gdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCd0aHVtYicpO1xuICAgICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgICAgICB0aHVtYlNoYXBlLmF0dHIoe1xuICAgICAgICAgICAgICAgIHgxOiBuZXdPZmZzZXQgKyBzaXplIC8gMixcbiAgICAgICAgICAgICAgICB4MjogbmV3T2Zmc2V0ICsgdGh1bWJMZW4gLSBzaXplIC8gMixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGh1bWJTaGFwZS5hdHRyKHtcbiAgICAgICAgICAgICAgICB5MTogbmV3T2Zmc2V0ICsgc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgeTI6IG5ld09mZnNldCArIHRodW1iTGVuIC0gc2l6ZSAvIDIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXRPZmZzZXRDaGFuZ2UobmV3T2Zmc2V0KTtcbiAgICB9O1xuICAgIFNjcm9sbGJhci5wcm90b3R5cGUuZW1pdE9mZnNldENoYW5nZSA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jZmcsIG9yaWdpbmFsVmFsdWUgPSBfYS50aHVtYk9mZnNldCwgdHJhY2tMZW4gPSBfYS50cmFja0xlbiwgdGh1bWJMZW4gPSBfYS50aHVtYkxlbjtcbiAgICAgICAgdGhpcy5jZmcudGh1bWJPZmZzZXQgPSBvZmZzZXQ7XG4gICAgICAgIC8vIOWPkemAgeS6i+S7tlxuICAgICAgICB0aGlzLmVtaXQoJ3Njcm9sbGNoYW5nZScsIHtcbiAgICAgICAgICAgIHRodW1iT2Zmc2V0OiBvZmZzZXQsXG4gICAgICAgICAgICByYXRpbzogdXRpbF8xLmNsYW1wKG9mZnNldCAvICh0cmFja0xlbiAtIHRodW1iTGVuKSwgMCwgMSksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGVnYXRlRW1pdCgndmFsdWVjaGFuZ2UnLCB7XG4gICAgICAgICAgICBvcmlnaW5hbFZhbHVlOiBvcmlnaW5hbFZhbHVlLFxuICAgICAgICAgICAgdmFsdWU6IG9mZnNldCxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gU2Nyb2xsYmFyO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLlNjcm9sbGJhciA9IFNjcm9sbGJhcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNjcm9sbGJhci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICog5LiA5Lqb6buY6K6k55qE5qC35byP6YWN572uXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuU0xJREVSX0NIQU5HRSA9IGV4cG9ydHMuVEVYVF9TVFlMRSA9IGV4cG9ydHMuSEFORExFUl9TVFlMRSA9IGV4cG9ydHMuREVGQVVMVF9IQU5ETEVSX1dJRFRIID0gZXhwb3J0cy5GT1JFR1JPVU5EX1NUWUxFID0gZXhwb3J0cy5CQUNLR1JPVU5EX1NUWUxFID0gdm9pZCAwO1xuZXhwb3J0cy5CQUNLR1JPVU5EX1NUWUxFID0ge1xuICAgIGZpbGw6ICcjNDE2MTgwJyxcbiAgICBvcGFjaXR5OiAwLjA1LFxufTtcbmV4cG9ydHMuRk9SRUdST1VORF9TVFlMRSA9IHtcbiAgICBmaWxsOiAnIzVCOEZGOScsXG4gICAgb3BhY2l0eTogMC4xNSxcbiAgICBjdXJzb3I6ICdtb3ZlJyxcbn07XG5leHBvcnRzLkRFRkFVTFRfSEFORExFUl9XSURUSCA9IDEwO1xuZXhwb3J0cy5IQU5ETEVSX1NUWUxFID0ge1xuICAgIHdpZHRoOiBleHBvcnRzLkRFRkFVTFRfSEFORExFUl9XSURUSCxcbiAgICBoZWlnaHQ6IDI0LFxufTtcbmV4cG9ydHMuVEVYVF9TVFlMRSA9IHtcbiAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgIGZpbGw6ICcjMDAwJyxcbiAgICBvcGFjaXR5OiAwLjQ1LFxufTtcbmV4cG9ydHMuU0xJREVSX0NIQU5HRSA9ICdzbGlkZXJjaGFuZ2UnO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkhhbmRsZXIgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBncm91cF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9ncm91cC1jb21wb25lbnRcIik7XG52YXIgREVGQVVMVF9TVFlMRSA9IHtcbiAgICBmaWxsOiAnI0Y3RjdGNycsXG4gICAgc3Ryb2tlOiAnI0JGQkZCRicsXG4gICAgcmFkaXVzOiAyLFxuICAgIG9wYWNpdHk6IDEsXG4gICAgY3Vyc29yOiAnZXctcmVzaXplJyxcbiAgICAvLyDpq5jkuq7nmoTpopzoibJcbiAgICBoaWdoTGlnaHRGaWxsOiAnI0ZGRicsXG59O1xudmFyIEhhbmRsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSGFuZGxlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIYW5kbGVyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEhhbmRsZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBuYW1lOiAnaGFuZGxlcicsIHg6IDAsIHk6IDAsIHdpZHRoOiAxMCwgaGVpZ2h0OiAyNCwgc3R5bGU6IERFRkFVTFRfU1RZTEUgfSk7XG4gICAgfTtcbiAgICBIYW5kbGVyLnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmNmZywgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0LCBzdHlsZSA9IF9hLnN0eWxlO1xuICAgICAgICB2YXIgZmlsbCA9IHN0eWxlLmZpbGwsIHN0cm9rZSA9IHN0eWxlLnN0cm9rZSwgcmFkaXVzID0gc3R5bGUucmFkaXVzLCBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSwgY3Vyc29yID0gc3R5bGUuY3Vyc29yO1xuICAgICAgICAvLyDmjInpkq7moYbmoYZcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdiYWNrZ3JvdW5kJyksXG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgICAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgICAgICAgICByYWRpdXM6IHJhZGl1cyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBvcGFjaXR5LFxuICAgICAgICAgICAgICAgIGN1cnNvcjogY3Vyc29yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOS4pOagueerlue6v1xuICAgICAgICB2YXIgeDEgPSAoMSAvIDMpICogd2lkdGg7XG4gICAgICAgIHZhciB4MiA9ICgyIC8gMykgKiB3aWR0aDtcbiAgICAgICAgdmFyIHkxID0gKDEgLyA0KSAqIGhlaWdodDtcbiAgICAgICAgdmFyIHkyID0gKDMgLyA0KSAqIGhlaWdodDtcbiAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdsaW5lLWxlZnQnKSxcbiAgICAgICAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDE6IHgxLFxuICAgICAgICAgICAgICAgIHkxOiB5MSxcbiAgICAgICAgICAgICAgICB4MjogeDEsXG4gICAgICAgICAgICAgICAgeTI6IHkyLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogc3Ryb2tlLFxuICAgICAgICAgICAgICAgIGN1cnNvcjogY3Vyc29yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbGluZS1yaWdodCcpLFxuICAgICAgICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4MTogeDIsXG4gICAgICAgICAgICAgICAgeTE6IHkxLFxuICAgICAgICAgICAgICAgIHgyOiB4MixcbiAgICAgICAgICAgICAgICB5MjogeTIsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHJva2UsXG4gICAgICAgICAgICAgICAgY3Vyc29yOiBjdXJzb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhhbmRsZXIucHJvdG90eXBlLmFwcGx5T2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm1vdmVFbGVtZW50VG8odGhpcy5nZXQoJ2dyb3VwJyksIHtcbiAgICAgICAgICAgIHg6IHRoaXMuZ2V0KCd4JyksXG4gICAgICAgICAgICB5OiB0aGlzLmdldCgneScpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhhbmRsZXIucHJvdG90eXBlLmluaXRFdmVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5iaW5kRXZlbnRzKCk7XG4gICAgfTtcbiAgICBIYW5kbGVyLnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmdldCgnZ3JvdXAnKS5vbignbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBoaWdoTGlnaHRGaWxsID0gX3RoaXMuZ2V0KCdzdHlsZScpLmhpZ2hMaWdodEZpbGw7XG4gICAgICAgICAgICBfdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCdiYWNrZ3JvdW5kJykuYXR0cignZmlsbCcsIGhpZ2hMaWdodEZpbGwpO1xuICAgICAgICAgICAgX3RoaXMuZHJhdygpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5nZXQoJ2dyb3VwJykub24oJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZmlsbCA9IF90aGlzLmdldCgnc3R5bGUnKS5maWxsO1xuICAgICAgICAgICAgX3RoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgnYmFja2dyb3VuZCcpLmF0dHIoJ2ZpbGwnLCBmaWxsKTtcbiAgICAgICAgICAgIF90aGlzLmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBIYW5kbGVyLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2FudmFzID0gdGhpcy5nZXQoJ2NvbnRhaW5lcicpLmdldCgnY2FudmFzJyk7XG4gICAgICAgIGlmIChjYW52YXMpIHtcbiAgICAgICAgICAgIGNhbnZhcy5kcmF3KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBIYW5kbGVyO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLkhhbmRsZXIgPSBIYW5kbGVyO1xuZXhwb3J0cy5kZWZhdWx0ID0gSGFuZGxlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhhbmRsZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgc2xpZGVyXzEgPSByZXF1aXJlKFwiLi9zbGlkZXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTbGlkZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNsaWRlcl8xLlNsaWRlcjsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TbGlkZXIgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBncm91cF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9ncm91cC1jb21wb25lbnRcIik7XG52YXIgdHJlbmRfMSA9IHJlcXVpcmUoXCIuLi90cmVuZC90cmVuZFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4vY29uc3RhbnRcIik7XG52YXIgaGFuZGxlcl8xID0gcmVxdWlyZShcIi4vaGFuZGxlclwiKTtcbnZhciBTbGlkZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2xpZGVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNsaWRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLm9uTW91c2VEb3duID0gZnVuY3Rpb24gKHRhcmdldCkgeyByZXR1cm4gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIF90aGlzLmN1cnJlbnRUYXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgICAgICAvLyDlj5blh7rljp/nlJ/kuovku7ZcbiAgICAgICAgICAgIHZhciBldmVudCA9IGUub3JpZ2luYWxFdmVudDtcbiAgICAgICAgICAgIC8vIDIuIOWtmOWCqOW9k+WJjeeCueWHu+S9jee9rlxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgLy8g5YW85a6556e75Yqo56uv6I635Y+W5pWw5o2uXG4gICAgICAgICAgICBfdGhpcy5wcmV2WCA9IHV0aWxfMS5nZXQoZXZlbnQsICd0b3VjaGVzLjAucGFnZVgnLCBldmVudC5wYWdlWCk7XG4gICAgICAgICAgICBfdGhpcy5wcmV2WSA9IHV0aWxfMS5nZXQoZXZlbnQsICd0b3VjaGVzLjAucGFnZVknLCBldmVudC5wYWdlWSk7XG4gICAgICAgICAgICAvLyAzLiDlvIDlp4vmu5HliqjnmoTml7blgJnvvIznu5HlrpogbW92ZSDlkowgdXAg5LqL5Lu2XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyRE9NID0gX3RoaXMuZ2V0Q29udGFpbmVyRE9NKCk7XG4gICAgICAgICAgICBjb250YWluZXJET00uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgX3RoaXMub25Nb3VzZU1vdmUpO1xuICAgICAgICAgICAgY29udGFpbmVyRE9NLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBfdGhpcy5vbk1vdXNlVXApO1xuICAgICAgICAgICAgY29udGFpbmVyRE9NLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBfdGhpcy5vbk1vdXNlVXApO1xuICAgICAgICAgICAgLy8g56e75Yqo56uv5LqL5Lu2XG4gICAgICAgICAgICBjb250YWluZXJET00uYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgX3RoaXMub25Nb3VzZU1vdmUpO1xuICAgICAgICAgICAgY29udGFpbmVyRE9NLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgX3RoaXMub25Nb3VzZVVwKTtcbiAgICAgICAgICAgIGNvbnRhaW5lckRPTS5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIF90aGlzLm9uTW91c2VVcCk7XG4gICAgICAgIH07IH07XG4gICAgICAgIF90aGlzLm9uTW91c2VNb3ZlID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgd2lkdGggPSBfdGhpcy5jZmcud2lkdGg7XG4gICAgICAgICAgICB2YXIgb3JpZ2luVmFsdWUgPSBbX3RoaXMuZ2V0KCdzdGFydCcpLCBfdGhpcy5nZXQoJ2VuZCcpXTtcbiAgICAgICAgICAgIC8vIOa7keWKqOi/h+eoi+S4re+8jOiuoeeul+WBj+enu++8jOabtOaWsOa7keWdl++8jOeEtuWQjiBlbWl0IOaVsOaNruWHuuWOu1xuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIHggPSB1dGlsXzEuZ2V0KGV2ZW50LCAndG91Y2hlcy4wLnBhZ2VYJywgZXZlbnQucGFnZVgpO1xuICAgICAgICAgICAgdmFyIHkgPSB1dGlsXzEuZ2V0KGV2ZW50LCAndG91Y2hlcy4wLnBhZ2VZJywgZXZlbnQucGFnZVkpO1xuICAgICAgICAgICAgLy8g5qiq5ZCR55qEIHNsaWRlciDlj6rlpITnkIYgeFxuICAgICAgICAgICAgdmFyIG9mZnNldFggPSB4IC0gX3RoaXMucHJldlg7XG4gICAgICAgICAgICB2YXIgb2Zmc2V0WFJhbmdlID0gX3RoaXMuYWRqdXN0T2Zmc2V0UmFuZ2Uob2Zmc2V0WCAvIHdpZHRoKTtcbiAgICAgICAgICAgIC8vIOabtOaWsCBzdGFydCBlbmQgcmFuZ2Ug6IyD5Zu0XG4gICAgICAgICAgICBfdGhpcy51cGRhdGVTdGFydEVuZChvZmZzZXRYUmFuZ2UpO1xuICAgICAgICAgICAgLy8g5pu05pawIHVpXG4gICAgICAgICAgICBfdGhpcy51cGRhdGVVSShfdGhpcy5nZXRFbGVtZW50QnlMb2NhbElkKCdmb3JlZ3JvdW5kJyksIF90aGlzLmdldEVsZW1lbnRCeUxvY2FsSWQoJ21pblRleHQnKSwgX3RoaXMuZ2V0RWxlbWVudEJ5TG9jYWxJZCgnbWF4VGV4dCcpKTtcbiAgICAgICAgICAgIF90aGlzLnByZXZYID0geDtcbiAgICAgICAgICAgIF90aGlzLnByZXZZID0geTtcbiAgICAgICAgICAgIF90aGlzLmRyYXcoKTtcbiAgICAgICAgICAgIC8vIOWboOS4uuWtmOWCqOeahCBzdGFydOOAgWVuZCDlj6/og73kuI3kuIDlrprmmK/mjInlpKflsI/lrZjlgqjnmoTvvIzmiYDku6XmjpLluo/kuIDkuIvvvIzlr7nlpJbmmK8gZW5kID49IHN0YXJ0XG4gICAgICAgICAgICBfdGhpcy5lbWl0KGNvbnN0YW50XzEuU0xJREVSX0NIQU5HRSwgW190aGlzLmdldCgnc3RhcnQnKSwgX3RoaXMuZ2V0KCdlbmQnKV0uc29ydCgpKTtcbiAgICAgICAgICAgIF90aGlzLmRlbGVnYXRlRW1pdCgndmFsdWVjaGFuZ2VkJywge1xuICAgICAgICAgICAgICAgIG9yaWdpblZhbHVlOiBvcmlnaW5WYWx1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogW190aGlzLmdldCgnc3RhcnQnKSwgX3RoaXMuZ2V0KCdlbmQnKV0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgX3RoaXMub25Nb3VzZVVwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8g57uT5p2f5LmL5ZCO77yM5Y+W5raI57uR5a6a55qE5LqL5Lu2XG4gICAgICAgICAgICBpZiAoX3RoaXMuY3VycmVudFRhcmdldCkge1xuICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRUYXJnZXQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyRE9NID0gX3RoaXMuZ2V0Q29udGFpbmVyRE9NKCk7XG4gICAgICAgICAgICBpZiAoY29udGFpbmVyRE9NKSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyRE9NLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIF90aGlzLm9uTW91c2VNb3ZlKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXJET00ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIF90aGlzLm9uTW91c2VVcCk7XG4gICAgICAgICAgICAgICAgLy8g6Ziy5q2i5ruR5Yqo5YiwIGNhbnZhcyDlpJbpg6jkuYvlkI7vvIznirbmgIHkuKLlpLFcbiAgICAgICAgICAgICAgICBjb250YWluZXJET00ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIF90aGlzLm9uTW91c2VVcCk7XG4gICAgICAgICAgICAgICAgLy8g56e75Yqo56uv5LqL5Lu2XG4gICAgICAgICAgICAgICAgY29udGFpbmVyRE9NLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIF90aGlzLm9uTW91c2VNb3ZlKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXJET00ucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBfdGhpcy5vbk1vdXNlVXApO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lckRPTS5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIF90aGlzLm9uTW91c2VVcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgU2xpZGVyLnByb3RvdHlwZS5zZXRSYW5nZSA9IGZ1bmN0aW9uIChtaW4sIG1heCkge1xuICAgICAgICB0aGlzLnNldCgnbWluTGltaXQnLCBtaW4pO1xuICAgICAgICB0aGlzLnNldCgnbWF4TGltaXQnLCBtYXgpO1xuICAgICAgICB2YXIgb2xkU3RhcnQgPSB0aGlzLmdldCgnc3RhcnQnKTtcbiAgICAgICAgdmFyIG9sZEVuZCA9IHRoaXMuZ2V0KCdlbmQnKTtcbiAgICAgICAgdmFyIG5ld1N0YXJ0ID0gdXRpbF8xLmNsYW1wKG9sZFN0YXJ0LCBtaW4sIG1heCk7XG4gICAgICAgIHZhciBuZXdFbmQgPSB1dGlsXzEuY2xhbXAob2xkRW5kLCBtaW4sIG1heCk7XG4gICAgICAgIGlmICghdGhpcy5nZXQoJ2lzSW5pdCcpICYmIChvbGRTdGFydCAhPT0gbmV3U3RhcnQgfHwgb2xkRW5kICE9PSBuZXdFbmQpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFZhbHVlKFtuZXdTdGFydCwgbmV3RW5kXSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNsaWRlci5wcm90b3R5cGUuZ2V0UmFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtaW46IHRoaXMuZ2V0KCdtaW5MaW1pdCcpIHx8IDAsXG4gICAgICAgICAgICBtYXg6IHRoaXMuZ2V0KCdtYXhMaW1pdCcpIHx8IDEsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBTbGlkZXIucHJvdG90eXBlLnNldFZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIHZhciBvcmlnaW5WYWx1ZSA9IFt0aGlzLmdldCgnc3RhcnQnKSwgdGhpcy5nZXQoJ2VuZCcpXTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKHtcbiAgICAgICAgICAgICAgICBzdGFydDogdXRpbF8xLmNsYW1wKHZhbHVlWzBdLCByYW5nZS5taW4sIHJhbmdlLm1heCksXG4gICAgICAgICAgICAgICAgZW5kOiB1dGlsXzEuY2xhbXAodmFsdWVbMV0sIHJhbmdlLm1pbiwgcmFuZ2UubWF4KSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCF0aGlzLmdldCgndXBkYXRlQXV0b1JlbmRlcicpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGVsZWdhdGVFbWl0KCd2YWx1ZWNoYW5nZWQnLCB7XG4gICAgICAgICAgICAgICAgb3JpZ2luVmFsdWU6IG9yaWdpblZhbHVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTbGlkZXIucHJvdG90eXBlLmdldFZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW3RoaXMuZ2V0KCdzdGFydCcpLCB0aGlzLmdldCgnZW5kJyldO1xuICAgIH07XG4gICAgU2xpZGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgbmFtZTogJ3NsaWRlcicsIHg6IDAsIHk6IDAsIHdpZHRoOiAxMDAsIGhlaWdodDogMTYsIGJhY2tncm91bmRTdHlsZToge30sIGZvcmVncm91bmRTdHlsZToge30sIGhhbmRsZXJTdHlsZToge30sIHRleHRTdHlsZToge30sIGRlZmF1bHRDZmc6IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kU3R5bGU6IGNvbnN0YW50XzEuQkFDS0dST1VORF9TVFlMRSxcbiAgICAgICAgICAgICAgICBmb3JlZ3JvdW5kU3R5bGU6IGNvbnN0YW50XzEuRk9SRUdST1VORF9TVFlMRSxcbiAgICAgICAgICAgICAgICBoYW5kbGVyU3R5bGU6IGNvbnN0YW50XzEuSEFORExFUl9TVFlMRSxcbiAgICAgICAgICAgICAgICB0ZXh0U3R5bGU6IGNvbnN0YW50XzEuVEVYVF9TVFlMRSxcbiAgICAgICAgICAgIH0gfSk7XG4gICAgfTtcbiAgICBTbGlkZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgdmFyIHN0YXJ0ID0gY2ZnLnN0YXJ0LCBlbmQgPSBjZmcuZW5kO1xuICAgICAgICB2YXIgdmFsaWRDZmcgPSB0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpO1xuICAgICAgICBpZiAoIXV0aWxfMS5pc05pbChzdGFydCkpIHtcbiAgICAgICAgICAgIHZhbGlkQ2ZnLnN0YXJ0ID0gdXRpbF8xLmNsYW1wKHN0YXJ0LCAwLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXV0aWxfMS5pc05pbChlbmQpKSB7XG4gICAgICAgICAgICB2YWxpZENmZy5lbmQgPSB1dGlsXzEuY2xhbXAoZW5kLCAwLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnVwZGF0ZS5jYWxsKHRoaXMsIHZhbGlkQ2ZnKTtcbiAgICAgICAgdGhpcy5taW5IYW5kbGVyID0gdGhpcy5nZXRDaGlsZENvbXBvbmVudEJ5SWQodGhpcy5nZXRFbGVtZW50SWQoJ21pbkhhbmRsZXInKSk7XG4gICAgICAgIHRoaXMubWF4SGFuZGxlciA9IHRoaXMuZ2V0Q2hpbGRDb21wb25lbnRCeUlkKHRoaXMuZ2V0RWxlbWVudElkKCdtYXhIYW5kbGVyJykpO1xuICAgIH07XG4gICAgU2xpZGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldCgnc3RhcnQnLCB1dGlsXzEuY2xhbXAodGhpcy5nZXQoJ3N0YXJ0JyksIDAsIDEpKTtcbiAgICAgICAgdGhpcy5zZXQoJ2VuZCcsIHV0aWxfMS5jbGFtcCh0aGlzLmdldCgnZW5kJyksIDAsIDEpKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBTbGlkZXIucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQsIHdpZHRoID0gX2Eud2lkdGgsIGhlaWdodCA9IF9hLmhlaWdodCwgX2IgPSBfYS50cmVuZENmZywgdHJlbmRDZmcgPSBfYiA9PT0gdm9pZCAwID8ge30gOiBfYiwgbWluVGV4dCA9IF9hLm1pblRleHQsIG1heFRleHQgPSBfYS5tYXhUZXh0LCBfYyA9IF9hLmJhY2tncm91bmRTdHlsZSwgYmFja2dyb3VuZFN0eWxlID0gX2MgPT09IHZvaWQgMCA/IHt9IDogX2MsIF9kID0gX2EuZm9yZWdyb3VuZFN0eWxlLCBmb3JlZ3JvdW5kU3R5bGUgPSBfZCA9PT0gdm9pZCAwID8ge30gOiBfZCwgX2UgPSBfYS50ZXh0U3R5bGUsIHRleHRTdHlsZSA9IF9lID09PSB2b2lkIDAgPyB7fSA6IF9lLCBfZiA9IF9hLmhhbmRsZXJTdHlsZSwgaGFuZGxlclN0eWxlID0gX2YgPT09IHZvaWQgMCA/IHt9IDogX2Y7XG4gICAgICAgIHZhciBtaW4gPSBzdGFydCAqIHdpZHRoO1xuICAgICAgICB2YXIgbWF4ID0gZW5kICogd2lkdGg7XG4gICAgICAgIC8vIOi2i+WKv+WbvuaVsOaNrlxuICAgICAgICBpZiAodXRpbF8xLnNpemUodXRpbF8xLmdldCh0cmVuZENmZywgJ2RhdGEnKSkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkQ29tcG9uZW50KGdyb3VwLCB0c2xpYl8xLl9fYXNzaWduKHsgY29tcG9uZW50OiB0cmVuZF8xLlRyZW5kLCBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ3RyZW5kJyksIHg6IDAsIHk6IDAsIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB9LCB0cmVuZENmZykpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDEuIOiDjOaZr1xuICAgICAgICB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ2JhY2tncm91bmQnKSxcbiAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogMCwgeTogMCwgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0IH0sIGJhY2tncm91bmRTdHlsZSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyAyLiDlt6blj7PmloflrZdcbiAgICAgICAgdmFyIG1pblRleHRTaGFwZSA9IHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbWluVGV4dCcpLFxuICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBcbiAgICAgICAgICAgICAgICAvLyB4OiAwLFxuICAgICAgICAgICAgICAgIHk6IGhlaWdodCAvIDIsIHRleHRBbGlnbjogJ3JpZ2h0JywgdGV4dDogbWluVGV4dCwgc2lsZW50OiBmYWxzZSB9LCB0ZXh0U3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIG1heFRleHRTaGFwZSA9IHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbWF4VGV4dCcpLFxuICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBcbiAgICAgICAgICAgICAgICAvLyB4OiAwLFxuICAgICAgICAgICAgICAgIHk6IGhlaWdodCAvIDIsIHRleHRBbGlnbjogJ2xlZnQnLCB0ZXh0OiBtYXhUZXh0LCBzaWxlbnQ6IGZhbHNlIH0sIHRleHRTdHlsZSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyAzLiDliY3mma8g6YCJ5Lit6IOM5pmv5qGGXG4gICAgICAgIHZhciBmb3JlZ3JvdW5kU2hhcGUgPSB0aGlzLmFkZFNoYXBlKGdyb3VwLCB7XG4gICAgICAgICAgICBpZDogdGhpcy5nZXRFbGVtZW50SWQoJ2ZvcmVncm91bmQnKSxcbiAgICAgICAgICAgIG5hbWU6ICdmb3JlZ3JvdW5kJyxcbiAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgXG4gICAgICAgICAgICAgICAgLy8geDogMCxcbiAgICAgICAgICAgICAgICB5OiAwLCBcbiAgICAgICAgICAgICAgICAvLyB3aWR0aDogMCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCB9LCBmb3JlZ3JvdW5kU3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8g5ruR5Z2X55u45YWz55qE5aSn5bCP5L+h5oGvXG4gICAgICAgIC8vIGNvbnN0IGhhbmRsZXJXaWR0aCA9IGdldChoYW5kbGVyU3R5bGUsICd3aWR0aCcsIDEwKTtcbiAgICAgICAgdmFyIGhhbmRsZXJIZWlnaHQgPSB1dGlsXzEuZ2V0KGhhbmRsZXJTdHlsZSwgJ2hlaWdodCcsIDI0KTtcbiAgICAgICAgLy8gNC4g5bem5Y+z5ruR5Z2XXG4gICAgICAgIHRoaXMubWluSGFuZGxlciA9IHRoaXMuYWRkQ29tcG9uZW50KGdyb3VwLCB0c2xpYl8xLl9fYXNzaWduKHsgY29tcG9uZW50OiBoYW5kbGVyXzEuSGFuZGxlciwgaWQ6IHRoaXMuZ2V0RWxlbWVudElkKCdtaW5IYW5kbGVyJyksIG5hbWU6ICdoYW5kbGVyLW1pbicsIHg6IDAsIHk6IChoZWlnaHQgLSBoYW5kbGVySGVpZ2h0KSAvIDIsIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoYW5kbGVySGVpZ2h0LCBjdXJzb3I6ICdldy1yZXNpemUnIH0sIGhhbmRsZXJTdHlsZSkpO1xuICAgICAgICB0aGlzLm1heEhhbmRsZXIgPSB0aGlzLmFkZENvbXBvbmVudChncm91cCwgdHNsaWJfMS5fX2Fzc2lnbih7IGNvbXBvbmVudDogaGFuZGxlcl8xLkhhbmRsZXIsIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbWF4SGFuZGxlcicpLCBuYW1lOiAnaGFuZGxlci1tYXgnLCB4OiAwLCB5OiAoaGVpZ2h0IC0gaGFuZGxlckhlaWdodCkgLyAyLCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGFuZGxlckhlaWdodCwgY3Vyc29yOiAnZXctcmVzaXplJyB9LCBoYW5kbGVyU3R5bGUpKTtcbiAgICAgICAgdGhpcy51cGRhdGVVSShmb3JlZ3JvdW5kU2hhcGUsIG1pblRleHRTaGFwZSwgbWF4VGV4dFNoYXBlKTtcbiAgICB9O1xuICAgIFNsaWRlci5wcm90b3R5cGUuYXBwbHlPZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMubW92ZUVsZW1lbnRUbyh0aGlzLmdldCgnZ3JvdXAnKSwge1xuICAgICAgICAgICAgeDogdGhpcy5nZXQoJ3gnKSxcbiAgICAgICAgICAgIHk6IHRoaXMuZ2V0KCd5JyksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU2xpZGVyLnByb3RvdHlwZS5pbml0RXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYmluZEV2ZW50cygpO1xuICAgIH07XG4gICAgU2xpZGVyLnByb3RvdHlwZS51cGRhdGVVSSA9IGZ1bmN0aW9uIChmb3JlZ3JvdW5kU2hhcGUsIG1pblRleHRTaGFwZSwgbWF4VGV4dFNoYXBlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQsIHdpZHRoID0gX2Eud2lkdGgsIG1pblRleHQgPSBfYS5taW5UZXh0LCBtYXhUZXh0ID0gX2EubWF4VGV4dCwgaGFuZGxlclN0eWxlID0gX2EuaGFuZGxlclN0eWxlO1xuICAgICAgICB2YXIgbWluID0gc3RhcnQgKiB3aWR0aDtcbiAgICAgICAgdmFyIG1heCA9IGVuZCAqIHdpZHRoO1xuICAgICAgICAvLyAxLiBmb3JlZ3JvdW5kXG4gICAgICAgIGZvcmVncm91bmRTaGFwZS5hdHRyKCd4JywgbWluKTtcbiAgICAgICAgZm9yZWdyb3VuZFNoYXBlLmF0dHIoJ3dpZHRoJywgbWF4IC0gbWluKTtcbiAgICAgICAgLy8g5ruR5Z2X55u45YWz55qE5aSn5bCP5L+h5oGvXG4gICAgICAgIHZhciBoYW5kbGVyV2lkdGggPSB1dGlsXzEuZ2V0KGhhbmRsZXJTdHlsZSwgJ3dpZHRoJywgY29uc3RhbnRfMS5ERUZBVUxUX0hBTkRMRVJfV0lEVEgpO1xuICAgICAgICAvLyDorr7nva7mlofmnKxcbiAgICAgICAgbWluVGV4dFNoYXBlLmF0dHIoJ3RleHQnLCBtaW5UZXh0KTtcbiAgICAgICAgbWF4VGV4dFNoYXBlLmF0dHIoJ3RleHQnLCBtYXhUZXh0KTtcbiAgICAgICAgdmFyIF9iID0gdGhpcy5fZG9kZ2VUZXh0KFttaW4sIG1heF0sIG1pblRleHRTaGFwZSwgbWF4VGV4dFNoYXBlKSwgbWluQXR0cnMgPSBfYlswXSwgbWF4QXR0cnMgPSBfYlsxXTtcbiAgICAgICAgLy8gMi4g5bem5L6n5ruR5Z2X5ZKM5paH5a2X5L2N572uXG4gICAgICAgIGlmICh0aGlzLm1pbkhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMubWluSGFuZGxlci51cGRhdGUoe1xuICAgICAgICAgICAgICAgIHg6IG1pbiAtIGhhbmRsZXJXaWR0aCAvIDIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghdGhpcy5nZXQoJ3VwZGF0ZUF1dG9SZW5kZXInKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWluSGFuZGxlci5yZW5kZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB1dGlsXzEuZWFjaChtaW5BdHRycywgZnVuY3Rpb24gKHYsIGspIHsgcmV0dXJuIG1pblRleHRTaGFwZS5hdHRyKGssIHYpOyB9KTtcbiAgICAgICAgLy8gMy4g5Y+z5L6n5ruR5Z2X5ZKM5paH5a2X5L2N572uXG4gICAgICAgIGlmICh0aGlzLm1heEhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMubWF4SGFuZGxlci51cGRhdGUoe1xuICAgICAgICAgICAgICAgIHg6IG1heCAtIGhhbmRsZXJXaWR0aCAvIDIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghdGhpcy5nZXQoJ3VwZGF0ZUF1dG9SZW5kZXInKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWF4SGFuZGxlci5yZW5kZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB1dGlsXzEuZWFjaChtYXhBdHRycywgZnVuY3Rpb24gKHYsIGspIHsgcmV0dXJuIG1heFRleHRTaGFwZS5hdHRyKGssIHYpOyB9KTtcbiAgICB9O1xuICAgIFNsaWRlci5wcm90b3R5cGUuYmluZEV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5nZXQoJ2dyb3VwJyk7XG4gICAgICAgIGdyb3VwLm9uKCdoYW5kbGVyLW1pbjptb3VzZWRvd24nLCB0aGlzLm9uTW91c2VEb3duKCdtaW5IYW5kbGVyJykpO1xuICAgICAgICBncm91cC5vbignaGFuZGxlci1taW46dG91Y2hzdGFydCcsIHRoaXMub25Nb3VzZURvd24oJ21pbkhhbmRsZXInKSk7XG4gICAgICAgIC8vIDIuIOWPs+a7keWdl+eahOa7keWKqFxuICAgICAgICBncm91cC5vbignaGFuZGxlci1tYXg6bW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bignbWF4SGFuZGxlcicpKTtcbiAgICAgICAgZ3JvdXAub24oJ2hhbmRsZXItbWF4OnRvdWNoc3RhcnQnLCB0aGlzLm9uTW91c2VEb3duKCdtYXhIYW5kbGVyJykpO1xuICAgICAgICAvLyAzLiDliY3mma/pgInkuK3ljLrln59cbiAgICAgICAgdmFyIGZvcmVncm91bmQgPSBncm91cC5maW5kQnlJZCh0aGlzLmdldEVsZW1lbnRJZCgnZm9yZWdyb3VuZCcpKTtcbiAgICAgICAgZm9yZWdyb3VuZC5vbignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bignZm9yZWdyb3VuZCcpKTtcbiAgICAgICAgZm9yZWdyb3VuZC5vbigndG91Y2hzdGFydCcsIHRoaXMub25Nb3VzZURvd24oJ2ZvcmVncm91bmQnKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDosIPmlbQgb2Zmc2V0UmFuZ2XvvIzlm6DkuLrkuIDkupvojIPlm7TnmoTpmZDliLZcbiAgICAgKiBAcGFyYW0gb2Zmc2V0UmFuZ2VcbiAgICAgKi9cbiAgICBTbGlkZXIucHJvdG90eXBlLmFkanVzdE9mZnNldFJhbmdlID0gZnVuY3Rpb24gKG9mZnNldFJhbmdlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIC8vIOmSiOWvueS4jeWQjOeahOa7keWKqOe7hOS7tu+8jOWkhOeQhueahOaWueW8j+S4jeWQjFxuICAgICAgICBzd2l0Y2ggKHRoaXMuY3VycmVudFRhcmdldCkge1xuICAgICAgICAgICAgY2FzZSAnbWluSGFuZGxlcic6IHtcbiAgICAgICAgICAgICAgICB2YXIgbWluID0gMCAtIHN0YXJ0O1xuICAgICAgICAgICAgICAgIHZhciBtYXggPSAxIC0gc3RhcnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKG1heCwgTWF0aC5tYXgobWluLCBvZmZzZXRSYW5nZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAnbWF4SGFuZGxlcic6IHtcbiAgICAgICAgICAgICAgICB2YXIgbWluID0gMCAtIGVuZDtcbiAgICAgICAgICAgICAgICB2YXIgbWF4ID0gMSAtIGVuZDtcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0aC5taW4obWF4LCBNYXRoLm1heChtaW4sIG9mZnNldFJhbmdlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlICdmb3JlZ3JvdW5kJzoge1xuICAgICAgICAgICAgICAgIHZhciBtaW4gPSAwIC0gc3RhcnQ7XG4gICAgICAgICAgICAgICAgdmFyIG1heCA9IDEgLSBlbmQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKG1heCwgTWF0aC5tYXgobWluLCBvZmZzZXRSYW5nZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBTbGlkZXIucHJvdG90eXBlLnVwZGF0ZVN0YXJ0RW5kID0gZnVuY3Rpb24gKG9mZnNldFJhbmdlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIC8vIOaTjeS9nOS4jeWQjOeahOe7hOS7tu+8jOWPjemmiOS4jeS4gOagt1xuICAgICAgICBzd2l0Y2ggKHRoaXMuY3VycmVudFRhcmdldCkge1xuICAgICAgICAgICAgY2FzZSAnbWluSGFuZGxlcic6XG4gICAgICAgICAgICAgICAgc3RhcnQgKz0gb2Zmc2V0UmFuZ2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtYXhIYW5kbGVyJzpcbiAgICAgICAgICAgICAgICBlbmQgKz0gb2Zmc2V0UmFuZ2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdmb3JlZ3JvdW5kJzpcbiAgICAgICAgICAgICAgICBzdGFydCArPSBvZmZzZXRSYW5nZTtcbiAgICAgICAgICAgICAgICBlbmQgKz0gb2Zmc2V0UmFuZ2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ3N0YXJ0Jywgc3RhcnQpO1xuICAgICAgICB0aGlzLnNldCgnZW5kJywgZW5kKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiwg+aVtCB0ZXh0IOeahOS9jee9ru+8jOiHquWKqOi6sumBv1xuICAgICAqIOagueaNruS9jee9ru+8jOiwg+aVtOi/lOWbnuaWsOeahOS9jee9rlxuICAgICAqIEBwYXJhbSByYW5nZVxuICAgICAqL1xuICAgIFNsaWRlci5wcm90b3R5cGUuX2RvZGdlVGV4dCA9IGZ1bmN0aW9uIChyYW5nZSwgbWluVGV4dFNoYXBlLCBtYXhUZXh0U2hhcGUpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgdmFyIF9jID0gdGhpcy5jZmcsIGhhbmRsZXJTdHlsZSA9IF9jLmhhbmRsZXJTdHlsZSwgd2lkdGggPSBfYy53aWR0aDtcbiAgICAgICAgdmFyIFBBRERJTkcgPSAyO1xuICAgICAgICB2YXIgaGFuZGxlcldpZHRoID0gdXRpbF8xLmdldChoYW5kbGVyU3R5bGUsICd3aWR0aCcsIGNvbnN0YW50XzEuREVGQVVMVF9IQU5ETEVSX1dJRFRIKTtcbiAgICAgICAgdmFyIG1pbiA9IHJhbmdlWzBdLCBtYXggPSByYW5nZVsxXTtcbiAgICAgICAgdmFyIHNvcnRlZCA9IGZhbHNlO1xuICAgICAgICAvLyDlpoLmnpzkuqTmjaLkuobkvY3nva7vvIzliJnlr7nlupTnmoQgbWluIG1heCDkuZ/kuqTkupJcbiAgICAgICAgaWYgKG1pbiA+IG1heCkge1xuICAgICAgICAgICAgX2EgPSBbbWF4LCBtaW5dLCBtaW4gPSBfYVswXSwgbWF4ID0gX2FbMV07XG4gICAgICAgICAgICBfYiA9IFttYXhUZXh0U2hhcGUsIG1pblRleHRTaGFwZV0sIG1pblRleHRTaGFwZSA9IF9iWzBdLCBtYXhUZXh0U2hhcGUgPSBfYlsxXTtcbiAgICAgICAgICAgIHNvcnRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6YG/6K6p6KeE5YiZ77yM5LyY5YWI5pi+56S65Zyo5Lik5L6n77yM5Y+q5pyJ5pi+56S65LiN5LiL55qE5pe25YCZ77yM5omN5pi+56S65Zyo5Lit6Ze0XG4gICAgICAgIHZhciBtaW5CQm94ID0gbWluVGV4dFNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdmFyIG1heEJCb3ggPSBtYXhUZXh0U2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgbWluQXR0cnMgPSBtaW5CQm94LndpZHRoID4gbWluIC0gUEFERElOR1xuICAgICAgICAgICAgPyB7IHg6IG1pbiArIGhhbmRsZXJXaWR0aCAvIDIgKyBQQURESU5HLCB0ZXh0QWxpZ246ICdsZWZ0JyB9XG4gICAgICAgICAgICA6IHsgeDogbWluIC0gaGFuZGxlcldpZHRoIC8gMiAtIFBBRERJTkcsIHRleHRBbGlnbjogJ3JpZ2h0JyB9O1xuICAgICAgICB2YXIgbWF4QXR0cnMgPSBtYXhCQm94LndpZHRoID4gd2lkdGggLSBtYXggLSBQQURESU5HXG4gICAgICAgICAgICA/IHsgeDogbWF4IC0gaGFuZGxlcldpZHRoIC8gMiAtIFBBRERJTkcsIHRleHRBbGlnbjogJ3JpZ2h0JyB9XG4gICAgICAgICAgICA6IHsgeDogbWF4ICsgaGFuZGxlcldpZHRoIC8gMiArIFBBRERJTkcsIHRleHRBbGlnbjogJ2xlZnQnIH07XG4gICAgICAgIHJldHVybiAhc29ydGVkID8gW21pbkF0dHJzLCBtYXhBdHRyc10gOiBbbWF4QXR0cnMsIG1pbkF0dHJzXTtcbiAgICB9O1xuICAgIFNsaWRlci5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgdmFyIGNhbnZhcyA9IGNvbnRhaW5lciAmJiBjb250YWluZXIuZ2V0KCdjYW52YXMnKTtcbiAgICAgICAgaWYgKGNhbnZhcykge1xuICAgICAgICAgICAgY2FudmFzLmRyYXcoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2xpZGVyLnByb3RvdHlwZS5nZXRDb250YWluZXJET00gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgIHZhciBjYW52YXMgPSBjb250YWluZXIgJiYgY29udGFpbmVyLmdldCgnY2FudmFzJyk7XG4gICAgICAgIHJldHVybiBjYW52YXMgJiYgY2FudmFzLmdldCgnY29udGFpbmVyJyk7XG4gICAgfTtcbiAgICByZXR1cm4gU2xpZGVyO1xufShncm91cF9jb21wb25lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLlNsaWRlciA9IFNsaWRlcjtcbmV4cG9ydHMuZGVmYXVsdCA9IFNsaWRlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNsaWRlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQ1JPU1NIQUlSX1kgPSBleHBvcnRzLkNST1NTSEFJUl9YID0gZXhwb3J0cy5OQU1FX0NMQVNTID0gZXhwb3J0cy5WQUxVRV9DTEFTUyA9IGV4cG9ydHMuTUFSS0VSX0NMQVNTID0gZXhwb3J0cy5MSVNUX0lURU1fQ0xBU1MgPSBleHBvcnRzLkxJU1RfQ0xBU1MgPSBleHBvcnRzLlRJVExFX0NMQVNTID0gZXhwb3J0cy5DT05UQUlORVJfQ0xBU1MgPSB2b2lkIDA7XG5leHBvcnRzLkNPTlRBSU5FUl9DTEFTUyA9ICdnMi10b29sdGlwJztcbmV4cG9ydHMuVElUTEVfQ0xBU1MgPSAnZzItdG9vbHRpcC10aXRsZSc7XG5leHBvcnRzLkxJU1RfQ0xBU1MgPSAnZzItdG9vbHRpcC1saXN0JztcbmV4cG9ydHMuTElTVF9JVEVNX0NMQVNTID0gJ2cyLXRvb2x0aXAtbGlzdC1pdGVtJztcbmV4cG9ydHMuTUFSS0VSX0NMQVNTID0gJ2cyLXRvb2x0aXAtbWFya2VyJztcbmV4cG9ydHMuVkFMVUVfQ0xBU1MgPSAnZzItdG9vbHRpcC12YWx1ZSc7XG5leHBvcnRzLk5BTUVfQ0xBU1MgPSAnZzItdG9vbHRpcC1uYW1lJztcbmV4cG9ydHMuQ1JPU1NIQUlSX1ggPSAnZzItdG9vbHRpcC1jcm9zc2hhaXIteCc7XG5leHBvcnRzLkNST1NTSEFJUl9ZID0gJ2cyLXRvb2x0aXAtY3Jvc3NoYWlyLXknO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3NzLWNvbnN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9hO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbi8vIHRvb2x0aXAg55u45YWzIGRvbSDnmoQgY3NzIOexu+WQjVxudmFyIENzc0NvbnN0ID0gcmVxdWlyZShcIi4vY3NzLWNvbnN0XCIpO1xuZXhwb3J0cy5kZWZhdWx0ID0gKF9hID0ge30sXG4gICAgLy8gY3NzIHN0eWxlIGZvciB0b29sdGlwXG4gICAgX2FbXCJcIiArIENzc0NvbnN0LkNPTlRBSU5FUl9DTEFTU10gPSB7XG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICB2aXNpYmlsaXR5OiAndmlzaWJsZScsXG4gICAgICAgIC8vIEAyMDE4LTA3LTI1IGJ5IGJsdWUubGIg6L+Z6YeM5Y675o6J5rWu5Yqo77yM54Gr54uQ5LiK5a2Y5Zyo5qC35byP6ZSZ5L2NXG4gICAgICAgIC8vIHdoaXRlU3BhY2U6ICdub3dyYXAnLFxuICAgICAgICB6SW5kZXg6IDgsXG4gICAgICAgIHRyYW5zaXRpb246ICd2aXNpYmlsaXR5IDAuMnMgY3ViaWMtYmV6aWVyKDAuMjMsIDEsIDAuMzIsIDEpLCAnICtcbiAgICAgICAgICAgICdsZWZ0IDAuNHMgY3ViaWMtYmV6aWVyKDAuMjMsIDEsIDAuMzIsIDEpLCAnICtcbiAgICAgICAgICAgICd0b3AgMC40cyBjdWJpYy1iZXppZXIoMC4yMywgMSwgMC4zMiwgMSknLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuOSknLFxuICAgICAgICBib3hTaGFkb3c6ICcwcHggMHB4IDEwcHggI2FlYWVhZScsXG4gICAgICAgIGJvcmRlclJhZGl1czogJzNweCcsXG4gICAgICAgIGNvbG9yOiAncmdiKDg3LCA4NywgODcpJyxcbiAgICAgICAgZm9udFNpemU6ICcxMnB4JyxcbiAgICAgICAgZm9udEZhbWlseTogdGhlbWVfMS5kZWZhdWx0LmZvbnRGYW1pbHksXG4gICAgICAgIGxpbmVIZWlnaHQ6ICcyMHB4JyxcbiAgICAgICAgcGFkZGluZzogJzEwcHggMTBweCA2cHggMTBweCcsXG4gICAgfSxcbiAgICBfYVtcIlwiICsgQ3NzQ29uc3QuVElUTEVfQ0xBU1NdID0ge1xuICAgICAgICBtYXJnaW5Cb3R0b206ICc0cHgnLFxuICAgIH0sXG4gICAgX2FbXCJcIiArIENzc0NvbnN0LkxJU1RfQ0xBU1NdID0ge1xuICAgICAgICBtYXJnaW46ICcwcHgnLFxuICAgICAgICBsaXN0U3R5bGVUeXBlOiAnbm9uZScsXG4gICAgICAgIHBhZGRpbmc6ICcwcHgnLFxuICAgIH0sXG4gICAgX2FbXCJcIiArIENzc0NvbnN0LkxJU1RfSVRFTV9DTEFTU10gPSB7XG4gICAgICAgIGxpc3RTdHlsZVR5cGU6ICdub25lJyxcbiAgICAgICAgbWFyZ2luQm90dG9tOiAnNHB4JyxcbiAgICB9LFxuICAgIF9hW1wiXCIgKyBDc3NDb25zdC5NQVJLRVJfQ0xBU1NdID0ge1xuICAgICAgICB3aWR0aDogJzhweCcsXG4gICAgICAgIGhlaWdodDogJzhweCcsXG4gICAgICAgIGJvcmRlclJhZGl1czogJzUwJScsXG4gICAgICAgIGRpc3BsYXk6ICdpbmxpbmUtYmxvY2snLFxuICAgICAgICBtYXJnaW5SaWdodDogJzhweCcsXG4gICAgfSxcbiAgICBfYVtcIlwiICsgQ3NzQ29uc3QuVkFMVUVfQ0xBU1NdID0ge1xuICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyxcbiAgICAgICAgZmxvYXQ6ICdyaWdodCcsXG4gICAgICAgIG1hcmdpbkxlZnQ6ICczMHB4JyxcbiAgICB9LFxuICAgIF9hW1wiXCIgKyBDc3NDb25zdC5DUk9TU0hBSVJfWF0gPSB7XG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICB3aWR0aDogJzFweCcsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC4yNSknLFxuICAgIH0sXG4gICAgX2FbXCJcIiArIENzc0NvbnN0LkNST1NTSEFJUl9ZXSA9IHtcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIGhlaWdodDogJzFweCcsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC4yNSknLFxuICAgIH0sXG4gICAgX2EpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aHRtbC10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGNvbG9yX3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9jb2xvci11dGlsXCIpO1xudmFyIGRvbV91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvZG9tLXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgaHRtbF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9odG1sLWNvbXBvbmVudFwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbC91dGlsXCIpO1xudmFyIENzc0NvbnN0ID0gcmVxdWlyZShcIi4vY3NzLWNvbnN0XCIpO1xudmFyIGh0bWxfdGhlbWVfMSA9IHJlcXVpcmUoXCIuL2h0bWwtdGhlbWVcIik7XG52YXIgYWxpZ25fMSA9IHJlcXVpcmUoXCIuLi91dGlsL2FsaWduXCIpO1xuZnVuY3Rpb24gaGFzT25lS2V5KG9iaiwga2V5cykge1xuICAgIHZhciByZXN1bHQgPSBmYWxzZTtcbiAgICB1dGlsXzEuZWFjaChrZXlzLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmICh1dGlsXzEuaGFzS2V5KG9iaiwga2V5KSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG52YXIgVG9vbHRpcCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUb29sdGlwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRvb2x0aXAoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IG5hbWU6ICd0b29sdGlwJywgdHlwZTogJ2h0bWwnLCB4OiAwLCB5OiAwLCBpdGVtczogW10sIGN1c3RvbUNvbnRlbnQ6IG51bGwsIGNvbnRhaW5lclRwbDogXCI8ZGl2IGNsYXNzPVxcXCJcIiArIENzc0NvbnN0LkNPTlRBSU5FUl9DTEFTUyArIFwiXFxcIj48ZGl2IGNsYXNzPVxcXCJcIiArIENzc0NvbnN0LlRJVExFX0NMQVNTICsgXCJcXFwiPjwvZGl2Pjx1bCBjbGFzcz1cXFwiXCIgKyBDc3NDb25zdC5MSVNUX0NMQVNTICsgXCJcXFwiPjwvdWw+PC9kaXY+XCIsIGl0ZW1UcGw6IFwiPGxpIGNsYXNzPVxcXCJcIiArIENzc0NvbnN0LkxJU1RfSVRFTV9DTEFTUyArIFwiXFxcIiBkYXRhLWluZGV4PXtpbmRleH0+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJcIiArIENzc0NvbnN0Lk1BUktFUl9DTEFTUyArIFwiXFxcIiBzdHlsZT1cXFwiYmFja2dyb3VuZDp7Y29sb3J9XFxcIj48L3NwYW4+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJcIiArIENzc0NvbnN0Lk5BTUVfQ0xBU1MgKyBcIlxcXCI+e25hbWV9PC9zcGFuPjpcXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XFxcIlwiICsgQ3NzQ29uc3QuVkFMVUVfQ0xBU1MgKyBcIlxcXCI+e3ZhbHVlfTwvc3Bhbj5cXG4gICAgICAgIDwvbGk+XCIsIHhDcm9zc2hhaXJUcGw6IFwiPGRpdiBjbGFzcz1cXFwiXCIgKyBDc3NDb25zdC5DUk9TU0hBSVJfWCArIFwiXFxcIj48L2Rpdj5cIiwgeUNyb3NzaGFpclRwbDogXCI8ZGl2IGNsYXNzPVxcXCJcIiArIENzc0NvbnN0LkNST1NTSEFJUl9ZICsgXCJcXFwiPjwvZGl2PlwiLCB0aXRsZTogbnVsbCwgc2hvd1RpdGxlOiB0cnVlLCBcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogdG9vbHRpcCDpmZDliLbnmoTljLrln59cbiAgICAgICAgICAgICAqIEB0eXBlIHtSZWdpb259XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHJlZ2lvbjogbnVsbCwgXG4gICAgICAgICAgICAvLyBjcm9zc2hhaXIg55qE6ZmQ5Yi25Yy65Z+fXG4gICAgICAgICAgICBjcm9zc2hhaXJzUmVnaW9uOiBudWxsLCBjb250YWluZXJDbGFzc05hbWU6IENzc0NvbnN0LkNPTlRBSU5FUl9DTEFTUywgXG4gICAgICAgICAgICAvLyB4LCB5LCB4eVxuICAgICAgICAgICAgY3Jvc3NoYWlyczogbnVsbCwgb2Zmc2V0OiAxMCwgcG9zaXRpb246ICdyaWdodCcsIGRvbVN0eWxlczogbnVsbCwgZGVmYXVsdFN0eWxlczogaHRtbF90aGVtZV8xLmRlZmF1bHQgfSk7XG4gICAgfTtcbiAgICAvLyB0b29sdGlwIOa4suafk+aXtu+8jOa4suafkyB0aXRsZe+8jGl0ZW1zIOWSjCBjb3Jvc3NoYWlyc1xuICAgIFRvb2x0aXAucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdjdXN0b21Db250ZW50JykpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyQ3VzdG9tQ29udGVudCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZXNldFRpdGxlKCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckl0ZW1zKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g57uY5Yi25a6M5oiQ5ZCO77yM5YaN5a6a5L2NXG4gICAgICAgIHRoaXMucmVzZXRQb3NpdGlvbigpO1xuICAgIH07XG4gICAgLy8g5aSN5YaZ5riF56m65Ye95pWw77yM5Zug5Li65pyJ5qih5p2/55qE5a2Y5Zyo77yM5omA5Lul6buY6K6k55qE5YaZ5rOV5LiN5ZCI6YCCXG4gICAgVG9vbHRpcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOeUseS6jiBjcm9zc2hhaXIg5rKh5pyJ5ZyoIGNvbnRhaW5lciDlhoXvvIzmiYDku6XpnIDopoHljZXni6zmuIXnkIZcbiAgICAgICAgdGhpcy5jbGVhckNyb3NzaGFpcnMoKTtcbiAgICAgICAgdGhpcy5zZXRUaXRsZSgnJyk7IC8vIOa4heepuuagh+mimFxuICAgICAgICB0aGlzLmNsZWFySXRlbURvbXMoKTtcbiAgICB9O1xuICAgIFRvb2x0aXAucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldENvbnRhaW5lcigpO1xuICAgICAgICBpZiAoIWNvbnRhaW5lciB8fCB0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgLy8g6Ziy5q2i5a655Zmo5LiN5a2Y5Zyo5oiW6ICF6KKr6ZSA5q+B5pe25oql6ZSZXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoY29udGFpbmVyLCB7XG4gICAgICAgICAgICB2aXNpYmlsaXR5OiAndmlzaWJsZScsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldENyb3NzSGFpcnNWaXNpYmxlKHRydWUpO1xuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0Q29udGFpbmVyKCk7XG4gICAgICAgIC8vIHJlbGF0aXZlOiBodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL2cyL2lzc3Vlcy8xMjIxXG4gICAgICAgIGlmICghY29udGFpbmVyIHx8IHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGNvbnRhaW5lciwge1xuICAgICAgICAgICAgdmlzaWJpbGl0eTogJ2hpZGRlbicsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldENyb3NzSGFpcnNWaXNpYmxlKGZhbHNlKTtcbiAgICB9O1xuICAgIC8vIOWunueOsCBJUG9pbnRMb2NhdGlvbiDnmoTmjqXlj6NcbiAgICBUb29sdGlwLnByb3RvdHlwZS5nZXRMb2NhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHsgeDogdGhpcy5nZXQoJ3gnKSwgeTogdGhpcy5nZXQoJ3knKSB9O1xuICAgIH07XG4gICAgLy8g5a6e546wIElQb2ludExvY2F0aW9uIOeahOaOpeWPo1xuICAgIFRvb2x0aXAucHJvdG90eXBlLnNldExvY2F0aW9uID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHRoaXMuc2V0KCd4JywgcG9pbnQueCk7XG4gICAgICAgIHRoaXMuc2V0KCd5JywgcG9pbnQueSk7XG4gICAgICAgIHRoaXMucmVzZXRQb3NpdGlvbigpO1xuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuc2V0Q3Jvc3NIYWlyc1Zpc2libGUgPSBmdW5jdGlvbiAodmlzaWJsZSkge1xuICAgICAgICB2YXIgZGlzcGxheSA9IHZpc2libGUgPyAnJyA6ICdub25lJztcbiAgICAgICAgdmFyIHhDcm9zc2hhaXJEb20gPSB0aGlzLmdldCgneENyb3NzaGFpckRvbScpO1xuICAgICAgICB2YXIgeUNyb3NzaGFpckRvbSA9IHRoaXMuZ2V0KCd5Q3Jvc3NoYWlyRG9tJyk7XG4gICAgICAgIHhDcm9zc2hhaXJEb20gJiZcbiAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKHhDcm9zc2hhaXJEb20sIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiBkaXNwbGF5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIHlDcm9zc2hhaXJEb20gJiZcbiAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKHlDcm9zc2hhaXJEb20sIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiBkaXNwbGF5LFxuICAgICAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDlpoLmnIkgY3VzdG9tQ29udGVudCDliJnmoLnmja4gY3VzdG9tQ29udGVudCDorr7nva4gY29udGFpbmVyXG4gICAgVG9vbHRpcC5wcm90b3R5cGUuaW5pdENvbnRhaW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0Q29udGFpbmVyLmNhbGwodGhpcyk7XG4gICAgICAgIGlmICh0aGlzLmdldCgnY3VzdG9tQ29udGVudCcpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5nZXQoJ2NvbnRhaW5lcicpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXQoJ2NvbnRhaW5lcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0SHRtbENvbnRlbnROb2RlKCk7XG4gICAgICAgICAgICB0aGlzLmdldCgncGFyZW50JykuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICAgICAgICAgIHRoaXMuc2V0KCdjb250YWluZXInLCBjb250YWluZXIpO1xuICAgICAgICAgICAgdGhpcy5yZXNldFN0eWxlcygpO1xuICAgICAgICAgICAgdGhpcy5hcHBseVN0eWxlcygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmm7TmlrDlsZ7mgKfnmoTlkIzml7bvvIzlj6/og73kvJrlvJXotbcgRE9NIOeahOWPmOWMlu+8jOi/memHjOWvueWPr+iDveW8lei1tyBET00g5Y+Y5YyW55qE5Zy65pmv5YGa5LqG5aSE55CGXG4gICAgVG9vbHRpcC5wcm90b3R5cGUudXBkYXRlSW5uZXIgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIGlmICh0aGlzLmdldCgnY3VzdG9tQ29udGVudCcpKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckN1c3RvbUNvbnRlbnQoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOabtOaWsOagh+mimFxuICAgICAgICAgICAgaWYgKGhhc09uZUtleShjZmcsIFsndGl0bGUnLCAnc2hvd1RpdGxlJ10pKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldFRpdGxlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDmm7TmlrDlhoXlrrlcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaGFzS2V5KGNmZywgJ2l0ZW1zJykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlckl0ZW1zKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS51cGRhdGVJbm5lci5jYWxsKHRoaXMsIGNmZyk7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5pbml0RG9tID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNhY2hlRG9tcygpO1xuICAgIH07XG4gICAgLy8g5riF55CGIERPTVxuICAgIFRvb2x0aXAucHJvdG90eXBlLnJlbW92ZURvbSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5yZW1vdmVEb20uY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5jbGVhckNyb3NzaGFpcnMoKTtcbiAgICB9O1xuICAgIC8vIOiwg+aVtOS9jee9rlxuICAgIFRvb2x0aXAucHJvdG90eXBlLnJlc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4ID0gdGhpcy5nZXQoJ3gnKTtcbiAgICAgICAgdmFyIHkgPSB0aGlzLmdldCgneScpO1xuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXQoJ29mZnNldCcpO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldE9mZnNldCgpLCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFk7XG4gICAgICAgIHZhciBwb3NpdGlvbiA9IHRoaXMuZ2V0KCdwb3NpdGlvbicpO1xuICAgICAgICB2YXIgcmVnaW9uID0gdGhpcy5nZXQoJ3JlZ2lvbicpO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXRDb250YWluZXIoKTtcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldEJCb3goKTtcbiAgICAgICAgdmFyIHdpZHRoID0gYmJveC53aWR0aCwgaGVpZ2h0ID0gYmJveC5oZWlnaHQ7XG4gICAgICAgIHZhciBsaW1pdEJveDtcbiAgICAgICAgaWYgKHJlZ2lvbikge1xuICAgICAgICAgICAgLy8g5LiN6ZmQ5Yi25L2N572uXG4gICAgICAgICAgICBsaW1pdEJveCA9IHV0aWxfMi5yZWdpb25Ub0JCb3gocmVnaW9uKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcG9pbnQgPSBhbGlnbl8xLmdldEFsaWduUG9pbnQoeCwgeSwgb2Zmc2V0LCB3aWR0aCwgaGVpZ2h0LCBwb3NpdGlvbiwgbGltaXRCb3gpO1xuICAgICAgICBkb21fdXRpbF8xLm1vZGlmeUNTUyhjb250YWluZXIsIHtcbiAgICAgICAgICAgIGxlZnQ6IHV0aWxfMi50b1B4KHBvaW50LnggKyBvZmZzZXRYKSxcbiAgICAgICAgICAgIHRvcDogdXRpbF8yLnRvUHgocG9pbnQueSArIG9mZnNldFkpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXNldENyb3NzaGFpcnMoKTtcbiAgICB9O1xuICAgIC8vIOagueaNriBjdXN0b21Db250ZW50IOa4suafk1xuICAgIFRvb2x0aXAucHJvdG90eXBlLnJlbmRlckN1c3RvbUNvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBub2RlID0gdGhpcy5nZXRIdG1sQ29udGVudE5vZGUoKTtcbiAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMuZ2V0KCdwYXJlbnQnKTtcbiAgICAgICAgdmFyIGN1ckNvbnRhaW5lciA9IHRoaXMuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgaWYgKGN1ckNvbnRhaW5lciAmJiBjdXJDb250YWluZXIucGFyZW50Tm9kZSA9PT0gcGFyZW50KSB7XG4gICAgICAgICAgICBwYXJlbnQucmVwbGFjZUNoaWxkKG5vZGUsIGN1ckNvbnRhaW5lcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ2NvbnRhaW5lcicsIG5vZGUpO1xuICAgICAgICB0aGlzLnJlc2V0U3R5bGVzKCk7XG4gICAgICAgIHRoaXMuYXBwbHlTdHlsZXMoKTtcbiAgICB9O1xuICAgIFRvb2x0aXAucHJvdG90eXBlLmdldEh0bWxDb250ZW50Tm9kZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGU7XG4gICAgICAgIHZhciBjdXN0b21Db250ZW50ID0gdGhpcy5nZXQoJ2N1c3RvbUNvbnRlbnQnKTtcbiAgICAgICAgaWYgKGN1c3RvbUNvbnRlbnQpIHtcbiAgICAgICAgICAgIHZhciBlbGVtID0gY3VzdG9tQ29udGVudCh0aGlzLmdldCgndGl0bGUnKSwgdGhpcy5nZXQoJ2l0ZW1zJykpO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0VsZW1lbnQoZWxlbSkpIHtcbiAgICAgICAgICAgICAgICBub2RlID0gZWxlbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBkb21fdXRpbF8xLmNyZWF0ZURvbShlbGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9O1xuICAgIC8vIOe8k+WtmOaooeadv+iuvue9rueahOWQhOenjSBET01cbiAgICBUb29sdGlwLnByb3RvdHlwZS5jYWNoZURvbXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldENvbnRhaW5lcigpO1xuICAgICAgICB2YXIgdGl0bGVEb20gPSBjb250YWluZXIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShDc3NDb25zdC5USVRMRV9DTEFTUylbMF07XG4gICAgICAgIHZhciBsaXN0RG9tID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoQ3NzQ29uc3QuTElTVF9DTEFTUylbMF07XG4gICAgICAgIHRoaXMuc2V0KCd0aXRsZURvbScsIHRpdGxlRG9tKTtcbiAgICAgICAgdGhpcy5zZXQoJ2xpc3REb20nLCBsaXN0RG9tKTtcbiAgICB9O1xuICAgIC8vIOmHjee9riB0aXRsZVxuICAgIFRvb2x0aXAucHJvdG90eXBlLnJlc2V0VGl0bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aXRsZSA9IHRoaXMuZ2V0KCd0aXRsZScpO1xuICAgICAgICB2YXIgc2hvd1RpdGxlID0gdGhpcy5nZXQoJ3Nob3dUaXRsZScpO1xuICAgICAgICBpZiAoc2hvd1RpdGxlICYmIHRpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFRpdGxlKHRpdGxlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0VGl0bGUoJycpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDorr7nva4gdGl0bGUg5paH5pysXG4gICAgVG9vbHRpcC5wcm90b3R5cGUuc2V0VGl0bGUgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICB2YXIgdGl0bGVEb20gPSB0aGlzLmdldCgndGl0bGVEb20nKTtcbiAgICAgICAgaWYgKHRpdGxlRG9tKSB7XG4gICAgICAgICAgICB0aXRsZURvbS5pbm5lclRleHQgPSB0ZXh0O1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDnu4jmraIgY3Jvc3NoYWlyXG4gICAgVG9vbHRpcC5wcm90b3R5cGUucmVzZXRDcm9zc2hhaXJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3Jvc3NoYWlyc1JlZ2lvbiA9IHRoaXMuZ2V0KCdjcm9zc2hhaXJzUmVnaW9uJyk7XG4gICAgICAgIHZhciBjcm9zc2hhaXJzID0gdGhpcy5nZXQoJ2Nyb3NzaGFpcnMnKTtcbiAgICAgICAgaWYgKCFjcm9zc2hhaXJzUmVnaW9uIHx8ICFjcm9zc2hhaXJzKSB7XG4gICAgICAgICAgICAvLyDkuI3mmL7npLogY3Jvc3NoYWly77yM6YO956e76Zmk77yM5rKh5pyJ6K6+5a6aIHJlZ2lvbiDkuZ/pg73np7vpmaTmjolcbiAgICAgICAgICAgIHRoaXMuY2xlYXJDcm9zc2hhaXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgY3Jvc3NoYWlyQm94ID0gdXRpbF8yLnJlZ2lvblRvQkJveChjcm9zc2hhaXJzUmVnaW9uKTtcbiAgICAgICAgICAgIHZhciB4Q3Jvc3NoYWlyRG9tID0gdGhpcy5nZXQoJ3hDcm9zc2hhaXJEb20nKTtcbiAgICAgICAgICAgIHZhciB5Q3Jvc3NoYWlyRG9tID0gdGhpcy5nZXQoJ3lDcm9zc2hhaXJEb20nKTtcbiAgICAgICAgICAgIGlmIChjcm9zc2hhaXJzID09PSAneCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2V0Q3Jvc3NoYWlyKCd4JywgY3Jvc3NoYWlyQm94KTtcbiAgICAgICAgICAgICAgICAvLyDku4XmmL7npLogeCDnmoQgY3Jvc3NoYWly77yMeSDnp7vpmaRcbiAgICAgICAgICAgICAgICBpZiAoeUNyb3NzaGFpckRvbSkge1xuICAgICAgICAgICAgICAgICAgICB5Q3Jvc3NoYWlyRG9tLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldCgneUNyb3NzaGFpckRvbScsIG51bGwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNyb3NzaGFpcnMgPT09ICd5Jykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzZXRDcm9zc2hhaXIoJ3knLCBjcm9zc2hhaXJCb3gpO1xuICAgICAgICAgICAgICAgIC8vIOS7heaYvuekuiB5IOeahCBjcm9zc2hhaXLvvIx4IOenu+mZpFxuICAgICAgICAgICAgICAgIGlmICh4Q3Jvc3NoYWlyRG9tKSB7XG4gICAgICAgICAgICAgICAgICAgIHhDcm9zc2hhaXJEb20ucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0KCd4Q3Jvc3NoYWlyRG9tJywgbnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldENyb3NzaGFpcigneCcsIGNyb3NzaGFpckJveCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNldENyb3NzaGFpcigneScsIGNyb3NzaGFpckJveCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldENyb3NzSGFpcnNWaXNpYmxlKHRoaXMuZ2V0KCd2aXNpYmxlJykpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDorr7lrpogY3Jvc3NoYWlyIOeahOS9jee9ru+8jOmcgOimgeWMuuWIhiB4LHlcbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZXNldENyb3NzaGFpciA9IGZ1bmN0aW9uIChuYW1lLCBiYm94KSB7XG4gICAgICAgIHZhciBjcm9zaGFpckRvbSA9IHRoaXMuY2hlY2tDcm9zc2hhaXIobmFtZSk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAobmFtZSA9PT0gJ3gnKSB7XG4gICAgICAgICAgICBkb21fdXRpbF8xLm1vZGlmeUNTUyhjcm9zaGFpckRvbSwge1xuICAgICAgICAgICAgICAgIGxlZnQ6IHV0aWxfMi50b1B4KHZhbHVlKSxcbiAgICAgICAgICAgICAgICB0b3A6IHV0aWxfMi50b1B4KGJib3gueSksXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB1dGlsXzIudG9QeChiYm94LmhlaWdodCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGNyb3NoYWlyRG9tLCB7XG4gICAgICAgICAgICAgICAgdG9wOiB1dGlsXzIudG9QeCh2YWx1ZSksXG4gICAgICAgICAgICAgICAgbGVmdDogdXRpbF8yLnRvUHgoYmJveC54KSxcbiAgICAgICAgICAgICAgICB3aWR0aDogdXRpbF8yLnRvUHgoYmJveC53aWR0aCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5aaC5p6cIGNyb3NzaGFpciDlr7nlupTnmoQgZG9tIOS4jeWtmOWcqO+8jOWImeWIm+W7ulxuICAgIFRvb2x0aXAucHJvdG90eXBlLmNoZWNrQ3Jvc3NoYWlyID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgdmFyIGRvbU5hbWUgPSBuYW1lICsgXCJDcm9zc2hhaXJEb21cIjtcbiAgICAgICAgdmFyIHRwbE5hbWUgPSBuYW1lICsgXCJDcm9zc2hhaXJUcGxcIjtcbiAgICAgICAgdmFyIGNvbnN0TmFtZSA9IFwiQ1JPU1NIQUlSX1wiICsgbmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICB2YXIgc3R5bGVOYW1lID0gQ3NzQ29uc3RbY29uc3ROYW1lXTtcbiAgICAgICAgdmFyIGNyb3NoYWlyRG9tID0gdGhpcy5nZXQoZG9tTmFtZSk7XG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzLmdldCgncGFyZW50Jyk7XG4gICAgICAgIGlmICghY3Jvc2hhaXJEb20pIHtcbiAgICAgICAgICAgIGNyb3NoYWlyRG9tID0gZG9tX3V0aWxfMS5jcmVhdGVEb20odGhpcy5nZXQodHBsTmFtZSkpOyAvLyDliJvlu7pcbiAgICAgICAgICAgIHRoaXMuYXBwbHlTdHlsZShzdHlsZU5hbWUsIGNyb3NoYWlyRG9tKTsgLy8g6K6+572u5Yid5aeL5qC35byPXG4gICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoY3Jvc2hhaXJEb20pOyAvLyDmt7vliqDliLDot58gdG9vbHRpcCDlkIznuqfnmoTnm67lvZXkuItcbiAgICAgICAgICAgIHRoaXMuc2V0KGRvbU5hbWUsIGNyb3NoYWlyRG9tKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3Jvc2hhaXJEb207XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZW5kZXJJdGVtcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jbGVhckl0ZW1Eb21zKCk7XG4gICAgICAgIHZhciBpdGVtcyA9IHRoaXMuZ2V0KCdpdGVtcycpO1xuICAgICAgICB2YXIgaXRlbVRwbCA9IHRoaXMuZ2V0KCdpdGVtVHBsJyk7XG4gICAgICAgIHZhciBsaXN0RG9tID0gdGhpcy5nZXQoJ2xpc3REb20nKTtcbiAgICAgICAgaWYgKGxpc3REb20pIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHZhciBjb2xvciA9IGNvbG9yX3V0aWxfMS5kZWZhdWx0LnRvQ1NTR3JhZGllbnQoaXRlbS5jb2xvcik7XG4gICAgICAgICAgICAgICAgdmFyIHN1YnN0aXR1dGVPYmogPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGl0ZW0pLCB7IGNvbG9yOiBjb2xvciB9KTtcbiAgICAgICAgICAgICAgICB2YXIgZG9tU3RyID0gdXRpbF8xLnN1YnN0aXR1dGUoaXRlbVRwbCwgc3Vic3RpdHV0ZU9iaik7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW1Eb20gPSBkb21fdXRpbF8xLmNyZWF0ZURvbShkb21TdHIpO1xuICAgICAgICAgICAgICAgIGxpc3REb20uYXBwZW5kQ2hpbGQoaXRlbURvbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlDaGlsZHJlblN0eWxlcyhsaXN0RG9tLCB0aGlzLmdldCgnZG9tU3R5bGVzJykpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5jbGVhckl0ZW1Eb21zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5nZXQoJ2xpc3REb20nKSkge1xuICAgICAgICAgICAgdXRpbF8yLmNsZWFyRG9tKHRoaXMuZ2V0KCdsaXN0RG9tJykpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5jbGVhckNyb3NzaGFpcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4Q3Jvc3NoYWlyRG9tID0gdGhpcy5nZXQoJ3hDcm9zc2hhaXJEb20nKTtcbiAgICAgICAgdmFyIHlDcm9zc2hhaXJEb20gPSB0aGlzLmdldCgneUNyb3NzaGFpckRvbScpO1xuICAgICAgICB4Q3Jvc3NoYWlyRG9tICYmIHhDcm9zc2hhaXJEb20ucmVtb3ZlKCk7XG4gICAgICAgIHlDcm9zc2hhaXJEb20gJiYgeUNyb3NzaGFpckRvbS5yZW1vdmUoKTtcbiAgICAgICAgdGhpcy5zZXQoJ3hDcm9zc2hhaXJEb20nLCBudWxsKTtcbiAgICAgICAgdGhpcy5zZXQoJ3lDcm9zc2hhaXJEb20nLCBudWxsKTtcbiAgICB9O1xuICAgIHJldHVybiBUb29sdGlwO1xufShodG1sX2NvbXBvbmVudF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRvb2x0aXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1odG1sLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGh0bWxfMSA9IHJlcXVpcmUoXCIuL2h0bWxcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJIdG1sXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBodG1sXzEuZGVmYXVsdDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5BUkVBX1NUWUxFID0gZXhwb3J0cy5MSU5FX1NUWUxFID0gZXhwb3J0cy5CQUNLR1JPVU5EX1NUWUxFID0gdm9pZCAwO1xuZXhwb3J0cy5CQUNLR1JPVU5EX1NUWUxFID0ge1xuICAgIC8vIGZpbGw6ICdyZWQnLFxuICAgIG9wYWNpdHk6IDAsXG59O1xuZXhwb3J0cy5MSU5FX1NUWUxFID0ge1xuICAgIHN0cm9rZTogJyNDNUM1QzUnLFxuICAgIHN0cm9rZU9wYWNpdHk6IDAuODUsXG59O1xuZXhwb3J0cy5BUkVBX1NUWUxFID0ge1xuICAgIGZpbGw6ICcjQ0FDRUQ0JyxcbiAgICBvcGFjaXR5OiAwLjg1LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5saW5lUGF0aFRvQXJlYVBhdGggPSBleHBvcnRzLmRhdGFUb1BhdGggPSBleHBvcnRzLmdldFNtb290aExpbmVQYXRoID0gZXhwb3J0cy5nZXRMaW5lUGF0aCA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHBhdGhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3BhdGgtdXRpbFwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIkBhbnR2L3NjYWxlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiDngrnmlbDnu4TovawgcGF0aFxuICogQHBhcmFtIHBvaW50c1xuICovXG5mdW5jdGlvbiBwb2ludHNUb1BhdGgocG9pbnRzKSB7XG4gICAgcmV0dXJuIHV0aWxfMS5tYXAocG9pbnRzLCBmdW5jdGlvbiAocCwgaWR4KSB7XG4gICAgICAgIHZhciBjb21tYW5kID0gaWR4ID09PSAwID8gJ00nIDogJ0wnO1xuICAgICAgICB2YXIgeCA9IHBbMF0sIHkgPSBwWzFdO1xuICAgICAgICByZXR1cm4gW2NvbW1hbmQsIHgsIHldO1xuICAgIH0pO1xufVxuLyoqXG4gKiDlsIbngrnov57mjqXmiJDot6/lvoQgcGF0aFxuICogQHBhcmFtIHBvaW50c1xuICovXG5mdW5jdGlvbiBnZXRMaW5lUGF0aChwb2ludHMpIHtcbiAgICByZXR1cm4gcG9pbnRzVG9QYXRoKHBvaW50cyk7XG59XG5leHBvcnRzLmdldExpbmVQYXRoID0gZ2V0TGluZVBhdGg7XG4vKipcbiAqIOWwhueCuei/nuaIkOW5s+a7keeahOabsue6v1xuICogQHBhcmFtIHBvaW50c1xuICovXG5mdW5jdGlvbiBnZXRTbW9vdGhMaW5lUGF0aChwb2ludHMpIHtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgIC8vIOS4pOeCueS7peWGheebtOaOpee7mOWItuaIkOi3r+W+hFxuICAgICAgICByZXR1cm4gZ2V0TGluZVBhdGgocG9pbnRzKTtcbiAgICB9XG4gICAgdmFyIGRhdGEgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgIC8vIOW9k+WJjeeCueWSjOS4iuS4gOS4queCueS4gOagt+eahOaXtuWAme+8jOW/veeVpeaOiVxuICAgICAgICBpZiAoIXV0aWxfMS5pc0VxdWFsKHAsIGRhdGEuc2xpY2UoZGF0YS5sZW5ndGggLSAyKSkpIHtcbiAgICAgICAgICAgIGRhdGEucHVzaChwWzBdLCBwWzFdKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIC8vIGNvbnN0IGNvbnN0cmFpbnQgPSBbIC8vIOiMg+WbtFxuICAgIC8vICAgWyAwLCAwIF0sXG4gICAgLy8gICBbIDEsIDEgXSxcbiAgICAvLyBdO1xuICAgIHZhciBwYXRoID0gcGF0aF91dGlsXzEuY2F0bXVsbFJvbTJCZXppZXIoZGF0YSwgZmFsc2UpO1xuICAgIHZhciBfYSA9IHV0aWxfMS5oZWFkKHBvaW50cyksIHggPSBfYVswXSwgeSA9IF9hWzFdO1xuICAgIHBhdGgudW5zaGlmdChbJ00nLCB4LCB5XSk7XG4gICAgcmV0dXJuIHBhdGg7XG59XG5leHBvcnRzLmdldFNtb290aExpbmVQYXRoID0gZ2V0U21vb3RoTGluZVBhdGg7XG4vKipcbiAqIOWwhuaVsOaNrui9rOaIkCBwYXRo77yM5Yip55SoIHNjYWxlIOeahOW9kuS4gOWMluiDveWKm1xuICogQHBhcmFtIGRhdGFcbiAqIEBwYXJhbSB3aWR0aFxuICogQHBhcmFtIGhlaWdodFxuICogQHBhcmFtIHNtb290aFxuICovXG5mdW5jdGlvbiBkYXRhVG9QYXRoKGRhdGEsIHdpZHRoLCBoZWlnaHQsIHNtb290aCkge1xuICAgIGlmIChzbW9vdGggPT09IHZvaWQgMCkgeyBzbW9vdGggPSB0cnVlOyB9XG4gICAgLy8g5Yip55SoIHNjYWxlIOadpeiOt+WPliB5IOS4iueahOaYoOWwhFxuICAgIHZhciB5ID0gbmV3IHNjYWxlXzEuTGluZWFyKHtcbiAgICAgICAgdmFsdWVzOiBkYXRhLFxuICAgIH0pO1xuICAgIHZhciB4ID0gbmV3IHNjYWxlXzEuQ2F0ZWdvcnkoe1xuICAgICAgICB2YWx1ZXM6IHV0aWxfMS5tYXAoZGF0YSwgZnVuY3Rpb24gKHYsIGlkeCkgeyByZXR1cm4gaWR4OyB9KSxcbiAgICB9KTtcbiAgICB2YXIgcG9pbnRzID0gdXRpbF8xLm1hcChkYXRhLCBmdW5jdGlvbiAodiwgaWR4KSB7XG4gICAgICAgIHJldHVybiBbeC5zY2FsZShpZHgpICogd2lkdGgsIGhlaWdodCAtIHkuc2NhbGUodikgKiBoZWlnaHRdO1xuICAgIH0pO1xuICAgIHJldHVybiBzbW9vdGggPyBnZXRTbW9vdGhMaW5lUGF0aChwb2ludHMpIDogZ2V0TGluZVBhdGgocG9pbnRzKTtcbn1cbmV4cG9ydHMuZGF0YVRvUGF0aCA9IGRhdGFUb1BhdGg7XG4vKipcbiAqIOe6vyBwYXRoIOi9rCBhcmVhIHBhdGhcbiAqIEBwYXJhbSBwYXRoXG4gKiBAcGFyYW0gd2lkdGhcbiAqIEBwYXJhbSBoZWlnaHRcbiAqL1xuZnVuY3Rpb24gbGluZVBhdGhUb0FyZWFQYXRoKHBhdGgsIHdpZHRoLCBoZWlnaHQpIHtcbiAgICB2YXIgYXJlYVBhdGggPSB0c2xpYl8xLl9fc3ByZWFkQXJyYXlzKHBhdGgpO1xuICAgIGFyZWFQYXRoLnB1c2goWydMJywgd2lkdGgsIDBdKTtcbiAgICBhcmVhUGF0aC5wdXNoKFsnTCcsIDAsIGhlaWdodF0pO1xuICAgIGFyZWFQYXRoLnB1c2goWydaJ10pO1xuICAgIHJldHVybiBhcmVhUGF0aDtcbn1cbmV4cG9ydHMubGluZVBhdGhUb0FyZWFQYXRoID0gbGluZVBhdGhUb0FyZWFQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuVHJlbmQgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBncm91cF9jb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuLi9hYnN0cmFjdC9ncm91cC1jb21wb25lbnRcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50XCIpO1xudmFyIHBhdGhfMSA9IHJlcXVpcmUoXCIuL3BhdGhcIik7XG52YXIgVHJlbmQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVHJlbmQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVHJlbmQoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgVHJlbmQucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBuYW1lOiAndHJlbmQnLCB4OiAwLCB5OiAwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDE2LCBzbW9vdGg6IHRydWUsIGlzQXJlYTogZmFsc2UsIGRhdGE6IFtdLCBiYWNrZ3JvdW5kU3R5bGU6IGNvbnN0YW50XzEuQkFDS0dST1VORF9TVFlMRSwgbGluZVN0eWxlOiBjb25zdGFudF8xLkxJTkVfU1RZTEUsIGFyZWFTdHlsZTogY29uc3RhbnRfMS5BUkVBX1NUWUxFIH0pO1xuICAgIH07XG4gICAgVHJlbmQucHJvdG90eXBlLnJlbmRlcklubmVyID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQsIGRhdGEgPSBfYS5kYXRhLCBzbW9vdGggPSBfYS5zbW9vdGgsIGlzQXJlYSA9IF9hLmlzQXJlYSwgYmFja2dyb3VuZFN0eWxlID0gX2EuYmFja2dyb3VuZFN0eWxlLCBsaW5lU3R5bGUgPSBfYS5saW5lU3R5bGUsIGFyZWFTdHlsZSA9IF9hLmFyZWFTdHlsZTtcbiAgICAgICAgLy8g6IOM5pmvXG4gICAgICAgIHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnYmFja2dyb3VuZCcpLFxuICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB4OiAwLCB5OiAwLCB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQgfSwgYmFja2dyb3VuZFN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBwYXRoID0gcGF0aF8xLmRhdGFUb1BhdGgoZGF0YSwgd2lkdGgsIGhlaWdodCwgc21vb3RoKTtcbiAgICAgICAgLy8g57q/XG4gICAgICAgIHRoaXMuYWRkU2hhcGUoZ3JvdXAsIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnbGluZScpLFxuICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBwYXRoOiBwYXRoIH0sIGxpbmVTdHlsZSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBhcmVhXG4gICAgICAgIC8vIOWcqCBwYXRoIOeahOWfuuehgOS4iu+8jOWinuWKoOS4pOS4quWdkOagh+eCuVxuICAgICAgICBpZiAoaXNBcmVhKSB7XG4gICAgICAgICAgICB2YXIgYXJlYVBhdGggPSBwYXRoXzEubGluZVBhdGhUb0FyZWFQYXRoKHBhdGgsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICAgICAgdGhpcy5hZGRTaGFwZShncm91cCwge1xuICAgICAgICAgICAgICAgIGlkOiB0aGlzLmdldEVsZW1lbnRJZCgnYXJlYScpLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IGFyZWFQYXRoIH0sIGFyZWFTdHlsZSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVHJlbmQucHJvdG90eXBlLmFwcGx5T2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmNmZywgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgICAgICAvLyDnu5/kuIDnp7vliqjliLDlr7nlupTnmoTkvY3nva5cbiAgICAgICAgdGhpcy5tb3ZlRWxlbWVudFRvKHRoaXMuZ2V0KCdncm91cCcpLCB7XG4gICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgeTogeSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gVHJlbmQ7XG59KGdyb3VwX2NvbXBvbmVudF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuVHJlbmQgPSBUcmVuZDtcbmV4cG9ydHMuZGVmYXVsdCA9IFRyZW5kO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dHJlbmQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldEFsaWduUG9pbnQgPSBleHBvcnRzLmdldFBvaW50QnlQb3NpdGlvbiA9IGV4cG9ydHMuZ2V0T3V0U2lkZXMgPSB2b2lkIDA7XG4vLyDmo4DmtYvlkITovrnmmK/lkKbotoXlh7pcbmZ1bmN0aW9uIGdldE91dFNpZGVzKHgsIHksIHdpZHRoLCBoZWlnaHQsIGxpbWl0Qm94KSB7XG4gICAgdmFyIGhpdHMgPSB7XG4gICAgICAgIGxlZnQ6IHggPCBsaW1pdEJveC54LFxuICAgICAgICByaWdodDogeCArIHdpZHRoID4gbGltaXRCb3gueCArIGxpbWl0Qm94LndpZHRoLFxuICAgICAgICB0b3A6IHkgPCBsaW1pdEJveC55LFxuICAgICAgICBib3R0b206IHkgKyBoZWlnaHQgPiBsaW1pdEJveC55ICsgbGltaXRCb3guaGVpZ2h0LFxuICAgIH07XG4gICAgcmV0dXJuIGhpdHM7XG59XG5leHBvcnRzLmdldE91dFNpZGVzID0gZ2V0T3V0U2lkZXM7XG5mdW5jdGlvbiBnZXRQb2ludEJ5UG9zaXRpb24oeCwgeSwgb2Zmc2V0LCB3aWR0aCwgaGVpZ2h0LCBwb3NpdGlvbikge1xuICAgIHZhciBweCA9IHg7XG4gICAgdmFyIHB5ID0geTtcbiAgICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgICAgIGNhc2UgJ2xlZnQnOiAvLyBsZWZ0IGNlbnRlclxuICAgICAgICAgICAgcHggPSB4IC0gd2lkdGggLSBvZmZzZXQ7XG4gICAgICAgICAgICBweSA9IHkgLSBoZWlnaHQgLyAyO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICAgIHB4ID0geCArIG9mZnNldDtcbiAgICAgICAgICAgIHB5ID0geSAtIGhlaWdodCAvIDI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICAgIHB4ID0geCAtIHdpZHRoIC8gMjtcbiAgICAgICAgICAgIHB5ID0geSAtIGhlaWdodCAtIG9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAgLy8gYm90dG9tXG4gICAgICAgICAgICBweCA9IHggLSB3aWR0aCAvIDI7XG4gICAgICAgICAgICBweSA9IHkgKyBvZmZzZXQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIC8vIGF1dG8sIOWcqCB0b3AtcmlnaHRcbiAgICAgICAgICAgIHB4ID0geCArIG9mZnNldDtcbiAgICAgICAgICAgIHB5ID0geSAtIGhlaWdodCAtIG9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBweCxcbiAgICAgICAgeTogcHksXG4gICAgfTtcbn1cbmV4cG9ydHMuZ2V0UG9pbnRCeVBvc2l0aW9uID0gZ2V0UG9pbnRCeVBvc2l0aW9uO1xuZnVuY3Rpb24gZ2V0QWxpZ25Qb2ludCh4LCB5LCBvZmZzZXQsIHdpZHRoLCBoZWlnaHQsIHBvc2l0aW9uLCBsaW1pdEJveCkge1xuICAgIHZhciBwb2ludCA9IGdldFBvaW50QnlQb3NpdGlvbih4LCB5LCBvZmZzZXQsIHdpZHRoLCBoZWlnaHQsIHBvc2l0aW9uKTtcbiAgICBpZiAobGltaXRCb3gpIHtcbiAgICAgICAgdmFyIG91dFNpZGVzID0gZ2V0T3V0U2lkZXMocG9pbnQueCwgcG9pbnQueSwgd2lkdGgsIGhlaWdodCwgbGltaXRCb3gpO1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICdhdXRvJykge1xuICAgICAgICAgICAgLy8g5aaC5p6c5pivIGF1dG/vvIzpu5jorqQgdG9vbHRpcCDlnKjlj7PkuIrop5LvvIzku4XpnIDopoHliKTlrprlj7PkvqflkozkuIrmtYvlhrLnqoHljbPlj69cbiAgICAgICAgICAgIGlmIChvdXRTaWRlcy5yaWdodCkge1xuICAgICAgICAgICAgICAgIHBvaW50LnggPSBNYXRoLm1heCgwLCB4IC0gd2lkdGggLSBvZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG91dFNpZGVzLnRvcCkge1xuICAgICAgICAgICAgICAgIHBvaW50LnkgPSBNYXRoLm1heCgwLCB5IC0gaGVpZ2h0IC0gb2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICBpZiAob3V0U2lkZXMubGVmdCkge1xuICAgICAgICAgICAgICAgIC8vIOW3puS+p+i6sumBv1xuICAgICAgICAgICAgICAgIHBvaW50LnggPSBsaW1pdEJveC54O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG91dFNpZGVzLnJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgLy8g5Y+z5L6n6Lqy6YG/XG4gICAgICAgICAgICAgICAgcG9pbnQueCA9IGxpbWl0Qm94LnggKyBsaW1pdEJveC53aWR0aCAtIHdpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSAndG9wJyAmJiBvdXRTaWRlcy50b3ApIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzkuIrpnaLlr7npvZDmo4DmtYvkuIrpnaLvvIzkuI3mo4DmtYvkuIvpnaJcbiAgICAgICAgICAgICAgICBwb2ludC55ID0geSArIG9mZnNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ2JvdHRvbScgJiYgb3V0U2lkZXMuYm90dG9tKSB7XG4gICAgICAgICAgICAgICAgcG9pbnQueSA9IHkgLSBoZWlnaHQgLSBvZmZzZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDmo4DmtYvlt6blj7PkvY3nva5cbiAgICAgICAgICAgIGlmIChvdXRTaWRlcy50b3ApIHtcbiAgICAgICAgICAgICAgICBwb2ludC55ID0gbGltaXRCb3gueTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvdXRTaWRlcy5ib3R0b20pIHtcbiAgICAgICAgICAgICAgICBwb2ludC55ID0gbGltaXRCb3gueSArIGxpbWl0Qm94LmhlaWdodCAtIGhlaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnICYmIG91dFNpZGVzLmxlZnQpIHtcbiAgICAgICAgICAgICAgICBwb2ludC54ID0geCArIG9mZnNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0JyAmJiBvdXRTaWRlcy5yaWdodCkge1xuICAgICAgICAgICAgICAgIHBvaW50LnggPSB4IC0gd2lkdGggLSBvZmZzZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBvaW50O1xufVxuZXhwb3J0cy5nZXRBbGlnblBvaW50ID0gZ2V0QWxpZ25Qb2ludDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFsaWduLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5wcm9wYWdhdGlvbkRlbGVnYXRlID0gdm9pZCAwO1xudmFyIGdyYXBoX2V2ZW50XzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlL2xpYi9ldmVudC9ncmFwaC1ldmVudFwiKTtcbi8qKlxuICpcbiAqIEBwYXJhbSBncm91cCDliIbnu4RcbiAqIEBwYXJhbSBldmVudE5hbWUg5LqL5Lu25ZCNXG4gKiBAcGFyYW0gZXZlbnRPYmplY3Qg5LqL5Lu25a+56LGhXG4gKi9cbmZ1bmN0aW9uIHByb3BhZ2F0aW9uRGVsZWdhdGUoZ3JvdXAsIGV2ZW50TmFtZSwgZXZlbnRPYmplY3QpIHtcbiAgICB2YXIgZXZlbnQgPSBuZXcgZ3JhcGhfZXZlbnRfMS5kZWZhdWx0KGV2ZW50TmFtZSwgZXZlbnRPYmplY3QpO1xuICAgIGV2ZW50LnRhcmdldCA9IGdyb3VwO1xuICAgIGV2ZW50LnByb3BhZ2F0aW9uUGF0aC5wdXNoKGdyb3VwKTsgLy8g5LuO5b2T5YmNIGdyb3VwIOW8gOWni+inpuWPkSBkZWxlZ2F0aW9uXG4gICAgZ3JvdXAuZW1pdERlbGVnYXRpb24oZXZlbnROYW1lLCBldmVudCk7XG4gICAgdmFyIHBhcmVudCA9IGdyb3VwLmdldFBhcmVudCgpO1xuICAgIC8vIOaJp+ihjOWGkuazoVxuICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgICAgLy8g5aeU5omY5LqL5Lu26KaB5YWI6Kem5Y+RXG4gICAgICAgIHBhcmVudC5lbWl0RGVsZWdhdGlvbihldmVudE5hbWUsIGV2ZW50KTtcbiAgICAgICAgZXZlbnQucHJvcGFnYXRpb25QYXRoLnB1c2gocGFyZW50KTtcbiAgICAgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudCgpO1xuICAgIH1cbn1cbmV4cG9ydHMucHJvcGFnYXRpb25EZWxlZ2F0ZSA9IHByb3BhZ2F0aW9uRGVsZWdhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucmVuZGVyVGFnID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2xhYmVsXCIpO1xudmFyIG1hdHJpeF8xID0gcmVxdWlyZShcIi4vbWF0cml4XCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG5mdW5jdGlvbiByZW5kZXJUYWcoY29udGFpbmVyLCB0YWdDZmcpIHtcbiAgICB2YXIgeCA9IHRhZ0NmZy54LCB5ID0gdGFnQ2ZnLnksIGNvbnRlbnQgPSB0YWdDZmcuY29udGVudCwgc3R5bGUgPSB0YWdDZmcuc3R5bGUsIGlkID0gdGFnQ2ZnLmlkLCBuYW1lID0gdGFnQ2ZnLm5hbWUsIHJvdGF0ZSA9IHRhZ0NmZy5yb3RhdGUsIG1heExlbmd0aCA9IHRhZ0NmZy5tYXhMZW5ndGgsIGF1dG9FbGxpcHNpcyA9IHRhZ0NmZy5hdXRvRWxsaXBzaXMsIGlzVmVydGljYWwgPSB0YWdDZmcuaXNWZXJ0aWNhbCwgZWxsaXBzaXNQb3NpdGlvbiA9IHRhZ0NmZy5lbGxpcHNpc1Bvc2l0aW9uLCBiYWNrZ3JvdW5kID0gdGFnQ2ZnLmJhY2tncm91bmQ7XG4gICAgdmFyIHRhZ0dyb3VwID0gY29udGFpbmVyLmFkZEdyb3VwKHtcbiAgICAgICAgaWQ6IGlkICsgXCItZ3JvdXBcIixcbiAgICAgICAgbmFtZTogbmFtZSArIFwiLWdyb3VwXCIsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgeTogeSxcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIC8vIFRleHQgc2hhcGVcbiAgICB2YXIgdGV4dCA9IHRhZ0dyb3VwLmFkZFNoYXBlKHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICBpZDogaWQsXG4gICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogMCwgeTogMCwgdGV4dDogY29udGVudCB9LCBzdHlsZSksXG4gICAgfSk7XG4gICAgLy8gbWF4TGVuZ3RoIOW6lOWMheWQqyBiYWNrZ3JvdW5kIOS4reeahCBwYWRkaW5nIOWAvFxuICAgIHZhciBwYWRkaW5nID0gdXRpbF8yLmZvcm1hdFBhZGRpbmcodXRpbF8xLmdldChiYWNrZ3JvdW5kLCAncGFkZGluZycsIDApKTtcbiAgICBpZiAobWF4TGVuZ3RoICYmIGF1dG9FbGxpcHNpcykge1xuICAgICAgICB2YXIgbWF4VGV4dExlbmd0aCA9IG1heExlbmd0aCAtIChwYWRkaW5nWzFdICsgcGFkZGluZ1szXSk7XG4gICAgICAgIC8vIOi2heWHuuiHquWKqOecgeeVpVxuICAgICAgICBsYWJlbF8xLmVsbGlwc2lzTGFiZWwoIWlzVmVydGljYWwsIHRleHQsIG1heFRleHRMZW5ndGgsIGVsbGlwc2lzUG9zaXRpb24pO1xuICAgIH1cbiAgICBpZiAoYmFja2dyb3VuZCkge1xuICAgICAgICAvLyDmuLLmn5PmlofmnKzog4zmma9cbiAgICAgICAgdmFyIGJhY2tncm91bmRTdHlsZSA9IHV0aWxfMS5nZXQoYmFja2dyb3VuZCwgJ3N0eWxlJywge30pO1xuICAgICAgICB2YXIgX2EgPSB0ZXh0LmdldENhbnZhc0JCb3goKSwgbWluWCA9IF9hLm1pblgsIG1pblkgPSBfYS5taW5ZLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgIHZhciB0YWdCZyA9IHRhZ0dyb3VwLmFkZFNoYXBlKCdyZWN0Jywge1xuICAgICAgICAgICAgaWQ6IGlkICsgXCItYmdcIixcbiAgICAgICAgICAgIG5hbWU6IGlkICsgXCItYmdcIixcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogbWluWCAtIHBhZGRpbmdbM10sIHk6IG1pblkgLSBwYWRkaW5nWzBdLCB3aWR0aDogd2lkdGggKyBwYWRkaW5nWzFdICsgcGFkZGluZ1szXSwgaGVpZ2h0OiBoZWlnaHQgKyBwYWRkaW5nWzBdICsgcGFkZGluZ1syXSB9LCBiYWNrZ3JvdW5kU3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGFnQmcudG9CYWNrKCk7XG4gICAgfVxuICAgIG1hdHJpeF8xLmFwcGx5VHJhbnNsYXRlKHRhZ0dyb3VwLCB4LCB5KTtcbiAgICBtYXRyaXhfMS5hcHBseVJvdGF0ZSh0YWdHcm91cCwgcm90YXRlLCB4LCB5KTtcbn1cbmV4cG9ydHMucmVuZGVyVGFnID0gcmVuZGVyVGFnO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z3JhcGhpYy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZWxsaXBzaXNMYWJlbCA9IGV4cG9ydHMudGVzdExhYmVsID0gZXhwb3J0cy5nZXRMYWJlbExlbmd0aCA9IGV4cG9ydHMuZ2V0TWF4TGFiZWxXaWR0aCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB0ZXh0XzEgPSByZXF1aXJlKFwiLi90ZXh0XCIpO1xudmFyIEVMTElQU0lTX0NPREUgPSAnXFx1MjAyNic7XG52YXIgRUxMSVBTSVNfQ09ERV9MRU5HVEggPSAyOyAvLyDnnIHnlaXlj7fnmoTplb/luqZcbi8qKiDojrflj5bmnIDplb/nmoQgbGFiZWwgKi9cbmZ1bmN0aW9uIGdldE1heExhYmVsV2lkdGgobGFiZWxzKSB7XG4gICAgdmFyIG1heCA9IDA7XG4gICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgdmFyIGJib3ggPSBsYWJlbC5nZXRCQm94KCk7XG4gICAgICAgIHZhciB3aWR0aCA9IGJib3gud2lkdGg7XG4gICAgICAgIGlmIChtYXggPCB3aWR0aCkge1xuICAgICAgICAgICAgbWF4ID0gd2lkdGg7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbWF4O1xufVxuZXhwb3J0cy5nZXRNYXhMYWJlbFdpZHRoID0gZ2V0TWF4TGFiZWxXaWR0aDtcbi8qKiDojrflj5ZsYWJlbOmVv+W6piAqL1xuZnVuY3Rpb24gZ2V0TGFiZWxMZW5ndGgoaXNWZXJ0aWNhbCwgbGFiZWwpIHtcbiAgICB2YXIgYmJveCA9IGxhYmVsLmdldENhbnZhc0JCb3goKTtcbiAgICByZXR1cm4gaXNWZXJ0aWNhbCA/IGJib3gud2lkdGggOiBiYm94LmhlaWdodDtcbn1cbmV4cG9ydHMuZ2V0TGFiZWxMZW5ndGggPSBnZXRMYWJlbExlbmd0aDtcbi8qIGxhYmVs6ZW/5bqm5piv5ZCm6LaF6L+H57qm5p2f5YC8ICovXG5mdW5jdGlvbiB0ZXN0TGFiZWwobGFiZWwsIGxpbWl0TGVuZ3RoKSB7XG4gICAgcmV0dXJuIGxhYmVsLmdldEJCb3goKS53aWR0aCA8IGxpbWl0TGVuZ3RoO1xufVxuZXhwb3J0cy50ZXN0TGFiZWwgPSB0ZXN0TGFiZWw7XG4vKiog5aSE55CGIHRleHQgc2hhcGUg55qE6Ieq5Yqo55yB55WlICovXG5mdW5jdGlvbiBlbGxpcHNpc0xhYmVsKGlzVmVydGljYWwsIGxhYmVsLCBsaW1pdExlbmd0aCwgcG9zaXRpb24pIHtcbiAgICBpZiAocG9zaXRpb24gPT09IHZvaWQgMCkgeyBwb3NpdGlvbiA9ICd0YWlsJzsgfVxuICAgIHZhciB0ZXh0ID0gbGFiZWwuYXR0cigndGV4dCcpO1xuICAgIHZhciBsYWJlbExlbmd0aCA9IGdldExhYmVsTGVuZ3RoKGlzVmVydGljYWwsIGxhYmVsKTtcbiAgICB2YXIgY29kZUxlbmd0aCA9IHRleHRfMS5zdHJMZW4odGV4dCk7XG4gICAgdmFyIGVsbGlwc2lzZWQgPSBmYWxzZTtcbiAgICBpZiAobGltaXRMZW5ndGggPCBsYWJlbExlbmd0aCkge1xuICAgICAgICB2YXIgcmVzZXZlTGVuZ3RoID0gTWF0aC5mbG9vcigobGltaXRMZW5ndGggLyBsYWJlbExlbmd0aCkgKiBjb2RlTGVuZ3RoKSAtIEVMTElQU0lTX0NPREVfTEVOR1RIOyAvLyDorqHnrpflh7rmnaXnmoTlupTor6Xkv53lrZjnmoTplb/luqZcbiAgICAgICAgdmFyIG5ld1RleHQgPSB2b2lkIDA7XG4gICAgICAgIGlmIChyZXNldmVMZW5ndGggPj0gMCkge1xuICAgICAgICAgICAgbmV3VGV4dCA9IHRleHRfMS5lbGxpcHNpc1N0cmluZyh0ZXh0LCByZXNldmVMZW5ndGgsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5ld1RleHQgPSBFTExJUFNJU19DT0RFO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuZXdUZXh0KSB7XG4gICAgICAgICAgICBsYWJlbC5hdHRyKCd0ZXh0JywgbmV3VGV4dCk7XG4gICAgICAgICAgICBlbGxpcHNpc2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZWxsaXBzaXNlZCkge1xuICAgICAgICBsYWJlbC5zZXQoJ3RpcCcsIHRleHQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGFiZWwuc2V0KCd0aXAnLCBudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIGVsbGlwc2lzZWQ7XG59XG5leHBvcnRzLmVsbGlwc2lzTGFiZWwgPSBlbGxpcHNpc0xhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmFwcGx5VHJhbnNsYXRlID0gZXhwb3J0cy5hcHBseVJvdGF0ZSA9IGV4cG9ydHMuYXBwbHlNYXRyaXgyQkJveCA9IGV4cG9ydHMuZ2V0QW5nbGVCeU1hdHJpeCA9IGV4cG9ydHMuZ2V0TWF0cml4QnlUcmFuc2xhdGUgPSBleHBvcnRzLmdldE1hdHJpeEJ5QW5nbGUgPSB2b2lkIDA7XG52YXIgbWF0cml4X3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9tYXRyaXgtdXRpbFwiKTtcbnZhciBpZGVudGl0eU1hdHJpeCA9IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbmZ1bmN0aW9uIGdldE1hdHJpeEJ5QW5nbGUocG9pbnQsIGFuZ2xlLCBtYXRyaXgpIHtcbiAgICBpZiAobWF0cml4ID09PSB2b2lkIDApIHsgbWF0cml4ID0gaWRlbnRpdHlNYXRyaXg7IH1cbiAgICBpZiAoIWFuZ2xlKSB7XG4gICAgICAgIC8vIOinkuW6puS4uiAwIOaIluiAhSBudWxsIOaXtui/lOWbniBudWxsXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbSA9IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShtYXRyaXgsIFtcbiAgICAgICAgWyd0JywgLXBvaW50LngsIC1wb2ludC55XSxcbiAgICAgICAgWydyJywgYW5nbGVdLFxuICAgICAgICBbJ3QnLCBwb2ludC54LCBwb2ludC55XSxcbiAgICBdKTtcbiAgICByZXR1cm4gbTtcbn1cbmV4cG9ydHMuZ2V0TWF0cml4QnlBbmdsZSA9IGdldE1hdHJpeEJ5QW5nbGU7XG5mdW5jdGlvbiBnZXRNYXRyaXhCeVRyYW5zbGF0ZShwb2ludCwgY3VycmVudE1hdHJpeCkge1xuICAgIGlmICghcG9pbnQueCAmJiAhcG9pbnQueSkge1xuICAgICAgICAvLyAw77yMMCDmiJbogIUgbmFuIOeahOaDheWGteS4i+i/lOWbniBudWxsXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKGN1cnJlbnRNYXRyaXggfHwgaWRlbnRpdHlNYXRyaXgsIFtbJ3QnLCBwb2ludC54LCBwb2ludC55XV0pO1xufVxuZXhwb3J0cy5nZXRNYXRyaXhCeVRyYW5zbGF0ZSA9IGdldE1hdHJpeEJ5VHJhbnNsYXRlO1xuLy8g5LuO55+p6Zi16I635Y+W5peL6L2s55qE6KeS5bqmXG5mdW5jdGlvbiBnZXRBbmdsZUJ5TWF0cml4KG1hdHJpeCkge1xuICAgIHZhciB4VmVjdG9yID0gWzEsIDAsIDBdO1xuICAgIHZhciBvdXQgPSBbMCwgMCwgMF07XG4gICAgbWF0cml4X3V0aWxfMS52ZWMzLnRyYW5zZm9ybU1hdDMob3V0LCB4VmVjdG9yLCBtYXRyaXgpO1xuICAgIHJldHVybiBNYXRoLmF0YW4yKG91dFsxXSwgb3V0WzBdKTtcbn1cbmV4cG9ydHMuZ2V0QW5nbGVCeU1hdHJpeCA9IGdldEFuZ2xlQnlNYXRyaXg7XG4vLyDnn6npmLUgKiDlkJHph49cbmZ1bmN0aW9uIG11bHRpcGx5VmVjMihtYXRyaXgsIHYpIHtcbiAgICB2YXIgb3V0ID0gWzAsIDBdO1xuICAgIG1hdHJpeF91dGlsXzEudmVjMi50cmFuc2Zvcm1NYXQzKG91dCwgdiwgbWF0cml4KTtcbiAgICByZXR1cm4gb3V0O1xufVxuZnVuY3Rpb24gYXBwbHlNYXRyaXgyQkJveChtYXRyaXgsIGJib3gpIHtcbiAgICB2YXIgdG9wTGVmdCA9IG11bHRpcGx5VmVjMihtYXRyaXgsIFtiYm94Lm1pblgsIGJib3gubWluWV0pO1xuICAgIHZhciB0b3BSaWdodCA9IG11bHRpcGx5VmVjMihtYXRyaXgsIFtiYm94Lm1heFgsIGJib3gubWluWV0pO1xuICAgIHZhciBib3R0b21MZWZ0ID0gbXVsdGlwbHlWZWMyKG1hdHJpeCwgW2Jib3gubWluWCwgYmJveC5tYXhZXSk7XG4gICAgdmFyIGJvdHRvbVJpZ2h0ID0gbXVsdGlwbHlWZWMyKG1hdHJpeCwgW2Jib3gubWF4WCwgYmJveC5tYXhZXSk7XG4gICAgdmFyIG1pblggPSBNYXRoLm1pbih0b3BMZWZ0WzBdLCB0b3BSaWdodFswXSwgYm90dG9tTGVmdFswXSwgYm90dG9tUmlnaHRbMF0pO1xuICAgIHZhciBtYXhYID0gTWF0aC5tYXgodG9wTGVmdFswXSwgdG9wUmlnaHRbMF0sIGJvdHRvbUxlZnRbMF0sIGJvdHRvbVJpZ2h0WzBdKTtcbiAgICB2YXIgbWluWSA9IE1hdGgubWluKHRvcExlZnRbMV0sIHRvcFJpZ2h0WzFdLCBib3R0b21MZWZ0WzFdLCBib3R0b21SaWdodFsxXSk7XG4gICAgdmFyIG1heFkgPSBNYXRoLm1heCh0b3BMZWZ0WzFdLCB0b3BSaWdodFsxXSwgYm90dG9tTGVmdFsxXSwgYm90dG9tUmlnaHRbMV0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IG1pblgsXG4gICAgICAgIHk6IG1pblksXG4gICAgICAgIG1pblg6IG1pblgsXG4gICAgICAgIG1pblk6IG1pblksXG4gICAgICAgIG1heFg6IG1heFgsXG4gICAgICAgIG1heFk6IG1heFksXG4gICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICB9O1xufVxuZXhwb3J0cy5hcHBseU1hdHJpeDJCQm94ID0gYXBwbHlNYXRyaXgyQkJveDtcbmZ1bmN0aW9uIGFwcGx5Um90YXRlKHNoYXBlLCByb3RhdGUsIHgsIHkpIHtcbiAgICBpZiAocm90YXRlKSB7XG4gICAgICAgIHZhciBtYXRyaXggPSBnZXRNYXRyaXhCeUFuZ2xlKHsgeDogeCwgeTogeSB9LCByb3RhdGUsIHNoYXBlLmdldE1hdHJpeCgpKTtcbiAgICAgICAgc2hhcGUuc2V0TWF0cml4KG1hdHJpeCk7XG4gICAgfVxufVxuZXhwb3J0cy5hcHBseVJvdGF0ZSA9IGFwcGx5Um90YXRlO1xuZnVuY3Rpb24gYXBwbHlUcmFuc2xhdGUoc2hhcGUsIHgsIHkpIHtcbiAgICB2YXIgdHJhbnNsYXRlTWF0cml4ID0gZ2V0TWF0cml4QnlUcmFuc2xhdGUoeyB4OiB4LCB5OiB5IH0pO1xuICAgIHNoYXBlLmF0dHIoJ21hdHJpeCcsIHRyYW5zbGF0ZU1hdHJpeCk7XG59XG5leHBvcnRzLmFwcGx5VHJhbnNsYXRlID0gYXBwbHlUcmFuc2xhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXRyaXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFN0YXRlc1N0eWxlID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLy8g6I635Y+W5aSa5Liq54q25oCB6YeP55qE5ZCI5bm25YC8XG5mdW5jdGlvbiBnZXRTdGF0ZXNTdHlsZShpdGVtLCBlbGVtZW50TmFtZSwgc3RhdGVTdHlsZXMpIHtcbiAgICB2YXIgc3R5bGVOYW1lID0gZWxlbWVudE5hbWUgKyBcIlN0eWxlXCI7IC8vIGFjdGl2ZVN0eWxlXG4gICAgdmFyIHN0eWxlcyA9IG51bGw7XG4gICAgdXRpbF8xLmVhY2goc3RhdGVTdHlsZXMsIGZ1bmN0aW9uICh2LCBzdGF0ZSkge1xuICAgICAgICBpZiAoaXRlbVtzdGF0ZV0gJiYgdltzdHlsZU5hbWVdKSB7XG4gICAgICAgICAgICBpZiAoIXN0eWxlcykge1xuICAgICAgICAgICAgICAgIHN0eWxlcyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXRpbF8xLm1peChzdHlsZXMsIHZbc3R5bGVOYW1lXSk7IC8vIOWQiOW5tuagt+W8j1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHN0eWxlcztcbn1cbmV4cG9ydHMuZ2V0U3RhdGVzU3R5bGUgPSBnZXRTdGF0ZXNTdHlsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5lbGxpcHNpc1N0cmluZyA9IGV4cG9ydHMuY2hhckF0TGVuZ3RoID0gZXhwb3J0cy5zdHJMZW4gPSB2b2lkIDA7XG52YXIgRUxMSVBTSVNfQ09ERSA9ICdcXHUyMDI2Jztcbi8qKiDojrflj5blrZfnrKbkuLLplb/luqYgKi9cbmZ1bmN0aW9uIHN0ckxlbihzdHIpIHtcbiAgICB2YXIgbGVuID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZW4gKz0gY2hhckF0TGVuZ3RoKHN0ciwgaSk7XG4gICAgfVxuICAgIHJldHVybiBsZW47XG59XG5leHBvcnRzLnN0ckxlbiA9IHN0ckxlbjtcbi8qKiDmmK/lkKblsZ7kuo5BU0NJSee8lueggeiMg+eVtCAqL1xuZnVuY3Rpb24gY2hhckF0TGVuZ3RoKHN0ciwgaSkge1xuICAgIGlmIChzdHIuY2hhckNvZGVBdChpKSA+IDAgJiYgc3RyLmNoYXJDb2RlQXQoaSkgPCAxMjgpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gMjtcbiAgICB9XG59XG5leHBvcnRzLmNoYXJBdExlbmd0aCA9IGNoYXJBdExlbmd0aDtcbi8qKiDmlofmnKznnIHnlaUgKi9cbmZ1bmN0aW9uIGVsbGlwc2lzU3RyaW5nKHN0ciwgcmVzZXZlTGVuZ3RoLCBwb3NpdGlvbikge1xuICAgIGlmIChwb3NpdGlvbiA9PT0gdm9pZCAwKSB7IHBvc2l0aW9uID0gJ3RhaWwnOyB9XG4gICAgdmFyIGNvdW50ID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgcnN0ID0gJyc7XG4gICAgaWYgKHBvc2l0aW9uID09PSAndGFpbCcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGluZGV4ID0gMDsgaSA8IHJlc2V2ZUxlbmd0aDspIHtcbiAgICAgICAgICAgIHZhciBjaGFyTGVuZ3RoID0gY2hhckF0TGVuZ3RoKHN0ciwgaW5kZXgpO1xuICAgICAgICAgICAgaWYgKGkgKyBjaGFyTGVuZ3RoIDw9IHJlc2V2ZUxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJzdCArPSBzdHJbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGkgKz0gY2hhckF0TGVuZ3RoKHN0ciwgaW5kZXgpO1xuICAgICAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByc3QgKz0gRUxMSVBTSVNfQ09ERTtcbiAgICB9XG4gICAgZWxzZSBpZiAocG9zaXRpb24gPT09ICdoZWFkJykge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgaW5kZXggPSBjb3VudCAtIDE7IGkgPCByZXNldmVMZW5ndGg7KSB7XG4gICAgICAgICAgICB2YXIgY2hhckxlbmd0aCA9IGNoYXJBdExlbmd0aChzdHIsIGluZGV4KTtcbiAgICAgICAgICAgIGlmIChpICsgY2hhckxlbmd0aCA8PSByZXNldmVMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByc3QgKz0gc3RyW2luZGV4XTtcbiAgICAgICAgICAgICAgICBpICs9IGNoYXJBdExlbmd0aChzdHIsIGluZGV4KTtcbiAgICAgICAgICAgICAgICBpbmRleC0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcnN0ID0gRUxMSVBTSVNfQ09ERSArIHJzdDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBzdGFydFN0ciA9ICcnO1xuICAgICAgICB2YXIgZW5kU3RyID0gJyc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBzdGFydEluZGV4ID0gMCwgZW5kSW5kZXggPSBjb3VudCAtIDE7IGkgPCByZXNldmVMZW5ndGg7KSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRDb2RlTGVuID0gY2hhckF0TGVuZ3RoKHN0ciwgc3RhcnRJbmRleCk7XG4gICAgICAgICAgICB2YXIgaGFzQWRkID0gZmFsc2U7IC8vIOiuvue9ruagh+W/l+S9je+8jOmYsuatouWktOWwvumDveayoeaciemZhOWKoOWtl+esplxuICAgICAgICAgICAgaWYgKHN0YXJ0Q29kZUxlbiArIGkgPD0gcmVzZXZlTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgc3RhcnRTdHIgKz0gc3RyW3N0YXJ0SW5kZXhdO1xuICAgICAgICAgICAgICAgIHN0YXJ0SW5kZXgrKztcbiAgICAgICAgICAgICAgICBpICs9IHN0YXJ0Q29kZUxlbjtcbiAgICAgICAgICAgICAgICBoYXNBZGQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGVuZENvZGVMZW4gPSBjaGFyQXRMZW5ndGgoc3RyLCBlbmRJbmRleCk7XG4gICAgICAgICAgICBpZiAoZW5kQ29kZUxlbiArIGkgPD0gcmVzZXZlTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZW5kU3RyID0gc3RyW2VuZEluZGV4XSArIGVuZFN0cjtcbiAgICAgICAgICAgICAgICBpICs9IGVuZENvZGVMZW47XG4gICAgICAgICAgICAgICAgZW5kSW5kZXgtLTtcbiAgICAgICAgICAgICAgICBoYXNBZGQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFoYXNBZGQpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzpg73msqHmnInlop7liqDlrZfnrKbvvIzor7TmmI7pg73kuI3pgILlkIjliJnkuK3mlq1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByc3QgPSBzdGFydFN0ciArIEVMTElQU0lTX0NPREUgKyBlbmRTdHI7XG4gICAgfVxuICAgIHJldHVybiByc3Q7XG59XG5leHBvcnRzLmVsbGlwc2lzU3RyaW5nID0gZWxsaXBzaXNTdHJpbmc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXh0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICAgIGZvbnRGYW1pbHk6IFwiXFxuICBcXFwiLWFwcGxlLXN5c3RlbVxcXCIsIEJsaW5rTWFjU3lzdGVtRm9udCwgXFxcIlNlZ29lIFVJXFxcIiwgUm9ib3RvLFxcXCJIZWx2ZXRpY2EgTmV1ZVxcXCIsXFxuICBIZWx2ZXRpY2EsIFxcXCJQaW5nRmFuZyBTQ1xcXCIsIFxcXCJIaXJhZ2lubyBTYW5zIEdCXFxcIiwgXFxcIk1pY3Jvc29mdCBZYUhlaVxcXCIsXFxuICBTaW1TdW4sIFxcXCJzYW5zLXNlcmlmXFxcIlwiLFxuICAgIHRleHRDb2xvcjogJyMyQzM1NDInLFxuICAgIGFjdGl2ZVRleHRDb2xvcjogJyMzMzMzMzMnLFxuICAgIHVuY2hlY2tlZENvbG9yOiAnI0Q4RDhEOCcsXG4gICAgbGluZUNvbG9yOiAnIzQxNjE4MCcsXG4gICAgcmVnaW9uQ29sb3I6ICcjQ0NEN0VCJyxcbiAgICB2ZXJ0aWNhbEF4aXNSb3RhdGU6IC1NYXRoLlBJIC8gNCxcbiAgICBob3Jpem9udGFsQXhpc1JvdGF0ZTogTWF0aC5QSSAvIDQsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFRleHRQb2ludCA9IGV4cG9ydHMudG9QeCA9IGV4cG9ydHMudXBkYXRlQ2xpcCA9IGV4cG9ydHMuZ2V0QkJveFdpdGhDbGlwID0gZXhwb3J0cy5tZXJnZUJCb3ggPSBleHBvcnRzLmludGVyc2VjdEJCb3ggPSBleHBvcnRzLm5lYXIgPSBleHBvcnRzLndhaXQgPSBleHBvcnRzLmRpc3RhbmNlID0gZXhwb3J0cy5nZXRDaXJjbGVQb2ludCA9IGV4cG9ydHMuZ2V0VmFsdWVCeVBlcmNlbnQgPSBleHBvcnRzLmNyZWF0ZUJCb3ggPSBleHBvcnRzLnBvaW50c1RvQkJveCA9IGV4cG9ydHMucmVnaW9uVG9CQm94ID0gZXhwb3J0cy5oYXNDbGFzcyA9IGV4cG9ydHMuY2xlYXJEb20gPSBleHBvcnRzLmZvcm1hdFBhZGRpbmcgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG5mdW5jdGlvbiBmb3JtYXRQYWRkaW5nKHBhZGRpbmcpIHtcbiAgICB2YXIgdG9wID0gMDtcbiAgICB2YXIgbGVmdCA9IDA7XG4gICAgdmFyIHJpZ2h0ID0gMDtcbiAgICB2YXIgYm90dG9tID0gMDtcbiAgICBpZiAodXRpbF8xLmlzTnVtYmVyKHBhZGRpbmcpKSB7XG4gICAgICAgIHRvcCA9IGxlZnQgPSByaWdodCA9IGJvdHRvbSA9IHBhZGRpbmc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHV0aWxfMS5pc0FycmF5KHBhZGRpbmcpKSB7XG4gICAgICAgIHRvcCA9IHBhZGRpbmdbMF07XG4gICAgICAgIHJpZ2h0ID0gIXV0aWxfMS5pc05pbChwYWRkaW5nWzFdKSA/IHBhZGRpbmdbMV0gOiBwYWRkaW5nWzBdO1xuICAgICAgICBib3R0b20gPSAhdXRpbF8xLmlzTmlsKHBhZGRpbmdbMl0pID8gcGFkZGluZ1syXSA6IHBhZGRpbmdbMF07XG4gICAgICAgIGxlZnQgPSAhdXRpbF8xLmlzTmlsKHBhZGRpbmdbM10pID8gcGFkZGluZ1szXSA6IHJpZ2h0O1xuICAgIH1cbiAgICByZXR1cm4gW3RvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdF07XG59XG5leHBvcnRzLmZvcm1hdFBhZGRpbmcgPSBmb3JtYXRQYWRkaW5nO1xuZnVuY3Rpb24gY2xlYXJEb20oY29udGFpbmVyKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gY29udGFpbmVyLmNoaWxkTm9kZXM7XG4gICAgdmFyIGxlbmd0aCA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gbGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKGNoaWxkcmVuW2ldKTtcbiAgICB9XG59XG5leHBvcnRzLmNsZWFyRG9tID0gY2xlYXJEb207XG5mdW5jdGlvbiBoYXNDbGFzcyhlbGVtZW50cywgY05hbWUpIHtcbiAgICByZXR1cm4gISFlbGVtZW50cy5jbGFzc05hbWUubWF0Y2gobmV3IFJlZ0V4cChcIihcXFxcc3xeKVwiICsgY05hbWUgKyBcIihcXFxcc3wkKVwiKSk7XG59XG5leHBvcnRzLmhhc0NsYXNzID0gaGFzQ2xhc3M7XG5mdW5jdGlvbiByZWdpb25Ub0JCb3gocmVnaW9uKSB7XG4gICAgdmFyIHN0YXJ0ID0gcmVnaW9uLnN0YXJ0LCBlbmQgPSByZWdpb24uZW5kO1xuICAgIHZhciBtaW5YID0gTWF0aC5taW4oc3RhcnQueCwgZW5kLngpO1xuICAgIHZhciBtaW5ZID0gTWF0aC5taW4oc3RhcnQueSwgZW5kLnkpO1xuICAgIHZhciBtYXhYID0gTWF0aC5tYXgoc3RhcnQueCwgZW5kLngpO1xuICAgIHZhciBtYXhZID0gTWF0aC5tYXgoc3RhcnQueSwgZW5kLnkpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IG1pblgsXG4gICAgICAgIHk6IG1pblksXG4gICAgICAgIG1pblg6IG1pblgsXG4gICAgICAgIG1pblk6IG1pblksXG4gICAgICAgIG1heFg6IG1heFgsXG4gICAgICAgIG1heFk6IG1heFksXG4gICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICB9O1xufVxuZXhwb3J0cy5yZWdpb25Ub0JCb3ggPSByZWdpb25Ub0JCb3g7XG5mdW5jdGlvbiBwb2ludHNUb0JCb3gocG9pbnRzKSB7XG4gICAgdmFyIHhzID0gcG9pbnRzLm1hcChmdW5jdGlvbiAocG9pbnQpIHsgcmV0dXJuIHBvaW50Lng7IH0pO1xuICAgIHZhciB5cyA9IHBvaW50cy5tYXAoZnVuY3Rpb24gKHBvaW50KSB7IHJldHVybiBwb2ludC55OyB9KTtcbiAgICB2YXIgbWluWCA9IE1hdGgubWluLmFwcGx5KE1hdGgsIHhzKTtcbiAgICB2YXIgbWluWSA9IE1hdGgubWluLmFwcGx5KE1hdGgsIHlzKTtcbiAgICB2YXIgbWF4WCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHhzKTtcbiAgICB2YXIgbWF4WSA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHlzKTtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBtaW5YLFxuICAgICAgICB5OiBtaW5ZLFxuICAgICAgICBtaW5YOiBtaW5YLFxuICAgICAgICBtaW5ZOiBtaW5ZLFxuICAgICAgICBtYXhYOiBtYXhYLFxuICAgICAgICBtYXhZOiBtYXhZLFxuICAgICAgICB3aWR0aDogbWF4WCAtIG1pblgsXG4gICAgICAgIGhlaWdodDogbWF4WSAtIG1pblksXG4gICAgfTtcbn1cbmV4cG9ydHMucG9pbnRzVG9CQm94ID0gcG9pbnRzVG9CQm94O1xuZnVuY3Rpb24gY3JlYXRlQkJveCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgbWluWDogeCxcbiAgICAgICAgbWluWTogeSxcbiAgICAgICAgbWF4WDogeCArIHdpZHRoLFxuICAgICAgICBtYXhZOiB5ICsgaGVpZ2h0LFxuICAgIH07XG59XG5leHBvcnRzLmNyZWF0ZUJCb3ggPSBjcmVhdGVCQm94O1xuZnVuY3Rpb24gZ2V0VmFsdWVCeVBlcmNlbnQobWluLCBtYXgsIHBlcmNlbnQpIHtcbiAgICByZXR1cm4gKDEgLSBwZXJjZW50KSAqIG1pbiArIG1heCAqIHBlcmNlbnQ7XG59XG5leHBvcnRzLmdldFZhbHVlQnlQZXJjZW50ID0gZ2V0VmFsdWVCeVBlcmNlbnQ7XG5mdW5jdGlvbiBnZXRDaXJjbGVQb2ludChjZW50ZXIsIHJhZGl1cywgYW5nbGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBjZW50ZXIueCArIE1hdGguY29zKGFuZ2xlKSAqIHJhZGl1cyxcbiAgICAgICAgeTogY2VudGVyLnkgKyBNYXRoLnNpbihhbmdsZSkgKiByYWRpdXMsXG4gICAgfTtcbn1cbmV4cG9ydHMuZ2V0Q2lyY2xlUG9pbnQgPSBnZXRDaXJjbGVQb2ludDtcbmZ1bmN0aW9uIGRpc3RhbmNlKHAxLCBwMikge1xuICAgIHZhciBkeCA9IHAyLnggLSBwMS54O1xuICAgIHZhciBkeSA9IHAyLnkgLSBwMS55O1xuICAgIHJldHVybiBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xufVxuZXhwb3J0cy5kaXN0YW5jZSA9IGRpc3RhbmNlO1xuZXhwb3J0cy53YWl0ID0gZnVuY3Rpb24gKGludGVydmFsKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgaW50ZXJ2YWwpO1xuICAgIH0pO1xufTtcbmV4cG9ydHMubmVhciA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFt4LCB5XS5pbmNsdWRlcyhJbmZpbml0eSkgPyBNYXRoLmFicyh4KSA9PT0gTWF0aC5hYnMoeSkgOiBNYXRoLmFicyh4IC0geSkgPCBNYXRoLnBvdyhOdW1iZXIuRVBTSUxPTiwgMC41KTtcbn07XG5mdW5jdGlvbiBpbnRlcnNlY3RCQm94KGJveDEsIGJveDIpIHtcbiAgICB2YXIgbWluWCA9IE1hdGgubWF4KGJveDEubWluWCwgYm94Mi5taW5YKTtcbiAgICB2YXIgbWluWSA9IE1hdGgubWF4KGJveDEubWluWSwgYm94Mi5taW5ZKTtcbiAgICB2YXIgbWF4WCA9IE1hdGgubWluKGJveDEubWF4WCwgYm94Mi5tYXhYKTtcbiAgICB2YXIgbWF4WSA9IE1hdGgubWluKGJveDEubWF4WSwgYm94Mi5tYXhZKTtcbiAgICByZXR1cm4gY3JlYXRlQkJveChtaW5YLCBtaW5ZLCBtYXhYIC0gbWluWCwgbWF4WSAtIG1pblkpO1xufVxuZXhwb3J0cy5pbnRlcnNlY3RCQm94ID0gaW50ZXJzZWN0QkJveDtcbmZ1bmN0aW9uIG1lcmdlQkJveChib3gxLCBib3gyKSB7XG4gICAgdmFyIG1pblggPSBNYXRoLm1pbihib3gxLm1pblgsIGJveDIubWluWCk7XG4gICAgdmFyIG1pblkgPSBNYXRoLm1pbihib3gxLm1pblksIGJveDIubWluWSk7XG4gICAgdmFyIG1heFggPSBNYXRoLm1heChib3gxLm1heFgsIGJveDIubWF4WCk7XG4gICAgdmFyIG1heFkgPSBNYXRoLm1heChib3gxLm1heFksIGJveDIubWF4WSk7XG4gICAgcmV0dXJuIGNyZWF0ZUJCb3gobWluWCwgbWluWSwgbWF4WCAtIG1pblgsIG1heFkgLSBtaW5ZKTtcbn1cbmV4cG9ydHMubWVyZ2VCQm94ID0gbWVyZ2VCQm94O1xuZnVuY3Rpb24gZ2V0QkJveFdpdGhDbGlwKGVsZW1lbnQpIHtcbiAgICB2YXIgY2xpcFNoYXBlID0gZWxlbWVudC5nZXRDbGlwKCk7XG4gICAgdmFyIGNsaXBCQm94ID0gY2xpcFNoYXBlICYmIGNsaXBTaGFwZS5nZXRCQm94KCk7XG4gICAgdmFyIGJib3g7XG4gICAgaWYgKCFlbGVtZW50LmlzR3JvdXAoKSkge1xuICAgICAgICAvLyDlpoLmnpzmmK/mma7pgJrnmoTlm77lvaJcbiAgICAgICAgYmJveCA9IGVsZW1lbnQuZ2V0QkJveCgpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIG1pblhfMSA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WF8xID0gLUluZmluaXR5O1xuICAgICAgICB2YXIgbWluWV8xID0gSW5maW5pdHk7XG4gICAgICAgIHZhciBtYXhZXzEgPSAtSW5maW5pdHk7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IGVsZW1lbnQuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuZ2V0KCd2aXNpYmxlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5YiG57uE5rKh5pyJ5a2Q5YWD57Sg77yM5YiZ55u05o6l6Lez6L+HXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5pc0dyb3VwKCkgJiYgY2hpbGQuZ2V0KCdjaGlsZHJlbicpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveCA9IGdldEJCb3hXaXRoQ2xpcChjaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIOiuoeeulyA0IOS4qumhtueCuVxuICAgICAgICAgICAgICAgICAgICB2YXIgbGVmdFRvcCA9IGNoaWxkLmFwcGx5VG9NYXRyaXgoW2JveC5taW5YLCBib3gubWluWSwgMV0pO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGVmdEJvdHRvbSA9IGNoaWxkLmFwcGx5VG9NYXRyaXgoW2JveC5taW5YLCBib3gubWF4WSwgMV0pO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmlnaHRUb3AgPSBjaGlsZC5hcHBseVRvTWF0cml4KFtib3gubWF4WCwgYm94Lm1pblksIDFdKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJpZ2h0Qm90dG9tID0gY2hpbGQuYXBwbHlUb01hdHJpeChbYm94Lm1heFgsIGJveC5tYXhZLCAxXSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIOS7juS4reWPluacgOWwj+eahOiMg+WbtFxuICAgICAgICAgICAgICAgICAgICB2YXIgYm94TWluWCA9IE1hdGgubWluKGxlZnRUb3BbMF0sIGxlZnRCb3R0b21bMF0sIHJpZ2h0VG9wWzBdLCByaWdodEJvdHRvbVswXSk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBib3hNYXhYID0gTWF0aC5tYXgobGVmdFRvcFswXSwgbGVmdEJvdHRvbVswXSwgcmlnaHRUb3BbMF0sIHJpZ2h0Qm90dG9tWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveE1pblkgPSBNYXRoLm1pbihsZWZ0VG9wWzFdLCBsZWZ0Qm90dG9tWzFdLCByaWdodFRvcFsxXSwgcmlnaHRCb3R0b21bMV0pO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYm94TWF4WSA9IE1hdGgubWF4KGxlZnRUb3BbMV0sIGxlZnRCb3R0b21bMV0sIHJpZ2h0VG9wWzFdLCByaWdodEJvdHRvbVsxXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChib3hNaW5YIDwgbWluWF8xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5YXzEgPSBib3hNaW5YO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChib3hNYXhYID4gbWF4WF8xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhYXzEgPSBib3hNYXhYO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChib3hNaW5ZIDwgbWluWV8xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5ZXzEgPSBib3hNaW5ZO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChib3hNYXhZID4gbWF4WV8xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhZXzEgPSBib3hNYXhZO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtaW5YXzEgPSAwO1xuICAgICAgICAgICAgbWF4WF8xID0gMDtcbiAgICAgICAgICAgIG1pbllfMSA9IDA7XG4gICAgICAgICAgICBtYXhZXzEgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGJib3ggPSBjcmVhdGVCQm94KG1pblhfMSwgbWluWV8xLCBtYXhYXzEgLSBtaW5YXzEsIG1heFlfMSAtIG1pbllfMSk7XG4gICAgfVxuICAgIGlmIChjbGlwQkJveCkge1xuICAgICAgICByZXR1cm4gaW50ZXJzZWN0QkJveChiYm94LCBjbGlwQkJveCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYmJveDtcbiAgICB9XG59XG5leHBvcnRzLmdldEJCb3hXaXRoQ2xpcCA9IGdldEJCb3hXaXRoQ2xpcDtcbmZ1bmN0aW9uIHVwZGF0ZUNsaXAoZWxlbWVudCwgbmV3RWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5nZXRDbGlwKCkgJiYgIW5ld0VsZW1lbnQuZ2V0Q2xpcCgpKSB7XG4gICAgICAgIC8vIOS4pOiAhemDveayoeaciSBjbGlwXG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIG5ld0NsaXBTaGFwZSA9IG5ld0VsZW1lbnQuZ2V0Q2xpcCgpO1xuICAgIGlmICghbmV3Q2xpcFNoYXBlKSB7XG4gICAgICAgIC8vIOaWsOeahCBlbGVtZW50IOayoeaciSBjbGlwXG4gICAgICAgIGVsZW1lbnQuc2V0Q2xpcChudWxsKTsgLy8g56e76ZmkIGNsaXBcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgY2xpcENmZyA9IHtcbiAgICAgICAgdHlwZTogbmV3Q2xpcFNoYXBlLmdldCgndHlwZScpLFxuICAgICAgICBhdHRyczogbmV3Q2xpcFNoYXBlLmF0dHIoKSxcbiAgICB9O1xuICAgIGVsZW1lbnQuc2V0Q2xpcChjbGlwQ2ZnKTtcbn1cbmV4cG9ydHMudXBkYXRlQ2xpcCA9IHVwZGF0ZUNsaXA7XG5mdW5jdGlvbiB0b1B4KG51bWJlcikge1xuICAgIHJldHVybiBudW1iZXIgKyBcInB4XCI7XG59XG5leHBvcnRzLnRvUHggPSB0b1B4O1xuZnVuY3Rpb24gZ2V0VGV4dFBvaW50KHN0YXJ0LCBlbmQsIHBvc2l0aW9uLCBvZmZzZXQpIHtcbiAgICB2YXIgbGluZUxlbmd0aCA9IGRpc3RhbmNlKHN0YXJ0LCBlbmQpO1xuICAgIHZhciBvZmZzZXRQZXJjZW50ID0gb2Zmc2V0IC8gbGluZUxlbmd0aDsgLy8g6K6h566X6Ze06Led5ZCM57q/55qE5q+U5L6L77yM55So5LqO6K6h566X5pyA57uI55qE5L2N572uXG4gICAgdmFyIHBlcmNlbnQgPSAwO1xuICAgIGlmIChwb3NpdGlvbiA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICBwZXJjZW50ID0gMCAtIG9mZnNldFBlcmNlbnQ7XG4gICAgfVxuICAgIGVsc2UgaWYgKHBvc2l0aW9uID09PSAnZW5kJykge1xuICAgICAgICBwZXJjZW50ID0gMSArIG9mZnNldFBlcmNlbnQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IGdldFZhbHVlQnlQZXJjZW50KHN0YXJ0LngsIGVuZC54LCBwZXJjZW50KSxcbiAgICAgICAgeTogZ2V0VmFsdWVCeVBlcmNlbnQoc3RhcnQueSwgZW5kLnksIHBlcmNlbnQpLFxuICAgIH07XG59XG5leHBvcnRzLmdldFRleHRQb2ludCA9IGdldFRleHRQb2ludDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBDb29yZGluYXRlIEJhc2UgQ2xhc3NcbiAqL1xudmFyIENvb3JkaW5hdGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29vcmRpbmF0ZShjZmcpIHtcbiAgICAgICAgLy8g6Ieq6Lqr5bGe5oCnXG4gICAgICAgIHRoaXMudHlwZSA9ICdjb29yZGluYXRlJztcbiAgICAgICAgdGhpcy5pc1JlY3QgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc0hlbGl4ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNQb2xhciA9IGZhbHNlO1xuICAgICAgICB0aGlzLmlzUmVmbGVjdFggPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc1JlZmxlY3RZID0gZmFsc2U7XG4gICAgICAgIHZhciBzdGFydCA9IGNmZy5zdGFydCwgZW5kID0gY2ZnLmVuZCwgX2EgPSBjZmcubWF0cml4LCBtYXRyaXggPSBfYSA9PT0gdm9pZCAwID8gWzEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDFdIDogX2EsIF9iID0gY2ZnLmlzVHJhbnNwb3NlZCwgaXNUcmFuc3Bvc2VkID0gX2IgPT09IHZvaWQgMCA/IGZhbHNlIDogX2I7XG4gICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICAgICAgdGhpcy5lbmQgPSBlbmQ7XG4gICAgICAgIHRoaXMubWF0cml4ID0gbWF0cml4O1xuICAgICAgICB0aGlzLm9yaWdpbmFsTWF0cml4ID0gdHNsaWJfMS5fX3NwcmVhZEFycmF5cyhtYXRyaXgpOyAvLyDljrvpmaTlvJXnlKhcbiAgICAgICAgdGhpcy5pc1RyYW5zcG9zZWQgPSBpc1RyYW5zcG9zZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOWIneWni+WMlua1geeoi1xuICAgICAqL1xuICAgIENvb3JkaW5hdGUucHJvdG90eXBlLmluaXRpYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGNlbnRlcuOAgXdpZHRo44CBaGVpZ2h0XG4gICAgICAgIHRoaXMuY2VudGVyID0ge1xuICAgICAgICAgICAgeDogKHRoaXMuc3RhcnQueCArIHRoaXMuZW5kLngpIC8gMixcbiAgICAgICAgICAgIHk6ICh0aGlzLnN0YXJ0LnkgKyB0aGlzLmVuZC55KSAvIDIsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMud2lkdGggPSBNYXRoLmFicyh0aGlzLmVuZC54IC0gdGhpcy5zdGFydC54KTtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBNYXRoLmFicyh0aGlzLmVuZC55IC0gdGhpcy5zdGFydC55KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOabtOaWsOmFjee9rlxuICAgICAqIEBwYXJhbSBjZmdcbiAgICAgKi9cbiAgICBDb29yZGluYXRlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHV0aWxfMS5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICAgICAgdGhpcy5pbml0aWFsKCk7XG4gICAgfTtcbiAgICBDb29yZGluYXRlLnByb3RvdHlwZS5jb252ZXJ0RGltID0gZnVuY3Rpb24gKHBlcmNlbnQsIGRpbSkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHZhciBfYiA9IHRoaXNbZGltXSwgc3RhcnQgPSBfYi5zdGFydCwgZW5kID0gX2IuZW5kO1xuICAgICAgICAvLyDkuqTmjaJcbiAgICAgICAgaWYgKHRoaXMuaXNSZWZsZWN0KGRpbSkpIHtcbiAgICAgICAgICAgIF9hID0gW2VuZCwgc3RhcnRdLCBzdGFydCA9IF9hWzBdLCBlbmQgPSBfYVsxXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RhcnQgKyBwZXJjZW50ICogKGVuZCAtIHN0YXJ0KTtcbiAgICB9O1xuICAgIENvb3JkaW5hdGUucHJvdG90eXBlLmludmVydERpbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZGltKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIF9iID0gdGhpc1tkaW1dLCBzdGFydCA9IF9iLnN0YXJ0LCBlbmQgPSBfYi5lbmQ7XG4gICAgICAgIC8vIOS6pOaNolxuICAgICAgICBpZiAodGhpcy5pc1JlZmxlY3QoZGltKSkge1xuICAgICAgICAgICAgX2EgPSBbZW5kLCBzdGFydF0sIHN0YXJ0ID0gX2FbMF0sIGVuZCA9IF9hWzFdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAodmFsdWUgLSBzdGFydCkgLyAoZW5kIC0gc3RhcnQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5bCG5Z2Q5qCH54K56L+b6KGM55+p6Zi15Y+Y5o2iXG4gICAgICogQHBhcmFtIHggICDlr7nlupQgeCDovbTnlLvluIPlnZDmoIdcbiAgICAgKiBAcGFyYW0geSAgIOWvueW6lCB5IOi9tOeUu+W4g+WdkOagh1xuICAgICAqIEBwYXJhbSB0YWcg6buY6K6k5Li6IDDvvIzlj6/lj5blgLwgMCwgMVxuICAgICAqIEByZXR1cm4gICAg6L+U5Zue5Y+Y5o2i5ZCO55qE5LiJ6Zi25ZCR6YePIFt4LCB5LCB6XVxuICAgICAqL1xuICAgIENvb3JkaW5hdGUucHJvdG90eXBlLmFwcGx5TWF0cml4ID0gZnVuY3Rpb24gKHgsIHksIHRhZykge1xuICAgICAgICBpZiAodGFnID09PSB2b2lkIDApIHsgdGFnID0gMDsgfVxuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5tYXRyaXg7XG4gICAgICAgIHZhciB2ZWN0b3IgPSBbeCwgeSwgdGFnXTtcbiAgICAgICAgbWF0cml4X3V0aWxfMS52ZWMzLnRyYW5zZm9ybU1hdDModmVjdG9yLCB2ZWN0b3IsIG1hdHJpeCk7XG4gICAgICAgIHJldHVybiB2ZWN0b3I7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIblnZDmoIfngrnov5vooYznn6npmLXpgIblj5jmjaJcbiAgICAgKiBAcGFyYW0geCAgIOWvueW6lCB4IOi9tOeUu+W4g+WdkOagh1xuICAgICAqIEBwYXJhbSB5ICAg5a+55bqUIHkg6L2055S75biD5Z2Q5qCHXG4gICAgICogQHBhcmFtIHRhZyDpu5jorqTkuLogMO+8jOWPr+WPluWAvCAwLCAxXG4gICAgICogQHJldHVybiAgICDov5Tlm57nn6npmLXpgIblj5jmjaLlkI7nmoTkuInpmLblkJHph48gW3gsIHksIHpdXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUuaW52ZXJ0TWF0cml4ID0gZnVuY3Rpb24gKHgsIHksIHRhZykge1xuICAgICAgICBpZiAodGFnID09PSB2b2lkIDApIHsgdGFnID0gMDsgfVxuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5tYXRyaXg7XG4gICAgICAgIHZhciBpbnZlcnRlZCA9IG1hdHJpeF91dGlsXzEubWF0My5pbnZlcnQoWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdLCBtYXRyaXgpO1xuICAgICAgICB2YXIgdmVjdG9yID0gW3gsIHksIHRhZ107XG4gICAgICAgIGlmIChpbnZlcnRlZCkge1xuICAgICAgICAgICAgLy8g5aaC5p6c5Li656m65YiZ5LiN6L+b6KGM55+p6Zi15Y+Y5YyW77yM6Ziy5q2i5oql6ZSZXG4gICAgICAgICAgICBtYXRyaXhfdXRpbF8xLnZlYzMudHJhbnNmb3JtTWF0Myh2ZWN0b3IsIHZlY3RvciwgaW52ZXJ0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2ZWN0b3I7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIblvZLkuIDljJbnmoTlnZDmoIfngrnmlbDmja7ovazmjaLkuLrnlLvluIPlnZDmoIfvvIzlubbmoLnmja7lnZDmoIfns7vlvZPliY3nn6npmLXov5vooYzlj5jmjaJcbiAgICAgKiBAcGFyYW0gcG9pbnQg5b2S5LiA5YyW55qE5Z2Q5qCH54K5XG4gICAgICogQHJldHVybiAgICAgIOi/lOWbnui/m+ihjOefqemYteWPmOaNouWQjueahOeUu+W4g+WdkOagh1xuICAgICAqL1xuICAgIENvb3JkaW5hdGUucHJvdG90eXBlLmNvbnZlcnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb252ZXJ0UG9pbnQocG9pbnQpLCB4ID0gX2EueCwgeSA9IF9hLnk7XG4gICAgICAgIHZhciB2ZWN0b3IgPSB0aGlzLmFwcGx5TWF0cml4KHgsIHksIDEpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogdmVjdG9yWzBdLFxuICAgICAgICAgICAgeTogdmVjdG9yWzFdLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5bCG6L+b6KGM6L+H55+p6Zi15Y+Y5o2i55S75biD5Z2Q5qCH6L2s5o2i5Li65b2S5LiA5YyW5Z2Q5qCHXG4gICAgICogQHBhcmFtIHBvaW50IOeUu+W4g+WdkOagh1xuICAgICAqIEByZXR1cm4gICAgICDov5Tlm57lvZLkuIDljJbnmoTlnZDmoIfngrlcbiAgICAgKi9cbiAgICBDb29yZGluYXRlLnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIHZlY3RvciA9IHRoaXMuaW52ZXJ0TWF0cml4KHBvaW50LngsIHBvaW50LnksIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5pbnZlcnRQb2ludCh7XG4gICAgICAgICAgICB4OiB2ZWN0b3JbMF0sXG4gICAgICAgICAgICB5OiB2ZWN0b3JbMV0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Z2Q5qCH57O75peL6L2s5Y+Y5o2iXG4gICAgICogQHBhcmFtICByYWRpYW4g5peL6L2s5byn5bqmXG4gICAgICogQHJldHVybiAgICAgICAg6L+U5Zue5Z2Q5qCH57O75a+56LGhXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUucm90YXRlID0gZnVuY3Rpb24gKHJhZGlhbikge1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5tYXRyaXg7XG4gICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLmNlbnRlcjtcbiAgICAgICAgbWF0cml4X3V0aWxfMS5leHQubGVmdFRyYW5zbGF0ZShtYXRyaXgsIG1hdHJpeCwgWy1jZW50ZXIueCwgLWNlbnRlci55XSk7XG4gICAgICAgIG1hdHJpeF91dGlsXzEuZXh0LmxlZnRSb3RhdGUobWF0cml4LCBtYXRyaXgsIHJhZGlhbik7XG4gICAgICAgIG1hdHJpeF91dGlsXzEuZXh0LmxlZnRUcmFuc2xhdGUobWF0cml4LCBtYXRyaXgsIFtjZW50ZXIueCwgY2VudGVyLnldKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlnZDmoIfns7vlj43lsITlj5jmjaJcbiAgICAgKiBAcGFyYW0gZGltIOWPjeWwhOe7tOW6plxuICAgICAqIEByZXR1cm4gICAg6L+U5Zue5Z2Q5qCH57O75a+56LGhXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUucmVmbGVjdCA9IGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgaWYgKGRpbSA9PT0gJ3gnKSB7XG4gICAgICAgICAgICB0aGlzLmlzUmVmbGVjdFggPSAhdGhpcy5pc1JlZmxlY3RYO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pc1JlZmxlY3RZID0gIXRoaXMuaXNSZWZsZWN0WTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWdkOagh+ezu+avlOS+i+WPmOaNolxuICAgICAqIEBwYXJhbSBzMSB4IOaWueWQkee8qeaUvuavlOS+i1xuICAgICAqIEBwYXJhbSBzMiB5IOaWueWQkee8qeaUvuavlOS+i1xuICAgICAqIEByZXR1cm4gICAgIOi/lOWbnuWdkOagh+ezu+WvueixoVxuICAgICAqL1xuICAgIENvb3JkaW5hdGUucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKHMxLCBzMikge1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5tYXRyaXg7XG4gICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLmNlbnRlcjtcbiAgICAgICAgbWF0cml4X3V0aWxfMS5leHQubGVmdFRyYW5zbGF0ZShtYXRyaXgsIG1hdHJpeCwgWy1jZW50ZXIueCwgLWNlbnRlci55XSk7XG4gICAgICAgIG1hdHJpeF91dGlsXzEuZXh0LmxlZnRTY2FsZShtYXRyaXgsIG1hdHJpeCwgW3MxLCBzMl0pO1xuICAgICAgICBtYXRyaXhfdXRpbF8xLmV4dC5sZWZ0VHJhbnNsYXRlKG1hdHJpeCwgbWF0cml4LCBbY2VudGVyLngsIGNlbnRlci55XSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Z2Q5qCH57O75bmz56e75Y+Y5o2iXG4gICAgICogQHBhcmFtIHggeCDmlrnlkJHlubPnp7vlg4/ntKBcbiAgICAgKiBAcGFyYW0geSB5IOaWueWQkeW5s+enu+WDj+e0oFxuICAgICAqIEByZXR1cm4gICAg6L+U5Zue5Z2Q5qCH57O75a+56LGhXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUudHJhbnNsYXRlID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgdmFyIG1hdHJpeCA9IHRoaXMubWF0cml4O1xuICAgICAgICBtYXRyaXhfdXRpbF8xLmV4dC5sZWZ0VHJhbnNsYXRlKG1hdHJpeCwgbWF0cml4LCBbeCwgeV0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWwhuWdkOagh+ezuyB4IHkg5Lik5Liq6L206L+b6KGM6L2s572uXG4gICAgICogQHJldHVybiDov5Tlm57lnZDmoIfns7vlr7nosaFcbiAgICAgKi9cbiAgICBDb29yZGluYXRlLnByb3RvdHlwZS50cmFuc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaXNUcmFuc3Bvc2VkID0gIXRoaXMuaXNUcmFuc3Bvc2VkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIENvb3JkaW5hdGUucHJvdG90eXBlLmdldENlbnRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2VudGVyO1xuICAgIH07XG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUuZ2V0V2lkdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpZHRoO1xuICAgIH07XG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUuZ2V0SGVpZ2h0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZWlnaHQ7XG4gICAgfTtcbiAgICBDb29yZGluYXRlLnByb3RvdHlwZS5nZXRSYWRpdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJhZGl1cztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIHdoZXRoZXIgaGFzIHJlZmxlY3RcbiAgICAgKiBAcGFyYW0gZGltXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUuaXNSZWZsZWN0ID0gZnVuY3Rpb24gKGRpbSkge1xuICAgICAgICByZXR1cm4gZGltID09PSAneCcgPyB0aGlzLmlzUmVmbGVjdFggOiB0aGlzLmlzUmVmbGVjdFk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDph43nva4gbWF0cml4XG4gICAgICogQHBhcmFtIG1hdHJpeCDlpoLmnpzkvKDlhaXvvIzliJnkvb/nlKjvvIzlkKbliJnkvb/nlKjmnoTpgKDlh73mlbDkuK3kvKDlhaXnmoTpu5jorqQgbWF0cml4XG4gICAgICovXG4gICAgQ29vcmRpbmF0ZS5wcm90b3R5cGUucmVzZXRNYXRyaXggPSBmdW5jdGlvbiAobWF0cml4KSB7XG4gICAgICAgIC8vIOWOu+mZpOW8leeUqOWFs+ezu1xuICAgICAgICB0aGlzLm1hdHJpeCA9IG1hdHJpeCA/IG1hdHJpeCA6IHRzbGliXzEuX19zcHJlYWRBcnJheXModGhpcy5vcmlnaW5hbE1hdHJpeCk7XG4gICAgfTtcbiAgICByZXR1cm4gQ29vcmRpbmF0ZTtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDb29yZGluYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG4vKipcbiAqIOesm+WNoeWwlOWdkOagh+ezu1xuICogaHR0cHM6Ly93d3cuemhpaHUuY29tL3F1ZXN0aW9uLzIwNjY1MzAzXG4gKi9cbnZhciBDYXJ0ZXNpYW4gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2FydGVzaWFuLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENhcnRlc2lhbihjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5pc1JlY3QgPSB0cnVlO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2NhcnRlc2lhbic7XG4gICAgICAgIF90aGlzLmluaXRpYWwoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBDYXJ0ZXNpYW4ucHJvdG90eXBlLmluaXRpYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdGlhbC5jYWxsKHRoaXMpO1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLnN0YXJ0O1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5lbmQ7XG4gICAgICAgIHRoaXMueCA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydC54LFxuICAgICAgICAgICAgZW5kOiBlbmQueCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy55ID0ge1xuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LnksXG4gICAgICAgICAgICBlbmQ6IGVuZC55LFxuICAgICAgICB9O1xuICAgIH07XG4gICAgQ2FydGVzaWFuLnByb3RvdHlwZS5jb252ZXJ0UG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgeCA9IHBvaW50LngsIHkgPSBwb2ludC55O1xuICAgICAgICAvLyDkuqTmjaJcbiAgICAgICAgaWYgKHRoaXMuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICBfYSA9IFt5LCB4XSwgeCA9IF9hWzBdLCB5ID0gX2FbMV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHRoaXMuY29udmVydERpbSh4LCAneCcpLFxuICAgICAgICAgICAgeTogdGhpcy5jb252ZXJ0RGltKHksICd5JyksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBDYXJ0ZXNpYW4ucHJvdG90eXBlLmludmVydFBvaW50ID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIHggPSB0aGlzLmludmVydERpbShwb2ludC54LCAneCcpO1xuICAgICAgICB2YXIgeSA9IHRoaXMuaW52ZXJ0RGltKHBvaW50LnksICd5Jyk7XG4gICAgICAgIGlmICh0aGlzLmlzVHJhbnNwb3NlZCkge1xuICAgICAgICAgICAgX2EgPSBbeSwgeF0sIHggPSBfYVswXSwgeSA9IF9hWzFdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHg6IHgsIHk6IHkgfTtcbiAgICB9O1xuICAgIHJldHVybiBDYXJ0ZXNpYW47XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDYXJ0ZXNpYW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jYXJ0ZXNpYW4uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG4vKipcbiAqIOieuuaXi+WdkOagh+ezu1xuICovXG52YXIgSGVsaXggPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSGVsaXgsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gSGVsaXgoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuaXNIZWxpeCA9IHRydWU7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnaGVsaXgnO1xuICAgICAgICB2YXIgX2EgPSBjZmcuc3RhcnRBbmdsZSwgc3RhcnRBbmdsZSA9IF9hID09PSB2b2lkIDAgPyAxLjI1ICogTWF0aC5QSSA6IF9hLCBfYiA9IGNmZy5lbmRBbmdsZSwgZW5kQW5nbGUgPSBfYiA9PT0gdm9pZCAwID8gNy4yNSAqIE1hdGguUEkgOiBfYiwgX2MgPSBjZmcuaW5uZXJSYWRpdXMsIGlubmVyUmFkaXVzID0gX2MgPT09IHZvaWQgMCA/IDAgOiBfYywgcmFkaXVzID0gY2ZnLnJhZGl1cztcbiAgICAgICAgX3RoaXMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XG4gICAgICAgIF90aGlzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XG4gICAgICAgIF90aGlzLmlubmVyUmFkaXVzID0gaW5uZXJSYWRpdXM7XG4gICAgICAgIF90aGlzLnJhZGl1cyA9IHJhZGl1cztcbiAgICAgICAgX3RoaXMuaW5pdGlhbCgpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEhlbGl4LnByb3RvdHlwZS5pbml0aWFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXRpYWwuY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIGluZGV4ID0gKHRoaXMuZW5kQW5nbGUgLSB0aGlzLnN0YXJ0QW5nbGUpIC8gKDIgKiBNYXRoLlBJKSArIDE7IC8vIOieuue6v+WciOaVsFxuICAgICAgICB2YXIgbWF4UmFkaXVzID0gTWF0aC5taW4odGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpIC8gMjtcbiAgICAgICAgaWYgKHRoaXMucmFkaXVzICYmIHRoaXMucmFkaXVzID49IDAgJiYgdGhpcy5yYWRpdXMgPD0gMSkge1xuICAgICAgICAgICAgbWF4UmFkaXVzID0gbWF4UmFkaXVzICogdGhpcy5yYWRpdXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kID0gTWF0aC5mbG9vcigobWF4UmFkaXVzICogKDEgLSB0aGlzLmlubmVyUmFkaXVzKSkgLyBpbmRleCk7XG4gICAgICAgIHRoaXMuYSA9IHRoaXMuZCAvIChNYXRoLlBJICogMik7IC8vIOieuue6v+ezu+aVsFxuICAgICAgICB0aGlzLnggPSB7XG4gICAgICAgICAgICBzdGFydDogdGhpcy5zdGFydEFuZ2xlLFxuICAgICAgICAgICAgZW5kOiB0aGlzLmVuZEFuZ2xlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnkgPSB7XG4gICAgICAgICAgICBzdGFydDogdGhpcy5pbm5lclJhZGl1cyAqIG1heFJhZGl1cyxcbiAgICAgICAgICAgIGVuZDogdGhpcy5pbm5lclJhZGl1cyAqIG1heFJhZGl1cyArIHRoaXMuZCAqIDAuOTksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIbnmb7liIbmr5TmlbDmja7lj5jmiJDlsY/luZXlnZDmoIdcbiAgICAgKiBAcGFyYW0gcG9pbnQg5b2S5LiA5YyW55qE54K55Z2Q5qCHXG4gICAgICogQHJldHVybiAgICAgIOi/lOWbnuWvueW6lOeahOWxj+W5leWdkOagh1xuICAgICAqL1xuICAgIEhlbGl4LnByb3RvdHlwZS5jb252ZXJ0UG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgeCA9IHBvaW50LngsIHkgPSBwb2ludC55O1xuICAgICAgICBpZiAodGhpcy5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgIF9hID0gW3ksIHhdLCB4ID0gX2FbMF0sIHkgPSBfYVsxXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGhpID0gdGhpcy5jb252ZXJ0RGltKHgsICd4Jyk7XG4gICAgICAgIHZhciByID0gdGhpcy5hICogdGhpO1xuICAgICAgICB2YXIgbmV3WSA9IHRoaXMuY29udmVydERpbSh5LCAneScpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogdGhpcy5jZW50ZXIueCArIE1hdGguY29zKHRoaSkgKiAociArIG5ld1kpLFxuICAgICAgICAgICAgeTogdGhpcy5jZW50ZXIueSArIE1hdGguc2luKHRoaSkgKiAociArIG5ld1kpLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5bCG5bGP5bmV5Z2Q5qCH54K56L+Y5Y6f5oiQ55m+5YiG5q+U5pWw5o2uXG4gICAgICogQHBhcmFtIHBvaW50IOWxj+W5leWdkOagh1xuICAgICAqIEByZXR1cm4gICAgICDov5Tlm57lr7nlupTnmoTlvZLkuIDljJblkI7nmoTmlbDmja5cbiAgICAgKi9cbiAgICBIZWxpeC5wcm90b3R5cGUuaW52ZXJ0UG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgZCA9IHRoaXMuZCArIHRoaXMueS5zdGFydDtcbiAgICAgICAgdmFyIHYgPSBtYXRyaXhfdXRpbF8xLnZlYzIuc3VidHJhY3QoWzAsIDBdLCBbcG9pbnQueCwgcG9pbnQueV0sIFt0aGlzLmNlbnRlci54LCB0aGlzLmNlbnRlci55XSk7XG4gICAgICAgIHZhciB0aGkgPSBtYXRyaXhfdXRpbF8xLmV4dC5hbmdsZVRvKHYsIFsxLCAwXSwgdHJ1ZSk7XG4gICAgICAgIHZhciByTWluID0gdGhpICogdGhpcy5hOyAvLyDlnZDmoIfkuI7ljp/ngrnnmoTov57nur/lnKjnrKzkuIDlnIjkuIrnmoTkuqTngrnvvIzmnIDlsI9y5YC8XG4gICAgICAgIGlmIChtYXRyaXhfdXRpbF8xLnZlYzIubGVuZ3RoKHYpIDwgck1pbikge1xuICAgICAgICAgICAgLy8g5Z2Q5qCH5LiO5Y6f54K555qE6L+e57q/5LiN5Y+v6IO95bCP5LqO5pyA5bCPcuWAvO+8jOS9huS4jeaOkumZpOWboOWwj+aVsOiuoeeul+S6p+eUn+eahOeVpeWwj+S6jnJNaW7nmoTmg4XlhrVcbiAgICAgICAgICAgIHJNaW4gPSBtYXRyaXhfdXRpbF8xLnZlYzIubGVuZ3RoKHYpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBpbmRleCA9IE1hdGguZmxvb3IoKG1hdHJpeF91dGlsXzEudmVjMi5sZW5ndGgodikgLSByTWluKSAvIGQpOyAvLyDlvZPliY3ngrnkvY3kuo7nrKxpbmRleOWciFxuICAgICAgICB0aGkgPSAyICogaW5kZXggKiBNYXRoLlBJICsgdGhpO1xuICAgICAgICB2YXIgciA9IHRoaXMuYSAqIHRoaTtcbiAgICAgICAgdmFyIG5ld1kgPSBtYXRyaXhfdXRpbF8xLnZlYzIubGVuZ3RoKHYpIC0gcjtcbiAgICAgICAgbmV3WSA9IHV0aWxfMS5pc051bWJlckVxdWFsKG5ld1ksIDApID8gMCA6IG5ld1k7XG4gICAgICAgIHZhciB4ID0gdGhpcy5pbnZlcnREaW0odGhpLCAneCcpO1xuICAgICAgICB2YXIgeSA9IHRoaXMuaW52ZXJ0RGltKG5ld1ksICd5Jyk7XG4gICAgICAgIHggPSB1dGlsXzEuaXNOdW1iZXJFcXVhbCh4LCAwKSA/IDAgOiB4O1xuICAgICAgICB5ID0gdXRpbF8xLmlzTnVtYmVyRXF1YWwoeSwgMCkgPyAwIDogeTtcbiAgICAgICAgaWYgKHRoaXMuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICBfYSA9IFt5LCB4XSwgeCA9IF9hWzBdLCB5ID0gX2FbMV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xuICAgIH07XG4gICAgcmV0dXJuIEhlbGl4O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSGVsaXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1oZWxpeC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBQb2xhciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQb2xhciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQb2xhcihjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5pc1BvbGFyID0gdHJ1ZTtcbiAgICAgICAgX3RoaXMudHlwZSA9ICdwb2xhcic7XG4gICAgICAgIHZhciBfYSA9IGNmZy5zdGFydEFuZ2xlLCBzdGFydEFuZ2xlID0gX2EgPT09IHZvaWQgMCA/IC1NYXRoLlBJIC8gMiA6IF9hLCBfYiA9IGNmZy5lbmRBbmdsZSwgZW5kQW5nbGUgPSBfYiA9PT0gdm9pZCAwID8gKE1hdGguUEkgKiAzKSAvIDIgOiBfYiwgX2MgPSBjZmcuaW5uZXJSYWRpdXMsIGlubmVyUmFkaXVzID0gX2MgPT09IHZvaWQgMCA/IDAgOiBfYywgcmFkaXVzID0gY2ZnLnJhZGl1cztcbiAgICAgICAgX3RoaXMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XG4gICAgICAgIF90aGlzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XG4gICAgICAgIF90aGlzLmlubmVyUmFkaXVzID0gaW5uZXJSYWRpdXM7XG4gICAgICAgIF90aGlzLnJhZGl1cyA9IHJhZGl1cztcbiAgICAgICAgX3RoaXMuaW5pdGlhbCgpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFBvbGFyLnByb3RvdHlwZS5pbml0aWFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXRpYWwuY2FsbCh0aGlzKTtcbiAgICAgICAgd2hpbGUgKHRoaXMuZW5kQW5nbGUgPCB0aGlzLnN0YXJ0QW5nbGUpIHtcbiAgICAgICAgICAgIHRoaXMuZW5kQW5nbGUgKz0gTWF0aC5QSSAqIDI7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG9uZUJveCA9IHRoaXMuZ2V0T25lQm94KCk7XG4gICAgICAgIHZhciBvbmVXaWR0aCA9IG9uZUJveC5tYXhYIC0gb25lQm94Lm1pblg7XG4gICAgICAgIHZhciBvbmVIZWlnaHQgPSBvbmVCb3gubWF4WSAtIG9uZUJveC5taW5ZO1xuICAgICAgICB2YXIgbGVmdCA9IE1hdGguYWJzKG9uZUJveC5taW5YKSAvIG9uZVdpZHRoO1xuICAgICAgICB2YXIgdG9wID0gTWF0aC5hYnMob25lQm94Lm1pblkpIC8gb25lSGVpZ2h0O1xuICAgICAgICB2YXIgbWF4UmFkaXVzO1xuICAgICAgICBpZiAodGhpcy5oZWlnaHQgLyBvbmVIZWlnaHQgPiB0aGlzLndpZHRoIC8gb25lV2lkdGgpIHtcbiAgICAgICAgICAgIC8vIHdpZHRoIOS4uuS4u1xuICAgICAgICAgICAgbWF4UmFkaXVzID0gdGhpcy53aWR0aCAvIG9uZVdpZHRoO1xuICAgICAgICAgICAgdGhpcy5jaXJjbGVDZW50ZXIgPSB7XG4gICAgICAgICAgICAgICAgeDogdGhpcy5jZW50ZXIueCAtICgwLjUgLSBsZWZ0KSAqIHRoaXMud2lkdGgsXG4gICAgICAgICAgICAgICAgeTogdGhpcy5jZW50ZXIueSAtICgwLjUgLSB0b3ApICogbWF4UmFkaXVzICogb25lSGVpZ2h0LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGhlaWdodCDkuLrkuLtcbiAgICAgICAgICAgIG1heFJhZGl1cyA9IHRoaXMuaGVpZ2h0IC8gb25lSGVpZ2h0O1xuICAgICAgICAgICAgdGhpcy5jaXJjbGVDZW50ZXIgPSB7XG4gICAgICAgICAgICAgICAgeDogdGhpcy5jZW50ZXIueCAtICgwLjUgLSBsZWZ0KSAqIG1heFJhZGl1cyAqIG9uZVdpZHRoLFxuICAgICAgICAgICAgICAgIHk6IHRoaXMuY2VudGVyLnkgLSAoMC41IC0gdG9wKSAqIHRoaXMuaGVpZ2h0LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBvbGFyUmFkaXVzID0gdGhpcy5yYWRpdXM7XG4gICAgICAgIGlmICghdGhpcy5yYWRpdXMpIHtcbiAgICAgICAgICAgIHRoaXMucG9sYXJSYWRpdXMgPSBtYXhSYWRpdXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yYWRpdXMgPiAwICYmIHRoaXMucmFkaXVzIDw9IDEpIHtcbiAgICAgICAgICAgIHRoaXMucG9sYXJSYWRpdXMgPSBtYXhSYWRpdXMgKiB0aGlzLnJhZGl1cztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJhZGl1cyA8PSAwIHx8IHRoaXMucmFkaXVzID4gbWF4UmFkaXVzKSB7XG4gICAgICAgICAgICB0aGlzLnBvbGFyUmFkaXVzID0gbWF4UmFkaXVzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMueCA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0QW5nbGUsXG4gICAgICAgICAgICBlbmQ6IHRoaXMuZW5kQW5nbGUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMueSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiB0aGlzLmlubmVyUmFkaXVzICogdGhpcy5wb2xhclJhZGl1cyxcbiAgICAgICAgICAgIGVuZDogdGhpcy5wb2xhclJhZGl1cyxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIFBvbGFyLnByb3RvdHlwZS5nZXRSYWRpdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvbGFyUmFkaXVzO1xuICAgIH07XG4gICAgUG9sYXIucHJvdG90eXBlLmNvbnZlcnRQb2ludCA9IGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLmdldENlbnRlcigpO1xuICAgICAgICB2YXIgeCA9IHBvaW50LngsIHkgPSBwb2ludC55O1xuICAgICAgICBpZiAodGhpcy5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgIF9hID0gW3ksIHhdLCB4ID0gX2FbMF0sIHkgPSBfYVsxXTtcbiAgICAgICAgfVxuICAgICAgICB4ID0gdGhpcy5jb252ZXJ0RGltKHgsICd4Jyk7XG4gICAgICAgIHkgPSB0aGlzLmNvbnZlcnREaW0oeSwgJ3knKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGNlbnRlci54ICsgTWF0aC5jb3MoeCkgKiB5LFxuICAgICAgICAgICAgeTogY2VudGVyLnkgKyBNYXRoLnNpbih4KSAqIHksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBQb2xhci5wcm90b3R5cGUuaW52ZXJ0UG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIGNlbnRlciA9IHRoaXMuZ2V0Q2VudGVyKCk7XG4gICAgICAgIHZhciB2UG9pbnQgPSBbcG9pbnQueCAtIGNlbnRlci54LCBwb2ludC55IC0gY2VudGVyLnldO1xuICAgICAgICB2YXIgbSA9IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICAgICAgbWF0cml4X3V0aWxfMS5leHQubGVmdFJvdGF0ZShtLCBtLCB0aGlzLnN0YXJ0QW5nbGUpO1xuICAgICAgICB2YXIgdlN0YXJ0MyA9IFsxLCAwLCAwXTtcbiAgICAgICAgbWF0cml4X3V0aWxfMS52ZWMzLnRyYW5zZm9ybU1hdDModlN0YXJ0MywgdlN0YXJ0MywgbSk7XG4gICAgICAgIHZhciB2U3RhcnQyID0gW3ZTdGFydDNbMF0sIHZTdGFydDNbMV1dO1xuICAgICAgICB2YXIgYW5nbGUgPSBtYXRyaXhfdXRpbF8xLmV4dC5hbmdsZVRvKHZTdGFydDIsIHZQb2ludCwgdGhpcy5lbmRBbmdsZSA8IHRoaXMuc3RhcnRBbmdsZSk7XG4gICAgICAgIGlmICh1dGlsXzEuaXNOdW1iZXJFcXVhbChhbmdsZSwgTWF0aC5QSSAqIDIpKSB7XG4gICAgICAgICAgICBhbmdsZSA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJhZGl1cyA9IG1hdHJpeF91dGlsXzEudmVjMi5sZW5ndGgodlBvaW50KTtcbiAgICAgICAgdmFyIHhQZXJjZW50ID0gYW5nbGUgLyAodGhpcy5lbmRBbmdsZSAtIHRoaXMuc3RhcnRBbmdsZSk7XG4gICAgICAgIHhQZXJjZW50ID0gdGhpcy5lbmRBbmdsZSAtIHRoaXMuc3RhcnRBbmdsZSA+IDAgPyB4UGVyY2VudCA6IC14UGVyY2VudDtcbiAgICAgICAgdmFyIHlQZXJjZW50ID0gdGhpcy5pbnZlcnREaW0ocmFkaXVzLCAneScpO1xuICAgICAgICB2YXIgcnN0ID0geyB4OiAwLCB5OiAwIH07XG4gICAgICAgIHJzdC54ID0gdGhpcy5pc1RyYW5zcG9zZWQgPyB5UGVyY2VudCA6IHhQZXJjZW50O1xuICAgICAgICByc3QueSA9IHRoaXMuaXNUcmFuc3Bvc2VkID8geFBlcmNlbnQgOiB5UGVyY2VudDtcbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9O1xuICAgIFBvbGFyLnByb3RvdHlwZS5nZXRDZW50ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNpcmNsZUNlbnRlcjtcbiAgICB9O1xuICAgIFBvbGFyLnByb3RvdHlwZS5nZXRPbmVCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gdGhpcy5zdGFydEFuZ2xlO1xuICAgICAgICB2YXIgZW5kQW5nbGUgPSB0aGlzLmVuZEFuZ2xlO1xuICAgICAgICBpZiAoTWF0aC5hYnMoZW5kQW5nbGUgLSBzdGFydEFuZ2xlKSA+PSBNYXRoLlBJICogMikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtaW5YOiAtMSxcbiAgICAgICAgICAgICAgICBtYXhYOiAxLFxuICAgICAgICAgICAgICAgIG1pblk6IC0xLFxuICAgICAgICAgICAgICAgIG1heFk6IDEsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHZhciB4cyA9IFswLCBNYXRoLmNvcyhzdGFydEFuZ2xlKSwgTWF0aC5jb3MoZW5kQW5nbGUpXTtcbiAgICAgICAgdmFyIHlzID0gWzAsIE1hdGguc2luKHN0YXJ0QW5nbGUpLCBNYXRoLnNpbihlbmRBbmdsZSldO1xuICAgICAgICBmb3IgKHZhciBpID0gTWF0aC5taW4oc3RhcnRBbmdsZSwgZW5kQW5nbGUpOyBpIDwgTWF0aC5tYXgoc3RhcnRBbmdsZSwgZW5kQW5nbGUpOyBpICs9IE1hdGguUEkgLyAxOCkge1xuICAgICAgICAgICAgeHMucHVzaChNYXRoLmNvcyhpKSk7XG4gICAgICAgICAgICB5cy5wdXNoKE1hdGguc2luKGkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluWDogTWF0aC5taW4uYXBwbHkoTWF0aCwgeHMpLFxuICAgICAgICAgICAgbWF4WDogTWF0aC5tYXguYXBwbHkoTWF0aCwgeHMpLFxuICAgICAgICAgICAgbWluWTogTWF0aC5taW4uYXBwbHkoTWF0aCwgeXMpLFxuICAgICAgICAgICAgbWF4WTogTWF0aC5tYXguYXBwbHkoTWF0aCwgeXMpLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFBvbGFyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG9sYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2xhci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIOaJgOacieeahCBDb29yZGluYXRlIG1hcFxudmFyIENPT1JESU5BVEVfTUFQID0ge307XG4vKipcbiAqIOmAmui/h+exu+Wei+iOt+W+lyBjb29yZGluYXRlIOexu1xuICogQHBhcmFtIHR5cGVcbiAqL1xuZXhwb3J0cy5nZXRDb29yZGluYXRlID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICByZXR1cm4gQ09PUkRJTkFURV9NQVBbdHlwZS50b0xvd2VyQ2FzZSgpXTtcbn07XG4vKipcbiAqIOazqOWGjCBjb29yZGluYXRlIOexu1xuICogQHBhcmFtIHR5cGVcbiAqIEBwYXJhbSBjdG9yXG4gKi9cbmV4cG9ydHMucmVnaXN0ZXJDb29yZGluYXRlID0gZnVuY3Rpb24gKHR5cGUsIGN0b3IpIHtcbiAgICAvLyDlrZjlgqjliLAgbWFwIOS4rVxuICAgIENPT1JESU5BVEVfTUFQW3R5cGUudG9Mb3dlckNhc2UoKV0gPSBjdG9yO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZhY3RvcnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vY29vcmQvYmFzZVwiKTtcbmV4cG9ydHMuQ29vcmRpbmF0ZSA9IGJhc2VfMS5kZWZhdWx0O1xudmFyIGNhcnRlc2lhbl8xID0gcmVxdWlyZShcIi4vY29vcmQvY2FydGVzaWFuXCIpO1xudmFyIGhlbGl4XzEgPSByZXF1aXJlKFwiLi9jb29yZC9oZWxpeFwiKTtcbnZhciBwb2xhcl8xID0gcmVxdWlyZShcIi4vY29vcmQvcG9sYXJcIik7XG52YXIgZmFjdG9yeV8xID0gcmVxdWlyZShcIi4vZmFjdG9yeVwiKTtcbmV4cG9ydHMuZ2V0Q29vcmRpbmF0ZSA9IGZhY3RvcnlfMS5nZXRDb29yZGluYXRlO1xuZXhwb3J0cy5yZWdpc3RlckNvb3JkaW5hdGUgPSBmYWN0b3J5XzEucmVnaXN0ZXJDb29yZGluYXRlO1xuZmFjdG9yeV8xLnJlZ2lzdGVyQ29vcmRpbmF0ZSgncmVjdCcsIGNhcnRlc2lhbl8xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyQ29vcmRpbmF0ZSgnY2FydGVzaWFuJywgY2FydGVzaWFuXzEuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJDb29yZGluYXRlKCdwb2xhcicsIHBvbGFyXzEuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJDb29yZGluYXRlKCdoZWxpeCcsIGhlbGl4XzEuZGVmYXVsdCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIodGFyZ2V0LCBldmVudFR5cGUsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHRhcmdldCkge1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldC5hZGRFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGNhbGxiYWNrLCBmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGNhbGxiYWNrLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXQuYXR0YWNoRXZlbnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIHRhcmdldC5hdHRhY2hFdmVudCgnb24nICsgZXZlbnRUeXBlLCBjYWxsYmFjayk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5kZXRhY2hFdmVudCgnb24nICsgZXZlbnRUeXBlLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnRzLmRlZmF1bHQgPSBhZGRFdmVudExpc3RlbmVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWV2ZW50LWxpc3RlbmVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiDliJvlu7pET00g6IqC54K5XG4gKiBAcGFyYW0gIHtTdHJpbmd9IHN0ciBEb20g5a2X56ym5LiyXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH0gIERPTSDoioLngrlcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIFRBQkxFO1xudmFyIFRBQkxFX1RSO1xudmFyIEZSQUdNRU5UX1JFRztcbnZhciBDT05UQUlORVJTO1xuZnVuY3Rpb24gaW5pdENvbnN0YW50cygpIHtcbiAgICBUQUJMRSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RhYmxlJyk7XG4gICAgVEFCTEVfVFIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0cicpO1xuICAgIEZSQUdNRU5UX1JFRyA9IC9eXFxzKjwoXFx3K3whKVtePl0qPi87XG4gICAgQ09OVEFJTkVSUyA9IHtcbiAgICAgICAgdHI6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3Rib2R5JyksXG4gICAgICAgIHRib2R5OiBUQUJMRSxcbiAgICAgICAgdGhlYWQ6IFRBQkxFLFxuICAgICAgICB0Zm9vdDogVEFCTEUsXG4gICAgICAgIHRkOiBUQUJMRV9UUixcbiAgICAgICAgdGg6IFRBQkxFX1RSLFxuICAgICAgICAnKic6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgIH07XG59XG5mdW5jdGlvbiBjcmVhdGVEb20oc3RyKSB7XG4gICAgaWYgKCFUQUJMRSkge1xuICAgICAgICBpbml0Q29uc3RhbnRzKCk7XG4gICAgfVxuICAgIHZhciBuYW1lID0gRlJBR01FTlRfUkVHLnRlc3Qoc3RyKSAmJiBSZWdFeHAuJDE7XG4gICAgaWYgKCFuYW1lIHx8ICEobmFtZSBpbiBDT05UQUlORVJTKSkge1xuICAgICAgICBuYW1lID0gJyonO1xuICAgIH1cbiAgICB2YXIgY29udGFpbmVyID0gQ09OVEFJTkVSU1tuYW1lXTtcbiAgICBzdHIgPSBzdHIucmVwbGFjZSgvKF5cXHMqKXwoXFxzKiQpL2csICcnKTtcbiAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJycgKyBzdHI7XG4gICAgdmFyIGRvbSA9IGNvbnRhaW5lci5jaGlsZE5vZGVzWzBdO1xuICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChkb20pO1xuICAgIHJldHVybiBkb207XG59XG5leHBvcnRzLmRlZmF1bHQgPSBjcmVhdGVEb207XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtZG9tLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4vZ2V0LXN0eWxlXCIpO1xuZnVuY3Rpb24gZ2V0SGVpZ2h0KGVsLCBkZWZhdWx0VmFsdWUpIHtcbiAgICB2YXIgaGVpZ2h0ID0gZ2V0X3N0eWxlXzEuZGVmYXVsdChlbCwgJ2hlaWdodCcsIGRlZmF1bHRWYWx1ZSk7XG4gICAgaWYgKGhlaWdodCA9PT0gJ2F1dG8nKSB7XG4gICAgICAgIGhlaWdodCA9IGVsLm9mZnNldEhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQoaGVpZ2h0KTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGdldEhlaWdodDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1oZWlnaHQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi9nZXQtc3R5bGVcIik7XG52YXIgZ2V0X2hlaWdodF8xID0gcmVxdWlyZShcIi4vZ2V0LWhlaWdodFwiKTtcbmZ1bmN0aW9uIGdldE91dGVySGVpZ2h0KGVsLCBkZWZhdWx0VmFsdWUpIHtcbiAgICB2YXIgaGVpZ2h0ID0gZ2V0X2hlaWdodF8xLmRlZmF1bHQoZWwsIGRlZmF1bHRWYWx1ZSk7XG4gICAgdmFyIGJUb3AgPSBwYXJzZUZsb2F0KGdldF9zdHlsZV8xLmRlZmF1bHQoZWwsICdib3JkZXJUb3BXaWR0aCcpKSB8fCAwO1xuICAgIHZhciBwVG9wID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAncGFkZGluZ1RvcCcpKSB8fCAwO1xuICAgIHZhciBwQm90dG9tID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAncGFkZGluZ0JvdHRvbScpKSB8fCAwO1xuICAgIHZhciBiQm90dG9tID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAnYm9yZGVyQm90dG9tV2lkdGgnKSkgfHwgMDtcbiAgICB2YXIgbVRvcCA9IHBhcnNlRmxvYXQoZ2V0X3N0eWxlXzEuZGVmYXVsdChlbCwgJ21hcmdpblRvcCcpKSB8fCAwO1xuICAgIHZhciBtQm90dG9tID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAnbWFyZ2luQm90dG9tJykpIHx8IDA7XG4gICAgcmV0dXJuIGhlaWdodCArIGJUb3AgKyBiQm90dG9tICsgcFRvcCArIHBCb3R0b20gKyBtVG9wICsgbUJvdHRvbTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGdldE91dGVySGVpZ2h0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW91dGVyLWhlaWdodC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBnZXRfc3R5bGVfMSA9IHJlcXVpcmUoXCIuL2dldC1zdHlsZVwiKTtcbnZhciBnZXRfd2lkdGhfMSA9IHJlcXVpcmUoXCIuL2dldC13aWR0aFwiKTtcbmZ1bmN0aW9uIGdldE91dGVyV2lkdGgoZWwsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHZhciB3aWR0aCA9IGdldF93aWR0aF8xLmRlZmF1bHQoZWwsIGRlZmF1bHRWYWx1ZSk7XG4gICAgdmFyIGJMZWZ0ID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAnYm9yZGVyTGVmdFdpZHRoJykpIHx8IDA7XG4gICAgdmFyIHBMZWZ0ID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAncGFkZGluZ0xlZnQnKSkgfHwgMDtcbiAgICB2YXIgcFJpZ2h0ID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAncGFkZGluZ1JpZ2h0JykpIHx8IDA7XG4gICAgdmFyIGJSaWdodCA9IHBhcnNlRmxvYXQoZ2V0X3N0eWxlXzEuZGVmYXVsdChlbCwgJ2JvcmRlclJpZ2h0V2lkdGgnKSkgfHwgMDtcbiAgICB2YXIgbVJpZ2h0ID0gcGFyc2VGbG9hdChnZXRfc3R5bGVfMS5kZWZhdWx0KGVsLCAnbWFyZ2luUmlnaHQnKSkgfHwgMDtcbiAgICB2YXIgbUxlZnQgPSBwYXJzZUZsb2F0KGdldF9zdHlsZV8xLmRlZmF1bHQoZWwsICdtYXJnaW5MZWZ0JykpIHx8IDA7XG4gICAgcmV0dXJuIHdpZHRoICsgYkxlZnQgKyBiUmlnaHQgKyBwTGVmdCArIHBSaWdodCArIG1MZWZ0ICsgbVJpZ2h0O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0T3V0ZXJXaWR0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1vdXRlci13aWR0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGdldFJhdGlvKCkge1xuICAgIHJldHVybiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyA/IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIDogMjtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGdldFJhdGlvO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXJhdGlvLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDojrflj5bmoLflvI9cbiAqIEBwYXJhbSAge09iamVjdH0gZG9tIERPTeiKgueCuVxuICogQHBhcmFtICB7U3RyaW5nfSBuYW1lIOagt+W8j+WQjVxuICogQHBhcmFtICB7QW55fSBkZWZhdWx0VmFsdWUg6buY6K6k5YC8XG4gKiBAcmV0dXJuIHtTdHJpbmd9IOWxnuaAp+WAvFxuICovXG5mdW5jdGlvbiBnZXRTdHlsZShkb20sIG5hbWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHZhciB2O1xuICAgIHRyeSB7XG4gICAgICAgIHYgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSA/XG4gICAgICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb20sIG51bGwpW25hbWVdIDpcbiAgICAgICAgICAgIGRvbS5zdHlsZVtuYW1lXTsgLy8g5LiA6Iis5LiN5Lya6LWw5Yiw6L+Z5Liq6YC76L6R77yMZG9tLnN0eWxlIOiOt+WPlueahOaYr+agh+etviBzdHlsZSDlsZ7mgKfvvIzkuZ/kuI3lh4bnoa5cbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gZG8gbm90aGluZ1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgdiA9IHYgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWx1ZSA6IHY7XG4gICAgfVxuICAgIHJldHVybiB2O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0U3R5bGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtc3R5bGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi9nZXQtc3R5bGVcIik7XG5mdW5jdGlvbiBnZXRIZWlnaHQoZWwsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHZhciB3aWR0aCA9IGdldF9zdHlsZV8xLmRlZmF1bHQoZWwsICd3aWR0aCcsIGRlZmF1bHRWYWx1ZSk7XG4gICAgaWYgKHdpZHRoID09PSAnYXV0bycpIHtcbiAgICAgICAgd2lkdGggPSBlbC5vZmZzZXRXaWR0aDtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQod2lkdGgpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0SGVpZ2h0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXdpZHRoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLy8gZG9tXG52YXIgYWRkX2V2ZW50X2xpc3RlbmVyXzEgPSByZXF1aXJlKFwiLi9hZGQtZXZlbnQtbGlzdGVuZXJcIik7XG5leHBvcnRzLmFkZEV2ZW50TGlzdGVuZXIgPSBhZGRfZXZlbnRfbGlzdGVuZXJfMS5kZWZhdWx0O1xudmFyIGNyZWF0ZV9kb21fMSA9IHJlcXVpcmUoXCIuL2NyZWF0ZS1kb21cIik7XG5leHBvcnRzLmNyZWF0ZURvbSA9IGNyZWF0ZV9kb21fMS5kZWZhdWx0O1xudmFyIGdldF9oZWlnaHRfMSA9IHJlcXVpcmUoXCIuL2dldC1oZWlnaHRcIik7XG5leHBvcnRzLmdldEhlaWdodCA9IGdldF9oZWlnaHRfMS5kZWZhdWx0O1xudmFyIGdldF9vdXRlcl9oZWlnaHRfMSA9IHJlcXVpcmUoXCIuL2dldC1vdXRlci1oZWlnaHRcIik7XG5leHBvcnRzLmdldE91dGVySGVpZ2h0ID0gZ2V0X291dGVyX2hlaWdodF8xLmRlZmF1bHQ7XG52YXIgZ2V0X291dGVyX3dpZHRoXzEgPSByZXF1aXJlKFwiLi9nZXQtb3V0ZXItd2lkdGhcIik7XG5leHBvcnRzLmdldE91dGVyV2lkdGggPSBnZXRfb3V0ZXJfd2lkdGhfMS5kZWZhdWx0O1xudmFyIGdldF9yYXRpb18xID0gcmVxdWlyZShcIi4vZ2V0LXJhdGlvXCIpO1xuZXhwb3J0cy5nZXRSYXRpbyA9IGdldF9yYXRpb18xLmRlZmF1bHQ7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi9nZXQtc3R5bGVcIik7XG5leHBvcnRzLmdldFN0eWxlID0gZ2V0X3N0eWxlXzEuZGVmYXVsdDtcbnZhciBnZXRfd2lkdGhfMSA9IHJlcXVpcmUoXCIuL2dldC13aWR0aFwiKTtcbmV4cG9ydHMuZ2V0V2lkdGggPSBnZXRfd2lkdGhfMS5kZWZhdWx0O1xudmFyIG1vZGlmeV9jc3NfMSA9IHJlcXVpcmUoXCIuL21vZGlmeS1jc3NcIik7XG5leHBvcnRzLm1vZGlmeUNTUyA9IG1vZGlmeV9jc3NfMS5kZWZhdWx0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiBtb2RpZnlDU1MoZG9tLCBjc3MpIHtcbiAgICBpZiAoZG9tKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBjc3MpIHtcbiAgICAgICAgICAgIGlmIChjc3MuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZVtrZXldID0gY3NzW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRvbTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IG1vZGlmeUNTUztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vZGlmeS1jc3MuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgV0lMRENBUkQgPSAnKic7XG4vKiBldmVudC1lbWl0dGVyICovXG52YXIgRXZlbnRFbWl0dGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOebkeWQrOS4gOS4quS6i+S7tlxuICAgICAqIEBwYXJhbSBldnRcbiAgICAgKiBAcGFyYW0gY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0gb25jZVxuICAgICAqL1xuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXZ0LCBjYWxsYmFjaywgb25jZSkge1xuICAgICAgICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdKSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZ0XSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2V2ZW50c1tldnRdLnB1c2goe1xuICAgICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgICAgICAgb25jZTogISFvbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnm5HlkKzkuIDkuKrkuovku7bkuIDmrKFcbiAgICAgKiBAcGFyYW0gZXZ0XG4gICAgICogQHBhcmFtIGNhbGxiYWNrXG4gICAgICovXG4gICAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gKGV2dCwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5vbihldnQsIGNhbGxiYWNrLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDop6blj5HkuIDkuKrkuovku7ZcbiAgICAgKiBAcGFyYW0gZXZ0XG4gICAgICogQHBhcmFtIGFyZ3NcbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBhcmdzW19pIC0gMV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbZXZ0XSB8fCBbXTtcbiAgICAgICAgdmFyIHdpbGRjYXJkRXZlbnRzID0gdGhpcy5fZXZlbnRzW1dJTERDQVJEXSB8fCBbXTtcbiAgICAgICAgLy8g5a6e6ZmF55qE5aSE55CGIGVtaXQg5pa55rOVXG4gICAgICAgIHZhciBkb0VtaXQgPSBmdW5jdGlvbiAoZXMpIHtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBlcy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlc1tpXSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIF9hID0gZXNbaV0sIGNhbGxiYWNrID0gX2EuY2FsbGJhY2ssIG9uY2UgPSBfYS5vbmNlO1xuICAgICAgICAgICAgICAgIGlmIChvbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIF90aGlzLl9ldmVudHNbZXZ0XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBsZW5ndGgtLTtcbiAgICAgICAgICAgICAgICAgICAgaS0tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjay5hcHBseShfdGhpcywgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGRvRW1pdChldmVudHMpO1xuICAgICAgICBkb0VtaXQod2lsZGNhcmRFdmVudHMpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Y+W5raI55uR5ZCs5LiA5Liq5LqL5Lu277yM5oiW6ICF5LiA5LiqY2hhbm5lbFxuICAgICAqIEBwYXJhbSBldnRcbiAgICAgKiBAcGFyYW0gY2FsbGJhY2tcbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICghZXZ0KSB7XG4gICAgICAgICAgICAvLyBldnQg5Li656m65YWo6YOo5riF6ZmkXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAvLyBldnQg5a2Y5Zyo77yMY2FsbGJhY2sg5Li656m677yM5riF6Zmk5LqL5Lu25omA5pyJ5pa55rOVXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1tldnRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZXZ0IOWtmOWcqO+8jGNhbGxiYWNrIOWtmOWcqO+8jOa4hemZpOWMuemFjeeahFxuICAgICAgICAgICAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbZXZ0XSB8fCBbXTtcbiAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoXzEgPSBldmVudHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoXzE7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnRzW2ldLmNhbGxiYWNrID09PSBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aF8xLS07XG4gICAgICAgICAgICAgICAgICAgICAgICBpLS07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1tldnRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qIOW9k+WJjeaJgOacieeahOS6i+S7tiAqL1xuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0RXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzO1xuICAgIH07XG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFdmVudEVtaXR0ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGV2ZW50X2VtaXR0ZXJfMSA9IHJlcXVpcmUoXCJAYW50di9ldmVudC1lbWl0dGVyXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgQmFzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhCYXNlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhc2UoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDmmK/lkKbooqvplIDmr4FcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICAgICAqL1xuICAgICAgICBfdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIGRlZmF1bHRDZmcgPSBfdGhpcy5nZXREZWZhdWx0Q2ZnKCk7XG4gICAgICAgIF90aGlzLmNmZyA9IHV0aWxfMS5taXgoZGVmYXVsdENmZywgY2ZnKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog6buY6K6k55qE6YWN572u6aG5XG4gICAgICogQHJldHVybnMge29iamVjdH0g6buY6K6k55qE6YWN572u6aG5XG4gICAgICovXG4gICAgQmFzZS5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+j55qE5pa55rOVXG4gICAgQmFzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2ZnW25hbWVdO1xuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+j55qE5pa55rOVXG4gICAgQmFzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuY2ZnW25hbWVdID0gdmFsdWU7XG4gICAgfTtcbiAgICAvLyDlrp7njrDmjqXlj6PnmoTmlrnms5VcbiAgICBCYXNlLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNmZyA9IHtcbiAgICAgICAgICAgIGRlc3Ryb3llZDogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vZmYoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgcmV0dXJuIEJhc2U7XG59KGV2ZW50X2VtaXR0ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRldGVjdF9icm93c2VyXzEgPSByZXF1aXJlKFwiZGV0ZWN0LWJyb3dzZXJcIik7XG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciB0aW1lbGluZV8xID0gcmVxdWlyZShcIi4uL2FuaW1hdGUvdGltZWxpbmVcIik7XG52YXIgZXZlbnRfY29udG9sbGVyXzEgPSByZXF1aXJlKFwiLi4vZXZlbnQvZXZlbnQtY29udG9sbGVyXCIpO1xudmFyIFBYX1NVRkZJWCA9ICdweCc7XG52YXIgYnJvd3NlciA9IGRldGVjdF9icm93c2VyXzEuZGV0ZWN0KCk7XG52YXIgaXNGaXJlZm94ID0gYnJvd3NlciAmJiBicm93c2VyLm5hbWUgPT09ICdmaXJlZm94JztcbnZhciBDYW52YXMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2FudmFzLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENhbnZhcyhjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5pbml0Q29udGFpbmVyKCk7XG4gICAgICAgIF90aGlzLmluaXREb20oKTtcbiAgICAgICAgX3RoaXMuaW5pdEV2ZW50cygpO1xuICAgICAgICBfdGhpcy5pbml0VGltZWxpbmUoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBDYW52YXMucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgLy8gc2V0IGRlZmF1bHQgY3Vyc29yIHN0eWxlIGZvciBjYW52YXNcbiAgICAgICAgY2ZnWydjdXJzb3InXSA9ICdkZWZhdWx0JztcbiAgICAgICAgLy8gQ1NTIHRyYW5zZm9ybSDnm67liY3lsJrmnKrnu4/ov4fplb/ml7bpl7Tpqozor4HvvIzkuLrkuobpgb/lhY3lvbHlk43kuIrlsYLkuJrliqHvvIzpu5jorqTlhbPpl63vvIzkuIrlsYLmjInpnIDlvIDlkK9cbiAgICAgICAgY2ZnWydzdXBwb3J0Q1NTVHJhbnNmb3JtJ10gPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGNmZztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDliJ3lp4vljJblrrnlmahcbiAgICAgKi9cbiAgICBDYW52YXMucHJvdG90eXBlLmluaXRDb250YWluZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcoY29udGFpbmVyKSkge1xuICAgICAgICAgICAgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoY29udGFpbmVyKTtcbiAgICAgICAgICAgIHRoaXMuc2V0KCdjb250YWluZXInLCBjb250YWluZXIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog5Yid5aeL5YyWIERPTVxuICAgICAqL1xuICAgIENhbnZhcy5wcm90b3R5cGUuaW5pdERvbSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5jcmVhdGVEb20oKTtcbiAgICAgICAgdGhpcy5zZXQoJ2VsJywgZWwpO1xuICAgICAgICAvLyDpmYTliqDliLDlrrnlmahcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgLy8g6K6+572u5Yid5aeL5a695bqmXG4gICAgICAgIHRoaXMuc2V0RE9NU2l6ZSh0aGlzLmdldCgnd2lkdGgnKSwgdGhpcy5nZXQoJ2hlaWdodCcpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDliJ3lp4vljJbnu5HlrprnmoTkuovku7ZcbiAgICAgKi9cbiAgICBDYW52YXMucHJvdG90eXBlLmluaXRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBldmVudENvbnRyb2xsZXIgPSBuZXcgZXZlbnRfY29udG9sbGVyXzEuZGVmYXVsdCh7XG4gICAgICAgICAgICBjYW52YXM6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICBldmVudENvbnRyb2xsZXIuaW5pdCgpO1xuICAgICAgICB0aGlzLnNldCgnZXZlbnRDb250cm9sbGVyJywgZXZlbnRDb250cm9sbGVyKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDliJ3lp4vljJbml7bpl7TovbRcbiAgICAgKi9cbiAgICBDYW52YXMucHJvdG90eXBlLmluaXRUaW1lbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpbWVsaW5lID0gbmV3IHRpbWVsaW5lXzEuZGVmYXVsdCh0aGlzKTtcbiAgICAgICAgdGhpcy5zZXQoJ3RpbWVsaW5lJywgdGltZWxpbmUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOS/ruaUueeUu+W4g+WvueW6lOeahCBET00g55qE5aSn5bCPXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoICDlrr3luqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IOmrmOW6plxuICAgICAqL1xuICAgIENhbnZhcy5wcm90b3R5cGUuc2V0RE9NU2l6ZSA9IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICBpZiAodXRpbF8xLmlzQnJvd3Nlcikge1xuICAgICAgICAgICAgZWwuc3R5bGUud2lkdGggPSB3aWR0aCArIFBYX1NVRkZJWDtcbiAgICAgICAgICAgIGVsLnN0eWxlLmhlaWdodCA9IGhlaWdodCArIFBYX1NVRkZJWDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+jXG4gICAgQ2FudmFzLnByb3RvdHlwZS5jaGFuZ2VTaXplID0gZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQpIHtcbiAgICAgICAgdGhpcy5zZXRET01TaXplKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICB0aGlzLnNldCgnd2lkdGgnLCB3aWR0aCk7XG4gICAgICAgIHRoaXMuc2V0KCdoZWlnaHQnLCBoZWlnaHQpO1xuICAgICAgICB0aGlzLm9uQ2FudmFzQ2hhbmdlKCdjaGFuZ2VTaXplJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blvZPliY3nmoTmuLLmn5PlvJXmk45cbiAgICAgKiBAcmV0dXJuIHtSZW5kZXJlcn0g6L+U5Zue5b2T5YmN55qE5riy5p+T5byV5pOOXG4gICAgICovXG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCdyZW5kZXJlcicpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W55S75biD55qEIGN1cnNvciDmoLflvI9cbiAgICAgKiBAcmV0dXJuIHtDdXJzb3J9XG4gICAgICovXG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRDdXJzb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnY3Vyc29yJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7nlLvluIPnmoQgY3Vyc29yIOagt+W8j1xuICAgICAqIEBwYXJhbSB7Q3Vyc29yfSBjdXJzb3IgIGN1cnNvciDmoLflvI9cbiAgICAgKi9cbiAgICBDYW52YXMucHJvdG90eXBlLnNldEN1cnNvciA9IGZ1bmN0aW9uIChjdXJzb3IpIHtcbiAgICAgICAgdGhpcy5zZXQoJ2N1cnNvcicsIGN1cnNvcik7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICBpZiAodXRpbF8xLmlzQnJvd3NlciAmJiBlbCkge1xuICAgICAgICAgICAgLy8g55u05o6l6K6+572u5qC35byP77yM5LiN562J5b6F6byg5qCH56e75Yqo5pe25YaN6K6+572uXG4gICAgICAgICAgICBlbC5zdHlsZS5jdXJzb3IgPSBjdXJzb3I7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOWunueOsOaOpeWPo1xuICAgIENhbnZhcy5wcm90b3R5cGUuZ2V0UG9pbnRCeUV2ZW50ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciBzdXBwb3J0Q1NTVHJhbnNmb3JtID0gdGhpcy5nZXQoJ3N1cHBvcnRDU1NUcmFuc2Zvcm0nKTtcbiAgICAgICAgaWYgKHN1cHBvcnRDU1NUcmFuc2Zvcm0pIHtcbiAgICAgICAgICAgIC8vIEZvciBGaXJlZm94IDw9IDM4XG4gICAgICAgICAgICBpZiAoaXNGaXJlZm94ICYmICF1dGlsXzEuaXNOaWwoZXYubGF5ZXJYKSAmJiBldi5sYXllclggIT09IGV2Lm9mZnNldFgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB4OiBldi5sYXllclgsXG4gICAgICAgICAgICAgICAgICAgIHk6IGV2LmxheWVyWSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoZXYub2Zmc2V0WCkpIHtcbiAgICAgICAgICAgICAgICAvLyBGb3IgSUU2KywgRmlyZWZveCA+PSAzOSwgQ2hyb21lLCBTYWZhcmksIE9wZXJhXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgeDogZXYub2Zmc2V0WCxcbiAgICAgICAgICAgICAgICAgICAgeTogZXYub2Zmc2V0WSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNob3VsZCBjYWxjdWxhdGUgYnkgc2VsZiBmb3Igb3RoZXIgY2FzZXMsIGxpa2UgU2FmYXJpIGluIGlvc1xuICAgICAgICAvLyBUT0RPOiBzdXBwb3J0IENTUyB0cmFuc2Zvcm1cbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRDbGllbnRCeUV2ZW50KGV2KSwgY2xpZW50WCA9IF9hLngsIGNsaWVudFkgPSBfYS55O1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQb2ludEJ5Q2xpZW50KGNsaWVudFgsIGNsaWVudFkpO1xuICAgIH07XG4gICAgLy8g6I635Y+WIHRvdWNoIOS6i+S7tueahCBjbGllbnRYIOWSjCBjbGllbnRZIOmcgOimgeWNleeLrOWkhOeQhlxuICAgIENhbnZhcy5wcm90b3R5cGUuZ2V0Q2xpZW50QnlFdmVudCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgY2xpZW50SW5mbyA9IGV2O1xuICAgICAgICBpZiAoZXYudG91Y2hlcykge1xuICAgICAgICAgICAgaWYgKGV2LnR5cGUgPT09ICd0b3VjaGVuZCcpIHtcbiAgICAgICAgICAgICAgICBjbGllbnRJbmZvID0gZXYuY2hhbmdlZFRvdWNoZXNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjbGllbnRJbmZvID0gZXYudG91Y2hlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogY2xpZW50SW5mby5jbGllbnRYLFxuICAgICAgICAgICAgeTogY2xpZW50SW5mby5jbGllbnRZLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+jXG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRQb2ludEJ5Q2xpZW50ID0gZnVuY3Rpb24gKGNsaWVudFgsIGNsaWVudFkpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHZhciBiYm94ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBjbGllbnRYIC0gYmJveC5sZWZ0LFxuICAgICAgICAgICAgeTogY2xpZW50WSAtIGJib3gudG9wLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+jXG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRDbGllbnRCeVBvaW50ID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHZhciBiYm94ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4ICsgYmJveC5sZWZ0LFxuICAgICAgICAgICAgeTogeSArIGJib3gudG9wLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+jXG4gICAgQ2FudmFzLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDplIDmr4EgRE9NIOWuueWZqFxuICAgICAqL1xuICAgIENhbnZhcy5wcm90b3R5cGUucmVtb3ZlRG9tID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog5riF55CG5omA5pyJ55qE5LqL5Lu2XG4gICAgICovXG4gICAgQ2FudmFzLnByb3RvdHlwZS5jbGVhckV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGV2ZW50Q29udHJvbGxlciA9IHRoaXMuZ2V0KCdldmVudENvbnRyb2xsZXInKTtcbiAgICAgICAgZXZlbnRDb250cm9sbGVyLmRlc3Ryb3koKTtcbiAgICB9O1xuICAgIENhbnZhcy5wcm90b3R5cGUuaXNDYW52YXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRQYXJlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgQ2FudmFzLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGltZWxpbmUgPSB0aGlzLmdldCgndGltZWxpbmUnKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdkZXN0cm95ZWQnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgLy8g5ZCM5Yid5aeL5YyW5pe255u45Y+N6aG65bqP6LCD55SoXG4gICAgICAgIGlmICh0aW1lbGluZSkge1xuICAgICAgICAgICAgLy8g55S75biD6ZSA5q+B5pe26Ieq5Yqo5YGc5q2i5Yqo55S7XG4gICAgICAgICAgICB0aW1lbGluZS5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhckV2ZW50cygpO1xuICAgICAgICB0aGlzLnJlbW92ZURvbSgpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIHJldHVybiBDYW52YXM7XG59KGNvbnRhaW5lcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IENhbnZhcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNhbnZhcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGVsZW1lbnRfMSA9IHJlcXVpcmUoXCIuL2VsZW1lbnRcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBTSEFQRV9NQVAgPSB7fTtcbnZhciBJTkRFWCA9ICdfSU5ERVgnO1xuZnVuY3Rpb24gYWZ0ZXJBZGQoZWxlbWVudCkge1xuICAgIGlmIChlbGVtZW50LmlzR3JvdXAoKSkge1xuICAgICAgICBpZiAoZWxlbWVudC5pc0VudGl0eUdyb3VwKCkgfHwgZWxlbWVudC5nZXQoJ2NoaWxkcmVuJykubGVuZ3RoKSB7XG4gICAgICAgICAgICBlbGVtZW50Lm9uQ2FudmFzQ2hhbmdlKCdhZGQnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5vbkNhbnZhc0NoYW5nZSgnYWRkJyk7XG4gICAgfVxufVxuLyoqXG4gKiDorr7nva4gY2FudmFzXG4gKiBAcGFyYW0ge0lFbGVtZW50fSBlbGVtZW50IOWFg+e0oFxuICogQHBhcmFtIHtJQ2FudmFzfSAgY2FudmFzICDnlLvluINcbiAqL1xuZnVuY3Rpb24gc2V0Q2FudmFzKGVsZW1lbnQsIGNhbnZhcykge1xuICAgIGVsZW1lbnQuc2V0KCdjYW52YXMnLCBjYW52YXMpO1xuICAgIGlmIChlbGVtZW50LmlzR3JvdXAoKSkge1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSBlbGVtZW50LmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBzZXRDYW52YXMoY2hpbGQsIGNhbnZhcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICog6K6+572uIHRpbWVsaW5lXG4gKiBAcGFyYW0ge0lFbGVtZW50fSBlbGVtZW50ICDlhYPntKBcbiAqIEBwYXJhbSB7VGltZWxpbmV9IHRpbWVsaW5lIOaXtumXtOi9tFxuICovXG5mdW5jdGlvbiBzZXRUaW1lbGluZShlbGVtZW50LCB0aW1lbGluZSkge1xuICAgIGVsZW1lbnQuc2V0KCd0aW1lbGluZScsIHRpbWVsaW5lKTtcbiAgICBpZiAoZWxlbWVudC5pc0dyb3VwKCkpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gZWxlbWVudC5nZXQoJ2NoaWxkcmVuJyk7XG4gICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZWxpbmUoY2hpbGQsIHRpbWVsaW5lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gY29udGFpbnMoY29udGFpbmVyLCBlbGVtZW50KSB7XG4gICAgdmFyIGNoaWxkcmVuID0gY29udGFpbmVyLmdldENoaWxkcmVuKCk7XG4gICAgcmV0dXJuIGNoaWxkcmVuLmluZGV4T2YoZWxlbWVudCkgPj0gMDtcbn1cbmZ1bmN0aW9uIHJlbW92ZUNoaWxkKGNvbnRhaW5lciwgZWxlbWVudCwgZGVzdHJveSkge1xuICAgIGlmIChkZXN0cm95ID09PSB2b2lkIDApIHsgZGVzdHJveSA9IHRydWU7IH1cbiAgICAvLyDkuI3lho3osIPnlKggZWxlbWVudC5yZW1vdmUoKSDmlrnms5XvvIzkvJrlh7rnjrDlvqrnjq/osIPnlKhcbiAgICBpZiAoZGVzdHJveSkge1xuICAgICAgICBlbGVtZW50LmRlc3Ryb3koKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuc2V0KCdwYXJlbnQnLCBudWxsKTtcbiAgICAgICAgZWxlbWVudC5zZXQoJ2NhbnZhcycsIG51bGwpO1xuICAgIH1cbiAgICB1dGlsXzEucmVtb3ZlRnJvbUFycmF5KGNvbnRhaW5lci5nZXRDaGlsZHJlbigpLCBlbGVtZW50KTtcbn1cbmZ1bmN0aW9uIGdldENvbXBhcmVyKGNvbXBhcmUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjb21wYXJlKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gMCA/IGxlZnRbSU5ERVhdIC0gcmlnaHRbSU5ERVhdIDogcmVzdWx0O1xuICAgIH07XG59XG52YXIgQ29udGFpbmVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbnRhaW5lciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDb250YWluZXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5pc0NhbnZhcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgLy8g5qC55o2u5a2Q6IqC54K556Gu5a6aIEJCb3hcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOaJgOacieeahOWAvOWPr+iDveWcqOeUu+W4g+eahOWPr+inhuWMuuWkllxuICAgICAgICB2YXIgbWluWCA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WCA9IC1JbmZpbml0eTtcbiAgICAgICAgdmFyIG1pblkgPSBJbmZpbml0eTtcbiAgICAgICAgdmFyIG1heFkgPSAtSW5maW5pdHk7XG4gICAgICAgIHZhciB4QXJyID0gW107XG4gICAgICAgIHZhciB5QXJyID0gW107XG4gICAgICAgIC8vIOWwhuWPr+ingeWFg+e0oOOAgeWbvuW9ouS7peWPiuS4jeS4uuepuueahOWbvuW9ouWIhue7hOetm+mAieWHuuadpe+8jOeUqOS6juWMheWbtOebkuWQiOW5tlxuICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmdldENoaWxkcmVuKCkuZmlsdGVyKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNoaWxkLmdldCgndmlzaWJsZScpICYmICghY2hpbGQuaXNHcm91cCgpIHx8IChjaGlsZC5pc0dyb3VwKCkgJiYgY2hpbGQuZ2V0Q2hpbGRyZW4oKS5sZW5ndGggPiAwKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgIHZhciBib3ggPSBjaGlsZC5nZXRCQm94KCk7XG4gICAgICAgICAgICAgICAgeEFyci5wdXNoKGJveC5taW5YLCBib3gubWF4WCk7XG4gICAgICAgICAgICAgICAgeUFyci5wdXNoKGJveC5taW5ZLCBib3gubWF4WSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1pblggPSBNYXRoLm1pbi5hcHBseShudWxsLCB4QXJyKTtcbiAgICAgICAgICAgIG1heFggPSBNYXRoLm1heC5hcHBseShudWxsLCB4QXJyKTtcbiAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbi5hcHBseShudWxsLCB5QXJyKTtcbiAgICAgICAgICAgIG1heFkgPSBNYXRoLm1heC5hcHBseShudWxsLCB5QXJyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG1pblggPSAwO1xuICAgICAgICAgICAgbWF4WCA9IDA7XG4gICAgICAgICAgICBtaW5ZID0gMDtcbiAgICAgICAgICAgIG1heFkgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBib3ggPSB7XG4gICAgICAgICAgICB4OiBtaW5YLFxuICAgICAgICAgICAgeTogbWluWSxcbiAgICAgICAgICAgIG1pblg6IG1pblgsXG4gICAgICAgICAgICBtaW5ZOiBtaW5ZLFxuICAgICAgICAgICAgbWF4WDogbWF4WCxcbiAgICAgICAgICAgIG1heFk6IG1heFksXG4gICAgICAgICAgICB3aWR0aDogbWF4WCAtIG1pblgsXG4gICAgICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYm94O1xuICAgIH07XG4gICAgLy8g6I635Y+W55S75biD55qE5YyF5Zu055uSXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRDYW52YXNCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWluWCA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WCA9IC1JbmZpbml0eTtcbiAgICAgICAgdmFyIG1pblkgPSBJbmZpbml0eTtcbiAgICAgICAgdmFyIG1heFkgPSAtSW5maW5pdHk7XG4gICAgICAgIHZhciB4QXJyID0gW107XG4gICAgICAgIHZhciB5QXJyID0gW107XG4gICAgICAgIC8vIOWwhuWPr+ingeWFg+e0oOOAgeWbvuW9ouS7peWPiuS4jeS4uuepuueahOWbvuW9ouWIhue7hOetm+mAieWHuuadpe+8jOeUqOS6juWMheWbtOebkuWQiOW5tlxuICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmdldENoaWxkcmVuKCkuZmlsdGVyKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNoaWxkLmdldCgndmlzaWJsZScpICYmICghY2hpbGQuaXNHcm91cCgpIHx8IChjaGlsZC5pc0dyb3VwKCkgJiYgY2hpbGQuZ2V0Q2hpbGRyZW4oKS5sZW5ndGggPiAwKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgIHZhciBib3ggPSBjaGlsZC5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgICAgICAgICAgeEFyci5wdXNoKGJveC5taW5YLCBib3gubWF4WCk7XG4gICAgICAgICAgICAgICAgeUFyci5wdXNoKGJveC5taW5ZLCBib3gubWF4WSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1pblggPSBNYXRoLm1pbi5hcHBseShudWxsLCB4QXJyKTtcbiAgICAgICAgICAgIG1heFggPSBNYXRoLm1heC5hcHBseShudWxsLCB4QXJyKTtcbiAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbi5hcHBseShudWxsLCB5QXJyKTtcbiAgICAgICAgICAgIG1heFkgPSBNYXRoLm1heC5hcHBseShudWxsLCB5QXJyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG1pblggPSAwO1xuICAgICAgICAgICAgbWF4WCA9IDA7XG4gICAgICAgICAgICBtaW5ZID0gMDtcbiAgICAgICAgICAgIG1heFkgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBib3ggPSB7XG4gICAgICAgICAgICB4OiBtaW5YLFxuICAgICAgICAgICAgeTogbWluWSxcbiAgICAgICAgICAgIG1pblg6IG1pblgsXG4gICAgICAgICAgICBtaW5ZOiBtaW5ZLFxuICAgICAgICAgICAgbWF4WDogbWF4WCxcbiAgICAgICAgICAgIG1heFk6IG1heFksXG4gICAgICAgICAgICB3aWR0aDogbWF4WCAtIG1pblgsXG4gICAgICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYm94O1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIGNmZ1snY2hpbGRyZW4nXSA9IFtdO1xuICAgICAgICByZXR1cm4gY2ZnO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIG9yaWdpblZhbHVlKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25BdHRyQ2hhbmdlLmNhbGwodGhpcywgbmFtZSwgdmFsdWUsIG9yaWdpblZhbHVlKTtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdtYXRyaXgnKSB7XG4gICAgICAgICAgICB2YXIgdG90YWxNYXRyaXggPSB0aGlzLmdldFRvdGFsTWF0cml4KCk7XG4gICAgICAgICAgICB0aGlzLl9hcHBseUNoaWxkcmVuTWFyaXgodG90YWxNYXRyaXgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDkuI3kvYblupTnlKjliLDoh6rlt7HouqvkuIrov5jopoHlupTnlKjkuo7lrZDlhYPntKBcbiAgICBDb250YWluZXIucHJvdG90eXBlLmFwcGx5TWF0cml4ID0gZnVuY3Rpb24gKG1hdHJpeCkge1xuICAgICAgICB2YXIgcHJlVG90YWxNYXRyaXggPSB0aGlzLmdldFRvdGFsTWF0cml4KCk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYXBwbHlNYXRyaXguY2FsbCh0aGlzLCBtYXRyaXgpO1xuICAgICAgICB2YXIgdG90YWxNYXRyaXggPSB0aGlzLmdldFRvdGFsTWF0cml4KCk7XG4gICAgICAgIC8vIHRvdGFsTWF0cml4IOayoeacieWPkeeUn+WPmOWMluaXtu+8jOi/memHjOS7heiAg+iZkeS4pOiAhemDveS4uiBudWxsIOaXtlxuICAgICAgICAvLyDkuI3nu6fnu63lkJHkuIvkvKDpgJLnn6npmLVcbiAgICAgICAgaWYgKHRvdGFsTWF0cml4ID09PSBwcmVUb3RhbE1hdHJpeCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FwcGx5Q2hpbGRyZW5NYXJpeCh0b3RhbE1hdHJpeCk7XG4gICAgfTtcbiAgICAvLyDlnKjlrZDlhYPntKDkuIrorr7nva7nn6npmLVcbiAgICBDb250YWluZXIucHJvdG90eXBlLl9hcHBseUNoaWxkcmVuTWFyaXggPSBmdW5jdGlvbiAodG90YWxNYXRyaXgpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICB1dGlsXzEuZWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICBjaGlsZC5hcHBseU1hdHJpeCh0b3RhbE1hdHJpeCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g5YW85a656ICB54mI5pys55qE5o6l5Y+jXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hZGRTaGFwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHlwZSA9IGFyZ3NbMF07XG4gICAgICAgIHZhciBjZmcgPSBhcmdzWzFdO1xuICAgICAgICBpZiAodXRpbF8xLmlzT2JqZWN0KHR5cGUpKSB7XG4gICAgICAgICAgICBjZmcgPSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2ZnWyd0eXBlJ10gPSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzaGFwZVR5cGUgPSBTSEFQRV9NQVBbY2ZnLnR5cGVdO1xuICAgICAgICBpZiAoIXNoYXBlVHlwZSkge1xuICAgICAgICAgICAgc2hhcGVUeXBlID0gdXRpbF8xLnVwcGVyRmlyc3QoY2ZnLnR5cGUpO1xuICAgICAgICAgICAgU0hBUEVfTUFQW2NmZy50eXBlXSA9IHNoYXBlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgU2hhcGVCYXNlID0gdGhpcy5nZXRTaGFwZUJhc2UoKTtcbiAgICAgICAgdmFyIHNoYXBlID0gbmV3IFNoYXBlQmFzZVtzaGFwZVR5cGVdKGNmZyk7XG4gICAgICAgIHRoaXMuYWRkKHNoYXBlKTtcbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hZGRHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZ3JvdXBDbGFzcyA9IGFyZ3NbMF0sIGNmZyA9IGFyZ3NbMV07XG4gICAgICAgIHZhciBncm91cDtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGdyb3VwQ2xhc3MpKSB7XG4gICAgICAgICAgICBpZiAoY2ZnKSB7XG4gICAgICAgICAgICAgICAgZ3JvdXAgPSBuZXcgZ3JvdXBDbGFzcyhjZmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZ3JvdXAgPSBuZXcgZ3JvdXBDbGFzcyh7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNhbnZhcyxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiB0aGlzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRtcENmZyA9IGdyb3VwQ2xhc3MgfHwge307XG4gICAgICAgICAgICB2YXIgVG1wR3JvdXBDbGFzcyA9IHRoaXMuZ2V0R3JvdXBCYXNlKCk7XG4gICAgICAgICAgICBncm91cCA9IG5ldyBUbXBHcm91cENsYXNzKHRtcENmZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGQoZ3JvdXApO1xuICAgICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldENhbnZhcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcztcbiAgICAgICAgaWYgKHRoaXMuaXNDYW52YXMoKSkge1xuICAgICAgICAgICAgY2FudmFzID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNhbnZhcyA9IHRoaXMuZ2V0KCdjYW52YXMnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FudmFzO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRTaGFwZSA9IGZ1bmN0aW9uICh4LCB5LCBldikge1xuICAgICAgICAvLyDlpoLmnpzkuI3mlK/mjIHmi77lj5bvvIzliJnnm7TmjqXov5Tlm55cbiAgICAgICAgaWYgKCF1dGlsXzEuaXNBbGxvd0NhcHR1cmUodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgdmFyIHNoYXBlO1xuICAgICAgICAvLyDlpoLmnpzlrrnlmajmmK8gZ3JvdXBcbiAgICAgICAgaWYgKCF0aGlzLmlzQ2FudmFzKCkpIHtcbiAgICAgICAgICAgIHZhciB2ID0gW3gsIHksIDFdO1xuICAgICAgICAgICAgLy8g5bCGIHgsIHkg6L2s5o2i5oiQ5a+55bqU5LqOIGdyb3VwIOeahOWxgOmDqOWdkOagh1xuICAgICAgICAgICAgdiA9IHRoaXMuaW52ZXJ0RnJvbU1hdHJpeCh2KTtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0NsaXBwZWQodlswXSwgdlsxXSkpIHtcbiAgICAgICAgICAgICAgICBzaGFwZSA9IHRoaXMuX2ZpbmRTaGFwZShjaGlsZHJlbiwgdlswXSwgdlsxXSwgZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc2hhcGUgPSB0aGlzLl9maW5kU2hhcGUoY2hpbGRyZW4sIHgsIHksIGV2KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLl9maW5kU2hhcGUgPSBmdW5jdGlvbiAoY2hpbGRyZW4sIHgsIHksIGV2KSB7XG4gICAgICAgIHZhciBzaGFwZSA9IG51bGw7XG4gICAgICAgIGZvciAodmFyIGkgPSBjaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzQWxsb3dDYXB0dXJlKGNoaWxkKSkge1xuICAgICAgICAgICAgICAgIGlmIChjaGlsZC5pc0dyb3VwKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSBjaGlsZC5nZXRTaGFwZSh4LCB5LCBldik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkLmlzSGl0KHgsIHkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNoYXBlID0gY2hpbGQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNoYXBlKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgY2FudmFzID0gdGhpcy5nZXRDYW52YXMoKTtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICB2YXIgdGltZWxpbmUgPSB0aGlzLmdldCgndGltZWxpbmUnKTtcbiAgICAgICAgdmFyIHByZVBhcmVudCA9IGVsZW1lbnQuZ2V0UGFyZW50KCk7XG4gICAgICAgIGlmIChwcmVQYXJlbnQpIHtcbiAgICAgICAgICAgIHJlbW92ZUNoaWxkKHByZVBhcmVudCwgZWxlbWVudCwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnQuc2V0KCdwYXJlbnQnLCB0aGlzKTtcbiAgICAgICAgaWYgKGNhbnZhcykge1xuICAgICAgICAgICAgc2V0Q2FudmFzKGVsZW1lbnQsIGNhbnZhcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbWVsaW5lKSB7XG4gICAgICAgICAgICBzZXRUaW1lbGluZShlbGVtZW50LCB0aW1lbGluZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2hpbGRyZW4ucHVzaChlbGVtZW50KTtcbiAgICAgICAgYWZ0ZXJBZGQoZWxlbWVudCk7XG4gICAgICAgIHRoaXMuX2FwcGx5RWxlbWVudE1hdHJpeChlbGVtZW50KTtcbiAgICB9O1xuICAgIC8vIOWwhuW9k+WJjeWuueWZqOeahOefqemYteW6lOeUqOWIsOWtkOWFg+e0oFxuICAgIENvbnRhaW5lci5wcm90b3R5cGUuX2FwcGx5RWxlbWVudE1hdHJpeCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciB0b3RhbE1hdHJpeCA9IHRoaXMuZ2V0VG90YWxNYXRyaXgoKTtcbiAgICAgICAgLy8g5re75Yqg5Zu+5b2i5oiW6ICF5YiG57uE5pe277yM6ZyA6KaB5oqK5b2T5YmN5Zu+5YWD55qE55+p6Zi16K6+572u6L+b5Y67XG4gICAgICAgIGlmICh0b3RhbE1hdHJpeCkge1xuICAgICAgICAgICAgZWxlbWVudC5hcHBseU1hdHJpeCh0b3RhbE1hdHJpeCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0Q2hpbGRyZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnY2hpbGRyZW4nKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICAvLyDnqLPlrprmjpLluo9cbiAgICAgICAgdXRpbF8xLmVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCwgaW5kZXgpIHtcbiAgICAgICAgICAgIGNoaWxkW0lOREVYXSA9IGluZGV4O1xuICAgICAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgICB9KTtcbiAgICAgICAgY2hpbGRyZW4uc29ydChnZXRDb21wYXJlcihmdW5jdGlvbiAob2JqMSwgb2JqMikge1xuICAgICAgICAgICAgcmV0dXJuIG9iajEuZ2V0KCd6SW5kZXgnKSAtIG9iajIuZ2V0KCd6SW5kZXgnKTtcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLm9uQ2FudmFzQ2hhbmdlKCdzb3J0Jyk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldCgnY2xlYXJpbmcnLCB0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICBmb3IgKHZhciBpID0gY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuW2ldLmRlc3Ryb3koKTsgLy8g6ZSA5q+B5a2Q5YWD57SgXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ2NoaWxkcmVuJywgW10pO1xuICAgICAgICB0aGlzLm9uQ2FudmFzQ2hhbmdlKCdjbGVhcicpO1xuICAgICAgICB0aGlzLnNldCgnY2xlYXJpbmcnLCBmYWxzZSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmdldCgnZGVzdHJveWVkJykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W56ys5LiA5Liq5a2Q5YWD57SgXG4gICAgICogQHJldHVybiB7SUVsZW1lbnR9IOesrOS4gOS4quWFg+e0oFxuICAgICAqL1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0Rmlyc3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldENoaWxkQnlJbmRleCgwKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluacgOWQjuS4gOS4quWtkOWFg+e0oFxuICAgICAqIEByZXR1cm4ge0lFbGVtZW50fSDlhYPntKBcbiAgICAgKi9cbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldExhc3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2hpbGRCeUluZGV4KGNoaWxkcmVuLmxlbmd0aCAtIDEpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5qC55o2u57Si5byV6I635Y+W5a2Q5YWD57SgXG4gICAgICogQHJldHVybiB7SUVsZW1lbnR9IOesrOS4gOS4quWFg+e0oFxuICAgICAqL1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0Q2hpbGRCeUluZGV4ID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuW2luZGV4XTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWtkOWFg+e0oOeahOaVsOmHj1xuICAgICAqIEByZXR1cm4ge251bWJlcn0g5a2Q5YWD57Sg5pWw6YePXG4gICAgICovXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRDb3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICByZXR1cm4gY2hpbGRyZW4ubGVuZ3RoO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm5YyF5ZCr5a+55bqU5YWD57SgXG4gICAgICogQHBhcmFtIHtJRWxlbWVudH0gZWxlbWVudCDlhYPntKBcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuY29udGFpbiA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuLmluZGV4T2YoZWxlbWVudCkgPiAtMTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOenu+mZpOWvueW6lOWtkOWFg+e0oFxuICAgICAqIEBwYXJhbSB7SUVsZW1lbnR9IGVsZW1lbnQg5a2Q5YWD57SgXG4gICAgICogQHBhcmFtIHtib29sZWFufSBkZXN0cm95IOaYr+WQpumUgOavgeWtkOWFg+e0oO+8jOm7mOiupOS4uiB0cnVlXG4gICAgICovXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uIChlbGVtZW50LCBkZXN0cm95KSB7XG4gICAgICAgIGlmIChkZXN0cm95ID09PSB2b2lkIDApIHsgZGVzdHJveSA9IHRydWU7IH1cbiAgICAgICAgaWYgKHRoaXMuY29udGFpbihlbGVtZW50KSkge1xuICAgICAgICAgICAgZWxlbWVudC5yZW1vdmUoZGVzdHJveSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOafpeaJvuaJgOacieWMuemFjeeahOWFg+e0oFxuICAgICAqIEBwYXJhbSAge0VsZW1lbnRGaWx0ZXJGbn0gICBmbiAg5Yy56YWN5Ye95pWwXG4gICAgICogQHJldHVybiB7SUVsZW1lbnRbXX0g5YWD57Sg5pWw57uEXG4gICAgICovXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5maW5kQWxsID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHZhciByc3QgPSBbXTtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICB1dGlsXzEuZWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmIChmbihlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHJzdC5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuaXNHcm91cCgpKSB7XG4gICAgICAgICAgICAgICAgcnN0ID0gcnN0LmNvbmNhdChlbGVtZW50LmZpbmRBbGwoZm4pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmn6Xmib7lhYPntKDvvIzmib7liLDnrKzkuIDkuKrov5Tlm55cbiAgICAgKiBAcGFyYW0gIHtFbGVtZW50RmlsdGVyRm59IGZuICAgIOWMuemFjeWHveaVsFxuICAgICAqIEByZXR1cm4ge0lFbGVtZW50fG51bGx9IOWFg+e0oO+8jOWPr+S7peS4uuepulxuICAgICAqL1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICB2YXIgcnN0ID0gbnVsbDtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbigpO1xuICAgICAgICB1dGlsXzEuZWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmIChmbihlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHJzdCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChlbGVtZW50LmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgICAgIHJzdCA9IGVsZW1lbnQuZmluZChmbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocnN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNriBJRCDmn6Xmib7lhYPntKBcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQg5YWD57SgIGlkXG4gICAgICogQHJldHVybiB7SUVsZW1lbnR8bnVsbH0g5YWD57SgXG4gICAgICovXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5maW5kQnlJZCA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5maW5kKGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudC5nZXQoJ2lkJykgPT09IGlkO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOivpeaWueazleWNs+WwhuW6n+W8g++8jOS4jeW7uuiuruS9v+eUqFxuICAgICAqIOagueaNriBjbGFzc05hbWUg5p+l5om+5YWD57SgXG4gICAgICogVE9ETzog6K+l5pa55byP5a6a5LmJ5pqC5pe25Y+q57uZIEc2IDMuMyDku6XlkI7nmoTniYjmnKzkvb/nlKjvvIzlvoUgRzYg5Lit55qEIGZpbmRCeUNsYXNzTmFtZSDmlrnms5Xnp7vpmaTlkI7vvIxHIOS5n+mcgOimgeWQjOatpeenu+mZpFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWUg5YWD57SgIGNsYXNzTmFtZVxuICAgICAqIEByZXR1cm4ge0lFbGVtZW50IHwgbnVsbH0g5YWD57SgXG4gICAgICovXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5maW5kQnlDbGFzc05hbWUgPSBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZpbmQoZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmdldCgnY2xhc3NOYW1lJykgPT09IGNsYXNzTmFtZTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmoLnmja4gbmFtZSDmn6Xmib7lhYPntKDliJfooahcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gICAgICBuYW1lIOWFg+e0oOWQjeensFxuICAgICAqIEByZXR1cm4ge0lFbGVtZW50W119IOWFg+e0oFxuICAgICAqL1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZmluZEFsbEJ5TmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZpbmRBbGwoZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmdldCgnbmFtZScpID09PSBuYW1lO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBDb250YWluZXI7XG59KGVsZW1lbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDb250YWluZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb250YWluZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgbWF0cml4XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9tYXRyaXhcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBNQVRSSVggPSAnbWF0cml4JztcbnZhciBDTE9ORV9DRkdTID0gWyd6SW5kZXgnLCAnY2FwdHVyZScsICd2aXNpYmxlJywgJ3R5cGUnXTtcbi8vIOWPr+S7peWcqCB0b0F0dHJzIOS4reiuvue9ru+8jOS9huS4jeWxnuS6jue7mOWbvuWxnuaAp+eahOWtl+autVxudmFyIFJFU0VSVkVEX1BPUlBTID0gWydyZXBlYXQnXTtcbnZhciBERUxFR0FUSU9OX1NQTElUID0gJzonO1xudmFyIFdJTERDQVJEID0gJyonO1xuLy8g6ZyA6KaB6ICD6JmR5pWw57uE5bWM5aWX5pWw57uE55qE5Zy65pmvXG4vLyDmlbDnu4TltYzlpZflr7nosaHnmoTlnLrmma/kuI3ogIPomZFcbmZ1bmN0aW9uIF9jbG9uZUFycmF5QXR0cihhcnIpIHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KGFycltpXSkpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtdLmNvbmNhdChhcnJbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGFycltpXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGdldEZvcm1hdEZyb21BdHRycyh0b0F0dHJzLCBzaGFwZSkge1xuICAgIHZhciBmcm9tQXR0cnMgPSB7fTtcbiAgICB2YXIgYXR0cnMgPSBzaGFwZS5hdHRycztcbiAgICBmb3IgKHZhciBrIGluIHRvQXR0cnMpIHtcbiAgICAgICAgZnJvbUF0dHJzW2tdID0gYXR0cnNba107XG4gICAgfVxuICAgIHJldHVybiBmcm9tQXR0cnM7XG59XG5mdW5jdGlvbiBnZXRGb3JtYXRUb0F0dHJzKHByb3BzLCBzaGFwZSkge1xuICAgIHZhciB0b0F0dHJzID0ge307XG4gICAgdmFyIGF0dHJzID0gc2hhcGUuYXR0cigpO1xuICAgIHV0aWxfMS5lYWNoKHByb3BzLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICBpZiAoUkVTRVJWRURfUE9SUFMuaW5kZXhPZihrKSA9PT0gLTEgJiYgIXV0aWxfMS5pc0VxdWFsKGF0dHJzW2tdLCB2KSkge1xuICAgICAgICAgICAgdG9BdHRyc1trXSA9IHY7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdG9BdHRycztcbn1cbmZ1bmN0aW9uIGNoZWNrRXhpc3RlZEF0dHJzKGFuaW1hdGlvbnMsIGFuaW1hdGlvbikge1xuICAgIGlmIChhbmltYXRpb24ub25GcmFtZSkge1xuICAgICAgICByZXR1cm4gYW5pbWF0aW9ucztcbiAgICB9XG4gICAgdmFyIHN0YXJ0VGltZSA9IGFuaW1hdGlvbi5zdGFydFRpbWUsIGRlbGF5ID0gYW5pbWF0aW9uLmRlbGF5LCBkdXJhdGlvbiA9IGFuaW1hdGlvbi5kdXJhdGlvbjtcbiAgICB2YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuICAgIHV0aWxfMS5lYWNoKGFuaW1hdGlvbnMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIC8vIOWQjuS4gOS4quWKqOeUu+W8gOWni+aJp+ihjOeahOaXtumXtCA8IOWJjeS4gOS4quWKqOeUu+eahOe7k+adn+aXtumXtCAmJiDlkI7kuIDkuKrliqjnlLvnmoTmiafooYzml7bpl7QgPiDliY3kuIDkuKrliqjnlLvnmoTlu7bov59cbiAgICAgICAgaWYgKHN0YXJ0VGltZSArIGRlbGF5IDwgaXRlbS5zdGFydFRpbWUgKyBpdGVtLmRlbGF5ICsgaXRlbS5kdXJhdGlvbiAmJiBkdXJhdGlvbiA+IGl0ZW0uZGVsYXkpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGFuaW1hdGlvbi50b0F0dHJzLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGl0ZW0udG9BdHRycywgaykpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGl0ZW0udG9BdHRyc1trXTtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGl0ZW0uZnJvbUF0dHJzW2tdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGFuaW1hdGlvbnM7XG59XG52YXIgRWxlbWVudCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGVtZW50LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEVsZW1lbnQoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgICog5Zu+5b2i5bGe5oCnXG4gICAgICAgICAqIEB0eXBlIHtTaGFwZUF0dHJzfVxuICAgICAgICAgKi9cbiAgICAgICAgX3RoaXMuYXR0cnMgPSB7fTtcbiAgICAgICAgdmFyIGF0dHJzID0gX3RoaXMuZ2V0RGVmYXVsdEF0dHJzKCk7XG4gICAgICAgIHV0aWxfMS5taXgoYXR0cnMsIGNmZy5hdHRycyk7XG4gICAgICAgIF90aGlzLmF0dHJzID0gYXR0cnM7XG4gICAgICAgIF90aGlzLmluaXRBdHRycyhhdHRycyk7XG4gICAgICAgIF90aGlzLmluaXRBbmltYXRlKCk7IC8vIOWIneWni+WMluWKqOeUu1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8vIG92ZXJyaWRlXG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICBjYXB0dXJlOiB0cnVlLFxuICAgICAgICAgICAgekluZGV4OiAwLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOiOt+WPlum7mOiupOeahOWxnuebuFxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmdldERlZmF1bHRBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1hdHJpeDogdGhpcy5nZXREZWZhdWx0TWF0cml4KCksXG4gICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOS4gOS6m+aWueazleiwg+eUqOS8muW8lei1t+eUu+W4g+WPmOWMllxuICAgICAqIEBwYXJhbSB7Q2hhbmdlVHlwZX0gY2hhbmdlVHlwZSDmlLnlj5jnmoTnsbvlnotcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5vbkNhbnZhc0NoYW5nZSA9IGZ1bmN0aW9uIChjaGFuZ2VUeXBlKSB7IH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOWIneWni+WMluWxnuaAp++8jOacieS6m+WxnuaAp+mcgOimgeWKoOW3pVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBhdHRycyDlsZ7mgKflgLxcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5pbml0QXR0cnMgPSBmdW5jdGlvbiAoYXR0cnMpIHsgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog5Yid5aeL5YyW5Yqo55S7XG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuaW5pdEFuaW1hdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0KCdhbmltYWJsZScsIHRydWUpO1xuICAgICAgICB0aGlzLnNldCgnYW5pbWF0aW5nJywgZmFsc2UpO1xuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUuaXNHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0UGFyZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoJ3BhcmVudCcpO1xuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0Q2FudmFzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoJ2NhbnZhcycpO1xuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUuYXR0ciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgYXJncyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgYXJnc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuYW1lID0gYXJnc1swXSwgdmFsdWUgPSBhcmdzWzFdO1xuICAgICAgICBpZiAoIW5hbWUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdHRycztcbiAgICAgICAgaWYgKHV0aWxfMS5pc09iamVjdChuYW1lKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgayBpbiBuYW1lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyKGssIG5hbWVba10pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hZnRlckF0dHJzQ2hhbmdlKG5hbWUpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICB0aGlzLnNldEF0dHIobmFtZSwgdmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5hZnRlckF0dHJzQ2hhbmdlKChfYSA9IHt9LFxuICAgICAgICAgICAgICAgIF9hW25hbWVdID0gdmFsdWUsXG4gICAgICAgICAgICAgICAgX2EpKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmF0dHJzW25hbWVdO1xuICAgIH07XG4gICAgLy8g5piv5ZCm6KKr6KOB5Ymq77yM6KKr6KOB5Ymq5YiZ5LiN5pi+56S677yM5LiN5Y+C5LiO5ou+5Y+WXG4gICAgRWxlbWVudC5wcm90b3R5cGUuaXNDbGlwcGVkID0gZnVuY3Rpb24gKHJlZlgsIHJlZlkpIHtcbiAgICAgICAgdmFyIGNsaXAgPSB0aGlzLmdldENsaXAoKTtcbiAgICAgICAgcmV0dXJuIGNsaXAgJiYgIWNsaXAuaXNIaXQocmVmWCwgcmVmWSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlhoXpg6jorr7nva7lsZ7mgKflgLznmoTmjqXlj6NcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSDlsZ7mgKflkI1cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsdWUg5bGe5oCn5YC8XG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0ciA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgICAgICB2YXIgb3JpZ2luVmFsdWUgPSB0aGlzLmF0dHJzW25hbWVdO1xuICAgICAgICBpZiAob3JpZ2luVmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmF0dHJzW25hbWVdID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLm9uQXR0ckNoYW5nZShuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog5bGe5oCn5YC85Y+R55Sf5pS55Y+YXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUg5bGe5oCn5ZCNXG4gICAgICogQHBhcmFtIHthbnl9IHZhbHVlIOWxnuaAp+WAvFxuICAgICAqIEBwYXJhbSB7YW55fSBvcmlnaW5WYWx1ZSDlsZ7mgKflgLxcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIG9yaWdpblZhbHVlKSB7XG4gICAgICAgIGlmIChuYW1lID09PSAnbWF0cml4Jykge1xuICAgICAgICAgICAgdGhpcy5zZXQoJ3RvdGFsTWF0cml4JywgbnVsbCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWxnuaAp+abtOaUueWQjumcgOimgeWBmueahOS6i+aDhVxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5hZnRlckF0dHJzQ2hhbmdlID0gZnVuY3Rpb24gKHRhcmdldEF0dHJzKSB7XG4gICAgICAgIHRoaXMub25DYW52YXNDaGFuZ2UoJ2F0dHInKTtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOS4jeaYr+mrmOmikeaTjeS9nOebtOaOpeS9v+eUqCBzZXRcbiAgICAgICAgdGhpcy5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5vbkNhbnZhc0NoYW5nZSgnc2hvdycpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOS4jeaYr+mrmOmikeaTjeS9nOebtOaOpeS9v+eUqCBzZXRcbiAgICAgICAgdGhpcy5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMub25DYW52YXNDaGFuZ2UoJ2hpZGUnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBFbGVtZW50LnByb3RvdHlwZS5zZXRaSW5kZXggPSBmdW5jdGlvbiAoekluZGV4KSB7XG4gICAgICAgIHRoaXMuc2V0KCd6SW5kZXgnLCB6SW5kZXgpO1xuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy5nZXRQYXJlbnQoKTtcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgLy8g5pS55Y+YIHpJbmRleCDkuI3lupTor6Xnq4vljbPop6blj5HmuLLmn5MgKOiwg+eUqCBvbkNhbnZhc0NoYW5nZSgnekluZGV4Jykp77yM6ZyA6KaB57uP6L+HIHNvcnQg5YaN6Kem5Y+RXG4gICAgICAgICAgICBwYXJlbnQuc29ydCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUudG9Gcm9udCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KCk7XG4gICAgICAgIGlmICghcGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoaWxkcmVuID0gcGFyZW50LmdldENoaWxkcmVuKCk7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB2YXIgaW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKHRoaXMpO1xuICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBjaGlsZHJlbi5wdXNoKHRoaXMpO1xuICAgICAgICB0aGlzLm9uQ2FudmFzQ2hhbmdlKCd6SW5kZXgnKTtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnRvQmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KCk7XG4gICAgICAgIGlmICghcGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNoaWxkcmVuID0gcGFyZW50LmdldENoaWxkcmVuKCk7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB2YXIgaW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKHRoaXMpO1xuICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBjaGlsZHJlbi51bnNoaWZ0KHRoaXMpO1xuICAgICAgICB0aGlzLm9uQ2FudmFzQ2hhbmdlKCd6SW5kZXgnKTtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChkZXN0cm95KSB7XG4gICAgICAgIGlmIChkZXN0cm95ID09PSB2b2lkIDApIHsgZGVzdHJveSA9IHRydWU7IH1cbiAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KCk7XG4gICAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgICAgIHV0aWxfMi5yZW1vdmVGcm9tQXJyYXkocGFyZW50LmdldENoaWxkcmVuKCksIHRoaXMpO1xuICAgICAgICAgICAgaWYgKCFwYXJlbnQuZ2V0KCdjbGVhcmluZycpKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c54i25YWD57Sg5q2j5Zyo5riF55CG77yM5b2T5YmN5YWD57Sg5LiN6Kem5Y+RIHJlbW92ZVxuICAgICAgICAgICAgICAgIHRoaXMub25DYW52YXNDaGFuZ2UoJ3JlbW92ZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vbkNhbnZhc0NoYW5nZSgncmVtb3ZlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlc3Ryb3kpIHtcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBFbGVtZW50LnByb3RvdHlwZS5yZXNldE1hdHJpeCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdHRyKE1BVFJJWCwgdGhpcy5nZXREZWZhdWx0TWF0cml4KCkpO1xuICAgICAgICB0aGlzLm9uQ2FudmFzQ2hhbmdlKCdtYXRyaXgnKTtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmdldE1hdHJpeCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXR0cihNQVRSSVgpO1xuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUuc2V0TWF0cml4ID0gZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgdGhpcy5hdHRyKE1BVFJJWCwgbSk7XG4gICAgICAgIHRoaXMub25DYW52YXNDaGFuZ2UoJ21hdHJpeCcpO1xuICAgIH07XG4gICAgLy8g6I635Y+W5oC755qEIG1hdHJpeFxuICAgIEVsZW1lbnQucHJvdG90eXBlLmdldFRvdGFsTWF0cml4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdG90YWxNYXRyaXggPSB0aGlzLmdldCgndG90YWxNYXRyaXgnKTtcbiAgICAgICAgaWYgKCF0b3RhbE1hdHJpeCkge1xuICAgICAgICAgICAgdmFyIGN1cnJlbnRNYXRyaXggPSB0aGlzLmF0dHIoJ21hdHJpeCcpO1xuICAgICAgICAgICAgdmFyIHBhcmVudE1hdHJpeCA9IHRoaXMuZ2V0KCdwYXJlbnRNYXRyaXgnKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnRNYXRyaXggJiYgY3VycmVudE1hdHJpeCkge1xuICAgICAgICAgICAgICAgIHRvdGFsTWF0cml4ID0gbWF0cml4XzEubXVsdGlwbHlNYXRyaXgocGFyZW50TWF0cml4LCBjdXJyZW50TWF0cml4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRvdGFsTWF0cml4ID0gY3VycmVudE1hdHJpeCB8fCBwYXJlbnRNYXRyaXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldCgndG90YWxNYXRyaXgnLCB0b3RhbE1hdHJpeCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvdGFsTWF0cml4O1xuICAgIH07XG4gICAgLy8g5LiK5bGC5YiG57uE6K6+572uIG1hdHJpeFxuICAgIEVsZW1lbnQucHJvdG90eXBlLmFwcGx5TWF0cml4ID0gZnVuY3Rpb24gKG1hdHJpeCkge1xuICAgICAgICB2YXIgY3VycmVudE1hdHJpeCA9IHRoaXMuYXR0cignbWF0cml4Jyk7XG4gICAgICAgIHZhciB0b3RhbE1hdHJpeCA9IG51bGw7XG4gICAgICAgIGlmIChtYXRyaXggJiYgY3VycmVudE1hdHJpeCkge1xuICAgICAgICAgICAgdG90YWxNYXRyaXggPSBtYXRyaXhfMS5tdWx0aXBseU1hdHJpeChtYXRyaXgsIGN1cnJlbnRNYXRyaXgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdG90YWxNYXRyaXggPSBjdXJyZW50TWF0cml4IHx8IG1hdHJpeDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldCgndG90YWxNYXRyaXgnLCB0b3RhbE1hdHJpeCk7XG4gICAgICAgIHRoaXMuc2V0KCdwYXJlbnRNYXRyaXgnLCBtYXRyaXgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOiOt+WPlum7mOiupOeahOefqemYtVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJbXXxudWxsfSDpu5jorqTnmoTnn6npmLVcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5nZXREZWZhdWx0TWF0cml4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIC8vIOWwhuWQkemHj+W6lOeUqOiuvue9rueahOefqemYtVxuICAgIEVsZW1lbnQucHJvdG90eXBlLmFwcGx5VG9NYXRyaXggPSBmdW5jdGlvbiAodikge1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5hdHRyKCdtYXRyaXgnKTtcbiAgICAgICAgaWYgKG1hdHJpeCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hdHJpeF8xLm11bHRpcGx5VmVjMihtYXRyaXgsIHYpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2O1xuICAgIH07XG4gICAgLy8g5qC55o2u6K6+572u55qE55+p6Zi177yM5bCG5ZCR6YeP6L2s5o2i55u45a+55LqO5Zu+5b2iL+WIhue7hOeahOS9jee9rlxuICAgIEVsZW1lbnQucHJvdG90eXBlLmludmVydEZyb21NYXRyaXggPSBmdW5jdGlvbiAodikge1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5hdHRyKCdtYXRyaXgnKTtcbiAgICAgICAgaWYgKG1hdHJpeCkge1xuICAgICAgICAgICAgdmFyIGludmVydE1hdHJpeCA9IG1hdHJpeF8xLmludmVydChtYXRyaXgpO1xuICAgICAgICAgICAgaWYgKGludmVydE1hdHJpeCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRyaXhfMS5tdWx0aXBseVZlYzIoaW52ZXJ0TWF0cml4LCB2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdjtcbiAgICB9O1xuICAgIC8vIOiuvue9riBjbGlwXG4gICAgRWxlbWVudC5wcm90b3R5cGUuc2V0Q2xpcCA9IGZ1bmN0aW9uIChjbGlwQ2ZnKSB7XG4gICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmdldENhbnZhcygpO1xuICAgICAgICAvLyDlupTor6Xlj6rorr7nva7lvZPliY3lhYPntKDnmoQgY2xpcO+8jOS4jeW6lOivpeWOu+S/ruaUuSBjbGlwIOacrOi6q++8jOaWueS+vyBjbGlwIOiiq+WkjeeUqFxuICAgICAgICAvLyBUT0RPOiBzZXRDbGlwIOeahOS8oOWPguaXoiBzaGFwZSDphY3nva7vvIzkuZ/mlK/mjIEgc2hhcGUg5a+56LGhXG4gICAgICAgIC8vIGNvbnN0IHByZVNoYXBlID0gdGhpcy5nZXQoJ2NsaXBTaGFwZScpO1xuICAgICAgICAvLyBpZiAocHJlU2hhcGUpIHtcbiAgICAgICAgLy8gICAvLyDlsIbkuYvliY3nmoQgY2xpcFNoYXBlIOmUgOavgVxuICAgICAgICAvLyAgIHByZVNoYXBlLmRlc3Ryb3koKTtcbiAgICAgICAgLy8gfVxuICAgICAgICB2YXIgY2xpcFNoYXBlID0gbnVsbDtcbiAgICAgICAgLy8g5aaC5p6c6YWN572u6aG55Li6IG51bGzvvIzliJnkuI3np7vpmaQgY2xpcFNoYXBlXG4gICAgICAgIGlmIChjbGlwQ2ZnKSB7XG4gICAgICAgICAgICB2YXIgU2hhcGVCYXNlID0gdGhpcy5nZXRTaGFwZUJhc2UoKTtcbiAgICAgICAgICAgIHZhciBzaGFwZVR5cGUgPSB1dGlsXzEudXBwZXJGaXJzdChjbGlwQ2ZnLnR5cGUpO1xuICAgICAgICAgICAgdmFyIENvbnMgPSBTaGFwZUJhc2Vbc2hhcGVUeXBlXTtcbiAgICAgICAgICAgIGlmIChDb25zKSB7XG4gICAgICAgICAgICAgICAgY2xpcFNoYXBlID0gbmV3IENvbnMoe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBjbGlwQ2ZnLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGlzQ2xpcFNoYXBlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdHRyczogY2xpcENmZy5hdHRycyxcbiAgICAgICAgICAgICAgICAgICAgY2FudmFzOiBjYW52YXMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ2NsaXBTaGFwZScsIGNsaXBTaGFwZSk7XG4gICAgICAgIHRoaXMub25DYW52YXNDaGFuZ2UoJ2NsaXAnKTtcbiAgICAgICAgcmV0dXJuIGNsaXBTaGFwZTtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmdldENsaXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOmrmOmikeeOh+iwg+eUqOeahOWcsOaWueebtOaOpeS9v+eUqCB0aGlzLmNmZy54eHhcbiAgICAgICAgdmFyIGNsaXBTaGFwZSA9IHRoaXMuY2ZnLmNsaXBTaGFwZTtcbiAgICAgICAgLy8g5pyq6K6+572u5pe26L+U5ZueIE51bGzvvIzkv53or4HkuIDoh7TmgKdcbiAgICAgICAgaWYgKCFjbGlwU2hhcGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbGlwU2hhcGU7XG4gICAgfTtcbiAgICBFbGVtZW50LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG9yaWdpbkF0dHJzID0gdGhpcy5hdHRycztcbiAgICAgICAgdmFyIGF0dHJzID0ge307XG4gICAgICAgIHV0aWxfMS5lYWNoKG9yaWdpbkF0dHJzLCBmdW5jdGlvbiAoaSwgaykge1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KG9yaWdpbkF0dHJzW2tdKSkge1xuICAgICAgICAgICAgICAgIGF0dHJzW2tdID0gX2Nsb25lQXJyYXlBdHRyKG9yaWdpbkF0dHJzW2tdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF0dHJzW2tdID0gb3JpZ2luQXR0cnNba107XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY29ucyA9IHRoaXMuY29uc3RydWN0b3I7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdmFyIGNsb25lID0gbmV3IGNvbnMoeyBhdHRyczogYXR0cnMgfSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKENMT05FX0NGR1MsIGZ1bmN0aW9uIChjZmdOYW1lKSB7XG4gICAgICAgICAgICBjbG9uZS5zZXQoY2ZnTmFtZSwgX3RoaXMuZ2V0KGNmZ05hbWUpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbG9uZTtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkZXN0cm95ZWQgPSB0aGlzLmRlc3Ryb3llZDtcbiAgICAgICAgaWYgKGRlc3Ryb3llZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYXR0cnMgPSB7fTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgICAgIC8vIHRoaXMub25DYW52YXNDaGFuZ2UoJ2Rlc3Ryb3knKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYr+WQpuWkhOS6juWKqOeUu+aaguWBnOeKtuaAgVxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IOaYr+WQpuWkhOS6juWKqOeUu+aaguWBnOeKtuaAgVxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmlzQW5pbWF0ZVBhdXNlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCdfcGF1c2UnKS5pc1BhdXNlZDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaJp+ihjOWKqOeUu++8jOaUr+aMgeWkmuenjeWHveaVsOetvuWQjVxuICAgICAqIDEuIGFuaW1hdGUodG9BdHRyczogRWxlbWVudEF0dHJzLCBkdXJhdGlvbjogbnVtYmVyLCBlYXNpbmc/OiBzdHJpbmcsIGNhbGxiYWNrPzogKCkgPT4gdm9pZCwgZGVsYXk/OiBudW1iZXIpXG4gICAgICogMi4gYW5pbWF0ZShvbkZyYW1lOiBPbkZyYW1lLCBkdXJhdGlvbjogbnVtYmVyLCBlYXNpbmc/OiBzdHJpbmcsIGNhbGxiYWNrPzogKCkgPT4gdm9pZCwgZGVsYXk/OiBudW1iZXIpXG4gICAgICogMy4gYW5pbWF0ZSh0b0F0dHJzOiBFbGVtZW50QXR0cnMsIGNmZzogQW5pbWF0ZUNmZylcbiAgICAgKiA0LiBhbmltYXRlKG9uRnJhbWU6IE9uRnJhbWUsIGNmZzogQW5pbWF0ZUNmZylcbiAgICAgKiDlkITkuKrlj4LmlbDnmoTlkKvkuYnkuLo6XG4gICAgICogICB0b0F0dHJzICDliqjnlLvmnIDnu4jnirbmgIFcbiAgICAgKiAgIG9uRnJhbWUgIOiHquWumuS5ieW4p+WKqOeUu+WHveaVsFxuICAgICAqICAgZHVyYXRpb24g5Yqo55S75omn6KGM5pe26Ze0XG4gICAgICogICBlYXNpbmcgICDliqjnlLvnvJPliqjmlYjmnpxcbiAgICAgKiAgIGNhbGxiYWNrIOWKqOeUu+aJp+ihjOWQjueahOWbnuiwg1xuICAgICAqICAgZGVsYXkgICAg5Yqo55S75bu26L+f5pe26Ze0XG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuYW5pbWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldCgnYW5pbWF0aW5nJywgdHJ1ZSk7XG4gICAgICAgIHZhciB0aW1lbGluZSA9IHRoaXMuZ2V0KCd0aW1lbGluZScpO1xuICAgICAgICBpZiAoIXRpbWVsaW5lKSB7XG4gICAgICAgICAgICB0aW1lbGluZSA9IHRoaXMuZ2V0KCdjYW52YXMnKS5nZXQoJ3RpbWVsaW5lJyk7XG4gICAgICAgICAgICB0aGlzLnNldCgndGltZWxpbmUnLCB0aW1lbGluZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFuaW1hdGlvbnMgPSB0aGlzLmdldCgnYW5pbWF0aW9ucycpIHx8IFtdO1xuICAgICAgICAvLyDliJ3lp4vljJYgdGlja1xuICAgICAgICBpZiAoIXRpbWVsaW5lLnRpbWVyKSB7XG4gICAgICAgICAgICB0aW1lbGluZS5pbml0VGltZXIoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdG9BdHRycyA9IGFyZ3NbMF0sIGR1cmF0aW9uID0gYXJnc1sxXSwgX2EgPSBhcmdzWzJdLCBlYXNpbmcgPSBfYSA9PT0gdm9pZCAwID8gJ2Vhc2VMaW5lYXInIDogX2EsIF9iID0gYXJnc1szXSwgY2FsbGJhY2sgPSBfYiA9PT0gdm9pZCAwID8gdXRpbF8xLm5vb3AgOiBfYiwgX2MgPSBhcmdzWzRdLCBkZWxheSA9IF9jID09PSB2b2lkIDAgPyAwIDogX2M7XG4gICAgICAgIHZhciBvbkZyYW1lO1xuICAgICAgICB2YXIgcmVwZWF0O1xuICAgICAgICB2YXIgcGF1c2VDYWxsYmFjaztcbiAgICAgICAgdmFyIHJlc3VtZUNhbGxiYWNrO1xuICAgICAgICB2YXIgYW5pbWF0ZUNmZztcbiAgICAgICAgLy8g56ys5LqM5Liq5Y+C5pWw77yM5pei5Y+v5Lul5piv5Yqo55S75pyA57uI54q25oCBIHRvQXR0cnPvvIzkuZ/lj6/ku6XmmK/oh6rlrprkuYnluKfliqjnlLvlh73mlbAgb25GcmFtZVxuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24odG9BdHRycykpIHtcbiAgICAgICAgICAgIG9uRnJhbWUgPSB0b0F0dHJzO1xuICAgICAgICAgICAgdG9BdHRycyA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc09iamVjdCh0b0F0dHJzKSAmJiB0b0F0dHJzLm9uRnJhbWUpIHtcbiAgICAgICAgICAgIC8vIOWFvOWuuSAzLjAg5Lit55qE5YaZ5rOV77yMb25GcmFtZSDlkowgcmVwZWF0IOWPr+WcqCB0b0F0dHJzIOS4reiuvue9rlxuICAgICAgICAgICAgb25GcmFtZSA9IHRvQXR0cnMub25GcmFtZTtcbiAgICAgICAgICAgIHJlcGVhdCA9IHRvQXR0cnMucmVwZWF0O1xuICAgICAgICB9XG4gICAgICAgIC8vIOesrOS6jOS4quWPguaVsO+8jOaXouWPr+S7peaYr+aJp+ihjOaXtumXtCBkdXJhdGlvbu+8jOS5n+WPr+S7peaYr+WKqOeUu+WPguaVsCBhbmltYXRlQ2ZnXG4gICAgICAgIGlmICh1dGlsXzEuaXNPYmplY3QoZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBhbmltYXRlQ2ZnID0gZHVyYXRpb247XG4gICAgICAgICAgICBkdXJhdGlvbiA9IGFuaW1hdGVDZmcuZHVyYXRpb247XG4gICAgICAgICAgICBlYXNpbmcgPSBhbmltYXRlQ2ZnLmVhc2luZyB8fCAnZWFzZUxpbmVhcic7XG4gICAgICAgICAgICBkZWxheSA9IGFuaW1hdGVDZmcuZGVsYXkgfHwgMDtcbiAgICAgICAgICAgIC8vIGFuaW1hdGVDZmcg5Lit55qE6K6+572u5LyY5YWI57qn5pu06auYXG4gICAgICAgICAgICByZXBlYXQgPSBhbmltYXRlQ2ZnLnJlcGVhdCB8fCByZXBlYXQgfHwgZmFsc2U7XG4gICAgICAgICAgICBjYWxsYmFjayA9IGFuaW1hdGVDZmcuY2FsbGJhY2sgfHwgdXRpbF8xLm5vb3A7XG4gICAgICAgICAgICBwYXVzZUNhbGxiYWNrID0gYW5pbWF0ZUNmZy5wYXVzZUNhbGxiYWNrIHx8IHV0aWxfMS5ub29wO1xuICAgICAgICAgICAgcmVzdW1lQ2FsbGJhY2sgPSBhbmltYXRlQ2ZnLnJlc3VtZUNhbGxiYWNrIHx8IHV0aWxfMS5ub29wO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g56ys5Zub5Liq5Y+C5pWw77yM5pei5Y+v5Lul5piv5Zue6LCD5Ye95pWwIGNhbGxiYWNr77yM5Lmf5Y+v5Lul5piv5bu26L+f5pe26Ze0IGRlbGF5XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKGNhbGxiYWNrKSkge1xuICAgICAgICAgICAgICAgIGRlbGF5ID0gY2FsbGJhY2s7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g56ys5LiJ5Liq5Y+C5pWw77yM5pei5Y+v5Lul5piv57yT5Yqo5Y+C5pWwIGVhc2luZ++8jOS5n+WPr+S7peaYr+Wbnuiwg+WHveaVsCBjYWxsYmFja1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGVhc2luZykpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGVhc2luZztcbiAgICAgICAgICAgICAgICBlYXNpbmcgPSAnZWFzZUxpbmVhcic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBlYXNpbmcgPSBlYXNpbmcgfHwgJ2Vhc2VMaW5lYXInO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBmb3JtYXRUb0F0dHJzID0gZ2V0Rm9ybWF0VG9BdHRycyh0b0F0dHJzLCB0aGlzKTtcbiAgICAgICAgdmFyIGFuaW1hdGlvbiA9IHtcbiAgICAgICAgICAgIGZyb21BdHRyczogZ2V0Rm9ybWF0RnJvbUF0dHJzKGZvcm1hdFRvQXR0cnMsIHRoaXMpLFxuICAgICAgICAgICAgdG9BdHRyczogZm9ybWF0VG9BdHRycyxcbiAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcbiAgICAgICAgICAgIGVhc2luZzogZWFzaW5nLFxuICAgICAgICAgICAgcmVwZWF0OiByZXBlYXQsXG4gICAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgICAgICAgICBwYXVzZUNhbGxiYWNrOiBwYXVzZUNhbGxiYWNrLFxuICAgICAgICAgICAgcmVzdW1lQ2FsbGJhY2s6IHJlc3VtZUNhbGxiYWNrLFxuICAgICAgICAgICAgZGVsYXk6IGRlbGF5LFxuICAgICAgICAgICAgc3RhcnRUaW1lOiB0aW1lbGluZS5nZXRUaW1lKCksXG4gICAgICAgICAgICBpZDogdXRpbF8xLnVuaXF1ZUlkKCksXG4gICAgICAgICAgICBvbkZyYW1lOiBvbkZyYW1lLFxuICAgICAgICAgICAgcGF0aEZvcm1hdHRlZDogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICAgIC8vIOWmguaenOWKqOeUu+WFg+e0oOmYn+WIl+S4reW3sue7j+aciei/meS4quWbvuW9ouS6hlxuICAgICAgICBpZiAoYW5pbWF0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyDlhYjmo4Dmn6XmmK/lkKbpnIDopoHlkIjlubblsZ7mgKfjgILoi6XmnInnm7jlkIznmoTliqjnlLvvvIzlsIbor6XlsZ7mgKfku47liY3kuIDkuKrliqjnlLvkuK3liKDpmaQs55u05o6l55So5ZCO5LiA5Liq5Yqo55S75LitXG4gICAgICAgICAgICBhbmltYXRpb25zID0gY2hlY2tFeGlzdGVkQXR0cnMoYW5pbWF0aW9ucywgYW5pbWF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOWQpuWImeWwhuWbvuW9oua3u+WKoOWIsOWKqOeUu+WFg+e0oOmYn+WIl1xuICAgICAgICAgICAgdGltZWxpbmUuYWRkQW5pbWF0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgYW5pbWF0aW9ucy5wdXNoKGFuaW1hdGlvbik7XG4gICAgICAgIHRoaXMuc2V0KCdhbmltYXRpb25zJywgYW5pbWF0aW9ucyk7XG4gICAgICAgIHRoaXMuc2V0KCdfcGF1c2UnLCB7IGlzUGF1c2VkOiBmYWxzZSB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWBnOatouWKqOeUu1xuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdG9FbmQg5piv5ZCm5Yiw5Yqo55S755qE5pyA57uI54q25oCBXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuc3RvcEFuaW1hdGUgPSBmdW5jdGlvbiAodG9FbmQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKHRvRW5kID09PSB2b2lkIDApIHsgdG9FbmQgPSB0cnVlOyB9XG4gICAgICAgIHZhciBhbmltYXRpb25zID0gdGhpcy5nZXQoJ2FuaW1hdGlvbnMnKTtcbiAgICAgICAgdXRpbF8xLmVhY2goYW5pbWF0aW9ucywgZnVuY3Rpb24gKGFuaW1hdGlvbikge1xuICAgICAgICAgICAgLy8g5bCG5Yqo55S75omn6KGM5Yiw5pyA5ZCO5LiA5binXG4gICAgICAgICAgICBpZiAodG9FbmQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYW5pbWF0aW9uLm9uRnJhbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuYXR0cihhbmltYXRpb24ub25GcmFtZSgxKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5hdHRyKGFuaW1hdGlvbi50b0F0dHJzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYW5pbWF0aW9uLmNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgLy8g5Yqo55S75YGc5q2i5pe255qE5Zue6LCDXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uLmNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldCgnYW5pbWF0aW5nJywgZmFsc2UpO1xuICAgICAgICB0aGlzLnNldCgnYW5pbWF0aW9ucycsIFtdKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaaguWBnOWKqOeUu1xuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnBhdXNlQW5pbWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpbWVsaW5lID0gdGhpcy5nZXQoJ3RpbWVsaW5lJyk7XG4gICAgICAgIHZhciBhbmltYXRpb25zID0gdGhpcy5nZXQoJ2FuaW1hdGlvbnMnKTtcbiAgICAgICAgdmFyIHBhdXNlVGltZSA9IHRpbWVsaW5lLmdldFRpbWUoKTtcbiAgICAgICAgdXRpbF8xLmVhY2goYW5pbWF0aW9ucywgZnVuY3Rpb24gKGFuaW1hdGlvbikge1xuICAgICAgICAgICAgYW5pbWF0aW9uLl9wYXVzZWQgPSB0cnVlO1xuICAgICAgICAgICAgYW5pbWF0aW9uLl9wYXVzZVRpbWUgPSBwYXVzZVRpbWU7XG4gICAgICAgICAgICBpZiAoYW5pbWF0aW9uLnBhdXNlQ2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAvLyDliqjnlLvmmoLlgZzml7bnmoTlm57osINcbiAgICAgICAgICAgICAgICBhbmltYXRpb24ucGF1c2VDYWxsYmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8g6K6w5b2V5LiL5piv5Zyo5LuA5LmI5pe25YCZ5pqC5YGc55qEXG4gICAgICAgIHRoaXMuc2V0KCdfcGF1c2UnLCB7XG4gICAgICAgICAgICBpc1BhdXNlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBhdXNlVGltZTogcGF1c2VUaW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmgaLlpI3liqjnlLtcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5yZXN1bWVBbmltYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGltZWxpbmUgPSB0aGlzLmdldCgndGltZWxpbmUnKTtcbiAgICAgICAgdmFyIGN1cnJlbnQgPSB0aW1lbGluZS5nZXRUaW1lKCk7XG4gICAgICAgIHZhciBhbmltYXRpb25zID0gdGhpcy5nZXQoJ2FuaW1hdGlvbnMnKTtcbiAgICAgICAgdmFyIHBhdXNlVGltZSA9IHRoaXMuZ2V0KCdfcGF1c2UnKS5wYXVzZVRpbWU7XG4gICAgICAgIC8vIOS5i+WQjuabtOaWsOWxnuaAp+mcgOimgeiuoeeul+WKqOeUu+W3sue7j+aJp+ihjOeahOaXtumVv++8jOWmguaenOaaguWBnOS6hu+8jOWwseaKiuWIneWni+aXtumXtOiwg+WQjlxuICAgICAgICB1dGlsXzEuZWFjaChhbmltYXRpb25zLCBmdW5jdGlvbiAoYW5pbWF0aW9uKSB7XG4gICAgICAgICAgICBhbmltYXRpb24uc3RhcnRUaW1lID0gYW5pbWF0aW9uLnN0YXJ0VGltZSArIChjdXJyZW50IC0gcGF1c2VUaW1lKTtcbiAgICAgICAgICAgIGFuaW1hdGlvbi5fcGF1c2VkID0gZmFsc2U7XG4gICAgICAgICAgICBhbmltYXRpb24uX3BhdXNlVGltZSA9IG51bGw7XG4gICAgICAgICAgICBpZiAoYW5pbWF0aW9uLnJlc3VtZUNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uLnJlc3VtZUNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldCgnX3BhdXNlJywge1xuICAgICAgICAgICAgaXNQYXVzZWQ6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXQoJ2FuaW1hdGlvbnMnLCBhbmltYXRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDop6blj5Hlp5TmiZjkuovku7ZcbiAgICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgICB0eXBlIOS6i+S7tuexu+Wei1xuICAgICAqIEBwYXJhbSAge0dyYXBoRXZlbnR9IGV2ZW50T2JqIOS6i+S7tuWvueixoVxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmVtaXREZWxlZ2F0aW9uID0gZnVuY3Rpb24gKHR5cGUsIGV2ZW50T2JqKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwYXRocyA9IGV2ZW50T2JqLnByb3BhZ2F0aW9uUGF0aDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZWxhdGl2ZVNoYXBlO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlZW50ZXInKSB7XG4gICAgICAgICAgICByZWxhdGl2ZVNoYXBlID0gZXZlbnRPYmouZnJvbVNoYXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdtb3VzZWxlYXZlJykge1xuICAgICAgICAgICAgcmVsYXRpdmVTaGFwZSA9IGV2ZW50T2JqLnRvU2hhcGU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBwYXRoc1tpXTtcbiAgICAgICAgICAgIC8vIOaaguWumui3nyBuYW1lIOe7keWumlxuICAgICAgICAgICAgdmFyIG5hbWVfMSA9IGVsZW1lbnQuZ2V0KCduYW1lJyk7XG4gICAgICAgICAgICBpZiAobmFtZV8xKSB7XG4gICAgICAgICAgICAgICAgLy8g56ys5LiA5LiqIG1vdXNlZW50ZXIg5ZKMIG1vdXNlbGVhdmUg55qE5YGc5q2i5Y2z5Y+v77yM5Zug5Li65ZCO6Z2i55qE6YO95piv5YmN6Z2i55qEIFBhcmVudFxuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAvLyDlj6rmnIkgZWxlbWVudCDmmK8gR3JvdXAg5oiW6ICFIENhbnZhcyDnmoTml7blgJnvvIzmiY3pnIDopoHliKTmlq0gaXNQYXJlbnRcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5pc0dyb3VwKCkgfHwgKGVsZW1lbnQuaXNDYW52YXMgJiYgZWxlbWVudC5pc0NhbnZhcygpKSkgJiZcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVTaGFwZSAmJlxuICAgICAgICAgICAgICAgICAgICB1dGlsXzIuaXNQYXJlbnQoZWxlbWVudCwgcmVsYXRpdmVTaGFwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYnJlYWtcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KG5hbWVfMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gobmFtZV8xLCBmdW5jdGlvbiAoc3ViTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuZW1pdERlbGVnYXRlRXZlbnQoZWxlbWVudCwgc3ViTmFtZSwgZXZlbnRPYmopO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNfMS5lbWl0RGVsZWdhdGVFdmVudChlbGVtZW50LCBuYW1lXzEsIGV2ZW50T2JqKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHZhciB0aGlzXzEgPSB0aGlzO1xuICAgICAgICAvLyDoh7PlsJHmnInkuIDkuKrlr7nosaHvvIzkuJTnrKzkuIDkuKrlr7nosaHkuLogc2hhcGVcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHN0YXRlXzEgPSBfbG9vcF8xKGkpO1xuICAgICAgICAgICAgaWYgKHN0YXRlXzEgPT09IFwiYnJlYWtcIilcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH07XG4gICAgRWxlbWVudC5wcm90b3R5cGUuZW1pdERlbGVnYXRlRXZlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgbmFtZSwgZXZlbnRPYmopIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuZ2V0RXZlbnRzKCk7XG4gICAgICAgIC8vIOS6i+S7tuWnlOaJmOeahOW9ouW8jyBuYW1lOnR5cGVcbiAgICAgICAgdmFyIGV2ZW50TmFtZSA9IG5hbWUgKyBERUxFR0FUSU9OX1NQTElUICsgZXZlbnRPYmoudHlwZTtcbiAgICAgICAgaWYgKGV2ZW50c1tldmVudE5hbWVdIHx8IGV2ZW50c1tXSUxEQ0FSRF0pIHtcbiAgICAgICAgICAgIC8vIOWvueS6jumAmumFjeespiAq77yM5LqL5Lu25ZCN56ewID0g5aeU5omY5LqL5Lu25ZCN56ewXG4gICAgICAgICAgICBldmVudE9iai5uYW1lID0gZXZlbnROYW1lO1xuICAgICAgICAgICAgZXZlbnRPYmouY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICBldmVudE9iai5kZWxlZ2F0ZVRhcmdldCA9IHRoaXM7XG4gICAgICAgICAgICAvLyDlsIblp5TmiZjkuovku7bnmoTnm5HlkKzlr7nosaEgZGVsZWdhdGVPYmplY3Qg5oyC6L295Yiw5LqL5Lu25a+56LGh5LiKXG4gICAgICAgICAgICBldmVudE9iai5kZWxlZ2F0ZU9iamVjdCA9IGVsZW1lbnQuZ2V0KCdkZWxlZ2F0ZU9iamVjdCcpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KGV2ZW50TmFtZSwgZXZlbnRPYmopO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnp7vliqjlhYPntKBcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdHJhbnNsYXRlWCDmsLTlubPnp7vliqjot53nprtcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdHJhbnNsYXRlWSDlnoLnm7Tnp7vliqjot53nprtcbiAgICAgKiBAcmV0dXJuIHtJRWxlbWVudH0g5YWD57SgXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUudHJhbnNsYXRlID0gZnVuY3Rpb24gKHRyYW5zbGF0ZVgsIHRyYW5zbGF0ZVkpIHtcbiAgICAgICAgaWYgKHRyYW5zbGF0ZVggPT09IHZvaWQgMCkgeyB0cmFuc2xhdGVYID0gMDsgfVxuICAgICAgICBpZiAodHJhbnNsYXRlWSA9PT0gdm9pZCAwKSB7IHRyYW5zbGF0ZVkgPSAwOyB9XG4gICAgICAgIHZhciBtYXRyaXggPSB0aGlzLmdldE1hdHJpeCgpO1xuICAgICAgICB2YXIgbmV3TWF0cml4ID0gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKG1hdHJpeCwgW1sndCcsIHRyYW5zbGF0ZVgsIHRyYW5zbGF0ZVldXSk7XG4gICAgICAgIHRoaXMuc2V0TWF0cml4KG5ld01hdHJpeCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog56e75Yqo5YWD57Sg5Yiw55uu5qCH5L2N572uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFgg55uu5qCH5L2N572u55qE5rC05bmz5Z2Q5qCHXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFgg55uu5qCH5L2N572u55qE5Z6C55u05Z2Q5qCHXG4gICAgICogQHJldHVybiB7SUVsZW1lbnR9IOWFg+e0oFxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLm1vdmUgPSBmdW5jdGlvbiAodGFyZ2V0WCwgdGFyZ2V0WSkge1xuICAgICAgICB2YXIgeCA9IHRoaXMuYXR0cigneCcpIHx8IDA7XG4gICAgICAgIHZhciB5ID0gdGhpcy5hdHRyKCd5JykgfHwgMDtcbiAgICAgICAgdGhpcy50cmFuc2xhdGUodGFyZ2V0WCAtIHgsIHRhcmdldFkgLSB5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnp7vliqjlhYPntKDliLDnm67moIfkvY3nva7vvIznrYnku7fkuo4gbW92ZSDmlrnms5XjgILnlLHkuo4gbW92ZVRvIOeahOivreS5ieaAp+abtOW8uu+8jOWboOatpOWcqOaWh+aho+S4reaOqOiNkOS9v+eUqCBtb3ZlVG8g5pa55rOVXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFgg55uu5qCH5L2N572u55qEIHgg6L205Z2Q5qCHXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFkg55uu5qCH5L2N572u55qEIHkg6L205Z2Q5qCHXG4gICAgICogQHJldHVybiB7SUVsZW1lbnR9IOWFg+e0oFxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLm1vdmVUbyA9IGZ1bmN0aW9uICh0YXJnZXRYLCB0YXJnZXRZKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1vdmUodGFyZ2V0WCwgdGFyZ2V0WSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnvKnmlL7lhYPntKBcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcmF0aW9YIOawtOW5s+e8qeaUvuavlOS+i1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpb1kg5Z6C55u057yp5pS+5q+U5L6LXG4gICAgICogQHJldHVybiB7SUVsZW1lbnR9IOWFg+e0oFxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKHJhdGlvWCwgcmF0aW9ZKSB7XG4gICAgICAgIHZhciBtYXRyaXggPSB0aGlzLmdldE1hdHJpeCgpO1xuICAgICAgICB2YXIgbmV3TWF0cml4ID0gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKG1hdHJpeCwgW1sncycsIHJhdGlvWCwgcmF0aW9ZIHx8IHJhdGlvWF1dKTtcbiAgICAgICAgdGhpcy5zZXRNYXRyaXgobmV3TWF0cml4KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDku6XnlLvluIPlt6bkuIrop5IgKDAsIDApIOS4uuS4reW/g+aXi+i9rOWFg+e0oFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByYWRpYW4g5peL6L2s6KeS5bqmKOW8p+W6puWAvClcbiAgICAgKiBAcmV0dXJuIHtJRWxlbWVudH0g5YWD57SgXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUucm90YXRlID0gZnVuY3Rpb24gKHJhZGlhbikge1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5nZXRNYXRyaXgoKTtcbiAgICAgICAgdmFyIG5ld01hdHJpeCA9IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShtYXRyaXgsIFtbJ3InLCByYWRpYW5dXSk7XG4gICAgICAgIHRoaXMuc2V0TWF0cml4KG5ld01hdHJpeCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Lul6LW35aeL54K55Li65Lit5b+D5peL6L2s5YWD57SgXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJhZGlhbiDml4vovazop5LluqYo5byn5bqm5YC8KVxuICAgICAqIEByZXR1cm4ge0lFbGVtZW50fSDlhYPntKBcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5yb3RhdGVBdFN0YXJ0ID0gZnVuY3Rpb24gKHJvdGF0ZSkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmF0dHIoKSwgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5nZXRNYXRyaXgoKTtcbiAgICAgICAgdmFyIG5ld01hdHJpeCA9IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShtYXRyaXgsIFtcbiAgICAgICAgICAgIFsndCcsIC14LCAteV0sXG4gICAgICAgICAgICBbJ3InLCByb3RhdGVdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pO1xuICAgICAgICB0aGlzLnNldE1hdHJpeChuZXdNYXRyaXgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOS7peS7u+aEj+eCuSAoeCwgeSkg5Li65Lit5b+D5peL6L2s5YWD57SgXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJhZGlhbiDml4vovazop5LluqYo5byn5bqm5YC8KVxuICAgICAqIEByZXR1cm4ge0lFbGVtZW50fSDlhYPntKBcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5yb3RhdGVBdFBvaW50ID0gZnVuY3Rpb24gKHgsIHksIHJvdGF0ZSkge1xuICAgICAgICB2YXIgbWF0cml4ID0gdGhpcy5nZXRNYXRyaXgoKTtcbiAgICAgICAgdmFyIG5ld01hdHJpeCA9IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShtYXRyaXgsIFtcbiAgICAgICAgICAgIFsndCcsIC14LCAteV0sXG4gICAgICAgICAgICBbJ3InLCByb3RhdGVdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pO1xuICAgICAgICB0aGlzLnNldE1hdHJpeChuZXdNYXRyaXgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRWxlbWVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVsZW1lbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lclwiKTtcbnZhciBBYnN0cmFjdEdyb3VwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEFic3RyYWN0R3JvdXAsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQWJzdHJhY3RHcm91cCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBBYnN0cmFjdEdyb3VwLnByb3RvdHlwZS5pc0dyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICAgIEFic3RyYWN0R3JvdXAucHJvdG90eXBlLmlzRW50aXR5R3JvdXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEFic3RyYWN0R3JvdXAucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2xvbmUgPSBfc3VwZXIucHJvdG90eXBlLmNsb25lLmNhbGwodGhpcyk7XG4gICAgICAgIC8vIOiOt+WPluaehOmAoOWHveaVsFxuICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmdldENoaWxkcmVuKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgY2xvbmUuYWRkKGNoaWxkLmNsb25lKCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbG9uZTtcbiAgICB9O1xuICAgIHJldHVybiBBYnN0cmFjdEdyb3VwO1xufShjb250YWluZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBYnN0cmFjdEdyb3VwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z3JvdXAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBlbGVtZW50XzEgPSByZXF1aXJlKFwiLi9lbGVtZW50XCIpO1xudmFyIG1hdHJpeF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0cml4XCIpO1xudmFyIEFic3RyYWN0U2hhcGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQWJzdHJhY3RTaGFwZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBYnN0cmFjdFNoYXBlKGNmZykge1xuICAgICAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvLyDmmK/lkKblnKjljIXlm7Tnm5LlhoVcbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5faXNJbkJCb3ggPSBmdW5jdGlvbiAocmVmWCwgcmVmWSkge1xuICAgICAgICB2YXIgYmJveCA9IHRoaXMuZ2V0QkJveCgpO1xuICAgICAgICByZXR1cm4gYmJveC5taW5YIDw9IHJlZlggJiYgYmJveC5tYXhYID49IHJlZlggJiYgYmJveC5taW5ZIDw9IHJlZlkgJiYgYmJveC5tYXhZID49IHJlZlk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsZ7mgKfmm7TmlLnlkI7pnIDopoHlgZrnmoTkuovmg4VcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHBhcmFtIHtTaGFwZUF0dHJzfSB0YXJnZXRBdHRycyDmuLLmn5PnmoTlm77lg4/lsZ7mgKdcbiAgICAgKi9cbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5hZnRlckF0dHJzQ2hhbmdlID0gZnVuY3Rpb24gKHRhcmdldEF0dHJzKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJBdHRyc0NoYW5nZS5jYWxsKHRoaXMsIHRhcmdldEF0dHJzKTtcbiAgICAgICAgdGhpcy5jbGVhckNhY2hlQkJveCgpO1xuICAgIH07XG4gICAgLy8g6K6h566X5YyF5Zu055uS5pe277yM6ZyA6KaB57yT5a2Y77yM6L+Z5piv5LiA5Liq6auY6aKR55qE5pON5L2cXG4gICAgQWJzdHJhY3RTaGFwZS5wcm90b3R5cGUuZ2V0QkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldCgnYmJveCcpO1xuICAgICAgICBpZiAoIWJib3gpIHtcbiAgICAgICAgICAgIGJib3ggPSB0aGlzLmNhbGN1bGF0ZUJCb3goKTtcbiAgICAgICAgICAgIHRoaXMuc2V0KCdiYm94JywgYmJveCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJib3g7XG4gICAgfTtcbiAgICAvLyDorqHnrpfnm7jlr7nkuo7nlLvluIPnmoTljIXlm7Tnm5JcbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5nZXRDYW52YXNCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2FudmFzQm94ID0gdGhpcy5nZXQoJ2NhbnZhc0JveCcpO1xuICAgICAgICBpZiAoIWNhbnZhc0JveCkge1xuICAgICAgICAgICAgY2FudmFzQm94ID0gdGhpcy5jYWxjdWxhdGVDYW52YXNCQm94KCk7XG4gICAgICAgICAgICB0aGlzLnNldCgnY2FudmFzQm94JywgY2FudmFzQm94KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FudmFzQm94O1xuICAgIH07XG4gICAgQWJzdHJhY3RTaGFwZS5wcm90b3R5cGUuYXBwbHlNYXRyaXggPSBmdW5jdGlvbiAobWF0cml4KSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYXBwbHlNYXRyaXguY2FsbCh0aGlzLCBtYXRyaXgpO1xuICAgICAgICAvLyDmuIXnkIbmjonnvJPlrZjnmoTljIXlm7Tnm5JcbiAgICAgICAgdGhpcy5zZXQoJ2NhbnZhc0JveCcsIG51bGwpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6h566X55u45a+55LqO55S75biD55qE5YyF5Zu055uS77yM6buY6K6k562J5ZCM5LqOIGJib3hcbiAgICAgKiBAcmV0dXJuIHtCQm94fSDljIXlm7Tnm5JcbiAgICAgKi9cbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5jYWxjdWxhdGVDYW52YXNCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYmJveCA9IHRoaXMuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgdG90YWxNYXRyaXggPSB0aGlzLmdldFRvdGFsTWF0cml4KCk7XG4gICAgICAgIHZhciBtaW5YID0gYmJveC5taW5YLCBtaW5ZID0gYmJveC5taW5ZLCBtYXhYID0gYmJveC5tYXhYLCBtYXhZID0gYmJveC5tYXhZO1xuICAgICAgICBpZiAodG90YWxNYXRyaXgpIHtcbiAgICAgICAgICAgIHZhciB0b3BMZWZ0ID0gbWF0cml4XzEubXVsdGlwbHlWZWMyKHRvdGFsTWF0cml4LCBbYmJveC5taW5YLCBiYm94Lm1pblldKTtcbiAgICAgICAgICAgIHZhciB0b3BSaWdodCA9IG1hdHJpeF8xLm11bHRpcGx5VmVjMih0b3RhbE1hdHJpeCwgW2Jib3gubWF4WCwgYmJveC5taW5ZXSk7XG4gICAgICAgICAgICB2YXIgYm90dG9tTGVmdCA9IG1hdHJpeF8xLm11bHRpcGx5VmVjMih0b3RhbE1hdHJpeCwgW2Jib3gubWluWCwgYmJveC5tYXhZXSk7XG4gICAgICAgICAgICB2YXIgYm90dG9tUmlnaHQgPSBtYXRyaXhfMS5tdWx0aXBseVZlYzIodG90YWxNYXRyaXgsIFtiYm94Lm1heFgsIGJib3gubWF4WV0pO1xuICAgICAgICAgICAgbWluWCA9IE1hdGgubWluKHRvcExlZnRbMF0sIHRvcFJpZ2h0WzBdLCBib3R0b21MZWZ0WzBdLCBib3R0b21SaWdodFswXSk7XG4gICAgICAgICAgICBtYXhYID0gTWF0aC5tYXgodG9wTGVmdFswXSwgdG9wUmlnaHRbMF0sIGJvdHRvbUxlZnRbMF0sIGJvdHRvbVJpZ2h0WzBdKTtcbiAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbih0b3BMZWZ0WzFdLCB0b3BSaWdodFsxXSwgYm90dG9tTGVmdFsxXSwgYm90dG9tUmlnaHRbMV0pO1xuICAgICAgICAgICAgbWF4WSA9IE1hdGgubWF4KHRvcExlZnRbMV0sIHRvcFJpZ2h0WzFdLCBib3R0b21MZWZ0WzFdLCBib3R0b21SaWdodFsxXSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRycztcbiAgICAgICAgLy8g5aaC5p6c5a2Y5ZyoIHNoYWRvdyDliJnorqHnrpcgc2hhZG93XG4gICAgICAgIGlmIChhdHRycy5zaGFkb3dDb2xvcikge1xuICAgICAgICAgICAgdmFyIF9hID0gYXR0cnMuc2hhZG93Qmx1ciwgc2hhZG93Qmx1ciA9IF9hID09PSB2b2lkIDAgPyAwIDogX2EsIF9iID0gYXR0cnMuc2hhZG93T2Zmc2V0WCwgc2hhZG93T2Zmc2V0WCA9IF9iID09PSB2b2lkIDAgPyAwIDogX2IsIF9jID0gYXR0cnMuc2hhZG93T2Zmc2V0WSwgc2hhZG93T2Zmc2V0WSA9IF9jID09PSB2b2lkIDAgPyAwIDogX2M7XG4gICAgICAgICAgICB2YXIgc2hhZG93TGVmdCA9IG1pblggLSBzaGFkb3dCbHVyICsgc2hhZG93T2Zmc2V0WDtcbiAgICAgICAgICAgIHZhciBzaGFkb3dSaWdodCA9IG1heFggKyBzaGFkb3dCbHVyICsgc2hhZG93T2Zmc2V0WDtcbiAgICAgICAgICAgIHZhciBzaGFkb3dUb3AgPSBtaW5ZIC0gc2hhZG93Qmx1ciArIHNoYWRvd09mZnNldFk7XG4gICAgICAgICAgICB2YXIgc2hhZG93Qm90dG9tID0gbWF4WSArIHNoYWRvd0JsdXIgKyBzaGFkb3dPZmZzZXRZO1xuICAgICAgICAgICAgbWluWCA9IE1hdGgubWluKG1pblgsIHNoYWRvd0xlZnQpO1xuICAgICAgICAgICAgbWF4WCA9IE1hdGgubWF4KG1heFgsIHNoYWRvd1JpZ2h0KTtcbiAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbihtaW5ZLCBzaGFkb3dUb3ApO1xuICAgICAgICAgICAgbWF4WSA9IE1hdGgubWF4KG1heFksIHNoYWRvd0JvdHRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IG1pblgsXG4gICAgICAgICAgICB5OiBtaW5ZLFxuICAgICAgICAgICAgbWluWDogbWluWCxcbiAgICAgICAgICAgIG1pblk6IG1pblksXG4gICAgICAgICAgICBtYXhYOiBtYXhYLFxuICAgICAgICAgICAgbWF4WTogbWF4WSxcbiAgICAgICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgICAgIGhlaWdodDogbWF4WSAtIG1pblksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog5riF55CG57yT5a2Y55qEIGJib3hcbiAgICAgKi9cbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5jbGVhckNhY2hlQkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXQoJ2Jib3gnLCBudWxsKTtcbiAgICAgICAgdGhpcy5zZXQoJ2NhbnZhc0JveCcsIG51bGwpO1xuICAgIH07XG4gICAgLy8g5a6e546w5o6l5Y+jXG4gICAgQWJzdHJhY3RTaGFwZS5wcm90b3R5cGUuaXNDbGlwU2hhcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldCgnaXNDbGlwU2hhcGUnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDkuI3lkIznmoTlm77lvaLoh6rlt7Hlrp7njrDmmK/lkKblnKjlm77lvaLlhoXpg6jnmoTpgLvovpHvvIzopoHliKTmlq3ovrnlkozloavlhYXljLrln59cbiAgICAgKiBAcGFyYW0gIHtudW1iZXJ9ICByZWZYIOebuOWvueS6juWbvuW9oueahOWdkOaghyB4XG4gICAgICogQHBhcmFtICB7bnVtYmVyfSAgcmVmWSDnm7jlr7nkuo7lm77lvaLnmoTlnZDmoIcgWVxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IOeCueaYr+WQpuWcqOWbvuW9ouWGhemDqFxuICAgICAqL1xuICAgIEFic3RyYWN0U2hhcGUucHJvdG90eXBlLmlzSW5TaGFwZSA9IGZ1bmN0aW9uIChyZWZYLCByZWZZKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYr+WQpuS7heS7heS9v+eUqCBCQm94IOajgOa1i+WwseWPr+S7peWIpOWumuaLvuWPluWIsOWbvuW9olxuICAgICAqIOm7mOiupOaYryBmYWxzZe+8jOS9huaYr+acieS6m+WbvuW9ouS+i+WmgiBpbWFnZeOAgW1hcmtlciDnrYnpg73lj6/nm7TmjqXkvb/nlKggQkJveCDnmoTmo4DmtYvogIzkuI3pnIDopoHkvb/nlKjlm77lvaLmi77lj5ZcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufSDku4Xku4Xkvb/nlKggQkJveCDov5vooYzmi77lj5ZcbiAgICAgKi9cbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5pc09ubHlIaXRCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIC8vIOS4jeWQjOeahCBTaGFwZSDlkIToh6rlrp7njrBcbiAgICBBYnN0cmFjdFNoYXBlLnByb3RvdHlwZS5pc0hpdCA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIHZhciBzdGFydEFycm93U2hhcGUgPSB0aGlzLmdldCgnc3RhcnRBcnJvd1NoYXBlJyk7XG4gICAgICAgIHZhciBlbmRBcnJvd1NoYXBlID0gdGhpcy5nZXQoJ2VuZEFycm93U2hhcGUnKTtcbiAgICAgICAgdmFyIHZlYyA9IFt4LCB5LCAxXTtcbiAgICAgICAgdmVjID0gdGhpcy5pbnZlcnRGcm9tTWF0cml4KHZlYyk7XG4gICAgICAgIHZhciByZWZYID0gdmVjWzBdLCByZWZZID0gdmVjWzFdO1xuICAgICAgICB2YXIgaW5CQm94ID0gdGhpcy5faXNJbkJCb3gocmVmWCwgcmVmWSk7XG4gICAgICAgIC8vIOi3s+i/h+WbvuW9oueahOaLvuWPlu+8jOWcqOafkOS6m+WbvuW9ouS4reWPr+S7peecgeeVpeS4gOWAjeeahOajgOa1i+aIkOacrFxuICAgICAgICBpZiAodGhpcy5pc09ubHlIaXRCb3goKSkge1xuICAgICAgICAgICAgcmV0dXJuIGluQkJveDtcbiAgICAgICAgfVxuICAgICAgICAvLyDooqvoo4Hlh4/mjonnmoTlkozkuI3lnKjljIXlm7Tnm5LlhoXnmoTkuI3ov5vooYzorqHnrpdcbiAgICAgICAgaWYgKGluQkJveCAmJiAhdGhpcy5pc0NsaXBwZWQocmVmWCwgcmVmWSkpIHtcbiAgICAgICAgICAgIC8vIOWvueWbvuW9oui/m+ihjOaLvuWPluWIpOaWrVxuICAgICAgICAgICAgaWYgKHRoaXMuaXNJblNoYXBlKHJlZlgsIHJlZlkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDlr7notbflp4vnrq3lpLTov5vooYzmi77lj5bliKTmlq1cbiAgICAgICAgICAgIGlmIChzdGFydEFycm93U2hhcGUgJiYgc3RhcnRBcnJvd1NoYXBlLmlzSGl0KHJlZlgsIHJlZlkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDlr7nnu5PmnZ/nrq3lpLTov5vooYzmi77lj5bliKTmlq1cbiAgICAgICAgICAgIGlmIChlbmRBcnJvd1NoYXBlICYmIGVuZEFycm93U2hhcGUuaXNIaXQocmVmWCwgcmVmWSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICByZXR1cm4gQWJzdHJhY3RTaGFwZTtcbn0oZWxlbWVudF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEFic3RyYWN0U2hhcGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zaGFwZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkM1RpbWVyID0gcmVxdWlyZShcImQzLXRpbWVyXCIpO1xudmFyIGQzRWFzZSA9IHJlcXVpcmUoXCJkMy1lYXNlXCIpO1xudmFyIGQzX2ludGVycG9sYXRlXzEgPSByZXF1aXJlKFwiZDMtaW50ZXJwb2xhdGVcIik7IC8vIOebruWJjeaVtOS9k+WKqOeUu+WPqumcgOimgeaVsOWAvOWSjOaVsOe7hOeahOW3ruWAvOiuoeeul1xudmFyIFBhdGhVdGlsID0gcmVxdWlyZShcIi4uL3V0aWwvcGF0aFwiKTtcbnZhciBjb2xvcl8xID0gcmVxdWlyZShcIi4uL3V0aWwvY29sb3JcIik7XG52YXIgSURFTlRJVFlfTUFUUklYID0gWzEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDFdO1xuLyoqXG4gKiDkvb/nlKggcmF0aW8g6L+b6KGM5o+S5YC86K6h566X5p2l5pu05paw5bGe5oCnXG4gKiBAcGFyYW0ge0lFbGVtZW50fSAgc2hhcGUgICAg5YWD57SgXG4gKiBAcGFyYW0ge0FuaW1hdGlvbn0gYW5pbWF0aW9uIOWKqOeUu1xuICogQHBhcmFtIHtudW1iZXJ9ICAgIHJhdGlvICAgIOavlOS+i1xuICogQHJldHVybiB7Ym9vbGVhbn0gIOWKqOeUu+aYr+WQpuaJp+ihjOWujOaIkFxuICovXG5mdW5jdGlvbiBfdXBkYXRlKHNoYXBlLCBhbmltYXRpb24sIHJhdGlvKSB7XG4gICAgdmFyIGNQcm9wcyA9IHt9OyAvLyDmraTliLvlsZ7mgKdcbiAgICB2YXIgZnJvbUF0dHJzID0gYW5pbWF0aW9uLmZyb21BdHRycywgdG9BdHRycyA9IGFuaW1hdGlvbi50b0F0dHJzO1xuICAgIGlmIChzaGFwZS5kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgaW50ZXJmOyAvLyAg5beu5YC85Ye95pWwXG4gICAgZm9yICh2YXIgayBpbiB0b0F0dHJzKSB7XG4gICAgICAgIGlmICghdXRpbF8xLmlzRXF1YWwoZnJvbUF0dHJzW2tdLCB0b0F0dHJzW2tdKSkge1xuICAgICAgICAgICAgaWYgKGsgPT09ICdwYXRoJykge1xuICAgICAgICAgICAgICAgIHZhciB0b1BhdGggPSB0b0F0dHJzW2tdO1xuICAgICAgICAgICAgICAgIHZhciBmcm9tUGF0aCA9IGZyb21BdHRyc1trXTtcbiAgICAgICAgICAgICAgICBpZiAodG9QYXRoLmxlbmd0aCA+IGZyb21QYXRoLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0b1BhdGggPSBQYXRoVXRpbC5wYXJzZVBhdGhTdHJpbmcodG9BdHRyc1trXSk7IC8vIOe7iOeCueeKtuaAgVxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aCA9IFBhdGhVdGlsLnBhcnNlUGF0aFN0cmluZyhmcm9tQXR0cnNba10pOyAvLyDotbflp4vnirbmgIFcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGggPSBQYXRoVXRpbC5maWxsUGF0aEJ5RGlmZihmcm9tUGF0aCwgdG9QYXRoKTtcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGggPSBQYXRoVXRpbC5mb3JtYXRQYXRoKGZyb21QYXRoLCB0b1BhdGgpO1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uZnJvbUF0dHJzLnBhdGggPSBmcm9tUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uLnRvQXR0cnMucGF0aCA9IHRvUGF0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIWFuaW1hdGlvbi5wYXRoRm9ybWF0dGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvUGF0aCA9IFBhdGhVdGlsLnBhcnNlUGF0aFN0cmluZyh0b0F0dHJzW2tdKTtcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGggPSBQYXRoVXRpbC5wYXJzZVBhdGhTdHJpbmcoZnJvbUF0dHJzW2tdKTtcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGggPSBQYXRoVXRpbC5mb3JtYXRQYXRoKGZyb21QYXRoLCB0b1BhdGgpO1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uZnJvbUF0dHJzLnBhdGggPSBmcm9tUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uLnRvQXR0cnMucGF0aCA9IHRvUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uLnBhdGhGb3JtYXR0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjUHJvcHNba10gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvUGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdG9QYXRoUG9pbnQgPSB0b1BhdGhbaV07XG4gICAgICAgICAgICAgICAgICAgIHZhciBmcm9tUGF0aFBvaW50ID0gZnJvbVBhdGhbaV07XG4gICAgICAgICAgICAgICAgICAgIHZhciBjUGF0aFBvaW50ID0gW107XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdG9QYXRoUG9pbnQubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNOdW1iZXIodG9QYXRoUG9pbnRbal0pICYmIGZyb21QYXRoUG9pbnQgJiYgdXRpbF8xLmlzTnVtYmVyKGZyb21QYXRoUG9pbnRbal0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJmID0gZDNfaW50ZXJwb2xhdGVfMS5pbnRlcnBvbGF0ZShmcm9tUGF0aFBvaW50W2pdLCB0b1BhdGhQb2ludFtqXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY1BhdGhQb2ludC5wdXNoKGludGVyZihyYXRpbykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY1BhdGhQb2ludC5wdXNoKHRvUGF0aFBvaW50W2pdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjUHJvcHNba10ucHVzaChjUGF0aFBvaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChrID09PSAnbWF0cml4Jykge1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgIOWvueefqemYtei/m+ihjOaPkuWAvOaXtu+8jOmcgOimgeS/neivgeefqemYteS4jeS4uuepuu+8jOS4uuepuuWImeS9v+eUqOWNleS9jeefqemYtVxuICAgICAgICAgICAgICAgICBUT0RPOiDkuoznu7TlkozkuInnu7TlnLrmma/kuIvljZXkvY3nn6npmLXkuI3lkIzvvIzkuYvlkI4gV2ViR0wg54mI6ZyA6KaB5YGa6L+b5LiA5q2l5aSE55CGXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgdmFyIG1hdHJpeEZuID0gZDNfaW50ZXJwb2xhdGVfMS5pbnRlcnBvbGF0ZUFycmF5KGZyb21BdHRyc1trXSB8fCBJREVOVElUWV9NQVRSSVgsIHRvQXR0cnNba10gfHwgSURFTlRJVFlfTUFUUklYKTtcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudE1hdHJpeCA9IG1hdHJpeEZuKHJhdGlvKTtcbiAgICAgICAgICAgICAgICBjUHJvcHNba10gPSBjdXJyZW50TWF0cml4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29sb3JfMS5pc0NvbG9yUHJvcChrKSAmJiBjb2xvcl8xLmlzR3JhZGllbnRDb2xvcih0b0F0dHJzW2tdKSkge1xuICAgICAgICAgICAgICAgIGNQcm9wc1trXSA9IHRvQXR0cnNba107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghdXRpbF8xLmlzRnVuY3Rpb24odG9BdHRyc1trXSkpIHtcbiAgICAgICAgICAgICAgICAvLyDpnZ7lh73mlbDnsbvlnovnmoTlgLzmiY3og73lgZrmj5LlgLxcbiAgICAgICAgICAgICAgICBpbnRlcmYgPSBkM19pbnRlcnBvbGF0ZV8xLmludGVycG9sYXRlKGZyb21BdHRyc1trXSwgdG9BdHRyc1trXSk7XG4gICAgICAgICAgICAgICAgY1Byb3BzW2tdID0gaW50ZXJmKHJhdGlvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzaGFwZS5hdHRyKGNQcm9wcyk7XG59XG4vKipcbiAqIOagueaNruiHquWumuS5ieW4p+WKqOeUu+WHveaVsCBvbkZyYW1lIOadpeabtOaWsOWxnuaAp1xuICogQHBhcmFtIHtJRWxlbWVudH0gIHNoYXBlICAgIOWFg+e0oFxuICogQHBhcmFtIHtBbmltYXRpb259IGFuaW1hdGlvbiDliqjnlLtcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICBlbGFwc2VkICDliqjnlLvmiafooYzml7bpl7Qo5q+r56eSKVxuICogQHJldHVybiB7Ym9vbGVhbn0gIOWKqOeUu+aYr+WQpuaJp+ihjOWujOaIkFxuICovXG5mdW5jdGlvbiB1cGRhdGUoc2hhcGUsIGFuaW1hdGlvbiwgZWxhcHNlZCkge1xuICAgIHZhciBzdGFydFRpbWUgPSBhbmltYXRpb24uc3RhcnRUaW1lLCBkZWxheSA9IGFuaW1hdGlvbi5kZWxheTtcbiAgICAvLyDlpoLmnpzov5jmsqHmnInlvIDlp4vmiafooYzmiJbmmoLlgZzvvIzlhYjkuI3mm7TmlrBcbiAgICBpZiAoZWxhcHNlZCA8IHN0YXJ0VGltZSArIGRlbGF5IHx8IGFuaW1hdGlvbi5fcGF1c2VkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIHJhdGlvO1xuICAgIHZhciBkdXJhdGlvbiA9IGFuaW1hdGlvbi5kdXJhdGlvbjtcbiAgICB2YXIgZWFzaW5nID0gYW5pbWF0aW9uLmVhc2luZztcbiAgICAvLyDlt7LmiafooYzml7bpl7RcbiAgICBlbGFwc2VkID0gZWxhcHNlZCAtIHN0YXJ0VGltZSAtIGFuaW1hdGlvbi5kZWxheTtcbiAgICBpZiAoYW5pbWF0aW9uLnJlcGVhdCkge1xuICAgICAgICAvLyDlpoLmnpzliqjnlLvph43lpI3miafooYzvvIzliJkgZWxhcHNlZCA+IGR1cmF0aW9u77yM6K6h566XIHJhdGlvIOaXtumcgOWPluaooVxuICAgICAgICByYXRpbyA9IChlbGFwc2VkICUgZHVyYXRpb24pIC8gZHVyYXRpb247XG4gICAgICAgIHJhdGlvID0gZDNFYXNlW2Vhc2luZ10ocmF0aW8pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmF0aW8gPSBlbGFwc2VkIC8gZHVyYXRpb247XG4gICAgICAgIGlmIChyYXRpbyA8IDEpIHtcbiAgICAgICAgICAgIC8vIOWKqOeUu+acquaJp+ihjOWujFxuICAgICAgICAgICAgcmF0aW8gPSBkM0Vhc2VbZWFzaW5nXShyYXRpbyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDliqjnlLvlt7LmiafooYzlroxcbiAgICAgICAgICAgIGlmIChhbmltYXRpb24ub25GcmFtZSkge1xuICAgICAgICAgICAgICAgIHNoYXBlLmF0dHIoYW5pbWF0aW9uLm9uRnJhbWUoMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2hhcGUuYXR0cihhbmltYXRpb24udG9BdHRycyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoYW5pbWF0aW9uLm9uRnJhbWUpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gYW5pbWF0aW9uLm9uRnJhbWUocmF0aW8pO1xuICAgICAgICBzaGFwZS5hdHRyKGF0dHJzKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIF91cGRhdGUoc2hhcGUsIGFuaW1hdGlvbiwgcmF0aW8pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG52YXIgVGltZWxpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICog5pe26Ze06L205p6E6YCg5Ye95pWw77yM5L6d6LWW5LqO55S75biDXG4gICAgICogQHBhcmFtIHt9XG4gICAgICovXG4gICAgZnVuY3Rpb24gVGltZWxpbmUoY2FudmFzKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDmiafooYzliqjnlLvnmoTlhYPntKDliJfooahcbiAgICAgICAgICogQHR5cGUge0lFbGVtZW50W119XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFuaW1hdG9ycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICog5b2T5YmN5pe26Ze0XG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICog5a6a5pe25ZmoXG4gICAgICAgICAqIEB0eXBlIHtkM1RpbWVyLlRpbWVyfVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy50aW1lciA9IG51bGw7XG4gICAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDliJ3lp4vljJblrprml7blmahcbiAgICAgKi9cbiAgICBUaW1lbGluZS5wcm90b3R5cGUuaW5pdFRpbWVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXNGaW5pc2hlZCA9IGZhbHNlO1xuICAgICAgICB2YXIgc2hhcGU7XG4gICAgICAgIHZhciBhbmltYXRpb25zO1xuICAgICAgICB2YXIgYW5pbWF0aW9uO1xuICAgICAgICB0aGlzLnRpbWVyID0gZDNUaW1lci50aW1lcihmdW5jdGlvbiAoZWxhcHNlZCkge1xuICAgICAgICAgICAgX3RoaXMuY3VycmVudCA9IGVsYXBzZWQ7XG4gICAgICAgICAgICBpZiAoX3RoaXMuYW5pbWF0b3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gX3RoaXMuYW5pbWF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgIHNoYXBlID0gX3RoaXMuYW5pbWF0b3JzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2hhcGUuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzlt7Lnu4/ooqvplIDmr4HvvIznm7TmjqXnp7vlh7rpmJ/liJdcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnJlbW92ZUFuaW1hdG9yKGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzaGFwZS5pc0FuaW1hdGVQYXVzZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9ucyA9IHNoYXBlLmdldCgnYW5pbWF0aW9ucycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IGFuaW1hdGlvbnMubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24gPSBhbmltYXRpb25zW2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRmluaXNoZWQgPSB1cGRhdGUoc2hhcGUsIGFuaW1hdGlvbiwgZWxhcHNlZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9ucy5zcGxpY2UoaiwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRmluaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbi5jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uLmNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5yZW1vdmVBbmltYXRvcihpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgYXV0b0RyYXcgPSBfdGhpcy5jYW52YXMuZ2V0KCdhdXRvRHJhdycpO1xuICAgICAgICAgICAgICAgIC8vIOmdnuiHquWKqOa4suafk+aooeW8j+S4i++8jOaJi+WKqOiwg+eUqCBjYW52YXMuZHJhdygpIOmHjeaWsOa4suafk1xuICAgICAgICAgICAgICAgIGlmICghYXV0b0RyYXcpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5aKe5Yqg5Yqo55S75YWD57SgXG4gICAgICovXG4gICAgVGltZWxpbmUucHJvdG90eXBlLmFkZEFuaW1hdG9yID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHRoaXMuYW5pbWF0b3JzLnB1c2goc2hhcGUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog56e76Zmk5Yqo55S75YWD57SgXG4gICAgICovXG4gICAgVGltZWxpbmUucHJvdG90eXBlLnJlbW92ZUFuaW1hdG9yID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHRoaXMuYW5pbWF0b3JzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmmK/lkKbmnInliqjnlLvlnKjmiafooYxcbiAgICAgKi9cbiAgICBUaW1lbGluZS5wcm90b3R5cGUuaXNBbmltYXRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuYW5pbWF0b3JzLmxlbmd0aDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWBnOatouWumuaXtuWZqFxuICAgICAqL1xuICAgIFRpbWVsaW5lLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgICAgICAgdGhpcy50aW1lci5zdG9wKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWBnOatouaXtumXtOi9tOS4iuaJgOacieWFg+e0oOeahOWKqOeUu++8jOW5tue9ruepuuWKqOeUu+WFg+e0oOWIl+ihqFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdG9FbmQg5piv5ZCm5Yiw5Yqo55S755qE5pyA57uI54q25oCB77yM55So5p2l6YCP5Lyg57uZ5Yqo55S75YWD57Sg55qEIHN0b3BBbmltYXRlIOaWueazlVxuICAgICAqL1xuICAgIFRpbWVsaW5lLnByb3RvdHlwZS5zdG9wQWxsQW5pbWF0aW9ucyA9IGZ1bmN0aW9uICh0b0VuZCkge1xuICAgICAgICBpZiAodG9FbmQgPT09IHZvaWQgMCkgeyB0b0VuZCA9IHRydWU7IH1cbiAgICAgICAgdGhpcy5hbmltYXRvcnMuZm9yRWFjaChmdW5jdGlvbiAoYW5pbWF0b3IpIHtcbiAgICAgICAgICAgIGFuaW1hdG9yLnN0b3BBbmltYXRlKHRvRW5kKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYW5pbWF0b3JzID0gW107XG4gICAgICAgIHRoaXMuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluW9k+WJjeaXtumXtFxuICAgICAqL1xuICAgIFRpbWVsaW5lLnByb3RvdHlwZS5nZXRUaW1lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50O1xuICAgIH07XG4gICAgcmV0dXJuIFRpbWVsaW5lO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRpbWVsaW5lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGltZWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiBkZWZhdWx0XzEoc2hhcGUpIHtcbiAgICB2YXIgX2EgPSBzaGFwZS5hdHRyKCksIHggPSBfYS54LCB5ID0gX2EueSwgciA9IF9hLnI7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCAtIHIsXG4gICAgICAgIHk6IHkgLSByLFxuICAgICAgICB3aWR0aDogciAqIDIsXG4gICAgICAgIGhlaWdodDogciAqIDIsXG4gICAgfTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGRlZmF1bHRfMTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNpcmNsZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGRlZmF1bHRfMShzaGFwZSkge1xuICAgIHZhciBhdHRycyA9IHNoYXBlLmF0dHIoKTtcbiAgICB2YXIgeCA9IGF0dHJzLngsIHkgPSBhdHRycy55LCByeCA9IGF0dHJzLnJ4LCByeSA9IGF0dHJzLnJ5O1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHggLSByeCxcbiAgICAgICAgeTogeSAtIHJ5LFxuICAgICAgICB3aWR0aDogcnggKiAyLFxuICAgICAgICBoZWlnaHQ6IHJ5ICogMixcbiAgICB9O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZGVmYXVsdF8xO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxsaXBzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciByZWdpc3Rlcl8xID0gcmVxdWlyZShcIi4vcmVnaXN0ZXJcIik7XG5leHBvcnRzLmdldEJCb3hNZXRob2QgPSByZWdpc3Rlcl8xLmdldE1ldGhvZDtcbnZhciByZWN0XzEgPSByZXF1aXJlKFwiLi9yZWN0XCIpO1xudmFyIGNpcmNsZV8xID0gcmVxdWlyZShcIi4vY2lyY2xlXCIpO1xudmFyIHBvbHlsaW5lXzEgPSByZXF1aXJlKFwiLi9wb2x5bGluZVwiKTtcbnZhciBwb2x5Z29uXzEgPSByZXF1aXJlKFwiLi9wb2x5Z29uXCIpO1xudmFyIHRleHRfMSA9IHJlcXVpcmUoXCIuL3RleHRcIik7XG52YXIgcGF0aF8xID0gcmVxdWlyZShcIi4vcGF0aFwiKTtcbnZhciBsaW5lXzEgPSByZXF1aXJlKFwiLi9saW5lXCIpO1xudmFyIGVsbGlwc2VfMSA9IHJlcXVpcmUoXCIuL2VsbGlwc2VcIik7XG5yZWdpc3Rlcl8xLnJlZ2lzdGVyKCdyZWN0JywgcmVjdF8xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlcignaW1hZ2UnLCByZWN0XzEuZGVmYXVsdCk7IC8vIGltYWdlIOS9v+eUqCByZWN0IOeahOWMheWbtOebkuiuoeeul1xucmVnaXN0ZXJfMS5yZWdpc3RlcignY2lyY2xlJywgY2lyY2xlXzEuZGVmYXVsdCk7XG5yZWdpc3Rlcl8xLnJlZ2lzdGVyKCdtYXJrZXInLCBjaXJjbGVfMS5kZWZhdWx0KTsgLy8gbWFya2VyIOS9v+eUqCBjaXJjbGUg55qE6K6h566X5pa55qGIXG5yZWdpc3Rlcl8xLnJlZ2lzdGVyKCdwb2x5bGluZScsIHBvbHlsaW5lXzEuZGVmYXVsdCk7XG5yZWdpc3Rlcl8xLnJlZ2lzdGVyKCdwb2x5Z29uJywgcG9seWdvbl8xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlcigndGV4dCcsIHRleHRfMS5kZWZhdWx0KTtcbnJlZ2lzdGVyXzEucmVnaXN0ZXIoJ3BhdGgnLCBwYXRoXzEuZGVmYXVsdCk7XG5yZWdpc3Rlcl8xLnJlZ2lzdGVyKCdsaW5lJywgbGluZV8xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlcignZWxsaXBzZScsIGVsbGlwc2VfMS5kZWZhdWx0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG5mdW5jdGlvbiBkZWZhdWx0XzEoc2hhcGUpIHtcbiAgICB2YXIgYXR0cnMgPSBzaGFwZS5hdHRyKCk7XG4gICAgdmFyIHgxID0gYXR0cnMueDEsIHkxID0gYXR0cnMueTEsIHgyID0gYXR0cnMueDIsIHkyID0gYXR0cnMueTI7XG4gICAgdmFyIG1pblggPSBNYXRoLm1pbih4MSwgeDIpO1xuICAgIHZhciBtYXhYID0gTWF0aC5tYXgoeDEsIHgyKTtcbiAgICB2YXIgbWluWSA9IE1hdGgubWluKHkxLCB5Mik7XG4gICAgdmFyIG1heFkgPSBNYXRoLm1heCh5MSwgeTIpO1xuICAgIHZhciBiYm94ID0ge1xuICAgICAgICBtaW5YOiBtaW5YLFxuICAgICAgICBtYXhYOiBtYXhYLFxuICAgICAgICBtaW5ZOiBtaW5ZLFxuICAgICAgICBtYXhZOiBtYXhZLFxuICAgIH07XG4gICAgYmJveCA9IHV0aWxfMS5tZXJnZUFycm93QkJveChzaGFwZSwgYmJveCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogYmJveC5taW5YLFxuICAgICAgICB5OiBiYm94Lm1pblksXG4gICAgICAgIHdpZHRoOiBiYm94Lm1heFggLSBiYm94Lm1pblgsXG4gICAgICAgIGhlaWdodDogYmJveC5tYXhZIC0gYmJveC5taW5ZLFxuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBkZWZhdWx0XzE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHF1YWRyYXRpY18xID0gcmVxdWlyZShcIkBhbnR2L2ctbWF0aC9saWIvcXVhZHJhdGljXCIpO1xudmFyIGN1YmljXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi9jdWJpY1wiKTtcbnZhciBhcmNfMSA9IHJlcXVpcmUoXCJAYW50di9nLW1hdGgvbGliL2FyY1wiKTtcbnZhciBwYXRoXzJfc2VnbWVudHNfMSA9IHJlcXVpcmUoXCJAYW50di9wYXRoLXV0aWwvbGliL3BhdGgtMi1zZWdtZW50c1wiKTtcbnZhciBpc19udW1iZXJfZXF1YWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1udW1iZXItZXF1YWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGdldFBhdGhCb3goc2VnbWVudHMsIGxpbmVXaWR0aCkge1xuICAgIHZhciB4QXJyID0gW107XG4gICAgdmFyIHlBcnIgPSBbXTtcbiAgICB2YXIgc2VnbWVudHNXaXRoQW5nbGUgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzZWdtZW50ID0gc2VnbWVudHNbaV07XG4gICAgICAgIHZhciBjdXJyZW50UG9pbnQgPSBzZWdtZW50LmN1cnJlbnRQb2ludCwgcGFyYW1zID0gc2VnbWVudC5wYXJhbXMsIHByZVBvaW50ID0gc2VnbWVudC5wcmVQb2ludDtcbiAgICAgICAgdmFyIGJveCA9IHZvaWQgMDtcbiAgICAgICAgc3dpdGNoIChzZWdtZW50LmNvbW1hbmQpIHtcbiAgICAgICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgICAgICAgIGJveCA9IHF1YWRyYXRpY18xLmRlZmF1bHQuYm94KHByZVBvaW50WzBdLCBwcmVQb2ludFsxXSwgcGFyYW1zWzFdLCBwYXJhbXNbMl0sIHBhcmFtc1szXSwgcGFyYW1zWzRdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0MnOlxuICAgICAgICAgICAgICAgIGJveCA9IGN1YmljXzEuZGVmYXVsdC5ib3gocHJlUG9pbnRbMF0sIHByZVBvaW50WzFdLCBwYXJhbXNbMV0sIHBhcmFtc1syXSwgcGFyYW1zWzNdLCBwYXJhbXNbNF0sIHBhcmFtc1s1XSwgcGFyYW1zWzZdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgICAgIHZhciBhcmNQYXJhbXMgPSBzZWdtZW50LmFyY1BhcmFtcztcbiAgICAgICAgICAgICAgICBib3ggPSBhcmNfMS5kZWZhdWx0LmJveChhcmNQYXJhbXMuY3gsIGFyY1BhcmFtcy5jeSwgYXJjUGFyYW1zLnJ4LCBhcmNQYXJhbXMucnksIGFyY1BhcmFtcy54Um90YXRpb24sIGFyY1BhcmFtcy5zdGFydEFuZ2xlLCBhcmNQYXJhbXMuZW5kQW5nbGUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB4QXJyLnB1c2goY3VycmVudFBvaW50WzBdKTtcbiAgICAgICAgICAgICAgICB5QXJyLnB1c2goY3VycmVudFBvaW50WzFdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoYm94KSB7XG4gICAgICAgICAgICBzZWdtZW50LmJveCA9IGJveDtcbiAgICAgICAgICAgIHhBcnIucHVzaChib3gueCwgYm94LnggKyBib3gud2lkdGgpO1xuICAgICAgICAgICAgeUFyci5wdXNoKGJveC55LCBib3gueSArIGJveC5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW5lV2lkdGggJiYgKHNlZ21lbnQuY29tbWFuZCA9PT0gJ0wnIHx8IHNlZ21lbnQuY29tbWFuZCA9PT0gJ00nKSAmJiBzZWdtZW50LnByZVBvaW50ICYmIHNlZ21lbnQubmV4dFBvaW50KSB7XG4gICAgICAgICAgICBzZWdtZW50c1dpdGhBbmdsZS5wdXNoKHNlZ21lbnQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIGJib3ggY2FsY3VsYXRpb24gc2hvdWxkIGlnbm9yZSBOYU4gZm9yIHBhdGggYXR0cmlidXRlXG4gICAgLy8gcmVmOiBodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL2cvaXNzdWVzLzIxMFxuICAgIHhBcnIgPSB4QXJyLmZpbHRlcihmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gIU51bWJlci5pc05hTihpdGVtKTsgfSk7XG4gICAgeUFyciA9IHlBcnIuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiAhTnVtYmVyLmlzTmFOKGl0ZW0pOyB9KTtcbiAgICB2YXIgbWluWCA9IE1hdGgubWluLmFwcGx5KG51bGwsIHhBcnIpO1xuICAgIHZhciBtaW5ZID0gTWF0aC5taW4uYXBwbHkobnVsbCwgeUFycik7XG4gICAgdmFyIG1heFggPSBNYXRoLm1heC5hcHBseShudWxsLCB4QXJyKTtcbiAgICB2YXIgbWF4WSA9IE1hdGgubWF4LmFwcGx5KG51bGwsIHlBcnIpO1xuICAgIGlmIChzZWdtZW50c1dpdGhBbmdsZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IG1pblgsXG4gICAgICAgICAgICB5OiBtaW5ZLFxuICAgICAgICAgICAgd2lkdGg6IG1heFggLSBtaW5YLFxuICAgICAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWdtZW50c1dpdGhBbmdsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VnbWVudCA9IHNlZ21lbnRzV2l0aEFuZ2xlW2ldO1xuICAgICAgICB2YXIgY3VycmVudFBvaW50ID0gc2VnbWVudC5jdXJyZW50UG9pbnQ7XG4gICAgICAgIHZhciBleHRyYSA9IHZvaWQgMDtcbiAgICAgICAgaWYgKGN1cnJlbnRQb2ludFswXSA9PT0gbWluWCkge1xuICAgICAgICAgICAgZXh0cmEgPSBnZXRFeHRyYUZyb21TZWdtZW50V2l0aEFuZ2xlKHNlZ21lbnQsIGxpbmVXaWR0aCk7XG4gICAgICAgICAgICBtaW5YID0gbWluWCAtIGV4dHJhLnhFeHRyYTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjdXJyZW50UG9pbnRbMF0gPT09IG1heFgpIHtcbiAgICAgICAgICAgIGV4dHJhID0gZ2V0RXh0cmFGcm9tU2VnbWVudFdpdGhBbmdsZShzZWdtZW50LCBsaW5lV2lkdGgpO1xuICAgICAgICAgICAgbWF4WCA9IG1heFggKyBleHRyYS54RXh0cmE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN1cnJlbnRQb2ludFsxXSA9PT0gbWluWSkge1xuICAgICAgICAgICAgZXh0cmEgPSBnZXRFeHRyYUZyb21TZWdtZW50V2l0aEFuZ2xlKHNlZ21lbnQsIGxpbmVXaWR0aCk7XG4gICAgICAgICAgICBtaW5ZID0gbWluWSAtIGV4dHJhLnlFeHRyYTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjdXJyZW50UG9pbnRbMV0gPT09IG1heFkpIHtcbiAgICAgICAgICAgIGV4dHJhID0gZ2V0RXh0cmFGcm9tU2VnbWVudFdpdGhBbmdsZShzZWdtZW50LCBsaW5lV2lkdGgpO1xuICAgICAgICAgICAgbWF4WSA9IG1heFkgKyBleHRyYS55RXh0cmE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogbWluWCxcbiAgICAgICAgeTogbWluWSxcbiAgICAgICAgd2lkdGg6IG1heFggLSBtaW5YLFxuICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgIH07XG59XG5mdW5jdGlvbiBnZXRFeHRyYUZyb21TZWdtZW50V2l0aEFuZ2xlKHNlZ21lbnQsIGxpbmVXaWR0aCkge1xuICAgIHZhciBwcmVQb2ludCA9IHNlZ21lbnQucHJlUG9pbnQsIGN1cnJlbnRQb2ludCA9IHNlZ21lbnQuY3VycmVudFBvaW50LCBuZXh0UG9pbnQgPSBzZWdtZW50Lm5leHRQb2ludDtcbiAgICB2YXIgY3VycmVudEFuZFByZSA9IE1hdGgucG93KGN1cnJlbnRQb2ludFswXSAtIHByZVBvaW50WzBdLCAyKSArIE1hdGgucG93KGN1cnJlbnRQb2ludFsxXSAtIHByZVBvaW50WzFdLCAyKTtcbiAgICB2YXIgY3VycmVudEFuZE5leHQgPSBNYXRoLnBvdyhjdXJyZW50UG9pbnRbMF0gLSBuZXh0UG9pbnRbMF0sIDIpICsgTWF0aC5wb3coY3VycmVudFBvaW50WzFdIC0gbmV4dFBvaW50WzFdLCAyKTtcbiAgICB2YXIgcHJlQW5kTmV4dCA9IE1hdGgucG93KHByZVBvaW50WzBdIC0gbmV4dFBvaW50WzBdLCAyKSArIE1hdGgucG93KHByZVBvaW50WzFdIC0gbmV4dFBvaW50WzFdLCAyKTtcbiAgICAvLyDku6UgY3VycmVudFBvaW50IOS4uumhtueCueeahOWkueinklxuICAgIHZhciBjdXJyZW50QW5nbGUgPSBNYXRoLmFjb3MoKGN1cnJlbnRBbmRQcmUgKyBjdXJyZW50QW5kTmV4dCAtIHByZUFuZE5leHQpIC8gKDIgKiBNYXRoLnNxcnQoY3VycmVudEFuZFByZSkgKiBNYXRoLnNxcnQoY3VycmVudEFuZE5leHQpKSk7XG4gICAgLy8g5aS56KeS5Li656m644CBIDAg5oiWIFBJIOaXtu+8jOS4jemcgOimgeiuoeeul+WkueinkuWkhOeahOmineWkluWuveW6plxuICAgIC8vIOazqOaEjzog55Sx5LqO6K6h566X57K+5bqm6Zeu6aKY77yM5aS56KeS5Li6IDAg55qE5oOF5Ya16K6h566X5Ye65p2l55qE6KeS5bqm5Y+v6IO95piv5LiA5Liq5b6I5bCP55qE5YC877yM6L+Y6ZyA6KaB5Yik5pat5YW25LiOIDAg5piv5ZCm6L+R5Ly855u4562JXG4gICAgaWYgKCFjdXJyZW50QW5nbGUgfHwgTWF0aC5zaW4oY3VycmVudEFuZ2xlKSA9PT0gMCB8fCBpc19udW1iZXJfZXF1YWxfMS5kZWZhdWx0KGN1cnJlbnRBbmdsZSwgMCkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHhFeHRyYTogMCxcbiAgICAgICAgICAgIHlFeHRyYTogMCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgdmFyIHhBbmdsZSA9IE1hdGguYWJzKE1hdGguYXRhbjIobmV4dFBvaW50WzFdIC0gY3VycmVudFBvaW50WzFdLCBuZXh0UG9pbnRbMF0gLSBjdXJyZW50UG9pbnRbMF0pKTtcbiAgICB2YXIgeUFuZ2xlID0gTWF0aC5hYnMoTWF0aC5hdGFuMihuZXh0UG9pbnRbMF0gLSBjdXJyZW50UG9pbnRbMF0sIG5leHRQb2ludFsxXSAtIGN1cnJlbnRQb2ludFsxXSkpO1xuICAgIC8vIOWwhuWkueinkui9rOS4uumUkOinklxuICAgIHhBbmdsZSA9IHhBbmdsZSA+IE1hdGguUEkgLyAyID8gTWF0aC5QSSAtIHhBbmdsZSA6IHhBbmdsZTtcbiAgICB5QW5nbGUgPSB5QW5nbGUgPiBNYXRoLlBJIC8gMiA/IE1hdGguUEkgLSB5QW5nbGUgOiB5QW5nbGU7XG4gICAgLy8g6L+Z6YeM5LiN6ICD6JmR5Zyo5rC05bmz5ZKM5Z6C55u05pa55ZCR55qE5oqV5b2x77yM55u05o6l5L2/55So5pyA5aSn5beu5YC8XG4gICAgLy8g55Sx5LqO5LiK5bGC57uf5LiA5Yqg5YeP5LqG5LqM5YiG5LmL5LiA57q/5a6977yM6L+Z6YeM6ZyA6KaB6L+b6KGM5byl6KGlXG4gICAgdmFyIGV4dHJhID0ge1xuICAgICAgICAvLyDmsLTlubPmlrnlkJHmipXlvbFcbiAgICAgICAgeEV4dHJhOiBNYXRoLmNvcyhjdXJyZW50QW5nbGUgLyAyIC0geEFuZ2xlKSAqICgobGluZVdpZHRoIC8gMikgKiAoMSAvIE1hdGguc2luKGN1cnJlbnRBbmdsZSAvIDIpKSkgLSBsaW5lV2lkdGggLyAyIHx8IDAsXG4gICAgICAgIC8vIOWeguebtOaWueWQkeaKleW9sVxuICAgICAgICB5RXh0cmE6IE1hdGguY29zKHlBbmdsZSAtIGN1cnJlbnRBbmdsZSAvIDIpICogKChsaW5lV2lkdGggLyAyKSAqICgxIC8gTWF0aC5zaW4oY3VycmVudEFuZ2xlIC8gMikpKSAtIGxpbmVXaWR0aCAvIDIgfHwgMCxcbiAgICB9O1xuICAgIHJldHVybiBleHRyYTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRfMShzaGFwZSkge1xuICAgIHZhciBhdHRycyA9IHNoYXBlLmF0dHIoKTtcbiAgICB2YXIgcGF0aCA9IGF0dHJzLnBhdGgsIHN0cm9rZSA9IGF0dHJzLnN0cm9rZTtcbiAgICB2YXIgbGluZVdpZHRoID0gc3Ryb2tlID8gYXR0cnMubGluZVdpZHRoIDogMDsgLy8g5Y+q5pyJ5pyJIHN0cm9rZSDml7bvvIxsaW5lV2lkdGgg5omN55Sf5pWIXG4gICAgdmFyIHNlZ21lbnRzID0gc2hhcGUuZ2V0KCdzZWdtZW50cycpIHx8IHBhdGhfMl9zZWdtZW50c18xLmRlZmF1bHQocGF0aCk7XG4gICAgdmFyIF9hID0gZ2V0UGF0aEJveChzZWdtZW50cywgbGluZVdpZHRoKSwgeCA9IF9hLngsIHkgPSBfYS55LCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgdmFyIGJib3ggPSB7XG4gICAgICAgIG1pblg6IHgsXG4gICAgICAgIG1pblk6IHksXG4gICAgICAgIG1heFg6IHggKyB3aWR0aCxcbiAgICAgICAgbWF4WTogeSArIGhlaWdodCxcbiAgICB9O1xuICAgIGJib3ggPSB1dGlsXzEubWVyZ2VBcnJvd0JCb3goc2hhcGUsIGJib3gpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IGJib3gubWluWCxcbiAgICAgICAgeTogYmJveC5taW5ZLFxuICAgICAgICB3aWR0aDogYmJveC5tYXhYIC0gYmJveC5taW5YLFxuICAgICAgICBoZWlnaHQ6IGJib3gubWF4WSAtIGJib3gubWluWSxcbiAgICB9O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZGVmYXVsdF8xO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi91dGlsXCIpO1xuZnVuY3Rpb24gZGVmYXVsdF8xKHNoYXBlKSB7XG4gICAgdmFyIGF0dHJzID0gc2hhcGUuYXR0cigpO1xuICAgIHZhciBwb2ludHMgPSBhdHRycy5wb2ludHM7XG4gICAgdmFyIHhBcnIgPSBbXTtcbiAgICB2YXIgeUFyciA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgeEFyci5wdXNoKHBvaW50WzBdKTtcbiAgICAgICAgeUFyci5wdXNoKHBvaW50WzFdKTtcbiAgICB9XG4gICAgcmV0dXJuIHV0aWxfMS5nZXRCQm94QnlBcnJheSh4QXJyLCB5QXJyKTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGRlZmF1bHRfMTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbHlnb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L2ctbWF0aC9saWIvdXRpbFwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuZnVuY3Rpb24gZGVmYXVsdF8xKHNoYXBlKSB7XG4gICAgdmFyIGF0dHJzID0gc2hhcGUuYXR0cigpO1xuICAgIHZhciBwb2ludHMgPSBhdHRycy5wb2ludHM7XG4gICAgdmFyIHhBcnIgPSBbXTtcbiAgICB2YXIgeUFyciA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgeEFyci5wdXNoKHBvaW50WzBdKTtcbiAgICAgICAgeUFyci5wdXNoKHBvaW50WzFdKTtcbiAgICB9XG4gICAgdmFyIF9hID0gdXRpbF8xLmdldEJCb3hCeUFycmF5KHhBcnIsIHlBcnIpLCB4ID0gX2EueCwgeSA9IF9hLnksIHdpZHRoID0gX2Eud2lkdGgsIGhlaWdodCA9IF9hLmhlaWdodDtcbiAgICB2YXIgYmJveCA9IHtcbiAgICAgICAgbWluWDogeCxcbiAgICAgICAgbWluWTogeSxcbiAgICAgICAgbWF4WDogeCArIHdpZHRoLFxuICAgICAgICBtYXhZOiB5ICsgaGVpZ2h0LFxuICAgIH07XG4gICAgYmJveCA9IHV0aWxfMi5tZXJnZUFycm93QkJveChzaGFwZSwgYmJveCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogYmJveC5taW5YLFxuICAgICAgICB5OiBiYm94Lm1pblksXG4gICAgICAgIHdpZHRoOiBiYm94Lm1heFggLSBiYm94Lm1pblgsXG4gICAgICAgIGhlaWdodDogYmJveC5tYXhZIC0gYmJveC5taW5ZLFxuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBkZWZhdWx0XzE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2x5bGluZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGRlZmF1bHRfMShzaGFwZSkge1xuICAgIHZhciBhdHRycyA9IHNoYXBlLmF0dHIoKTtcbiAgICB2YXIgeCA9IGF0dHJzLngsIHkgPSBhdHRycy55LCB3aWR0aCA9IGF0dHJzLndpZHRoLCBoZWlnaHQgPSBhdHRycy5oZWlnaHQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB9O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZGVmYXVsdF8xO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBjYWNoZSA9IG5ldyBNYXAoKTtcbi8qKlxuICog5rOo5YaM6K6h566X5YyF5Zu055uS55qE566X5rOVXG4gKiBAcGFyYW0gdHlwZSDmlrnms5XlkI1cbiAqIEBwYXJhbSBtZXRob2Qg5pa55rOVXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyKHR5cGUsIG1ldGhvZCkge1xuICAgIGNhY2hlLnNldCh0eXBlLCBtZXRob2QpO1xufVxuZXhwb3J0cy5yZWdpc3RlciA9IHJlZ2lzdGVyO1xuLyoqXG4gKiDojrflj5borqHnrpfljIXlm7Tnm5LnmoTnrpfms5VcbiAqIEBwYXJhbSB0eXBlIOaWueazleWQjVxuICovXG5mdW5jdGlvbiBnZXRNZXRob2QodHlwZSkge1xuICAgIHJldHVybiBjYWNoZS5nZXQodHlwZSk7XG59XG5leHBvcnRzLmdldE1ldGhvZCA9IGdldE1ldGhvZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlZ2lzdGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRleHRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3RleHRcIik7XG5mdW5jdGlvbiBkZWZhdWx0XzEoc2hhcGUpIHtcbiAgICB2YXIgYXR0cnMgPSBzaGFwZS5hdHRyKCk7XG4gICAgdmFyIHggPSBhdHRycy54LCB5ID0gYXR0cnMueSwgdGV4dCA9IGF0dHJzLnRleHQsIGZvbnRTaXplID0gYXR0cnMuZm9udFNpemUsIGxpbmVIZWlnaHQgPSBhdHRycy5saW5lSGVpZ2h0O1xuICAgIHZhciBmb250ID0gYXR0cnMuZm9udDtcbiAgICBpZiAoIWZvbnQpIHtcbiAgICAgICAgLy8g5aaC5p6c5pyq57uE6KOFIGZvbnRcbiAgICAgICAgZm9udCA9IHRleHRfMS5hc3NlbWJsZUZvbnQoYXR0cnMpO1xuICAgIH1cbiAgICB2YXIgd2lkdGggPSB0ZXh0XzEuZ2V0VGV4dFdpZHRoKHRleHQsIGZvbnQpO1xuICAgIHZhciBiYm94O1xuICAgIGlmICghd2lkdGgpIHtcbiAgICAgICAgLy8g5aaC5p6cd2lkdGjkuI3lrZjlnKjvvIzlm5vngrnlhbHlhbblrp7ngrlcbiAgICAgICAgYmJveCA9IHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDAsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgdGV4dEFsaWduID0gYXR0cnMudGV4dEFsaWduLCB0ZXh0QmFzZWxpbmUgPSBhdHRycy50ZXh0QmFzZWxpbmU7XG4gICAgICAgIHZhciBoZWlnaHQgPSB0ZXh0XzEuZ2V0VGV4dEhlaWdodCh0ZXh0LCBmb250U2l6ZSwgbGluZUhlaWdodCk7IC8vIGF0dHJzLmhlaWdodFxuICAgICAgICAvLyDpu5jorqTlt6blj7Plr7npvZDvvJpsZWZ0LCDpu5jorqTkuIrkuIvlr7npvZAgYm90dG9tXG4gICAgICAgIHZhciBwb2ludCA9IHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5IC0gaGVpZ2h0LFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGV4dEFsaWduKSB7XG4gICAgICAgICAgICBpZiAodGV4dEFsaWduID09PSAnZW5kJyB8fCB0ZXh0QWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgICAgICBwb2ludC54IC09IHdpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGV4dEFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgICAgIHBvaW50LnggLT0gd2lkdGggLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0ZXh0QmFzZWxpbmUpIHtcbiAgICAgICAgICAgIGlmICh0ZXh0QmFzZWxpbmUgPT09ICd0b3AnKSB7XG4gICAgICAgICAgICAgICAgcG9pbnQueSArPSBoZWlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0ZXh0QmFzZWxpbmUgPT09ICdtaWRkbGUnKSB7XG4gICAgICAgICAgICAgICAgcG9pbnQueSArPSBoZWlnaHQgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJib3ggPSB7XG4gICAgICAgICAgICB4OiBwb2ludC54LFxuICAgICAgICAgICAgeTogcG9pbnQueSxcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gYmJveDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGRlZmF1bHRfMTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRleHQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vLyDlkIjlubbljIXlm7Tnm5JcbmZ1bmN0aW9uIG1lcmdlQkJveChiYm94MSwgYmJveDIpIHtcbiAgICBpZiAoIWJib3gxIHx8ICFiYm94Mikge1xuICAgICAgICByZXR1cm4gYmJveDEgfHwgYmJveDI7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIG1pblg6IE1hdGgubWluKGJib3gxLm1pblgsIGJib3gyLm1pblgpLFxuICAgICAgICBtaW5ZOiBNYXRoLm1pbihiYm94MS5taW5ZLCBiYm94Mi5taW5ZKSxcbiAgICAgICAgbWF4WDogTWF0aC5tYXgoYmJveDEubWF4WCwgYmJveDIubWF4WCksXG4gICAgICAgIG1heFk6IE1hdGgubWF4KGJib3gxLm1heFksIGJib3gyLm1heFkpLFxuICAgIH07XG59XG5leHBvcnRzLm1lcmdlQkJveCA9IG1lcmdlQkJveDtcbi8vIOWQiOW5tueureWktOeahOWMheWbtOebklxuZnVuY3Rpb24gbWVyZ2VBcnJvd0JCb3goc2hhcGUsIGJib3gpIHtcbiAgICB2YXIgc3RhcnRBcnJvd1NoYXBlID0gc2hhcGUuZ2V0KCdzdGFydEFycm93U2hhcGUnKTtcbiAgICB2YXIgZW5kQXJyb3dTaGFwZSA9IHNoYXBlLmdldCgnZW5kQXJyb3dTaGFwZScpO1xuICAgIHZhciBzdGFydEFycm93QkJveCA9IG51bGw7XG4gICAgdmFyIGVuZEFycm93QkJveCA9IG51bGw7XG4gICAgaWYgKHN0YXJ0QXJyb3dTaGFwZSkge1xuICAgICAgICBzdGFydEFycm93QkJveCA9IHN0YXJ0QXJyb3dTaGFwZS5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgIGJib3ggPSBtZXJnZUJCb3goYmJveCwgc3RhcnRBcnJvd0JCb3gpO1xuICAgIH1cbiAgICBpZiAoZW5kQXJyb3dTaGFwZSkge1xuICAgICAgICBlbmRBcnJvd0JCb3ggPSBlbmRBcnJvd1NoYXBlLmdldENhbnZhc0JCb3goKTtcbiAgICAgICAgYmJveCA9IG1lcmdlQkJveChiYm94LCBlbmRBcnJvd0JCb3gpO1xuICAgIH1cbiAgICByZXR1cm4gYmJveDtcbn1cbmV4cG9ydHMubWVyZ2VBcnJvd0JCb3ggPSBtZXJnZUFycm93QkJveDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcg5LqL5Lu25aSE55CG5ZmoXG4gKiBAYXV0aG9yIGR4cTYxM0BnbWFpbC5jb21cbiAqL1xudmFyIGdyYXBoX2V2ZW50XzEgPSByZXF1aXJlKFwiLi9ncmFwaC1ldmVudFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbC91dGlsXCIpO1xudmFyIENMSUNLX09GRlNFVCA9IDQwO1xudmFyIExFRlRfQlROX0NPREUgPSAwO1xudmFyIERFTEVHQVRJT05fU1BMSVQgPSAnOic7XG52YXIgRVZFTlRTID0gW1xuICAgICdtb3VzZWRvd24nLFxuICAgICdtb3VzZXVwJyxcbiAgICAnZGJsY2xpY2snLFxuICAgICdtb3VzZW91dCcsXG4gICAgJ21vdXNlb3ZlcicsXG4gICAgJ21vdXNlbW92ZScsXG4gICAgJ21vdXNlbGVhdmUnLFxuICAgICdtb3VzZWVudGVyJyxcbiAgICAndG91Y2hzdGFydCcsXG4gICAgJ3RvdWNobW92ZScsXG4gICAgJ3RvdWNoZW5kJyxcbiAgICAnZHJhZ2VudGVyJyxcbiAgICAnZHJhZ292ZXInLFxuICAgICdkcmFnbGVhdmUnLFxuICAgICdkcm9wJyxcbiAgICAnY29udGV4dG1lbnUnLFxuICAgICdtb3VzZXdoZWVsJyxcbl07XG4vLyDmmK/lkKbmnInlp5TmiZjkuovku7bnm5HlkKxcbmZ1bmN0aW9uIGhhc0RlbGVnYXRpb24oZXZlbnRzLCB0eXBlKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGV2ZW50cykge1xuICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYga2V5LmluZGV4T2YoREVMRUdBVElPTl9TUExJVCArIHR5cGUpID49IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8vIOinpuWPkeebruagh+S6i+S7tu+8jOebruagh+WPquiDveaYryBzaGFwZSDmiJYgY2FudmFzXG5mdW5jdGlvbiBlbWl0VGFyZ2V0RXZlbnQodGFyZ2V0LCB0eXBlLCBldmVudE9iaikge1xuICAgIGV2ZW50T2JqLm5hbWUgPSB0eXBlO1xuICAgIGV2ZW50T2JqLnRhcmdldCA9IHRhcmdldDtcbiAgICBldmVudE9iai5jdXJyZW50VGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGV2ZW50T2JqLmRlbGVnYXRlVGFyZ2V0ID0gdGFyZ2V0O1xuICAgIHRhcmdldC5lbWl0KHR5cGUsIGV2ZW50T2JqKTtcbn1cbi8vIOS6i+S7tuWGkuazoSwgZW50ZXIg5ZKMIGxlYXZlIOmcgOimgeWvuSBmcm9tU2hhcGUg5ZKMIHRvU2hhcGUg6L+b6KGM5Yik5ZCMXG5mdW5jdGlvbiBidWJibGVFdmVudChjb250YWluZXIsIHR5cGUsIGV2ZW50T2JqKSB7XG4gICAgaWYgKGV2ZW50T2JqLmJ1YmJsZXMpIHtcbiAgICAgICAgdmFyIHJlbGF0aXZlU2hhcGUgPSB2b2lkIDA7XG4gICAgICAgIHZhciBpc092ZXJFdmVudCA9IGZhbHNlO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlZW50ZXInKSB7XG4gICAgICAgICAgICByZWxhdGl2ZVNoYXBlID0gZXZlbnRPYmouZnJvbVNoYXBlO1xuICAgICAgICAgICAgaXNPdmVyRXZlbnQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdtb3VzZWxlYXZlJykge1xuICAgICAgICAgICAgaXNPdmVyRXZlbnQgPSB0cnVlO1xuICAgICAgICAgICAgcmVsYXRpdmVTaGFwZSA9IGV2ZW50T2JqLnRvU2hhcGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY2FudmFzIOS4iueahCBtb3VzZWVudGVy77yMIG1vdXNlbGVhdmUg5LqL5Lu277yM5LuF5b2T6L+b5YWl5oiW6ICF56e75Ye6IGNhbnZhcyDml7bop6blj5FcbiAgICAgICAgaWYgKGNvbnRhaW5lci5pc0NhbnZhcygpICYmIGlzT3ZlckV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8g5aaC5p6c55u45YWz5Zu+5b2i5ZCM5b2T5YmN5Zu+5b2i5Zyo5ZCM5LiA5Liq5a655Zmo5YaF77yM5LiN6Kem5Y+R5LqL5Lu2XG4gICAgICAgIGlmIChyZWxhdGl2ZVNoYXBlICYmIHV0aWxfMS5pc1BhcmVudChjb250YWluZXIsIHJlbGF0aXZlU2hhcGUpKSB7XG4gICAgICAgICAgICAvLyDpmLvmraLnu6fnu63lkJHkuIrlhpLms6FcbiAgICAgICAgICAgIGV2ZW50T2JqLmJ1YmJsZXMgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyDkuovku7blkI3np7Dlj6/og73lnKjlp5TmiZjov4fnqIvkuK3ooqvkv67mlLnvvIzlm6DmraTkuovku7blhpLms6Hml7bpnIDopoHph43mlrDorr7nva7kuovku7blkI3np7BcbiAgICAgICAgZXZlbnRPYmoubmFtZSA9IHR5cGU7XG4gICAgICAgIGV2ZW50T2JqLmN1cnJlbnRUYXJnZXQgPSBjb250YWluZXI7XG4gICAgICAgIGV2ZW50T2JqLmRlbGVnYXRlVGFyZ2V0ID0gY29udGFpbmVyO1xuICAgICAgICBjb250YWluZXIuZW1pdCh0eXBlLCBldmVudE9iaik7XG4gICAgfVxufVxudmFyIEV2ZW50Q29udHJvbGxlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBFdmVudENvbnRyb2xsZXIoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIC8vIOato+WcqOiiq+aLluaLveeahOWbvuW9olxuICAgICAgICB0aGlzLmRyYWdnaW5nU2hhcGUgPSBudWxsO1xuICAgICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgICAgIC8vIOW9k+WJjem8oOaghy90b3VjaOaJgOWcqOS9jee9rueahOWbvuW9olxuICAgICAgICB0aGlzLmN1cnJlbnRTaGFwZSA9IG51bGw7XG4gICAgICAgIHRoaXMubW91c2Vkb3duU2hhcGUgPSBudWxsO1xuICAgICAgICB0aGlzLm1vdXNlZG93blBvaW50ID0gbnVsbDtcbiAgICAgICAgLy8g57uf5LiA5aSE55CG5omA5pyJ55qE5Zue6LCDXG4gICAgICAgIHRoaXMuX2V2ZW50Q2FsbGJhY2sgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciB0eXBlID0gZXYudHlwZTtcbiAgICAgICAgICAgIF90aGlzLl90cmlnZ2VyRXZlbnQodHlwZSwgZXYpO1xuICAgICAgICB9O1xuICAgICAgICAvLyDlnKggZG9jdW1lbnQg5aSE55CG5ouW5ou95Yiw55S75biD5aSW55qE5LqL5Lu277yM5aSE55CG5LuO5Zu+5b2i5LiK56e76Zmk55S75biD5pyq6KKr5o2V5o2J55qE6Zeu6aKYXG4gICAgICAgIHRoaXMuX29uRG9jdW1lbnRNb3ZlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgY2FudmFzID0gX3RoaXMuY2FudmFzO1xuICAgICAgICAgICAgdmFyIGVsID0gY2FudmFzLmdldCgnZWwnKTtcbiAgICAgICAgICAgIGlmIChlbCAhPT0gZXYudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN5ZyoIGNhbnZhcyDkuIrnp7vliqhcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuZHJhZ2dpbmcgfHwgX3RoaXMuY3VycmVudFNoYXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb2ludEluZm8gPSBfdGhpcy5fZ2V0UG9pbnRJbmZvKGV2KTtcbiAgICAgICAgICAgICAgICAgICAgLy8g6L+Y5Zyo5ouW5ou96L+H56iL5LitXG4gICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5kcmFnZ2luZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2VtaXRFdmVudCgnZHJhZycsIGV2LCBwb2ludEluZm8sIF90aGlzLmRyYWdnaW5nU2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIOivtOaYjuS7juafkOS4quWbvuW9ouebtOaOpeenu+WKqOWIsOS6hueUu+W4g+Wklumdou+8jFxuICAgICAgICAgICAgICAgICAgICAvLyDkv67lpI3kuoYgbW91c2VsZWF2ZSDnmoQgYnVnIOWQjuS4jeWGjeWHuueOsOi/meenjeaDheWGtVxuICAgICAgICAgICAgICAgICAgICAvLyBpZiAodGhpcy5jdXJyZW50U2hhcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gICB0aGlzLl9lbWl0RXZlbnQoJ21vdXNlbGVhdmUnLCBldiwgcG9pbnRJbmZvLCB0aGlzLmN1cnJlbnRTaGFwZSwgdGhpcy5jdXJyZW50U2hhcGUsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAvLyAgIHRoaXMuY3VycmVudFNoYXBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgLy8g5ZyoIGRvY3VtZW50IOS4iuWkhOeQhuaLluaLveWIsOWklumdou+8jOmHiuaUvum8oOagh+aXtuinpuWPkSBkcmFnZW5kXG4gICAgICAgIHRoaXMuX29uRG9jdW1lbnRNb3VzZVVwID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgY2FudmFzID0gX3RoaXMuY2FudmFzO1xuICAgICAgICAgICAgdmFyIGVsID0gY2FudmFzLmdldCgnZWwnKTtcbiAgICAgICAgICAgIGlmIChlbCAhPT0gZXYudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN5ZyoIGNhbnZhcyDkuIrnp7vliqhcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuZHJhZ2dpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvaW50SW5mbyA9IF90aGlzLl9nZXRQb2ludEluZm8oZXYpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuZHJhZ2dpbmdTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5a2Y5Zyo5ouW5ou955qE5Zu+5b2i77yM5YiZ5Lmf6Kem5Y+RIGRyb3Ag5LqL5Lu2XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fZW1pdEV2ZW50KCdkcm9wJywgZXYsIHBvaW50SW5mbywgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2VtaXRFdmVudCgnZHJhZ2VuZCcsIGV2LCBwb2ludEluZm8sIF90aGlzLmRyYWdnaW5nU2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5fYWZ0ZXJEcmFnKF90aGlzLmRyYWdnaW5nU2hhcGUsIHBvaW50SW5mbywgZXYpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jYW52YXMgPSBjZmcuY2FudmFzO1xuICAgIH1cbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRFdmVudHMoKTtcbiAgICB9O1xuICAgIC8vIOazqOWGjOS6i+S7tlxuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuX2JpbmRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuY2FudmFzLmdldCgnZWwnKTtcbiAgICAgICAgdXRpbF8xLmVhY2goRVZFTlRTLCBmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgX3RoaXMuX2V2ZW50Q2FsbGJhY2spO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGRvY3VtZW50KSB7XG4gICAgICAgICAgICAvLyDlpITnkIbnp7vliqjliLDlpJbpnaLmsqHmnInop6blj5Egc2hhcGUgbW91c2UgbGVhdmUg55qE5LqL5Lu2XG4gICAgICAgICAgICAvLyDlpITnkIbmi5bmi73liLDlpJbpg6jnmoTpl67pophcbiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuX29uRG9jdW1lbnRNb3ZlKTtcbiAgICAgICAgICAgIC8vIOWkhOeQhuaLluaLvei/h+eoi+S4reWcqOWklumDqOmHiuaUvum8oOagh+eahOmXrumimFxuICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuX29uRG9jdW1lbnRNb3VzZVVwKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5riF55CG5LqL5Lu2XG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5fY2xlYXJFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuY2FudmFzLmdldCgnZWwnKTtcbiAgICAgICAgdXRpbF8xLmVhY2goRVZFTlRTLCBmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgX3RoaXMuX2V2ZW50Q2FsbGJhY2spO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGRvY3VtZW50KSB7XG4gICAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLl9vbkRvY3VtZW50TW92ZSk7XG4gICAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5fb25Eb2N1bWVudE1vdXNlVXApO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLl9nZXRFdmVudE9iaiA9IGZ1bmN0aW9uICh0eXBlLCBldmVudCwgcG9pbnQsIHRhcmdldCwgZnJvbVNoYXBlLCB0b1NoYXBlKSB7XG4gICAgICAgIHZhciBldmVudE9iaiA9IG5ldyBncmFwaF9ldmVudF8xLmRlZmF1bHQodHlwZSwgZXZlbnQpO1xuICAgICAgICBldmVudE9iai5mcm9tU2hhcGUgPSBmcm9tU2hhcGU7XG4gICAgICAgIGV2ZW50T2JqLnRvU2hhcGUgPSB0b1NoYXBlO1xuICAgICAgICBldmVudE9iai54ID0gcG9pbnQueDtcbiAgICAgICAgZXZlbnRPYmoueSA9IHBvaW50Lnk7XG4gICAgICAgIGV2ZW50T2JqLmNsaWVudFggPSBwb2ludC5jbGllbnRYO1xuICAgICAgICBldmVudE9iai5jbGllbnRZID0gcG9pbnQuY2xpZW50WTtcbiAgICAgICAgZXZlbnRPYmoucHJvcGFnYXRpb25QYXRoLnB1c2godGFyZ2V0KTtcbiAgICAgICAgLy8g5LqL5Lu255qEeCx55bqU6K+l5piv5Z+65LqO55S75biD5bem5LiK6KeS55qE77yM5LiOY2FudmFz55qEbWF0cml45peg5YWzXG4gICAgICAgIHJldHVybiBldmVudE9iajtcbiAgICB9O1xuICAgIC8vIOagueaNrueCueiOt+WPluWbvuW9ou+8jOaPkOWPluaIkOeLrOeri+aWueazle+8jOS+v+S6juWQjue7reS8mOWMllxuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuX2dldFNoYXBlID0gZnVuY3Rpb24gKHBvaW50LCBldikge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW52YXMuZ2V0U2hhcGUocG9pbnQueCwgcG9pbnQueSwgZXYpO1xuICAgIH07XG4gICAgLy8g6I635Y+W5LqL5Lu255qE5b2T5YmN54K555qE5L+h5oGvXG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5fZ2V0UG9pbnRJbmZvID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmNhbnZhcztcbiAgICAgICAgdmFyIGNsaWVudFBvaW50ID0gY2FudmFzLmdldENsaWVudEJ5RXZlbnQoZXYpO1xuICAgICAgICB2YXIgcG9pbnQgPSBjYW52YXMuZ2V0UG9pbnRCeUV2ZW50KGV2KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHBvaW50LngsXG4gICAgICAgICAgICB5OiBwb2ludC55LFxuICAgICAgICAgICAgY2xpZW50WDogY2xpZW50UG9pbnQueCxcbiAgICAgICAgICAgIGNsaWVudFk6IGNsaWVudFBvaW50LnksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvLyDop6blj5Hkuovku7ZcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLl90cmlnZ2VyRXZlbnQgPSBmdW5jdGlvbiAodHlwZSwgZXYpIHtcbiAgICAgICAgdmFyIHBvaW50SW5mbyA9IHRoaXMuX2dldFBvaW50SW5mbyhldik7XG4gICAgICAgIC8vIOavj+asoemDveiOt+WPluWbvuW9ouacieS4gOWumuaIkOacrO+8jOWQjuacn+WPr+S7peiAg+iZkei/m+ihjOe8k+WtmOetlueVpVxuICAgICAgICB2YXIgc2hhcGUgPSB0aGlzLl9nZXRTaGFwZShwb2ludEluZm8sIGV2KTtcbiAgICAgICAgdmFyIG1ldGhvZCA9IHRoaXNbXCJfb25cIiArIHR5cGVdO1xuICAgICAgICB2YXIgbGVhdmVDYW52YXMgPSBmYWxzZTtcbiAgICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICAgICAgbWV0aG9kLmNhbGwodGhpcywgcG9pbnRJbmZvLCBzaGFwZSwgZXYpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHByZVNoYXBlID0gdGhpcy5jdXJyZW50U2hhcGU7XG4gICAgICAgICAgICAvLyDlpoLmnpzov5vlhaXjgIHnp7vlh7rnlLvluIPml7blrZjlnKjlm77lvaLvvIzliJnopoHliIbliKvop6blj5Hkuovku7ZcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnbW91c2VlbnRlcicgfHwgdHlwZSA9PT0gJ2RyYWdlbnRlcicgfHwgdHlwZSA9PT0gJ21vdXNlb3ZlcicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQodHlwZSwgZXYsIHBvaW50SW5mbywgbnVsbCwgbnVsbCwgc2hhcGUpOyAvLyDlhYjov5vlhaXnlLvluINcbiAgICAgICAgICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KHR5cGUsIGV2LCBwb2ludEluZm8sIHNoYXBlLCBudWxsLCBzaGFwZSk7IC8vIOWGjeinpuWPkeWbvuW9oueahOS6i+S7tlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlZW50ZXInICYmIHRoaXMuZHJhZ2dpbmdTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzmraPlnKjmi5bmi73lm77lvaIsIOWImeinpuWPkSBkcmFnbGVhdmVcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdkcmFnZW50ZXInLCBldiwgcG9pbnRJbmZvLCBudWxsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlID09PSAnbW91c2VsZWF2ZScgfHwgdHlwZSA9PT0gJ2RyYWdsZWF2ZScgfHwgdHlwZSA9PT0gJ21vdXNlb3V0Jykge1xuICAgICAgICAgICAgICAgIGxlYXZlQ2FudmFzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAocHJlU2hhcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KHR5cGUsIGV2LCBwb2ludEluZm8sIHByZVNoYXBlLCBwcmVTaGFwZSwgbnVsbCk7IC8vIOWFiOinpuWPkeWbvuW9oueahOS6i+S7tlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQodHlwZSwgZXYsIHBvaW50SW5mbywgbnVsbCwgcHJlU2hhcGUsIG51bGwpOyAvLyDlho3op6blj5HnprvlvIDnlLvluIPkuovku7ZcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlbGVhdmUnICYmIHRoaXMuZHJhZ2dpbmdTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ2RyYWdsZWF2ZScsIGV2LCBwb2ludEluZm8sIG51bGwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCh0eXBlLCBldiwgcG9pbnRJbmZvLCBzaGFwZSwgbnVsbCwgbnVsbCk7IC8vIOS4gOiIrOS6i+S7tuS4reS4jemcgOimgeiAg+iZkSBmcm9tLCB0b1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghbGVhdmVDYW52YXMpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNoYXBlID0gc2hhcGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5b2T6byg5qCH5LuO55S75biD56e75Yqo5YiwIHNoYXBlIOaIluiAheS7jiBwcmVTaGFwZSDnp7vliqjliLAgc2hhcGUg5pe277yM5bqU55SoIHNoYXBlIOS4iueahOm8oOagh+agt+W8j1xuICAgICAgICBpZiAoc2hhcGUgJiYgIXNoYXBlLmdldCgnZGVzdHJveWVkJykpIHtcbiAgICAgICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmNhbnZhcztcbiAgICAgICAgICAgIHZhciBlbCA9IGNhbnZhcy5nZXQoJ2VsJyk7XG4gICAgICAgICAgICBlbC5zdHlsZS5jdXJzb3IgPSBzaGFwZS5hdHRyKCdjdXJzb3InKSB8fCBjYW52YXMuZ2V0KCdjdXJzb3InKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g6K6w5b2V5LiL54K55Ye755qE5L2N572u44CB5Zu+5b2i77yM5L6/5LqO5ouW5ou95LqL5Lu244CBY2xpY2sg5LqL5Lu255qE5Yik5a6aXG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5fb25tb3VzZWRvd24gPSBmdW5jdGlvbiAocG9pbnRJbmZvLCBzaGFwZSwgZXZlbnQpIHtcbiAgICAgICAgLy8g5Y+q5pyJ6byg5qCH5bem6ZSu55qEIG1vdXNlZG93biDkuovku7bmiY3kvJrorr7nva4gbW91c2Vkb3duU2hhcGUg562J5bGe5oCn77yM6YG/5YWN6byg5qCH5Y+z6ZSu55qEIG1vdXNlZG93biDkuovku7blvJXotbflhbbku5bkuovku7blj5HnlJ9cbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbiA9PT0gTEVGVF9CVE5fQ09ERSkge1xuICAgICAgICAgICAgdGhpcy5tb3VzZWRvd25TaGFwZSA9IHNoYXBlO1xuICAgICAgICAgICAgdGhpcy5tb3VzZWRvd25Qb2ludCA9IHBvaW50SW5mbztcbiAgICAgICAgICAgIHRoaXMubW91c2Vkb3duVGltZVN0YW1wID0gZXZlbnQudGltZVN0YW1wO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2VtaXRFdmVudCgnbW91c2Vkb3duJywgZXZlbnQsIHBvaW50SW5mbywgc2hhcGUsIG51bGwsIG51bGwpOyAvLyBtb3VzZWRvd24g5LiN6ICD6JmRZnJvbVNoYXBlLCB0b1NoYXBlXG4gICAgfTtcbiAgICAvLyBtb3VzZWxlYXZlIOWSjCBtb3VzZWVudGVyIOmDveaYr+aIkOWvueWtmOWcqOeahFxuICAgIC8vIG1vdXNlZW50ZXIg5ZKMIG1vdXNlb3ZlciDlkIzml7bop6blj5FcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLl9lbWl0TW91c2VvdmVyRXZlbnRzID0gZnVuY3Rpb24gKGV2ZW50LCBwb2ludEluZm8sIGZyb21TaGFwZSwgdG9TaGFwZSkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmNhbnZhcy5nZXQoJ2VsJyk7XG4gICAgICAgIGlmIChmcm9tU2hhcGUgIT09IHRvU2hhcGUpIHtcbiAgICAgICAgICAgIGlmIChmcm9tU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ21vdXNlb3V0JywgZXZlbnQsIHBvaW50SW5mbywgZnJvbVNoYXBlLCBmcm9tU2hhcGUsIHRvU2hhcGUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCgnbW91c2VsZWF2ZScsIGV2ZW50LCBwb2ludEluZm8sIGZyb21TaGFwZSwgZnJvbVNoYXBlLCB0b1NoYXBlKTtcbiAgICAgICAgICAgICAgICAvLyDlvZPpvKDmoIfku44gZnJvbVNoYXBlIOenu+WKqOWIsOeUu+W4g+S4iuaXtu+8jOmHjee9rum8oOagh+agt+W8j1xuICAgICAgICAgICAgICAgIGlmICghdG9TaGFwZSB8fCB0b1NoYXBlLmdldCgnZGVzdHJveWVkJykpIHtcbiAgICAgICAgICAgICAgICAgICAgZWwuc3R5bGUuY3Vyc29yID0gdGhpcy5jYW52YXMuZ2V0KCdjdXJzb3InKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodG9TaGFwZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCgnbW91c2VvdmVyJywgZXZlbnQsIHBvaW50SW5mbywgdG9TaGFwZSwgZnJvbVNoYXBlLCB0b1NoYXBlKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ21vdXNlZW50ZXInLCBldmVudCwgcG9pbnRJbmZvLCB0b1NoYXBlLCBmcm9tU2hhcGUsIHRvU2hhcGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyBkcmFnb3ZlciDkuI3nrYnlkIzkuo4gbW91c2VvdmVy77yM6ICM562J5ZCM5LqOIG1vdXNlbW92ZVxuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuX2VtaXREcmFnb3ZlckV2ZW50cyA9IGZ1bmN0aW9uIChldmVudCwgcG9pbnRJbmZvLCBmcm9tU2hhcGUsIHRvU2hhcGUsIGlzQ2FudmFzRW1pdCkge1xuICAgICAgICBpZiAodG9TaGFwZSkge1xuICAgICAgICAgICAgaWYgKHRvU2hhcGUgIT09IGZyb21TaGFwZSkge1xuICAgICAgICAgICAgICAgIGlmIChmcm9tU2hhcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdkcmFnbGVhdmUnLCBldmVudCwgcG9pbnRJbmZvLCBmcm9tU2hhcGUsIGZyb21TaGFwZSwgdG9TaGFwZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCgnZHJhZ2VudGVyJywgZXZlbnQsIHBvaW50SW5mbywgdG9TaGFwZSwgZnJvbVNoYXBlLCB0b1NoYXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNDYW52YXNFbWl0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdkcmFnb3ZlcicsIGV2ZW50LCBwb2ludEluZm8sIHRvU2hhcGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGZyb21TaGFwZSkge1xuICAgICAgICAgICAgLy8gVE9ETzog5q2k5aSE5Yik5pat5pyJ6Zeu6aKY77yM5b2TIGRyYWcg5Zu+5b2i5pe277yM5Lmf5Lya6Kem5Y+R5LiA5qyhIGRyYWdsZWF2ZSDkuovku7bvvIzlm6DkuLrmraTml7YgdG9TaGFwZSDkuLogbnVsbO+8jOi/meS4jeaYr+aJgOacn+acm+eahFxuICAgICAgICAgICAgLy8g57uP6L+H56m655m95Yy65Z+fXG4gICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ2RyYWdsZWF2ZScsIGV2ZW50LCBwb2ludEluZm8sIGZyb21TaGFwZSwgZnJvbVNoYXBlLCB0b1NoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNDYW52YXNFbWl0KSB7XG4gICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ2RyYWdvdmVyJywgZXZlbnQsIHBvaW50SW5mbywgdG9TaGFwZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIGRyYWcg5a6M5oiQ5ZCO77yM6ZyA6KaB5YGa5LiA5Lqb5riF55CG5bel5L2cXG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5fYWZ0ZXJEcmFnID0gZnVuY3Rpb24gKGRyYWdnaW5nU2hhcGUsIHBvaW50SW5mbywgZXZlbnQpIHtcbiAgICAgICAgaWYgKGRyYWdnaW5nU2hhcGUpIHtcbiAgICAgICAgICAgIGRyYWdnaW5nU2hhcGUuc2V0KCdjYXB0dXJlJywgdHJ1ZSk7IC8vIOaBouWkjeWPr+S7peaLvuWPllxuICAgICAgICAgICAgdGhpcy5kcmFnZ2luZ1NoYXBlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgICAgIC8vIGRyYWcg5a6M5oiQ5ZCO77yM5pyJ5Y+v6IO9IGRyYWdnaW5nU2hhcGUg5bey57uP56e75Yqo5Yiw5LqG5b2T5YmN5L2N572u77yM5omA5Lul5LiN6IO955u05o6l5Y+W5b2T5YmN5Zu+5b2iXG4gICAgICAgIHZhciBzaGFwZSA9IHRoaXMuX2dldFNoYXBlKHBvaW50SW5mbywgZXZlbnQpO1xuICAgICAgICAvLyDmi5bmi73lrozmiJDlkI7vvIzov5vooYwgZW50ZXLvvIxsZWF2ZSDnmoTliKTlrppcbiAgICAgICAgaWYgKHNoYXBlICE9PSBkcmFnZ2luZ1NoYXBlKSB7XG4gICAgICAgICAgICB0aGlzLl9lbWl0TW91c2VvdmVyRXZlbnRzKGV2ZW50LCBwb2ludEluZm8sIGRyYWdnaW5nU2hhcGUsIHNoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmN1cnJlbnRTaGFwZSA9IHNoYXBlOyAvLyDmm7TmlrDlvZPliY0gc2hhcGXvvIzlpoLmnpzkuI3lpITnkIblvZPliY3lm77lvaLnmoQgbW91c2VsZWF2ZSDkuovku7blj6/og73kvJrlh7rpl67pophcbiAgICB9O1xuICAgIC8vIOaMiemUruaKrOi1t+aXtu+8jOS8mue7iOatouaLluaLveOAgeinpuWPkeeCueWHu1xuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuX29ubW91c2V1cCA9IGZ1bmN0aW9uIChwb2ludEluZm8sIHNoYXBlLCBldmVudCkge1xuICAgICAgICAvLyBlZXZlbnQuYnV0dG9uID09PSAwIOihqOekuum8oOagh+W3pumUruS6i+S7tu+8jOatpOWkhOWKoOS4iuWIpOaWreS4u+imgeaYr+S4uuS6humBv+WFjeWPs+mUrum8oOagh+S8muinpuWPkSBtb3VzZXVwIOWSjCBjbGljayDkuovku7ZcbiAgICAgICAgLy8gcmVmOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTW91c2VFdmVudC9idXR0b25cbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbiA9PT0gTEVGVF9CVE5fQ09ERSkge1xuICAgICAgICAgICAgdmFyIGRyYWdnaW5nU2hhcGUgPSB0aGlzLmRyYWdnaW5nU2hhcGU7XG4gICAgICAgICAgICBpZiAodGhpcy5kcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIC8vIOWtmOWcqOWPr+S7peaLluaLveeahOWbvuW9ou+8jOWQjOaXtuaLluaLveWIsOWFtuS7luWbvuW9ouS4iuaXtuinpuWPkSBkcmFnIOS6i+S7tlxuICAgICAgICAgICAgICAgIGlmIChkcmFnZ2luZ1NoYXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCgnZHJvcCcsIGV2ZW50LCBwb2ludEluZm8sIHNoYXBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdkcmFnZW5kJywgZXZlbnQsIHBvaW50SW5mbywgZHJhZ2dpbmdTaGFwZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWZ0ZXJEcmFnKGRyYWdnaW5nU2hhcGUsIHBvaW50SW5mbywgZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdtb3VzZXVwJywgZXZlbnQsIHBvaW50SW5mbywgc2hhcGUpOyAvLyDlhYjop6blj5EgbW91c2V1cCDlho3op6blj5EgY2xpY2tcbiAgICAgICAgICAgICAgICBpZiAoc2hhcGUgPT09IHRoaXMubW91c2Vkb3duU2hhcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdjbGljaycsIGV2ZW50LCBwb2ludEluZm8sIHNoYXBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5tb3VzZWRvd25TaGFwZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3VzZWRvd25Qb2ludCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOW9k+inpuWPkea1j+iniOWZqOeahCBkcmFnb3ZlciDkuovku7bml7bvvIzkuI3kvJrlho3op6blj5EgbW91c2Vtb3ZlIO+8jOaJgOS7pei/meaXtuWAmeeahCBkcmFnZW50ZXIsIGRyYWdsZWF2ZSDkuovku7bpnIDopoHph43mlrDlpITnkIZcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLl9vbmRyYWdvdmVyID0gZnVuY3Rpb24gKHBvaW50SW5mbywgc2hhcGUsIGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIOWmguaenOS4jeWvuSBkcmFnb3ZlciDov5vooYwgcHJldmVudERlZmF1bHTvvIzliJnkuI3kvJrlnKggY2FudmFzIOS4iuinpuWPkSBkcm9wIOS6i+S7tlxuICAgICAgICB2YXIgcHJlU2hhcGUgPSB0aGlzLmN1cnJlbnRTaGFwZTtcbiAgICAgICAgdGhpcy5fZW1pdERyYWdvdmVyRXZlbnRzKGV2ZW50LCBwb2ludEluZm8sIHByZVNoYXBlLCBzaGFwZSwgdHJ1ZSk7XG4gICAgfTtcbiAgICAvLyDlpKfph4/nmoTlm77lvaLkuovku7bvvIzpg73pgJrov4cgbW91c2Vtb3ZlIOaooeaLn1xuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuX29ubW91c2Vtb3ZlID0gZnVuY3Rpb24gKHBvaW50SW5mbywgc2hhcGUsIGV2ZW50KSB7XG4gICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmNhbnZhcztcbiAgICAgICAgdmFyIHByZVNoYXBlID0gdGhpcy5jdXJyZW50U2hhcGU7XG4gICAgICAgIHZhciBkcmFnZ2luZ1NoYXBlID0gdGhpcy5kcmFnZ2luZ1NoYXBlO1xuICAgICAgICAvLyDmraPlnKjmi5bmi73ml7ZcbiAgICAgICAgaWYgKHRoaXMuZHJhZ2dpbmcpIHtcbiAgICAgICAgICAgIC8vIOato+WcqOaLluaLveS4rVxuICAgICAgICAgICAgaWYgKGRyYWdnaW5nU2hhcGUpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzmi5bmi73kuoYgc2hhcGUg5Lya6Kem5Y+RIGRyYWdlbnRlciwgZHJhZ2xlYXZlLCBkcmFnb3ZlciDlkowgZHJhZyDkuovku7ZcbiAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RHJhZ292ZXJFdmVudHMoZXZlbnQsIHBvaW50SW5mbywgcHJlU2hhcGUsIHNoYXBlLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDlpoLmnpzlrZjlnKggZHJhZ2dpbmdTaGFwZSDliJnkvJrlnKggZHJhZ2dpbmdTaGFwZSDkuIrop6blj5EgZHJhZyDkuovku7bvvIzlhpLms6HliLAgY2FudmFzIOS4ilxuICAgICAgICAgICAgLy8g5ZCm5YiZ5ZyoIGNhbnZhcyDkuIrop6blj5EgZHJhZyDkuovku7ZcbiAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCgnZHJhZycsIGV2ZW50LCBwb2ludEluZm8sIGRyYWdnaW5nU2hhcGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIG1vdXNlZG93blBvaW50ID0gdGhpcy5tb3VzZWRvd25Qb2ludDtcbiAgICAgICAgICAgIGlmIChtb3VzZWRvd25Qb2ludCkge1xuICAgICAgICAgICAgICAgIC8vIOW9k+m8oOagh+eCueWHu+S4i+WOu++8jOWQjOaXtuenu+WKqOaXtu+8jOi/m+ihjCBkcmFnIOWIpOWumlxuICAgICAgICAgICAgICAgIHZhciBtb3VzZWRvd25TaGFwZSA9IHRoaXMubW91c2Vkb3duU2hhcGU7XG4gICAgICAgICAgICAgICAgdmFyIG5vdyA9IGV2ZW50LnRpbWVTdGFtcDtcbiAgICAgICAgICAgICAgICB2YXIgdGltZVdpbmRvdyA9IG5vdyAtIHRoaXMubW91c2Vkb3duVGltZVN0YW1wO1xuICAgICAgICAgICAgICAgIHZhciBkeCA9IG1vdXNlZG93blBvaW50LmNsaWVudFggLSBwb2ludEluZm8uY2xpZW50WDtcbiAgICAgICAgICAgICAgICB2YXIgZHkgPSBtb3VzZWRvd25Qb2ludC5jbGllbnRZIC0gcG9pbnRJbmZvLmNsaWVudFk7XG4gICAgICAgICAgICAgICAgdmFyIGRpc3QgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgICAgICAgICAgICBpZiAodGltZVdpbmRvdyA+IDEyMCB8fCBkaXN0ID4gQ0xJQ0tfT0ZGU0VUKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtb3VzZWRvd25TaGFwZSAmJiBtb3VzZWRvd25TaGFwZS5nZXQoJ2RyYWdnYWJsZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDorr7nva7kuoYgZHJhZ2dhYmxlIOeahCBzaGFwZSDmiY3og73op6blj5EgZHJhZyDnm7jlhbPnmoTkuovku7ZcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyYWdnaW5nU2hhcGUgPSB0aGlzLm1vdXNlZG93blNoYXBlOyAvLyDmi5bliqjpvKDmoIfngrnkuIvml7bnmoQgc2hhcGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyYWdnaW5nU2hhcGUuc2V0KCdjYXB0dXJlJywgZmFsc2UpOyAvLyDnpoHmraLnu6fnu63mi77lj5bvvIzlkKbliJnml6Dms5Xov5vooYwgZHJhZ292ZXIsZHJhZ2VudGVyLGRyYWdsZWF2ZSxkcm9w55qE5Yik5a6aXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nU2hhcGUgPSBkcmFnZ2luZ1NoYXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ2RyYWdzdGFydCcsIGV2ZW50LCBwb2ludEluZm8sIGRyYWdnaW5nU2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5riF55CG5oyJ5LiL6byg5qCH5pe257yT5a2Y55qE5YC8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vdXNlZG93blNoYXBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW91c2Vkb3duUG9pbnQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFtb3VzZWRvd25TaGFwZSAmJiBjYW52YXMuZ2V0KCdkcmFnZ2FibGUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g6K6+572u5LqGIGRyYWdnYWJsZSDnmoQgY2FudmFzIOaJjeiDveinpuWPkSBkcmFnIOebuOWFs+eahOS6i+S7tlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbWl0RXZlbnQoJ2RyYWdzdGFydCcsIGV2ZW50LCBwb2ludEluZm8sIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5riF55CG5oyJ5LiL6byg5qCH5pe257yT5a2Y55qE5YC8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vdXNlZG93blNoYXBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW91c2Vkb3duUG9pbnQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdE1vdXNlb3ZlckV2ZW50cyhldmVudCwgcG9pbnRJbmZvLCBwcmVTaGFwZSwgc2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdtb3VzZW1vdmUnLCBldmVudCwgcG9pbnRJbmZvLCBzaGFwZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRNb3VzZW92ZXJFdmVudHMoZXZlbnQsIHBvaW50SW5mbywgcHJlU2hhcGUsIHNoYXBlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1pdEV2ZW50KCdtb3VzZW1vdmUnLCBldmVudCwgcG9pbnRJbmZvLCBzaGFwZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5rKh5pyJ5oyJ6ZSu5oyJ5LiL5pe277yM5YiZ55u05o6l6Kem5Y+RIG1vdXNlIG92ZXIg55u45YWz55qE5ZCE56eN5LqL5Lu2XG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdE1vdXNlb3ZlckV2ZW50cyhldmVudCwgcG9pbnRJbmZvLCBwcmVTaGFwZSwgc2hhcGUpO1xuICAgICAgICAgICAgICAgIC8vIOWni+e7iOinpuWPkeenu+WKqFxuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRFdmVudCgnbW91c2Vtb3ZlJywgZXZlbnQsIHBvaW50SW5mbywgc2hhcGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDop6blj5Hkuovku7ZcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLl9lbWl0RXZlbnQgPSBmdW5jdGlvbiAodHlwZSwgZXZlbnQsIHBvaW50SW5mbywgc2hhcGUsIGZyb21TaGFwZSwgdG9TaGFwZSkge1xuICAgICAgICB2YXIgZXZlbnRPYmogPSB0aGlzLl9nZXRFdmVudE9iaih0eXBlLCBldmVudCwgcG9pbnRJbmZvLCBzaGFwZSwgZnJvbVNoYXBlLCB0b1NoYXBlKTtcbiAgICAgICAgLy8g5a2Y5ZyoIHNoYXBlIOinpuWPke+8jOWImei/m+ihjOWGkuazoeWkhOeQhlxuICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICAgIGV2ZW50T2JqLnNoYXBlID0gc2hhcGU7XG4gICAgICAgICAgICAvLyDop6blj5Egc2hhcGUg5LiK55qE5LqL5Lu2XG4gICAgICAgICAgICBlbWl0VGFyZ2V0RXZlbnQoc2hhcGUsIHR5cGUsIGV2ZW50T2JqKTtcbiAgICAgICAgICAgIHZhciBwYXJlbnRfMSA9IHNoYXBlLmdldFBhcmVudCgpO1xuICAgICAgICAgICAgLy8g5omn6KGM5YaS5rOhXG4gICAgICAgICAgICB3aGlsZSAocGFyZW50XzEpIHtcbiAgICAgICAgICAgICAgICAvLyDlp5TmiZjkuovku7bopoHlhYjop6blj5FcbiAgICAgICAgICAgICAgICBwYXJlbnRfMS5lbWl0RGVsZWdhdGlvbih0eXBlLCBldmVudE9iaik7XG4gICAgICAgICAgICAgICAgLy8g5LqL5Lu25YaS5rOh5YGc5q2i77yM5LiN6IO95aao56KN5aeU5omY5LqL5Lu2XG4gICAgICAgICAgICAgICAgaWYgKCFldmVudE9iai5wcm9wYWdhdGlvblN0b3BwZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYnViYmxlRXZlbnQocGFyZW50XzEsIHR5cGUsIGV2ZW50T2JqKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXZlbnRPYmoucHJvcGFnYXRpb25QYXRoLnB1c2gocGFyZW50XzEpO1xuICAgICAgICAgICAgICAgIHBhcmVudF8xID0gcGFyZW50XzEuZ2V0UGFyZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzmsqHmnIkgc2hhcGUg55u05o6l5ZyoIGNhbnZhcyDkuIrop6blj5FcbiAgICAgICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmNhbnZhcztcbiAgICAgICAgICAgIC8vIOebtOaOpeinpuWPkSBjYW52YXMg5LiK55qE5LqL5Lu2XG4gICAgICAgICAgICBlbWl0VGFyZ2V0RXZlbnQoY2FudmFzLCB0eXBlLCBldmVudE9iaik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g5riF55CG5LqL5Lu2XG4gICAgICAgIHRoaXMuX2NsZWFyRXZlbnRzKCk7XG4gICAgICAgIC8vIOa4heeQhue8k+WtmOeahOWvueixoVxuICAgICAgICB0aGlzLmNhbnZhcyA9IG51bGw7XG4gICAgICAgIHRoaXMuY3VycmVudFNoYXBlID0gbnVsbDtcbiAgICAgICAgdGhpcy5kcmFnZ2luZ1NoYXBlID0gbnVsbDtcbiAgICAgICAgdGhpcy5tb3VzZWRvd25Qb2ludCA9IG51bGw7XG4gICAgICAgIHRoaXMubW91c2Vkb3duU2hhcGUgPSBudWxsO1xuICAgICAgICB0aGlzLm1vdXNlZG93blRpbWVTdGFtcCA9IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gRXZlbnRDb250cm9sbGVyO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEV2ZW50Q29udHJvbGxlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LWNvbnRvbGxlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBHcmFwaEV2ZW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdyYXBoRXZlbnQodHlwZSwgZXZlbnQpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOaYr+WQpuWFgeiuuOWGkuazoVxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYnViYmxlcyA9IHRydWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDop6blj5Hlr7nosaFcbiAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOebkeWQrOWvueixoVxuICAgICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jdXJyZW50VGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWnlOaJmOWvueixoVxuICAgICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kZWxlZ2F0ZVRhcmdldCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDlp5TmiZjkuovku7bnm5HlkKzlr7nosaHnmoTku6PnkIblr7nosaHvvIzljbMgZXYuZGVsZWdhdGVPYmplY3QgPSBldi5jdXJyZW50VGFyZ2V0LmdldCgnZGVsZWdhdGVPYmplY3QnKVxuICAgICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kZWxlZ2F0ZU9iamVjdCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDmmK/lkKbpmLvmraLkuobljp/nlJ/kuovku7ZcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOaYr+WQpumYu+atouS8oOaSre+8iOWQkeS4iuWGkuazoe+8iVxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDop6blj5Hkuovku7bnmoTlm77lvaJcbiAgICAgICAgICogQHR5cGUge0lTaGFwZX1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuc2hhcGUgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICog5byA5aeL6Kem5Y+R5LqL5Lu255qE5Zu+5b2iXG4gICAgICAgICAqIEB0eXBlIHtJU2hhcGV9XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmZyb21TaGFwZSA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDkuovku7bnu5PmnZ/ml7bnmoTop6blj5Hlm77lvaJcbiAgICAgICAgICogQHR5cGUge0lTaGFwZX1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudG9TaGFwZSA9IG51bGw7XG4gICAgICAgIC8vIOinpuWPkeS6i+S7tueahOi3r+W+hFxuICAgICAgICB0aGlzLnByb3BhZ2F0aW9uUGF0aCA9IFtdO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLm5hbWUgPSB0eXBlO1xuICAgICAgICB0aGlzLm9yaWdpbmFsRXZlbnQgPSBldmVudDtcbiAgICAgICAgdGhpcy50aW1lU3RhbXAgPSBldmVudC50aW1lU3RhbXA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOmYu+atoua1j+iniOWZqOm7mOiupOeahOihjOS4ulxuICAgICAqL1xuICAgIEdyYXBoRXZlbnQucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy5vcmlnaW5hbEV2ZW50LnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgICAgICB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6Zi75q2i5YaS5rOhXG4gICAgICovXG4gICAgR3JhcGhFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XG4gICAgfTtcbiAgICBHcmFwaEV2ZW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0aGlzLnR5cGU7XG4gICAgICAgIHJldHVybiBcIltFdmVudCAodHlwZT1cIiArIHR5cGUgKyBcIildXCI7XG4gICAgfTtcbiAgICBHcmFwaEV2ZW50LnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIEdyYXBoRXZlbnQucHJvdG90eXBlLnJlc3RvcmUgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgcmV0dXJuIEdyYXBoRXZlbnQ7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JhcGhFdmVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdyYXBoLWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IEcg55qE5Z+656GA5o6l5Y+j5a6a5LmJ5ZKM5omA5pyJ55qE5oq96LGh57G7XG4gKiBAYXV0aG9yIGR4cTYxM0BnbWFpbC5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIFBhdGhVdGlsID0gcmVxdWlyZShcIi4vdXRpbC9wYXRoXCIpO1xuZXhwb3J0cy5QYXRoVXRpbCA9IFBhdGhVdGlsO1xudmFyIHBrZyA9IHJlcXVpcmUoJy4uL3BhY2thZ2UuanNvbicpO1xuZXhwb3J0cy52ZXJzaW9uID0gcGtnLnZlcnNpb247XG52YXIgZ3JhcGhfZXZlbnRfMSA9IHJlcXVpcmUoXCIuL2V2ZW50L2dyYXBoLWV2ZW50XCIpO1xuZXhwb3J0cy5FdmVudCA9IGdyYXBoX2V2ZW50XzEuZGVmYXVsdDtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9hYnN0cmFjdC9iYXNlXCIpO1xuZXhwb3J0cy5CYXNlID0gYmFzZV8xLmRlZmF1bHQ7XG52YXIgY2FudmFzXzEgPSByZXF1aXJlKFwiLi9hYnN0cmFjdC9jYW52YXNcIik7XG5leHBvcnRzLkFic3RyYWN0Q2FudmFzID0gY2FudmFzXzEuZGVmYXVsdDtcbnZhciBncm91cF8xID0gcmVxdWlyZShcIi4vYWJzdHJhY3QvZ3JvdXBcIik7XG5leHBvcnRzLkFic3RyYWN0R3JvdXAgPSBncm91cF8xLmRlZmF1bHQ7XG52YXIgc2hhcGVfMSA9IHJlcXVpcmUoXCIuL2Fic3RyYWN0L3NoYXBlXCIpO1xuZXhwb3J0cy5BYnN0cmFjdFNoYXBlID0gc2hhcGVfMS5kZWZhdWx0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnRlcmZhY2VzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dHlwZXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmlzQ29sb3JQcm9wID0gZnVuY3Rpb24gKHByb3ApIHsgcmV0dXJuIFsnZmlsbCcsICdzdHJva2UnLCAnZmlsbFN0eWxlJywgJ3N0cm9rZVN0eWxlJ10uaW5jbHVkZXMocHJvcCk7IH07XG5leHBvcnRzLmlzR3JhZGllbnRDb2xvciA9IGZ1bmN0aW9uICh2YWwpIHsgcmV0dXJuIC9eW3IsUixMLGxdezF9W1xcc10qXFwoLy50ZXN0KHZhbCk7IH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb2xvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyDnn6npmLXov5DnrpfvvIzmnKzmnaXmmK/opoHlvJXlhaUgZ2wtbWF0cml4LCDkvYbmmK/ogIPomZHliLAgZy1tb2JpbGUg5a+55aSn5bCP5pyJ6ZmQ5Yi277yM5ZCM5pe2IGctd2ViZ2wg5L2/55So55qEIG1hdHJpeCDkuI3kuIDoh7RcbiAqIOaJgOS7pe+8jOi/memHjOS7heWunueOsCAyRCDlh6DkuKrov5DnrpfvvIzkuIrlsYLoh6rlt7HlvJXlhaUgZ2wtbWF0cml4XG4gKiBAYXV0aG9yIGR4cTYxM0BnbWFpbC5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiAz6Zi255+p6Zi155u45LmYXG4gKiBAcGFyYW0ge251bWJlcltdfSBhIOefqemYtTFcbiAqIEBwYXJhbSB7bnVtYmVyW119IGIg55+p6Zi1MlxuICovXG5mdW5jdGlvbiBtdWx0aXBseU1hdHJpeChhLCBiKSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBhMDAgPSBhWzBdO1xuICAgIHZhciBhMDEgPSBhWzFdO1xuICAgIHZhciBhMDIgPSBhWzJdO1xuICAgIHZhciBhMTAgPSBhWzNdO1xuICAgIHZhciBhMTEgPSBhWzRdO1xuICAgIHZhciBhMTIgPSBhWzVdO1xuICAgIHZhciBhMjAgPSBhWzZdO1xuICAgIHZhciBhMjEgPSBhWzddO1xuICAgIHZhciBhMjIgPSBhWzhdO1xuICAgIHZhciBiMDAgPSBiWzBdO1xuICAgIHZhciBiMDEgPSBiWzFdO1xuICAgIHZhciBiMDIgPSBiWzJdO1xuICAgIHZhciBiMTAgPSBiWzNdO1xuICAgIHZhciBiMTEgPSBiWzRdO1xuICAgIHZhciBiMTIgPSBiWzVdO1xuICAgIHZhciBiMjAgPSBiWzZdO1xuICAgIHZhciBiMjEgPSBiWzddO1xuICAgIHZhciBiMjIgPSBiWzhdO1xuICAgIG91dFswXSA9IGIwMCAqIGEwMCArIGIwMSAqIGExMCArIGIwMiAqIGEyMDtcbiAgICBvdXRbMV0gPSBiMDAgKiBhMDEgKyBiMDEgKiBhMTEgKyBiMDIgKiBhMjE7XG4gICAgb3V0WzJdID0gYjAwICogYTAyICsgYjAxICogYTEyICsgYjAyICogYTIyO1xuICAgIG91dFszXSA9IGIxMCAqIGEwMCArIGIxMSAqIGExMCArIGIxMiAqIGEyMDtcbiAgICBvdXRbNF0gPSBiMTAgKiBhMDEgKyBiMTEgKiBhMTEgKyBiMTIgKiBhMjE7XG4gICAgb3V0WzVdID0gYjEwICogYTAyICsgYjExICogYTEyICsgYjEyICogYTIyO1xuICAgIG91dFs2XSA9IGIyMCAqIGEwMCArIGIyMSAqIGExMCArIGIyMiAqIGEyMDtcbiAgICBvdXRbN10gPSBiMjAgKiBhMDEgKyBiMjEgKiBhMTEgKyBiMjIgKiBhMjE7XG4gICAgb3V0WzhdID0gYjIwICogYTAyICsgYjIxICogYTEyICsgYjIyICogYTIyO1xuICAgIHJldHVybiBvdXQ7XG59XG5leHBvcnRzLm11bHRpcGx5TWF0cml4ID0gbXVsdGlwbHlNYXRyaXg7XG4vKipcbiAqIDPpmLbnn6npmLXlkIwy6Zi25ZCR6YeP55u45LmYXG4gKiBAcGFyYW0ge251bWJlcltdfSBtIOefqemYtVxuICogQHBhcmFtIHtudW1iZXJbXX0gdiDkuozpmLblkJHph49cbiAqL1xuZnVuY3Rpb24gbXVsdGlwbHlWZWMyKG0sIHYpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIHggPSB2WzBdO1xuICAgIHZhciB5ID0gdlsxXTtcbiAgICBvdXRbMF0gPSBtWzBdICogeCArIG1bM10gKiB5ICsgbVs2XTtcbiAgICBvdXRbMV0gPSBtWzFdICogeCArIG1bNF0gKiB5ICsgbVs3XTtcbiAgICByZXR1cm4gb3V0O1xufVxuZXhwb3J0cy5tdWx0aXBseVZlYzIgPSBtdWx0aXBseVZlYzI7XG4vKipcbiAqIOefqemYteeahOmAhlxuICogQHBhcmFtIHtudW1iZXJbXX0gYSDnn6npmLVcbiAqL1xuZnVuY3Rpb24gaW52ZXJ0KGEpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIGEwMCA9IGFbMF07XG4gICAgdmFyIGEwMSA9IGFbMV07XG4gICAgdmFyIGEwMiA9IGFbMl07XG4gICAgdmFyIGExMCA9IGFbM107XG4gICAgdmFyIGExMSA9IGFbNF07XG4gICAgdmFyIGExMiA9IGFbNV07XG4gICAgdmFyIGEyMCA9IGFbNl07XG4gICAgdmFyIGEyMSA9IGFbN107XG4gICAgdmFyIGEyMiA9IGFbOF07XG4gICAgdmFyIGIwMSA9IGEyMiAqIGExMSAtIGExMiAqIGEyMTtcbiAgICB2YXIgYjExID0gLWEyMiAqIGExMCArIGExMiAqIGEyMDtcbiAgICB2YXIgYjIxID0gYTIxICogYTEwIC0gYTExICogYTIwO1xuICAgIC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcbiAgICB2YXIgZGV0ID0gYTAwICogYjAxICsgYTAxICogYjExICsgYTAyICogYjIxO1xuICAgIGlmICghZGV0KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkZXQgPSAxLjAgLyBkZXQ7XG4gICAgb3V0WzBdID0gYjAxICogZGV0O1xuICAgIG91dFsxXSA9ICgtYTIyICogYTAxICsgYTAyICogYTIxKSAqIGRldDtcbiAgICBvdXRbMl0gPSAoYTEyICogYTAxIC0gYTAyICogYTExKSAqIGRldDtcbiAgICBvdXRbM10gPSBiMTEgKiBkZXQ7XG4gICAgb3V0WzRdID0gKGEyMiAqIGEwMCAtIGEwMiAqIGEyMCkgKiBkZXQ7XG4gICAgb3V0WzVdID0gKC1hMTIgKiBhMDAgKyBhMDIgKiBhMTApICogZGV0O1xuICAgIG91dFs2XSA9IGIyMSAqIGRldDtcbiAgICBvdXRbN10gPSAoLWEyMSAqIGEwMCArIGEwMSAqIGEyMCkgKiBkZXQ7XG4gICAgb3V0WzhdID0gKGExMSAqIGEwMCAtIGEwMSAqIGExMCkgKiBkZXQ7XG4gICAgcmV0dXJuIG91dDtcbn1cbmV4cG9ydHMuaW52ZXJ0ID0gaW52ZXJ0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWF0cml4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLy8g5YWo5bGA6K6+572u5LiA5Liq5ZSv5LiA56a75bGP55qEIGN0eO+8jOeUqOS6juiuoeeulyBpc1BvaW50SW5QYXRoXG52YXIgb2ZmU2NyZWVuQ3R4ID0gbnVsbDtcbmZ1bmN0aW9uIGdldE9mZlNjcmVlbkNvbnRleHQoKSB7XG4gICAgaWYgKCFvZmZTY3JlZW5DdHgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICBjYW52YXMud2lkdGggPSAxO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gMTtcbiAgICAgICAgb2ZmU2NyZWVuQ3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgfVxuICAgIHJldHVybiBvZmZTY3JlZW5DdHg7XG59XG5leHBvcnRzLmdldE9mZlNjcmVlbkNvbnRleHQgPSBnZXRPZmZTY3JlZW5Db250ZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b2Zmc2NyZWVuLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIFNQQUNFUyA9ICdcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOSc7XG52YXIgUEFUSF9DT01NQU5EID0gbmV3IFJlZ0V4cChcIihbYS16XSlbXCIgKyBTUEFDRVMgKyBcIixdKigoLT9cXFxcZCpcXFxcLj9cXFxcZCooPzplW1xcXFwtK10/XFxcXGQrKT9bXCIgKyBTUEFDRVMgKyBcIl0qLD9bXCIgKyBTUEFDRVMgKyBcIl0qKSspXCIsICdpZycpO1xudmFyIFBBVEhfVkFMVUVTID0gbmV3IFJlZ0V4cChcIigtP1xcXFxkKlxcXFwuP1xcXFxkKig/OmVbXFxcXC0rXT9cXFxcZCspPylbXCIgKyBTUEFDRVMgKyBcIl0qLD9bXCIgKyBTUEFDRVMgKyBcIl0qXCIsICdpZycpO1xuLy8gUGFyc2UgZ2l2ZW4gcGF0aCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBhcnJheXMgb2YgcGF0aCBzZWdtZW50c1xudmFyIHBhcnNlUGF0aFN0cmluZyA9IGZ1bmN0aW9uIChwYXRoU3RyaW5nKSB7XG4gICAgaWYgKCFwYXRoU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAodXRpbF8xLmlzQXJyYXkocGF0aFN0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIHBhdGhTdHJpbmc7XG4gICAgfVxuICAgIHZhciBwYXJhbUNvdW50cyA9IHtcbiAgICAgICAgYTogNyxcbiAgICAgICAgYzogNixcbiAgICAgICAgbzogMixcbiAgICAgICAgaDogMSxcbiAgICAgICAgbDogMixcbiAgICAgICAgbTogMixcbiAgICAgICAgcjogNCxcbiAgICAgICAgcTogNCxcbiAgICAgICAgczogNCxcbiAgICAgICAgdDogMixcbiAgICAgICAgdjogMSxcbiAgICAgICAgdTogMyxcbiAgICAgICAgejogMCxcbiAgICB9O1xuICAgIHZhciBkYXRhID0gW107XG4gICAgU3RyaW5nKHBhdGhTdHJpbmcpLnJlcGxhY2UoUEFUSF9DT01NQU5ELCBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICB2YXIgcGFyYW1zID0gW107XG4gICAgICAgIHZhciBuYW1lID0gYi50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBjLnJlcGxhY2UoUEFUSF9WQUxVRVMsIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICBiICYmIHBhcmFtcy5wdXNoKCtiKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChuYW1lID09PSAnbScgJiYgcGFyYW1zLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgIGRhdGEucHVzaChbYl0uY29uY2F0KHBhcmFtcy5zcGxpY2UoMCwgMikpKTtcbiAgICAgICAgICAgIG5hbWUgPSAnbCc7XG4gICAgICAgICAgICBiID0gYiA9PT0gJ20nID8gJ2wnIDogJ0wnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYW1lID09PSAnbycgJiYgcGFyYW1zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgZGF0YS5wdXNoKFtiLCBwYXJhbXNbMF1dKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmFtZSA9PT0gJ3InKSB7XG4gICAgICAgICAgICBkYXRhLnB1c2goW2JdLmNvbmNhdChwYXJhbXMpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHdoaWxlIChwYXJhbXMubGVuZ3RoID49IHBhcmFtQ291bnRzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5wdXNoKFtiXS5jb25jYXQocGFyYW1zLnNwbGljZSgwLCBwYXJhbUNvdW50c1tuYW1lXSkpKTtcbiAgICAgICAgICAgICAgICBpZiAoIXBhcmFtQ291bnRzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aFN0cmluZztcbiAgICB9KTtcbiAgICByZXR1cm4gZGF0YTtcbn07XG5leHBvcnRzLnBhcnNlUGF0aFN0cmluZyA9IHBhcnNlUGF0aFN0cmluZztcbi8vIGh0dHA6Ly9zY2hlcGVycy5jYy9nZXR0aW5nLXRvLXRoZS1wb2ludFxudmFyIGNhdG11bGxSb21Ub0JlemllciA9IGZ1bmN0aW9uIChjcnAsIHopIHtcbiAgICB2YXIgZCA9IFtdO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBmb3IgKHZhciBpID0gMCwgaUxlbiA9IGNycC5sZW5ndGg7IGlMZW4gLSAyICogIXogPiBpOyBpICs9IDIpIHtcbiAgICAgICAgdmFyIHAgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgeDogK2NycFtpIC0gMl0sXG4gICAgICAgICAgICAgICAgeTogK2NycFtpIC0gMV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHg6ICtjcnBbaV0sXG4gICAgICAgICAgICAgICAgeTogK2NycFtpICsgMV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHg6ICtjcnBbaSArIDJdLFxuICAgICAgICAgICAgICAgIHk6ICtjcnBbaSArIDNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB4OiArY3JwW2kgKyA0XSxcbiAgICAgICAgICAgICAgICB5OiArY3JwW2kgKyA1XSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgICAgIGlmICh6KSB7XG4gICAgICAgICAgICBpZiAoIWkpIHtcbiAgICAgICAgICAgICAgICBwWzBdID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiArY3JwW2lMZW4gLSAyXSxcbiAgICAgICAgICAgICAgICAgICAgeTogK2NycFtpTGVuIC0gMV0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlMZW4gLSA0ID09PSBpKSB7XG4gICAgICAgICAgICAgICAgcFszXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogK2NycFswXSxcbiAgICAgICAgICAgICAgICAgICAgeTogK2NycFsxXSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaUxlbiAtIDIgPT09IGkpIHtcbiAgICAgICAgICAgICAgICBwWzJdID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiArY3JwWzBdLFxuICAgICAgICAgICAgICAgICAgICB5OiArY3JwWzFdLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcFszXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogK2NycFsyXSxcbiAgICAgICAgICAgICAgICAgICAgeTogK2NycFszXSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGlMZW4gLSA0ID09PSBpKSB7XG4gICAgICAgICAgICAgICAgcFszXSA9IHBbMl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghaSkge1xuICAgICAgICAgICAgICAgIHBbMF0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6ICtjcnBbaV0sXG4gICAgICAgICAgICAgICAgICAgIHk6ICtjcnBbaSArIDFdLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZC5wdXNoKFtcbiAgICAgICAgICAgICdDJyxcbiAgICAgICAgICAgICgtcFswXS54ICsgNiAqIHBbMV0ueCArIHBbMl0ueCkgLyA2LFxuICAgICAgICAgICAgKC1wWzBdLnkgKyA2ICogcFsxXS55ICsgcFsyXS55KSAvIDYsXG4gICAgICAgICAgICAocFsxXS54ICsgNiAqIHBbMl0ueCAtIHBbM10ueCkgLyA2LFxuICAgICAgICAgICAgKHBbMV0ueSArIDYgKiBwWzJdLnkgLSBwWzNdLnkpIC8gNixcbiAgICAgICAgICAgIHBbMl0ueCxcbiAgICAgICAgICAgIHBbMl0ueSxcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIHJldHVybiBkO1xufTtcbmV4cG9ydHMuY2F0bXVsbFJvbVRvQmV6aWVyID0gY2F0bXVsbFJvbVRvQmV6aWVyO1xudmFyIGVsbGlwc2VQYXRoID0gZnVuY3Rpb24gKHgsIHksIHJ4LCByeSwgYSkge1xuICAgIHZhciByZXMgPSBbXTtcbiAgICBpZiAoYSA9PT0gbnVsbCAmJiByeSA9PT0gbnVsbCkge1xuICAgICAgICByeSA9IHJ4O1xuICAgIH1cbiAgICB4ID0gK3g7XG4gICAgeSA9ICt5O1xuICAgIHJ4ID0gK3J4O1xuICAgIHJ5ID0gK3J5O1xuICAgIGlmIChhICE9PSBudWxsKSB7XG4gICAgICAgIHZhciByYWQgPSBNYXRoLlBJIC8gMTgwO1xuICAgICAgICB2YXIgeDEgPSB4ICsgcnggKiBNYXRoLmNvcygtcnkgKiByYWQpO1xuICAgICAgICB2YXIgeDIgPSB4ICsgcnggKiBNYXRoLmNvcygtYSAqIHJhZCk7XG4gICAgICAgIHZhciB5MSA9IHkgKyByeCAqIE1hdGguc2luKC1yeSAqIHJhZCk7XG4gICAgICAgIHZhciB5MiA9IHkgKyByeCAqIE1hdGguc2luKC1hICogcmFkKTtcbiAgICAgICAgcmVzID0gW1xuICAgICAgICAgICAgWydNJywgeDEsIHkxXSxcbiAgICAgICAgICAgIFsnQScsIHJ4LCByeCwgMCwgKyhhIC0gcnkgPiAxODApLCAwLCB4MiwgeTJdLFxuICAgICAgICBdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmVzID0gW1snTScsIHgsIHldLCBbJ20nLCAwLCAtcnldLCBbJ2EnLCByeCwgcnksIDAsIDEsIDEsIDAsIDIgKiByeV0sIFsnYScsIHJ4LCByeSwgMCwgMSwgMSwgMCwgLTIgKiByeV0sIFsneiddXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn07XG52YXIgcGF0aFRvQWJzb2x1dGUgPSBmdW5jdGlvbiAocGF0aEFycmF5KSB7XG4gICAgcGF0aEFycmF5ID0gcGFyc2VQYXRoU3RyaW5nKHBhdGhBcnJheSk7XG4gICAgaWYgKCFwYXRoQXJyYXkgfHwgIXBhdGhBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCAwLCAwXV07XG4gICAgfVxuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgeCA9IDA7XG4gICAgdmFyIHkgPSAwO1xuICAgIHZhciBteCA9IDA7XG4gICAgdmFyIG15ID0gMDtcbiAgICB2YXIgc3RhcnQgPSAwO1xuICAgIHZhciBwYTA7XG4gICAgdmFyIGRvdHM7XG4gICAgaWYgKHBhdGhBcnJheVswXVswXSA9PT0gJ00nKSB7XG4gICAgICAgIHggPSArcGF0aEFycmF5WzBdWzFdO1xuICAgICAgICB5ID0gK3BhdGhBcnJheVswXVsyXTtcbiAgICAgICAgbXggPSB4O1xuICAgICAgICBteSA9IHk7XG4gICAgICAgIHN0YXJ0Kys7XG4gICAgICAgIHJlc1swXSA9IFsnTScsIHgsIHldO1xuICAgIH1cbiAgICB2YXIgY3J6ID0gcGF0aEFycmF5Lmxlbmd0aCA9PT0gMyAmJlxuICAgICAgICBwYXRoQXJyYXlbMF1bMF0gPT09ICdNJyAmJlxuICAgICAgICBwYXRoQXJyYXlbMV1bMF0udG9VcHBlckNhc2UoKSA9PT0gJ1InICYmXG4gICAgICAgIHBhdGhBcnJheVsyXVswXS50b1VwcGVyQ2FzZSgpID09PSAnWic7XG4gICAgZm9yICh2YXIgciA9IHZvaWQgMCwgcGEgPSB2b2lkIDAsIGkgPSBzdGFydCwgaWkgPSBwYXRoQXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICByZXMucHVzaCgociA9IFtdKSk7XG4gICAgICAgIHBhID0gcGF0aEFycmF5W2ldO1xuICAgICAgICBwYTAgPSBwYVswXTtcbiAgICAgICAgaWYgKHBhMCAhPT0gcGEwLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIHJbMF0gPSBwYTAudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIHN3aXRjaCAoclswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgICAgICAgICByWzFdID0gcGFbMV07XG4gICAgICAgICAgICAgICAgICAgIHJbMl0gPSBwYVsyXTtcbiAgICAgICAgICAgICAgICAgICAgclszXSA9IHBhWzNdO1xuICAgICAgICAgICAgICAgICAgICByWzRdID0gcGFbNF07XG4gICAgICAgICAgICAgICAgICAgIHJbNV0gPSBwYVs1XTtcbiAgICAgICAgICAgICAgICAgICAgcls2XSA9ICtwYVs2XSArIHg7XG4gICAgICAgICAgICAgICAgICAgIHJbN10gPSArcGFbN10gKyB5O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgICAgICAgICAgclsxXSA9ICtwYVsxXSArIHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICAgICAgICAgICAgICByWzFdID0gK3BhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnUic6XG4gICAgICAgICAgICAgICAgICAgIGRvdHMgPSBbeCwgeV0uY29uY2F0KHBhLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDIsIGpqID0gZG90cy5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb3RzW2pdID0gK2RvdHNbal0gKyB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgZG90c1srK2pdID0gK2RvdHNbal0gKyB5O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJlcy5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVzLmNvbmNhdChjYXRtdWxsUm9tVG9CZXppZXIoZG90cywgY3J6KSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ08nOlxuICAgICAgICAgICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIGRvdHMgPSBlbGxpcHNlUGF0aCh4LCB5LCBwYVsxXSwgcGFbMl0pO1xuICAgICAgICAgICAgICAgICAgICBkb3RzLnB1c2goZG90c1swXSk7XG4gICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoZG90cyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1UnOlxuICAgICAgICAgICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoZWxsaXBzZVBhdGgoeCwgeSwgcGFbMV0sIHBhWzJdLCBwYVszXSkpO1xuICAgICAgICAgICAgICAgICAgICByID0gWydVJ10uY29uY2F0KHJlc1tyZXMubGVuZ3RoIC0gMV0uc2xpY2UoLTIpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgICAgIG14ID0gK3BhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgbXkgPSArcGFbMl0gKyB5O1xuICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gZm9yIGxpbnRcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMSwgamogPSBwYS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gK3BhW2pdICsgKGogJSAyID8geCA6IHkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocGEwID09PSAnUicpIHtcbiAgICAgICAgICAgIGRvdHMgPSBbeCwgeV0uY29uY2F0KHBhLnNsaWNlKDEpKTtcbiAgICAgICAgICAgIHJlcy5wb3AoKTtcbiAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoY2F0bXVsbFJvbVRvQmV6aWVyKGRvdHMsIGNyeikpO1xuICAgICAgICAgICAgciA9IFsnUiddLmNvbmNhdChwYS5zbGljZSgtMikpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBhMCA9PT0gJ08nKSB7XG4gICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICBkb3RzID0gZWxsaXBzZVBhdGgoeCwgeSwgcGFbMV0sIHBhWzJdKTtcbiAgICAgICAgICAgIGRvdHMucHVzaChkb3RzWzBdKTtcbiAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoZG90cyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocGEwID09PSAnVScpIHtcbiAgICAgICAgICAgIHJlcy5wb3AoKTtcbiAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoZWxsaXBzZVBhdGgoeCwgeSwgcGFbMV0sIHBhWzJdLCBwYVszXSkpO1xuICAgICAgICAgICAgciA9IFsnVSddLmNvbmNhdChyZXNbcmVzLmxlbmd0aCAtIDFdLnNsaWNlKC0yKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMCwga2sgPSBwYS5sZW5ndGg7IGsgPCBrazsgaysrKSB7XG4gICAgICAgICAgICAgICAgcltrXSA9IHBhW2tdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHBhMCA9IHBhMC50b1VwcGVyQ2FzZSgpO1xuICAgICAgICBpZiAocGEwICE9PSAnTycpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoclswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ1onOlxuICAgICAgICAgICAgICAgICAgICB4ID0gK214O1xuICAgICAgICAgICAgICAgICAgICB5ID0gK215O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdIJzpcbiAgICAgICAgICAgICAgICAgICAgeCA9IHJbMV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1YnOlxuICAgICAgICAgICAgICAgICAgICB5ID0gclsxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgICAgIG14ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgICAgICBteSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vIGZvciBsaW50XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgeCA9IHJbci5sZW5ndGggLSAyXTtcbiAgICAgICAgICAgICAgICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcbmV4cG9ydHMucGF0aFRvQWJzb2x1dGUgPSBwYXRoVG9BYnNvbHV0ZTtcbnZhciBsMmMgPSBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIpIHtcbiAgICByZXR1cm4gW3gxLCB5MSwgeDIsIHkyLCB4MiwgeTJdO1xufTtcbnZhciBxMmMgPSBmdW5jdGlvbiAoeDEsIHkxLCBheCwgYXksIHgyLCB5Mikge1xuICAgIHZhciBfMTMgPSAxIC8gMztcbiAgICB2YXIgXzIzID0gMiAvIDM7XG4gICAgcmV0dXJuIFtfMTMgKiB4MSArIF8yMyAqIGF4LCBfMTMgKiB5MSArIF8yMyAqIGF5LCBfMTMgKiB4MiArIF8yMyAqIGF4LCBfMTMgKiB5MiArIF8yMyAqIGF5LCB4MiwgeTJdO1xufTtcbnZhciBhMmMgPSBmdW5jdGlvbiAoeDEsIHkxLCByeCwgcnksIGFuZ2xlLCBsYXJnZV9hcmNfZmxhZywgc3dlZXBfZmxhZywgeDIsIHkyLCByZWN1cnNpdmUpIHtcbiAgICAvLyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvZiB3aGVyZSB0aGlzIG1hdGggY2FtZSBmcm9tIHZpc2l0OlxuICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ltcGxub3RlLmh0bWwjQXJjSW1wbGVtZW50YXRpb25Ob3Rlc1xuICAgIGlmIChyeCA9PT0gcnkpIHtcbiAgICAgICAgcnggKz0gMTtcbiAgICB9XG4gICAgdmFyIF8xMjAgPSAoTWF0aC5QSSAqIDEyMCkgLyAxODA7XG4gICAgdmFyIHJhZCA9IChNYXRoLlBJIC8gMTgwKSAqICgrYW5nbGUgfHwgMCk7XG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIHZhciB4eTtcbiAgICB2YXIgZjE7XG4gICAgdmFyIGYyO1xuICAgIHZhciBjeDtcbiAgICB2YXIgY3k7XG4gICAgdmFyIHJvdGF0ZSA9IGZ1bmN0aW9uICh4LCB5LCByYWQpIHtcbiAgICAgICAgdmFyIFggPSB4ICogTWF0aC5jb3MocmFkKSAtIHkgKiBNYXRoLnNpbihyYWQpO1xuICAgICAgICB2YXIgWSA9IHggKiBNYXRoLnNpbihyYWQpICsgeSAqIE1hdGguY29zKHJhZCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBYLFxuICAgICAgICAgICAgeTogWSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGlmICghcmVjdXJzaXZlKSB7XG4gICAgICAgIHh5ID0gcm90YXRlKHgxLCB5MSwgLXJhZCk7XG4gICAgICAgIHgxID0geHkueDtcbiAgICAgICAgeTEgPSB4eS55O1xuICAgICAgICB4eSA9IHJvdGF0ZSh4MiwgeTIsIC1yYWQpO1xuICAgICAgICB4MiA9IHh5Lng7XG4gICAgICAgIHkyID0geHkueTtcbiAgICAgICAgaWYgKHgxID09PSB4MiAmJiB5MSA9PT0geTIpIHtcbiAgICAgICAgICAgIC8vIOiLpeW8p+eahOi1t+Wni+eCueWSjOe7iOeCuemHjeWPoOWImemUmeW8gOS4gOeCuVxuICAgICAgICAgICAgeDIgKz0gMTtcbiAgICAgICAgICAgIHkyICs9IDE7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29uc3QgY29zID0gTWF0aC5jb3MoTWF0aC5QSSAvIDE4MCAqIGFuZ2xlKTtcbiAgICAgICAgLy8gY29uc3Qgc2luID0gTWF0aC5zaW4oTWF0aC5QSSAvIDE4MCAqIGFuZ2xlKTtcbiAgICAgICAgdmFyIHggPSAoeDEgLSB4MikgLyAyO1xuICAgICAgICB2YXIgeSA9ICh5MSAtIHkyKSAvIDI7XG4gICAgICAgIHZhciBoID0gKHggKiB4KSAvIChyeCAqIHJ4KSArICh5ICogeSkgLyAocnkgKiByeSk7XG4gICAgICAgIGlmIChoID4gMSkge1xuICAgICAgICAgICAgaCA9IE1hdGguc3FydChoKTtcbiAgICAgICAgICAgIHJ4ID0gaCAqIHJ4O1xuICAgICAgICAgICAgcnkgPSBoICogcnk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJ4MiA9IHJ4ICogcng7XG4gICAgICAgIHZhciByeTIgPSByeSAqIHJ5O1xuICAgICAgICB2YXIgayA9IChsYXJnZV9hcmNfZmxhZyA9PT0gc3dlZXBfZmxhZyA/IC0xIDogMSkgKlxuICAgICAgICAgICAgTWF0aC5zcXJ0KE1hdGguYWJzKChyeDIgKiByeTIgLSByeDIgKiB5ICogeSAtIHJ5MiAqIHggKiB4KSAvIChyeDIgKiB5ICogeSArIHJ5MiAqIHggKiB4KSkpO1xuICAgICAgICBjeCA9IChrICogcnggKiB5KSAvIHJ5ICsgKHgxICsgeDIpIC8gMjtcbiAgICAgICAgY3kgPSAoayAqIC1yeSAqIHgpIC8gcnggKyAoeTEgKyB5MikgLyAyO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGYxID0gTWF0aC5hc2luKCgoeTEgLSBjeSkgLyByeSkudG9GaXhlZCg5KSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgZjIgPSBNYXRoLmFzaW4oKCh5MiAtIGN5KSAvIHJ5KS50b0ZpeGVkKDkpKTtcbiAgICAgICAgZjEgPSB4MSA8IGN4ID8gTWF0aC5QSSAtIGYxIDogZjE7XG4gICAgICAgIGYyID0geDIgPCBjeCA/IE1hdGguUEkgLSBmMiA6IGYyO1xuICAgICAgICBmMSA8IDAgJiYgKGYxID0gTWF0aC5QSSAqIDIgKyBmMSk7XG4gICAgICAgIGYyIDwgMCAmJiAoZjIgPSBNYXRoLlBJICogMiArIGYyKTtcbiAgICAgICAgaWYgKHN3ZWVwX2ZsYWcgJiYgZjEgPiBmMikge1xuICAgICAgICAgICAgZjEgPSBmMSAtIE1hdGguUEkgKiAyO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc3dlZXBfZmxhZyAmJiBmMiA+IGYxKSB7XG4gICAgICAgICAgICBmMiA9IGYyIC0gTWF0aC5QSSAqIDI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGYxID0gcmVjdXJzaXZlWzBdO1xuICAgICAgICBmMiA9IHJlY3Vyc2l2ZVsxXTtcbiAgICAgICAgY3ggPSByZWN1cnNpdmVbMl07XG4gICAgICAgIGN5ID0gcmVjdXJzaXZlWzNdO1xuICAgIH1cbiAgICB2YXIgZGYgPSBmMiAtIGYxO1xuICAgIGlmIChNYXRoLmFicyhkZikgPiBfMTIwKSB7XG4gICAgICAgIHZhciBmMm9sZCA9IGYyO1xuICAgICAgICB2YXIgeDJvbGQgPSB4MjtcbiAgICAgICAgdmFyIHkyb2xkID0geTI7XG4gICAgICAgIGYyID0gZjEgKyBfMTIwICogKHN3ZWVwX2ZsYWcgJiYgZjIgPiBmMSA/IDEgOiAtMSk7XG4gICAgICAgIHgyID0gY3ggKyByeCAqIE1hdGguY29zKGYyKTtcbiAgICAgICAgeTIgPSBjeSArIHJ5ICogTWF0aC5zaW4oZjIpO1xuICAgICAgICByZXMgPSBhMmMoeDIsIHkyLCByeCwgcnksIGFuZ2xlLCAwLCBzd2VlcF9mbGFnLCB4Mm9sZCwgeTJvbGQsIFtmMiwgZjJvbGQsIGN4LCBjeV0pO1xuICAgIH1cbiAgICBkZiA9IGYyIC0gZjE7XG4gICAgdmFyIGMxID0gTWF0aC5jb3MoZjEpO1xuICAgIHZhciBzMSA9IE1hdGguc2luKGYxKTtcbiAgICB2YXIgYzIgPSBNYXRoLmNvcyhmMik7XG4gICAgdmFyIHMyID0gTWF0aC5zaW4oZjIpO1xuICAgIHZhciB0ID0gTWF0aC50YW4oZGYgLyA0KTtcbiAgICB2YXIgaHggPSAoNCAvIDMpICogcnggKiB0O1xuICAgIHZhciBoeSA9ICg0IC8gMykgKiByeSAqIHQ7XG4gICAgdmFyIG0xID0gW3gxLCB5MV07XG4gICAgdmFyIG0yID0gW3gxICsgaHggKiBzMSwgeTEgLSBoeSAqIGMxXTtcbiAgICB2YXIgbTMgPSBbeDIgKyBoeCAqIHMyLCB5MiAtIGh5ICogYzJdO1xuICAgIHZhciBtNCA9IFt4MiwgeTJdO1xuICAgIG0yWzBdID0gMiAqIG0xWzBdIC0gbTJbMF07XG4gICAgbTJbMV0gPSAyICogbTFbMV0gLSBtMlsxXTtcbiAgICBpZiAocmVjdXJzaXZlKSB7XG4gICAgICAgIHJldHVybiBbbTIsIG0zLCBtNF0uY29uY2F0KHJlcyk7XG4gICAgfVxuICAgIHJlcyA9IFttMiwgbTMsIG00XVxuICAgICAgICAuY29uY2F0KHJlcylcbiAgICAgICAgLmpvaW4oKVxuICAgICAgICAuc3BsaXQoJywnKTtcbiAgICB2YXIgbmV3cmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcmVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgbmV3cmVzW2ldID0gaSAlIDIgPyByb3RhdGUocmVzW2kgLSAxXSwgcmVzW2ldLCByYWQpLnkgOiByb3RhdGUocmVzW2ldLCByZXNbaSArIDFdLCByYWQpLng7XG4gICAgfVxuICAgIHJldHVybiBuZXdyZXM7XG59O1xudmFyIHBhdGhUb0N1cnZlID0gZnVuY3Rpb24gKHBhdGgsIHBhdGgyKSB7XG4gICAgdmFyIHAgPSBwYXRoVG9BYnNvbHV0ZShwYXRoKTtcbiAgICB2YXIgcDIgPSBwYXRoMiAmJiBwYXRoVG9BYnNvbHV0ZShwYXRoMik7XG4gICAgdmFyIGF0dHJzID0ge1xuICAgICAgICB4OiAwLFxuICAgICAgICB5OiAwLFxuICAgICAgICBieDogMCxcbiAgICAgICAgYnk6IDAsXG4gICAgICAgIFg6IDAsXG4gICAgICAgIFk6IDAsXG4gICAgICAgIHF4OiBudWxsLFxuICAgICAgICBxeTogbnVsbCxcbiAgICB9O1xuICAgIHZhciBhdHRyczIgPSB7XG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDAsXG4gICAgICAgIGJ4OiAwLFxuICAgICAgICBieTogMCxcbiAgICAgICAgWDogMCxcbiAgICAgICAgWTogMCxcbiAgICAgICAgcXg6IG51bGwsXG4gICAgICAgIHF5OiBudWxsLFxuICAgIH07XG4gICAgdmFyIHBjb21zMSA9IFtdOyAvLyBwYXRoIGNvbW1hbmRzIG9mIG9yaWdpbmFsIHBhdGggcFxuICAgIHZhciBwY29tczIgPSBbXTsgLy8gcGF0aCBjb21tYW5kcyBvZiBvcmlnaW5hbCBwYXRoIHAyXG4gICAgdmFyIHBmaXJzdCA9ICcnOyAvLyB0ZW1wb3JhcnkgaG9sZGVyIGZvciBvcmlnaW5hbCBwYXRoIGNvbW1hbmRcbiAgICB2YXIgcGNvbSA9ICcnOyAvLyBob2xkZXIgZm9yIHByZXZpb3VzIHBhdGggY29tbWFuZCBvZiBvcmlnaW5hbCBwYXRoXG4gICAgdmFyIGlpO1xuICAgIHZhciBwcm9jZXNzUGF0aCA9IGZ1bmN0aW9uIChwYXRoLCBkLCBwY29tKSB7XG4gICAgICAgIHZhciBueDtcbiAgICAgICAgdmFyIG55O1xuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybiBbJ0MnLCBkLngsIGQueSwgZC54LCBkLnksIGQueCwgZC55XTtcbiAgICAgICAgfVxuICAgICAgICAhKHBhdGhbMF0gaW5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBUOiAxLFxuICAgICAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICB9KSAmJiAoZC5xeCA9IGQucXkgPSBudWxsKTtcbiAgICAgICAgc3dpdGNoIChwYXRoWzBdKSB7XG4gICAgICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgICAgICBkLlggPSBwYXRoWzFdO1xuICAgICAgICAgICAgICAgIGQuWSA9IHBhdGhbMl07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdBJzpcbiAgICAgICAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGEyYy5hcHBseSgwLCBbZC54LCBkLnldLmNvbmNhdChwYXRoLnNsaWNlKDEpKSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnUyc6XG4gICAgICAgICAgICAgICAgaWYgKHBjb20gPT09ICdDJyB8fCBwY29tID09PSAnUycpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gXCJTXCIgY2FzZSB3ZSBoYXZlIHRvIHRha2UgaW50byBhY2NvdW50LCBpZiB0aGUgcHJldmlvdXMgY29tbWFuZCBpcyBDL1MuXG4gICAgICAgICAgICAgICAgICAgIG54ID0gZC54ICogMiAtIGQuYng7IC8vIEFuZCByZWZsZWN0IHRoZSBwcmV2aW91c1xuICAgICAgICAgICAgICAgICAgICBueSA9IGQueSAqIDIgLSBkLmJ5OyAvLyBjb21tYW5kJ3MgY29udHJvbCBwb2ludCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBwb2ludC5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG9yIHNvbWUgZWxzZSBvciBub3RoaW5nXG4gICAgICAgICAgICAgICAgICAgIG54ID0gZC54O1xuICAgICAgICAgICAgICAgICAgICBueSA9IGQueTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQycsIG54LCBueV0uY29uY2F0KHBhdGguc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnVCc6XG4gICAgICAgICAgICAgICAgaWYgKHBjb20gPT09ICdRJyB8fCBwY29tID09PSAnVCcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gXCJUXCIgY2FzZSB3ZSBoYXZlIHRvIHRha2UgaW50byBhY2NvdW50LCBpZiB0aGUgcHJldmlvdXMgY29tbWFuZCBpcyBRL1QuXG4gICAgICAgICAgICAgICAgICAgIGQucXggPSBkLnggKiAyIC0gZC5xeDsgLy8gQW5kIG1ha2UgYSByZWZsZWN0aW9uIHNpbWlsYXJcbiAgICAgICAgICAgICAgICAgICAgZC5xeSA9IGQueSAqIDIgLSBkLnF5OyAvLyB0byBjYXNlIFwiU1wiLlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gb3Igc29tZXRoaW5nIGVsc2Ugb3Igbm90aGluZ1xuICAgICAgICAgICAgICAgICAgICBkLnF4ID0gZC54O1xuICAgICAgICAgICAgICAgICAgICBkLnF5ID0gZC55O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KHEyYyhkLngsIGQueSwgZC5xeCwgZC5xeSwgcGF0aFsxXSwgcGF0aFsyXSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICAgICAgZC5xeCA9IHBhdGhbMV07XG4gICAgICAgICAgICAgICAgZC5xeSA9IHBhdGhbMl07XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChxMmMoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0sIHBhdGhbM10sIHBhdGhbNF0pKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0wnOlxuICAgICAgICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQobDJjKGQueCwgZC55LCBwYXRoWzFdLCBwYXRoWzJdKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdIJzpcbiAgICAgICAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGwyYyhkLngsIGQueSwgcGF0aFsxXSwgZC55KSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGwyYyhkLngsIGQueSwgZC54LCBwYXRoWzFdKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGwyYyhkLngsIGQueSwgZC5YLCBkLlkpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfTtcbiAgICB2YXIgZml4QXJjID0gZnVuY3Rpb24gKHBwLCBpKSB7XG4gICAgICAgIGlmIChwcFtpXS5sZW5ndGggPiA3KSB7XG4gICAgICAgICAgICBwcFtpXS5zaGlmdCgpO1xuICAgICAgICAgICAgdmFyIHBpID0gcHBbaV07XG4gICAgICAgICAgICB3aGlsZSAocGkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcGNvbXMxW2ldID0gJ0EnOyAvLyBpZiBjcmVhdGVkIG11bHRpcGxlIEM6cywgdGhlaXIgb3JpZ2luYWwgc2VnIGlzIHNhdmVkXG4gICAgICAgICAgICAgICAgcDIgJiYgKHBjb21zMltpXSA9ICdBJyk7IC8vIHRoZSBzYW1lIGFzIGFib3ZlXG4gICAgICAgICAgICAgICAgcHAuc3BsaWNlKGkrKywgMCwgWydDJ10uY29uY2F0KHBpLnNwbGljZSgwLCA2KSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHAuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaWkgPSBNYXRoLm1heChwLmxlbmd0aCwgKHAyICYmIHAyLmxlbmd0aCkgfHwgMCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHZhciBmaXhNID0gZnVuY3Rpb24gKHBhdGgxLCBwYXRoMiwgYTEsIGEyLCBpKSB7XG4gICAgICAgIGlmIChwYXRoMSAmJiBwYXRoMiAmJiBwYXRoMVtpXVswXSA9PT0gJ00nICYmIHBhdGgyW2ldWzBdICE9PSAnTScpIHtcbiAgICAgICAgICAgIHBhdGgyLnNwbGljZShpLCAwLCBbJ00nLCBhMi54LCBhMi55XSk7XG4gICAgICAgICAgICBhMS5ieCA9IDA7XG4gICAgICAgICAgICBhMS5ieSA9IDA7XG4gICAgICAgICAgICBhMS54ID0gcGF0aDFbaV1bMV07XG4gICAgICAgICAgICBhMS55ID0gcGF0aDFbaV1bMl07XG4gICAgICAgICAgICBpaSA9IE1hdGgubWF4KHAubGVuZ3RoLCAocDIgJiYgcDIubGVuZ3RoKSB8fCAwKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgaWkgPSBNYXRoLm1heChwLmxlbmd0aCwgKHAyICYmIHAyLmxlbmd0aCkgfHwgMCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgIHBbaV0gJiYgKHBmaXJzdCA9IHBbaV1bMF0pOyAvLyBzYXZlIGN1cnJlbnQgcGF0aCBjb21tYW5kXG4gICAgICAgIGlmIChwZmlyc3QgIT09ICdDJykge1xuICAgICAgICAgICAgLy8gQyBpcyBub3Qgc2F2ZWQgeWV0LCBiZWNhdXNlIGl0IG1heSBiZSByZXN1bHQgb2YgY29udmVyc2lvblxuICAgICAgICAgICAgcGNvbXMxW2ldID0gcGZpcnN0OyAvLyBTYXZlIGN1cnJlbnQgcGF0aCBjb21tYW5kXG4gICAgICAgICAgICBpICYmIChwY29tID0gcGNvbXMxW2kgLSAxXSk7IC8vIEdldCBwcmV2aW91cyBwYXRoIGNvbW1hbmQgcGNvbVxuICAgICAgICB9XG4gICAgICAgIHBbaV0gPSBwcm9jZXNzUGF0aChwW2ldLCBhdHRycywgcGNvbSk7IC8vIFByZXZpb3VzIHBhdGggY29tbWFuZCBpcyBpbnB1dHRlZCB0byBwcm9jZXNzUGF0aFxuICAgICAgICBpZiAocGNvbXMxW2ldICE9PSAnQScgJiYgcGZpcnN0ID09PSAnQycpXG4gICAgICAgICAgICBwY29tczFbaV0gPSAnQyc7IC8vIEEgaXMgdGhlIG9ubHkgY29tbWFuZFxuICAgICAgICAvLyB3aGljaCBtYXkgcHJvZHVjZSBtdWx0aXBsZSBDOnNcbiAgICAgICAgLy8gc28gd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCBDIGlzIGFsc28gQyBpbiBvcmlnaW5hbCBwYXRoXG4gICAgICAgIGZpeEFyYyhwLCBpKTsgLy8gZml4QXJjIGFkZHMgYWxzbyB0aGUgcmlnaHQgYW1vdW50IG9mIEE6cyB0byBwY29tczFcbiAgICAgICAgaWYgKHAyKSB7XG4gICAgICAgICAgICAvLyB0aGUgc2FtZSBwcm9jZWR1cmVzIGlzIGRvbmUgdG8gcDJcbiAgICAgICAgICAgIHAyW2ldICYmIChwZmlyc3QgPSBwMltpXVswXSk7XG4gICAgICAgICAgICBpZiAocGZpcnN0ICE9PSAnQycpIHtcbiAgICAgICAgICAgICAgICBwY29tczJbaV0gPSBwZmlyc3Q7XG4gICAgICAgICAgICAgICAgaSAmJiAocGNvbSA9IHBjb21zMltpIC0gMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcDJbaV0gPSBwcm9jZXNzUGF0aChwMltpXSwgYXR0cnMyLCBwY29tKTtcbiAgICAgICAgICAgIGlmIChwY29tczJbaV0gIT09ICdBJyAmJiBwZmlyc3QgPT09ICdDJykge1xuICAgICAgICAgICAgICAgIHBjb21zMltpXSA9ICdDJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpeEFyYyhwMiwgaSk7XG4gICAgICAgIH1cbiAgICAgICAgZml4TShwLCBwMiwgYXR0cnMsIGF0dHJzMiwgaSk7XG4gICAgICAgIGZpeE0ocDIsIHAsIGF0dHJzMiwgYXR0cnMsIGkpO1xuICAgICAgICB2YXIgc2VnID0gcFtpXTtcbiAgICAgICAgdmFyIHNlZzIgPSBwMiAmJiBwMltpXTtcbiAgICAgICAgdmFyIHNlZ2xlbiA9IHNlZy5sZW5ndGg7XG4gICAgICAgIHZhciBzZWcybGVuID0gcDIgJiYgc2VnMi5sZW5ndGg7XG4gICAgICAgIGF0dHJzLnggPSBzZWdbc2VnbGVuIC0gMl07XG4gICAgICAgIGF0dHJzLnkgPSBzZWdbc2VnbGVuIC0gMV07XG4gICAgICAgIGF0dHJzLmJ4ID0gcGFyc2VGbG9hdChzZWdbc2VnbGVuIC0gNF0pIHx8IGF0dHJzLng7XG4gICAgICAgIGF0dHJzLmJ5ID0gcGFyc2VGbG9hdChzZWdbc2VnbGVuIC0gM10pIHx8IGF0dHJzLnk7XG4gICAgICAgIGF0dHJzMi5ieCA9IHAyICYmIChwYXJzZUZsb2F0KHNlZzJbc2VnMmxlbiAtIDRdKSB8fCBhdHRyczIueCk7XG4gICAgICAgIGF0dHJzMi5ieSA9IHAyICYmIChwYXJzZUZsb2F0KHNlZzJbc2VnMmxlbiAtIDNdKSB8fCBhdHRyczIueSk7XG4gICAgICAgIGF0dHJzMi54ID0gcDIgJiYgc2VnMltzZWcybGVuIC0gMl07XG4gICAgICAgIGF0dHJzMi55ID0gcDIgJiYgc2VnMltzZWcybGVuIC0gMV07XG4gICAgfVxuICAgIHJldHVybiBwMiA/IFtwLCBwMl0gOiBwO1xufTtcbmV4cG9ydHMucGF0aFRvQ3VydmUgPSBwYXRoVG9DdXJ2ZTtcbnZhciBwMnMgPSAvLD8oW2Etel0pLD8vZ2k7XG52YXIgcGFyc2VQYXRoQXJyYXkgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgIHJldHVybiBwYXRoLmpvaW4oJywnKS5yZXBsYWNlKHAycywgJyQxJyk7XG59O1xuZXhwb3J0cy5wYXJzZVBhdGhBcnJheSA9IHBhcnNlUGF0aEFycmF5O1xudmFyIGJhc2UzID0gZnVuY3Rpb24gKHQsIHAxLCBwMiwgcDMsIHA0KSB7XG4gICAgdmFyIHQxID0gLTMgKiBwMSArIDkgKiBwMiAtIDkgKiBwMyArIDMgKiBwNDtcbiAgICB2YXIgdDIgPSB0ICogdDEgKyA2ICogcDEgLSAxMiAqIHAyICsgNiAqIHAzO1xuICAgIHJldHVybiB0ICogdDIgLSAzICogcDEgKyAzICogcDI7XG59O1xudmFyIGJlemxlbiA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHopIHtcbiAgICBpZiAoeiA9PT0gbnVsbCkge1xuICAgICAgICB6ID0gMTtcbiAgICB9XG4gICAgeiA9IHogPiAxID8gMSA6IHogPCAwID8gMCA6IHo7XG4gICAgdmFyIHoyID0geiAvIDI7XG4gICAgdmFyIG4gPSAxMjtcbiAgICB2YXIgVHZhbHVlcyA9IFtcbiAgICAgICAgLTAuMTI1MixcbiAgICAgICAgMC4xMjUyLFxuICAgICAgICAtMC4zNjc4LFxuICAgICAgICAwLjM2NzgsXG4gICAgICAgIC0wLjU4NzMsXG4gICAgICAgIDAuNTg3MyxcbiAgICAgICAgLTAuNzY5OSxcbiAgICAgICAgMC43Njk5LFxuICAgICAgICAtMC45MDQxLFxuICAgICAgICAwLjkwNDEsXG4gICAgICAgIC0wLjk4MTYsXG4gICAgICAgIDAuOTgxNixcbiAgICBdO1xuICAgIHZhciBDdmFsdWVzID0gWzAuMjQ5MSwgMC4yNDkxLCAwLjIzMzUsIDAuMjMzNSwgMC4yMDMyLCAwLjIwMzIsIDAuMTYwMSwgMC4xNjAxLCAwLjEwNjksIDAuMTA2OSwgMC4wNDcyLCAwLjA0NzJdO1xuICAgIHZhciBzdW0gPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIHZhciBjdCA9IHoyICogVHZhbHVlc1tpXSArIHoyO1xuICAgICAgICB2YXIgeGJhc2UgPSBiYXNlMyhjdCwgeDEsIHgyLCB4MywgeDQpO1xuICAgICAgICB2YXIgeWJhc2UgPSBiYXNlMyhjdCwgeTEsIHkyLCB5MywgeTQpO1xuICAgICAgICB2YXIgY29tYiA9IHhiYXNlICogeGJhc2UgKyB5YmFzZSAqIHliYXNlO1xuICAgICAgICBzdW0gKz0gQ3ZhbHVlc1tpXSAqIE1hdGguc3FydChjb21iKTtcbiAgICB9XG4gICAgcmV0dXJuIHoyICogc3VtO1xufTtcbnZhciBjdXJ2ZURpbSA9IGZ1bmN0aW9uICh4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgICB2YXIgdHZhbHVlcyA9IFtdO1xuICAgIHZhciBib3VuZHMgPSBbW10sIFtdXTtcbiAgICB2YXIgYTtcbiAgICB2YXIgYjtcbiAgICB2YXIgYztcbiAgICB2YXIgdDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI7ICsraSkge1xuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgICAgYiA9IDYgKiB4MCAtIDEyICogeDEgKyA2ICogeDI7XG4gICAgICAgICAgICBhID0gLTMgKiB4MCArIDkgKiB4MSAtIDkgKiB4MiArIDMgKiB4MztcbiAgICAgICAgICAgIGMgPSAzICogeDEgLSAzICogeDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBiID0gNiAqIHkwIC0gMTIgKiB5MSArIDYgKiB5MjtcbiAgICAgICAgICAgIGEgPSAtMyAqIHkwICsgOSAqIHkxIC0gOSAqIHkyICsgMyAqIHkzO1xuICAgICAgICAgICAgYyA9IDMgKiB5MSAtIDMgKiB5MDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTWF0aC5hYnMoYSkgPCAxZS0xMikge1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKGIpIDwgMWUtMTIpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHQgPSAtYyAvIGI7XG4gICAgICAgICAgICBpZiAodCA+IDAgJiYgdCA8IDEpIHtcbiAgICAgICAgICAgICAgICB0dmFsdWVzLnB1c2godCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYjJhYyA9IGIgKiBiIC0gNCAqIGMgKiBhO1xuICAgICAgICB2YXIgc3FydGIyYWMgPSBNYXRoLnNxcnQoYjJhYyk7XG4gICAgICAgIGlmIChiMmFjIDwgMCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHQxID0gKC1iICsgc3FydGIyYWMpIC8gKDIgKiBhKTtcbiAgICAgICAgaWYgKHQxID4gMCAmJiB0MSA8IDEpIHtcbiAgICAgICAgICAgIHR2YWx1ZXMucHVzaCh0MSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHQyID0gKC1iIC0gc3FydGIyYWMpIC8gKDIgKiBhKTtcbiAgICAgICAgaWYgKHQyID4gMCAmJiB0MiA8IDEpIHtcbiAgICAgICAgICAgIHR2YWx1ZXMucHVzaCh0Mik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIGogPSB0dmFsdWVzLmxlbmd0aDtcbiAgICB2YXIgamxlbiA9IGo7XG4gICAgdmFyIG10O1xuICAgIHdoaWxlIChqLS0pIHtcbiAgICAgICAgdCA9IHR2YWx1ZXNbal07XG4gICAgICAgIG10ID0gMSAtIHQ7XG4gICAgICAgIGJvdW5kc1swXVtqXSA9IG10ICogbXQgKiBtdCAqIHgwICsgMyAqIG10ICogbXQgKiB0ICogeDEgKyAzICogbXQgKiB0ICogdCAqIHgyICsgdCAqIHQgKiB0ICogeDM7XG4gICAgICAgIGJvdW5kc1sxXVtqXSA9IG10ICogbXQgKiBtdCAqIHkwICsgMyAqIG10ICogbXQgKiB0ICogeTEgKyAzICogbXQgKiB0ICogdCAqIHkyICsgdCAqIHQgKiB0ICogeTM7XG4gICAgfVxuICAgIGJvdW5kc1swXVtqbGVuXSA9IHgwO1xuICAgIGJvdW5kc1sxXVtqbGVuXSA9IHkwO1xuICAgIGJvdW5kc1swXVtqbGVuICsgMV0gPSB4MztcbiAgICBib3VuZHNbMV1bamxlbiArIDFdID0geTM7XG4gICAgYm91bmRzWzBdLmxlbmd0aCA9IGJvdW5kc1sxXS5sZW5ndGggPSBqbGVuICsgMjtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW46IHtcbiAgICAgICAgICAgIHg6IE1hdGgubWluLmFwcGx5KDAsIGJvdW5kc1swXSksXG4gICAgICAgICAgICB5OiBNYXRoLm1pbi5hcHBseSgwLCBib3VuZHNbMV0pLFxuICAgICAgICB9LFxuICAgICAgICBtYXg6IHtcbiAgICAgICAgICAgIHg6IE1hdGgubWF4LmFwcGx5KDAsIGJvdW5kc1swXSksXG4gICAgICAgICAgICB5OiBNYXRoLm1heC5hcHBseSgwLCBib3VuZHNbMV0pLFxuICAgICAgICB9LFxuICAgIH07XG59O1xudmFyIGludGVyc2VjdCA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIHtcbiAgICBpZiAoTWF0aC5tYXgoeDEsIHgyKSA8IE1hdGgubWluKHgzLCB4NCkgfHxcbiAgICAgICAgTWF0aC5taW4oeDEsIHgyKSA+IE1hdGgubWF4KHgzLCB4NCkgfHxcbiAgICAgICAgTWF0aC5tYXgoeTEsIHkyKSA8IE1hdGgubWluKHkzLCB5NCkgfHxcbiAgICAgICAgTWF0aC5taW4oeTEsIHkyKSA+IE1hdGgubWF4KHkzLCB5NCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgbnggPSAoeDEgKiB5MiAtIHkxICogeDIpICogKHgzIC0geDQpIC0gKHgxIC0geDIpICogKHgzICogeTQgLSB5MyAqIHg0KTtcbiAgICB2YXIgbnkgPSAoeDEgKiB5MiAtIHkxICogeDIpICogKHkzIC0geTQpIC0gKHkxIC0geTIpICogKHgzICogeTQgLSB5MyAqIHg0KTtcbiAgICB2YXIgZGVub21pbmF0b3IgPSAoeDEgLSB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgLSB4NCk7XG4gICAgaWYgKCFkZW5vbWluYXRvcikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBweCA9IG54IC8gZGVub21pbmF0b3I7XG4gICAgdmFyIHB5ID0gbnkgLyBkZW5vbWluYXRvcjtcbiAgICB2YXIgcHgyID0gK3B4LnRvRml4ZWQoMik7XG4gICAgdmFyIHB5MiA9ICtweS50b0ZpeGVkKDIpO1xuICAgIGlmIChweDIgPCArTWF0aC5taW4oeDEsIHgyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB4MiA+ICtNYXRoLm1heCh4MSwgeDIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHgyIDwgK01hdGgubWluKHgzLCB4NCkudG9GaXhlZCgyKSB8fFxuICAgICAgICBweDIgPiArTWF0aC5tYXgoeDMsIHg0KS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB5MiA8ICtNYXRoLm1pbih5MSwgeTIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHkyID4gK01hdGgubWF4KHkxLCB5MikudG9GaXhlZCgyKSB8fFxuICAgICAgICBweTIgPCArTWF0aC5taW4oeTMsIHk0KS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB5MiA+ICtNYXRoLm1heCh5MywgeTQpLnRvRml4ZWQoMikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBweCxcbiAgICAgICAgeTogcHksXG4gICAgfTtcbn07XG52YXIgaXNQb2ludEluc2lkZUJCb3ggPSBmdW5jdGlvbiAoYmJveCwgeCwgeSkge1xuICAgIHJldHVybiB4ID49IGJib3gueCAmJiB4IDw9IGJib3gueCArIGJib3gud2lkdGggJiYgeSA+PSBiYm94LnkgJiYgeSA8PSBiYm94LnkgKyBiYm94LmhlaWdodDtcbn07XG52YXIgcmVjdFBhdGggPSBmdW5jdGlvbiAoeCwgeSwgdywgaCwgcikge1xuICAgIGlmIChyKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCAreCArICtyLCB5XSxcbiAgICAgICAgICAgIFsnbCcsIHcgLSByICogMiwgMF0sXG4gICAgICAgICAgICBbJ2EnLCByLCByLCAwLCAwLCAxLCByLCByXSxcbiAgICAgICAgICAgIFsnbCcsIDAsIGggLSByICogMl0sXG4gICAgICAgICAgICBbJ2EnLCByLCByLCAwLCAwLCAxLCAtciwgcl0sXG4gICAgICAgICAgICBbJ2wnLCByICogMiAtIHcsIDBdLFxuICAgICAgICAgICAgWydhJywgciwgciwgMCwgMCwgMSwgLXIsIC1yXSxcbiAgICAgICAgICAgIFsnbCcsIDAsIHIgKiAyIC0gaF0sXG4gICAgICAgICAgICBbJ2EnLCByLCByLCAwLCAwLCAxLCByLCAtcl0sXG4gICAgICAgICAgICBbJ3onXSxcbiAgICAgICAgXTtcbiAgICB9XG4gICAgdmFyIHJlcyA9IFtbJ00nLCB4LCB5XSwgWydsJywgdywgMF0sIFsnbCcsIDAsIGhdLCBbJ2wnLCAtdywgMF0sIFsneiddXTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmVzLnBhcnNlUGF0aEFycmF5ID0gcGFyc2VQYXRoQXJyYXk7XG4gICAgcmV0dXJuIHJlcztcbn07XG5leHBvcnRzLnJlY3RQYXRoID0gcmVjdFBhdGg7XG52YXIgYm94ID0gZnVuY3Rpb24gKHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcbiAgICBpZiAoeCA9PT0gbnVsbCkge1xuICAgICAgICB4ID0geSA9IHdpZHRoID0gaGVpZ2h0ID0gMDtcbiAgICB9XG4gICAgaWYgKHkgPT09IG51bGwpIHtcbiAgICAgICAgeSA9IHgueTtcbiAgICAgICAgd2lkdGggPSB4LndpZHRoO1xuICAgICAgICBoZWlnaHQgPSB4LmhlaWdodDtcbiAgICAgICAgeCA9IHgueDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICB3OiB3aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgIGg6IGhlaWdodCxcbiAgICAgICAgeDI6IHggKyB3aWR0aCxcbiAgICAgICAgeTI6IHkgKyBoZWlnaHQsXG4gICAgICAgIGN4OiB4ICsgd2lkdGggLyAyLFxuICAgICAgICBjeTogeSArIGhlaWdodCAvIDIsXG4gICAgICAgIHIxOiBNYXRoLm1pbih3aWR0aCwgaGVpZ2h0KSAvIDIsXG4gICAgICAgIHIyOiBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSAvIDIsXG4gICAgICAgIHIwOiBNYXRoLnNxcnQod2lkdGggKiB3aWR0aCArIGhlaWdodCAqIGhlaWdodCkgLyAyLFxuICAgICAgICBwYXRoOiByZWN0UGF0aCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSxcbiAgICAgICAgdmI6IFt4LCB5LCB3aWR0aCwgaGVpZ2h0XS5qb2luKCcgJyksXG4gICAgfTtcbn07XG52YXIgaXNCQm94SW50ZXJzZWN0ID0gZnVuY3Rpb24gKGJib3gxLCBiYm94Mikge1xuICAgIGJib3gxID0gYm94KGJib3gxKTtcbiAgICBiYm94MiA9IGJveChiYm94Mik7XG4gICAgcmV0dXJuIChpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueSkgfHxcbiAgICAgICAgaXNQb2ludEluc2lkZUJCb3goYmJveDIsIGJib3gxLngyLCBiYm94MS55KSB8fFxuICAgICAgICBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueTIpIHx8XG4gICAgICAgIGlzUG9pbnRJbnNpZGVCQm94KGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpIHx8XG4gICAgICAgIGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55KSB8fFxuICAgICAgICBpc1BvaW50SW5zaWRlQkJveChiYm94MSwgYmJveDIueDIsIGJib3gyLnkpIHx8XG4gICAgICAgIGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55MikgfHxcbiAgICAgICAgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngyLCBiYm94Mi55MikgfHxcbiAgICAgICAgKCgoYmJveDEueCA8IGJib3gyLngyICYmIGJib3gxLnggPiBiYm94Mi54KSB8fCAoYmJveDIueCA8IGJib3gxLngyICYmIGJib3gyLnggPiBiYm94MS54KSkgJiZcbiAgICAgICAgICAgICgoYmJveDEueSA8IGJib3gyLnkyICYmIGJib3gxLnkgPiBiYm94Mi55KSB8fCAoYmJveDIueSA8IGJib3gxLnkyICYmIGJib3gyLnkgPiBiYm94MS55KSkpKTtcbn07XG52YXIgYmV6aWVyQkJveCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSkge1xuICAgIGlmICghdXRpbF8xLmlzQXJyYXkocDF4KSkge1xuICAgICAgICBwMXggPSBbcDF4LCBwMXksIGMxeCwgYzF5LCBjMngsIGMyeSwgcDJ4LCBwMnldO1xuICAgIH1cbiAgICB2YXIgYmJveCA9IGN1cnZlRGltLmFwcGx5KG51bGwsIHAxeCk7XG4gICAgcmV0dXJuIGJveChiYm94Lm1pbi54LCBiYm94Lm1pbi55LCBiYm94Lm1heC54IC0gYmJveC5taW4ueCwgYmJveC5tYXgueSAtIGJib3gubWluLnkpO1xufTtcbnZhciBmaW5kRG90c0F0U2VnbWVudCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdCkge1xuICAgIHZhciB0MSA9IDEgLSB0O1xuICAgIHZhciB0MTMgPSBNYXRoLnBvdyh0MSwgMyk7XG4gICAgdmFyIHQxMiA9IE1hdGgucG93KHQxLCAyKTtcbiAgICB2YXIgdDIgPSB0ICogdDtcbiAgICB2YXIgdDMgPSB0MiAqIHQ7XG4gICAgdmFyIHggPSB0MTMgKiBwMXggKyB0MTIgKiAzICogdCAqIGMxeCArIHQxICogMyAqIHQgKiB0ICogYzJ4ICsgdDMgKiBwMng7XG4gICAgdmFyIHkgPSB0MTMgKiBwMXkgKyB0MTIgKiAzICogdCAqIGMxeSArIHQxICogMyAqIHQgKiB0ICogYzJ5ICsgdDMgKiBwMnk7XG4gICAgdmFyIG14ID0gcDF4ICsgMiAqIHQgKiAoYzF4IC0gcDF4KSArIHQyICogKGMyeCAtIDIgKiBjMXggKyBwMXgpO1xuICAgIHZhciBteSA9IHAxeSArIDIgKiB0ICogKGMxeSAtIHAxeSkgKyB0MiAqIChjMnkgLSAyICogYzF5ICsgcDF5KTtcbiAgICB2YXIgbnggPSBjMXggKyAyICogdCAqIChjMnggLSBjMXgpICsgdDIgKiAocDJ4IC0gMiAqIGMyeCArIGMxeCk7XG4gICAgdmFyIG55ID0gYzF5ICsgMiAqIHQgKiAoYzJ5IC0gYzF5KSArIHQyICogKHAyeSAtIDIgKiBjMnkgKyBjMXkpO1xuICAgIHZhciBheCA9IHQxICogcDF4ICsgdCAqIGMxeDtcbiAgICB2YXIgYXkgPSB0MSAqIHAxeSArIHQgKiBjMXk7XG4gICAgdmFyIGN4ID0gdDEgKiBjMnggKyB0ICogcDJ4O1xuICAgIHZhciBjeSA9IHQxICogYzJ5ICsgdCAqIHAyeTtcbiAgICB2YXIgYWxwaGEgPSA5MCAtIChNYXRoLmF0YW4yKG14IC0gbngsIG15IC0gbnkpICogMTgwKSAvIE1hdGguUEk7XG4gICAgLy8gKG14ID4gbnggfHwgbXkgPCBueSkgJiYgKGFscGhhICs9IDE4MCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgbToge1xuICAgICAgICAgICAgeDogbXgsXG4gICAgICAgICAgICB5OiBteSxcbiAgICAgICAgfSxcbiAgICAgICAgbjoge1xuICAgICAgICAgICAgeDogbngsXG4gICAgICAgICAgICB5OiBueSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RhcnQ6IHtcbiAgICAgICAgICAgIHg6IGF4LFxuICAgICAgICAgICAgeTogYXksXG4gICAgICAgIH0sXG4gICAgICAgIGVuZDoge1xuICAgICAgICAgICAgeDogY3gsXG4gICAgICAgICAgICB5OiBjeSxcbiAgICAgICAgfSxcbiAgICAgICAgYWxwaGE6IGFscGhhLFxuICAgIH07XG59O1xudmFyIGludGVySGVscGVyID0gZnVuY3Rpb24gKGJlejEsIGJlejIsIGp1c3RDb3VudCkge1xuICAgIHZhciBiYm94MSA9IGJlemllckJCb3goYmV6MSk7XG4gICAgdmFyIGJib3gyID0gYmV6aWVyQkJveChiZXoyKTtcbiAgICBpZiAoIWlzQkJveEludGVyc2VjdChiYm94MSwgYmJveDIpKSB7XG4gICAgICAgIHJldHVybiBqdXN0Q291bnQgPyAwIDogW107XG4gICAgfVxuICAgIHZhciBsMSA9IGJlemxlbi5hcHBseSgwLCBiZXoxKTtcbiAgICB2YXIgbDIgPSBiZXpsZW4uYXBwbHkoMCwgYmV6Mik7XG4gICAgdmFyIG4xID0gfn4obDEgLyA4KTtcbiAgICB2YXIgbjIgPSB+fihsMiAvIDgpO1xuICAgIHZhciBkb3RzMSA9IFtdO1xuICAgIHZhciBkb3RzMiA9IFtdO1xuICAgIHZhciB4eSA9IHt9O1xuICAgIHZhciByZXMgPSBqdXN0Q291bnQgPyAwIDogW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuMSArIDE7IGkrKykge1xuICAgICAgICB2YXIgZCA9IGZpbmREb3RzQXRTZWdtZW50LmFwcGx5KDAsIGJlejEuY29uY2F0KGkgLyBuMSkpO1xuICAgICAgICBkb3RzMS5wdXNoKHtcbiAgICAgICAgICAgIHg6IGQueCxcbiAgICAgICAgICAgIHk6IGQueSxcbiAgICAgICAgICAgIHQ6IGkgLyBuMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjIgKyAxOyBpKyspIHtcbiAgICAgICAgdmFyIGQgPSBmaW5kRG90c0F0U2VnbWVudC5hcHBseSgwLCBiZXoyLmNvbmNhdChpIC8gbjIpKTtcbiAgICAgICAgZG90czIucHVzaCh7XG4gICAgICAgICAgICB4OiBkLngsXG4gICAgICAgICAgICB5OiBkLnksXG4gICAgICAgICAgICB0OiBpIC8gbjIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4xOyBpKyspIHtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBuMjsgaisrKSB7XG4gICAgICAgICAgICB2YXIgZGkgPSBkb3RzMVtpXTtcbiAgICAgICAgICAgIHZhciBkaTEgPSBkb3RzMVtpICsgMV07XG4gICAgICAgICAgICB2YXIgZGogPSBkb3RzMltqXTtcbiAgICAgICAgICAgIHZhciBkajEgPSBkb3RzMltqICsgMV07XG4gICAgICAgICAgICB2YXIgY2kgPSBNYXRoLmFicyhkaTEueCAtIGRpLngpIDwgMC4wMDEgPyAneScgOiAneCc7XG4gICAgICAgICAgICB2YXIgY2ogPSBNYXRoLmFicyhkajEueCAtIGRqLngpIDwgMC4wMDEgPyAneScgOiAneCc7XG4gICAgICAgICAgICB2YXIgaXMgPSBpbnRlcnNlY3QoZGkueCwgZGkueSwgZGkxLngsIGRpMS55LCBkai54LCBkai55LCBkajEueCwgZGoxLnkpO1xuICAgICAgICAgICAgaWYgKGlzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHh5W2lzLngudG9GaXhlZCg0KV0gPT09IGlzLnkudG9GaXhlZCg0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgeHlbaXMueC50b0ZpeGVkKDQpXSA9IGlzLnkudG9GaXhlZCg0KTtcbiAgICAgICAgICAgICAgICB2YXIgdDEgPSBkaS50ICsgTWF0aC5hYnMoKGlzW2NpXSAtIGRpW2NpXSkgLyAoZGkxW2NpXSAtIGRpW2NpXSkpICogKGRpMS50IC0gZGkudCk7XG4gICAgICAgICAgICAgICAgdmFyIHQyID0gZGoudCArIE1hdGguYWJzKChpc1tjal0gLSBkaltjal0pIC8gKGRqMVtjal0gLSBkaltjal0pKSAqIChkajEudCAtIGRqLnQpO1xuICAgICAgICAgICAgICAgIGlmICh0MSA+PSAwICYmIHQxIDw9IDEgJiYgdDIgPj0gMCAmJiB0MiA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGlzLngsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaXMueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MTogdDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdDI6IHQyLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn07XG52YXIgaW50ZXJQYXRoSGVscGVyID0gZnVuY3Rpb24gKHBhdGgxLCBwYXRoMiwganVzdENvdW50KSB7XG4gICAgcGF0aDEgPSBwYXRoVG9DdXJ2ZShwYXRoMSk7XG4gICAgcGF0aDIgPSBwYXRoVG9DdXJ2ZShwYXRoMik7XG4gICAgdmFyIHgxO1xuICAgIHZhciB5MTtcbiAgICB2YXIgeDI7XG4gICAgdmFyIHkyO1xuICAgIHZhciB4MW07XG4gICAgdmFyIHkxbTtcbiAgICB2YXIgeDJtO1xuICAgIHZhciB5Mm07XG4gICAgdmFyIGJlejE7XG4gICAgdmFyIGJlejI7XG4gICAgdmFyIHJlcyA9IGp1c3RDb3VudCA/IDAgOiBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwYXRoMS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgIHZhciBwaSA9IHBhdGgxW2ldO1xuICAgICAgICBpZiAocGlbMF0gPT09ICdNJykge1xuICAgICAgICAgICAgeDEgPSB4MW0gPSBwaVsxXTtcbiAgICAgICAgICAgIHkxID0geTFtID0gcGlbMl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAocGlbMF0gPT09ICdDJykge1xuICAgICAgICAgICAgICAgIGJlejEgPSBbeDEsIHkxXS5jb25jYXQocGkuc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgIHgxID0gYmV6MVs2XTtcbiAgICAgICAgICAgICAgICB5MSA9IGJlejFbN107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBiZXoxID0gW3gxLCB5MSwgeDEsIHkxLCB4MW0sIHkxbSwgeDFtLCB5MW1dO1xuICAgICAgICAgICAgICAgIHgxID0geDFtO1xuICAgICAgICAgICAgICAgIHkxID0geTFtO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gcGF0aDIubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgIHZhciBwaiA9IHBhdGgyW2pdO1xuICAgICAgICAgICAgICAgIGlmIChwalswXSA9PT0gJ00nKSB7XG4gICAgICAgICAgICAgICAgICAgIHgyID0geDJtID0gcGpbMV07XG4gICAgICAgICAgICAgICAgICAgIHkyID0geTJtID0gcGpbMl07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGpbMF0gPT09ICdDJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmV6MiA9IFt4MiwgeTJdLmNvbmNhdChwai5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB4MiA9IGJlejJbNl07XG4gICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGJlejJbN107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXoyID0gW3gyLCB5MiwgeDIsIHkyLCB4Mm0sIHkybSwgeDJtLCB5Mm1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSB4Mm07XG4gICAgICAgICAgICAgICAgICAgICAgICB5MiA9IHkybTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YXIgaW50ciA9IGludGVySGVscGVyKGJlejEsIGJlejIsIGp1c3RDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSBpbnRyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgayA9IDAsIGtrID0gaW50ci5sZW5ndGg7IGsgPCBrazsgaysrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cltrXS5zZWdtZW50MSA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cltrXS5zZWdtZW50MiA9IGo7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cltrXS5iZXoxID0gYmV6MTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRyW2tdLmJlejIgPSBiZXoyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVzLmNvbmNhdChpbnRyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcbnZhciBpbnRlcnNlY3Rpb24gPSBmdW5jdGlvbiAocGF0aDEsIHBhdGgyKSB7XG4gICAgcmV0dXJuIGludGVyUGF0aEhlbHBlcihwYXRoMSwgcGF0aDIpO1xufTtcbmV4cG9ydHMuaW50ZXJzZWN0aW9uID0gaW50ZXJzZWN0aW9uO1xuZnVuY3Rpb24gZGVjYXN0ZWxqYXUocG9pbnRzLCB0KSB7XG4gICAgdmFyIGxlZnQgPSBbXTtcbiAgICB2YXIgcmlnaHQgPSBbXTtcbiAgICBmdW5jdGlvbiByZWN1cnNlKHBvaW50cywgdCkge1xuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgbGVmdC5wdXNoKHBvaW50c1swXSk7XG4gICAgICAgICAgICByaWdodC5wdXNoKHBvaW50c1swXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgbWlkZGxlUG9pbnRzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBsZWZ0LnB1c2gocG9pbnRzWzBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IHBvaW50cy5sZW5ndGggLSAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0LnB1c2gocG9pbnRzW2kgKyAxXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1pZGRsZVBvaW50c1tpXSA9IFtcbiAgICAgICAgICAgICAgICAgICAgKDEgLSB0KSAqIHBvaW50c1tpXVswXSArIHQgKiBwb2ludHNbaSArIDFdWzBdLFxuICAgICAgICAgICAgICAgICAgICAoMSAtIHQpICogcG9pbnRzW2ldWzFdICsgdCAqIHBvaW50c1tpICsgMV1bMV0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlY3Vyc2UobWlkZGxlUG9pbnRzLCB0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocG9pbnRzLmxlbmd0aCkge1xuICAgICAgICByZWN1cnNlKHBvaW50cywgdCk7XG4gICAgfVxuICAgIHJldHVybiB7IGxlZnQ6IGxlZnQsIHJpZ2h0OiByaWdodC5yZXZlcnNlKCkgfTtcbn1cbmZ1bmN0aW9uIHNwbGl0Q3VydmUoc3RhcnQsIGVuZCwgY291bnQpIHtcbiAgICB2YXIgcG9pbnRzID0gW1tzdGFydFsxXSwgc3RhcnRbMl1dXTtcbiAgICBjb3VudCA9IGNvdW50IHx8IDI7XG4gICAgdmFyIHNlZ21lbnRzID0gW107XG4gICAgaWYgKGVuZFswXSA9PT0gJ0EnKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKGVuZFs2XSk7XG4gICAgICAgIHBvaW50cy5wdXNoKGVuZFs3XSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGVuZFswXSA9PT0gJ0MnKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbMV0sIGVuZFsyXV0pO1xuICAgICAgICBwb2ludHMucHVzaChbZW5kWzNdLCBlbmRbNF1dKTtcbiAgICAgICAgcG9pbnRzLnB1c2goW2VuZFs1XSwgZW5kWzZdXSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGVuZFswXSA9PT0gJ1MnIHx8IGVuZFswXSA9PT0gJ1EnKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbMV0sIGVuZFsyXV0pO1xuICAgICAgICBwb2ludHMucHVzaChbZW5kWzNdLCBlbmRbNF1dKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbMV0sIGVuZFsyXV0pO1xuICAgIH1cbiAgICB2YXIgbGVmdFNlZ21lbnRzID0gcG9pbnRzO1xuICAgIHZhciB0ID0gMSAvIGNvdW50O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQgLSAxOyBpKyspIHtcbiAgICAgICAgdmFyIHJ0ID0gdCAvICgxIC0gdCAqIGkpO1xuICAgICAgICB2YXIgc3BsaXQgPSBkZWNhc3RlbGphdShsZWZ0U2VnbWVudHMsIHJ0KTtcbiAgICAgICAgc2VnbWVudHMucHVzaChzcGxpdC5sZWZ0KTtcbiAgICAgICAgbGVmdFNlZ21lbnRzID0gc3BsaXQucmlnaHQ7XG4gICAgfVxuICAgIHNlZ21lbnRzLnB1c2gobGVmdFNlZ21lbnRzKTtcbiAgICB2YXIgcmVzdWx0ID0gc2VnbWVudHMubWFwKGZ1bmN0aW9uIChzZWdtZW50KSB7XG4gICAgICAgIHZhciBjbWQgPSBbXTtcbiAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSA0KSB7XG4gICAgICAgICAgICBjbWQucHVzaCgnQycpO1xuICAgICAgICAgICAgY21kID0gY21kLmNvbmNhdChzZWdtZW50WzJdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICAgICAgY21kLnB1c2goJ1EnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNtZCA9IGNtZC5jb25jYXQoc2VnbWVudFsxXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjbWQucHVzaCgnTCcpO1xuICAgICAgICB9XG4gICAgICAgIGNtZCA9IGNtZC5jb25jYXQoc2VnbWVudFtzZWdtZW50Lmxlbmd0aCAtIDFdKTtcbiAgICAgICAgcmV0dXJuIGNtZDtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxudmFyIHNwbGl0U2VnbWVudCA9IGZ1bmN0aW9uIChzdGFydCwgZW5kLCBjb3VudCkge1xuICAgIGlmIChjb3VudCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gW1tdLmNvbmNhdChzdGFydCldO1xuICAgIH1cbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcbiAgICBpZiAoZW5kWzBdID09PSAnTCcgfHwgZW5kWzBdID09PSAnQycgfHwgZW5kWzBdID09PSAnUScpIHtcbiAgICAgICAgc2VnbWVudHMgPSBzZWdtZW50cy5jb25jYXQoc3BsaXRDdXJ2ZShzdGFydCwgZW5kLCBjb3VudCkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIHRlbXAgPSBbXS5jb25jYXQoc3RhcnQpO1xuICAgICAgICBpZiAodGVtcFswXSA9PT0gJ00nKSB7XG4gICAgICAgICAgICB0ZW1wWzBdID0gJ0wnO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IGNvdW50IC0gMTsgaSsrKSB7XG4gICAgICAgICAgICBzZWdtZW50cy5wdXNoKHRlbXApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzZWdtZW50cztcbn07XG52YXIgZmlsbFBhdGggPSBmdW5jdGlvbiAoc291cmNlLCB0YXJnZXQpIHtcbiAgICBpZiAoc291cmNlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gc291cmNlO1xuICAgIH1cbiAgICB2YXIgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCAtIDE7XG4gICAgdmFyIHRhcmdldExlbiA9IHRhcmdldC5sZW5ndGggLSAxO1xuICAgIHZhciByYXRpbyA9IHNvdXJjZUxlbiAvIHRhcmdldExlbjtcbiAgICB2YXIgc2VnbWVudHNUb0ZpbGwgPSBbXTtcbiAgICBpZiAoc291cmNlLmxlbmd0aCA9PT0gMSAmJiBzb3VyY2VbMF1bMF0gPT09ICdNJykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhcmdldExlbiAtIHNvdXJjZUxlbjsgaSsrKSB7XG4gICAgICAgICAgICBzb3VyY2UucHVzaChzb3VyY2VbMF0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFyZ2V0TGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGluZGV4ID0gTWF0aC5mbG9vcihyYXRpbyAqIGkpO1xuICAgICAgICBzZWdtZW50c1RvRmlsbFtpbmRleF0gPSAoc2VnbWVudHNUb0ZpbGxbaW5kZXhdIHx8IDApICsgMTtcbiAgICB9XG4gICAgdmFyIGZpbGxlZCA9IHNlZ21lbnRzVG9GaWxsLnJlZHVjZShmdW5jdGlvbiAoZmlsbGVkLCBjb3VudCwgaSkge1xuICAgICAgICBpZiAoaSA9PT0gc291cmNlTGVuKSB7XG4gICAgICAgICAgICByZXR1cm4gZmlsbGVkLmNvbmNhdChzb3VyY2Vbc291cmNlTGVuXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbGxlZC5jb25jYXQoc3BsaXRTZWdtZW50KHNvdXJjZVtpXSwgc291cmNlW2kgKyAxXSwgY291bnQpKTtcbiAgICB9LCBbXSk7XG4gICAgZmlsbGVkLnVuc2hpZnQoc291cmNlWzBdKTtcbiAgICBpZiAodGFyZ2V0W3RhcmdldExlbl0gPT09ICdaJyB8fCB0YXJnZXRbdGFyZ2V0TGVuXSA9PT0gJ3onKSB7XG4gICAgICAgIGZpbGxlZC5wdXNoKCdaJyk7XG4gICAgfVxuICAgIHJldHVybiBmaWxsZWQ7XG59O1xuZXhwb3J0cy5maWxsUGF0aCA9IGZpbGxQYXRoO1xudmFyIGlzRXF1YWwgPSBmdW5jdGlvbiAob2JqMSwgb2JqMikge1xuICAgIGlmIChvYmoxLmxlbmd0aCAhPT0gb2JqMi5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gdHJ1ZTtcbiAgICB1dGlsXzEuZWFjaChvYmoxLCBmdW5jdGlvbiAoaXRlbSwgaSkge1xuICAgICAgICBpZiAoaXRlbSAhPT0gb2JqMltpXSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbmZ1bmN0aW9uIGdldE1pbkRpZmYoZGVsLCBhZGQsIG1vZGlmeSkge1xuICAgIHZhciB0eXBlID0gbnVsbDtcbiAgICB2YXIgbWluID0gbW9kaWZ5O1xuICAgIGlmIChhZGQgPCBtaW4pIHtcbiAgICAgICAgbWluID0gYWRkO1xuICAgICAgICB0eXBlID0gJ2FkZCc7XG4gICAgfVxuICAgIGlmIChkZWwgPCBtaW4pIHtcbiAgICAgICAgbWluID0gZGVsO1xuICAgICAgICB0eXBlID0gJ2RlbCc7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgIG1pbjogbWluLFxuICAgIH07XG59XG4vKlxuICogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV2ZW5zaHRlaW5fZGlzdGFuY2VcbiAqIOiuoeeul+S4pOadoXBhdGjnmoTnvJbovpHot53nprtcbiAqL1xudmFyIGxldmVuc2h0ZWluRGlzdGFuY2UgPSBmdW5jdGlvbiAoc291cmNlLCB0YXJnZXQpIHtcbiAgICB2YXIgc291cmNlTGVuID0gc291cmNlLmxlbmd0aDtcbiAgICB2YXIgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aDtcbiAgICB2YXIgc291cmNlU2VnbWVudDtcbiAgICB2YXIgdGFyZ2V0U2VnbWVudDtcbiAgICB2YXIgdGVtcCA9IDA7XG4gICAgaWYgKHNvdXJjZUxlbiA9PT0gMCB8fCB0YXJnZXRMZW4gPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBkaXN0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPD0gc291cmNlTGVuOyBpKyspIHtcbiAgICAgICAgZGlzdFtpXSA9IFtdO1xuICAgICAgICBkaXN0W2ldWzBdID0geyBtaW46IGkgfTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gdGFyZ2V0TGVuOyBqKyspIHtcbiAgICAgICAgZGlzdFswXVtqXSA9IHsgbWluOiBqIH07XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IHNvdXJjZUxlbjsgaSsrKSB7XG4gICAgICAgIHNvdXJjZVNlZ21lbnQgPSBzb3VyY2VbaSAtIDFdO1xuICAgICAgICBmb3IgKHZhciBqID0gMTsgaiA8PSB0YXJnZXRMZW47IGorKykge1xuICAgICAgICAgICAgdGFyZ2V0U2VnbWVudCA9IHRhcmdldFtqIC0gMV07XG4gICAgICAgICAgICBpZiAoaXNFcXVhbChzb3VyY2VTZWdtZW50LCB0YXJnZXRTZWdtZW50KSkge1xuICAgICAgICAgICAgICAgIHRlbXAgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGVtcCA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGVsID0gZGlzdFtpIC0gMV1bal0ubWluICsgMTtcbiAgICAgICAgICAgIHZhciBhZGQgPSBkaXN0W2ldW2ogLSAxXS5taW4gKyAxO1xuICAgICAgICAgICAgdmFyIG1vZGlmeSA9IGRpc3RbaSAtIDFdW2ogLSAxXS5taW4gKyB0ZW1wO1xuICAgICAgICAgICAgZGlzdFtpXVtqXSA9IGdldE1pbkRpZmYoZGVsLCBhZGQsIG1vZGlmeSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRpc3Q7XG59O1xudmFyIGZpbGxQYXRoQnlEaWZmID0gZnVuY3Rpb24gKHNvdXJjZSwgdGFyZ2V0KSB7XG4gICAgdmFyIGRpZmZNYXRyaXggPSBsZXZlbnNodGVpbkRpc3RhbmNlKHNvdXJjZSwgdGFyZ2V0KTtcbiAgICB2YXIgc291cmNlTGVuID0gc291cmNlLmxlbmd0aDtcbiAgICB2YXIgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aDtcbiAgICB2YXIgY2hhbmdlcyA9IFtdO1xuICAgIHZhciBpbmRleCA9IDE7XG4gICAgdmFyIG1pblBvcyA9IDE7XG4gICAgLy8g5aaC5p6cc291cmNl5ZKMdGFyZ2V05LiN5piv5a6M5YWo5LiN55u4562JXG4gICAgaWYgKGRpZmZNYXRyaXhbc291cmNlTGVuXVt0YXJnZXRMZW5dLm1pbiAhPT0gc291cmNlTGVuKSB7XG4gICAgICAgIC8vIOiOt+WPluS7jnNvdXJjZeWIsHRhcmdldOaJgOmcgOaUueWKqFxuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8PSBzb3VyY2VMZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIG1pbiA9IGRpZmZNYXRyaXhbaV1baV0ubWluO1xuICAgICAgICAgICAgbWluUG9zID0gaTtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSBpbmRleDsgaiA8PSB0YXJnZXRMZW47IGorKykge1xuICAgICAgICAgICAgICAgIGlmIChkaWZmTWF0cml4W2ldW2pdLm1pbiA8IG1pbikge1xuICAgICAgICAgICAgICAgICAgICBtaW4gPSBkaWZmTWF0cml4W2ldW2pdLm1pbjtcbiAgICAgICAgICAgICAgICAgICAgbWluUG9zID0gajtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbmRleCA9IG1pblBvcztcbiAgICAgICAgICAgIGlmIChkaWZmTWF0cml4W2ldW2luZGV4XS50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2hhbmdlcy5wdXNoKHsgaW5kZXg6IGkgLSAxLCB0eXBlOiBkaWZmTWF0cml4W2ldW2luZGV4XS50eXBlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOWvuXNvdXJjZei/m+ihjOWinuWIoHBhdGhcbiAgICAgICAgZm9yICh2YXIgaSA9IGNoYW5nZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGluZGV4ID0gY2hhbmdlc1tpXS5pbmRleDtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VzW2ldLnR5cGUgPT09ICdhZGQnKSB7XG4gICAgICAgICAgICAgICAgc291cmNlLnNwbGljZShpbmRleCwgMCwgW10uY29uY2F0KHNvdXJjZVtpbmRleF0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvdXJjZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHNvdXJjZeWwvumDqOihpem9kFxuICAgIHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGg7XG4gICAgdmFyIGRpZmYgPSB0YXJnZXRMZW4gLSBzb3VyY2VMZW47XG4gICAgaWYgKHNvdXJjZUxlbiA8IHRhcmdldExlbikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpZmY7IGkrKykge1xuICAgICAgICAgICAgaWYgKHNvdXJjZVtzb3VyY2VMZW4gLSAxXVswXSA9PT0gJ3onIHx8IHNvdXJjZVtzb3VyY2VMZW4gLSAxXVswXSA9PT0gJ1onKSB7XG4gICAgICAgICAgICAgICAgc291cmNlLnNwbGljZShzb3VyY2VMZW4gLSAyLCAwLCBzb3VyY2Vbc291cmNlTGVuIC0gMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc291cmNlLnB1c2goc291cmNlW3NvdXJjZUxlbiAtIDFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNvdXJjZUxlbiArPSAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2U7XG59O1xuZXhwb3J0cy5maWxsUGF0aEJ5RGlmZiA9IGZpbGxQYXRoQnlEaWZmO1xuLy8g5bCG5Lik5Liq54K55Z2H5YiG5oiQY291bnTkuKrngrlcbmZ1bmN0aW9uIF9zcGxpdFBvaW50cyhwb2ludHMsIGZvcm1lciwgY291bnQpIHtcbiAgICB2YXIgcmVzdWx0ID0gW10uY29uY2F0KHBvaW50cyk7XG4gICAgdmFyIGluZGV4O1xuICAgIHZhciB0ID0gMSAvIChjb3VudCArIDEpO1xuICAgIHZhciBmb3JtZXJFbmQgPSBfZ2V0U2VnbWVudFBvaW50cyhmb3JtZXIpWzBdO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IGNvdW50OyBpKyspIHtcbiAgICAgICAgdCAqPSBpO1xuICAgICAgICBpbmRleCA9IE1hdGguZmxvb3IocG9pbnRzLmxlbmd0aCAqIHQpO1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHJlc3VsdC51bnNoaWZ0KFtmb3JtZXJFbmRbMF0gKiB0ICsgcG9pbnRzW2luZGV4XVswXSAqICgxIC0gdCksIGZvcm1lckVuZFsxXSAqIHQgKyBwb2ludHNbaW5kZXhdWzFdICogKDEgLSB0KV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzdWx0LnNwbGljZShpbmRleCwgMCwgW1xuICAgICAgICAgICAgICAgIGZvcm1lckVuZFswXSAqIHQgKyBwb2ludHNbaW5kZXhdWzBdICogKDEgLSB0KSxcbiAgICAgICAgICAgICAgICBmb3JtZXJFbmRbMV0gKiB0ICsgcG9pbnRzW2luZGV4XVsxXSAqICgxIC0gdCksXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLypcbiAqIOaKveWPlnBhdGhTZWdtZW505Lit55qE5YWz6ZSu54K5XG4gKiBNLEwsQSxRLEgsVuS4gOS4querr+eCuVxuICogUSwgU+aKveWPluS4gOS4querr+eCue+8jOS4gOS4quaOp+WItueCuVxuICogQ+aKveWPluS4gOS4querr+eCue+8jOS4pOS4quaOp+WItueCuVxuICovXG5mdW5jdGlvbiBfZ2V0U2VnbWVudFBvaW50cyhzZWdtZW50KSB7XG4gICAgdmFyIHBvaW50cyA9IFtdO1xuICAgIHN3aXRjaCAoc2VnbWVudFswXSkge1xuICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzFdLCBzZWdtZW50WzJdXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbNl0sIHNlZ21lbnRbN11dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdRJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzNdLCBzZWdtZW50WzRdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbMV0sIHNlZ21lbnRbMl1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdDJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzVdLCBzZWdtZW50WzZdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbM10sIHNlZ21lbnRbNF1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzNdLCBzZWdtZW50WzRdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbMV0sIHNlZ21lbnRbMV1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzFdLCBzZWdtZW50WzFdXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50cztcbn1cbnZhciBmb3JtYXRQYXRoID0gZnVuY3Rpb24gKGZyb21QYXRoLCB0b1BhdGgpIHtcbiAgICBpZiAoZnJvbVBhdGgubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIGZyb21QYXRoO1xuICAgIH1cbiAgICB2YXIgcG9pbnRzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9QYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChmcm9tUGF0aFtpXVswXSAhPT0gdG9QYXRoW2ldWzBdKSB7XG4gICAgICAgICAgICAvLyDojrflj5Zmcm9tUGF0aOeahHBhdGhTZWdtZW5055qE56uv54K577yM5qC55o2udG9QYXRo55qE5oyH5Luk5a+55YW25pS56YCgXG4gICAgICAgICAgICBwb2ludHMgPSBfZ2V0U2VnbWVudFBvaW50cyhmcm9tUGF0aFtpXSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRvUGF0aFtpXVswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ00nOlxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnTSddLmNvbmNhdChwb2ludHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGhbaV0gPSBbJ0wnXS5jb25jYXQocG9pbnRzWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gW10uY29uY2F0KHRvUGF0aFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldWzZdID0gcG9pbnRzWzBdWzBdO1xuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXVs3XSA9IHBvaW50c1swXVsxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzID0gX3NwbGl0UG9pbnRzKHBvaW50cywgZnJvbVBhdGhbaSAtIDFdLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gWydRJ10uY29uY2F0KHBvaW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFyciwgaSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyci5jb25jYXQoaSk7XG4gICAgICAgICAgICAgICAgICAgIH0sIFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnVCddLmNvbmNhdChwb2ludHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdDJzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPCAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludHMgPSBfc3BsaXRQb2ludHMocG9pbnRzLCBmcm9tUGF0aFtpIC0gMV0sIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGhbaV0gPSB0b1BhdGhbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGhbaV0gPSBbJ0MnXS5jb25jYXQocG9pbnRzLnJlZHVjZShmdW5jdGlvbiAoYXJyLCBpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyLmNvbmNhdChpKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgW10pKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnUyc6XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzID0gX3NwbGl0UG9pbnRzKHBvaW50cywgZnJvbVBhdGhbaSAtIDFdLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gWydTJ10uY29uY2F0KHBvaW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFyciwgaSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyci5jb25jYXQoaSk7XG4gICAgICAgICAgICAgICAgICAgIH0sIFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmcm9tUGF0aDtcbn07XG5leHBvcnRzLmZvcm1hdFBhdGggPSBmb3JtYXRQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xudmFyIG9mZnNjcmVlbl8xID0gcmVxdWlyZShcIi4vb2Zmc2NyZWVuXCIpO1xuLyoqXG4gKiDojrflj5bmlofmnKznmoTpq5jluqZcbiAqIEBwYXJhbSB0ZXh0IOaWh+acrFxuICogQHBhcmFtIGZvbnRTaXplIOWtl+S9k+Wkp+Wwj1xuICogQHBhcmFtIGxpbmVIZWlnaHQg6KGM6auY77yM5Y+v5Lul5Li656m6XG4gKi9cbmZ1bmN0aW9uIGdldFRleHRIZWlnaHQodGV4dCwgZm9udFNpemUsIGxpbmVIZWlnaHQpIHtcbiAgICB2YXIgbGluZUNvdW50ID0gMTtcbiAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHRleHQpKSB7XG4gICAgICAgIGxpbmVDb3VudCA9IHRleHQuc3BsaXQoJ1xcbicpLmxlbmd0aDtcbiAgICB9XG4gICAgaWYgKGxpbmVDb3VudCA+IDEpIHtcbiAgICAgICAgdmFyIHNwYWNlaW5nWSA9IGdldExpbmVTcGFjZWluZyhmb250U2l6ZSwgbGluZUhlaWdodCk7XG4gICAgICAgIHJldHVybiBmb250U2l6ZSAqIGxpbmVDb3VudCArIHNwYWNlaW5nWSAqIChsaW5lQ291bnQgLSAxKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvbnRTaXplO1xufVxuZXhwb3J0cy5nZXRUZXh0SGVpZ2h0ID0gZ2V0VGV4dEhlaWdodDtcbi8qKlxuICog6I635Y+W6KGM6Ze06Led5aaC5p6c5paH5pys5aSa6KGM77yM6ZyA6KaB6I635Y+W5paH5pys6Ze06LedXG4gKiBAcGFyYW0gZm9udFNpemUg5a2X5L2T5aSn5bCPXG4gKiBAcGFyYW0gbGluZUhlaWdodCDooYzpq5hcbiAqL1xuZnVuY3Rpb24gZ2V0TGluZVNwYWNlaW5nKGZvbnRTaXplLCBsaW5lSGVpZ2h0KSB7XG4gICAgcmV0dXJuIGxpbmVIZWlnaHQgPyBsaW5lSGVpZ2h0IC0gZm9udFNpemUgOiBmb250U2l6ZSAqIDAuMTQ7XG59XG5leHBvcnRzLmdldExpbmVTcGFjZWluZyA9IGdldExpbmVTcGFjZWluZztcbi8qKlxuICog5a2X5L2T5a695bqmXG4gKiBAcGFyYW0gdGV4dCDmlofmnKxcbiAqIEBwYXJhbSBmb250IOWtl+S9k1xuICovXG5mdW5jdGlvbiBnZXRUZXh0V2lkdGgodGV4dCwgZm9udCkge1xuICAgIHZhciBjb250ZXh0ID0gb2Zmc2NyZWVuXzEuZ2V0T2ZmU2NyZWVuQ29udGV4dCgpOyAvLyDojrflj5bnprvlsY/nmoQgY3R4IOi/m+ihjOiuoeeul1xuICAgIHZhciB3aWR0aCA9IDA7XG4gICAgLy8gbnVsbCDmiJbogIUgdW5kZWZpbmVkIOaXtu+8jOWuveW6puS4uiAwXG4gICAgaWYgKHV0aWxfMS5pc05pbCh0ZXh0KSB8fCB0ZXh0ID09PSAnJykge1xuICAgICAgICByZXR1cm4gd2lkdGg7XG4gICAgfVxuICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgIGNvbnRleHQuZm9udCA9IGZvbnQ7XG4gICAgaWYgKHV0aWxfMS5pc1N0cmluZyh0ZXh0KSAmJiB0ZXh0LmluY2x1ZGVzKCdcXG4nKSkge1xuICAgICAgICB2YXIgdGV4dEFyciA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0ZXh0QXJyLCBmdW5jdGlvbiAoc3ViVGV4dCkge1xuICAgICAgICAgICAgdmFyIG1lYXN1cmVXaWR0aCA9IGNvbnRleHQubWVhc3VyZVRleHQoc3ViVGV4dCkud2lkdGg7XG4gICAgICAgICAgICBpZiAod2lkdGggPCBtZWFzdXJlV2lkdGgpIHtcbiAgICAgICAgICAgICAgICB3aWR0aCA9IG1lYXN1cmVXaWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB3aWR0aCA9IGNvbnRleHQubWVhc3VyZVRleHQodGV4dCkud2lkdGg7XG4gICAgfVxuICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgIHJldHVybiB3aWR0aDtcbn1cbmV4cG9ydHMuZ2V0VGV4dFdpZHRoID0gZ2V0VGV4dFdpZHRoO1xuZnVuY3Rpb24gYXNzZW1ibGVGb250KGF0dHJzKSB7XG4gICAgdmFyIGZvbnRTaXplID0gYXR0cnMuZm9udFNpemUsIGZvbnRGYW1pbHkgPSBhdHRycy5mb250RmFtaWx5LCBmb250V2VpZ2h0ID0gYXR0cnMuZm9udFdlaWdodCwgZm9udFN0eWxlID0gYXR0cnMuZm9udFN0eWxlLCBmb250VmFyaWFudCA9IGF0dHJzLmZvbnRWYXJpYW50O1xuICAgIHJldHVybiBbZm9udFN0eWxlLCBmb250VmFyaWFudCwgZm9udFdlaWdodCwgZm9udFNpemUgKyBcInB4XCIsIGZvbnRGYW1pbHldLmpvaW4oJyAnKS50cmltKCk7XG59XG5leHBvcnRzLmFzc2VtYmxlRm9udCA9IGFzc2VtYmxlRm9udDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRleHQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiByZW1vdmVGcm9tQXJyYXkoYXJyLCBvYmopIHtcbiAgICB2YXIgaW5kZXggPSBhcnIuaW5kZXhPZihvYmopO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgYXJyLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxufVxuZXhwb3J0cy5yZW1vdmVGcm9tQXJyYXkgPSByZW1vdmVGcm9tQXJyYXk7XG5leHBvcnRzLmlzQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnO1xudmFyIGlzX25pbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL2lzLW5pbFwiKTtcbmV4cG9ydHMuaXNOaWwgPSBpc19uaWxfMS5kZWZhdWx0O1xudmFyIGlzX2Z1bmN0aW9uXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvaXMtZnVuY3Rpb25cIik7XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc19mdW5jdGlvbl8xLmRlZmF1bHQ7XG52YXIgaXNfc3RyaW5nXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvaXMtc3RyaW5nXCIpO1xuZXhwb3J0cy5pc1N0cmluZyA9IGlzX3N0cmluZ18xLmRlZmF1bHQ7XG52YXIgaXNfb2JqZWN0XzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvaXMtb2JqZWN0XCIpO1xuZXhwb3J0cy5pc09iamVjdCA9IGlzX29iamVjdF8xLmRlZmF1bHQ7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1hcnJheVwiKTtcbmV4cG9ydHMuaXNBcnJheSA9IGlzX2FycmF5XzEuZGVmYXVsdDtcbnZhciBtaXhfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9taXhcIik7XG5leHBvcnRzLm1peCA9IG1peF8xLmRlZmF1bHQ7XG52YXIgZWFjaF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL2VhY2hcIik7XG5leHBvcnRzLmVhY2ggPSBlYWNoXzEuZGVmYXVsdDtcbnZhciB1cHBlcl9maXJzdF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL3VwcGVyLWZpcnN0XCIpO1xuZXhwb3J0cy51cHBlckZpcnN0ID0gdXBwZXJfZmlyc3RfMS5kZWZhdWx0O1xuLy8g5piv5ZCm5YWD57Sg55qE54i25a655ZmoXG5mdW5jdGlvbiBpc1BhcmVudChjb250YWluZXIsIHNoYXBlKSB7XG4gICAgLy8g5omA5pyJIHNoYXBlIOmDveaYryBjYW52YXMg55qE5a2Q5YWD57SgXG4gICAgaWYgKGNvbnRhaW5lci5pc0NhbnZhcygpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB2YXIgcGFyZW50ID0gc2hhcGUuZ2V0UGFyZW50KCk7XG4gICAgdmFyIGlzUGFyZW50ID0gZmFsc2U7XG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgICBpZiAocGFyZW50ID09PSBjb250YWluZXIpIHtcbiAgICAgICAgICAgIGlzUGFyZW50ID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIGlzUGFyZW50O1xufVxuZXhwb3J0cy5pc1BhcmVudCA9IGlzUGFyZW50O1xuZnVuY3Rpb24gaXNBbGxvd0NhcHR1cmUoZWxlbWVudCkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gZWxlbWVudC5jZmcudmlzaWJsZSAmJiBlbGVtZW50LmNmZy5jYXB0dXJlO1xufVxuZXhwb3J0cy5pc0FsbG93Q2FwdHVyZSA9IGlzQWxsb3dDYXB0dXJlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dXRpbC5qcy5tYXAiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwiX19ucG1pbnN0YWxsX2RvbmVcIjogZmFsc2UsXG4gIFwiX2FyZ3NcIjogW1xuICAgIFtcbiAgICAgIFwiQGFudHYvZy1iYXNlQDAuNC43XCIsXG4gICAgICBcIkM6XFxcXHhhbXBwXFxcXGh0ZG9jc1xcXFxpY2Vocm1cXFxcd2ViXCJcbiAgICBdXG4gIF0sXG4gIFwiX2Zyb21cIjogXCJAYW50di9nLWJhc2VAMC40LjdcIixcbiAgXCJfaWRcIjogXCJAYW50di9nLWJhc2VAMC40LjdcIixcbiAgXCJfaW5CdW5kbGVcIjogZmFsc2UsXG4gIFwiX2ludGVncml0eVwiOiBcInNoYTUxMi13S1NwUzMvTTFzbFU5MmlPZ2kyUVY0TUNkODJKMWQyUHlQY1FBcnFTRlJVWlUwS25WTUlsOTV2NzlkRzBCZTRZdkZhWjNiVnJUNk5zMUN6cjhvcGxoQT09XCIsXG4gIFwiX2xvY2F0aW9uXCI6IFwiL0BhbnR2L2ctYmFzZVwiLFxuICBcIl9waGFudG9tQ2hpbGRyZW5cIjoge30sXG4gIFwiX3JlcXVlc3RlZFwiOiB7XG4gICAgXCJ0eXBlXCI6IFwidmVyc2lvblwiLFxuICAgIFwicmVnaXN0cnlcIjogdHJ1ZSxcbiAgICBcInJhd1wiOiBcIkBhbnR2L2ctYmFzZUAwLjQuN1wiLFxuICAgIFwibmFtZVwiOiBcIkBhbnR2L2ctYmFzZVwiLFxuICAgIFwiZXNjYXBlZE5hbWVcIjogXCJAYW50diUyZmctYmFzZVwiLFxuICAgIFwic2NvcGVcIjogXCJAYW50dlwiLFxuICAgIFwicmF3U3BlY1wiOiBcIjAuNC43XCIsXG4gICAgXCJzYXZlU3BlY1wiOiBudWxsLFxuICAgIFwiZmV0Y2hTcGVjXCI6IFwiMC40LjdcIlxuICB9LFxuICBcIl9yZXF1aXJlZEJ5XCI6IFtcbiAgICBcIi9AYW50di9jb21wb25lbnRcIixcbiAgICBcIi9AYW50di9nLWNhbnZhc1wiLFxuICAgIFwiL0BhbnR2L2ctc3ZnXCIsXG4gICAgXCIvQGFudHYvZzJcIixcbiAgICBcIi9AYW50di9nMnBsb3RcIlxuICBdLFxuICBcIl9yZXNvbHZlZFwiOiBcImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL0BhbnR2L2ctYmFzZS8tL2ctYmFzZS0wLjQuNy50Z3pcIixcbiAgXCJfc3BlY1wiOiBcIjAuNC43XCIsXG4gIFwiX3doZXJlXCI6IFwiQzpcXFxceGFtcHBcXFxcaHRkb2NzXFxcXGljZWhybVxcXFx3ZWJcIixcbiAgXCJhdXRob3JcIjoge1xuICAgIFwibmFtZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9vcmdzL2FudHZpcy9wZW9wbGVcIlxuICB9LFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy91dGlsL2lzc3Vlc1wiXG4gIH0sXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcIkBhbnR2L2V2ZW50LWVtaXR0ZXJcIjogXCJeMC4xLjFcIixcbiAgICBcIkBhbnR2L2ctbWF0aFwiOiBcIl4wLjEuM1wiLFxuICAgIFwiQGFudHYvbWF0cml4LXV0aWxcIjogXCJeMy4xLjAtYmV0YS4xXCIsXG4gICAgXCJAYW50di9wYXRoLXV0aWxcIjogXCJ+Mi4wLjVcIixcbiAgICBcIkBhbnR2L3V0aWxcIjogXCJ+Mi4wLjBcIixcbiAgICBcIkB0eXBlcy9kMy10aW1lclwiOiBcIl4xLjAuOVwiLFxuICAgIFwiZDMtZWFzZVwiOiBcIl4xLjAuNVwiLFxuICAgIFwiZDMtaW50ZXJwb2xhdGVcIjogXCJeMS4zLjJcIixcbiAgICBcImQzLXRpbWVyXCI6IFwiXjEuMC45XCIsXG4gICAgXCJkZXRlY3QtYnJvd3NlclwiOiBcIl41LjEuMFwiXG4gIH0sXG4gIFwiZGVzY3JpcHRpb25cIjogXCJBIGNvbW1vbiB1dGlsIGNvbGxlY3Rpb24gZm9yIGFudHYgcHJvamVjdHNcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGFudHYvdG9yY2hcIjogXCJeMS4wLjBcIixcbiAgICBcImdsLW1hdHJpeFwiOiBcIl4zLjAuMFwiLFxuICAgIFwibGVzc1wiOiBcIl4zLjkuMFwiLFxuICAgIFwibnBtLXJ1bi1hbGxcIjogXCJeNC4xLjVcIixcbiAgICBcInRzYy13YXRjaFwiOiBcIl40LjAuMFwiXG4gIH0sXG4gIFwiZmlsZXNcIjogW1xuICAgIFwicGFja2FnZS5qc29uXCIsXG4gICAgXCJlc21cIixcbiAgICBcImxpYlwiLFxuICAgIFwiTElDRU5TRVwiLFxuICAgIFwiUkVBRE1FLm1kXCJcbiAgXSxcbiAgXCJnaXRIZWFkXCI6IFwiZWI2YTI1MDNjYjdiYjgxNTQ2OTc1OTJiMTA2ODA5MzlkOTU0YTMxYVwiLFxuICBcImhvbWVwYWdlXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy91dGlsI3JlYWRtZVwiLFxuICBcImtleXdvcmRzXCI6IFtcbiAgICBcInV0aWxcIixcbiAgICBcImFudHZcIixcbiAgICBcImdcIlxuICBdLFxuICBcImxpY2Vuc2VcIjogXCJJU0NcIixcbiAgXCJtYWluXCI6IFwibGliL2luZGV4LmpzXCIsXG4gIFwibW9kdWxlXCI6IFwiZXNtL2luZGV4LmpzXCIsXG4gIFwibmFtZVwiOiBcIkBhbnR2L2ctYmFzZVwiLFxuICBcInB1Ymxpc2hDb25maWdcIjoge1xuICAgIFwiYWNjZXNzXCI6IFwicHVibGljXCJcbiAgfSxcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImdpdCtodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL3V0aWwuZ2l0XCJcbiAgfSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcImJ1aWxkXCI6IFwibnBtIHJ1biBjbGVhbiAmJiBydW4tcCBidWlsZDoqXCIsXG4gICAgXCJidWlsZDpjanNcIjogXCJ0c2MgLXAgdHNjb25maWcuanNvbiAtLXRhcmdldCBFUzUgLS1tb2R1bGUgY29tbW9uanMgLS1vdXREaXIgbGliXCIsXG4gICAgXCJidWlsZDplc21cIjogXCJ0c2MgLXAgdHNjb25maWcuanNvbiAtLXRhcmdldCBFUzUgLS1tb2R1bGUgRVNOZXh0IC0tb3V0RGlyIGVzbVwiLFxuICAgIFwiY2xlYW5cIjogXCJybSAtcmYgZXNtIGxpYlwiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJucG0gcnVuIGNvdmVyYWdlLWdlbmVyYXRvciAmJiBucG0gcnVuIGNvdmVyYWdlLXZpZXdlclwiLFxuICAgIFwiY292ZXJhZ2UtZ2VuZXJhdG9yXCI6IFwidG9yY2ggLS1jb3ZlcmFnZSAtLWNvbXBpbGUgLS1zb3VyY2UtcGF0dGVybiBzcmMvKi5qcyxzcmMvKiovKi5qcyAtLW9wdHMgdGVzdHMvbW9jaGEub3B0c1wiLFxuICAgIFwiY292ZXJhZ2Utdmlld2VyXCI6IFwidG9yY2gtY292ZXJhZ2VcIixcbiAgICBcInRlc3RcIjogXCJ0b3JjaCAtLXJlbmRlcmVyIC0tY29tcGlsZSAtLW9wdHMgdGVzdHMvbW9jaGEub3B0c1wiLFxuICAgIFwidGVzdC1saXZlXCI6IFwidG9yY2ggLS1jb21waWxlIC0taW50ZXJhY3RpdmUgLS1vcHRzIHRlc3RzL21vY2hhLm9wdHNcIixcbiAgICBcInRzY1wiOiBcInRzYyAtLW5vRW1pdFwiLFxuICAgIFwidHlwZWNoZWNrXCI6IFwidHNjIC0tbm9FbWl0XCIsXG4gICAgXCJ3YXRjaDpjanNcIjogXCJ0c2Mtd2F0Y2ggLXAgdHNjb25maWcuanNvbiAtLXRhcmdldCBFUzUgLS1tb2R1bGUgY29tbW9uanMgLS1vdXREaXIgbGliIC0tY29tcGlsZXIgdHlwZXNjcmlwdC9iaW4vdHNjXCJcbiAgfSxcbiAgXCJ0eXBlc1wiOiBcImxpYi9pbmRleC5kLnRzXCIsXG4gIFwidmVyc2lvblwiOiBcIjAuNC43XCJcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ19iYXNlXzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlXCIpO1xudmFyIGhpdF8xID0gcmVxdWlyZShcIi4vdXRpbC9oaXRcIik7XG52YXIgU2hhcGUgPSByZXF1aXJlKFwiLi9zaGFwZVwiKTtcbnZhciBncm91cF8xID0gcmVxdWlyZShcIi4vZ3JvdXBcIik7XG52YXIgZHJhd18xID0gcmVxdWlyZShcIi4vdXRpbC9kcmF3XCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWwvdXRpbFwiKTtcbnZhciBDYW52YXMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2FudmFzLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENhbnZhcygpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBDYW52YXMucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgLy8g6K6+572u5riy5p+T5byV5pOO5Li6IGNhbnZhc++8jOWPquivu+WxnuaAp1xuICAgICAgICBjZmdbJ3JlbmRlcmVyJ10gPSAnY2FudmFzJztcbiAgICAgICAgLy8g5piv5ZCm6Ieq5Yqo57uY5Yi277yM5LiN6ZyA6KaB55So5oi36LCD55SoIGRyYXcg5pa55rOVXG4gICAgICAgIGNmZ1snYXV0b0RyYXcnXSA9IHRydWU7XG4gICAgICAgIC8vIOaYr+WQpuWFgeiuuOWxgOmDqOWIt+aWsOWbvuihqFxuICAgICAgICBjZmdbJ2xvY2FsUmVmcmVzaCddID0gdHJ1ZTtcbiAgICAgICAgY2ZnWydyZWZyZXNoRWxlbWVudHMnXSA9IFtdO1xuICAgICAgICAvLyDmmK/lkKblnKjop4blm77lhoXoh6rliqjoo4HliapcbiAgICAgICAgY2ZnWydjbGlwVmlldyddID0gdHJ1ZTtcbiAgICAgICAgY2ZnWydxdWlja0hpdCddID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBjZmc7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDkuIDkupvmlrnms5XosIPnlKjkvJrlvJXotbfnlLvluIPlj5jljJZcbiAgICAgKiBAcGFyYW0ge0NoYW5nZVR5cGV9IGNoYW5nZVR5cGUg5pS55Y+Y55qE57G75Z6LXG4gICAgICovXG4gICAgQ2FudmFzLnByb3RvdHlwZS5vbkNhbnZhc0NoYW5nZSA9IGZ1bmN0aW9uIChjaGFuZ2VUeXBlKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDop6blj5HnlLvluIPmm7TmlrDnmoTkuInnp40gY2hhbmdlVHlwZVxuICAgICAgICAgKiAxLiBhdHRyOiDkv67mlLnnlLvluIPnmoTnu5jlm77lsZ7mgKdcbiAgICAgICAgICogMi4gc29ydDog55S75biD5o6S5bqP77yM5Zu+5b2i55qE5bGC5qyh5Lya5Y+R55Sf5Y+Y5YyWXG4gICAgICAgICAqIDMuIGNoYW5nZVNpemU6IOaUueWPmOeUu+W4g+Wkp+Wwj1xuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGNoYW5nZVR5cGUgPT09ICdhdHRyJyB8fCBjaGFuZ2VUeXBlID09PSAnc29ydCcgfHwgY2hhbmdlVHlwZSA9PT0gJ2NoYW5nZVNpemUnKSB7XG4gICAgICAgICAgICB0aGlzLnNldCgncmVmcmVzaEVsZW1lbnRzJywgW3RoaXNdKTtcbiAgICAgICAgICAgIHRoaXMuZHJhdygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDYW52YXMucHJvdG90eXBlLmdldFNoYXBlQmFzZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFNoYXBlO1xuICAgIH07XG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRHcm91cEJhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBncm91cF8xLmRlZmF1bHQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blsY/luZXlg4/ntKDmr5RcbiAgICAgKi9cbiAgICBDYW52YXMucHJvdG90eXBlLmdldFBpeGVsUmF0aW8gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwaXhlbFJhdGlvID0gdGhpcy5nZXQoJ3BpeGVsUmF0aW8nKSB8fCB1dGlsXzEuZ2V0UGl4ZWxSYXRpbygpO1xuICAgICAgICAvLyDkuI3otrMgMSDnmoTlj5YgMe+8jOi2heWHuiAxIOeahOWPluaVtFxuICAgICAgICByZXR1cm4gcGl4ZWxSYXRpbyA+PSAxID8gTWF0aC5jZWlsKHBpeGVsUmF0aW8pIDogMTtcbiAgICB9O1xuICAgIENhbnZhcy5wcm90b3R5cGUuZ2V0Vmlld1JhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluWDogMCxcbiAgICAgICAgICAgIG1pblk6IDAsXG4gICAgICAgICAgICBtYXhYOiB0aGlzLmdldCgnd2lkdGgnKSxcbiAgICAgICAgICAgIG1heFk6IHRoaXMuZ2V0KCdoZWlnaHQnKSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8vIOWkjeWGmeWfuuexu+eahOaWueazleeUn+aIkOagh+etvlxuICAgIENhbnZhcy5wcm90b3R5cGUuY3JlYXRlRG9tID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICB2YXIgY29udGV4dCA9IGVsZW1lbnQuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgLy8g57yT5a2YIGNvbnRleHQg5a+56LGhXG4gICAgICAgIHRoaXMuc2V0KCdjb250ZXh0JywgY29udGV4dCk7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH07XG4gICAgQ2FudmFzLnByb3RvdHlwZS5zZXRET01TaXplID0gZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5zZXRET01TaXplLmNhbGwodGhpcywgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5nZXQoJ2NvbnRleHQnKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHZhciBwaXhlbFJhdGlvID0gdGhpcy5nZXRQaXhlbFJhdGlvKCk7XG4gICAgICAgIGVsLndpZHRoID0gcGl4ZWxSYXRpbyAqIHdpZHRoO1xuICAgICAgICBlbC5oZWlnaHQgPSBwaXhlbFJhdGlvICogaGVpZ2h0O1xuICAgICAgICAvLyDorr7nva4gY2FudmFzIOWFg+e0oOeahOWuveW6puWSjOmrmOW6pu+8jOS8mumHjee9rue8qeaUvu+8jOWboOatpCBjb250ZXh0LnNjYWxlIOmcgOimgeWcqOavj+asoeiuvue9ruWuveOAgemrmOWQjuiwg+eUqFxuICAgICAgICBpZiAocGl4ZWxSYXRpbyA+IDEpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc2NhbGUocGl4ZWxSYXRpbywgcGl4ZWxSYXRpbyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOWkjeWGmeWfuuexu+aWueazlVxuICAgIENhbnZhcy5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY2xlYXIuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5fY2xlYXJGcmFtZSgpOyAvLyDpnIDopoHmuIXnkIbmjonlu7bov5/nu5jliLbnmoTluKdcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmdldCgnY29udGV4dCcpO1xuICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICBjb250ZXh0LmNsZWFyUmVjdCgwLCAwLCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCk7XG4gICAgfTtcbiAgICBDYW52YXMucHJvdG90eXBlLmdldFNoYXBlID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdxdWlja0hpdCcpKSB7XG4gICAgICAgICAgICByZXR1cm4gaGl0XzEuZ2V0U2hhcGUodGhpcywgeCwgeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZ2V0U2hhcGUuY2FsbCh0aGlzLCB4LCB5LCBudWxsKTtcbiAgICB9O1xuICAgIC8vIOWvuee7mOWItuWMuuWfn+i+uee8mOWPluaVtO+8jOmBv+WFjea1rueCueaVsOmXrumimFxuICAgIENhbnZhcy5wcm90b3R5cGUuX2dldFJlZnJlc2hSZWdpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMuZ2V0KCdyZWZyZXNoRWxlbWVudHMnKTtcbiAgICAgICAgdmFyIHZpZXdSZWdpb24gPSB0aGlzLmdldFZpZXdSYW5nZSgpO1xuICAgICAgICB2YXIgcmVnaW9uO1xuICAgICAgICAvLyDlpoLmnpzmmK/lvZPliY3nlLvluIPmlbTkvZPlj5HnlJ/kuoblj5jljJbvvIzliJnnm7TmjqXph43nu5jmlbTkuKrnlLvluINcbiAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCAmJiBlbGVtZW50c1swXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgcmVnaW9uID0gdmlld1JlZ2lvbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlZ2lvbiA9IGRyYXdfMS5nZXRNZXJnZWRSZWdpb24oZWxlbWVudHMpO1xuICAgICAgICAgICAgaWYgKHJlZ2lvbikge1xuICAgICAgICAgICAgICAgIHJlZ2lvbi5taW5YID0gTWF0aC5mbG9vcihyZWdpb24ubWluWCk7XG4gICAgICAgICAgICAgICAgcmVnaW9uLm1pblkgPSBNYXRoLmZsb29yKHJlZ2lvbi5taW5ZKTtcbiAgICAgICAgICAgICAgICByZWdpb24ubWF4WCA9IE1hdGguY2VpbChyZWdpb24ubWF4WCk7XG4gICAgICAgICAgICAgICAgcmVnaW9uLm1heFkgPSBNYXRoLmNlaWwocmVnaW9uLm1heFkpO1xuICAgICAgICAgICAgICAgIHZhciBjbGlwVmlldyA9IHRoaXMuZ2V0KCdjbGlwVmlldycpO1xuICAgICAgICAgICAgICAgIC8vIOiHquWKqOijgeWJquS4jeWcqCB2aWV3IOWGheeahOWMuuWfn1xuICAgICAgICAgICAgICAgIGlmIChjbGlwVmlldykge1xuICAgICAgICAgICAgICAgICAgICByZWdpb24gPSBkcmF3XzEubWVyZ2VWaWV3KHJlZ2lvbiwgdmlld1JlZ2lvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWdpb247XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliLfmlrDlm77lvaLlhYPntKDvvIzov5nph4zku4Xku4XmmK/mlL7lhaXpmJ/liJfvvIzkuIvmrKHnu5jliLbml7bov5vooYznu5jliLZcbiAgICAgKiBAcGFyYW0ge0lFbGVtZW50fSBlbGVtZW50IOWbvuW9ouWFg+e0oFxuICAgICAqL1xuICAgIENhbnZhcy5wcm90b3R5cGUucmVmcmVzaEVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgcmVmcmVzaEVsZW1lbnRzID0gdGhpcy5nZXQoJ3JlZnJlc2hFbGVtZW50cycpO1xuICAgICAgICByZWZyZXNoRWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgLy8gaWYgKHRoaXMuZ2V0KCdhdXRvRHJhdycpKSB7XG4gICAgICAgIC8vICAgdGhpcy5fc3RhcnREcmF3KCk7XG4gICAgICAgIC8vIH1cbiAgICB9O1xuICAgIC8vIOa4heeQhui/mOWcqOi/m+ihjOeahOe7mOWItlxuICAgIENhbnZhcy5wcm90b3R5cGUuX2NsZWFyRnJhbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkcmF3RnJhbWUgPSB0aGlzLmdldCgnZHJhd0ZyYW1lJyk7XG4gICAgICAgIGlmIChkcmF3RnJhbWUpIHtcbiAgICAgICAgICAgIC8vIOWmguaenOWFqOmDqOa4suafk+aXtu+8jOWtmOWcqOWxgOmDqOa4suafk++8jOWImeaKm+W8g+aOieWxgOmDqOa4suafk1xuICAgICAgICAgICAgdXRpbF8xLmNsZWFyQW5pbWF0aW9uRnJhbWUoZHJhd0ZyYW1lKTtcbiAgICAgICAgICAgIHRoaXMuc2V0KCdkcmF3RnJhbWUnLCBudWxsKTtcbiAgICAgICAgICAgIHRoaXMuc2V0KCdyZWZyZXNoRWxlbWVudHMnLCBbXSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOaJi+W3peiwg+eUqOe7mOWItuaOpeWPo1xuICAgIENhbnZhcy5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRyYXdGcmFtZSA9IHRoaXMuZ2V0KCdkcmF3RnJhbWUnKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdhdXRvRHJhdycpICYmIGRyYXdGcmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N0YXJ0RHJhdygpO1xuICAgIH07XG4gICAgLy8g57uY5Yi25omA5pyJ5Zu+5b2iXG4gICAgQ2FudmFzLnByb3RvdHlwZS5fZHJhd0FsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmdldCgnY29udGV4dCcpO1xuICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmdldENoaWxkcmVuKCk7XG4gICAgICAgIGNvbnRleHQuY2xlYXJSZWN0KDAsIDAsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0KTtcbiAgICAgICAgZHJhd18xLmFwcGx5QXR0cnNUb0NvbnRleHQoY29udGV4dCwgdGhpcyk7XG4gICAgICAgIGRyYXdfMS5kcmF3Q2hpbGRyZW4oY29udGV4dCwgY2hpbGRyZW4pO1xuICAgICAgICAvLyDlr7nkuo4gaHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy9nL2lzc3Vlcy80MjIg55qE5Zy65pmv77yM5YWo5bGA5riy5p+T55qE5qih5byP5LiL5Lmf5Lya6K6w5b2V5pu05paw55qE5YWD57Sg6Zif5YiX77yM5Zug5q2k5YWo5bGA5riy5p+T5a6M5ZCO5Lmf6ZyA6KaB572u56m6XG4gICAgICAgIHRoaXMuc2V0KCdyZWZyZXNoRWxlbWVudHMnLCBbXSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLblsYDpg6hcbiAgICBDYW52YXMucHJvdG90eXBlLl9kcmF3UmVnaW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGV4dCA9IHRoaXMuZ2V0KCdjb250ZXh0Jyk7XG4gICAgICAgIHZhciByZWZyZXNoRWxlbWVudHMgPSB0aGlzLmdldCgncmVmcmVzaEVsZW1lbnRzJyk7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgdmFyIHJlZ2lvbiA9IHRoaXMuX2dldFJlZnJlc2hSZWdpb24oKTtcbiAgICAgICAgLy8g6ZyA6KaB5rOo5oSP5Y+v6IO95rKh5pyJIHJlZ2lvbiDnmoTlnLrmma9cbiAgICAgICAgLy8g5LiA6Iis5Y+R55Sf5Zyo6K6+572u5LqGIGxvY2FsUmVmcmVzaCAs5Zyo5rKh5pyJ5Zu+5b2i5Y+R55Sf5Y+Y5YyW55qE5oOF5Ya15LiL77yM55So5oi36LCD55So5LqGIGRyYXdcbiAgICAgICAgaWYgKHJlZ2lvbikge1xuICAgICAgICAgICAgLy8g5riF55CG5oyH5a6a5Yy65Z+fXG4gICAgICAgICAgICBjb250ZXh0LmNsZWFyUmVjdChyZWdpb24ubWluWCwgcmVnaW9uLm1pblksIHJlZ2lvbi5tYXhYIC0gcmVnaW9uLm1pblgsIHJlZ2lvbi5tYXhZIC0gcmVnaW9uLm1pblkpO1xuICAgICAgICAgICAgLy8g5L+d5a2Y5LiK5LiL5paH77yM6K6+572uIGNsaXBcbiAgICAgICAgICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVjdChyZWdpb24ubWluWCwgcmVnaW9uLm1pblksIHJlZ2lvbi5tYXhYIC0gcmVnaW9uLm1pblgsIHJlZ2lvbi5tYXhZIC0gcmVnaW9uLm1pblkpO1xuICAgICAgICAgICAgY29udGV4dC5jbGlwKCk7XG4gICAgICAgICAgICBkcmF3XzEuYXBwbHlBdHRyc1RvQ29udGV4dChjb250ZXh0LCB0aGlzKTtcbiAgICAgICAgICAgIC8vIOe7mOWItuWtkOWFg+e0oFxuICAgICAgICAgICAgZHJhd18xLmRyYXdDaGlsZHJlbihjb250ZXh0LCBjaGlsZHJlbiwgcmVnaW9uKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgICAgIHV0aWxfMS5lYWNoKHJlZnJlc2hFbGVtZW50cywgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmdldCgnaGFzQ2hhbmdlZCcpKSB7XG4gICAgICAgICAgICAgICAgLy8g5Zyo6KeG56qX5aSW55qEIEdyb3VwIOWFg+e0oOS8muWKoOWFpeWIsOabtOaWsOmYn+WIl+mHjO+8jOS9huWunumZheWNtOayoeacieaJp+ihjCBkcmF3KCkg6YC76L6R77yM5Lmf5bCx5rKh5pyJ5riF6ZmkIGhhc0NoYW5nZWQg5qCH6K6wXG4gICAgICAgICAgICAgICAgLy8g5Y2z5bey57uP6YeN57uY5a6M44CB5L2GIGhhc0NoYW5nZWQg5qCH6K6w5rKh5pyJ5riF6Zmk55qE5YWD57Sg77yM6ZyA6KaB57uf5LiA5riF6Zmk5o6J44CC5Li76KaB5pivIEdyb3VwIOWtmOWcqOmXrumimO+8jOWFt+S9k+WOn+WboOW+heaOkuafpVxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0KCdoYXNDaGFuZ2VkJywgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXQoJ3JlZnJlc2hFbGVtZW50cycsIFtdKTtcbiAgICB9O1xuICAgIC8vIOinpuWPkee7mOWItlxuICAgIENhbnZhcy5wcm90b3R5cGUuX3N0YXJ0RHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGRyYXdGcmFtZSA9IHRoaXMuZ2V0KCdkcmF3RnJhbWUnKTtcbiAgICAgICAgaWYgKCFkcmF3RnJhbWUpIHtcbiAgICAgICAgICAgIGRyYXdGcmFtZSA9IHV0aWxfMS5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5nZXQoJ2xvY2FsUmVmcmVzaCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9kcmF3UmVnaW9uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5fZHJhd0FsbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfdGhpcy5zZXQoJ2RyYXdGcmFtZScsIG51bGwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNldCgnZHJhd0ZyYW1lJywgZHJhd0ZyYW1lKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ2FudmFzLnByb3RvdHlwZS5za2lwRHJhdyA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICByZXR1cm4gQ2FudmFzO1xufShnX2Jhc2VfMS5BYnN0cmFjdENhbnZhcykpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2FudmFzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2FudmFzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ19iYXNlXzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlXCIpO1xudmFyIFNoYXBlID0gcmVxdWlyZShcIi4vc2hhcGVcIik7XG52YXIgZHJhd18xID0gcmVxdWlyZShcIi4vdXRpbC9kcmF3XCIpO1xudmFyIEdyb3VwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEdyb3VwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyb3VwKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOS4gOS6m+aWueazleiwg+eUqOS8muW8lei1t+eUu+W4g+WPmOWMllxuICAgICAqIEBwYXJhbSB7Q2hhbmdlVHlwZX0gY2hhbmdlVHlwZSDmlLnlj5jnmoTnsbvlnotcbiAgICAgKi9cbiAgICBHcm91cC5wcm90b3R5cGUub25DYW52YXNDaGFuZ2UgPSBmdW5jdGlvbiAoY2hhbmdlVHlwZSkge1xuICAgICAgICBkcmF3XzEucmVmcmVzaEVsZW1lbnQodGhpcywgY2hhbmdlVHlwZSk7XG4gICAgfTtcbiAgICBHcm91cC5wcm90b3R5cGUuZ2V0U2hhcGVCYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gU2hhcGU7XG4gICAgfTtcbiAgICBHcm91cC5wcm90b3R5cGUuZ2V0R3JvdXBCYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gR3JvdXA7XG4gICAgfTtcbiAgICAvLyDlkIwgc2hhcGUg5Lit55qE5pa55rOV6YeN5aSN5LqGXG4gICAgR3JvdXAucHJvdG90eXBlLl9hcHBseUNsaXAgPSBmdW5jdGlvbiAoY29udGV4dCwgY2xpcCkge1xuICAgICAgICBpZiAoY2xpcCkge1xuICAgICAgICAgICAgY29udGV4dC5zYXZlKCk7XG4gICAgICAgICAgICAvLyDlsIYgY2xpcCDnmoTlsZ7mgKfmjILovb3liLAgY29udGV4dCDkuIpcbiAgICAgICAgICAgIGRyYXdfMS5hcHBseUF0dHJzVG9Db250ZXh0KGNvbnRleHQsIGNsaXApO1xuICAgICAgICAgICAgLy8g57uY5Yi2IGNsaXAg6Lev5b6EXG4gICAgICAgICAgICBjbGlwLmNyZWF0ZVBhdGgoY29udGV4dCk7XG4gICAgICAgICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgIC8vIOijgeWJqlxuICAgICAgICAgICAgY29udGV4dC5jbGlwKCk7XG4gICAgICAgICAgICBjbGlwLl9hZnRlckRyYXcoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgR3JvdXAucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiAoY29udGV4dCwgcmVnaW9uKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgY29udGV4dC5zYXZlKCk7XG4gICAgICAgICAgICAvLyBncm91cCDkuIrnmoTnn6npmLXlkozlsZ7mgKfkuZ/kvJrlupTnlKjliLDkuIrkuIvmlofkuIpcbiAgICAgICAgICAgIC8vIOWFiOWwhiBhdHRycyDlupTnlKjliLDkuIrkuIvmlofkuK3vvIzlho3orr7nva4gY2xpcOOAguWboOS4uiBjbGlwIOW6lOivpeiiq+W9k+WJjeWFg+e0oOeahCBtYXRyaXgg5omA5b2x5ZONXG4gICAgICAgICAgICBkcmF3XzEuYXBwbHlBdHRyc1RvQ29udGV4dChjb250ZXh0LCB0aGlzKTtcbiAgICAgICAgICAgIHRoaXMuX2FwcGx5Q2xpcChjb250ZXh0LCB0aGlzLmdldENsaXAoKSk7XG4gICAgICAgICAgICBkcmF3XzEuZHJhd0NoaWxkcmVuKGNvbnRleHQsIGNoaWxkcmVuLCByZWdpb24pO1xuICAgICAgICAgICAgY29udGV4dC5yZXN0b3JlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6L+Z6YeM55qE5oiQ5pys5q+U6L6D5aSnXG4gICAgICAgIHRoaXMuc2V0KCdjYWNoZUNhbnZhc0JCb3gnLCB0aGlzLmdldENhbnZhc0JCb3goKSk7XG4gICAgICAgIC8vIOe7mOWItuWQju+8jOa2iOmZpOabtOaWsOagh+iusFxuICAgICAgICB0aGlzLnNldCgnaGFzQ2hhbmdlZCcsIGZhbHNlKTtcbiAgICB9O1xuICAgIC8vIOe7mOWItuaXtuiiq+i3s+i/h++8jOS4gOiIrOWPkeeUn+WcqOWIhue7hOmakOiXj+aXtlxuICAgIEdyb3VwLnByb3RvdHlwZS5za2lwRHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXQoJ2NhY2hlQ2FudmFzQkJveCcsIG51bGwpO1xuICAgICAgICB0aGlzLnNldCgnaGFzQ2hhbmdlZCcsIGZhbHNlKTtcbiAgICB9O1xuICAgIHJldHVybiBHcm91cDtcbn0oZ19iYXNlXzEuQWJzdHJhY3RHcm91cCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JvdXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncm91cC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuU2hhcGUgPSBleHBvcnRzLnZlcnNpb24gPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBTaGFwZSA9IHJlcXVpcmUoXCIuL3NoYXBlXCIpO1xuZXhwb3J0cy5TaGFwZSA9IFNoYXBlO1xudmFyIHBrZyA9IHJlcXVpcmUoJy4uL3BhY2thZ2UuanNvbicpO1xuZXhwb3J0cy52ZXJzaW9uID0gcGtnLnZlcnNpb247XG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiLi90eXBlc1wiKSwgZXhwb3J0cyk7XG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiLi9pbnRlcmZhY2VzXCIpLCBleHBvcnRzKTtcbnZhciBnX2Jhc2VfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZ19iYXNlXzEuRXZlbnQ7IH0gfSk7XG52YXIgY2FudmFzXzEgPSByZXF1aXJlKFwiLi9jYW52YXNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDYW52YXNcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNhbnZhc18xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZ3JvdXBfMSA9IHJlcXVpcmUoXCIuL2dyb3VwXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiR3JvdXBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdyb3VwXzEuZGVmYXVsdDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vLyDlr7zlh7ogZy1iYXNlIOS4reeahCBpbnRlcmZhY2VzXG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiQGFudHYvZy1iYXNlL2xpYi9pbnRlcmZhY2VzXCIpLCBleHBvcnRzKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludGVyZmFjZXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBnX2Jhc2VfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2VcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBkcmF3XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9kcmF3XCIpO1xudmFyIGluZGV4XzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlL2xpYi9iYm94L2luZGV4XCIpO1xudmFyIFNoYXBlID0gcmVxdWlyZShcIi4vaW5kZXhcIik7XG52YXIgZ3JvdXBfMSA9IHJlcXVpcmUoXCIuLi9ncm91cFwiKTtcbnZhciBTaGFwZUJhc2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2hhcGVCYXNlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNoYXBlQmFzZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmdldERlZmF1bHRBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMuY2FsbCh0aGlzKTtcbiAgICAgICAgLy8g6K6+572u6buY6K6k5YC8XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSwgeyBsaW5lV2lkdGg6IDEsIGxpbmVBcHBlbmRXaWR0aDogMCwgc3Ryb2tlT3BhY2l0eTogMSwgZmlsbE9wYWNpdHk6IDEgfSk7XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmdldFNoYXBlQmFzZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFNoYXBlO1xuICAgIH07XG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5nZXRHcm91cEJhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBncm91cF8xLmRlZmF1bHQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDkuIDkupvmlrnms5XosIPnlKjkvJrlvJXotbfnlLvluIPlj5jljJZcbiAgICAgKiBAcGFyYW0ge0NoYW5nZVR5cGV9IGNoYW5nZVR5cGUg5pS55Y+Y55qE57G75Z6LXG4gICAgICovXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5vbkNhbnZhc0NoYW5nZSA9IGZ1bmN0aW9uIChjaGFuZ2VUeXBlKSB7XG4gICAgICAgIGRyYXdfMS5yZWZyZXNoRWxlbWVudCh0aGlzLCBjaGFuZ2VUeXBlKTtcbiAgICB9O1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuY2FsY3VsYXRlQkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0aGlzLmdldCgndHlwZScpO1xuICAgICAgICB2YXIgbGluZVdpZHRoID0gdGhpcy5nZXRIaXRMaW5lV2lkdGgoKTtcbiAgICAgICAgLy8gY29uc3QgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGJib3hNZXRob2QgPSBpbmRleF8xLmdldEJCb3hNZXRob2QodHlwZSk7XG4gICAgICAgIHZhciBib3ggPSBiYm94TWV0aG9kKHRoaXMpO1xuICAgICAgICB2YXIgaGFsZkxpbmVXaWR0aCA9IGxpbmVXaWR0aCAvIDI7XG4gICAgICAgIHZhciBtaW5YID0gYm94LnggLSBoYWxmTGluZVdpZHRoO1xuICAgICAgICB2YXIgbWluWSA9IGJveC55IC0gaGFsZkxpbmVXaWR0aDtcbiAgICAgICAgdmFyIG1heFggPSBib3gueCArIGJveC53aWR0aCArIGhhbGZMaW5lV2lkdGg7XG4gICAgICAgIHZhciBtYXhZID0gYm94LnkgKyBib3guaGVpZ2h0ICsgaGFsZkxpbmVXaWR0aDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IG1pblgsXG4gICAgICAgICAgICBtaW5YOiBtaW5YLFxuICAgICAgICAgICAgeTogbWluWSxcbiAgICAgICAgICAgIG1pblk6IG1pblksXG4gICAgICAgICAgICB3aWR0aDogYm94LndpZHRoICsgbGluZVdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBib3guaGVpZ2h0ICsgbGluZVdpZHRoLFxuICAgICAgICAgICAgbWF4WDogbWF4WCxcbiAgICAgICAgICAgIG1heFk6IG1heFksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmlzRmlsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5hdHRyc1snZmlsbCddIHx8IHRoaXMuaXNDbGlwU2hhcGUoKTtcbiAgICB9O1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuaXNTdHJva2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuYXR0cnNbJ3N0cm9rZSddO1xuICAgIH07XG4gICAgLy8g5ZCMIHNoYXBlIOS4reeahOaWueazlemHjeWkjeS6hlxuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuX2FwcGx5Q2xpcCA9IGZ1bmN0aW9uIChjb250ZXh0LCBjbGlwKSB7XG4gICAgICAgIGlmIChjbGlwKSB7XG4gICAgICAgICAgICBjb250ZXh0LnNhdmUoKTtcbiAgICAgICAgICAgIC8vIOWwhiBjbGlwIOeahOWxnuaAp+aMgui9veWIsCBjb250ZXh0IOS4ilxuICAgICAgICAgICAgZHJhd18xLmFwcGx5QXR0cnNUb0NvbnRleHQoY29udGV4dCwgY2xpcCk7XG4gICAgICAgICAgICAvLyDnu5jliLYgY2xpcCDot6/lvoRcbiAgICAgICAgICAgIGNsaXAuY3JlYXRlUGF0aChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgICAgICAgICAgLy8g6KOB5YmqXG4gICAgICAgICAgICBjb250ZXh0LmNsaXAoKTtcbiAgICAgICAgICAgIGNsaXAuX2FmdGVyRHJhdygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDnu5jliLblm77lvaLml7bpnIDopoHogIPomZEgcmVnaW9uIOmZkOWItlxuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uIChjb250ZXh0LCByZWdpb24pIHtcbiAgICAgICAgdmFyIGNsaXAgPSB0aGlzLmdldENsaXAoKTtcbiAgICAgICAgLy8g5aaC5p6c5oyH5a6a5LqG5Yy65Z+f77yM5b2T5LiO5oyH5a6a5Yy65Z+f55u45Lqk5pe277yM5omN5Lya6Kem5Y+R5riy5p+TXG4gICAgICAgIGlmIChyZWdpb24pIHtcbiAgICAgICAgICAgIC8vIOaYr+WQpuebuOS6pOmcgOimgeiAg+iZkSBjbGlwIOeahOWMheWbtOebklxuICAgICAgICAgICAgdmFyIGJib3ggPSBjbGlwID8gZHJhd18xLmdldE1lcmdlZFJlZ2lvbihbdGhpcywgY2xpcF0pIDogdGhpcy5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgICAgICBpZiAoIXV0aWxfMS5pbnRlcnNlY3RSZWN0KHJlZ2lvbiwgYmJveCkpIHtcbiAgICAgICAgICAgICAgICAvLyDlm77lvaLnmoTljIXlm7Tnm5LkuI7ph43nu5jljLrln5/kuI3nm7jkuqTml7bvvIzkuZ/pnIDopoHmuIXpmaTmoIforrBcbiAgICAgICAgICAgICAgICB0aGlzLnNldCgnaGFzQ2hhbmdlZCcsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC5zYXZlKCk7XG4gICAgICAgIC8vIOWFiOWwhiBhdHRycyDlupTnlKjliLDkuIrkuIvmlofkuK3vvIzlho3orr7nva4gY2xpcOOAguWboOS4uiBjbGlwIOW6lOivpeiiq+W9k+WJjeWFg+e0oOeahCBtYXRyaXgg5omA5b2x5ZONXG4gICAgICAgIGRyYXdfMS5hcHBseUF0dHJzVG9Db250ZXh0KGNvbnRleHQsIHRoaXMpO1xuICAgICAgICB0aGlzLl9hcHBseUNsaXAoY29udGV4dCwgdGhpcy5nZXRDbGlwKCkpO1xuICAgICAgICB0aGlzLmRyYXdQYXRoKGNvbnRleHQpO1xuICAgICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICAgICAgdGhpcy5fYWZ0ZXJEcmF3KCk7XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLl9hZnRlckRyYXcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBiYm94ID0gdGhpcy5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmdldENhbnZhcygpO1xuICAgICAgICAvLyDnu5jliLbnmoTml7blgJnnvJPlrZjljIXlm7Tnm5JcbiAgICAgICAgdGhpcy5zZXQoJ2NhY2hlQ2FudmFzQkJveCcsIGJib3gpO1xuICAgICAgICBpZiAoY2FudmFzKSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB2YXIgdmlld1JhbmdlID0gY2FudmFzLmdldFZpZXdSYW5nZSgpO1xuICAgICAgICAgICAgdGhpcy5zZXQoJ2lzSW5WaWV3JywgdXRpbF8xLmludGVyc2VjdFJlY3QoYmJveCwgdmlld1JhbmdlKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g57uY5Yi25ZCO5raI6Zmk5qCH6K6wXG4gICAgICAgIHRoaXMuc2V0KCdoYXNDaGFuZ2VkJywgZmFsc2UpO1xuICAgIH07XG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5za2lwRHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXQoJ2NhY2hlQ2FudmFzQkJveCcsIG51bGwpO1xuICAgICAgICB0aGlzLnNldCgnaXNJblZpZXcnLCBudWxsKTtcbiAgICAgICAgdGhpcy5zZXQoJ2hhc0NoYW5nZWQnLCBmYWxzZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnu5jliLblm77lvaLnmoTot6/lvoRcbiAgICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCDkuIrkuIvmlodcbiAgICAgKi9cbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmRyYXdQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVQYXRoKGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0cm9rZUFuZEZpbGwoY29udGV4dCk7XG4gICAgICAgIHRoaXMuYWZ0ZXJEcmF3UGF0aChjb250ZXh0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiDloavlhYXlm77lvaJcbiAgICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBjb250ZXh0IOS4iuS4i+aWh1xuICAgICAqL1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOe7mOWItuWbvuW9oui+ueahhlxuICAgICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IGNvbnRleHQg5LiK5LiL5paHXG4gICAgICovXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5zdHJva2UgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgIH07XG4gICAgLy8g57uY5Yi25oiW6ICF5aGr5YWFXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5zdHJva2VBbmRGaWxsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRycywgbGluZVdpZHRoID0gX2EubGluZVdpZHRoLCBvcGFjaXR5ID0gX2Eub3BhY2l0eSwgc3Ryb2tlT3BhY2l0eSA9IF9hLnN0cm9rZU9wYWNpdHksIGZpbGxPcGFjaXR5ID0gX2EuZmlsbE9wYWNpdHk7XG4gICAgICAgIGlmICh0aGlzLmlzRmlsbCgpKSB7XG4gICAgICAgICAgICBpZiAoIXV0aWxfMS5pc05pbChmaWxsT3BhY2l0eSkgJiYgZmlsbE9wYWNpdHkgIT09IDEpIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0Lmdsb2JhbEFscGhhID0gZmlsbE9wYWNpdHk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWxsKGNvbnRleHQpO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZ2xvYmFsQWxwaGEgPSBvcGFjaXR5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWxsKGNvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzU3Ryb2tlKCkpIHtcbiAgICAgICAgICAgIGlmIChsaW5lV2lkdGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoc3Ryb2tlT3BhY2l0eSkgJiYgc3Ryb2tlT3BhY2l0eSAhPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0Lmdsb2JhbEFscGhhID0gc3Ryb2tlT3BhY2l0eTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJva2UoY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZnRlckRyYXdQYXRoKGNvbnRleHQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIOe7mOWItuWbvuW9oueahOi3r+W+hFxuICAgICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IOS4iuS4i+aWh1xuICAgICAqL1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7IH07XG4gICAgLyoqXG4gICAgICog57uY5Yi25a6M5oiQIHBhdGgg5ZCO55qE5pON5L2cXG4gICAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQg5LiK5LiL5paHXG4gICAgICovXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5hZnRlckRyYXdQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQpIHsgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmlzSW5TaGFwZSA9IGZ1bmN0aW9uIChyZWZYLCByZWZZKSB7XG4gICAgICAgIC8vIHJldHVybiBIaXRVdGlsLmlzSGl0U2hhcGUodGhpcywgcmVmWCwgcmVmWSk7XG4gICAgICAgIHZhciBpc1N0cm9rZSA9IHRoaXMuaXNTdHJva2UoKTtcbiAgICAgICAgdmFyIGlzRmlsbCA9IHRoaXMuaXNGaWxsKCk7XG4gICAgICAgIHZhciBsaW5lV2lkdGggPSB0aGlzLmdldEhpdExpbmVXaWR0aCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5pc0luU3Ryb2tlT3JQYXRoKHJlZlgsIHJlZlksIGlzU3Ryb2tlLCBpc0ZpbGwsIGxpbmVXaWR0aCk7XG4gICAgfTtcbiAgICAvLyDkuYvmiYDku6XkuI3mi4bmiJAgaXNJblN0cm9rZSDlkowgaXNJblBhdGgg5Zyo5LqO5Lik6ICF5a2Y5Zyo5LiA5Lqb5YWx5ZCM55qE6K6h566XXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5pc0luU3Ryb2tlT3JQYXRoID0gZnVuY3Rpb24gKHgsIHksIGlzU3Ryb2tlLCBpc0ZpbGwsIGxpbmVXaWR0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bnur/mi77lj5bnmoTlrr3luqZcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSDnur/nmoTmi77lj5blrr3luqZcbiAgICAgKi9cbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmdldEhpdExpbmVXaWR0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzU3Ryb2tlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cnM7XG4gICAgICAgIHJldHVybiBhdHRyc1snbGluZVdpZHRoJ10gKyBhdHRyc1snbGluZUFwcGVuZFdpZHRoJ107XG4gICAgfTtcbiAgICByZXR1cm4gU2hhcGVCYXNlO1xufShnX2Jhc2VfMS5BYnN0cmFjdFNoYXBlKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTaGFwZUJhc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOWchlxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbi8vIFRPRE86IOaaguaXtuS4jemcgOimgeWchueahOW3peWFt+aWueazle+8jOWQjue7reWmguaenOmcgOimgeaUr+aMgSBwb2ludEF077yMdGFuZ2VudEFuZ2xlIOaXtuWGjeW8leWFpVxuLy8gaW1wb3J0IENpcmNsZVV0aWwgZnJvbSAnQGFudHYvZy1tYXRoL2xpYi9jaXJjbGUnO1xudmFyIENpcmNsZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhDaXJjbGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ2lyY2xlKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIENpcmNsZS5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgcjogMCB9KTtcbiAgICB9O1xuICAgIENpcmNsZS5wcm90b3R5cGUuaXNJblN0cm9rZU9yUGF0aCA9IGZ1bmN0aW9uICh4LCB5LCBpc1N0cm9rZSwgaXNGaWxsLCBsaW5lV2lkdGgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBjeCA9IGF0dHJzLng7XG4gICAgICAgIHZhciBjeSA9IGF0dHJzLnk7XG4gICAgICAgIHZhciByID0gYXR0cnMucjtcbiAgICAgICAgdmFyIGhhbGZMaW5lV2lkdGggPSBsaW5lV2lkdGggLyAyO1xuICAgICAgICB2YXIgYWJzRGlzdGFuY2UgPSB1dGlsXzEuZGlzdGFuY2UoY3gsIGN5LCB4LCB5KTtcbiAgICAgICAgLy8g55u05o6l55So6Led56a777yM5aaC5p6c5ZCM5pe25a2Y5Zyo6L655ZKM5aGr5YWF5pe277yM5Y+v5Lul5YeP5bCR5Lik5qyh6K6h566XXG4gICAgICAgIGlmIChpc0ZpbGwgJiYgaXNTdHJva2UpIHtcbiAgICAgICAgICAgIHJldHVybiBhYnNEaXN0YW5jZSA8PSByICsgaGFsZkxpbmVXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNGaWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYWJzRGlzdGFuY2UgPD0gcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNTdHJva2UpIHtcbiAgICAgICAgICAgIHJldHVybiBhYnNEaXN0YW5jZSA+PSByIC0gaGFsZkxpbmVXaWR0aCAmJiBhYnNEaXN0YW5jZSA8PSByICsgaGFsZkxpbmVXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBDaXJjbGUucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGN4ID0gYXR0cnMueDtcbiAgICAgICAgdmFyIGN5ID0gYXR0cnMueTtcbiAgICAgICAgdmFyIHIgPSBhdHRycy5yO1xuICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgICBjb250ZXh0LmFyYyhjeCwgY3ksIHIsIDAsIE1hdGguUEkgKiAyLCBmYWxzZSk7XG4gICAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfTtcbiAgICByZXR1cm4gQ2lyY2xlO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2lyY2xlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2lyY2xlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOakreWchlxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG4vLyDmmoLml7bkuI3pnIDopoFcbi8vIGltcG9ydCBFbGxpcHNlVXRpbCBmcm9tICdAYW50di9nLW1hdGgvbGliL2VsbGlwc2UnO1xuLy8g5qC55o2u5qSt5ZyG5YWs5byP6K6h566XIHgqeC9yeCpyeCArIHkqeS9yeSpyeTtcbmZ1bmN0aW9uIGVsbGlwc2VEaXN0YW5jZShzcXVhcmVYLCBzcXVhcmVZLCByeCwgcnkpIHtcbiAgICByZXR1cm4gc3F1YXJlWCAvIChyeCAqIHJ4KSArIHNxdWFyZVkgLyAocnkgKiByeSk7XG59XG52YXIgRWxsaXBzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGxpcHNlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEVsbGlwc2UoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgRWxsaXBzZS5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgcng6IDAsIHJ5OiAwIH0pO1xuICAgIH07XG4gICAgRWxsaXBzZS5wcm90b3R5cGUuaXNJblN0cm9rZU9yUGF0aCA9IGZ1bmN0aW9uICh4LCB5LCBpc1N0cm9rZSwgaXNGaWxsLCBsaW5lV2lkdGgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBoYWxmTGluZVdpdGggPSBsaW5lV2lkdGggLyAyO1xuICAgICAgICB2YXIgY3ggPSBhdHRycy54O1xuICAgICAgICB2YXIgY3kgPSBhdHRycy55O1xuICAgICAgICB2YXIgcnggPSBhdHRycy5yeCwgcnkgPSBhdHRycy5yeTtcbiAgICAgICAgdmFyIHNxdWFyZVggPSAoeCAtIGN4KSAqICh4IC0gY3gpO1xuICAgICAgICB2YXIgc3F1YXJlWSA9ICh5IC0gY3kpICogKHkgLSBjeSk7XG4gICAgICAgIC8vIOS9v+eUqOakreWchueahOWFrOW8j++8miB4KngvcngqcnggKyB5KnkvcnkqcnkgPSAxO1xuICAgICAgICBpZiAoaXNGaWxsICYmIGlzU3Ryb2tlKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxsaXBzZURpc3RhbmNlKHNxdWFyZVgsIHNxdWFyZVksIHJ4ICsgaGFsZkxpbmVXaXRoLCByeSArIGhhbGZMaW5lV2l0aCkgPD0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNGaWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxsaXBzZURpc3RhbmNlKHNxdWFyZVgsIHNxdWFyZVksIHJ4LCByeSkgPD0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNTdHJva2UpIHtcbiAgICAgICAgICAgIHJldHVybiAoZWxsaXBzZURpc3RhbmNlKHNxdWFyZVgsIHNxdWFyZVksIHJ4IC0gaGFsZkxpbmVXaXRoLCByeSAtIGhhbGZMaW5lV2l0aCkgPj0gMSAmJlxuICAgICAgICAgICAgICAgIGVsbGlwc2VEaXN0YW5jZShzcXVhcmVYLCBzcXVhcmVZLCByeCArIGhhbGZMaW5lV2l0aCwgcnkgKyBoYWxmTGluZVdpdGgpIDw9IDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEVsbGlwc2UucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGN4ID0gYXR0cnMueDtcbiAgICAgICAgdmFyIGN5ID0gYXR0cnMueTtcbiAgICAgICAgdmFyIHJ4ID0gYXR0cnMucng7XG4gICAgICAgIHZhciByeSA9IGF0dHJzLnJ5O1xuICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgICAvLyDlhbzlrrnpgLvovpFcbiAgICAgICAgaWYgKGNvbnRleHQuZWxsaXBzZSkge1xuICAgICAgICAgICAgY29udGV4dC5lbGxpcHNlKGN4LCBjeSwgcngsIHJ5LCAwLCAwLCBNYXRoLlBJICogMiwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5aaC5p6c5LiN5pSv5oyB77yM5YiZ5L2/55So5ZyG5p2l57uY5Yi277yM6L+b6KGM5Y+Y5b2iXG4gICAgICAgICAgICB2YXIgciA9IHJ4ID4gcnkgPyByeCA6IHJ5O1xuICAgICAgICAgICAgdmFyIHNjYWxlWCA9IHJ4ID4gcnkgPyAxIDogcnggLyByeTtcbiAgICAgICAgICAgIHZhciBzY2FsZVkgPSByeCA+IHJ5ID8gcnkgLyByeCA6IDE7XG4gICAgICAgICAgICBjb250ZXh0LnNhdmUoKTtcbiAgICAgICAgICAgIGNvbnRleHQudHJhbnNsYXRlKGN4LCBjeSk7XG4gICAgICAgICAgICBjb250ZXh0LnNjYWxlKHNjYWxlWCwgc2NhbGVZKTtcbiAgICAgICAgICAgIGNvbnRleHQuYXJjKDAsIDAsIHIsIDAsIE1hdGguUEkgKiAyKTtcbiAgICAgICAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgICAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIEVsbGlwc2U7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGxpcHNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxsaXBzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyDlm77niYdcbiAqIEBhdXRob3IgZHhxNjEzQGdtYWlsLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG5mdW5jdGlvbiBpc0NhbnZhcyhkb20pIHtcbiAgICByZXR1cm4gZG9tIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgJiYgdXRpbF8xLmlzU3RyaW5nKGRvbS5ub2RlTmFtZSkgJiYgZG9tLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdDQU5WQVMnO1xufVxudmFyIEltYWdlU2hhcGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSW1hZ2VTaGFwZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBJbWFnZVNoYXBlKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEltYWdlU2hhcGUucHJvdG90eXBlLmdldERlZmF1bHRBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgYXR0cnMpLCB7IHg6IDAsIHk6IDAsIHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSk7XG4gICAgfTtcbiAgICBJbWFnZVNoYXBlLnByb3RvdHlwZS5pbml0QXR0cnMgPSBmdW5jdGlvbiAoYXR0cnMpIHtcbiAgICAgICAgdGhpcy5fc2V0SW1hZ2UoYXR0cnMuaW1nKTtcbiAgICB9O1xuICAgIC8vIGltYWdlIOS4jeiuoeeulyBzdHJva2VcbiAgICBJbWFnZVNoYXBlLnByb3RvdHlwZS5pc1N0cm9rZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgLy8g5LuF5LuF5L2/55So5YyF5Zu055uS5qOA5rWL5p2l6L+b6KGM5ou+5Y+WXG4gICAgLy8g5omA5Lul5LiN6ZyA6KaB5aSN5YaZIGlzSW5TdHJva2VPclBhdGgg55qE5pa55rOVXG4gICAgSW1hZ2VTaGFwZS5wcm90b3R5cGUuaXNPbmx5SGl0Qm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICAgIEltYWdlU2hhcGUucHJvdG90eXBlLl9hZnRlckxvYWRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmdldCgndG9EcmF3JykgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHZhciBjYW52YXMgPSB0aGlzLmdldCgnY2FudmFzJyk7XG4gICAgICAgICAgICBpZiAoY2FudmFzKSB7XG4gICAgICAgICAgICAgICAgLy8g6L+Z5q615bqU6K+l5pS55oiQ5bGA6YOo5riy5p+TXG4gICAgICAgICAgICAgICAgY2FudmFzLmRyYXcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOi/meenjeaWueW8j+WmguaenOWPkeeUn+mBruaMoeS8muWHuueOsOmXrumimFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlUGF0aCh0aGlzLmdldCgnY29udGV4dCcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgSW1hZ2VTaGFwZS5wcm90b3R5cGUuX3NldEltYWdlID0gZnVuY3Rpb24gKGltZykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHJzO1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGltZykpIHtcbiAgICAgICAgICAgIHZhciBpbWFnZV8xID0gbmV3IEltYWdlKCk7XG4gICAgICAgICAgICBpbWFnZV8xLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAvLyDlm77niYfmnKrliqDovb3lrozvvIzliJnlt7Lnu4/ooqvplIDmr4FcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g57yT5a2Y5Y6f5aeL5Zyw5Z2A77yM5Y+v5Lul5YGa5a+55q+U77yM6Ziy5q2i6YeN5aSN5Yqg6L295Zu+54mHXG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c6ICD6JmR5Yiw5Zyo5Yqg6L296L+H56iL5Lit5Y+v6IO95pu/5o2iIGltZyDlsZ7mgKfvvIzliJnmg4XlhrXmm7TliqDlpI3mnYJcbiAgICAgICAgICAgICAgICAvLyB0aGlzLnNldCgnaW1nU3JjJywgaW1nKTtcbiAgICAgICAgICAgICAgICAvLyDov5nph4zkvJrlvqrnjq/osIPnlKggX3NldEltYWdlIOaWueazle+8jOS9huS4jeS8muWGjei1sOi/meS4quWIhuaUr1xuICAgICAgICAgICAgICAgIF90aGlzLmF0dHIoJ2ltZycsIGltYWdlXzEpO1xuICAgICAgICAgICAgICAgIF90aGlzLnNldCgnbG9hZGluZycsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5fYWZ0ZXJMb2FkaW5nKCk7XG4gICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gX3RoaXMuZ2V0KCdjYWxsYmFjaycpO1xuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKF90aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaW1hZ2VfMS5zcmMgPSBpbWc7XG4gICAgICAgICAgICAvLyDorr7nva7ot6jln59cbiAgICAgICAgICAgIGltYWdlXzEuY3Jvc3NPcmlnaW4gPSAnQW5vbnltb3VzJztcbiAgICAgICAgICAgIC8vIGxvYWRpbmcg6L+H56iL5Lit5LiN57uY5Yi2XG4gICAgICAgICAgICB0aGlzLnNldCgnbG9hZGluZycsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGltZyBpbnN0YW5jZW9mIEltYWdlKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzmmK/kuIDkuKogaW1hZ2Ug5a+56LGh77yM5YiZ6K6+572u5a696auYXG4gICAgICAgICAgICBpZiAoIWF0dHJzLndpZHRoKSB7XG4gICAgICAgICAgICAgICAgYXR0cnMud2lkdGggPSBpbWcud2lkdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWF0dHJzLmhlaWdodCkge1xuICAgICAgICAgICAgICAgIGF0dHJzLmhlaWdodCA9IGltZy5oZWlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNDYW52YXMoaW1nKSkge1xuICAgICAgICAgICAgLy8g5aaC5p6c6K6+572u5LqGIGNhbnZhcyDlr7nosaFcbiAgICAgICAgICAgIGlmICghYXR0cnMud2lkdGgpIHtcbiAgICAgICAgICAgICAgICBhdHRycy53aWR0aCA9IE51bWJlcihpbWcuZ2V0QXR0cmlidXRlKCd3aWR0aCcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghYXR0cnMuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgYXR0cnMuaGVpZ2h0LCBOdW1iZXIoaW1nLmdldEF0dHJpYnV0ZSgnaGVpZ2h0JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBJbWFnZVNoYXBlLnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIG9yaWdpblZhbHVlKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25BdHRyQ2hhbmdlLmNhbGwodGhpcywgbmFtZSwgdmFsdWUsIG9yaWdpblZhbHVlKTtcbiAgICAgICAgLy8g5aaC5p6c5Yqg6L2955qE5bey57uP5piv5b2T5YmN5Zu+54mH77yM5YiZ5LiN5YaN5aSE55CGXG4gICAgICAgIGlmIChuYW1lID09PSAnaW1nJykge1xuICAgICAgICAgICAgLy8g5Y+v5Lul5Yqg57yT5Yay77yMJiYgdGhpcy5nZXQoJ2ltZ1NyYycpICE9PSB2YWx1ZVxuICAgICAgICAgICAgdGhpcy5fc2V0SW1hZ2UodmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBJbWFnZVNoYXBlLnByb3RvdHlwZS5jcmVhdGVQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgLy8g5q2j5Zyo5Yqg6L295YiZ5LiN57uY5Yi2XG4gICAgICAgIGlmICh0aGlzLmdldCgnbG9hZGluZycpKSB7XG4gICAgICAgICAgICB0aGlzLnNldCgndG9EcmF3JywgdHJ1ZSk7IC8vIOWKoOi9veWujOaIkOWQjue7mOWItlxuICAgICAgICAgICAgdGhpcy5zZXQoJ2NvbnRleHQnLCBjb250ZXh0KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIHggPSBhdHRycy54LCB5ID0gYXR0cnMueSwgd2lkdGggPSBhdHRycy53aWR0aCwgaGVpZ2h0ID0gYXR0cnMuaGVpZ2h0LCBzeCA9IGF0dHJzLnN4LCBzeSA9IGF0dHJzLnN5LCBzd2lkdGggPSBhdHRycy5zd2lkdGgsIHNoZWlnaHQgPSBhdHRycy5zaGVpZ2h0O1xuICAgICAgICB2YXIgaW1nID0gYXR0cnMuaW1nO1xuICAgICAgICBpZiAoaW1nIGluc3RhbmNlb2YgSW1hZ2UgfHwgaXNDYW52YXMoaW1nKSkge1xuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoc3gpICYmICF1dGlsXzEuaXNOaWwoc3kpICYmICF1dGlsXzEuaXNOaWwoc3dpZHRoKSAmJiAhdXRpbF8xLmlzTmlsKHNoZWlnaHQpKSB7XG4gICAgICAgICAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UoaW1nLCBzeCwgc3ksIHN3aWR0aCwgc2hlaWdodCwgeCwgeSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmRyYXdJbWFnZShpbWcsIHgsIHksIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gSW1hZ2VTaGFwZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEltYWdlU2hhcGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbWFnZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQmFzZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYmFzZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgY2lyY2xlXzEgPSByZXF1aXJlKFwiLi9jaXJjbGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDaXJjbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNpcmNsZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZWxsaXBzZV8xID0gcmVxdWlyZShcIi4vZWxsaXBzZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVsbGlwc2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGVsbGlwc2VfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGltYWdlXzEgPSByZXF1aXJlKFwiLi9pbWFnZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkltYWdlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbWFnZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIi4vbGluZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxpbmVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxpbmVfMS5kZWZhdWx0OyB9IH0pO1xudmFyIG1hcmtlcl8xID0gcmVxdWlyZShcIi4vbWFya2VyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWFya2VyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBtYXJrZXJfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHBhdGhfMSA9IHJlcXVpcmUoXCIuL3BhdGhcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJQYXRoXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBwYXRoXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBwb2x5Z29uXzEgPSByZXF1aXJlKFwiLi9wb2x5Z29uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUG9seWdvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcG9seWdvbl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcG9seWxpbmVfMSA9IHJlcXVpcmUoXCIuL3BvbHlsaW5lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUG9seWxpbmVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHBvbHlsaW5lXzEuZGVmYXVsdDsgfSB9KTtcbnZhciByZWN0XzEgPSByZXF1aXJlKFwiLi9yZWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUmVjdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVjdF8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgdGV4dF8xID0gcmVxdWlyZShcIi4vdGV4dFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRleHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRleHRfMS5kZWZhdWx0OyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQGZpbGVvdmVydmlldyDlnIZcbiAqIEBhdXRob3IgZHhxNjEzQGdtYWlsLmNvbVxuICovXG52YXIgbGluZV8xID0gcmVxdWlyZShcIkBhbnR2L2ctbWF0aC9saWIvbGluZVwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIGxpbmVfMiA9IHJlcXVpcmUoXCIuLi91dGlsL2luLXN0cm9rZS9saW5lXCIpO1xudmFyIEFycm93VXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL2Fycm93XCIpO1xudmFyIExpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTGluZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaW5lKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIExpbmUucHJvdG90eXBlLmdldERlZmF1bHRBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgYXR0cnMpLCB7IHgxOiAwLCB5MTogMCwgeDI6IDAsIHkyOiAwLCBzdGFydEFycm93OiBmYWxzZSwgZW5kQXJyb3c6IGZhbHNlIH0pO1xuICAgIH07XG4gICAgTGluZS5wcm90b3R5cGUuaW5pdEF0dHJzID0gZnVuY3Rpb24gKGF0dHJzKSB7XG4gICAgICAgIHRoaXMuc2V0QXJyb3coKTtcbiAgICB9O1xuICAgIC8vIOabtOaWsOWxnuaAp+aXtu+8jOajgOa1i+aYr+WQpuabtOaUueS6hueureWktFxuICAgIExpbmUucHJvdG90eXBlLm9uQXR0ckNoYW5nZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UuY2FsbCh0aGlzLCBuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpO1xuICAgICAgICAvLyDnlLHkuo7nrq3lpLTnmoTnu5jliLbkvp3otZbkuo4gbGluZSDnmoTor7jlpJogYXR0cnPvvIzlm6DmraTov5nph4zkuI3lho3lr7nmr4/kuKogYXR0ciDov5vooYzliKTmlq3vvIxhdHRyIOavj+asoeWPmOWMlumDveS8muW9seWTjeeureWktOeahOabtOaWsFxuICAgICAgICB0aGlzLnNldEFycm93KCk7XG4gICAgfTtcbiAgICBMaW5lLnByb3RvdHlwZS5zZXRBcnJvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciB4MSA9IGF0dHJzLngxLCB5MSA9IGF0dHJzLnkxLCB4MiA9IGF0dHJzLngyLCB5MiA9IGF0dHJzLnkyLCBzdGFydEFycm93ID0gYXR0cnMuc3RhcnRBcnJvdywgZW5kQXJyb3cgPSBhdHRycy5lbmRBcnJvdztcbiAgICAgICAgaWYgKHN0YXJ0QXJyb3cpIHtcbiAgICAgICAgICAgIEFycm93VXRpbC5hZGRTdGFydEFycm93KHRoaXMsIGF0dHJzLCB4MiwgeTIsIHgxLCB5MSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZEFycm93KSB7XG4gICAgICAgICAgICBBcnJvd1V0aWwuYWRkRW5kQXJyb3codGhpcywgYXR0cnMsIHgxLCB5MSwgeDIsIHkyKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTGluZS5wcm90b3R5cGUuaXNJblN0cm9rZU9yUGF0aCA9IGZ1bmN0aW9uICh4LCB5LCBpc1N0cm9rZSwgaXNGaWxsLCBsaW5lV2lkdGgpIHtcbiAgICAgICAgaWYgKCFpc1N0cm9rZSB8fCAhbGluZVdpZHRoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRyKCksIHgxID0gX2EueDEsIHkxID0gX2EueTEsIHgyID0gX2EueDIsIHkyID0gX2EueTI7XG4gICAgICAgIHJldHVybiBsaW5lXzIuZGVmYXVsdCh4MSwgeTEsIHgyLCB5MiwgbGluZVdpZHRoLCB4LCB5KTtcbiAgICB9O1xuICAgIExpbmUucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIHgxID0gYXR0cnMueDEsIHkxID0gYXR0cnMueTEsIHgyID0gYXR0cnMueDIsIHkyID0gYXR0cnMueTIsIHN0YXJ0QXJyb3cgPSBhdHRycy5zdGFydEFycm93LCBlbmRBcnJvdyA9IGF0dHJzLmVuZEFycm93O1xuICAgICAgICB2YXIgc3RhcnRBcnJvd0Rpc3RhbmNlID0ge1xuICAgICAgICAgICAgZHg6IDAsXG4gICAgICAgICAgICBkeTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGVuZEFycm93RGlzdGFuY2UgPSB7XG4gICAgICAgICAgICBkeDogMCxcbiAgICAgICAgICAgIGR5OiAwLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoc3RhcnRBcnJvdyAmJiBzdGFydEFycm93LmQpIHtcbiAgICAgICAgICAgIHN0YXJ0QXJyb3dEaXN0YW5jZSA9IEFycm93VXRpbC5nZXRTaG9ydGVuT2Zmc2V0KHgxLCB5MSwgeDIsIHkyLCBhdHRycy5zdGFydEFycm93LmQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbmRBcnJvdyAmJiBlbmRBcnJvdy5kKSB7XG4gICAgICAgICAgICBlbmRBcnJvd0Rpc3RhbmNlID0gQXJyb3dVdGlsLmdldFNob3J0ZW5PZmZzZXQoeDEsIHkxLCB4MiwgeTIsIGF0dHJzLmVuZEFycm93LmQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICAgIC8vIOWmguaenOiHquWumuS5ieeureWktO+8jOe6v+adoeebuOW6lOe8qei/m1xuICAgICAgICBjb250ZXh0Lm1vdmVUbyh4MSArIHN0YXJ0QXJyb3dEaXN0YW5jZS5keCwgeTEgKyBzdGFydEFycm93RGlzdGFuY2UuZHkpO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyh4MiAtIGVuZEFycm93RGlzdGFuY2UuZHgsIHkyIC0gZW5kQXJyb3dEaXN0YW5jZS5keSk7XG4gICAgfTtcbiAgICBMaW5lLnByb3RvdHlwZS5hZnRlckRyYXdQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgdmFyIHN0YXJ0QXJyb3dTaGFwZSA9IHRoaXMuZ2V0KCdzdGFydEFycm93U2hhcGUnKTtcbiAgICAgICAgdmFyIGVuZEFycm93U2hhcGUgPSB0aGlzLmdldCgnZW5kQXJyb3dTaGFwZScpO1xuICAgICAgICBpZiAoc3RhcnRBcnJvd1NoYXBlKSB7XG4gICAgICAgICAgICBzdGFydEFycm93U2hhcGUuZHJhdyhjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW5kQXJyb3dTaGFwZSkge1xuICAgICAgICAgICAgZW5kQXJyb3dTaGFwZS5kcmF3KGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBHZXQgbGVuZ3RoIG9mIGxpbmVcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IGxlbmd0aFxuICAgICAqL1xuICAgIExpbmUucHJvdG90eXBlLmdldFRvdGFsTGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmF0dHIoKSwgeDEgPSBfYS54MSwgeTEgPSBfYS55MSwgeDIgPSBfYS54MiwgeTIgPSBfYS55MjtcbiAgICAgICAgcmV0dXJuIGxpbmVfMS5kZWZhdWx0Lmxlbmd0aCh4MSwgeTEsIHgyLCB5Mik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBHZXQgcG9pbnQgYWNjb3JkaW5nIHRvIHJhdGlvXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJhdGlvXG4gICAgICogQHJldHVybiB7UG9pbnR9IHBvaW50XG4gICAgICovXG4gICAgTGluZS5wcm90b3R5cGUuZ2V0UG9pbnQgPSBmdW5jdGlvbiAocmF0aW8pIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRyKCksIHgxID0gX2EueDEsIHkxID0gX2EueTEsIHgyID0gX2EueDIsIHkyID0gX2EueTI7XG4gICAgICAgIHJldHVybiBsaW5lXzEuZGVmYXVsdC5wb2ludEF0KHgxLCB5MSwgeDIsIHkyLCByYXRpbyk7XG4gICAgfTtcbiAgICByZXR1cm4gTGluZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IE1hcmtlclxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBhdGhfMl9hYnNvbHV0ZV8xID0gcmVxdWlyZShcIkBhbnR2L3BhdGgtdXRpbC9saWIvcGF0aC0yLWFic29sdXRlXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciBkcmF3XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9kcmF3XCIpO1xudmFyIFN5bWJvbHMgPSB7XG4gICAgLy8g5ZyGXG4gICAgY2lyY2xlOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgWydNJywgeCAtIHIsIHldLFxuICAgICAgICAgICAgWydBJywgciwgciwgMCwgMSwgMCwgeCArIHIsIHldLFxuICAgICAgICAgICAgWydBJywgciwgciwgMCwgMSwgMCwgeCAtIHIsIHldLFxuICAgICAgICBdO1xuICAgIH0sXG4gICAgLy8g5q2j5pa55b2iXG4gICAgc3F1YXJlOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICByZXR1cm4gW1snTScsIHggLSByLCB5IC0gcl0sIFsnTCcsIHggKyByLCB5IC0gcl0sIFsnTCcsIHggKyByLCB5ICsgcl0sIFsnTCcsIHggLSByLCB5ICsgcl0sIFsnWiddXTtcbiAgICB9LFxuICAgIC8vIOiPseW9olxuICAgIGRpYW1vbmQ6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbWydNJywgeCAtIHIsIHldLCBbJ0wnLCB4LCB5IC0gcl0sIFsnTCcsIHggKyByLCB5XSwgWydMJywgeCwgeSArIHJdLCBbJ1onXV07XG4gICAgfSxcbiAgICAvLyDkuInop5LlvaJcbiAgICB0cmlhbmdsZTogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgdmFyIGRpZmZZID0gciAqIE1hdGguc2luKCgxIC8gMykgKiBNYXRoLlBJKTtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSArIGRpZmZZXSwgWydMJywgeCwgeSAtIGRpZmZZXSwgWydMJywgeCArIHIsIHkgKyBkaWZmWV0sIFsnWiddXTtcbiAgICB9LFxuICAgIC8vIOWAkuS4ieinkuW9olxuICAgICd0cmlhbmdsZS1kb3duJzogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgdmFyIGRpZmZZID0gciAqIE1hdGguc2luKCgxIC8gMykgKiBNYXRoLlBJKTtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSAtIGRpZmZZXSwgWydMJywgeCArIHIsIHkgLSBkaWZmWV0sIFsnTCcsIHgsIHkgKyBkaWZmWV0sIFsnWiddXTtcbiAgICB9LFxufTtcbnZhciBNYXJrZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTWFya2VyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIE1hcmtlcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBNYXJrZXIucHJvdG90eXBlLmluaXRBdHRycyA9IGZ1bmN0aW9uIChhdHRycykge1xuICAgICAgICB0aGlzLl9yZXNldFBhcmFtc0NhY2hlKCk7XG4gICAgfTtcbiAgICAvLyDph43nva7nu5jliLYgcGF0aCDlrZjlgqjnmoTnvJPlrZhcbiAgICBNYXJrZXIucHJvdG90eXBlLl9yZXNldFBhcmFtc0NhY2hlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDkuLrkuobliqDpgJ8gcGF0aCDnmoTnu5jliLbjgIHmi77lj5blkozorqHnrpfvvIzov5nkuKrlnLDmlrnlj6/ku6XnvJPlrZjlvojlpJrkuJzopb9cbiAgICAgICAgLy8g6L+Z5Lqb57yT5a2Y6YO95piv56ys5LiA5qyh6ZyA6KaB5pe26K6h566X5ZKM5a2Y5YKo77yM6Jm954S25aKe5Yqg5LqG5aSN5p2C5bqm77yM5L2G5piv6aKR57mB6LCD55So55qE5pa55rOV77yM5oCn6IO95pyJ5b6I5aSn5o+Q5Y2HXG4gICAgICAgIHRoaXMuc2V0KCdwYXJhbXNDYWNoZScsIHt9KTsgLy8g5riF55CG57yT5a2YXG4gICAgfTtcbiAgICAvLyDmm7TmlrDlsZ7mgKfml7bvvIzmo4DmtYvmmK/lkKbmm7TmlLnkuoYgcGF0aFxuICAgIE1hcmtlci5wcm90b3R5cGUub25BdHRyQ2hhbmdlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCBvcmlnaW5WYWx1ZSkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLm9uQXR0ckNoYW5nZS5jYWxsKHRoaXMsIG5hbWUsIHZhbHVlLCBvcmlnaW5WYWx1ZSk7XG4gICAgICAgIGlmIChbJ3N5bWJvbCcsICd4JywgJ3knLCAncicsICdyYWRpdXMnXS5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gcGF0aCDnm7jlhbPlsZ7mgKfmm7TmlLnml7bvvIzmuIXnkIbnvJPlrZhcbiAgICAgICAgICAgIHRoaXMuX3Jlc2V0UGFyYW1zQ2FjaGUoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5LuF5LuF5L2/55So5YyF5Zu055uS5qOA5rWL5p2l6L+b6KGM5ou+5Y+WXG4gICAgLy8g5omA5Lul5LiN6ZyA6KaB5aSN5YaZIGlzSW5TdHJva2VPclBhdGgg55qE5pa55rOVXG4gICAgTWFya2VyLnByb3RvdHlwZS5pc09ubHlIaXRCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgTWFya2VyLnByb3RvdHlwZS5fZ2V0UiA9IGZ1bmN0aW9uIChhdHRycykge1xuICAgICAgICAvLyDlhbzlrrkgciDlkowgcmFkaXVzIOS4pOenjeWGmeazle+8jOaOqOiNkOS9v+eUqCByXG4gICAgICAgIHJldHVybiB1dGlsXzEuaXNOaWwoYXR0cnMucikgPyBhdHRycy5yYWRpdXMgOiBhdHRycy5yO1xuICAgIH07XG4gICAgTWFya2VyLnByb3RvdHlwZS5fZ2V0UGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciB4ID0gYXR0cnMueCwgeSA9IGF0dHJzLnk7XG4gICAgICAgIHZhciBzeW1ib2wgPSBhdHRycy5zeW1ib2wgfHwgJ2NpcmNsZSc7XG4gICAgICAgIHZhciByID0gdGhpcy5fZ2V0UihhdHRycyk7XG4gICAgICAgIHZhciBtZXRob2Q7XG4gICAgICAgIHZhciBwYXRoO1xuICAgICAgICBpZiAodXRpbF8yLmlzRnVuY3Rpb24oc3ltYm9sKSkge1xuICAgICAgICAgICAgbWV0aG9kID0gc3ltYm9sO1xuICAgICAgICAgICAgcGF0aCA9IG1ldGhvZCh4LCB5LCByKTtcbiAgICAgICAgICAgIC8vIOWwhiBwYXRoIOi9rOaIkOe7neWvuei3r+W+hFxuICAgICAgICAgICAgcGF0aCA9IHBhdGhfMl9hYnNvbHV0ZV8xLmRlZmF1bHQocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDlhoXnva4gc3ltYm9sIOeahCBwYXRoIOmDveaYr+e7neWvuei3r+W+hO+8jOebtOaOpee7mOWItuWNs+WPr++8jOS4jemcgOimgeWvuSBwYXRoIOi/m+ihjOeJueauiuWkhOeQhlxuICAgICAgICAgICAgbWV0aG9kID0gTWFya2VyLlN5bWJvbHNbc3ltYm9sXTtcbiAgICAgICAgICAgIHBhdGggPSBtZXRob2QoeCwgeSwgcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtZXRob2QpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihzeW1ib2wgKyBcIiBtYXJrZXIgaXMgbm90IHN1cHBvcnRlZC5cIik7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIE1hcmtlci5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5fZ2V0UGF0aCgpO1xuICAgICAgICB2YXIgcGFyYW1zQ2FjaGUgPSB0aGlzLmdldCgncGFyYW1zQ2FjaGUnKTtcbiAgICAgICAgZHJhd18xLmRyYXdQYXRoKHRoaXMsIGNvbnRleHQsIHsgcGF0aDogcGF0aCB9LCBwYXJhbXNDYWNoZSk7XG4gICAgfTtcbiAgICBNYXJrZXIuU3ltYm9scyA9IFN5bWJvbHM7XG4gICAgcmV0dXJuIE1hcmtlcjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1hcmtlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1hcmtlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGN1YmljXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi9jdWJpY1wiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIHBhdGhfMl9hYnNvbHV0ZV8xID0gcmVxdWlyZShcIkBhbnR2L3BhdGgtdXRpbC9saWIvcGF0aC0yLWFic29sdXRlXCIpO1xudmFyIHBhdGhfMl9zZWdtZW50c18xID0gcmVxdWlyZShcIkBhbnR2L3BhdGgtdXRpbC9saWIvcGF0aC0yLXNlZ21lbnRzXCIpO1xudmFyIGRyYXdfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2RyYXdcIik7XG52YXIgcG9pbnRfaW5fcGF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvaW4tcGF0aC9wb2ludC1pbi1wYXRoXCIpO1xudmFyIHBvbHlnb25fMSA9IHJlcXVpcmUoXCIuLi91dGlsL2luLXBhdGgvcG9seWdvblwiKTtcbnZhciBwYXRoXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9wYXRoXCIpO1xudmFyIEFycm93VXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL2Fycm93XCIpO1xuLy8g5piv5ZCm5Zyo5aSa5Liq5aSa6L655b2i5YaF6YOoXG5mdW5jdGlvbiBpc0luUG9seWdvbnMocG9seWdvbnMsIHgsIHkpIHtcbiAgICB2YXIgaXNIaXQgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvbHlnb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSBwb2x5Z29uc1tpXTtcbiAgICAgICAgaXNIaXQgPSBwb2x5Z29uXzEuZGVmYXVsdChwb2ludHMsIHgsIHkpO1xuICAgICAgICBpZiAoaXNIaXQpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpc0hpdDtcbn1cbnZhciBQYXRoID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBhdGgsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUGF0aCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBQYXRoLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSwgeyBzdGFydEFycm93OiBmYWxzZSwgZW5kQXJyb3c6IGZhbHNlIH0pO1xuICAgIH07XG4gICAgUGF0aC5wcm90b3R5cGUuaW5pdEF0dHJzID0gZnVuY3Rpb24gKGF0dHJzKSB7XG4gICAgICAgIHRoaXMuX3NldFBhdGhBcnIoYXR0cnMucGF0aCk7XG4gICAgICAgIHRoaXMuc2V0QXJyb3coKTtcbiAgICB9O1xuICAgIC8vIOabtOaWsOWxnuaAp+aXtu+8jOajgOa1i+aYr+WQpuabtOaUueS6hiBwYXRoXG4gICAgUGF0aC5wcm90b3R5cGUub25BdHRyQ2hhbmdlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCBvcmlnaW5WYWx1ZSkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLm9uQXR0ckNoYW5nZS5jYWxsKHRoaXMsIG5hbWUsIHZhbHVlLCBvcmlnaW5WYWx1ZSk7XG4gICAgICAgIGlmIChuYW1lID09PSAncGF0aCcpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFBhdGhBcnIodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOeUseS6jueureWktOeahOe7mOWItuS+nei1luS6jiBsaW5lIOeahOivuOWkmiBhdHRyc++8jOWboOatpOi/memHjOS4jeWGjeWvueavj+S4qiBhdHRyIOi/m+ihjOWIpOaWre+8jGF0dHIg5q+P5qyh5Y+Y5YyW6YO95Lya5b2x5ZON566t5aS055qE5pu05pawXG4gICAgICAgIHRoaXMuc2V0QXJyb3coKTtcbiAgICB9O1xuICAgIC8vIOWwhiBwYXRoIOi9rOaNouaIkOe7neWvuei3r+W+hFxuICAgIFBhdGgucHJvdG90eXBlLl9zZXRQYXRoQXJyID0gZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgLy8g6L2s5o2iIHBhdGgg55qE5qC85byPXG4gICAgICAgIHRoaXMuYXR0cnMucGF0aCA9IHBhdGhfMl9hYnNvbHV0ZV8xLmRlZmF1bHQocGF0aCk7XG4gICAgICAgIHZhciBoYXNBcmMgPSBwYXRoXzEuZGVmYXVsdC5oYXNBcmMocGF0aCk7XG4gICAgICAgIC8vIOS4uuS6huWKoOmAnyBwYXRoIOeahOe7mOWItuOAgeaLvuWPluWSjOiuoeeul++8jOi/meS4quWcsOaWueWPr+S7pee8k+WtmOW+iOWkmuS4nOilv1xuICAgICAgICAvLyDov5nkupvnvJPlrZjpg73mmK/nrKzkuIDmrKHpnIDopoHml7borqHnrpflkozlrZjlgqjvvIzomb3nhLblop7liqDkuoblpI3mnYLluqbvvIzkvYbmmK/popHnuYHosIPnlKjnmoTmlrnms5XvvIzmgKfog73mnInlvojlpKfmj5DljYdcbiAgICAgICAgdGhpcy5zZXQoJ2hhc0FyYycsIGhhc0FyYyk7XG4gICAgICAgIHRoaXMuc2V0KCdwYXJhbXNDYWNoZScsIHt9KTsgLy8g5riF55CG57yT5a2YXG4gICAgICAgIHRoaXMuc2V0KCdzZWdtZW50cycsIG51bGwpOyAvLyDlu7bov5/nlJ/miJAgcGF0aO+8jOWcqOWKqOeUu+WcuuaZr+S4i+WPr+iDveS4jeS8muacieaLvuWPllxuICAgICAgICB0aGlzLnNldCgnY3VydmUnLCBudWxsKTtcbiAgICAgICAgdGhpcy5zZXQoJ3RDYWNoZScsIG51bGwpO1xuICAgICAgICB0aGlzLnNldCgndG90YWxMZW5ndGgnLCBudWxsKTtcbiAgICB9O1xuICAgIFBhdGgucHJvdG90eXBlLmdldFNlZ21lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VnbWVudHMgPSB0aGlzLmdldCgnc2VnZW1lbnRzJyk7XG4gICAgICAgIGlmICghc2VnbWVudHMpIHtcbiAgICAgICAgICAgIHNlZ21lbnRzID0gcGF0aF8yX3NlZ21lbnRzXzEuZGVmYXVsdCh0aGlzLmF0dHIoJ3BhdGgnKSk7XG4gICAgICAgICAgICB0aGlzLnNldCgnc2VnbWVudHMnLCBzZWdtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlZ21lbnRzO1xuICAgIH07XG4gICAgUGF0aC5wcm90b3R5cGUuc2V0QXJyb3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgc3RhcnRBcnJvdyA9IGF0dHJzLnN0YXJ0QXJyb3csIGVuZEFycm93ID0gYXR0cnMuZW5kQXJyb3c7XG4gICAgICAgIGlmIChzdGFydEFycm93KSB7XG4gICAgICAgICAgICB2YXIgdGFuZ2VudCA9IHRoaXMuZ2V0U3RhcnRUYW5nZW50KCk7XG4gICAgICAgICAgICBBcnJvd1V0aWwuYWRkU3RhcnRBcnJvdyh0aGlzLCBhdHRycywgdGFuZ2VudFswXVswXSwgdGFuZ2VudFswXVsxXSwgdGFuZ2VudFsxXVswXSwgdGFuZ2VudFsxXVsxXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZEFycm93KSB7XG4gICAgICAgICAgICB2YXIgdGFuZ2VudCA9IHRoaXMuZ2V0RW5kVGFuZ2VudCgpO1xuICAgICAgICAgICAgQXJyb3dVdGlsLmFkZEVuZEFycm93KHRoaXMsIGF0dHJzLCB0YW5nZW50WzBdWzBdLCB0YW5nZW50WzBdWzFdLCB0YW5nZW50WzFdWzBdLCB0YW5nZW50WzFdWzFdKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUGF0aC5wcm90b3R5cGUuaXNJblN0cm9rZU9yUGF0aCA9IGZ1bmN0aW9uICh4LCB5LCBpc1N0cm9rZSwgaXNGaWxsLCBsaW5lV2lkdGgpIHtcbiAgICAgICAgdmFyIHNlZ21lbnRzID0gdGhpcy5nZXRTZWdtZW50cygpO1xuICAgICAgICB2YXIgaGFzQXJjID0gdGhpcy5nZXQoJ2hhc0FyYycpO1xuICAgICAgICB2YXIgaXNIaXQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGlzU3Ryb2tlKSB7XG4gICAgICAgICAgICBpc0hpdCA9IHBhdGhfMS5kZWZhdWx0LmlzUG9pbnRJblN0cm9rZShzZWdtZW50cywgbGluZVdpZHRoLCB4LCB5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzSGl0ICYmIGlzRmlsbCkge1xuICAgICAgICAgICAgaWYgKGhhc0FyYykge1xuICAgICAgICAgICAgICAgIC8vIOWtmOWcqOabsue6v+aXtu+8jOaaguaXtuS9v+eUqCBjYW52YXMg55qEIGFwaSDorqHnrpfvvIzlkI7nu63lj6/ku6Xov5vooYzlpJrovrnlvaLliIflibJcbiAgICAgICAgICAgICAgICBpc0hpdCA9IHBvaW50X2luX3BhdGhfMS5kZWZhdWx0KHRoaXMsIHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHBhdGggPSB0aGlzLmF0dHIoJ3BhdGgnKTtcbiAgICAgICAgICAgICAgICB2YXIgZXh0cmFjdFJlc3V0bCA9IHBhdGhfMS5kZWZhdWx0LmV4dHJhY3RQb2x5Z29ucyhwYXRoKTtcbiAgICAgICAgICAgICAgICAvLyDmj5Dlj5blh7rmnaXnmoTlpJrovrnlvaLljIXlkKvpl63lkIjnmoTlkozpnZ7pl63lkIjnmoTvvIzlnKjov5nph4znu5/kuIDmjInnhaflpJrovrnlvaLlpITnkIZcbiAgICAgICAgICAgICAgICBpc0hpdCA9IGlzSW5Qb2x5Z29ucyhleHRyYWN0UmVzdXRsLnBvbHlnb25zLCB4LCB5KSB8fCBpc0luUG9seWdvbnMoZXh0cmFjdFJlc3V0bC5wb2x5bGluZXMsIHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc0hpdDtcbiAgICB9O1xuICAgIFBhdGgucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIHBhcmFtc0NhY2hlID0gdGhpcy5nZXQoJ3BhcmFtc0NhY2hlJyk7IC8vIOeUseS6juiuoeeul+WchuW8p+eahOWPguaVsOaIkOacrOW+iOWkp++8jOaJgOS7peimgee8k+WtmFxuICAgICAgICBkcmF3XzEuZHJhd1BhdGgodGhpcywgY29udGV4dCwgYXR0cnMsIHBhcmFtc0NhY2hlKTtcbiAgICB9O1xuICAgIFBhdGgucHJvdG90eXBlLmFmdGVyRHJhd1BhdGggPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICB2YXIgc3RhcnRBcnJvd1NoYXBlID0gdGhpcy5nZXQoJ3N0YXJ0QXJyb3dTaGFwZScpO1xuICAgICAgICB2YXIgZW5kQXJyb3dTaGFwZSA9IHRoaXMuZ2V0KCdlbmRBcnJvd1NoYXBlJyk7XG4gICAgICAgIGlmIChzdGFydEFycm93U2hhcGUpIHtcbiAgICAgICAgICAgIHN0YXJ0QXJyb3dTaGFwZS5kcmF3KGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbmRBcnJvd1NoYXBlKSB7XG4gICAgICAgICAgICBlbmRBcnJvd1NoYXBlLmRyYXcoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEdldCB0b3RhbCBsZW5ndGggb2YgcGF0aFxuICAgICAqIEByZXR1cm4ge251bWJlcn0gbGVuZ3RoXG4gICAgICovXG4gICAgUGF0aC5wcm90b3R5cGUuZ2V0VG90YWxMZW5ndGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b3RhbExlbmd0aCA9IHRoaXMuZ2V0KCd0b3RhbExlbmd0aCcpO1xuICAgICAgICBpZiAoIXV0aWxfMS5pc05pbCh0b3RhbExlbmd0aCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0b3RhbExlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jYWxjdWxhdGVDdXJ2ZSgpO1xuICAgICAgICB0aGlzLl9zZXRUY2FjaGUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCd0b3RhbExlbmd0aCcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHBvaW50IGFjY29yZGluZyB0byByYXRpb1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpb1xuICAgICAqIEByZXR1cm4ge1BvaW50fSBwb2ludFxuICAgICAqL1xuICAgIFBhdGgucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKHJhdGlvKSB7XG4gICAgICAgIHZhciB0Q2FjaGUgPSB0aGlzLmdldCgndENhY2hlJyk7XG4gICAgICAgIGlmICghdENhY2hlKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWxjdWxhdGVDdXJ2ZSgpO1xuICAgICAgICAgICAgdGhpcy5fc2V0VGNhY2hlKCk7XG4gICAgICAgICAgICB0Q2FjaGUgPSB0aGlzLmdldCgndENhY2hlJyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHN1YnQ7XG4gICAgICAgIHZhciBpbmRleDtcbiAgICAgICAgdmFyIGN1cnZlID0gdGhpcy5nZXQoJ2N1cnZlJyk7XG4gICAgICAgIGlmICghdENhY2hlIHx8IHRDYWNoZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGlmIChjdXJ2ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGN1cnZlWzBdWzFdLFxuICAgICAgICAgICAgICAgICAgICB5OiBjdXJ2ZVswXVsyXSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLmVhY2godENhY2hlLCBmdW5jdGlvbiAodiwgaSkge1xuICAgICAgICAgICAgaWYgKHJhdGlvID49IHZbMF0gJiYgcmF0aW8gPD0gdlsxXSkge1xuICAgICAgICAgICAgICAgIHN1YnQgPSAocmF0aW8gLSB2WzBdKSAvICh2WzFdIC0gdlswXSk7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHNlZyA9IGN1cnZlW2luZGV4XTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc05pbChzZWcpIHx8IHV0aWxfMS5pc05pbChpbmRleCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsID0gc2VnLmxlbmd0aDtcbiAgICAgICAgdmFyIG5leHRTZWcgPSBjdXJ2ZVtpbmRleCArIDFdO1xuICAgICAgICByZXR1cm4gY3ViaWNfMS5kZWZhdWx0LnBvaW50QXQoc2VnW2wgLSAyXSwgc2VnW2wgLSAxXSwgbmV4dFNlZ1sxXSwgbmV4dFNlZ1syXSwgbmV4dFNlZ1szXSwgbmV4dFNlZ1s0XSwgbmV4dFNlZ1s1XSwgbmV4dFNlZ1s2XSwgc3VidCk7XG4gICAgfTtcbiAgICBQYXRoLnByb3RvdHlwZS5fY2FsY3VsYXRlQ3VydmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5hdHRyKCkucGF0aDtcbiAgICAgICAgdGhpcy5zZXQoJ2N1cnZlJywgcGF0aF8xLmRlZmF1bHQucGF0aFRvQ3VydmUocGF0aCkpO1xuICAgIH07XG4gICAgUGF0aC5wcm90b3R5cGUuX3NldFRjYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRvdGFsTGVuZ3RoID0gMDtcbiAgICAgICAgdmFyIHRlbXBMZW5ndGggPSAwO1xuICAgICAgICAvLyDmr4/mrrUgY3VydmUg5a+55bqU6LW35q2i54K555qE6ZW/5bqm5q+U5L6L5YiX6KGo77yM5b2i5aaCOiBbWzAsIDAuMjVdLCBbMC4yNSwgMC42XS4gWzAuNiwgMC45XSwgWzAuOSwgMV1dXG4gICAgICAgIHZhciB0Q2FjaGUgPSBbXTtcbiAgICAgICAgdmFyIHNlZ21lbnRUO1xuICAgICAgICB2YXIgc2VnbWVudEw7XG4gICAgICAgIHZhciBzZWdtZW50TjtcbiAgICAgICAgdmFyIGw7XG4gICAgICAgIHZhciBjdXJ2ZSA9IHRoaXMuZ2V0KCdjdXJ2ZScpO1xuICAgICAgICBpZiAoIWN1cnZlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLmVhY2goY3VydmUsIGZ1bmN0aW9uIChzZWdtZW50LCBpKSB7XG4gICAgICAgICAgICBzZWdtZW50TiA9IGN1cnZlW2kgKyAxXTtcbiAgICAgICAgICAgIGwgPSBzZWdtZW50Lmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChzZWdtZW50Tikge1xuICAgICAgICAgICAgICAgIHRvdGFsTGVuZ3RoICs9XG4gICAgICAgICAgICAgICAgICAgIGN1YmljXzEuZGVmYXVsdC5sZW5ndGgoc2VnbWVudFtsIC0gMl0sIHNlZ21lbnRbbCAtIDFdLCBzZWdtZW50TlsxXSwgc2VnbWVudE5bMl0sIHNlZ21lbnROWzNdLCBzZWdtZW50Tls0XSwgc2VnbWVudE5bNV0sIHNlZ21lbnROWzZdKSB8fCAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXQoJ3RvdGFsTGVuZ3RoJywgdG90YWxMZW5ndGgpO1xuICAgICAgICBpZiAodG90YWxMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuc2V0KCd0Q2FjaGUnLCBbXSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLmVhY2goY3VydmUsIGZ1bmN0aW9uIChzZWdtZW50LCBpKSB7XG4gICAgICAgICAgICBzZWdtZW50TiA9IGN1cnZlW2kgKyAxXTtcbiAgICAgICAgICAgIGwgPSBzZWdtZW50Lmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChzZWdtZW50Tikge1xuICAgICAgICAgICAgICAgIHNlZ21lbnRUID0gW107XG4gICAgICAgICAgICAgICAgc2VnbWVudFRbMF0gPSB0ZW1wTGVuZ3RoIC8gdG90YWxMZW5ndGg7XG4gICAgICAgICAgICAgICAgc2VnbWVudEwgPSBjdWJpY18xLmRlZmF1bHQubGVuZ3RoKHNlZ21lbnRbbCAtIDJdLCBzZWdtZW50W2wgLSAxXSwgc2VnbWVudE5bMV0sIHNlZ21lbnROWzJdLCBzZWdtZW50TlszXSwgc2VnbWVudE5bNF0sIHNlZ21lbnROWzVdLCBzZWdtZW50Tls2XSk7XG4gICAgICAgICAgICAgICAgLy8g5b2TIHBhdGgg5LiN6L+e57ut5pe277yMc2VnbWVudEwg5Y+v6IO95Li656m677yM5Li656m65pe26ZyA6KaB5L2c5Li6IDAg5aSE55CGXG4gICAgICAgICAgICAgICAgdGVtcExlbmd0aCArPSBzZWdtZW50TCB8fCAwO1xuICAgICAgICAgICAgICAgIHNlZ21lbnRUWzFdID0gdGVtcExlbmd0aCAvIHRvdGFsTGVuZ3RoO1xuICAgICAgICAgICAgICAgIHRDYWNoZS5wdXNoKHNlZ21lbnRUKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0KCd0Q2FjaGUnLCB0Q2FjaGUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHN0YXJ0IHRhbmdlbnQgdmVjdG9yXG4gICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICovXG4gICAgUGF0aC5wcm90b3R5cGUuZ2V0U3RhcnRUYW5nZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VnbWVudHMgPSB0aGlzLmdldFNlZ21lbnRzKCk7XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIGlmIChzZWdtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHNlZ21lbnRzWzBdLmN1cnJlbnRQb2ludDtcbiAgICAgICAgICAgIHZhciBlbmRQb2ludCA9IHNlZ21lbnRzWzFdLmN1cnJlbnRQb2ludDtcbiAgICAgICAgICAgIHZhciB0YW5nZW50ID0gc2VnbWVudHNbMV0uc3RhcnRUYW5nZW50O1xuICAgICAgICAgICAgcmVzdWx0ID0gW107XG4gICAgICAgICAgICBpZiAodGFuZ2VudCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtzdGFydFBvaW50WzBdIC0gdGFuZ2VudFswXSwgc3RhcnRQb2ludFsxXSAtIHRhbmdlbnRbMV1dKTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChbc3RhcnRQb2ludFswXSwgc3RhcnRQb2ludFsxXV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goW2VuZFBvaW50WzBdLCBlbmRQb2ludFsxXV0pO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtzdGFydFBvaW50WzBdLCBzdGFydFBvaW50WzFdXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEdldCBlbmQgdGFuZ2VudCB2ZWN0b3JcbiAgICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICAgKi9cbiAgICBQYXRoLnByb3RvdHlwZS5nZXRFbmRUYW5nZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VnbWVudHMgPSB0aGlzLmdldFNlZ21lbnRzKCk7XG4gICAgICAgIHZhciBsZW5ndGggPSBzZWdtZW50cy5sZW5ndGg7XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIGlmIChsZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHNlZ21lbnRzW2xlbmd0aCAtIDJdLmN1cnJlbnRQb2ludDtcbiAgICAgICAgICAgIHZhciBlbmRQb2ludCA9IHNlZ21lbnRzW2xlbmd0aCAtIDFdLmN1cnJlbnRQb2ludDtcbiAgICAgICAgICAgIHZhciB0YW5nZW50ID0gc2VnbWVudHNbbGVuZ3RoIC0gMV0uZW5kVGFuZ2VudDtcbiAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgaWYgKHRhbmdlbnQpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChbZW5kUG9pbnRbMF0gLSB0YW5nZW50WzBdLCBlbmRQb2ludFsxXSAtIHRhbmdlbnRbMV1dKTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChbZW5kUG9pbnRbMF0sIGVuZFBvaW50WzFdXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChbc3RhcnRQb2ludFswXSwgc3RhcnRQb2ludFsxXV0pO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtlbmRQb2ludFswXSwgZW5kUG9pbnRbMV1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgcmV0dXJuIFBhdGg7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyDlpJrovrnlvaJcbiAqIEBhdXRob3IgZHhxNjEzQGdtYWlsLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xudmFyIHBvbHlsaW5lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9pbi1zdHJva2UvcG9seWxpbmVcIik7XG52YXIgcG9seWdvbl8xID0gcmVxdWlyZShcIi4uL3V0aWwvaW4tcGF0aC9wb2x5Z29uXCIpO1xudmFyIFBvbHlnb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUG9seWdvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQb2x5Z29uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFBvbHlnb24ucHJvdG90eXBlLmlzSW5TdHJva2VPclBhdGggPSBmdW5jdGlvbiAoeCwgeSwgaXNTdHJva2UsIGlzRmlsbCwgbGluZVdpZHRoKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLmF0dHIoKS5wb2ludHM7XG4gICAgICAgIHZhciBpc0hpdCA9IGZhbHNlO1xuICAgICAgICBpZiAoaXNTdHJva2UpIHtcbiAgICAgICAgICAgIGlzSGl0ID0gcG9seWxpbmVfMS5kZWZhdWx0KHBvaW50cywgbGluZVdpZHRoLCB4LCB5LCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzSGl0ICYmIGlzRmlsbCkge1xuICAgICAgICAgICAgaXNIaXQgPSBwb2x5Z29uXzEuZGVmYXVsdChwb2ludHMsIHgsIHkpOyAvLyBpc1BvaW50SW5QYXRoKHNoYXBlLCB4LCB5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNIaXQ7XG4gICAgfTtcbiAgICBQb2x5Z29uLnByb3RvdHlwZS5jcmVhdGVQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBwb2ludHMgPSBhdHRycy5wb2ludHM7XG4gICAgICAgIGlmIChwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKHBvaW50WzBdLCBwb2ludFsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhwb2ludFswXSwgcG9pbnRbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfTtcbiAgICByZXR1cm4gUG9seWdvbjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBvbHlnb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2x5Z29uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIkBhbnR2L2ctbWF0aC9saWIvbGluZVwiKTtcbnZhciBwb2x5bGluZV8xID0gcmVxdWlyZShcIkBhbnR2L2ctbWF0aC9saWIvcG9seWxpbmVcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBwb2x5bGluZV8yID0gcmVxdWlyZShcIi4uL3V0aWwvaW4tc3Ryb2tlL3BvbHlsaW5lXCIpO1xudmFyIEFycm93VXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL2Fycm93XCIpO1xudmFyIFBvbHlMaW5lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBvbHlMaW5lLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBvbHlMaW5lKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSwgeyBzdGFydEFycm93OiBmYWxzZSwgZW5kQXJyb3c6IGZhbHNlIH0pO1xuICAgIH07XG4gICAgUG9seUxpbmUucHJvdG90eXBlLmluaXRBdHRycyA9IGZ1bmN0aW9uIChhdHRycykge1xuICAgICAgICB0aGlzLnNldEFycm93KCk7XG4gICAgfTtcbiAgICAvLyDmm7TmlrDlsZ7mgKfml7bvvIzmo4DmtYvmmK/lkKbmm7TmlLnkuoYgcG9pbnRzXG4gICAgUG9seUxpbmUucHJvdG90eXBlLm9uQXR0ckNoYW5nZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UuY2FsbCh0aGlzLCBuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpO1xuICAgICAgICB0aGlzLnNldEFycm93KCk7XG4gICAgICAgIGlmIChbJ3BvaW50cyddLmluZGV4T2YobmFtZSkgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNldENhY2hlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5fcmVzZXRDYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXQoJ3RvdGFsTGVuZ3RoJywgbnVsbCk7XG4gICAgICAgIHRoaXMuc2V0KCd0Q2FjaGUnLCBudWxsKTtcbiAgICB9O1xuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5zZXRBcnJvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuYXR0cnMsIHBvaW50cyA9IF9hLnBvaW50cywgc3RhcnRBcnJvdyA9IF9hLnN0YXJ0QXJyb3csIGVuZEFycm93ID0gX2EuZW5kQXJyb3c7XG4gICAgICAgIHZhciBsZW5ndGggPSBwb2ludHMubGVuZ3RoO1xuICAgICAgICB2YXIgeDEgPSBwb2ludHNbMF1bMF07XG4gICAgICAgIHZhciB5MSA9IHBvaW50c1swXVsxXTtcbiAgICAgICAgdmFyIHgyID0gcG9pbnRzW2xlbmd0aCAtIDFdWzBdO1xuICAgICAgICB2YXIgeTIgPSBwb2ludHNbbGVuZ3RoIC0gMV1bMV07XG4gICAgICAgIGlmIChzdGFydEFycm93KSB7XG4gICAgICAgICAgICBBcnJvd1V0aWwuYWRkU3RhcnRBcnJvdyh0aGlzLCBhdHRycywgcG9pbnRzWzFdWzBdLCBwb2ludHNbMV1bMV0sIHgxLCB5MSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZEFycm93KSB7XG4gICAgICAgICAgICBBcnJvd1V0aWwuYWRkRW5kQXJyb3codGhpcywgYXR0cnMsIHBvaW50c1tsZW5ndGggLSAyXVswXSwgcG9pbnRzW2xlbmd0aCAtIDJdWzFdLCB4MiwgeTIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDkuI3lhYHorrggZmlsbFxuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5pc0ZpbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5pc0luU3Ryb2tlT3JQYXRoID0gZnVuY3Rpb24gKHgsIHksIGlzU3Ryb2tlLCBpc0ZpbGwsIGxpbmVXaWR0aCkge1xuICAgICAgICAvLyDmsqHmnInorr7nva4gc3Ryb2tlIOS4jeiDveiiq+aLvuWPliwg5rKh5pyJ57q/5a695LiN6IO96KKr5ou+5Y+WXG4gICAgICAgIGlmICghaXNTdHJva2UgfHwgIWxpbmVXaWR0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLmF0dHIoKS5wb2ludHM7XG4gICAgICAgIHJldHVybiBwb2x5bGluZV8yLmRlZmF1bHQocG9pbnRzLCBsaW5lV2lkdGgsIHgsIHksIGZhbHNlKTtcbiAgICB9O1xuICAgIC8vIOWni+e7iOWhq+WFhVxuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5pc1N0cm9rZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICBQb2x5TGluZS5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuYXR0cigpLCBwb2ludHMgPSBfYS5wb2ludHMsIHN0YXJ0QXJyb3cgPSBfYS5zdGFydEFycm93LCBlbmRBcnJvdyA9IF9hLmVuZEFycm93O1xuICAgICAgICB2YXIgbGVuZ3RoID0gcG9pbnRzLmxlbmd0aDtcbiAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHgxID0gcG9pbnRzWzBdWzBdO1xuICAgICAgICB2YXIgeTEgPSBwb2ludHNbMF1bMV07XG4gICAgICAgIHZhciB4MiA9IHBvaW50c1tsZW5ndGggLSAxXVswXTtcbiAgICAgICAgdmFyIHkyID0gcG9pbnRzW2xlbmd0aCAtIDFdWzFdO1xuICAgICAgICAvLyDlpoLmnpzlrprkuYnkuobnrq3lpLTvvIzlubbkuJTmmK/oh6rlrprkuYnnrq3lpLTvvIznur/mnaHnm7jlupTnvKnov5tcbiAgICAgICAgaWYgKHN0YXJ0QXJyb3cgJiYgc3RhcnRBcnJvdy5kKSB7XG4gICAgICAgICAgICB2YXIgZGlzdGFuY2UgPSBBcnJvd1V0aWwuZ2V0U2hvcnRlbk9mZnNldCh4MSwgeTEsIHBvaW50c1sxXVswXSwgcG9pbnRzWzFdWzFdLCBzdGFydEFycm93LmQpO1xuICAgICAgICAgICAgeDEgKz0gZGlzdGFuY2UuZHg7XG4gICAgICAgICAgICB5MSArPSBkaXN0YW5jZS5keTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW5kQXJyb3cgJiYgZW5kQXJyb3cuZCkge1xuICAgICAgICAgICAgdmFyIGRpc3RhbmNlID0gQXJyb3dVdGlsLmdldFNob3J0ZW5PZmZzZXQocG9pbnRzW2xlbmd0aCAtIDJdWzBdLCBwb2ludHNbbGVuZ3RoIC0gMl1bMV0sIHgyLCB5MiwgZW5kQXJyb3cuZCk7XG4gICAgICAgICAgICB4MiAtPSBkaXN0YW5jZS5keDtcbiAgICAgICAgICAgIHkyIC09IGRpc3RhbmNlLmR5O1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICAgIGNvbnRleHQubW92ZVRvKHgxLCB5MSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhwb2ludFswXSwgcG9pbnRbMV0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQubGluZVRvKHgyLCB5Mik7XG4gICAgfTtcbiAgICBQb2x5TGluZS5wcm90b3R5cGUuYWZ0ZXJEcmF3UGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIHZhciBzdGFydEFycm93U2hhcGUgPSB0aGlzLmdldCgnc3RhcnRBcnJvd1NoYXBlJyk7XG4gICAgICAgIHZhciBlbmRBcnJvd1NoYXBlID0gdGhpcy5nZXQoJ2VuZEFycm93U2hhcGUnKTtcbiAgICAgICAgaWYgKHN0YXJ0QXJyb3dTaGFwZSkge1xuICAgICAgICAgICAgc3RhcnRBcnJvd1NoYXBlLmRyYXcoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZEFycm93U2hhcGUpIHtcbiAgICAgICAgICAgIGVuZEFycm93U2hhcGUuZHJhdyhjb250ZXh0KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IGxlbmd0aCBvZiBwb2x5bGluZVxuICAgICAqIEByZXR1cm4ge251bWJlcn0gbGVuZ3RoXG4gICAgICovXG4gICAgUG9seUxpbmUucHJvdG90eXBlLmdldFRvdGFsTGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5hdHRyKCkucG9pbnRzO1xuICAgICAgICAvLyBnZXQgdG90YWxMZW5ndGggZnJvbSBjYWNoZVxuICAgICAgICB2YXIgdG90YWxMZW5ndGggPSB0aGlzLmdldCgndG90YWxMZW5ndGgnKTtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwodG90YWxMZW5ndGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdG90YWxMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ3RvdGFsTGVuZ3RoJywgcG9seWxpbmVfMS5kZWZhdWx0Lmxlbmd0aChwb2ludHMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCd0b3RhbExlbmd0aCcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHBvaW50IGFjY29yZGluZyB0byByYXRpb1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpb1xuICAgICAqIEByZXR1cm4ge1BvaW50fSBwb2ludFxuICAgICAqL1xuICAgIFBvbHlMaW5lLnByb3RvdHlwZS5nZXRQb2ludCA9IGZ1bmN0aW9uIChyYXRpbykge1xuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5hdHRyKCkucG9pbnRzO1xuICAgICAgICAvLyBnZXQgdENhY2hlIGZyb20gY2FjaGVcbiAgICAgICAgdmFyIHRDYWNoZSA9IHRoaXMuZ2V0KCd0Q2FjaGUnKTtcbiAgICAgICAgaWYgKCF0Q2FjaGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFRjYWNoZSgpO1xuICAgICAgICAgICAgdENhY2hlID0gdGhpcy5nZXQoJ3RDYWNoZScpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdWJ0O1xuICAgICAgICB2YXIgaW5kZXg7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRDYWNoZSwgZnVuY3Rpb24gKHYsIGkpIHtcbiAgICAgICAgICAgIGlmIChyYXRpbyA+PSB2WzBdICYmIHJhdGlvIDw9IHZbMV0pIHtcbiAgICAgICAgICAgICAgICBzdWJ0ID0gKHJhdGlvIC0gdlswXSkgLyAodlsxXSAtIHZbMF0pO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBsaW5lXzEuZGVmYXVsdC5wb2ludEF0KHBvaW50c1tpbmRleF1bMF0sIHBvaW50c1tpbmRleF1bMV0sIHBvaW50c1tpbmRleCArIDFdWzBdLCBwb2ludHNbaW5kZXggKyAxXVsxXSwgc3VidCk7XG4gICAgfTtcbiAgICBQb2x5TGluZS5wcm90b3R5cGUuX3NldFRjYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMuYXR0cigpLnBvaW50cztcbiAgICAgICAgaWYgKCFwb2ludHMgfHwgcG9pbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0b3RhbExlbmd0aCA9IHRoaXMuZ2V0VG90YWxMZW5ndGgoKTtcbiAgICAgICAgaWYgKHRvdGFsTGVuZ3RoIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGVtcExlbmd0aCA9IDA7XG4gICAgICAgIHZhciB0Q2FjaGUgPSBbXTtcbiAgICAgICAgdmFyIHNlZ21lbnRUO1xuICAgICAgICB2YXIgc2VnbWVudEw7XG4gICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHAsIGkpIHtcbiAgICAgICAgICAgIGlmIChwb2ludHNbaSArIDFdKSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudFQgPSBbXTtcbiAgICAgICAgICAgICAgICBzZWdtZW50VFswXSA9IHRlbXBMZW5ndGggLyB0b3RhbExlbmd0aDtcbiAgICAgICAgICAgICAgICBzZWdtZW50TCA9IGxpbmVfMS5kZWZhdWx0Lmxlbmd0aChwWzBdLCBwWzFdLCBwb2ludHNbaSArIDFdWzBdLCBwb2ludHNbaSArIDFdWzFdKTtcbiAgICAgICAgICAgICAgICB0ZW1wTGVuZ3RoICs9IHNlZ21lbnRMO1xuICAgICAgICAgICAgICAgIHNlZ21lbnRUWzFdID0gdGVtcExlbmd0aCAvIHRvdGFsTGVuZ3RoO1xuICAgICAgICAgICAgICAgIHRDYWNoZS5wdXNoKHNlZ21lbnRUKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0KCd0Q2FjaGUnLCB0Q2FjaGUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHN0YXJ0IHRhbmdlbnQgdmVjdG9yXG4gICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICovXG4gICAgUG9seUxpbmUucHJvdG90eXBlLmdldFN0YXJ0VGFuZ2VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMuYXR0cigpLnBvaW50cztcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICByZXN1bHQucHVzaChbcG9pbnRzWzFdWzBdLCBwb2ludHNbMV1bMV1dKTtcbiAgICAgICAgcmVzdWx0LnB1c2goW3BvaW50c1swXVswXSwgcG9pbnRzWzBdWzFdXSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBHZXQgZW5kIHRhbmdlbnQgdmVjdG9yXG4gICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICovXG4gICAgUG9seUxpbmUucHJvdG90eXBlLmdldEVuZFRhbmdlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLmF0dHIoKS5wb2ludHM7XG4gICAgICAgIHZhciBsID0gcG9pbnRzLmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgcmVzdWx0LnB1c2goW3BvaW50c1tsIC0gMV1bMF0sIHBvaW50c1tsIC0gMV1bMV1dKTtcbiAgICAgICAgcmVzdWx0LnB1c2goW3BvaW50c1tsXVswXSwgcG9pbnRzW2xdWzFdXSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICByZXR1cm4gUG9seUxpbmU7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQb2x5TGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbHlsaW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOefqeW9olxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgcGFyc2VfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3BhcnNlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3V0aWxcIik7XG52YXIgcmVjdF8xID0gcmVxdWlyZShcIi4uL3V0aWwvaW4tc3Ryb2tlL3JlY3RcIik7XG52YXIgcmVjdF9yYWRpdXNfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2luLXN0cm9rZS9yZWN0LXJhZGl1c1wiKTtcbnZhciBwb2ludF9pbl9wYXRoXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9pbi1wYXRoL3BvaW50LWluLXBhdGhcIik7XG52YXIgUmVjdCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhSZWN0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJlY3QoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUmVjdC5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCwgcmFkaXVzOiAwIH0pO1xuICAgIH07XG4gICAgUmVjdC5wcm90b3R5cGUuaXNJblN0cm9rZU9yUGF0aCA9IGZ1bmN0aW9uICh4LCB5LCBpc1N0cm9rZSwgaXNGaWxsLCBsaW5lV2lkdGgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBtaW5YID0gYXR0cnMueDtcbiAgICAgICAgdmFyIG1pblkgPSBhdHRycy55O1xuICAgICAgICB2YXIgd2lkdGggPSBhdHRycy53aWR0aDtcbiAgICAgICAgdmFyIGhlaWdodCA9IGF0dHJzLmhlaWdodDtcbiAgICAgICAgdmFyIHJhZGl1cyA9IGF0dHJzLnJhZGl1cztcbiAgICAgICAgLy8g5peg5ZyG6KeS5pe255qE562W55WlXG4gICAgICAgIGlmICghcmFkaXVzKSB7XG4gICAgICAgICAgICB2YXIgaGFsZldpZHRoID0gbGluZVdpZHRoIC8gMjtcbiAgICAgICAgICAgIC8vIOWQjOaXtuWhq+WFheWSjOW4puaciei+ueahhlxuICAgICAgICAgICAgaWYgKGlzRmlsbCAmJiBpc1N0cm9rZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1dGlsXzEuaW5Cb3gobWluWCAtIGhhbGZXaWR0aCwgbWluWSAtIGhhbGZXaWR0aCwgd2lkdGggKyBoYWxmV2lkdGgsIGhlaWdodCArIGhhbGZXaWR0aCwgeCwgeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDku4XloavlhYVcbiAgICAgICAgICAgIGlmIChpc0ZpbGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXRpbF8xLmluQm94KG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQsIHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3Ryb2tlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlY3RfMS5kZWZhdWx0KG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQsIGxpbmVXaWR0aCwgeCwgeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgaXNIaXQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChpc1N0cm9rZSkge1xuICAgICAgICAgICAgICAgIGlzSGl0ID0gcmVjdF9yYWRpdXNfMS5kZWZhdWx0KG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQsIHJhZGl1cywgbGluZVdpZHRoLCB4LCB5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIOS7heWhq+WFheaXtuW4puacieWchuinkueahOefqeW9ouebtOaOpemAmui/h+WbvuW9ouaLvuWPllxuICAgICAgICAgICAgLy8g5Lul5ZCO5Y+v5Lul5pS55oiQ57qv5pWw5a2m55qE6L+R5Ly85ou+5Y+W77yM5bCG5ZyG5byn5YiH5Ymy5oiQ5aSa6L655b2iXG4gICAgICAgICAgICBpZiAoIWlzSGl0ICYmIGlzRmlsbCkge1xuICAgICAgICAgICAgICAgIGlzSGl0ID0gcG9pbnRfaW5fcGF0aF8xLmRlZmF1bHQodGhpcywgeCwgeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaXNIaXQ7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJlY3QucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIHggPSBhdHRycy54O1xuICAgICAgICB2YXIgeSA9IGF0dHJzLnk7XG4gICAgICAgIHZhciB3aWR0aCA9IGF0dHJzLndpZHRoO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gYXR0cnMuaGVpZ2h0O1xuICAgICAgICB2YXIgcmFkaXVzID0gYXR0cnMucmFkaXVzO1xuICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgICBpZiAocmFkaXVzID09PSAwKSB7XG4gICAgICAgICAgICAvLyDmlLnmiJDljp/nlJ/nmoRyZWN05pa55rOVXG4gICAgICAgICAgICBjb250ZXh0LnJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgX2EgPSBwYXJzZV8xLnBhcnNlUmFkaXVzKHJhZGl1cyksIHIxID0gX2FbMF0sIHIyID0gX2FbMV0sIHIzID0gX2FbMl0sIHI0ID0gX2FbM107XG4gICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyh4ICsgcjEsIHkpO1xuICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCArIHdpZHRoIC0gcjIsIHkpO1xuICAgICAgICAgICAgcjIgIT09IDAgJiYgY29udGV4dC5hcmMoeCArIHdpZHRoIC0gcjIsIHkgKyByMiwgcjIsIC1NYXRoLlBJIC8gMiwgMCk7XG4gICAgICAgICAgICBjb250ZXh0LmxpbmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQgLSByMyk7XG4gICAgICAgICAgICByMyAhPT0gMCAmJiBjb250ZXh0LmFyYyh4ICsgd2lkdGggLSByMywgeSArIGhlaWdodCAtIHIzLCByMywgMCwgTWF0aC5QSSAvIDIpO1xuICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCArIHI0LCB5ICsgaGVpZ2h0KTtcbiAgICAgICAgICAgIHI0ICE9PSAwICYmIGNvbnRleHQuYXJjKHggKyByNCwgeSArIGhlaWdodCAtIHI0LCByNCwgTWF0aC5QSSAvIDIsIE1hdGguUEkpO1xuICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCwgeSArIHIxKTtcbiAgICAgICAgICAgIHIxICE9PSAwICYmIGNvbnRleHQuYXJjKHggKyByMSwgeSArIHIxLCByMSwgTWF0aC5QSSwgTWF0aC5QSSAqIDEuNSk7XG4gICAgICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gUmVjdDtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFJlY3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOaWh+acrFxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdXRpbFwiKTtcbnZhciB0ZXh0XzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlL2xpYi91dGlsL3RleHRcIik7XG52YXIgVGV4dCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUZXh0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRleHQoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLy8g6buY6K6k5paH5pys5bGe5oCnXG4gICAgVGV4dC5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgdGV4dDogbnVsbCwgZm9udFNpemU6IDEyLCBmb250RmFtaWx5OiAnc2Fucy1zZXJpZicsIGZvbnRTdHlsZTogJ25vcm1hbCcsIGZvbnRXZWlnaHQ6ICdub3JtYWwnLCBmb250VmFyaWFudDogJ25vcm1hbCcsIHRleHRBbGlnbjogJ3N0YXJ0JywgdGV4dEJhc2VsaW5lOiAnYm90dG9tJyB9KTtcbiAgICB9O1xuICAgIC8vIOS7heS7heS9v+eUqOWMheWbtOebkuajgOa1i+adpei/m+ihjOaLvuWPllxuICAgIFRleHQucHJvdG90eXBlLmlzT25seUhpdEJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICAvLyDliJ3lp4vljJbml7bnu4TlkIggZm9udO+8jOWQjOaXtuWIpOaWrSB0ZXh0IOaYr+WQpuaNouihjFxuICAgIFRleHQucHJvdG90eXBlLmluaXRBdHRycyA9IGZ1bmN0aW9uIChhdHRycykge1xuICAgICAgICB0aGlzLl9hc3NlbWJsZUZvbnQoKTtcbiAgICAgICAgaWYgKGF0dHJzLnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFRleHQoYXR0cnMudGV4dCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOe7hOijheWtl+S9k1xuICAgIFRleHQucHJvdG90eXBlLl9hc3NlbWJsZUZvbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cnM7XG4gICAgICAgIGF0dHJzLmZvbnQgPSB0ZXh0XzEuYXNzZW1ibGVGb250KGF0dHJzKTtcbiAgICB9O1xuICAgIC8vIOWmguaenOaWh+acrOaNouihjO+8jOWImee8k+WtmOaVsOe7hFxuICAgIFRleHQucHJvdG90eXBlLl9zZXRUZXh0ID0gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgdmFyIHRleHRBcnIgPSBudWxsO1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHRleHQpICYmIHRleHQuaW5kZXhPZignXFxuJykgIT09IC0xKSB7XG4gICAgICAgICAgICB0ZXh0QXJyID0gdGV4dC5zcGxpdCgnXFxuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ3RleHRBcnInLCB0ZXh0QXJyKTtcbiAgICB9O1xuICAgIC8vIOabtOaWsOWxnuaAp+aXtu+8jOajgOa1i+aYr+WQpuabtOaUueS6hiBmb25044CBdGV4dFxuICAgIFRleHQucHJvdG90eXBlLm9uQXR0ckNoYW5nZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UuY2FsbCh0aGlzLCBuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpO1xuICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoKCdmb250JykpIHtcbiAgICAgICAgICAgIHRoaXMuX2Fzc2VtYmxlRm9udCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYW1lID09PSAndGV4dCcpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFRleHQodmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDov5nkuKrmlrnms5XlnKggdGV4dCDml7bmsqHmnInlj6/ku6XlgZrnmoTkuovmg4XvvIzlpoLmnpzopoHmlK/mjIHmloflrZfog4zmma/ml7blj6/ku6XogIPomZFcbiAgICAvLyBjcmVhdGVQYXRoKGNvbnRleHQpIHtcbiAgICAvLyB9XG4gICAgLy8g5aaC5p6c5paH5pys5aSa6KGM77yM6ZyA6KaB6I635Y+W5paH5pys6Ze06LedXG4gICAgVGV4dC5wcm90b3R5cGUuX2dldFNwYWNlaW5nWSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRycztcbiAgICAgICAgdmFyIGxpbmVIZWlnaHQgPSBhdHRycy5saW5lSGVpZ2h0O1xuICAgICAgICB2YXIgZm9udFNpemUgPSBhdHRycy5mb250U2l6ZSAqIDE7XG4gICAgICAgIHJldHVybiBsaW5lSGVpZ2h0ID8gbGluZUhlaWdodCAtIGZvbnRTaXplIDogZm9udFNpemUgKiAwLjE0O1xuICAgIH07XG4gICAgLy8g57uY5Yi25paH5pys77yM6ICD6JmR5aSa6KGM55qE5Zy65pmvXG4gICAgVGV4dC5wcm90b3R5cGUuX2RyYXdUZXh0QXJyID0gZnVuY3Rpb24gKGNvbnRleHQsIHRleHRBcnIsIGlzRmlsbCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHJzO1xuICAgICAgICB2YXIgdGV4dEJhc2VsaW5lID0gYXR0cnMudGV4dEJhc2VsaW5lO1xuICAgICAgICB2YXIgeCA9IGF0dHJzLng7XG4gICAgICAgIHZhciB5ID0gYXR0cnMueTtcbiAgICAgICAgdmFyIGZvbnRTaXplID0gYXR0cnMuZm9udFNpemUgKiAxO1xuICAgICAgICB2YXIgc3BhY2VpbmdZID0gdGhpcy5fZ2V0U3BhY2VpbmdZKCk7XG4gICAgICAgIHZhciBoZWlnaHQgPSB0ZXh0XzEuZ2V0VGV4dEhlaWdodChhdHRycy50ZXh0LCBhdHRycy5mb250U2l6ZSwgYXR0cnMubGluZUhlaWdodCk7XG4gICAgICAgIHZhciBzdWJZO1xuICAgICAgICB1dGlsXzEuZWFjaCh0ZXh0QXJyLCBmdW5jdGlvbiAoc3ViVGV4dCwgaW5kZXgpIHtcbiAgICAgICAgICAgIHN1YlkgPSB5ICsgaW5kZXggKiAoc3BhY2VpbmdZICsgZm9udFNpemUpIC0gaGVpZ2h0ICsgZm9udFNpemU7IC8vIGJvdHRvbTtcbiAgICAgICAgICAgIGlmICh0ZXh0QmFzZWxpbmUgPT09ICdtaWRkbGUnKVxuICAgICAgICAgICAgICAgIHN1YlkgKz0gaGVpZ2h0IC0gZm9udFNpemUgLSAoaGVpZ2h0IC0gZm9udFNpemUpIC8gMjtcbiAgICAgICAgICAgIGlmICh0ZXh0QmFzZWxpbmUgPT09ICd0b3AnKVxuICAgICAgICAgICAgICAgIHN1YlkgKz0gaGVpZ2h0IC0gZm9udFNpemU7XG4gICAgICAgICAgICBpZiAoaXNGaWxsKSB7XG4gICAgICAgICAgICAgICAgY29udGV4dC5maWxsVGV4dChzdWJUZXh0LCB4LCBzdWJZKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlVGV4dChzdWJUZXh0LCB4LCBzdWJZKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDnu5jliLbmlofmnKzvvIzlkIzml7bogIPomZHloavlhYXlkoznu5jliLbovrnmoYZcbiAgICBUZXh0LnByb3RvdHlwZS5fZHJhd1RleHQgPSBmdW5jdGlvbiAoY29udGV4dCwgaXNGaWxsKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgeCA9IGF0dHJzLng7XG4gICAgICAgIHZhciB5ID0gYXR0cnMueTtcbiAgICAgICAgdmFyIHRleHRBcnIgPSB0aGlzLmdldCgndGV4dEFycicpO1xuICAgICAgICBpZiAodGV4dEFycikge1xuICAgICAgICAgICAgdGhpcy5fZHJhd1RleHRBcnIoY29udGV4dCwgdGV4dEFyciwgaXNGaWxsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciB0ZXh0ID0gYXR0cnMudGV4dDtcbiAgICAgICAgICAgIGlmIChpc0ZpbGwpIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmZpbGxUZXh0KHRleHQsIHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udGV4dC5zdHJva2VUZXh0KHRleHQsIHgsIHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDlpI3lhpnnu5jliLblkozloavlhYXnmoTpgLvovpHvvJrlr7nkuo7mlofmnKzvvIzlupTor6XlhYjnu5jliLbovrnmoYbvvIzlho3ov5vooYzloavlhYVcbiAgICBUZXh0LnByb3RvdHlwZS5zdHJva2VBbmRGaWxsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRycywgbGluZVdpZHRoID0gX2EubGluZVdpZHRoLCBvcGFjaXR5ID0gX2Eub3BhY2l0eSwgc3Ryb2tlT3BhY2l0eSA9IF9hLnN0cm9rZU9wYWNpdHksIGZpbGxPcGFjaXR5ID0gX2EuZmlsbE9wYWNpdHk7XG4gICAgICAgIGlmICh0aGlzLmlzU3Ryb2tlKCkpIHtcbiAgICAgICAgICAgIGlmIChsaW5lV2lkdGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoc3Ryb2tlT3BhY2l0eSkgJiYgc3Ryb2tlT3BhY2l0eSAhPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0Lmdsb2JhbEFscGhhID0gb3BhY2l0eTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJva2UoY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNGaWxsKCkpIHtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmlzTmlsKGZpbGxPcGFjaXR5KSAmJiBmaWxsT3BhY2l0eSAhPT0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZ2xvYmFsQWxwaGEgPSBmaWxsT3BhY2l0eTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGwoY29udGV4dCk7XG4gICAgICAgICAgICAgICAgY29udGV4dC5nbG9iYWxBbHBoYSA9IG9wYWNpdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGwoY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZnRlckRyYXdQYXRoKGNvbnRleHQpO1xuICAgIH07XG4gICAgLy8g5aSN5YaZ5aGr5YWF6YC76L6RXG4gICAgVGV4dC5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIHRoaXMuX2RyYXdUZXh0KGNvbnRleHQsIHRydWUpO1xuICAgIH07XG4gICAgLy8g5aSN5YaZ57uY5Yi26L655qGG55qE6YC76L6RXG4gICAgVGV4dC5wcm90b3R5cGUuc3Ryb2tlID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fZHJhd1RleHQoY29udGV4dCwgZmFsc2UpO1xuICAgIH07XG4gICAgcmV0dXJuIFRleHQ7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLy8g5a+85Ye6IGctYmFzZSDkuK3nmoQgdHlwZXNcbnRzbGliXzEuX19leHBvcnRTdGFyKHJlcXVpcmUoXCJAYW50di9nLWJhc2UvbGliL3R5cGVzXCIpLCBleHBvcnRzKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXR5cGVzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vLyDlkJHph4/plb/luqZcbmZ1bmN0aW9uIHZNYWcodikge1xuICAgIHJldHVybiBNYXRoLnNxcnQodlswXSAqIHZbMF0gKyB2WzFdICogdlsxXSk7XG59XG4vLyB1LnYvfHV8fHZ877yM6K6h566X5aS56KeS55qE5L2Z5bym5YC8XG5mdW5jdGlvbiB2UmF0aW8odSwgdikge1xuICAgIC8vIOW9k+WtmOWcqOS4gOS4quWQkemHj+eahOmVv+W6puS4uiAwIOaXtu+8jOWkueinkuS5n+S4uiAw77yM5Y2z5aS56KeS55qE5L2Z5bym5YC85Li6IDFcbiAgICByZXR1cm4gdk1hZyh1KSAqIHZNYWcodikgPyAodVswXSAqIHZbMF0gKyB1WzFdICogdlsxXSkgLyAodk1hZyh1KSAqIHZNYWcodikpIDogMTtcbn1cbi8vIOWQkemHj+inkuW6plxuZnVuY3Rpb24gdkFuZ2xlKHUsIHYpIHtcbiAgICByZXR1cm4gKHVbMF0gKiB2WzFdIDwgdVsxXSAqIHZbMF0gPyAtMSA6IDEpICogTWF0aC5hY29zKHZSYXRpbyh1LCB2KSk7XG59XG4vLyBBIDA6cnggMTpyeSAyOngtYXhpcy1yb3RhdGlvbiAzOmxhcmdlLWFyYy1mbGFnIDQ6c3dlZXAtZmxhZyA1OiB4IDY6IHlcbmZ1bmN0aW9uIGdldEFyY1BhcmFtcyhzdGFydFBvaW50LCBwYXJhbXMpIHtcbiAgICB2YXIgcnggPSBwYXJhbXNbMV07XG4gICAgdmFyIHJ5ID0gcGFyYW1zWzJdO1xuICAgIHZhciB4Um90YXRpb24gPSB1dGlsXzEubW9kKHV0aWxfMS50b1JhZGlhbihwYXJhbXNbM10pLCBNYXRoLlBJICogMik7XG4gICAgdmFyIGFyY0ZsYWcgPSBwYXJhbXNbNF07XG4gICAgdmFyIHN3ZWVwRmxhZyA9IHBhcmFtc1s1XTtcbiAgICAvLyDlvKflvaLotbfngrnlnZDmoIdcbiAgICB2YXIgeDEgPSBzdGFydFBvaW50WzBdO1xuICAgIHZhciB5MSA9IHN0YXJ0UG9pbnRbMV07XG4gICAgLy8g5byn5b2i57uI54K55Z2Q5qCHXG4gICAgdmFyIHgyID0gcGFyYW1zWzZdO1xuICAgIHZhciB5MiA9IHBhcmFtc1s3XTtcbiAgICB2YXIgeHAgPSAoTWF0aC5jb3MoeFJvdGF0aW9uKSAqICh4MSAtIHgyKSkgLyAyLjAgKyAoTWF0aC5zaW4oeFJvdGF0aW9uKSAqICh5MSAtIHkyKSkgLyAyLjA7XG4gICAgdmFyIHlwID0gKC0xICogTWF0aC5zaW4oeFJvdGF0aW9uKSAqICh4MSAtIHgyKSkgLyAyLjAgKyAoTWF0aC5jb3MoeFJvdGF0aW9uKSAqICh5MSAtIHkyKSkgLyAyLjA7XG4gICAgdmFyIGxhbWJkYSA9ICh4cCAqIHhwKSAvIChyeCAqIHJ4KSArICh5cCAqIHlwKSAvIChyeSAqIHJ5KTtcbiAgICBpZiAobGFtYmRhID4gMSkge1xuICAgICAgICByeCAqPSBNYXRoLnNxcnQobGFtYmRhKTtcbiAgICAgICAgcnkgKj0gTWF0aC5zcXJ0KGxhbWJkYSk7XG4gICAgfVxuICAgIHZhciBkaWZmID0gcnggKiByeCAqICh5cCAqIHlwKSArIHJ5ICogcnkgKiAoeHAgKiB4cCk7XG4gICAgdmFyIGYgPSBkaWZmID8gTWF0aC5zcXJ0KChyeCAqIHJ4ICogKHJ5ICogcnkpIC0gZGlmZikgLyBkaWZmKSA6IDE7XG4gICAgaWYgKGFyY0ZsYWcgPT09IHN3ZWVwRmxhZykge1xuICAgICAgICBmICo9IC0xO1xuICAgIH1cbiAgICBpZiAoaXNOYU4oZikpIHtcbiAgICAgICAgZiA9IDA7XG4gICAgfVxuICAgIC8vIOaXi+i9rOWJjeeahOi1t+eCueWdkOagh++8jOS4lOW9k+mVv+WNiui9tOWSjOefreWNiui9tOeahOmVv+W6puS4uiAwIOaXtu+8jOWdkOagh+aMiSAoMCwgMCkg5aSE55CGXG4gICAgdmFyIGN4cCA9IHJ5ID8gKGYgKiByeCAqIHlwKSAvIHJ5IDogMDtcbiAgICB2YXIgY3lwID0gcnggPyAoZiAqIC1yeSAqIHhwKSAvIHJ4IDogMDtcbiAgICAvLyDmpK3lnIblnIblv4PlnZDmoIdcbiAgICB2YXIgY3ggPSAoeDEgKyB4MikgLyAyLjAgKyBNYXRoLmNvcyh4Um90YXRpb24pICogY3hwIC0gTWF0aC5zaW4oeFJvdGF0aW9uKSAqIGN5cDtcbiAgICB2YXIgY3kgPSAoeTEgKyB5MikgLyAyLjAgKyBNYXRoLnNpbih4Um90YXRpb24pICogY3hwICsgTWF0aC5jb3MoeFJvdGF0aW9uKSAqIGN5cDtcbiAgICAvLyDotbflp4vngrnnmoTljZXkvY3lkJHph49cbiAgICB2YXIgdSA9IFsoeHAgLSBjeHApIC8gcngsICh5cCAtIGN5cCkgLyByeV07XG4gICAgLy8g57uI5q2i54K555qE5Y2V5L2N5ZCR6YePXG4gICAgdmFyIHYgPSBbKC0xICogeHAgLSBjeHApIC8gcngsICgtMSAqIHlwIC0gY3lwKSAvIHJ5XTtcbiAgICAvLyDorqHnrpfotbflp4vngrnlkozlnIblv4PnmoTov57nur/vvIzkuI4geCDovbTmraPmlrnlkJHnmoTlpLnop5JcbiAgICB2YXIgdGhldGEgPSB2QW5nbGUoWzEsIDBdLCB1KTtcbiAgICAvLyDorqHnrpflnIblvKfotbflp4vngrnlkoznu4jmraLngrnkuI7mpK3lnIblnIblv4Pov57nur/nmoTlpLnop5JcbiAgICB2YXIgZFRoZXRhID0gdkFuZ2xlKHUsIHYpO1xuICAgIGlmICh2UmF0aW8odSwgdikgPD0gLTEpIHtcbiAgICAgICAgZFRoZXRhID0gTWF0aC5QSTtcbiAgICB9XG4gICAgaWYgKHZSYXRpbyh1LCB2KSA+PSAxKSB7XG4gICAgICAgIGRUaGV0YSA9IDA7XG4gICAgfVxuICAgIGlmIChzd2VlcEZsYWcgPT09IDAgJiYgZFRoZXRhID4gMCkge1xuICAgICAgICBkVGhldGEgPSBkVGhldGEgLSAyICogTWF0aC5QSTtcbiAgICB9XG4gICAgaWYgKHN3ZWVwRmxhZyA9PT0gMSAmJiBkVGhldGEgPCAwKSB7XG4gICAgICAgIGRUaGV0YSA9IGRUaGV0YSArIDIgKiBNYXRoLlBJO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBjeDogY3gsXG4gICAgICAgIGN5OiBjeSxcbiAgICAgICAgLy8g5byn5b2i55qE6LW354K55ZKM57uI54K555u45ZCM5pe277yM6ZW/6L205ZKM55+t6L2055qE6ZW/5bqm5oyJIDAg5aSE55CGXG4gICAgICAgIHJ4OiB1dGlsXzEuaXNTYW1lUG9pbnQoc3RhcnRQb2ludCwgW3gyLCB5Ml0pID8gMCA6IHJ4LFxuICAgICAgICByeTogdXRpbF8xLmlzU2FtZVBvaW50KHN0YXJ0UG9pbnQsIFt4MiwgeTJdKSA/IDAgOiByeSxcbiAgICAgICAgc3RhcnRBbmdsZTogdGhldGEsXG4gICAgICAgIGVuZEFuZ2xlOiB0aGV0YSArIGRUaGV0YSxcbiAgICAgICAgeFJvdGF0aW9uOiB4Um90YXRpb24sXG4gICAgICAgIGFyY0ZsYWc6IGFyY0ZsYWcsXG4gICAgICAgIHN3ZWVwRmxhZzogc3dlZXBGbGFnLFxuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBnZXRBcmNQYXJhbXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hcmMtcGFyYW1zLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5hZGRFbmRBcnJvdyA9IGV4cG9ydHMuYWRkU3RhcnRBcnJvdyA9IGV4cG9ydHMuZ2V0U2hvcnRlbk9mZnNldCA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHNoYXBlXzEgPSByZXF1aXJlKFwiLi4vc2hhcGVcIik7XG52YXIgc2luID0gTWF0aC5zaW4sIGNvcyA9IE1hdGguY29zLCBhdGFuMiA9IE1hdGguYXRhbjIsIFBJID0gTWF0aC5QSTtcbmZ1bmN0aW9uIF9hZGREZWZhdWx0QXJyb3coc2hhcGUsIGF0dHJzLCB4MSwgeTEsIHgyLCB5MiwgaXNTdGFydCkge1xuICAgIHZhciBzdHJva2UgPSBhdHRycy5zdHJva2UsIGxpbmVXaWR0aCA9IGF0dHJzLmxpbmVXaWR0aDtcbiAgICB2YXIgeCA9IHgxIC0geDI7XG4gICAgdmFyIHkgPSB5MSAtIHkyO1xuICAgIHZhciByYWQgPSBhdGFuMih5LCB4KTtcbiAgICB2YXIgYXJyb3dTaGFwZSA9IG5ldyBzaGFwZV8xLlBhdGgoe1xuICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgIGNhbnZhczogc2hhcGUuZ2V0KCdjYW52YXMnKSxcbiAgICAgICAgaXNBcnJvd1NoYXBlOiB0cnVlLFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgLy8g6buY6K6k566t5aS055qE6L656ZW/5Li6IDEw77yM5aS56KeS5Li6IDYwIOW6plxuICAgICAgICAgICAgcGF0aDogXCJNXCIgKyAxMCAqIGNvcyhQSSAvIDYpICsgXCIsXCIgKyAxMCAqIHNpbihQSSAvIDYpICsgXCIgTDAsMCBMXCIgKyAxMCAqIGNvcyhQSSAvIDYpICsgXCIsLVwiICsgMTAgKiBzaW4oUEkgLyA2KSxcbiAgICAgICAgICAgIC8vIOS9v+eUqCBzaGFwZSBzdHJva2Ug5YC8XG4gICAgICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgICAgIGxpbmVXaWR0aDogbGluZVdpZHRoLFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIGFycm93U2hhcGUudHJhbnNsYXRlKHgyLCB5Mik7XG4gICAgYXJyb3dTaGFwZS5yb3RhdGVBdFBvaW50KHgyLCB5MiwgcmFkKTtcbiAgICBzaGFwZS5zZXQoaXNTdGFydCA/ICdzdGFydEFycm93U2hhcGUnIDogJ2VuZEFycm93U2hhcGUnLCBhcnJvd1NoYXBlKTtcbn1cbi8qKlxuICog566t5aS0IHBhdGgg55qE6K6+572u6KaB5rGCXG4gKiAxLiDnrq3lpLTpobbngrnlnZDmoIfpnIDopoHkuLogKDAsIDApXG4gKiAyLiDnrq3lpLTlpLnop5LnmoTkuK3lv4PliIblibLnur/pnIDopoHkuI4gWCDovbTmraPmlrnlkJHlr7npvZBcbiAqL1xuZnVuY3Rpb24gX2FkZEN1c3RvbWl6ZWRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyLCBpc1N0YXJ0KSB7XG4gICAgdmFyIHN0YXJ0QXJyb3cgPSBhdHRycy5zdGFydEFycm93LCBlbmRBcnJvdyA9IGF0dHJzLmVuZEFycm93LCBzdHJva2UgPSBhdHRycy5zdHJva2UsIGxpbmVXaWR0aCA9IGF0dHJzLmxpbmVXaWR0aDtcbiAgICB2YXIgYXJyb3dBdHRycyA9IGlzU3RhcnQgPyBzdGFydEFycm93IDogZW5kQXJyb3c7XG4gICAgdmFyIGQgPSBhcnJvd0F0dHJzLmQsIGFycm93RmlsbCA9IGFycm93QXR0cnMuZmlsbCwgYXJyb3dTdHJva2UgPSBhcnJvd0F0dHJzLnN0cm9rZSwgYXJyb3dMaW5lV2lkdGggPSBhcnJvd0F0dHJzLmxpbmVXaWR0aCwgcmVzdEF0dHJzID0gdHNsaWJfMS5fX3Jlc3QoYXJyb3dBdHRycywgW1wiZFwiLCBcImZpbGxcIiwgXCJzdHJva2VcIiwgXCJsaW5lV2lkdGhcIl0pO1xuICAgIHZhciB4ID0geDEgLSB4MjtcbiAgICB2YXIgeSA9IHkxIC0geTI7XG4gICAgdmFyIHJhZCA9IGF0YW4yKHksIHgpO1xuICAgIGlmIChkKSB7XG4gICAgICAgIHgyID0geDIgLSBjb3MocmFkKSAqIGQ7XG4gICAgICAgIHkyID0geTIgLSBzaW4ocmFkKSAqIGQ7XG4gICAgfVxuICAgIHZhciBhcnJvd1NoYXBlID0gbmV3IHNoYXBlXzEuUGF0aCh7XG4gICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgY2FudmFzOiBzaGFwZS5nZXQoJ2NhbnZhcycpLFxuICAgICAgICBpc0Fycm93U2hhcGU6IHRydWUsXG4gICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHJlc3RBdHRycyksIHsgXG4gICAgICAgICAgICAvLyDmlK/mjIHljZXni6zorr7nva7nrq3lpLTnmoQgc3Ryb2tlIOWSjCBsaW5lV2lkdGjvvIzoi6XkuLrnqbrliJnkvb/nlKggc2hhcGUg55qE5YC8XG4gICAgICAgICAgICBzdHJva2U6IGFycm93U3Ryb2tlIHx8IHN0cm9rZSwgbGluZVdpZHRoOiBhcnJvd0xpbmVXaWR0aCB8fCBsaW5lV2lkdGgsIFxuICAgICAgICAgICAgLy8g566t5aS05piv5ZCm5aGr5YWF6ZyA6KaB5omL5Yqo6K6+572u77yM5LiN5Lya57un5om/6IeqIHNoYXBlIOeahOWAvFxuICAgICAgICAgICAgZmlsbDogYXJyb3dGaWxsIH0pLFxuICAgIH0pO1xuICAgIGFycm93U2hhcGUudHJhbnNsYXRlKHgyLCB5Mik7XG4gICAgYXJyb3dTaGFwZS5yb3RhdGVBdFBvaW50KHgyLCB5MiwgcmFkKTtcbiAgICBzaGFwZS5zZXQoaXNTdGFydCA/ICdzdGFydEFycm93U2hhcGUnIDogJ2VuZEFycm93U2hhcGUnLCBhcnJvd1NoYXBlKTtcbn1cbi8qKlxuICog5aaC5p6c6Ieq5a6a5LmJ566t5aS05bm25LiU5pyJIGQg6ZyA6KaB5YGa5YGP56e777yM5aaC5p6c55u05o6l55S777yM57q/5p2h5Lya6LaF5Ye6566t5aS05bCW56uv77yM5Zug5q2k6ZyA6KaB5qC55o2u566t5aS05YGP56e7IGQsIOi/lOWbnue6v+mcgOimgee8qeefreeahOi3neemu1xuICogfC0tLS0tLS0tLS0tLS0tLS1cbiAqIHw8fC0tLS0tLS0tLS0tLS0tXG4gKiB8XG4gKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICogQHBhcmFtIHtudW1iZXJ9IHgyIOeureWktOS9nOeUqOeCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTIg566t5aS05L2c55So54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSBkICDnrq3lpLTmsr/nur/mnaHmlrnlkJHnmoTlgY/np7vot53nprtcbiAqIEByZXR1cm4ge3tkeDogbnVtYmVyLCBkeTogbnVtYmVyfX0g6L+U5Zue57q/5p2h5YGP56e76Led56a7XG4gKi9cbmZ1bmN0aW9uIGdldFNob3J0ZW5PZmZzZXQoeDEsIHkxLCB4MiwgeTIsIGQpIHtcbiAgICB2YXIgcmFkID0gYXRhbjIoeTIgLSB5MSwgeDIgLSB4MSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZHg6IGNvcyhyYWQpICogZCxcbiAgICAgICAgZHk6IHNpbihyYWQpICogZCxcbiAgICB9O1xufVxuZXhwb3J0cy5nZXRTaG9ydGVuT2Zmc2V0ID0gZ2V0U2hvcnRlbk9mZnNldDtcbi8qKlxuICog57uY5Yi26LW35aeL566t5aS0XG4gKiBAcGFyYW0ge0lTaGFwZX0gc2hhcGUg5Zu+5b2iXG4gKiBAcGFyYW0ge1NoYXBlQXR0cnN9IGF0dHJzIHNoYXBlIOeahOe7mOWbvuWxnuaAp1xuICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnrq3lpLTkvZznlKjngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkyIOeureWktOS9nOeUqOeCuSB5XG4gKi9cbmZ1bmN0aW9uIGFkZFN0YXJ0QXJyb3coc2hhcGUsIGF0dHJzLCB4MSwgeTEsIHgyLCB5Mikge1xuICAgIGlmICh0eXBlb2YgYXR0cnMuc3RhcnRBcnJvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgX2FkZEN1c3RvbWl6ZWRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyLCB0cnVlKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoYXR0cnMuc3RhcnRBcnJvdykge1xuICAgICAgICBfYWRkRGVmYXVsdEFycm93KHNoYXBlLCBhdHRycywgeDEsIHkxLCB4MiwgeTIsIHRydWUpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2hhcGUuc2V0KCdzdGFydEFycm93U2hhcGUnLCBudWxsKTtcbiAgICB9XG59XG5leHBvcnRzLmFkZFN0YXJ0QXJyb3cgPSBhZGRTdGFydEFycm93O1xuLyoqXG4gKiDnu5jliLbnu5PmnZ/nrq3lpLRcbiAqIEBwYXJhbSB7SVNoYXBlfSBzaGFwZSDlm77lvaJcbiAqIEBwYXJhbSB7U2hhcGVBdHRyc30gYXR0cnMgc2hhcGUg55qE57uY5Zu+5bGe5oCnXG4gKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICogQHBhcmFtIHtudW1iZXJ9IHgyIOeureWktOS9nOeUqOeCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTIg566t5aS05L2c55So54K5IHlcbiAqL1xuZnVuY3Rpb24gYWRkRW5kQXJyb3coc2hhcGUsIGF0dHJzLCB4MSwgeTEsIHgyLCB5Mikge1xuICAgIGlmICh0eXBlb2YgYXR0cnMuZW5kQXJyb3cgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIF9hZGRDdXN0b21pemVkQXJyb3coc2hhcGUsIGF0dHJzLCB4MSwgeTEsIHgyLCB5MiwgZmFsc2UpO1xuICAgIH1cbiAgICBlbHNlIGlmIChhdHRycy5lbmRBcnJvdykge1xuICAgICAgICBfYWRkRGVmYXVsdEFycm93KHNoYXBlLCBhdHRycywgeDEsIHkxLCB4MiwgeTIsIGZhbHNlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNoYXBlLnNldCgnc3RhcnRBcnJvd1NoYXBlJywgbnVsbCk7XG4gICAgfVxufVxuZXhwb3J0cy5hZGRFbmRBcnJvdyA9IGFkZEVuZEFycm93O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXJyb3cuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm1lcmdlVmlldyA9IGV4cG9ydHMuZ2V0TWVyZ2VkUmVnaW9uID0gZXhwb3J0cy5nZXRSZWZyZXNoUmVnaW9uID0gZXhwb3J0cy5yZWZyZXNoRWxlbWVudCA9IGV4cG9ydHMuZHJhd1BhdGggPSBleHBvcnRzLmRyYXdDaGlsZHJlbiA9IGV4cG9ydHMuYXBwbHlBdHRyc1RvQ29udGV4dCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwYXJzZV8xID0gcmVxdWlyZShcIi4vcGFyc2VcIik7XG52YXIgYXJjX3BhcmFtc18xID0gcmVxdWlyZShcIi4vYXJjLXBhcmFtc1wiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xudmFyIEFycm93VXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL2Fycm93XCIpO1xudmFyIFNIQVBFX0FUVFJTX01BUCA9IHtcbiAgICBmaWxsOiAnZmlsbFN0eWxlJyxcbiAgICBzdHJva2U6ICdzdHJva2VTdHlsZScsXG4gICAgb3BhY2l0eTogJ2dsb2JhbEFscGhhJyxcbn07XG5mdW5jdGlvbiBhcHBseUF0dHJzVG9Db250ZXh0KGNvbnRleHQsIGVsZW1lbnQpIHtcbiAgICB2YXIgYXR0cnMgPSBlbGVtZW50LmF0dHIoKTtcbiAgICBmb3IgKHZhciBrIGluIGF0dHJzKSB7XG4gICAgICAgIHZhciB2ID0gYXR0cnNba107XG4gICAgICAgIC8vIOi9rOaNouS4gOS4i+S4jeS4jiBjYW52YXMg5YW85a6555qE5bGe5oCn5ZCNXG4gICAgICAgIHZhciBuYW1lXzEgPSBTSEFQRV9BVFRSU19NQVBba10gPyBTSEFQRV9BVFRSU19NQVBba10gOiBrO1xuICAgICAgICBpZiAobmFtZV8xID09PSAnbWF0cml4JyAmJiB2KSB7XG4gICAgICAgICAgICAvLyDorr7nva7nn6npmLVcbiAgICAgICAgICAgIGNvbnRleHQudHJhbnNmb3JtKHZbMF0sIHZbMV0sIHZbM10sIHZbNF0sIHZbNl0sIHZbN10pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5hbWVfMSA9PT0gJ2xpbmVEYXNoJyAmJiBjb250ZXh0LnNldExpbmVEYXNoKSB7XG4gICAgICAgICAgICAvLyDorr7nva7omZrnur/vvIzlj6rmlK/mjIHmlbDnu4TlvaLlvI/vvIzpnZ7mlbDnu4TlvaLlvI/kuI3lgZrku7vkvZXmk43kvZxcbiAgICAgICAgICAgIHV0aWxfMS5pc0FycmF5KHYpICYmIGNvbnRleHQuc2V0TGluZURhc2godik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAobmFtZV8xID09PSAnc3Ryb2tlU3R5bGUnIHx8IG5hbWVfMSA9PT0gJ2ZpbGxTdHlsZScpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzlrZjlnKjmuJDlj5jjgIFwYXR0ZXJuIOi/meS4quW8gOmUgOacieS6m+Wkp1xuICAgICAgICAgICAgICAgIC8vIOWPr+S7peiAg+iZkee8k+WtmOacuuWItu+8jOmAmui/hyBoYXNVcGRhdGUg5p2l6YG/5YWN5LiA5Lqb6L+Q566XXG4gICAgICAgICAgICAgICAgdiA9IHBhcnNlXzEucGFyc2VTdHlsZShjb250ZXh0LCBlbGVtZW50LCB2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG5hbWVfMSA9PT0gJ2dsb2JhbEFscGhhJykge1xuICAgICAgICAgICAgICAgIC8vIG9wYWNpdHkg5pWI5p6c5Y+v5Lul5Y+g5Yqg77yM5a2Q5YWD57Sg55qEIG9wYWNpdHkg6ZyA6KaB5LiO54i25YWD57SgIG9wYWNpdHkg55u45LmYXG4gICAgICAgICAgICAgICAgdiA9IHYgKiBjb250ZXh0Lmdsb2JhbEFscGhhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGV4dFtuYW1lXzFdID0gdjtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydHMuYXBwbHlBdHRyc1RvQ29udGV4dCA9IGFwcGx5QXR0cnNUb0NvbnRleHQ7XG5mdW5jdGlvbiBkcmF3Q2hpbGRyZW4oY29udGV4dCwgY2hpbGRyZW4sIHJlZ2lvbikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgICAgIGlmIChjaGlsZC5nZXQoJ3Zpc2libGUnKSkge1xuICAgICAgICAgICAgY2hpbGQuZHJhdyhjb250ZXh0LCByZWdpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2hpbGQuc2tpcERyYXcoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydHMuZHJhd0NoaWxkcmVuID0gZHJhd0NoaWxkcmVuO1xuLy8g57uY5Yi2IHBhdGhcbmZ1bmN0aW9uIGRyYXdQYXRoKHNoYXBlLCBjb250ZXh0LCBhdHRycywgYXJjUGFyYW1zQ2FjaGUpIHtcbiAgICB2YXIgcGF0aCA9IGF0dHJzLnBhdGgsIHN0YXJ0QXJyb3cgPSBhdHRycy5zdGFydEFycm93LCBlbmRBcnJvdyA9IGF0dHJzLmVuZEFycm93O1xuICAgIHZhciBjdXJyZW50UG9pbnQgPSBbMCwgMF07IC8vIOW9k+WJjeWbvuW9olxuICAgIHZhciBzdGFydE1vdmVQb2ludCA9IFswLCAwXTsgLy8g5byA5aeLIE0g55qE54K577yM5Y+v6IO95Lya5pyJ5aSa5LiqXG4gICAgdmFyIGRpc3RhbmNlID0ge1xuICAgICAgICBkeDogMCxcbiAgICAgICAgZHk6IDAsXG4gICAgfTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcGFyYW1zID0gcGF0aFtpXTtcbiAgICAgICAgdmFyIGNvbW1hbmQgPSBwYXJhbXNbMF07XG4gICAgICAgIGlmIChpID09PSAwICYmIHN0YXJ0QXJyb3cgJiYgc3RhcnRBcnJvdy5kKSB7XG4gICAgICAgICAgICB2YXIgdGFuZ2VudCA9IHNoYXBlLmdldFN0YXJ0VGFuZ2VudCgpO1xuICAgICAgICAgICAgZGlzdGFuY2UgPSBBcnJvd1V0aWwuZ2V0U2hvcnRlbk9mZnNldCh0YW5nZW50WzBdWzBdLCB0YW5nZW50WzBdWzFdLCB0YW5nZW50WzFdWzBdLCB0YW5nZW50WzFdWzFdLCBzdGFydEFycm93LmQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGkgPT09IHBhdGgubGVuZ3RoIC0gMiAmJiBwYXRoW2kgKyAxXVswXSA9PT0gJ1onICYmIGVuZEFycm93ICYmIGVuZEFycm93LmQpIHtcbiAgICAgICAgICAgIC8vIOS4uuS6humYsuatoue7k+WwvuS4uiBaIOeahCBzZWdtZW50IOe8qeefreS4jei1t+aViO+8jOmcgOimgeWPluacgOWQjuS4pOS4qiBzZWdtZW50IOeJueauiuWkhOeQhlxuICAgICAgICAgICAgdmFyIGxhc3RQYXRoID0gcGF0aFtpICsgMV07XG4gICAgICAgICAgICBpZiAobGFzdFBhdGhbMF0gPT09ICdaJykge1xuICAgICAgICAgICAgICAgIHZhciB0YW5nZW50ID0gc2hhcGUuZ2V0RW5kVGFuZ2VudCgpO1xuICAgICAgICAgICAgICAgIGRpc3RhbmNlID0gQXJyb3dVdGlsLmdldFNob3J0ZW5PZmZzZXQodGFuZ2VudFswXVswXSwgdGFuZ2VudFswXVsxXSwgdGFuZ2VudFsxXVswXSwgdGFuZ2VudFsxXVsxXSwgZW5kQXJyb3cuZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaSA9PT0gcGF0aC5sZW5ndGggLSAxICYmIGVuZEFycm93ICYmIGVuZEFycm93LmQpIHtcbiAgICAgICAgICAgIGlmIChwYXRoWzBdICE9PSAnWicpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFuZ2VudCA9IHNoYXBlLmdldEVuZFRhbmdlbnQoKTtcbiAgICAgICAgICAgICAgICBkaXN0YW5jZSA9IEFycm93VXRpbC5nZXRTaG9ydGVuT2Zmc2V0KHRhbmdlbnRbMF1bMF0sIHRhbmdlbnRbMF1bMV0sIHRhbmdlbnRbMV1bMF0sIHRhbmdlbnRbMV1bMV0sIGVuZEFycm93LmQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBkeCA9IGRpc3RhbmNlLmR4LCBkeSA9IGRpc3RhbmNlLmR5O1xuICAgICAgICAvLyBWLEgsUyxUIOmDveWcqOWJjemdouiiq+i9rOaNouaIkOagh+WHhuW9ouW8j1xuICAgICAgICBzd2l0Y2ggKGNvbW1hbmQpIHtcbiAgICAgICAgICAgIGNhc2UgJ00nOlxuICAgICAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKHBhcmFtc1sxXSAtIGR4LCBwYXJhbXNbMl0gLSBkeSk7XG4gICAgICAgICAgICAgICAgc3RhcnRNb3ZlUG9pbnQgPSBbcGFyYW1zWzFdLCBwYXJhbXNbMl1dO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICAgICAgY29udGV4dC5saW5lVG8ocGFyYW1zWzFdIC0gZHgsIHBhcmFtc1syXSAtIGR5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgICAgICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbyhwYXJhbXNbMV0sIHBhcmFtc1syXSwgcGFyYW1zWzNdIC0gZHgsIHBhcmFtc1s0XSAtIGR5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0MnOlxuICAgICAgICAgICAgICAgIGNvbnRleHQuYmV6aWVyQ3VydmVUbyhwYXJhbXNbMV0sIHBhcmFtc1syXSwgcGFyYW1zWzNdLCBwYXJhbXNbNF0sIHBhcmFtc1s1XSAtIGR4LCBwYXJhbXNbNl0gLSBkeSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdBJzoge1xuICAgICAgICAgICAgICAgIHZhciBhcmNQYXJhbXMgPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgLy8g5Li65LqG5Yqg6YCf57uY5Yi277yM5Y+v5Lul5o+Q5L6b5Y+C5pWw55qE57yT5a2Y77yM5ZCE5Liq5Zu+5b2i6Ieq5bex57yT5a2YXG4gICAgICAgICAgICAgICAgaWYgKGFyY1BhcmFtc0NhY2hlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFyY1BhcmFtcyA9IGFyY1BhcmFtc0NhY2hlW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFyY1BhcmFtcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJjUGFyYW1zID0gYXJjX3BhcmFtc18xLmRlZmF1bHQoY3VycmVudFBvaW50LCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJjUGFyYW1zQ2FjaGVbaV0gPSBhcmNQYXJhbXM7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFyY1BhcmFtcyA9IGFyY19wYXJhbXNfMS5kZWZhdWx0KGN1cnJlbnRQb2ludCwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGN4ID0gYXJjUGFyYW1zLmN4LCBjeSA9IGFyY1BhcmFtcy5jeSwgcnggPSBhcmNQYXJhbXMucngsIHJ5ID0gYXJjUGFyYW1zLnJ5LCBzdGFydEFuZ2xlID0gYXJjUGFyYW1zLnN0YXJ0QW5nbGUsIGVuZEFuZ2xlID0gYXJjUGFyYW1zLmVuZEFuZ2xlLCB4Um90YXRpb24gPSBhcmNQYXJhbXMueFJvdGF0aW9uLCBzd2VlcEZsYWcgPSBhcmNQYXJhbXMuc3dlZXBGbGFnO1xuICAgICAgICAgICAgICAgIC8vIOebtOaOpeS9v+eUqOakreWchueahCBhcGlcbiAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5lbGxpcHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZWxsaXBzZShjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgMSAtIHN3ZWVwRmxhZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgciA9IHJ4ID4gcnkgPyByeCA6IHJ5O1xuICAgICAgICAgICAgICAgICAgICB2YXIgc2NhbGVYID0gcnggPiByeSA/IDEgOiByeCAvIHJ5O1xuICAgICAgICAgICAgICAgICAgICB2YXIgc2NhbGVZID0gcnggPiByeSA/IHJ5IC8gcnggOiAxO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnRyYW5zbGF0ZShjeCwgY3kpO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnJvdGF0ZSh4Um90YXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnNjYWxlKHNjYWxlWCwgc2NhbGVZKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5hcmMoMCwgMCwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIDEgLSBzd2VlcEZsYWcpO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnNjYWxlKDEgLyBzY2FsZVgsIDEgLyBzY2FsZVkpO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnJvdGF0ZSgteFJvdGF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC50cmFuc2xhdGUoLWN4LCAtY3kpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgJ1onOlxuICAgICAgICAgICAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vIOacieS6hiBaIOWQju+8jOW9k+WJjeiKgueCueS7juW8gOWniyBNIOeahOeCueW8gOWni1xuICAgICAgICBpZiAoY29tbWFuZCA9PT0gJ1onKSB7XG4gICAgICAgICAgICBjdXJyZW50UG9pbnQgPSBzdGFydE1vdmVQb2ludDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsZW4gPSBwYXJhbXMubGVuZ3RoO1xuICAgICAgICAgICAgY3VycmVudFBvaW50ID0gW3BhcmFtc1tsZW4gLSAyXSwgcGFyYW1zW2xlbiAtIDFdXTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydHMuZHJhd1BhdGggPSBkcmF3UGF0aDtcbi8vIOWIt+aWsOWbvuW9ouWFg+e0oChTaGFwZSDmiJbogIUgR3JvdXApXG5mdW5jdGlvbiByZWZyZXNoRWxlbWVudChlbGVtZW50LCBjaGFuZ2VUeXBlKSB7XG4gICAgdmFyIGNhbnZhcyA9IGVsZW1lbnQuZ2V0KCdjYW52YXMnKTtcbiAgICAvLyDlj6rmnInlrZjlnKjkuo4gY2FudmFzIOS4iuaXtueUn+aViFxuICAgIGlmIChjYW52YXMpIHtcbiAgICAgICAgaWYgKGNoYW5nZVR5cGUgPT09ICdyZW1vdmUnKSB7XG4gICAgICAgICAgICAvLyDkuIDml6YgcmVtb3Zl77yM5YiZ5peg5rOV5ZyoIGVsZW1lbnQg5LiK5ou/5Yiw5YyF5Zu055uSXG4gICAgICAgICAgICAvLyBkZXN0cm95IOWQjuaJgOacieWxnuaAp+mDveaLv+S4jeWIsO+8jOaJgOS7pemcgOimgeaaguWtmOS4gOS4i1xuICAgICAgICAgICAgLy8g6L+Z5piv5LiA5q61IGhhY2sg55qE5Luj56CBXG4gICAgICAgICAgICBlbGVtZW50Ll9jYWNoZUNhbnZhc0JCb3ggPSBlbGVtZW50LmdldCgnY2FjaGVDYW52YXNCQm94Jyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6Ziy5q2i5Y+N5aSN5Yi35pawXG4gICAgICAgIGlmICghZWxlbWVudC5nZXQoJ2hhc0NoYW5nZWQnKSkge1xuICAgICAgICAgICAgLy8g5pys5p2l5Y+q5pyJ5bGA6YOo5riy5p+T5qih5byP5LiL77yM5omN6ZyA6KaB6K6w5b2V5pu05paw55qE5YWD57Sg6Zif5YiXXG4gICAgICAgICAgICAvLyBpZiAoY2FudmFzLmdldCgnbG9jYWxSZWZyZXNoJykpIHtcbiAgICAgICAgICAgIC8vICAgY2FudmFzLnJlZnJlc2hFbGVtZW50KGVsZW1lbnQsIGNoYW5nZVR5cGUsIGNhbnZhcyk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAvLyDkvYblr7nkuo4gaHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy9nL2lzc3Vlcy80MjIg55qE5Zy65pmv77yM5YWo5bGA5riy5p+T55qE5qih5byP5LiL5Lmf6ZyA6KaB6K6w5b2V5pu05paw55qE5YWD57Sg6Zif5YiXXG4gICAgICAgICAgICBjYW52YXMucmVmcmVzaEVsZW1lbnQoZWxlbWVudCwgY2hhbmdlVHlwZSwgY2FudmFzKTtcbiAgICAgICAgICAgIGlmIChjYW52YXMuZ2V0KCdhdXRvRHJhdycpKSB7XG4gICAgICAgICAgICAgICAgY2FudmFzLmRyYXcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsZW1lbnQuc2V0KCdoYXNDaGFuZ2VkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnRzLnJlZnJlc2hFbGVtZW50ID0gcmVmcmVzaEVsZW1lbnQ7XG5mdW5jdGlvbiBnZXRSZWZyZXNoUmVnaW9uKGVsZW1lbnQpIHtcbiAgICB2YXIgcmVnaW9uO1xuICAgIGlmICghZWxlbWVudC5kZXN0cm95ZWQpIHtcbiAgICAgICAgdmFyIGNhY2hlQm94ID0gZWxlbWVudC5nZXQoJ2NhY2hlQ2FudmFzQkJveCcpO1xuICAgICAgICB2YXIgdmFsaWRDYWNoZSA9IGNhY2hlQm94ICYmICEhKGNhY2hlQm94LndpZHRoICYmIGNhY2hlQm94LmhlaWdodCk7XG4gICAgICAgIHZhciBiYm94ID0gZWxlbWVudC5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgIHZhciB2YWxpZEJCb3ggPSBiYm94ICYmICEhKGJib3gud2lkdGggJiYgYmJveC5oZWlnaHQpO1xuICAgICAgICAvLyDmmK/lkKbmmK/mnInmlYggYmJveCDliKTlrprvvIzkuIDkupsgTmFOIOaIluiAhSDlrr3pq5jkuLogMCDnmoTmg4XlhrXov4fmu6TmjolcbiAgICAgICAgaWYgKHZhbGlkQ2FjaGUgJiYgdmFsaWRCQm94KSB7XG4gICAgICAgICAgICByZWdpb24gPSB1dGlsXzIubWVyZ2VSZWdpb24oY2FjaGVCb3gsIGJib3gpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZhbGlkQ2FjaGUpIHtcbiAgICAgICAgICAgIHJlZ2lvbiA9IGNhY2hlQm94O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZhbGlkQkJveCkge1xuICAgICAgICAgICAgcmVnaW9uID0gYmJveDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g5Zug5Li65YWD57Sg5bey57uP6ZSA5q+B5omA5Lul5peg5rOV6I635Y+W5Yiw57yT5a2Y55qE5YyF5Zu055uSXG4gICAgICAgIHJlZ2lvbiA9IGVsZW1lbnRbJ19jYWNoZUNhbnZhc0JCb3gnXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlZ2lvbjtcbn1cbmV4cG9ydHMuZ2V0UmVmcmVzaFJlZ2lvbiA9IGdldFJlZnJlc2hSZWdpb247XG5mdW5jdGlvbiBnZXRNZXJnZWRSZWdpb24oZWxlbWVudHMpIHtcbiAgICBpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIG1pblhBcnIgPSBbXTtcbiAgICB2YXIgbWluWUFyciA9IFtdO1xuICAgIHZhciBtYXhYQXJyID0gW107XG4gICAgdmFyIG1heFlBcnIgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHZhciByZWdpb24gPSBnZXRSZWZyZXNoUmVnaW9uKGVsKTtcbiAgICAgICAgaWYgKHJlZ2lvbikge1xuICAgICAgICAgICAgbWluWEFyci5wdXNoKHJlZ2lvbi5taW5YKTtcbiAgICAgICAgICAgIG1pbllBcnIucHVzaChyZWdpb24ubWluWSk7XG4gICAgICAgICAgICBtYXhYQXJyLnB1c2gocmVnaW9uLm1heFgpO1xuICAgICAgICAgICAgbWF4WUFyci5wdXNoKHJlZ2lvbi5tYXhZKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIG1pblg6IE1hdGgubWluLmFwcGx5KG51bGwsIG1pblhBcnIpLFxuICAgICAgICBtaW5ZOiBNYXRoLm1pbi5hcHBseShudWxsLCBtaW5ZQXJyKSxcbiAgICAgICAgbWF4WDogTWF0aC5tYXguYXBwbHkobnVsbCwgbWF4WEFyciksXG4gICAgICAgIG1heFk6IE1hdGgubWF4LmFwcGx5KG51bGwsIG1heFlBcnIpLFxuICAgIH07XG59XG5leHBvcnRzLmdldE1lcmdlZFJlZ2lvbiA9IGdldE1lcmdlZFJlZ2lvbjtcbmZ1bmN0aW9uIG1lcmdlVmlldyhyZWdpb24sIHZpZXdSZWdpb24pIHtcbiAgICBpZiAoIXJlZ2lvbiB8fCAhdmlld1JlZ2lvbikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8g5LiN55u45Lqk77yM5YiZ55u05o6l6L+U5ZueIG51bGxcbiAgICBpZiAoIXV0aWxfMi5pbnRlcnNlY3RSZWN0KHJlZ2lvbiwgdmlld1JlZ2lvbikpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIG1pblg6IE1hdGgubWF4KHJlZ2lvbi5taW5YLCB2aWV3UmVnaW9uLm1pblgpLFxuICAgICAgICBtaW5ZOiBNYXRoLm1heChyZWdpb24ubWluWSwgdmlld1JlZ2lvbi5taW5ZKSxcbiAgICAgICAgbWF4WDogTWF0aC5taW4ocmVnaW9uLm1heFgsIHZpZXdSZWdpb24ubWF4WCksXG4gICAgICAgIG1heFk6IE1hdGgubWluKHJlZ2lvbi5tYXhZLCB2aWV3UmVnaW9uLm1heFkpLFxuICAgIH07XG59XG5leHBvcnRzLm1lcmdlVmlldyA9IG1lcmdlVmlldztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRyYXcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFNoYXBlID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2UvbGliL3V0aWwvdXRpbFwiKTtcbnZhciBtYXRyaXhfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2UvbGliL3V0aWwvbWF0cml4XCIpO1xuZnVuY3Rpb24gaW52ZXJ0RnJvbU1hdHJpeCh2LCBtYXRyaXgpIHtcbiAgICBpZiAobWF0cml4KSB7XG4gICAgICAgIHZhciBpbnZlcnRNYXRyaXggPSBtYXRyaXhfMS5pbnZlcnQobWF0cml4KTtcbiAgICAgICAgcmV0dXJuIG1hdHJpeF8xLm11bHRpcGx5VmVjMihpbnZlcnRNYXRyaXgsIHYpO1xuICAgIH1cbiAgICByZXR1cm4gdjtcbn1cbmZ1bmN0aW9uIGdldFJlZlhZKGVsZW1lbnQsIHgsIHkpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdmFyIHRvdGFsTWF0cml4ID0gZWxlbWVudC5nZXRUb3RhbE1hdHJpeCgpO1xuICAgIGlmICh0b3RhbE1hdHJpeCkge1xuICAgICAgICB2YXIgX2EgPSBpbnZlcnRGcm9tTWF0cml4KFt4LCB5LCAxXSwgdG90YWxNYXRyaXgpLCByZWZYID0gX2FbMF0sIHJlZlkgPSBfYVsxXTtcbiAgICAgICAgcmV0dXJuIFtyZWZYLCByZWZZXTtcbiAgICB9XG4gICAgcmV0dXJuIFt4LCB5XTtcbn1cbi8vIOaLvuWPluWJjeeahOajgOa1i++8jOWPquaciemAmui/h+ajgOa1i+aJjeiDvee7p+e7reaLvuWPllxuZnVuY3Rpb24gcHJlVGVzdChlbGVtZW50LCB4LCB5KSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGlmIChlbGVtZW50LmlzQ2FudmFzICYmIGVsZW1lbnQuaXNDYW52YXMoKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8g5LiN5YWB6K646KKr5ou+5Y+W77yM5YiZ6L+U5ZueIG51bGxcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgaWYgKCF1dGlsXzEuaXNBbGxvd0NhcHR1cmUoZWxlbWVudCkgJiYgZWxlbWVudC5jZmcuaXNJblZpZXcgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGVsZW1lbnQuY2ZnLmNsaXBTaGFwZSkge1xuICAgICAgICAvLyDlpoLmnpzlrZjlnKggY2xpcFxuICAgICAgICB2YXIgX2EgPSBnZXRSZWZYWShlbGVtZW50LCB4LCB5KSwgcmVmWCA9IF9hWzBdLCByZWZZID0gX2FbMV07XG4gICAgICAgIGlmIChlbGVtZW50LmlzQ2xpcHBlZChyZWZYLCByZWZZKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEB0cy1pZ25vcmUg77yM6L+Z5Liq5Zyw5pa56LCD55So6L+H5LqO6aKR57mBXG4gICAgdmFyIGJib3ggPSBlbGVtZW50LmNmZy5jYWNoZUNhbnZhc0JCb3g7XG4gICAgaWYgKCFiYm94KSB7XG4gICAgICAgIGJib3ggPSBlbGVtZW50LmdldENhbnZhc0JCb3goKTtcbiAgICB9XG4gICAgaWYgKCEoeCA+PSBiYm94Lm1pblggJiYgeCA8PSBiYm94Lm1heFggJiYgeSA+PSBiYm94Lm1pblkgJiYgeSA8PSBiYm94Lm1heFkpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBnZXRTaGFwZShjb250YWluZXIsIHgsIHkpIHtcbiAgICAvLyDmsqHmnInpgJrov4fmo4DmtYvvvIzliJnov5Tlm54gbnVsbFxuICAgIGlmICghcHJlVGVzdChjb250YWluZXIsIHgsIHkpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgc2hhcGUgPSBudWxsO1xuICAgIHZhciBjaGlsZHJlbiA9IGNvbnRhaW5lci5nZXRDaGlsZHJlbigpO1xuICAgIHZhciBjb3VudCA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gY291bnQgLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB2YXIgY2hpbGQgPSBjaGlsZHJlbltpXTtcbiAgICAgICAgaWYgKGNoaWxkLmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgc2hhcGUgPSBnZXRTaGFwZShjaGlsZCwgeCwgeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocHJlVGVzdChjaGlsZCwgeCwgeSkpIHtcbiAgICAgICAgICAgIHZhciBjdXJTaGFwZSA9IGNoaWxkO1xuICAgICAgICAgICAgdmFyIF9hID0gZ2V0UmVmWFkoY2hpbGQsIHgsIHkpLCByZWZYID0gX2FbMF0sIHJlZlkgPSBfYVsxXTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGlmIChjdXJTaGFwZS5pc0luU2hhcGUocmVmWCwgcmVmWSkpIHtcbiAgICAgICAgICAgICAgICBzaGFwZSA9IGNoaWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzaGFwZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNoYXBlO1xufVxuZXhwb3J0cy5nZXRTaGFwZSA9IGdldFNoYXBlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aGl0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIG9mZnNjcmVlbl8xID0gcmVxdWlyZShcIkBhbnR2L2ctYmFzZS9saWIvdXRpbC9vZmZzY3JlZW5cIik7XG5mdW5jdGlvbiBpc1BvaW50SW5QYXRoKHNoYXBlLCB4LCB5KSB7XG4gICAgdmFyIGN0eCA9IG9mZnNjcmVlbl8xLmdldE9mZlNjcmVlbkNvbnRleHQoKTtcbiAgICBzaGFwZS5jcmVhdGVQYXRoKGN0eCk7XG4gICAgcmV0dXJuIGN0eC5pc1BvaW50SW5QYXRoKHgsIHkpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gaXNQb2ludEluUGF0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvaW50LWluLXBhdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcg5Yik5pat54K55piv5ZCm5Zyo5aSa6L655b2i5YaFXG4gKiBAYXV0aG9yIGR4cTYxM0BnbWFpbC5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLy8g5aSa6L655b2i55qE5bCE57q/5qOA5rWL77yM5Y+C6ICD77yaaHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dpbGxpYW1TdW4wMTIyL2FydGljbGUvZGV0YWlscy83Nzk5NDUyNlxudmFyIHRvbGVyYW5jZSA9IDFlLTY7XG4vLyDkuInmgIHlh73mlbDvvIzliKTmlq3kuKTkuKpkb3VibGXlnKhlcHPnsr7luqbkuIvnmoTlpKflsI/lhbPns7tcbmZ1bmN0aW9uIGRjbXAoeCkge1xuICAgIGlmIChNYXRoLmFicyh4KSA8IHRvbGVyYW5jZSkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIHggPCAwID8gLTEgOiAxO1xufVxuLy8g5Yik5pat54K5UeaYr+WQpuWcqHAx5ZKMcDLnmoTnur/mrrXkuIpcbmZ1bmN0aW9uIG9uU2VnbWVudChwMSwgcDIsIHEpIHtcbiAgICBpZiAoKHFbMF0gLSBwMVswXSkgKiAocDJbMV0gLSBwMVsxXSkgPT09IChwMlswXSAtIHAxWzBdKSAqIChxWzFdIC0gcDFbMV0pICYmXG4gICAgICAgIE1hdGgubWluKHAxWzBdLCBwMlswXSkgPD0gcVswXSAmJlxuICAgICAgICBxWzBdIDw9IE1hdGgubWF4KHAxWzBdLCBwMlswXSkgJiZcbiAgICAgICAgTWF0aC5taW4ocDFbMV0sIHAyWzFdKSA8PSBxWzFdICYmXG4gICAgICAgIHFbMV0gPD0gTWF0aC5tYXgocDFbMV0sIHAyWzFdKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuLy8g5Yik5pat54K5UOWcqOWkmui+ueW9ouWGhS3lsITnur/ms5VcbmZ1bmN0aW9uIGlzSW5Qb2x5Z29uKHBvaW50cywgeCwgeSkge1xuICAgIHZhciBpc0hpdCA9IGZhbHNlO1xuICAgIHZhciBuID0gcG9pbnRzLmxlbmd0aDtcbiAgICBpZiAobiA8PSAyKSB7XG4gICAgICAgIC8vIHN2ZyDkuK3ngrnlsI/kuo4gMyDkuKrml7bvvIzkuI3mmL7npLrvvIzkuZ/ml6Dms5Xooqvmi77lj5ZcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47IGkrKykge1xuICAgICAgICB2YXIgcDEgPSBwb2ludHNbaV07XG4gICAgICAgIHZhciBwMiA9IHBvaW50c1soaSArIDEpICUgbl07XG4gICAgICAgIGlmIChvblNlZ21lbnQocDEsIHAyLCBbeCwgeV0pKSB7XG4gICAgICAgICAgICAvLyDngrnlnKjlpJrovrnlvaLkuIDmnaHovrnkuIpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWJjeS4gOS4quWIpOaWrW1pbihwMVsxXSxwMlsxXSk8UC55PD1tYXgocDFbMV0scDJbMV0pXG4gICAgICAgIC8vIOWQjuS4gOS4quWIpOaWreiiq+a1i+eCuSDlnKgg5bCE57q/5LiO6L655Lqk54K5IOeahOW3pui+uVxuICAgICAgICBpZiAoZGNtcChwMVsxXSAtIHkpID4gMCAhPT0gZGNtcChwMlsxXSAtIHkpID4gMCAmJlxuICAgICAgICAgICAgZGNtcCh4IC0gKCh5IC0gcDFbMV0pICogKHAxWzBdIC0gcDJbMF0pKSAvIChwMVsxXSAtIHAyWzFdKSAtIHAxWzBdKSA8IDApIHtcbiAgICAgICAgICAgIGlzSGl0ID0gIWlzSGl0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpc0hpdDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGlzSW5Qb2x5Z29uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cG9seWdvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGFyYyhjeCwgY3ksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBsaW5lV2lkdGgsIHgsIHkpIHtcbiAgICB2YXIgYW5nbGUgPSAoTWF0aC5hdGFuMih5IC0gY3ksIHggLSBjeCkgKyBNYXRoLlBJICogMikgJSAoTWF0aC5QSSAqIDIpOyAvLyDovazmjaLliLAgMCAtIDIgKiBNYXRoLlBJIOS5i+mXtFxuICAgIGlmIChhbmdsZSA8IHN0YXJ0QW5nbGUgfHwgYW5nbGUgPiBlbmRBbmdsZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBwb2ludCA9IHtcbiAgICAgICAgeDogY3ggKyByICogTWF0aC5jb3MoYW5nbGUpLFxuICAgICAgICB5OiBjeSArIHIgKiBNYXRoLnNpbihhbmdsZSksXG4gICAgfTtcbiAgICByZXR1cm4gdXRpbF8xLmRpc3RhbmNlKHBvaW50LngsIHBvaW50LnksIHgsIHkpIDw9IGxpbmVXaWR0aCAvIDI7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBhcmM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hcmMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIkBhbnR2L2ctbWF0aC9saWIvbGluZVwiKTtcbmZ1bmN0aW9uIGluTGluZSh4MSwgeTEsIHgyLCB5MiwgbGluZVdpZHRoLCB4LCB5KSB7XG4gICAgdmFyIG1pblggPSBNYXRoLm1pbih4MSwgeDIpO1xuICAgIHZhciBtYXhYID0gTWF0aC5tYXgoeDEsIHgyKTtcbiAgICB2YXIgbWluWSA9IE1hdGgubWluKHkxLCB5Mik7XG4gICAgdmFyIG1heFkgPSBNYXRoLm1heCh5MSwgeTIpO1xuICAgIHZhciBoYWxmV2lkdGggPSBsaW5lV2lkdGggLyAyO1xuICAgIC8vIOWboOS4uuebruWJjeeahOaWueahiOaYr+iuoeeul+eCueWIsOebtOe6v+eahOi3neemu++8jOiAjOacieWPr+iDveS8muWcqOW7tumVv+e6v+S4iu+8jOaJgOS7peimgeWFiOWIpOaWreaYr+WQpuWcqOWMheWbtOebkuWGhVxuICAgIC8vIOi/meenjeaWueahiOS8muWcqOawtOW5s+aIluiAheerluebtOeahOaDheWGteS4i+i9vee6v+eahOW7tumVv+e6v+S4iuacieWNiiBsaW5lV2lkdGgg55qE6K+v5beuXG4gICAgaWYgKCEoeCA+PSBtaW5YIC0gaGFsZldpZHRoICYmIHggPD0gbWF4WCArIGhhbGZXaWR0aCAmJiB5ID49IG1pblkgLSBoYWxmV2lkdGggJiYgeSA8PSBtYXhZICsgaGFsZldpZHRoKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIOWboOS4uuW3sue7j+iuoeeul+S6huWMheWbtOebku+8jOaJgOS7peS7hemcgOimgeiuoeeul+WIsOebtOe6v+eahOi3neemu+WNs+WPr++8jOWPr+S7peaYvuiRl+aPkOWNh+aAp+iDvVxuICAgIHJldHVybiBsaW5lXzEuZGVmYXVsdC5wb2ludFRvTGluZSh4MSwgeTEsIHgyLCB5MiwgeCwgeSkgPD0gbGluZVdpZHRoIC8gMjtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGluTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIi4vbGluZVwiKTtcbmZ1bmN0aW9uIGluUG9seWxpbmUocG9pbnRzLCBsaW5lV2lkdGgsIHgsIHksIGlzQ2xvc2UpIHtcbiAgICB2YXIgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICAgIGlmIChjb3VudCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50IC0gMTsgaSsrKSB7XG4gICAgICAgIHZhciB4MSA9IHBvaW50c1tpXVswXTtcbiAgICAgICAgdmFyIHkxID0gcG9pbnRzW2ldWzFdO1xuICAgICAgICB2YXIgeDIgPSBwb2ludHNbaSArIDFdWzBdO1xuICAgICAgICB2YXIgeTIgPSBwb2ludHNbaSArIDFdWzFdO1xuICAgICAgICBpZiAobGluZV8xLmRlZmF1bHQoeDEsIHkxLCB4MiwgeTIsIGxpbmVXaWR0aCwgeCwgeSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIOWmguaenOWwgemXre+8jOWImeiuoeeul+i1t+Wni+eCueWSjOe7k+adn+eCueeahOi+uVxuICAgIGlmIChpc0Nsb3NlKSB7XG4gICAgICAgIHZhciBmaXJzdCA9IHBvaW50c1swXTtcbiAgICAgICAgdmFyIGxhc3QgPSBwb2ludHNbY291bnQgLSAxXTtcbiAgICAgICAgaWYgKGxpbmVfMS5kZWZhdWx0KGZpcnN0WzBdLCBmaXJzdFsxXSwgbGFzdFswXSwgbGFzdFsxXSwgbGluZVdpZHRoLCB4LCB5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gaW5Qb2x5bGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbHlsaW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGxpbmVfMSA9IHJlcXVpcmUoXCIuL2xpbmVcIik7XG52YXIgYXJjXzEgPSByZXF1aXJlKFwiLi9hcmNcIik7XG5mdW5jdGlvbiByZWN0V2l0aFJhZGl1cyhtaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMsIGxpbmVXaWR0aCwgeCwgeSkge1xuICAgIHZhciBoYWxmV2lkdGggPSBsaW5lV2lkdGggLyAyO1xuICAgIHJldHVybiAobGluZV8xLmRlZmF1bHQobWluWCArIHJhZGl1cywgbWluWSwgbWluWCArIHdpZHRoIC0gcmFkaXVzLCBtaW5ZLCBsaW5lV2lkdGgsIHgsIHkpIHx8XG4gICAgICAgIGxpbmVfMS5kZWZhdWx0KG1pblggKyB3aWR0aCwgbWluWSArIHJhZGl1cywgbWluWCArIHdpZHRoLCBtaW5ZICsgaGVpZ2h0IC0gcmFkaXVzLCBsaW5lV2lkdGgsIHgsIHkpIHx8XG4gICAgICAgIGxpbmVfMS5kZWZhdWx0KG1pblggKyB3aWR0aCAtIHJhZGl1cywgbWluWSArIGhlaWdodCwgbWluWCArIHJhZGl1cywgbWluWSArIGhlaWdodCwgbGluZVdpZHRoLCB4LCB5KSB8fFxuICAgICAgICBsaW5lXzEuZGVmYXVsdChtaW5YLCBtaW5ZICsgaGVpZ2h0IC0gcmFkaXVzLCBtaW5YLCBtaW5ZICsgcmFkaXVzLCBsaW5lV2lkdGgsIHgsIHkpIHx8XG4gICAgICAgIGFyY18xLmRlZmF1bHQobWluWCArIHdpZHRoIC0gcmFkaXVzLCBtaW5ZICsgcmFkaXVzLCByYWRpdXMsIDEuNSAqIE1hdGguUEksIDIgKiBNYXRoLlBJLCBsaW5lV2lkdGgsIHgsIHkpIHx8XG4gICAgICAgIGFyY18xLmRlZmF1bHQobWluWCArIHdpZHRoIC0gcmFkaXVzLCBtaW5ZICsgaGVpZ2h0IC0gcmFkaXVzLCByYWRpdXMsIDAsIDAuNSAqIE1hdGguUEksIGxpbmVXaWR0aCwgeCwgeSkgfHxcbiAgICAgICAgYXJjXzEuZGVmYXVsdChtaW5YICsgcmFkaXVzLCBtaW5ZICsgaGVpZ2h0IC0gcmFkaXVzLCByYWRpdXMsIDAuNSAqIE1hdGguUEksIE1hdGguUEksIGxpbmVXaWR0aCwgeCwgeSkgfHxcbiAgICAgICAgYXJjXzEuZGVmYXVsdChtaW5YICsgcmFkaXVzLCBtaW5ZICsgcmFkaXVzLCByYWRpdXMsIE1hdGguUEksIDEuNSAqIE1hdGguUEksIGxpbmVXaWR0aCwgeCwgeSkpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gcmVjdFdpdGhSYWRpdXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZWN0LXJhZGl1cy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGluUmVjdChtaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0LCBsaW5lV2lkdGgsIHgsIHkpIHtcbiAgICB2YXIgaGFsZldpZHRoID0gbGluZVdpZHRoIC8gMjtcbiAgICAvLyDlsIblm5vkuKrovrnnnIvlgZrnn6nlvaLmnaXmo4DmtYvvvIzmr5TovrnnmoTmo4DmtYvnrpfms5XopoHlv6tcbiAgICByZXR1cm4gKHV0aWxfMS5pbkJveChtaW5YIC0gaGFsZldpZHRoLCBtaW5ZIC0gaGFsZldpZHRoLCB3aWR0aCwgbGluZVdpZHRoLCB4LCB5KSB8fCAvLyDkuIrovrlcbiAgICAgICAgdXRpbF8xLmluQm94KG1pblggKyB3aWR0aCAtIGhhbGZXaWR0aCwgbWluWSAtIGhhbGZXaWR0aCwgbGluZVdpZHRoLCBoZWlnaHQsIHgsIHkpIHx8IC8vIOWPs+i+uVxuICAgICAgICB1dGlsXzEuaW5Cb3gobWluWCArIGhhbGZXaWR0aCwgbWluWSArIGhlaWdodCAtIGhhbGZXaWR0aCwgd2lkdGgsIGxpbmVXaWR0aCwgeCwgeSkgfHwgLy8g5LiL6L65XG4gICAgICAgIHV0aWxfMS5pbkJveChtaW5YIC0gaGFsZldpZHRoLCBtaW5ZICsgaGFsZldpZHRoLCBsaW5lV2lkdGgsIGhlaWdodCwgeCwgeSkpOyAvLyDlt6bovrlcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGluUmVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlY3QuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnBhcnNlUmFkaXVzID0gZXhwb3J0cy5wYXJzZVN0eWxlID0gZXhwb3J0cy5wYXJzZVBhdHRlcm4gPSBleHBvcnRzLnBhcnNlUmFkaWFsR3JhZGllbnQgPSBleHBvcnRzLnBhcnNlTGluZUdyYWRpZW50ID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG52YXIgcmVnZXhUYWdzID0gL1tNTEhWUVRDU0FaXShbXk1MSFZRVENTQVpdKikvZ2k7XG52YXIgcmVnZXhEb3QgPSAvW15cXHNcXCxdKy9naTtcbnZhciByZWdleExHID0gL15sXFxzKlxcKFxccyooW1xcZC5dKylcXHMqXFwpXFxzKiguKikvaTtcbnZhciByZWdleFJHID0gL15yXFxzKlxcKFxccyooW1xcZC5dKylcXHMqLFxccyooW1xcZC5dKylcXHMqLFxccyooW1xcZC5dKylcXHMqXFwpXFxzKiguKikvaTtcbnZhciByZWdleFBSID0gL15wXFxzKlxcKFxccyooW2F4eW5dKVxccypcXClcXHMqKC4qKS9pO1xudmFyIHJlZ2V4Q29sb3JTdG9wID0gL1tcXGQuXSs6KCNbXlxcc10rfFteXFwpXStcXCkpL2dpO1xuZnVuY3Rpb24gYWRkU3RvcChzdGVwcywgZ3JhZGllbnQpIHtcbiAgICB2YXIgYXJyID0gc3RlcHMubWF0Y2gocmVnZXhDb2xvclN0b3ApO1xuICAgIHV0aWxfMS5lYWNoKGFyciwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgdmFyIGl0ZW1BcnIgPSBpdGVtLnNwbGl0KCc6Jyk7XG4gICAgICAgIGdyYWRpZW50LmFkZENvbG9yU3RvcChpdGVtQXJyWzBdLCBpdGVtQXJyWzFdKTtcbiAgICB9KTtcbn1cbi8qKlxuICog5bCG6L655ZKM5aGr5YWF6K6+572u55qE6aKc6Imy6L2s5o2i5oiQ57q/5oCn5riQ5Y+Y5a+56LGhXG4gKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBjYW52YXMg5LiK5LiL5paHXG4gKiBAcGFyYW0ge0lFbGVtZW50fSAgICAgICAgICAgICAgICAgZWxlbWVudCAg5Zu+5b2i5YWD57SgXG4gKiBAcGFyYW0ge3N0cmluZ30gICAgICAgICAgICAgICAgICAgZ3JhZGllbnRTdHIgICDpopzoibJcbiAqIEByZXR1cm5zIHthbnl9IOa4kOWPmOWvueixoVxuICovXG5mdW5jdGlvbiBwYXJzZUxpbmVHcmFkaWVudChjb250ZXh0LCBlbGVtZW50LCBncmFkaWVudFN0cikge1xuICAgIHZhciBhcnIgPSByZWdleExHLmV4ZWMoZ3JhZGllbnRTdHIpO1xuICAgIHZhciBhbmdsZSA9IChwYXJzZUZsb2F0KGFyclsxXSkgJSAzNjApICogKE1hdGguUEkgLyAxODApO1xuICAgIHZhciBzdGVwcyA9IGFyclsyXTtcbiAgICB2YXIgYm94ID0gZWxlbWVudC5nZXRCQm94KCk7XG4gICAgdmFyIHN0YXJ0O1xuICAgIHZhciBlbmQ7XG4gICAgaWYgKGFuZ2xlID49IDAgJiYgYW5nbGUgPCAoMSAvIDIpICogTWF0aC5QSSkge1xuICAgICAgICBzdGFydCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5taW5YLFxuICAgICAgICAgICAgeTogYm94Lm1pblksXG4gICAgICAgIH07XG4gICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5tYXhYLFxuICAgICAgICAgICAgeTogYm94Lm1heFksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGVsc2UgaWYgKCgxIC8gMikgKiBNYXRoLlBJIDw9IGFuZ2xlICYmIGFuZ2xlIDwgTWF0aC5QSSkge1xuICAgICAgICBzdGFydCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5tYXhYLFxuICAgICAgICAgICAgeTogYm94Lm1pblksXG4gICAgICAgIH07XG4gICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5taW5YLFxuICAgICAgICAgICAgeTogYm94Lm1heFksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGVsc2UgaWYgKE1hdGguUEkgPD0gYW5nbGUgJiYgYW5nbGUgPCAoMyAvIDIpICogTWF0aC5QSSkge1xuICAgICAgICBzdGFydCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5tYXhYLFxuICAgICAgICAgICAgeTogYm94Lm1heFksXG4gICAgICAgIH07XG4gICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5taW5YLFxuICAgICAgICAgICAgeTogYm94Lm1pblksXG4gICAgICAgIH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzdGFydCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5taW5YLFxuICAgICAgICAgICAgeTogYm94Lm1heFksXG4gICAgICAgIH07XG4gICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgIHg6IGJveC5tYXhYLFxuICAgICAgICAgICAgeTogYm94Lm1pblksXG4gICAgICAgIH07XG4gICAgfVxuICAgIHZhciB0YW5UaGV0YSA9IE1hdGgudGFuKGFuZ2xlKTtcbiAgICB2YXIgdGFuVGhldGEyID0gdGFuVGhldGEgKiB0YW5UaGV0YTtcbiAgICB2YXIgeCA9IChlbmQueCAtIHN0YXJ0LnggKyB0YW5UaGV0YSAqIChlbmQueSAtIHN0YXJ0LnkpKSAvICh0YW5UaGV0YTIgKyAxKSArIHN0YXJ0Lng7XG4gICAgdmFyIHkgPSAodGFuVGhldGEgKiAoZW5kLnggLSBzdGFydC54ICsgdGFuVGhldGEgKiAoZW5kLnkgLSBzdGFydC55KSkpIC8gKHRhblRoZXRhMiArIDEpICsgc3RhcnQueTtcbiAgICB2YXIgZ3JhZGllbnQgPSBjb250ZXh0LmNyZWF0ZUxpbmVhckdyYWRpZW50KHN0YXJ0LngsIHN0YXJ0LnksIHgsIHkpO1xuICAgIGFkZFN0b3Aoc3RlcHMsIGdyYWRpZW50KTtcbiAgICByZXR1cm4gZ3JhZGllbnQ7XG59XG5leHBvcnRzLnBhcnNlTGluZUdyYWRpZW50ID0gcGFyc2VMaW5lR3JhZGllbnQ7XG4vKipcbiAqIOWwhui+ueWSjOWhq+WFheiuvue9rueahOminOiJsui9rOaNouaIkOWchuW9oua4kOWPmOWvueixoVxuICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgY2FudmFzIOS4iuS4i+aWh1xuICogQHBhcmFtIHtJRWxlbWVudH0gICAgICAgICAgICAgICAgIGVsZW1lbnQgIOWbvuW9ouWFg+e0oFxuICogQHBhcmFtIHtzdHJpbmd9ICAgICAgICAgICAgICAgICAgIGdyYWRpZW50U3RyICAg6aKc6ImyXG4gKiBAcmV0dXJucyB7YW55fSDmuJDlj5jlr7nosaFcbiAqL1xuZnVuY3Rpb24gcGFyc2VSYWRpYWxHcmFkaWVudChjb250ZXh0LCBlbGVtZW50LCBncmFkaWVudFN0cikge1xuICAgIHZhciBhcnIgPSByZWdleFJHLmV4ZWMoZ3JhZGllbnRTdHIpO1xuICAgIHZhciBmeCA9IHBhcnNlRmxvYXQoYXJyWzFdKTtcbiAgICB2YXIgZnkgPSBwYXJzZUZsb2F0KGFyclsyXSk7XG4gICAgdmFyIGZyID0gcGFyc2VGbG9hdChhcnJbM10pO1xuICAgIHZhciBzdGVwcyA9IGFycls0XTtcbiAgICAvLyDnjq/ljYrlvoTkuLow5pe277yM6buY6K6k5peg5riQ5Y+Y77yM5Y+W5riQ5Y+Y5bqP5YiX55qE5pyA5ZCO5LiA5Liq6aKc6ImyXG4gICAgaWYgKGZyID09PSAwKSB7XG4gICAgICAgIHZhciBjb2xvcnMgPSBzdGVwcy5tYXRjaChyZWdleENvbG9yU3RvcCk7XG4gICAgICAgIHJldHVybiBjb2xvcnNbY29sb3JzLmxlbmd0aCAtIDFdLnNwbGl0KCc6JylbMV07XG4gICAgfVxuICAgIHZhciBib3ggPSBlbGVtZW50LmdldEJCb3goKTtcbiAgICB2YXIgd2lkdGggPSBib3gubWF4WCAtIGJveC5taW5YO1xuICAgIHZhciBoZWlnaHQgPSBib3gubWF4WSAtIGJveC5taW5ZO1xuICAgIHZhciByID0gTWF0aC5zcXJ0KHdpZHRoICogd2lkdGggKyBoZWlnaHQgKiBoZWlnaHQpIC8gMjtcbiAgICB2YXIgZ3JhZGllbnQgPSBjb250ZXh0LmNyZWF0ZVJhZGlhbEdyYWRpZW50KGJveC5taW5YICsgd2lkdGggKiBmeCwgYm94Lm1pblkgKyBoZWlnaHQgKiBmeSwgMCwgYm94Lm1pblggKyB3aWR0aCAvIDIsIGJveC5taW5ZICsgaGVpZ2h0IC8gMiwgZnIgKiByKTtcbiAgICBhZGRTdG9wKHN0ZXBzLCBncmFkaWVudCk7XG4gICAgcmV0dXJuIGdyYWRpZW50O1xufVxuZXhwb3J0cy5wYXJzZVJhZGlhbEdyYWRpZW50ID0gcGFyc2VSYWRpYWxHcmFkaWVudDtcbi8qKlxuICog6L655ZKM5aGr5YWF6K6+572u55qE6aKc6Imy6L2s5o2i5oiQIHBhdHRlcm5cbiAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IGNhbnZhcyDkuIrkuIvmlodcbiAqIEBwYXJhbSB7SUVsZW1lbnR9ICAgICAgICAgICAgICAgICBlbGVtZW50ICDlm77lvaLlhYPntKBcbiAqIEBwYXJhbSB7c3RyaW5nfSAgICAgICAgICAgICAgICAgICBwYXR0ZXJuU3RyICAg55Sf5oiQIHBhdHRlcm4g55qE5a2X56ym5LiyXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGF0dGVybihjb250ZXh0LCBlbGVtZW50LCBwYXR0ZXJuU3RyKSB7XG4gICAgLy8g5Zyo6L2s5o2i6L+H56iL5Lit6L+b6KGM5LqG57yT5a2YXG4gICAgaWYgKGVsZW1lbnQuZ2V0KCdwYXR0ZXJuU291cmNlJykgJiYgZWxlbWVudC5nZXQoJ3BhdHRlcm5Tb3VyY2UnKSA9PT0gcGF0dGVyblN0cikge1xuICAgICAgICByZXR1cm4gZWxlbWVudC5nZXQoJ3BhdHRlcm4nKTtcbiAgICB9XG4gICAgdmFyIHBhdHRlcm47XG4gICAgdmFyIGltZztcbiAgICB2YXIgYXJyID0gcmVnZXhQUi5leGVjKHBhdHRlcm5TdHIpO1xuICAgIHZhciByZXBlYXQgPSBhcnJbMV07XG4gICAgdmFyIHNvdXJjZSA9IGFyclsyXTtcbiAgICAvLyBGdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiBwYXR0ZXJuIGxvYWRzXG4gICAgZnVuY3Rpb24gb25sb2FkKCkge1xuICAgICAgICAvLyBDcmVhdGUgcGF0dGVyblxuICAgICAgICBwYXR0ZXJuID0gY29udGV4dC5jcmVhdGVQYXR0ZXJuKGltZywgcmVwZWF0KTtcbiAgICAgICAgZWxlbWVudC5zZXQoJ3BhdHRlcm4nLCBwYXR0ZXJuKTsgLy8gYmUgYSBjYWNoZVxuICAgICAgICBlbGVtZW50LnNldCgncGF0dGVyblNvdXJjZScsIHBhdHRlcm5TdHIpO1xuICAgIH1cbiAgICBzd2l0Y2ggKHJlcGVhdCkge1xuICAgICAgICBjYXNlICdhJzpcbiAgICAgICAgICAgIHJlcGVhdCA9ICdyZXBlYXQnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3gnOlxuICAgICAgICAgICAgcmVwZWF0ID0gJ3JlcGVhdC14JztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd5JzpcbiAgICAgICAgICAgIHJlcGVhdCA9ICdyZXBlYXQteSc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbic6XG4gICAgICAgICAgICByZXBlYXQgPSAnbm8tcmVwZWF0JztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVwZWF0ID0gJ25vLXJlcGVhdCc7XG4gICAgfVxuICAgIGltZyA9IG5ldyBJbWFnZSgpO1xuICAgIC8vIElmIHNvdXJjZSBVUkwgaXMgbm90IGEgZGF0YSBVUkxcbiAgICBpZiAoIXNvdXJjZS5tYXRjaCgvXmRhdGE6L2kpKSB7XG4gICAgICAgIC8vIFNldCBjcm9zc09yaWdpbiBmb3IgdGhpcyBpbWFnZVxuICAgICAgICBpbWcuY3Jvc3NPcmlnaW4gPSAnQW5vbnltb3VzJztcbiAgICB9XG4gICAgaW1nLnNyYyA9IHNvdXJjZTtcbiAgICBpZiAoaW1nLmNvbXBsZXRlKSB7XG4gICAgICAgIG9ubG9hZCgpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaW1nLm9ubG9hZCA9IG9ubG9hZDtcbiAgICAgICAgLy8gRml4IG9ubG9hZCgpIGJ1ZyBpbiBJRTlcbiAgICAgICAgaW1nLnNyYyA9IGltZy5zcmM7XG4gICAgfVxuICAgIHJldHVybiBwYXR0ZXJuO1xufVxuZXhwb3J0cy5wYXJzZVBhdHRlcm4gPSBwYXJzZVBhdHRlcm47XG5mdW5jdGlvbiBwYXJzZVN0eWxlKGNvbnRleHQsIGVsZW1lbnQsIGNvbG9yKSB7XG4gICAgaWYgKHV0aWxfMS5pc1N0cmluZyhjb2xvcikpIHtcbiAgICAgICAgaWYgKGNvbG9yWzFdID09PSAnKCcgfHwgY29sb3JbMl0gPT09ICcoJykge1xuICAgICAgICAgICAgaWYgKGNvbG9yWzBdID09PSAnbCcpIHtcbiAgICAgICAgICAgICAgICAvLyByZWdleExHLnRlc3QoY29sb3IpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlTGluZUdyYWRpZW50KGNvbnRleHQsIGVsZW1lbnQsIGNvbG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb2xvclswXSA9PT0gJ3InKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVnZXhSRy50ZXN0KGNvbG9yKVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVJhZGlhbEdyYWRpZW50KGNvbnRleHQsIGVsZW1lbnQsIGNvbG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb2xvclswXSA9PT0gJ3AnKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVnZXhQUi50ZXN0KGNvbG9yKVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVBhdHRlcm4oY29udGV4dCwgZWxlbWVudCwgY29sb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9XG59XG5leHBvcnRzLnBhcnNlU3R5bGUgPSBwYXJzZVN0eWxlO1xuZnVuY3Rpb24gcGFyc2VSYWRpdXMocmFkaXVzKSB7XG4gICAgdmFyIHIxID0gMDtcbiAgICB2YXIgcjIgPSAwO1xuICAgIHZhciByMyA9IDA7XG4gICAgdmFyIHI0ID0gMDtcbiAgICBpZiAodXRpbF8xLmlzQXJyYXkocmFkaXVzKSkge1xuICAgICAgICBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcjEgPSByMiA9IHIzID0gcjQgPSByYWRpdXNbMF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgcjEgPSByMyA9IHJhZGl1c1swXTtcbiAgICAgICAgICAgIHIyID0gcjQgPSByYWRpdXNbMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICAgICAgcjEgPSByYWRpdXNbMF07XG4gICAgICAgICAgICByMiA9IHI0ID0gcmFkaXVzWzFdO1xuICAgICAgICAgICAgcjMgPSByYWRpdXNbMl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByMSA9IHJhZGl1c1swXTtcbiAgICAgICAgICAgIHIyID0gcmFkaXVzWzFdO1xuICAgICAgICAgICAgcjMgPSByYWRpdXNbMl07XG4gICAgICAgICAgICByNCA9IHJhZGl1c1szXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcjEgPSByMiA9IHIzID0gcjQgPSByYWRpdXM7XG4gICAgfVxuICAgIHJldHVybiBbcjEsIHIyLCByMywgcjRdO1xufVxuZXhwb3J0cy5wYXJzZVJhZGl1cyA9IHBhcnNlUmFkaXVzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFyc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQGZpbGVvdmVydmlldyBwYXRoIOeahOS4gOS6m+W3peWFt1xuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbnZhciBnX2Jhc2VfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2VcIik7XG52YXIgcXVhZHJhdGljXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi9xdWFkcmF0aWNcIik7XG52YXIgY3ViaWNfMSA9IHJlcXVpcmUoXCJAYW50di9nLW1hdGgvbGliL2N1YmljXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIi4vaW4tc3Ryb2tlL2xpbmVcIik7XG52YXIgYXJjXzEgPSByZXF1aXJlKFwiLi9pbi1zdHJva2UvYXJjXCIpO1xudmFyIG1hdDMgPSByZXF1aXJlKFwiZ2wtbWF0cml4L21hdDNcIik7XG52YXIgdmVjMyA9IHJlcXVpcmUoXCJnbC1tYXRyaXgvdmVjM1wiKTtcbmZ1bmN0aW9uIGhhc0FyYyhwYXRoKSB7XG4gICAgdmFyIGhhc0FyYyA9IGZhbHNlO1xuICAgIHZhciBjb3VudCA9IHBhdGgubGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICB2YXIgcGFyYW1zID0gcGF0aFtpXTtcbiAgICAgICAgdmFyIGNtZCA9IHBhcmFtc1swXTtcbiAgICAgICAgaWYgKGNtZCA9PT0gJ0MnIHx8IGNtZCA9PT0gJ0EnIHx8IGNtZCA9PT0gJ1EnKSB7XG4gICAgICAgICAgICBoYXNBcmMgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhhc0FyYztcbn1cbmZ1bmN0aW9uIGlzUG9pbnRJblN0cm9rZShzZWdtZW50cywgbGluZVdpZHRoLCB4LCB5KSB7XG4gICAgdmFyIGlzSGl0ID0gZmFsc2U7XG4gICAgdmFyIGhhbGZXaWR0aCA9IGxpbmVXaWR0aCAvIDI7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VnbWVudCA9IHNlZ21lbnRzW2ldO1xuICAgICAgICB2YXIgY3VycmVudFBvaW50ID0gc2VnbWVudC5jdXJyZW50UG9pbnQsIHBhcmFtcyA9IHNlZ21lbnQucGFyYW1zLCBwcmVQb2ludCA9IHNlZ21lbnQucHJlUG9pbnQsIGJveCA9IHNlZ21lbnQuYm94O1xuICAgICAgICAvLyDlpoLmnpzlnKjliY3pnaLlt7Lnu4/nlJ/miJDov4fljIXlm7Tnm5LvvIznm7TmjqXmjInnhafljIXlm7Tnm5LorqHnrpdcbiAgICAgICAgaWYgKGJveCAmJiAhdXRpbF8xLmluQm94KGJveC54IC0gaGFsZldpZHRoLCBib3gueSAtIGhhbGZXaWR0aCwgYm94LndpZHRoICsgbGluZVdpZHRoLCBib3guaGVpZ2h0ICsgbGluZVdpZHRoLCB4LCB5KSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChzZWdtZW50LmNvbW1hbmQpIHtcbiAgICAgICAgICAgIC8vIEwg5ZKMIFog6YO95piv55u057q/77yMIE0g5LiN6L+b6KGM5ou+5Y+WXG4gICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgIGNhc2UgJ1onOlxuICAgICAgICAgICAgICAgIGlzSGl0ID0gbGluZV8xLmRlZmF1bHQocHJlUG9pbnRbMF0sIHByZVBvaW50WzFdLCBjdXJyZW50UG9pbnRbMF0sIGN1cnJlbnRQb2ludFsxXSwgbGluZVdpZHRoLCB4LCB5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgICAgICAgIHZhciBxRGlzdGFuY2UgPSBxdWFkcmF0aWNfMS5kZWZhdWx0LnBvaW50RGlzdGFuY2UocHJlUG9pbnRbMF0sIHByZVBvaW50WzFdLCBwYXJhbXNbMV0sIHBhcmFtc1syXSwgcGFyYW1zWzNdLCBwYXJhbXNbNF0sIHgsIHkpO1xuICAgICAgICAgICAgICAgIGlzSGl0ID0gcURpc3RhbmNlIDw9IGxpbmVXaWR0aCAvIDI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdDJzpcbiAgICAgICAgICAgICAgICB2YXIgY0Rpc3RhbmNlID0gY3ViaWNfMS5kZWZhdWx0LnBvaW50RGlzdGFuY2UocHJlUG9pbnRbMF0sIHByZVBvaW50WzFdLCBwYXJhbXNbMV0sIHBhcmFtc1syXSwgcGFyYW1zWzNdLCBwYXJhbXNbNF0sIHBhcmFtc1s1XSwgcGFyYW1zWzZdLCB4LCB5KTtcbiAgICAgICAgICAgICAgICBpc0hpdCA9IGNEaXN0YW5jZSA8PSBsaW5lV2lkdGggLyAyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgLy8g6K6h566X54K55Yiw5qSt5ZyG5ZyG5byn55qE6Led56a777yM5pqC5pe25L2/55So6L+R5Ly8566X5rOV77yM5ZCO6Z2i5Y+v5Lul5pS55oiQ5YiH5Ymy5rOV5rGC5pyA6L+R6Led56a7XG4gICAgICAgICAgICAgICAgdmFyIGFyY1BhcmFtcyA9IHNlZ21lbnQuYXJjUGFyYW1zO1xuICAgICAgICAgICAgICAgIHZhciBjeCA9IGFyY1BhcmFtcy5jeCwgY3kgPSBhcmNQYXJhbXMuY3ksIHJ4ID0gYXJjUGFyYW1zLnJ4LCByeSA9IGFyY1BhcmFtcy5yeSwgc3RhcnRBbmdsZSA9IGFyY1BhcmFtcy5zdGFydEFuZ2xlLCBlbmRBbmdsZSA9IGFyY1BhcmFtcy5lbmRBbmdsZSwgeFJvdGF0aW9uID0gYXJjUGFyYW1zLnhSb3RhdGlvbjtcbiAgICAgICAgICAgICAgICB2YXIgcCA9IFt4LCB5LCAxXTtcbiAgICAgICAgICAgICAgICB2YXIgbSA9IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICAgICAgICAgICAgICB2YXIgciA9IHJ4ID4gcnkgPyByeCA6IHJ5O1xuICAgICAgICAgICAgICAgIHZhciBzY2FsZVggPSByeCA+IHJ5ID8gMSA6IHJ4IC8gcnk7XG4gICAgICAgICAgICAgICAgdmFyIHNjYWxlWSA9IHJ4ID4gcnkgPyByeSAvIHJ4IDogMTtcbiAgICAgICAgICAgICAgICBtYXQzLnRyYW5zbGF0ZShtLCBtLCBbLWN4LCAtY3ldKTtcbiAgICAgICAgICAgICAgICBtYXQzLnJvdGF0ZShtLCBtLCAteFJvdGF0aW9uKTtcbiAgICAgICAgICAgICAgICBtYXQzLnNjYWxlKG0sIG0sIFsxIC8gc2NhbGVYLCAxIC8gc2NhbGVZXSk7XG4gICAgICAgICAgICAgICAgdmVjMy50cmFuc2Zvcm1NYXQzKHAsIHAsIG0pO1xuICAgICAgICAgICAgICAgIGlzSGl0ID0gYXJjXzEuZGVmYXVsdCgwLCAwLCByLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgbGluZVdpZHRoLCBwWzBdLCBwWzFdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzSGl0KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNIaXQ7XG59XG4vKipcbiAqIOaPkOWPluWHuuWGhemDqOeahOmXreWQiOWkmui+ueW9ouWSjOmdnumXreWQiOeahOWkmui+ueW9ou+8jOWBh+iuviBwYXRoIOS4jeWtmOWcqOWchuW8p1xuICogQHBhcmFtIHtBcnJheX0gcGF0aCDot6/lvoRcbiAqIEByZXR1cm5zIHtBcnJheX0g54K555qE6ZuG5ZCIXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RQb2x5Z29ucyhwYXRoKSB7XG4gICAgdmFyIGNvdW50ID0gcGF0aC5sZW5ndGg7XG4gICAgdmFyIHBvbHlnb25zID0gW107XG4gICAgdmFyIHBvbHlsaW5lcyA9IFtdO1xuICAgIHZhciBwb2ludHMgPSBbXTsgLy8g6Ziy5q2i56ys5LiA5Liq5ZG95Luk5LiN5pivICdNJ1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICB2YXIgcGFyYW1zID0gcGF0aFtpXTtcbiAgICAgICAgdmFyIGNtZCA9IHBhcmFtc1swXTtcbiAgICAgICAgaWYgKGNtZCA9PT0gJ00nKSB7XG4gICAgICAgICAgICAvLyDpgYfliLAgJ00nIOWIpOWumuaYr+WQpuaYr+aWsOaVsOe7hO+8jOaWsOaVsOe7hOS4reayoeacieeCuVxuICAgICAgICAgICAgaWYgKHBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzlrZjlnKjngrnvvIzliJnor7TmmI7msqHmnInpgYfliLAgJ1on77yM5byA5aeL5LqG5LiA5Liq5paw55qE5aSa6L655b2iXG4gICAgICAgICAgICAgICAgcG9seWxpbmVzLnB1c2gocG9pbnRzKTtcbiAgICAgICAgICAgICAgICBwb2ludHMgPSBbXTsgLy8g5Yib5bu65paw55qE54K5XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb2ludHMucHVzaChbcGFyYW1zWzFdLCBwYXJhbXNbMl1dKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjbWQgPT09ICdaJykge1xuICAgICAgICAgICAgaWYgKHBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyDlrZjlnKjngrlcbiAgICAgICAgICAgICAgICBwb2x5Z29ucy5wdXNoKHBvaW50cyk7XG4gICAgICAgICAgICAgICAgcG9pbnRzID0gW107IC8vIOW8gOWni+aWsOeahOeCuembhuWQiFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5aaC5p6c5LiN5a2Y5Zyo54K577yM5ZCM5pe2ICdaJ++8jOWImeivtOaYjuaYr+mUmeivr++8jOS4jeWkhOeQhlxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3BhcmFtc1sxXSwgcGFyYW1zWzJdXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8g6K+05piOIHBvaW50cyDmnKrmlL7lhaUgcG9seWdvbnMg5oiW6ICFIHBvbHlsaW5lXG4gICAgLy8g5LuF5b2T5Y+q5pyJ5LiA5LiqIE3vvIzmsqHmnIkgWiDml7bkvJrlj5HnlJ/ov5nnp43mg4XlhrVcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcG9seWxpbmVzLnB1c2gocG9pbnRzKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcG9seWdvbnM6IHBvbHlnb25zLFxuICAgICAgICBwb2x5bGluZXM6IHBvbHlsaW5lcyxcbiAgICB9O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gdHNsaWJfMS5fX2Fzc2lnbih7IGhhc0FyYzogaGFzQXJjLFxuICAgIGV4dHJhY3RQb2x5Z29uczogZXh0cmFjdFBvbHlnb25zLFxuICAgIGlzUG9pbnRJblN0cm9rZTogaXNQb2ludEluU3Ryb2tlIH0sIGdfYmFzZV8xLlBhdGhVdGlsKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmlzU2FtZVBvaW50ID0gZXhwb3J0cy5tZXJnZVJlZ2lvbiA9IGV4cG9ydHMuaW50ZXJzZWN0UmVjdCA9IGV4cG9ydHMuaW5Cb3ggPSBleHBvcnRzLmRpc3RhbmNlID0gZXhwb3J0cy5nZXRQaXhlbFJhdGlvID0gdm9pZCAwO1xuZnVuY3Rpb24gZ2V0UGl4ZWxSYXRpbygpIHtcbiAgICByZXR1cm4gd2luZG93ID8gd2luZG93LmRldmljZVBpeGVsUmF0aW8gOiAxO1xufVxuZXhwb3J0cy5nZXRQaXhlbFJhdGlvID0gZ2V0UGl4ZWxSYXRpbztcbi8qKlxuICog5Lik54K55LmL6Ze055qE6Led56a7XG4gKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICogQHBhcmFtIHtudW1iZXJ9IHgyIOe7k+adn+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTIg57uT5p2f54K5IHlcbiAqL1xuZnVuY3Rpb24gZGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpIHtcbiAgICB2YXIgZHggPSB4MSAtIHgyO1xuICAgIHZhciBkeSA9IHkxIC0geTI7XG4gICAgcmV0dXJuIE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG59XG5leHBvcnRzLmRpc3RhbmNlID0gZGlzdGFuY2U7XG4vKipcbiAqIOaYr+WQpuWcqOWMheWbtOebkuWGhVxuICogQHBhcmFtIHtudW1iZXJ9IG1pblggICDljIXlm7Tnm5LlvIDlp4vnmoTngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IG1pblkgICDljIXlm7Tnm5LlvIDlp4vnmoTngrkgeVxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoICDlrr3luqZcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQg6auY5bqmXG4gKiBAcGFyYW0ge1t0eXBlXX0geCAgICAgIOajgOa1i+eCueeahCB4XG4gKiBAcGFyYW0ge1t0eXBlXX0geSAgICAgIOebkea1i+eCueeahCB5XG4gKi9cbmZ1bmN0aW9uIGluQm94KG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQsIHgsIHkpIHtcbiAgICByZXR1cm4geCA+PSBtaW5YICYmIHggPD0gbWluWCArIHdpZHRoICYmIHkgPj0gbWluWSAmJiB5IDw9IG1pblkgKyBoZWlnaHQ7XG59XG5leHBvcnRzLmluQm94ID0gaW5Cb3g7XG5mdW5jdGlvbiBpbnRlcnNlY3RSZWN0KGJveDEsIGJveDIpIHtcbiAgICByZXR1cm4gIShib3gyLm1pblggPiBib3gxLm1heFggfHwgYm94Mi5tYXhYIDwgYm94MS5taW5YIHx8IGJveDIubWluWSA+IGJveDEubWF4WSB8fCBib3gyLm1heFkgPCBib3gxLm1pblkpO1xufVxuZXhwb3J0cy5pbnRlcnNlY3RSZWN0ID0gaW50ZXJzZWN0UmVjdDtcbi8vIOWQiOW5tuS4pOS4quWMuuWfn1xuZnVuY3Rpb24gbWVyZ2VSZWdpb24ocmVnaW9uMSwgcmVnaW9uMikge1xuICAgIGlmICghcmVnaW9uMSB8fCAhcmVnaW9uMikge1xuICAgICAgICByZXR1cm4gcmVnaW9uMSB8fCByZWdpb24yO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBtaW5YOiBNYXRoLm1pbihyZWdpb24xLm1pblgsIHJlZ2lvbjIubWluWCksXG4gICAgICAgIG1pblk6IE1hdGgubWluKHJlZ2lvbjEubWluWSwgcmVnaW9uMi5taW5ZKSxcbiAgICAgICAgbWF4WDogTWF0aC5tYXgocmVnaW9uMS5tYXhYLCByZWdpb24yLm1heFgpLFxuICAgICAgICBtYXhZOiBNYXRoLm1heChyZWdpb24xLm1heFksIHJlZ2lvbjIubWF4WSksXG4gICAgfTtcbn1cbmV4cG9ydHMubWVyZ2VSZWdpb24gPSBtZXJnZVJlZ2lvbjtcbi8qKlxuICog5Yik5pat5Lik5Liq54K55piv5ZCm6YeN5ZCI77yM54K55Z2Q5qCH55qE5qC85byP5Li6IFt4LCB5XVxuICogQHBhcmFtIHtBcnJheX0gcG9pbnQxIOesrOS4gOS4queCuVxuICogQHBhcmFtIHtBcnJheX0gcG9pbnQyIOesrOS6jOS4queCuVxuICovXG5mdW5jdGlvbiBpc1NhbWVQb2ludChwb2ludDEsIHBvaW50Mikge1xuICAgIHJldHVybiBwb2ludDFbMF0gPT09IHBvaW50MlswXSAmJiBwb2ludDFbMV0gPT09IHBvaW50MlsxXTtcbn1cbmV4cG9ydHMuaXNTYW1lUG9pbnQgPSBpc1NhbWVQb2ludDtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1uaWxcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc05pbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaXNfbmlsXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBpc19zdHJpbmdfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1zdHJpbmdcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc1N0cmluZ1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaXNfc3RyaW5nXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL2lzLWZ1bmN0aW9uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaXNGdW5jdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaXNfZnVuY3Rpb25fMS5kZWZhdWx0OyB9IH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvaXMtYXJyYXlcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc0FycmF5XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpc19hcnJheV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZWFjaF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL2VhY2hcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJlYWNoXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBlYWNoXzEuZGVmYXVsdDsgfSB9KTtcbnZhciB0b19yYWRpYW5fMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi90by1yYWRpYW5cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0b1JhZGlhblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdG9fcmFkaWFuXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBtb2RfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9tb2RcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJtb2RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG1vZF8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgaXNfbnVtYmVyX2VxdWFsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvaXMtbnVtYmVyLWVxdWFsXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaXNOdW1iZXJFcXVhbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaXNfbnVtYmVyX2VxdWFsXzEuZGVmYXVsdDsgfSB9KTtcbnZhciByZXF1ZXN0X2FuaW1hdGlvbl9mcmFtZV8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL3JlcXVlc3QtYW5pbWF0aW9uLWZyYW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVxdWVzdEFuaW1hdGlvbkZyYW1lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiByZXF1ZXN0X2FuaW1hdGlvbl9mcmFtZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgY2xlYXJfYW5pbWF0aW9uX2ZyYW1lXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvY2xlYXItYW5pbWF0aW9uLWZyYW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiY2xlYXJBbmltYXRpb25GcmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY2xlYXJfYW5pbWF0aW9uX2ZyYW1lXzEuZGVmYXVsdDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIl9fbnBtaW5zdGFsbF9kb25lXCI6IGZhbHNlLFxuICBcIl9hcmdzXCI6IFtcbiAgICBbXG4gICAgICBcIkBhbnR2L2ctY2FudmFzQDAuNC4xNFwiLFxuICAgICAgXCJDOlxcXFx4YW1wcFxcXFxodGRvY3NcXFxcaWNlaHJtXFxcXHdlYlwiXG4gICAgXVxuICBdLFxuICBcIl9mcm9tXCI6IFwiQGFudHYvZy1jYW52YXNAMC40LjE0XCIsXG4gIFwiX2lkXCI6IFwiQGFudHYvZy1jYW52YXNAMC40LjE0XCIsXG4gIFwiX2luQnVuZGxlXCI6IGZhbHNlLFxuICBcIl9pbnRlZ3JpdHlcIjogXCJzaGE1MTItQlBwRWJIdnN6RVBRSGhzc1BRcklPRjJ6S3p0aW9nYWJoaUJRL01DWDNxdkxVWGdCUlJ6TjZrdHdTODE2ZlFQYTgyUllpR1VtekVVRGhnQ1hVV1hBY2c9PVwiLFxuICBcIl9sb2NhdGlvblwiOiBcIi9AYW50di9nLWNhbnZhc1wiLFxuICBcIl9waGFudG9tQ2hpbGRyZW5cIjoge30sXG4gIFwiX3JlcXVlc3RlZFwiOiB7XG4gICAgXCJ0eXBlXCI6IFwidmVyc2lvblwiLFxuICAgIFwicmVnaXN0cnlcIjogdHJ1ZSxcbiAgICBcInJhd1wiOiBcIkBhbnR2L2ctY2FudmFzQDAuNC4xNFwiLFxuICAgIFwibmFtZVwiOiBcIkBhbnR2L2ctY2FudmFzXCIsXG4gICAgXCJlc2NhcGVkTmFtZVwiOiBcIkBhbnR2JTJmZy1jYW52YXNcIixcbiAgICBcInNjb3BlXCI6IFwiQGFudHZcIixcbiAgICBcInJhd1NwZWNcIjogXCIwLjQuMTRcIixcbiAgICBcInNhdmVTcGVjXCI6IG51bGwsXG4gICAgXCJmZXRjaFNwZWNcIjogXCIwLjQuMTRcIlxuICB9LFxuICBcIl9yZXF1aXJlZEJ5XCI6IFtcbiAgICBcIi9AYW50di9nMlwiLFxuICAgIFwiL0BhbnR2L2cycGxvdFwiXG4gIF0sXG4gIFwiX3Jlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvQGFudHYvZy1jYW52YXMvLS9nLWNhbnZhcy0wLjQuMTQudGd6XCIsXG4gIFwiX3NwZWNcIjogXCIwLjQuMTRcIixcbiAgXCJfd2hlcmVcIjogXCJDOlxcXFx4YW1wcFxcXFxodGRvY3NcXFxcaWNlaHJtXFxcXHdlYlwiLFxuICBcImF1dGhvclwiOiB7XG4gICAgXCJuYW1lXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL29yZ3MvYW50dmlzL3Blb3BsZVwiXG4gIH0sXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL2cvaXNzdWVzXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGFudHYvZy1iYXNlXCI6IFwiXjAuNC43XCIsXG4gICAgXCJAYW50di9nLW1hdGhcIjogXCJeMC4xLjNcIixcbiAgICBcIkBhbnR2L3BhdGgtdXRpbFwiOiBcIn4yLjAuNVwiLFxuICAgIFwiQGFudHYvdXRpbFwiOiBcIn4yLjAuMFwiLFxuICAgIFwiZ2wtbWF0cml4XCI6IFwiXjMuMC4wXCJcbiAgfSxcbiAgXCJkZXNjcmlwdGlvblwiOiBcIkEgY2FudmFzIGxpYnJhcnkgd2hpY2ggcHJvdmlkaW5nIDJkXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcIkBhbnR2L3RvcmNoXCI6IFwiXjEuMC4wXCIsXG4gICAgXCJsZXNzXCI6IFwiXjMuOS4wXCIsXG4gICAgXCJucG0tcnVuLWFsbFwiOiBcIl40LjEuNVwiLFxuICAgIFwid2VicGFja1wiOiBcIl40LjI2LjFcIixcbiAgICBcIndlYnBhY2stY2xpXCI6IFwiXjMuMS4yXCJcbiAgfSxcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCJwYWNrYWdlLmpzb25cIixcbiAgICBcImVzbVwiLFxuICAgIFwibGliXCIsXG4gICAgXCJkaXN0XCIsXG4gICAgXCJMSUNFTlNFXCIsXG4gICAgXCJSRUFETUUubWRcIlxuICBdLFxuICBcImdpdEhlYWRcIjogXCI2YjQxMDdjOGNmYWUxYjg5M2MzODU3NThhZDhlODcwMjM2ZjczZjZiXCIsXG4gIFwiaG9tZXBhZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL2cjcmVhZG1lXCIsXG4gIFwia2V5d29yZHNcIjogW1xuICAgIFwidXRpbFwiLFxuICAgIFwiYW50dlwiLFxuICAgIFwiZ1wiXG4gIF0sXG4gIFwibGljZW5zZVwiOiBcIklTQ1wiLFxuICBcIm1haW5cIjogXCJsaWIvaW5kZXguanNcIixcbiAgXCJtb2R1bGVcIjogXCJlc20vaW5kZXguanNcIixcbiAgXCJuYW1lXCI6IFwiQGFudHYvZy1jYW52YXNcIixcbiAgXCJwdWJsaXNoQ29uZmlnXCI6IHtcbiAgICBcImFjY2Vzc1wiOiBcInB1YmxpY1wiXG4gIH0sXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ0eXBlXCI6IFwiZ2l0XCIsXG4gICAgXCJ1cmxcIjogXCJnaXQraHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy9nLmdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJidWlsZFwiOiBcIm5wbSBydW4gY2xlYW4gJiYgcnVuLXAgYnVpbGQ6KlwiLFxuICAgIFwiYnVpbGQ6Y2pzXCI6IFwidHNjIC1wIHRzY29uZmlnLmpzb24gLS10YXJnZXQgRVM1IC0tbW9kdWxlIGNvbW1vbmpzIC0tb3V0RGlyIGxpYlwiLFxuICAgIFwiYnVpbGQ6ZXNtXCI6IFwidHNjIC1wIHRzY29uZmlnLmpzb24gLS10YXJnZXQgRVM1IC0tbW9kdWxlIEVTTmV4dCAtLW91dERpciBlc21cIixcbiAgICBcImJ1aWxkOnVtZFwiOiBcIndlYnBhY2sgLS1jb25maWcgd2VicGFjay5jb25maWcuanMgLS1tb2RlIHByb2R1Y3Rpb25cIixcbiAgICBcImNsZWFuXCI6IFwicm0gLXJmIGVzbSBsaWIgZGlzdFwiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJucG0gcnVuIGNvdmVyYWdlLWdlbmVyYXRvciAmJiBucG0gcnVuIGNvdmVyYWdlLXZpZXdlclwiLFxuICAgIFwiY292ZXJhZ2UtZ2VuZXJhdG9yXCI6IFwidG9yY2ggLS1jb3ZlcmFnZSAtLWNvbXBpbGUgLS1zb3VyY2UtcGF0dGVybiBzcmMvKi5qcyxzcmMvKiovKi5qcyAtLW9wdHMgdGVzdHMvbW9jaGEub3B0c1wiLFxuICAgIFwiY292ZXJhZ2Utdmlld2VyXCI6IFwidG9yY2gtY292ZXJhZ2VcIixcbiAgICBcImRpc3RcIjogXCJ3ZWJwYWNrIC0tY29uZmlnIHdlYnBhY2suY29uZmlnLmpzIC0tbW9kZSBwcm9kdWN0aW9uXCIsXG4gICAgXCJ0ZXN0XCI6IFwidG9yY2ggLS1yZW5kZXJlciAtLWNvbXBpbGUgLS1vcHRzIHRlc3RzL21vY2hhLm9wdHNcIixcbiAgICBcInRlc3QtbGl2ZVwiOiBcInRvcmNoIC0tY29tcGlsZSAtLWludGVyYWN0aXZlIC0tb3B0cyB0ZXN0cy9tb2NoYS5vcHRzXCIsXG4gICAgXCJ0c2NcIjogXCJ0c2MgLS1ub0VtaXRcIixcbiAgICBcInR5cGVjaGVja1wiOiBcInRzYyAtLW5vRW1pdFwiXG4gIH0sXG4gIFwidHlwZXNcIjogXCJsaWIvaW5kZXguZC50c1wiLFxuICBcInVucGtnXCI6IFwiZGlzdC9nLm1pbi5qc1wiLFxuICBcInZlcnNpb25cIjogXCIwLjQuMTRcIlxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgd2hlZWxfMSA9IHJlcXVpcmUoXCIuL3doZWVsXCIpO1xuZXhwb3J0cy5XaGVlbCA9IHdoZWVsXzEuV2hlZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGV2ZW50X2VtaXR0ZXJfMSA9IHJlcXVpcmUoXCJAYW50di9ldmVudC1lbWl0dGVyXCIpO1xudmFyIGQzRWFzZSA9IHJlcXVpcmUoXCJkMy1lYXNlXCIpO1xudmFyIGdtXzEgPSByZXF1aXJlKFwiLi4vZ21cIik7XG52YXIgY2xvY2tfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9jbG9ja1wiKTtcbi8vIOeci+mCo+S4quabsue6v+i3n+WQiOmAguS6hlxudmFyIGVhc2UgPSBkM0Vhc2UuZWFzZUN1YmljSW47XG52YXIgVE9UQUxfTVMgPSA4MDA7IC8vIOaDr+aAp+a7muWKqOaXtumXtO+8m+iwg+WPguW3peeoi+W4iO+8jOaIluiAheagueaNrumAn+W6puadpeiuoeeul+i/meS4quaXtumXtFxudmFyIFNXSVBFID0gJ3N3aXBlJztcbnZhciBQQU4gPSAncGFuJztcbnZhciBXSEVFTCA9ICd3aGVlbCc7XG4vKipcbiAqIOe7mSB2aWV3IOa3u+WKoOenu+WKqOerr+eahOa7muWKqOiDveWKm++8mlxuICogIC0g55uR5ZCsIHRvdWNoIOS6i+S7tu+8jGVtaXQgd2hlZWwg5LqL5Lu2XG4gKiAgLSDmu5rliqjmg6/mgKfljIXoo4VcbiAqICAtIOWSjCBwYyDnmoQgd2hlZWwg5LqL5Lu25L+d5oyB5Z+65pys5LiA6Ie0XG4gKi9cbnZhciBXaGVlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhXaGVlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBXaGVlbChlbGVtZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnJhZk1zID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHBhbiDkuovku7ZcbiAgICAgICAgICogQHBhcmFtIGV2XG4gICAgICAgICAqL1xuICAgICAgICBfdGhpcy5vblBhbiA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgdmFyIGRlbHRhWCA9IGV2LmRlbHRhWCwgZGVsdGFZID0gZXYuZGVsdGFZO1xuICAgICAgICAgICAgdmFyIGUgPSBfdGhpcy5nZXRXcmFwcGVyRXZlbnQoZXYsIGRlbHRhWCwgZGVsdGFZKTtcbiAgICAgICAgICAgIF90aGlzLmVtaXQoV0hFRUwsIGUpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICog5b2T5Ye6546wIHN3aXBlIOS6i+S7tueahOaXtuWAmVxuICAgICAgICAgKiBAcGFyYW0gZXZcbiAgICAgICAgICovXG4gICAgICAgIF90aGlzLm9uU3dpcGUgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzcGVlZFggPSBldi5zcGVlZFgsIHNwZWVkWSA9IGV2LnNwZWVkWTtcbiAgICAgICAgICAgIC8vIHJhZiDlvqrnjq/miafooYznmoTml7bpl7TmiLNcbiAgICAgICAgICAgIF90aGlzLnJhZk1zID0gY2xvY2tfMS5jbG9jay5ub3coKTtcbiAgICAgICAgICAgIF90aGlzLm1zID0gX3RoaXMucmFmTXM7XG4gICAgICAgICAgICAvLyDlr7nkuo7msqHmnInmu5HliqjnmoTmg4XlhrXkuIvvvIzkuI3lgZrlpITnkIZcbiAgICAgICAgICAgIGlmIChzcGVlZFggIT09IDAgfHwgc3BlZWRZICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMucmFmSW5lcnRpYShldik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIF90aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICBfdGhpcy5nbSA9IG5ldyBnbV8xLkdNKGVsZW1lbnQsIHsgZ2VzdHVyZXM6IFsnUGFuJywgJ1N3aXBlJ10gfSk7XG4gICAgICAgIF90aGlzLmdtLm9uKFNXSVBFLCBfdGhpcy5vblN3aXBlKTtcbiAgICAgICAgX3RoaXMuZ20ub24oUEFOLCBfdGhpcy5vblBhbik7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgV2hlZWwucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJhZik7XG4gICAgICAgIHRoaXMuZ20uZGVzdHJveSgpO1xuICAgICAgICB0aGlzLm9mZigpO1xuICAgIH07XG4gICAgLy8g5L2/55SoIHJhZiDov5vooYzmg6/mgKfmu5HliqhcbiAgICBXaGVlbC5wcm90b3R5cGUucmFmSW5lcnRpYSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc3BlZWRYID0gZXYuc3BlZWRYLCBzcGVlZFkgPSBldi5zcGVlZFk7XG4gICAgICAgIHRoaXMucmFmID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgbm93ID0gY2xvY2tfMS5jbG9jay5ub3coKTtcbiAgICAgICAgICAgIHZhciByYXRpbyA9IChub3cgLSBfdGhpcy5tcykgLyBUT1RBTF9NUztcbiAgICAgICAgICAgIGlmIChyYXRpbyA8IDEpIHtcbiAgICAgICAgICAgICAgICByYXRpbyA9IGVhc2UoMSAtIHJhdGlvKTtcbiAgICAgICAgICAgICAgICAvLyDmipjmjZ/kuYvlkI7nmoTpgJ/luqYgKiDml7bpl7TvvIznrYnkuo7ot53nprtcbiAgICAgICAgICAgICAgICB2YXIgdCA9IG5vdyAtIF90aGlzLnJhZk1zO1xuICAgICAgICAgICAgICAgIHZhciBtb3ZlZFggPSBzcGVlZFggKiByYXRpbyAqIHQ7XG4gICAgICAgICAgICAgICAgdmFyIG1vdmVkWSA9IHNwZWVkWSAqIHJhdGlvICogdDtcbiAgICAgICAgICAgICAgICB2YXIgZSA9IF90aGlzLmdldFdyYXBwZXJFdmVudChldiwgbW92ZWRYLCBtb3ZlZFkpO1xuICAgICAgICAgICAgICAgIC8vIOWPkeWHuiB3aGVlbCDkuovku7ZcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0KFdIRUVMLCBlKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5yYWZNcyA9IG5vdzsgLy8g6K6w5b2V5pe26Ze0XG4gICAgICAgICAgICAgICAgLy8g6L+b6KGM5LiL5LiA5qyhXG4gICAgICAgICAgICAgICAgX3RoaXMucmFmSW5lcnRpYShldik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgV2hlZWwucHJvdG90eXBlLmdldFdyYXBwZXJFdmVudCA9IGZ1bmN0aW9uIChldiwgZGVsdGFYLCBkZWx0YVkpIHtcbiAgICAgICAgLy8g56e75Yqo56uv55qE5ruR5Yqo5bqU6K+l5piv6Lef6ZqP5omL5oyHXG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGV2KSwgeyBkZWx0YVg6IC1kZWx0YVgsIGRlbHRhWTogLWRlbHRhWSB9KTtcbiAgICB9O1xuICAgIHJldHVybiBXaGVlbDtcbn0oZXZlbnRfZW1pdHRlcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuV2hlZWwgPSBXaGVlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdoZWVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIEdlc3R1cmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gR2VzdHVyZShnbSkge1xuICAgICAgICB0aGlzLkVWRU5UID0gJ2dlc3R1cmUnO1xuICAgICAgICB0aGlzLmdtID0gZ207XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOWkhOeQhuS6i+S7tlxuICAgICAqIEBwYXJhbSBldlxuICAgICAqL1xuICAgIEdlc3R1cmUucHJvdG90eXBlLmRvID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciB0eXBlID0gZXYudHlwZTtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlICd0b3VjaHN0YXJ0JzpcbiAgICAgICAgICAgICAgICB0aGlzLm9uVG91Y2hTdGFydChldik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0b3VjaG1vdmUnOlxuICAgICAgICAgICAgICAgIHRoaXMub25Ub3VjaE1vdmUoZXYpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndG91Y2hlbmQnOlxuICAgICAgICAgICAgICAgIHRoaXMub25Ub3VjaEVuZChldik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0b3VjaGNhbmNlbCc6XG4gICAgICAgICAgICAgICAgdGhpcy5vblRvdWNoQ2FuY2VsKGV2KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDop6blj5Hkuovku7ZcbiAgICAgKiBAcGFyYW0gZVxuICAgICAqL1xuICAgIEdlc3R1cmUucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICB0aGlzLmdtLmVtaXQodGhpcy5FVkVOVCwgZSk7XG4gICAgfTtcbiAgICByZXR1cm4gR2VzdHVyZTtcbn0oKSk7XG5leHBvcnRzLkdlc3R1cmUgPSBHZXN0dXJlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2VzdHVyZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBnZXN0dXJlXzEgPSByZXF1aXJlKFwiLi9nZXN0dXJlXCIpO1xuZXhwb3J0cy5HZXN0dXJlID0gZ2VzdHVyZV8xLkdlc3R1cmU7XG52YXIgcGFuXzEgPSByZXF1aXJlKFwiLi9wYW5cIik7XG52YXIgcHJlc3NfMSA9IHJlcXVpcmUoXCIuL3ByZXNzXCIpO1xudmFyIHN3aXBlXzEgPSByZXF1aXJlKFwiLi9zd2lwZVwiKTtcbnZhciB0YXBfMSA9IHJlcXVpcmUoXCIuL3RhcFwiKTtcbnZhciBNQVAgPSB7XG4gICAgUGFuOiBwYW5fMS5QYW4sXG4gICAgUHJlc3M6IHByZXNzXzEuUHJlc3MsXG4gICAgU3dpcGU6IHN3aXBlXzEuU3dpcGUsXG4gICAgVGFwOiB0YXBfMS5UYXAsXG59O1xuZXhwb3J0cy5nZXRHZXN0dXJlID0gZnVuY3Rpb24gKGcpIHsgcmV0dXJuIE1BUFtnXTsgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ2VzdHVyZV8xID0gcmVxdWlyZShcIi4vZ2VzdHVyZVwiKTtcbnZhciBQYW4gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGFuLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBhbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLkVWRU5UID0gJ3Bhbic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUGFuLnByb3RvdHlwZS5vblRvdWNoQ2FuY2VsID0gZnVuY3Rpb24gKGV2KSB7IH07XG4gICAgUGFuLnByb3RvdHlwZS5vblRvdWNoRW5kID0gZnVuY3Rpb24gKGV2KSB7IH07XG4gICAgUGFuLnByb3RvdHlwZS5vblRvdWNoTW92ZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgeCA9IGV2LngsIHkgPSBldi55O1xuICAgICAgICB2YXIgZGVsdGFYID0geCAtIHRoaXMucHJlWDtcbiAgICAgICAgdmFyIGRlbHRhWSA9IHkgLSB0aGlzLnByZVk7XG4gICAgICAgIHRoaXMucHJlWCA9IHg7XG4gICAgICAgIHRoaXMucHJlWSA9IHk7XG4gICAgICAgIHRoaXMuZW1pdCh7IHg6IHgsIHk6IHksIGRlbHRhWDogZGVsdGFYLCBkZWx0YVk6IGRlbHRhWSwgZXZlbnQ6IGV2IH0pO1xuICAgIH07XG4gICAgUGFuLnByb3RvdHlwZS5vblRvdWNoU3RhcnQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdmFyIHggPSBldi54LCB5ID0gZXYueTtcbiAgICAgICAgdGhpcy5wcmVYID0geDtcbiAgICAgICAgdGhpcy5wcmVZID0geTtcbiAgICB9O1xuICAgIHJldHVybiBQYW47XG59KGdlc3R1cmVfMS5HZXN0dXJlKSk7XG5leHBvcnRzLlBhbiA9IFBhbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGNsb2NrXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvY2xvY2tcIik7XG52YXIgZ2VzdHVyZV8xID0gcmVxdWlyZShcIi4vZ2VzdHVyZVwiKTtcbnZhciBUSU1FID0gMzAwO1xudmFyIERJU1RBTkNFID0gMTA7XG52YXIgUHJlc3MgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUHJlc3MsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUHJlc3MoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5FVkVOVCA9ICdwcmVzcyc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUHJlc3MucHJvdG90eXBlLm9uVG91Y2hDYW5jZWwgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgICB9O1xuICAgIFByZXNzLnByb3RvdHlwZS5vblRvdWNoRW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gICAgfTtcbiAgICBQcmVzcy5wcm90b3R5cGUub25Ub3VjaE1vdmUgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdmFyIHggPSBldi54LCB5ID0gZXYueTtcbiAgICAgICAgaWYgKHggLSB0aGlzLnRvdWNoU3RhcnRYID4gRElTVEFOQ0UgfHwgeSAtIHRoaXMudG91Y2hTdGFydFkgPiBESVNUQU5DRSkge1xuICAgICAgICAgICAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUHJlc3MucHJvdG90eXBlLm9uVG91Y2hTdGFydCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICAgICAgICB2YXIgeCA9IGV2LngsIHkgPSBldi55O1xuICAgICAgICB0aGlzLnRvdWNoU3RhcnRUaW1lID0gY2xvY2tfMS5jbG9jay5ub3coKTtcbiAgICAgICAgdGhpcy50b3VjaFN0YXJ0WCA9IHg7XG4gICAgICAgIHRoaXMudG91Y2hTdGFydFkgPSB5O1xuICAgICAgICB0aGlzLnByZXNzVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmVtaXQoeyB4OiB4LCB5OiB5LCBldmVudDogZXYgfSk7XG4gICAgICAgIH0sIFRJTUUpO1xuICAgIH07XG4gICAgUHJlc3MucHJvdG90eXBlLmNsZWFyVGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLnByZXNzVGltZW91dCk7XG4gICAgfTtcbiAgICByZXR1cm4gUHJlc3M7XG59KGdlc3R1cmVfMS5HZXN0dXJlKSk7XG5leHBvcnRzLlByZXNzID0gUHJlc3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wcmVzcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGNsb2NrXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvY2xvY2tcIik7XG52YXIgZ2VzdHVyZV8xID0gcmVxdWlyZShcIi4vZ2VzdHVyZVwiKTtcbnZhciBTV0lQRV9USU1FX0dBUCA9IDEwMDtcbnZhciBTd2lwZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTd2lwZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTd2lwZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLkVWRU5UID0gJ3N3aXBlJztcbiAgICAgICAgLy8g5pyA5ZCO5LiA5qyhIG1vdmUg55qE5LqL5Lu277yM55So5LqO5Yy65YiGIHN3aXBlIOWSjCBwYW5cbiAgICAgICAgX3RoaXMubGF0ZXN0TW92ZVRpbWUgPSAwO1xuICAgICAgICAvLyDmnIDlkI7kuqTkupLnmoTml7bpl7TvvIznlKjkuo7orqHnrpfpgJ/luqZcbiAgICAgICAgX3RoaXMubXMgPSAwO1xuICAgICAgICAvLyDmnIDlkI7nmoQgbW92ZSDpgJ/luqbvvIznlKjkuo50b3VjaGVuZCDkuYvlkI7lgZrmg6/mgKdcbiAgICAgICAgX3RoaXMuc3BlZWRYID0gMDtcbiAgICAgICAgX3RoaXMuc3BlZWRZID0gMDtcbiAgICAgICAgLy8g5pyA5ZCOIG1vdmUg55qEIHjvvIx5IOS9jee9rlxuICAgICAgICBfdGhpcy5wcmVYID0gMDtcbiAgICAgICAgX3RoaXMucHJlWSA9IDA7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgU3dpcGUucHJvdG90eXBlLm9uVG91Y2hDYW5jZWwgPSBmdW5jdGlvbiAoZXYpIHsgfTtcbiAgICBTd2lwZS5wcm90b3R5cGUub25Ub3VjaEVuZCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgc3BlZWRYID0gdGhpcy5zcGVlZFg7XG4gICAgICAgIHZhciBzcGVlZFkgPSB0aGlzLnNwZWVkWTtcbiAgICAgICAgaWYgKGNsb2NrXzEuY2xvY2subm93KCkgLSB0aGlzLmxhdGVzdE1vdmVUaW1lIDwgU1dJUEVfVElNRV9HQVApIHtcbiAgICAgICAgICAgIHZhciB4ID0gZXYueCwgeSA9IGV2Lnk7XG4gICAgICAgICAgICAvLyDmipvlh7rkuovku7ZcbiAgICAgICAgICAgIHRoaXMuZW1pdCh7IHg6IHgsIHk6IHksIHNwZWVkWDogc3BlZWRYLCBzcGVlZFk6IHNwZWVkWSwgZXZlbnQ6IGV2IH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTd2lwZS5wcm90b3R5cGUub25Ub3VjaE1vdmUgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdmFyIHggPSBldi54LCB5ID0gZXYueTtcbiAgICAgICAgdmFyIG1zID0gY2xvY2tfMS5jbG9jay5ub3coKTtcbiAgICAgICAgLy8gMS4g6K6h566XIHdoZWVsIOWBj+enu1xuICAgICAgICB2YXIgZGVsdGFYID0geCAtIHRoaXMucHJlWDtcbiAgICAgICAgdmFyIGRlbHRhWSA9IHkgLSB0aGlzLnByZVk7XG4gICAgICAgIHZhciBkZWx0YVRpbWUgPSBtcyAtIHRoaXMubXM7XG4gICAgICAgIC8vIDIuIOiuoeeul+mAn+W6pu+8iOeugOeJiOWQp++8iVxuICAgICAgICB0aGlzLnNwZWVkWCA9IGRlbHRhWCAvIGRlbHRhVGltZTtcbiAgICAgICAgdGhpcy5zcGVlZFkgPSBkZWx0YVkgLyBkZWx0YVRpbWU7XG4gICAgICAgIC8vIOiusOW9leacgOWQjuS4gOasoeenu+WKqOS6i+S7tlxuICAgICAgICB0aGlzLmxhdGVzdE1vdmVUaW1lID0gbXM7XG4gICAgfTtcbiAgICBTd2lwZS5wcm90b3R5cGUub25Ub3VjaFN0YXJ0ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciB4ID0gZXYueCwgeSA9IGV2Lnk7XG4gICAgICAgIC8vIOWIneWni+WMllxuICAgICAgICB0aGlzLnNwZWVkWCA9IHRoaXMuc3BlZWRZID0gMDtcbiAgICAgICAgdGhpcy5wcmVYID0geDtcbiAgICAgICAgdGhpcy5wcmVZID0geTtcbiAgICAgICAgdGhpcy5tcyA9IGNsb2NrXzEuY2xvY2subm93KCk7XG4gICAgfTtcbiAgICByZXR1cm4gU3dpcGU7XG59KGdlc3R1cmVfMS5HZXN0dXJlKSk7XG5leHBvcnRzLlN3aXBlID0gU3dpcGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zd2lwZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGNsb2NrXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvY2xvY2tcIik7XG52YXIgZ2VzdHVyZV8xID0gcmVxdWlyZShcIi4vZ2VzdHVyZVwiKTtcbnZhciBUSU1FID0gMzAwO1xudmFyIERJU1RBTkNFID0gMjtcbnZhciBUYXAgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVGFwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRhcCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLkVWRU5UID0gJ3RhcCc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVGFwLnByb3RvdHlwZS5vblRvdWNoQ2FuY2VsID0gZnVuY3Rpb24gKGV2KSB7IH07XG4gICAgVGFwLnByb3RvdHlwZS5vblRvdWNoRW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciB4ID0gZXYueCwgeSA9IGV2Lnk7XG4gICAgICAgIGlmICh4IC0gdGhpcy50b3VjaFN0YXJ0WCA8IERJU1RBTkNFICYmXG4gICAgICAgICAgICB5IC0gdGhpcy50b3VjaFN0YXJ0WSA8IERJU1RBTkNFICYmXG4gICAgICAgICAgICBjbG9ja18xLmNsb2NrLm5vdygpIC0gdGhpcy50b3VjaFN0YXJ0VGltZSA8IFRJTUUpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCh7IHg6IHgsIHk6IHksIGV2ZW50OiBldiB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVGFwLnByb3RvdHlwZS5vblRvdWNoTW92ZSA9IGZ1bmN0aW9uIChldikgeyB9O1xuICAgIFRhcC5wcm90b3R5cGUub25Ub3VjaFN0YXJ0ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciB4ID0gZXYueCwgeSA9IGV2Lnk7XG4gICAgICAgIHRoaXMudG91Y2hTdGFydFRpbWUgPSBjbG9ja18xLmNsb2NrLm5vdygpO1xuICAgICAgICB0aGlzLnRvdWNoU3RhcnRYID0geDtcbiAgICAgICAgdGhpcy50b3VjaFN0YXJ0WSA9IHk7XG4gICAgfTtcbiAgICByZXR1cm4gVGFwO1xufShnZXN0dXJlXzEuR2VzdHVyZSkpO1xuZXhwb3J0cy5UYXAgPSBUYXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10YXAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBldmVudF9lbWl0dGVyXzEgPSByZXF1aXJlKFwiQGFudHYvZXZlbnQtZW1pdHRlclwiKTtcbnZhciBnZXN0dXJlc18xID0gcmVxdWlyZShcIi4vZ2VzdHVyZXNcIik7XG4vKipcbiAqIOe7mSB2aWV3IOa3u+WKoOenu+WKqOerr+eahOa7muWKqOiDveWKm++8mlxuICogIC0g55uR5ZCsIHRvdWNoIOS6i+S7tu+8jGVtaXQgd2hlZWwg5LqL5Lu2XG4gKiAgLSDmu5rliqjmg6/mgKfljIXoo4VcbiAqICAtIOWSjCBwYyDnmoQgd2hlZWwg5LqL5Lu25L+d5oyB5Z+65pys5LiA6Ie0XG4gKi9cbnZhciBHTSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHTSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBHTShlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChvcHRpb25zID09PSB2b2lkIDApIHsgb3B0aW9ucyA9IHt9OyB9XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0b3VjaHN0YXJ0IOinpuWPkVxuICAgICAgICAgKiBAcGFyYW0gZXZcbiAgICAgICAgICovXG4gICAgICAgIF90aGlzLm9uVG91Y2hTdGFydCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgX3RoaXMucHJldmVudEV2ZW50KGV2KTtcbiAgICAgICAgICAgIF90aGlzLmVsZW1lbnQub24oJ3RvdWNobW92ZScsIF90aGlzLm9uVG91Y2hNb3ZlKTtcbiAgICAgICAgICAgIF90aGlzLmVsZW1lbnQub24oJ3RvdWNoZW5kJywgX3RoaXMub25Ub3VjaEVuZCk7XG4gICAgICAgICAgICBfdGhpcy5lbGVtZW50Lm9uKCd0b3VjaGNhbmNlbCcsIF90aGlzLm9uVG91Y2hDYW5jZWwpO1xuICAgICAgICAgICAgX3RoaXMuZW1pdCgndG91Y2hkb3duJywgZXYpO1xuICAgICAgICAgICAgX3RoaXMuZG9HZXN0dXJlcyhldik7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0b3VjaG1vdmUg6Kem5Y+RXG4gICAgICAgICAqIEBwYXJhbSBldlxuICAgICAgICAgKi9cbiAgICAgICAgX3RoaXMub25Ub3VjaE1vdmUgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIF90aGlzLnByZXZlbnRFdmVudChldik7XG4gICAgICAgICAgICBfdGhpcy5lbWl0KCd0b3VjaG1vdmUnLCBldik7XG4gICAgICAgICAgICBfdGhpcy5kb0dlc3R1cmVzKGV2KTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRvdWNoZW5kIOinpuWPkVxuICAgICAgICAgKiBAcGFyYW0gZXZcbiAgICAgICAgICovXG4gICAgICAgIF90aGlzLm9uVG91Y2hFbmQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIF90aGlzLnByZXZlbnRFdmVudChldik7XG4gICAgICAgICAgICBfdGhpcy5lbWl0KCd0b3VjaGVuZCcsIGV2KTtcbiAgICAgICAgICAgIF90aGlzLmVsZW1lbnQub2ZmKCd0b3VjaG1vdmUnLCBfdGhpcy5vblRvdWNoTW92ZSk7XG4gICAgICAgICAgICBfdGhpcy5lbGVtZW50Lm9mZigndG91Y2hlbmQnLCBfdGhpcy5vblRvdWNoRW5kKTtcbiAgICAgICAgICAgIF90aGlzLmVsZW1lbnQub2ZmKCd0b3VjaGNhbmNlbCcsIF90aGlzLm9uVG91Y2hDYW5jZWwpO1xuICAgICAgICAgICAgX3RoaXMuZG9HZXN0dXJlcyhldik7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0b3VjaGNhbmNlbCDop6blj5FcbiAgICAgICAgICogQHBhcmFtIGV2XG4gICAgICAgICAqL1xuICAgICAgICBfdGhpcy5vblRvdWNoQ2FuY2VsID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBfdGhpcy5wcmV2ZW50RXZlbnQoZXYpO1xuICAgICAgICAgICAgX3RoaXMuZW1pdCgndG91Y2hjYW5jZWwnLCBldik7XG4gICAgICAgICAgICBfdGhpcy5lbGVtZW50Lm9mZigndG91Y2htb3ZlJywgX3RoaXMub25Ub3VjaE1vdmUpO1xuICAgICAgICAgICAgX3RoaXMuZWxlbWVudC5vZmYoJ3RvdWNoZW5kJywgX3RoaXMub25Ub3VjaEVuZCk7XG4gICAgICAgICAgICBfdGhpcy5lbGVtZW50Lm9mZigndG91Y2hjYW5jZWwnLCBfdGhpcy5vblRvdWNoQ2FuY2VsKTtcbiAgICAgICAgICAgIF90aGlzLmRvR2VzdHVyZXMoZXYpO1xuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgX3RoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIF90aGlzLmluaXRpYWxHZXN0dXJlcygpO1xuICAgICAgICBfdGhpcy5iaW5kVG91Y2hTdGFydCgpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOmUgOavge+8jOWPlua2iOS6i+S7tue7keWumlxuICAgICAqL1xuICAgIEdNLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQub2ZmKCd0b3VjaHN0YXJ0JywgdGhpcy5vblRvdWNoU3RhcnQpO1xuICAgICAgICB0aGlzLm9mZigpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5a6e5L6L5YyW5omL5Yq/XG4gICAgICovXG4gICAgR00ucHJvdG90eXBlLmluaXRpYWxHZXN0dXJlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGdlc3R1cmVzID0gdGhpcy5vcHRpb25zLmdlc3R1cmVzIHx8IFsnUGFuJywgJ1ByZXNzJywgJ1N3aXBlJywgJ1RhcCddO1xuICAgICAgICB0aGlzLmdlc3R1cmVzID0gZ2VzdHVyZXMubWFwKGZ1bmN0aW9uIChnZXN0dXJlKSB7XG4gICAgICAgICAgICB2YXIgQ3RvciA9IGdlc3R1cmVzXzEuZ2V0R2VzdHVyZShnZXN0dXJlKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ3RvcihfdGhpcyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog57uR5a6aIHRvdWNoc3RhcnQg5LqL5Lu2XG4gICAgICovXG4gICAgR00ucHJvdG90eXBlLmJpbmRUb3VjaFN0YXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQub24oJ3RvdWNoc3RhcnQnLCB0aGlzLm9uVG91Y2hTdGFydCk7XG4gICAgfTtcbiAgICBHTS5wcm90b3R5cGUucHJldmVudEV2ZW50ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciB0eXBlID0gZXYudHlwZTtcbiAgICAgICAgdmFyIHByZXZlbnRzID0gdGhpcy5vcHRpb25zLnByZXZlbnRzIHx8IFtdO1xuICAgICAgICBpZiAocHJldmVudHMuaW5jbHVkZXModHlwZSkpIHtcbiAgICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEdNLnByb3RvdHlwZS5kb0dlc3R1cmVzID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHRoaXMuZ2VzdHVyZXMuZm9yRWFjaChmdW5jdGlvbiAoZykge1xuICAgICAgICAgICAgZy5kbyhldik7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEdNO1xufShldmVudF9lbWl0dGVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5HTSA9IEdNO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z20uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZ21fMSA9IHJlcXVpcmUoXCIuL2dtXCIpO1xuZXhwb3J0cy5HTSA9IGdtXzEuR007XG4vLyDljIXoo4XnmoTkuIrlsYIgd2hlZWwg5LqL5Lu2XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuL2V2ZW50XCIpO1xuZXhwb3J0cy5XaGVlbCA9IGV2ZW50XzEuV2hlZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIOaXtumSn1xuZXhwb3J0cy5jbG9jayA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gJ29iamVjdCcgJiYgcGVyZm9ybWFuY2Uubm93ID8gcGVyZm9ybWFuY2UgOiBEYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xvY2suanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbnZhciBlbGxpcHNlXzEgPSByZXF1aXJlKFwiLi9lbGxpcHNlXCIpO1xuLy8g5YGP5a+85pWwIHhcbmZ1bmN0aW9uIGRlcml2YXRpdmVYQXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFuZ2xlKSB7XG4gICAgcmV0dXJuIC0xICogcnggKiBNYXRoLmNvcyh4Um90YXRpb24pICogTWF0aC5zaW4oYW5nbGUpIC0gcnkgKiBNYXRoLnNpbih4Um90YXRpb24pICogTWF0aC5jb3MoYW5nbGUpO1xufVxuLy8g5YGP5a+85pWwIHlcbmZ1bmN0aW9uIGRlcml2YXRpdmVZQXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFuZ2xlKSB7XG4gICAgcmV0dXJuIC0xICogcnggKiBNYXRoLnNpbih4Um90YXRpb24pICogTWF0aC5zaW4oYW5nbGUpICsgcnkgKiBNYXRoLmNvcyh4Um90YXRpb24pICogTWF0aC5jb3MoYW5nbGUpO1xufVxuLy8geCDnmoTmnoHlgLxcbmZ1bmN0aW9uIHhFeHRyZW1hKHJ4LCByeSwgeFJvdGF0aW9uKSB7XG4gICAgcmV0dXJuIE1hdGguYXRhbigoLXJ5IC8gcngpICogTWF0aC50YW4oeFJvdGF0aW9uKSk7XG59XG4vLyB5IOeahOaegeWAvFxuZnVuY3Rpb24geUV4dHJlbWEocngsIHJ5LCB4Um90YXRpb24pIHtcbiAgICByZXR1cm4gTWF0aC5hdGFuKHJ5IC8gKHJ4ICogTWF0aC50YW4oeFJvdGF0aW9uKSkpO1xufVxuLy8g5qC55o2u6KeS5bqm5rGCIHgg5Z2Q5qCHXG5mdW5jdGlvbiB4QXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgYW5nbGUpIHtcbiAgICByZXR1cm4gcnggKiBNYXRoLmNvcyh4Um90YXRpb24pICogTWF0aC5jb3MoYW5nbGUpIC0gcnkgKiBNYXRoLnNpbih4Um90YXRpb24pICogTWF0aC5zaW4oYW5nbGUpICsgY3g7XG59XG4vLyDmoLnmja7op5LluqbmsYIgeSDlnZDmoIdcbmZ1bmN0aW9uIHlBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBhbmdsZSkge1xuICAgIHJldHVybiByeCAqIE1hdGguc2luKHhSb3RhdGlvbikgKiBNYXRoLmNvcyhhbmdsZSkgKyByeSAqIE1hdGguY29zKHhSb3RhdGlvbikgKiBNYXRoLnNpbihhbmdsZSkgKyBjeTtcbn1cbi8vIOiOt+WPlueCueWcqOakreWchuS4iueahOinkuW6plxuZnVuY3Rpb24gZ2V0QW5nbGUocngsIHJ5LCB4MCwgeTApIHtcbiAgICB2YXIgYW5nbGUgPSBNYXRoLmF0YW4yKHkwICogcngsIHgwICogcnkpO1xuICAgIC8vIOi9rOaNouWIsCAwIC0gMlBJIOWGhVxuICAgIHJldHVybiAoYW5nbGUgKyBNYXRoLlBJICogMikgJSAoTWF0aC5QSSAqIDIpO1xufVxuLy8g5qC55o2u6KeS5bqm6I635Y+W77yMeCx5XG5mdW5jdGlvbiBnZXRQb2ludChyeCwgcnksIGFuZ2xlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogcnggKiBNYXRoLmNvcyhhbmdsZSksXG4gICAgICAgIHk6IHJ5ICogTWF0aC5zaW4oYW5nbGUpLFxuICAgIH07XG59XG4vLyDml4vovaxcbmZ1bmN0aW9uIHJvdGF0ZSh4LCB5LCBhbmdsZSkge1xuICAgIHZhciBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgdmFyIHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgICByZXR1cm4gW3ggKiBjb3MgLSB5ICogc2luLCB4ICogc2luICsgeSAqIGNvc107XG59XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgLyoqXG4gICAgICog6K6h566X5YyF5Zu055uSXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGN4ICAgICAgICAg5ZyG5b+DIHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY3kgICAgICAgICDlnIblv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCAgICAgICAgIHgg6L205pa55ZCR55qE5Y2K5b6EXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ5ICAgICAgICAgeSDovbTmlrnlkJHnmoTljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geFJvdGF0aW9uICDml4vovazop5LluqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRBbmdsZSDotbflp4vop5LluqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kQW5nbGUgICDnu5PmnZ/op5LluqZcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOWMheWbtOebkuWvueixoVxuICAgICAqL1xuICAgIGJveDogZnVuY3Rpb24gKGN4LCBjeSwgcngsIHJ5LCB4Um90YXRpb24sIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSB7XG4gICAgICAgIHZhciB4RGltID0geEV4dHJlbWEocngsIHJ5LCB4Um90YXRpb24pO1xuICAgICAgICB2YXIgbWluWCA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WCA9IC1JbmZpbml0eTtcbiAgICAgICAgdmFyIHhzID0gW3N0YXJ0QW5nbGUsIGVuZEFuZ2xlXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IC1NYXRoLlBJICogMjsgaSA8PSBNYXRoLlBJICogMjsgaSArPSBNYXRoLlBJKSB7XG4gICAgICAgICAgICB2YXIgeEFuZ2xlID0geERpbSArIGk7XG4gICAgICAgICAgICBpZiAoc3RhcnRBbmdsZSA8IGVuZEFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0QW5nbGUgPCB4QW5nbGUgJiYgeEFuZ2xlIDwgZW5kQW5nbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgeHMucHVzaCh4QW5nbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChlbmRBbmdsZSA8IHhBbmdsZSAmJiB4QW5nbGUgPCBzdGFydEFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgICAgIHhzLnB1c2goeEFuZ2xlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHggPSB4QXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgeHNbaV0pO1xuICAgICAgICAgICAgaWYgKHggPCBtaW5YKSB7XG4gICAgICAgICAgICAgICAgbWluWCA9IHg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeCA+IG1heFgpIHtcbiAgICAgICAgICAgICAgICBtYXhYID0geDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgeURpbSA9IHlFeHRyZW1hKHJ4LCByeSwgeFJvdGF0aW9uKTtcbiAgICAgICAgdmFyIG1pblkgPSBJbmZpbml0eTtcbiAgICAgICAgdmFyIG1heFkgPSAtSW5maW5pdHk7XG4gICAgICAgIHZhciB5cyA9IFtzdGFydEFuZ2xlLCBlbmRBbmdsZV07XG4gICAgICAgIGZvciAodmFyIGkgPSAtTWF0aC5QSSAqIDI7IGkgPD0gTWF0aC5QSSAqIDI7IGkgKz0gTWF0aC5QSSkge1xuICAgICAgICAgICAgdmFyIHlBbmdsZSA9IHlEaW0gKyBpO1xuICAgICAgICAgICAgaWYgKHN0YXJ0QW5nbGUgPCBlbmRBbmdsZSkge1xuICAgICAgICAgICAgICAgIGlmIChzdGFydEFuZ2xlIDwgeUFuZ2xlICYmIHlBbmdsZSA8IGVuZEFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgICAgIHlzLnB1c2goeUFuZ2xlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoZW5kQW5nbGUgPCB5QW5nbGUgJiYgeUFuZ2xlIDwgc3RhcnRBbmdsZSkge1xuICAgICAgICAgICAgICAgICAgICB5cy5wdXNoKHlBbmdsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciB5ID0geUF0KGN4LCBjeSwgcngsIHJ5LCB4Um90YXRpb24sIHlzW2ldKTtcbiAgICAgICAgICAgIGlmICh5IDwgbWluWSkge1xuICAgICAgICAgICAgICAgIG1pblkgPSB5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHkgPiBtYXhZKSB7XG4gICAgICAgICAgICAgICAgbWF4WSA9IHk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IG1pblgsXG4gICAgICAgICAgICB5OiBtaW5ZLFxuICAgICAgICAgICAgd2lkdGg6IG1heFggLSBtaW5YLFxuICAgICAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOiOt+WPluWchuW8p+eahOmVv+W6pu+8jOiuoeeul+WchuW8p+mVv+W6puaXtuS4jeiAg+iZkeaXi+i9rOinkuW6pu+8jFxuICAgICAqIOS7hei3nyByeCwgcnksIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlIOebuOWFs1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjeCAgICAgICAgIOWchuW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGN5ICAgICAgICAg5ZyG5b+DIHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnggICAgICAgICB4IOi9tOaWueWQkeeahOWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSAgICAgICAgIHkg6L205pa55ZCR55qE5Y2K5b6EXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHhSb3RhdGlvbiAg5peL6L2s6KeS5bqmXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0QW5nbGUg6LW35aeL6KeS5bqmXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZEFuZ2xlICAg57uT5p2f6KeS5bqmXG4gICAgICovXG4gICAgbGVuZ3RoOiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUpIHsgfSxcbiAgICAvKipcbiAgICAgKiDojrflj5bmjIflrprngrnliLDlnIblvKfnmoTmnIDov5Hot53nprvnmoTngrlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY3ggICAgICAgICDlnIblv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjeSAgICAgICAgIOWchuW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4ICAgICAgICAgeCDovbTmlrnlkJHnmoTljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkgICAgICAgICB5IOi9tOaWueWQkeeahOWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4Um90YXRpb24gIOaXi+i9rOinkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydEFuZ2xlIOi1t+Wni+inkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRBbmdsZSAgIOe7k+adn+inkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MCAgICAgICAgIOaMh+WumueCueeahCB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkwICAgICAgICAg5oyH5a6a54K555qEIHlcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOWIsOaMh+WumueCueacgOi/kei3neemu+eahOeCuVxuICAgICAqL1xuICAgIG5lYXJlc3RQb2ludDogZnVuY3Rpb24gKGN4LCBjeSwgcngsIHJ5LCB4Um90YXRpb24sIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCB4MCwgeTApIHtcbiAgICAgICAgLy8g5bCG5pyA6L+R6Led56a76Zeu6aKY6L2s5o2i5oiQ5Yiw5qSt5ZyG5Lit5b+DIDAsMCDmsqHmnInml4vovaznmoTmpK3lnIbpl67pophcbiAgICAgICAgdmFyIHJlbGF0aXZlVmVjdG9yID0gcm90YXRlKHgwIC0gY3gsIHkwIC0gY3ksIC14Um90YXRpb24pO1xuICAgICAgICB2YXIgeDEgPSByZWxhdGl2ZVZlY3RvclswXSwgeTEgPSByZWxhdGl2ZVZlY3RvclsxXTtcbiAgICAgICAgLy8g6K6h566X54K55Yiw5qSt5ZyG55qE5pyA6L+R55qE54K5XG4gICAgICAgIHZhciByZWxhdGl2ZVBvaW50ID0gZWxsaXBzZV8xLmRlZmF1bHQubmVhcmVzdFBvaW50KDAsIDAsIHJ4LCByeSwgeDEsIHkxKTtcbiAgICAgICAgLy8g6I635Y+W54K55Zyo5qSt5ZyG5LiK55qE6KeS5bqmXG4gICAgICAgIHZhciBhbmdsZSA9IGdldEFuZ2xlKHJ4LCByeSwgcmVsYXRpdmVQb2ludC54LCByZWxhdGl2ZVBvaW50LnkpO1xuICAgICAgICAvLyDngrnmsqHmnInlnKjlnIblvKfkuIpcbiAgICAgICAgaWYgKGFuZ2xlIDwgc3RhcnRBbmdsZSkge1xuICAgICAgICAgICAgLy8g5bCP5LqO6LW35aeL5ZyG5bynXG4gICAgICAgICAgICByZWxhdGl2ZVBvaW50ID0gZ2V0UG9pbnQocngsIHJ5LCBzdGFydEFuZ2xlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhbmdsZSA+IGVuZEFuZ2xlKSB7XG4gICAgICAgICAgICAvLyDlpKfkuo7nu5PmnZ/lnIblvKdcbiAgICAgICAgICAgIHJlbGF0aXZlUG9pbnQgPSBnZXRQb2ludChyeCwgcnksIGVuZEFuZ2xlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyDml4vovazliLAgeFJvdGF0aW9uIOeahOinkuW6plxuICAgICAgICB2YXIgdmVjdG9yID0gcm90YXRlKHJlbGF0aXZlUG9pbnQueCwgcmVsYXRpdmVQb2ludC55LCB4Um90YXRpb24pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogdmVjdG9yWzBdICsgY3gsXG4gICAgICAgICAgICB5OiB2ZWN0b3JbMV0gKyBjeSxcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIHBvaW50RGlzdGFuY2U6IGZ1bmN0aW9uIChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgeDAsIHkwKSB7XG4gICAgICAgIHZhciBuZWFyZXN0UG9pbnQgPSB0aGlzLm5lYXJlc3RQb2ludChjeCwgY3ksIHJ4LCByeSwgeDAsIHkwKTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kaXN0YW5jZShuZWFyZXN0UG9pbnQueCwgbmVhcmVzdFBvaW50LnksIHgwLCB5MCk7XG4gICAgfSxcbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHQpIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSkgKiB0ICsgc3RhcnRBbmdsZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBhbmdsZSksXG4gICAgICAgICAgICB5OiB5QXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgYW5nbGUpLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgdGFuZ2VudEFuZ2xlOiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHQpIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSkgKiB0ICsgc3RhcnRBbmdsZTtcbiAgICAgICAgdmFyIGR4ID0gZGVyaXZhdGl2ZVhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW5nbGUpO1xuICAgICAgICB2YXIgZHkgPSBkZXJpdmF0aXZlWUF0KGN4LCBjeSwgcngsIHJ5LCB4Um90YXRpb24sIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBhbmdsZSk7XG4gICAgICAgIHJldHVybiB1dGlsXzEucGlNb2QoTWF0aC5hdGFuMihkeSwgZHgpKTtcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFyYy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuc25hcExlbmd0aCA9IGV4cG9ydHMubmVhcmVzdFBvaW50ID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG52YXIgRVBTSUxPTiA9IDAuMDAwMTtcbi8qKlxuICog5L2/55So54mb6aG/5YiH5Ymy5rOV5rGC5pyA6L+R55qE54K5XG4gKiBAcGFyYW0ge251bWJlcltdfSB4QXJyICAgICAg54K555qEIHgg5pWw57uEXG4gKiBAcGFyYW0ge251bWJlcltdfSB5QXJyICAgICAg54K555qEIHkg5pWw57uEXG4gKiBAcGFyYW0ge251bWJlcn0gICB4ICAgICAgICAg5oyH5a6a55qE54K5IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSAgIHkgICAgICAgICDmjIflrprnmoTngrkgeVxuICogQHBhcmFtIHtGdW5jdGlvbn0gdENhbGxiYWNrIOW3ruWAvOWHveaVsFxuICovXG5mdW5jdGlvbiBuZWFyZXN0UG9pbnQoeEFyciwgeUFyciwgeCwgeSwgdENhbGxiYWNrLCBsZW5ndGgpIHtcbiAgICB2YXIgdDtcbiAgICB2YXIgZCA9IEluZmluaXR5O1xuICAgIHZhciB2MCA9IFt4LCB5XTtcbiAgICB2YXIgc2VnTnVtID0gMjA7XG4gICAgaWYgKGxlbmd0aCAmJiBsZW5ndGggPiAyMDApIHtcbiAgICAgICAgc2VnTnVtID0gbGVuZ3RoIC8gMTA7XG4gICAgfVxuICAgIHZhciBpbmNyZWFzZVJhdGUgPSAxIC8gc2VnTnVtO1xuICAgIHZhciBpbnRlcnZhbCA9IGluY3JlYXNlUmF0ZSAvIDEwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IHNlZ051bTsgaSsrKSB7XG4gICAgICAgIHZhciBfdCA9IGkgKiBpbmNyZWFzZVJhdGU7XG4gICAgICAgIHZhciB2MSA9IFt0Q2FsbGJhY2suYXBwbHkobnVsbCwgeEFyci5jb25jYXQoW190XSkpLCB0Q2FsbGJhY2suYXBwbHkobnVsbCwgeUFyci5jb25jYXQoW190XSkpXTtcbiAgICAgICAgdmFyIGQxID0gdXRpbF8xLmRpc3RhbmNlKHYwWzBdLCB2MFsxXSwgdjFbMF0sIHYxWzFdKTtcbiAgICAgICAgaWYgKGQxIDwgZCkge1xuICAgICAgICAgICAgdCA9IF90O1xuICAgICAgICAgICAgZCA9IGQxO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIOaPkOWJjee7iOatolxuICAgIGlmICh0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4QXJyWzBdLFxuICAgICAgICAgICAgeTogeUFyclswXSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHQgPT09IDEpIHtcbiAgICAgICAgdmFyIGNvdW50ID0geEFyci5sZW5ndGg7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4QXJyW2NvdW50IC0gMV0sXG4gICAgICAgICAgICB5OiB5QXJyW2NvdW50IC0gMV0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIGQgPSBJbmZpbml0eTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHtcbiAgICAgICAgaWYgKGludGVydmFsIDwgRVBTSUxPTikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHByZXYgPSB0IC0gaW50ZXJ2YWw7XG4gICAgICAgIHZhciBuZXh0ID0gdCArIGludGVydmFsO1xuICAgICAgICB2YXIgdjEgPSBbdENhbGxiYWNrLmFwcGx5KG51bGwsIHhBcnIuY29uY2F0KFtwcmV2XSkpLCB0Q2FsbGJhY2suYXBwbHkobnVsbCwgeUFyci5jb25jYXQoW3ByZXZdKSldO1xuICAgICAgICB2YXIgZDEgPSB1dGlsXzEuZGlzdGFuY2UodjBbMF0sIHYwWzFdLCB2MVswXSwgdjFbMV0pO1xuICAgICAgICBpZiAocHJldiA+PSAwICYmIGQxIDwgZCkge1xuICAgICAgICAgICAgdCA9IHByZXY7XG4gICAgICAgICAgICBkID0gZDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgdjIgPSBbdENhbGxiYWNrLmFwcGx5KG51bGwsIHhBcnIuY29uY2F0KFtuZXh0XSkpLCB0Q2FsbGJhY2suYXBwbHkobnVsbCwgeUFyci5jb25jYXQoW25leHRdKSldO1xuICAgICAgICAgICAgdmFyIGQyID0gdXRpbF8xLmRpc3RhbmNlKHYwWzBdLCB2MFsxXSwgdjJbMF0sIHYyWzFdKTtcbiAgICAgICAgICAgIGlmIChuZXh0IDw9IDEgJiYgZDIgPCBkKSB7XG4gICAgICAgICAgICAgICAgdCA9IG5leHQ7XG4gICAgICAgICAgICAgICAgZCA9IGQyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaW50ZXJ2YWwgKj0gMC41O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHRDYWxsYmFjay5hcHBseShudWxsLCB4QXJyLmNvbmNhdChbdF0pKSxcbiAgICAgICAgeTogdENhbGxiYWNrLmFwcGx5KG51bGwsIHlBcnIuY29uY2F0KFt0XSkpLFxuICAgIH07XG59XG5leHBvcnRzLm5lYXJlc3RQb2ludCA9IG5lYXJlc3RQb2ludDtcbi8vIOi/keS8vOaxguinoyBodHRwczovL2NvbW11bml0eS5raHJvbm9zLm9yZy90LzNkLWN1YmljLWJlemllci1zZWdtZW50LWxlbmd0aC82MjM2My8yXG5mdW5jdGlvbiBzbmFwTGVuZ3RoKHhBcnIsIHlBcnIpIHtcbiAgICB2YXIgdG90YWxMZW5ndGggPSAwO1xuICAgIHZhciBjb3VudCA9IHhBcnIubGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICB2YXIgeCA9IHhBcnJbaV07XG4gICAgICAgIHZhciB5ID0geUFycltpXTtcbiAgICAgICAgdmFyIG5leHRYID0geEFyclsoaSArIDEpICUgY291bnRdO1xuICAgICAgICB2YXIgbmV4dFkgPSB5QXJyWyhpICsgMSkgJSBjb3VudF07XG4gICAgICAgIHRvdGFsTGVuZ3RoICs9IHV0aWxfMS5kaXN0YW5jZSh4LCB5LCBuZXh0WCwgbmV4dFkpO1xuICAgIH1cbiAgICByZXR1cm4gdG90YWxMZW5ndGggLyAyO1xufVxuZXhwb3J0cy5zbmFwTGVuZ3RoID0gc25hcExlbmd0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJlemllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xudmFyIGxpbmVfMSA9IHJlcXVpcmUoXCIuL2xpbmVcIik7XG52YXIgYmV6aWVyXzEgPSByZXF1aXJlKFwiLi9iZXppZXJcIik7XG5mdW5jdGlvbiBjdWJpY0F0KHAwLCBwMSwgcDIsIHAzLCB0KSB7XG4gICAgdmFyIG9uZXQgPSAxIC0gdDsgLy8gdCAqIHQgKiB0IOeahOaAp+iDveWkp+amguaYryBNYXRoLnBvdyh0LCAzKSDnmoTkuInlgI1cbiAgICByZXR1cm4gb25ldCAqIG9uZXQgKiBvbmV0ICogcDAgKyAzICogcDEgKiB0ICogb25ldCAqIG9uZXQgKyAzICogcDIgKiB0ICogdCAqIG9uZXQgKyBwMyAqIHQgKiB0ICogdDtcbn1cbmZ1bmN0aW9uIGRlcml2YXRpdmVBdChwMCwgcDEsIHAyLCBwMywgdCkge1xuICAgIHZhciBvbmV0ID0gMSAtIHQ7XG4gICAgcmV0dXJuIDMgKiAob25ldCAqIG9uZXQgKiAocDEgLSBwMCkgKyAyICogb25ldCAqIHQgKiAocDIgLSBwMSkgKyB0ICogdCAqIChwMyAtIHAyKSk7XG59XG5mdW5jdGlvbiBleHRyZW1hKHAwLCBwMSwgcDIsIHAzKSB7XG4gICAgdmFyIGEgPSAtMyAqIHAwICsgOSAqIHAxIC0gOSAqIHAyICsgMyAqIHAzO1xuICAgIHZhciBiID0gNiAqIHAwIC0gMTIgKiBwMSArIDYgKiBwMjtcbiAgICB2YXIgYyA9IDMgKiBwMSAtIDMgKiBwMDtcbiAgICB2YXIgZXh0cmVtYXMgPSBbXTtcbiAgICB2YXIgdDE7XG4gICAgdmFyIHQyO1xuICAgIHZhciBkaXNjU3FydDtcbiAgICBpZiAodXRpbF8xLmlzTnVtYmVyRXF1YWwoYSwgMCkpIHtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOdW1iZXJFcXVhbChiLCAwKSkge1xuICAgICAgICAgICAgdDEgPSAtYyAvIGI7XG4gICAgICAgICAgICBpZiAodDEgPj0gMCAmJiB0MSA8PSAxKSB7XG4gICAgICAgICAgICAgICAgZXh0cmVtYXMucHVzaCh0MSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBkaXNjID0gYiAqIGIgLSA0ICogYSAqIGM7XG4gICAgICAgIGlmICh1dGlsXzEuaXNOdW1iZXJFcXVhbChkaXNjLCAwKSkge1xuICAgICAgICAgICAgZXh0cmVtYXMucHVzaCgtYiAvICgyICogYSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRpc2MgPiAwKSB7XG4gICAgICAgICAgICBkaXNjU3FydCA9IE1hdGguc3FydChkaXNjKTtcbiAgICAgICAgICAgIHQxID0gKC1iICsgZGlzY1NxcnQpIC8gKDIgKiBhKTtcbiAgICAgICAgICAgIHQyID0gKC1iIC0gZGlzY1NxcnQpIC8gKDIgKiBhKTtcbiAgICAgICAgICAgIGlmICh0MSA+PSAwICYmIHQxIDw9IDEpIHtcbiAgICAgICAgICAgICAgICBleHRyZW1hcy5wdXNoKHQxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0MiA+PSAwICYmIHQyIDw9IDEpIHtcbiAgICAgICAgICAgICAgICBleHRyZW1hcy5wdXNoKHQyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXh0cmVtYXM7XG59XG4vLyDliIblibLotJ3loZ7lsJTmm7Lnur9cbmZ1bmN0aW9uIGRpdmlkZUN1YmljKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgdCkge1xuICAgIC8vIOWIkuWIhueCuVxuICAgIHZhciB4dCA9IGN1YmljQXQoeDEsIHgyLCB4MywgeDQsIHQpO1xuICAgIHZhciB5dCA9IGN1YmljQXQoeTEsIHkyLCB5MywgeTQsIHQpO1xuICAgIC8vIOiuoeeul+S4pOeCueS5i+mXtOeahOW3ruWAvOeCuVxuICAgIHZhciBjMSA9IGxpbmVfMS5kZWZhdWx0LnBvaW50QXQoeDEsIHkxLCB4MiwgeTIsIHQpO1xuICAgIHZhciBjMiA9IGxpbmVfMS5kZWZhdWx0LnBvaW50QXQoeDIsIHkyLCB4MywgeTMsIHQpO1xuICAgIHZhciBjMyA9IGxpbmVfMS5kZWZhdWx0LnBvaW50QXQoeDMsIHkzLCB4NCwgeTQsIHQpO1xuICAgIHZhciBjMTIgPSBsaW5lXzEuZGVmYXVsdC5wb2ludEF0KGMxLngsIGMxLnksIGMyLngsIGMyLnksIHQpO1xuICAgIHZhciBjMjMgPSBsaW5lXzEuZGVmYXVsdC5wb2ludEF0KGMyLngsIGMyLnksIGMzLngsIGMzLnksIHQpO1xuICAgIHJldHVybiBbXG4gICAgICAgIFt4MSwgeTEsIGMxLngsIGMxLnksIGMxMi54LCBjMTIueSwgeHQsIHl0XSxcbiAgICAgICAgW3h0LCB5dCwgYzIzLngsIGMyMy55LCBjMy54LCBjMy55LCB4NCwgeTRdLFxuICAgIF07XG59XG4vLyDkvb/nlKjov63ku6Pms5Xlj5botJ3loZ7lsJTmm7Lnur/nmoTplb/luqbvvIzkuozpmLblkozkuInpmLbliIblvIDlhpnvvIzmm7TmuIXmmbDlkozkvr/kuo7osIPor5VcbmZ1bmN0aW9uIGN1YmljTGVuZ3RoKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgaXRlcmF0aW9uQ291bnQpIHtcbiAgICBpZiAoaXRlcmF0aW9uQ291bnQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGJlemllcl8xLnNuYXBMZW5ndGgoW3gxLCB4MiwgeDMsIHg0XSwgW3kxLCB5MiwgeTMsIHk0XSk7XG4gICAgfVxuICAgIHZhciBjdWJpY3MgPSBkaXZpZGVDdWJpYyh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIDAuNSk7XG4gICAgdmFyIGxlZnQgPSBjdWJpY3NbMF07XG4gICAgdmFyIHJpZ2h0ID0gY3ViaWNzWzFdO1xuICAgIGxlZnQucHVzaChpdGVyYXRpb25Db3VudCAtIDEpO1xuICAgIHJpZ2h0LnB1c2goaXRlcmF0aW9uQ291bnQgLSAxKTtcbiAgICByZXR1cm4gY3ViaWNMZW5ndGguYXBwbHkobnVsbCwgbGVmdCkgKyBjdWJpY0xlbmd0aC5hcHBseShudWxsLCByaWdodCk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgZXh0cmVtYTogZXh0cmVtYSxcbiAgICBib3g6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIHtcbiAgICAgICAgdmFyIHhBcnIgPSBbeDEsIHg0XTtcbiAgICAgICAgdmFyIHlBcnIgPSBbeTEsIHk0XTtcbiAgICAgICAgdmFyIHhFeHRyZW1hID0gZXh0cmVtYSh4MSwgeDIsIHgzLCB4NCk7XG4gICAgICAgIHZhciB5RXh0cmVtYSA9IGV4dHJlbWEoeTEsIHkyLCB5MywgeTQpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhFeHRyZW1hLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4QXJyLnB1c2goY3ViaWNBdCh4MSwgeDIsIHgzLCB4NCwgeEV4dHJlbWFbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHlFeHRyZW1hLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB5QXJyLnB1c2goY3ViaWNBdCh5MSwgeTIsIHkzLCB5NCwgeUV4dHJlbWFbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXRpbF8xLmdldEJCb3hCeUFycmF5KHhBcnIsIHlBcnIpO1xuICAgIH0sXG4gICAgbGVuZ3RoOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0KSB7XG4gICAgICAgIC8vIOi/reS7o+S4ieasoe+8jOWIkuWIhuaIkCA4IOauteaxgumVv+W6plxuICAgICAgICByZXR1cm4gY3ViaWNMZW5ndGgoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCAzKTtcbiAgICB9LFxuICAgIG5lYXJlc3RQb2ludDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeDAsIHkwLCBsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGJlemllcl8xLm5lYXJlc3RQb2ludChbeDEsIHgyLCB4MywgeDRdLCBbeTEsIHkyLCB5MywgeTRdLCB4MCwgeTAsIGN1YmljQXQsIGxlbmd0aCk7XG4gICAgfSxcbiAgICBwb2ludERpc3RhbmNlOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB4MCwgeTAsIGxlbmd0aCkge1xuICAgICAgICB2YXIgcG9pbnQgPSB0aGlzLm5lYXJlc3RQb2ludCh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHgwLCB5MCwgbGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kaXN0YW5jZShwb2ludC54LCBwb2ludC55LCB4MCwgeTApO1xuICAgIH0sXG4gICAgaW50ZXJwb2xhdGlvbkF0OiBjdWJpY0F0LFxuICAgIHBvaW50QXQ6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGN1YmljQXQoeDEsIHgyLCB4MywgeDQsIHQpLFxuICAgICAgICAgICAgeTogY3ViaWNBdCh5MSwgeTIsIHkzLCB5NCwgdCksXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBkaXZpZGU6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHQpIHtcbiAgICAgICAgcmV0dXJuIGRpdmlkZUN1YmljKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgdCk7XG4gICAgfSxcbiAgICB0YW5nZW50QW5nbGU6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHQpIHtcbiAgICAgICAgdmFyIGR4ID0gZGVyaXZhdGl2ZUF0KHgxLCB4MiwgeDMsIHg0LCB0KTtcbiAgICAgICAgdmFyIGR5ID0gZGVyaXZhdGl2ZUF0KHkxLCB5MiwgeTMsIHk0LCB0KTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5waU1vZChNYXRoLmF0YW4yKGR5LCBkeCkpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3ViaWMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcg5qSt5ZyG55qE5LiA5Lqb6K6h566X77yMXG4gKiAgLSDlkajplb/orqHnrpflj4LogIPvvJpodHRwczovL3d3dy5tYXRoc2lzZnVuLmNvbS9nZW9tZXRyeS9lbGxpcHNlLXBlcmltZXRlci5odG1sXG4gKiAgLSDot53nprvorqHnrpflj4LogIPvvJpodHRwczovL3dldC1yb2JvdHMuZ2hvc3QuaW8vc2ltcGxlLW1ldGhvZC1mb3ItZGlzdGFuY2UtdG8tZWxsaXBzZS9cbiAqIEBhdXRob3IgZHhxNjEzQGdtYWlsLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGNvcHlzaWduKHYxLCB2Mikge1xuICAgIHZhciBhYnN2ID0gTWF0aC5hYnModjEpO1xuICAgIHJldHVybiB2MiA+IDAgPyBhYnN2IDogYWJzdiAqIC0xO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICAgIC8qKlxuICAgICAqIOWMheWbtOebkuiuoeeul1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmpK3lnIbkuK3lv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmpK3lnIbkuK3lv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCDmpK3lnIYgeCDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkg5qSt5ZyGIHkg5pa55ZCR5Y2K5b6EXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDljIXlm7Tnm5JcbiAgICAgKi9cbiAgICBib3g6IGZ1bmN0aW9uICh4LCB5LCByeCwgcnkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHggLSByeCxcbiAgICAgICAgICAgIHk6IHkgLSByeSxcbiAgICAgICAgICAgIHdpZHRoOiByeCAqIDIsXG4gICAgICAgICAgICBoZWlnaHQ6IHJ5ICogMixcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOiuoeeul+WRqOmVv++8jOS9v+eUqOi/keS8vOazlVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmpK3lnIbkuK3lv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmpK3lnIbkuK3lv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCDmpK3lnIYgeCDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkg5qSt5ZyGIHkg5pa55ZCR5Y2K5b6EXG4gICAgICogQHJldHVybiB7bnVtYmVyfSDmpK3lnIblkajplb9cbiAgICAgKi9cbiAgICBsZW5ndGg6IGZ1bmN0aW9uICh4LCB5LCByeCwgcnkpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguUEkgKiAoMyAqIChyeCArIHJ5KSAtIE1hdGguc3FydCgoMyAqIHJ4ICsgcnkpICogKHJ4ICsgMyAqIHJ5KSkpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog6Led56a75qSt5ZyG5pyA6L+R55qE54K5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHggIOakreWchuS4reW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkgIOakreWchuS4reW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4IOakreWchiB4IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSDmpK3lnIYgeSDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDAgIOaMh+WumueahOeCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkwICDmjIflrprnmoTngrkgeVxuICAgICAqIEByZXR1cm4ge29iamVjdH0g5qSt5ZyG5LiK6Led56a75oyH5a6a54K55pyA6L+R55qE54K5XG4gICAgICovXG4gICAgbmVhcmVzdFBvaW50OiBmdW5jdGlvbiAoeCwgeSwgcngsIHJ5LCB4MCwgeTApIHtcbiAgICAgICAgdmFyIGEgPSByeDtcbiAgICAgICAgdmFyIGIgPSByeTtcbiAgICAgICAgLy8g5YGH5aaC5qSt5ZyG5Y2K5b6E5Li6MOWImei/lOWbnuWchuW/g1xuICAgICAgICBpZiAoYSA9PT0gMCB8fCBiID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8g6L2s5o2i5oiQIDDvvIwgMCDkuLrkuK3lv4PnmoTmpK3lnIborqHnrpdcbiAgICAgICAgdmFyIHJlbGF0aXZlWCA9IHgwIC0geDtcbiAgICAgICAgdmFyIHJlbGF0aXZlWSA9IHkwIC0geTtcbiAgICAgICAgdmFyIHB4ID0gTWF0aC5hYnMocmVsYXRpdmVYKTtcbiAgICAgICAgdmFyIHB5ID0gTWF0aC5hYnMocmVsYXRpdmVZKTtcbiAgICAgICAgdmFyIHNxdWFyZUEgPSBhICogYTtcbiAgICAgICAgdmFyIHNxdWFyZUIgPSBiICogYjtcbiAgICAgICAgLy8gY29uc3QgYW5nbGUwID0gTWF0aC5hdGFuMihyZWxhdGl2ZVksIHJlbGF0aXZlWCk7XG4gICAgICAgIHZhciB0ID0gTWF0aC5QSSAvIDQ7XG4gICAgICAgIHZhciBuZWFyZXN0WDsgLy8g5qSt5ZyG5LiK55qE5Lu75LiA54K5XG4gICAgICAgIHZhciBuZWFyZXN0WTtcbiAgICAgICAgLy8g6L+t5LujIDQg5qyhXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgICAgICBuZWFyZXN0WCA9IGEgKiBNYXRoLmNvcyh0KTtcbiAgICAgICAgICAgIG5lYXJlc3RZID0gYiAqIE1hdGguc2luKHQpO1xuICAgICAgICAgICAgdmFyIGV4ID0gKChzcXVhcmVBIC0gc3F1YXJlQikgKiBNYXRoLnBvdyhNYXRoLmNvcyh0KSwgMykpIC8gYTtcbiAgICAgICAgICAgIHZhciBleSA9ICgoc3F1YXJlQiAtIHNxdWFyZUEpICogTWF0aC5wb3coTWF0aC5zaW4odCksIDMpKSAvIGI7XG4gICAgICAgICAgICB2YXIgcngxID0gbmVhcmVzdFggLSBleDtcbiAgICAgICAgICAgIHZhciByeTEgPSBuZWFyZXN0WSAtIGV5O1xuICAgICAgICAgICAgdmFyIHF4ID0gcHggLSBleDtcbiAgICAgICAgICAgIHZhciBxeSA9IHB5IC0gZXk7XG4gICAgICAgICAgICB2YXIgciA9IE1hdGguaHlwb3QocnkxLCByeDEpO1xuICAgICAgICAgICAgdmFyIHEgPSBNYXRoLmh5cG90KHF5LCBxeCk7XG4gICAgICAgICAgICB2YXIgZGVsdGFfYyA9IHIgKiBNYXRoLmFzaW4oKHJ4MSAqIHF5IC0gcnkxICogcXgpIC8gKHIgKiBxKSk7XG4gICAgICAgICAgICB2YXIgZGVsdGFfdCA9IGRlbHRhX2MgLyBNYXRoLnNxcnQoc3F1YXJlQSArIHNxdWFyZUIgLSBuZWFyZXN0WCAqIG5lYXJlc3RYIC0gbmVhcmVzdFkgKiBuZWFyZXN0WSk7XG4gICAgICAgICAgICB0ICs9IGRlbHRhX3Q7XG4gICAgICAgICAgICB0ID0gTWF0aC5taW4oTWF0aC5QSSAvIDIsIE1hdGgubWF4KDAsIHQpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCArIGNvcHlzaWduKG5lYXJlc3RYLCByZWxhdGl2ZVgpLFxuICAgICAgICAgICAgeTogeSArIGNvcHlzaWduKG5lYXJlc3RZLCByZWxhdGl2ZVkpLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog54K55Yiw5qSt5ZyG5pyA6L+R55qE6Led56a7XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHggIOakreWchuS4reW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkgIOakreWchuS4reW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4IOakreWchiB4IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSDmpK3lnIYgeSDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDAgIOaMh+WumueahOeCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkwICDmjIflrprnmoTngrkgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g54K55Yiw5qSt5ZyG55qE6Led56a7XG4gICAgICovXG4gICAgcG9pbnREaXN0YW5jZTogZnVuY3Rpb24gKHgsIHksIHJ4LCByeSwgeDAsIHkwKSB7XG4gICAgICAgIHZhciBuZWFyZXN0UG9pbnQgPSB0aGlzLm5lYXJlc3RQb2ludCh4LCB5LCByeCwgcnksIHgwLCB5MCk7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGlzdGFuY2UobmVhcmVzdFBvaW50LngsIG5lYXJlc3RQb2ludC55LCB4MCwgeTApO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5q+U5L6L6I635Y+W54K5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgg5qSt5ZyG5Lit5b+DIHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geSDmpK3lnIbkuK3lv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCDmpK3lnIYgeCDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkg5qSt5ZyGIHkg5pa55ZCR5Y2K5b6EXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5oyH5a6a5q+U5L6L77yMeOi9tOaWueWQkeS4uiAwXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDngrlcbiAgICAgKi9cbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoeCwgeSwgcngsIHJ5LCB0KSB7XG4gICAgICAgIHZhciBhbmdsZSA9IDIgKiBNYXRoLlBJICogdDsgLy8g5oyJ54Wn6KeS5bqm6L+b6KGM6K6h566X77yM6ICM5LiN5oyJ54Wn5ZGo6ZW/6K6h566XXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4ICsgcnggKiBNYXRoLmNvcyhhbmdsZSksXG4gICAgICAgICAgICB5OiB5ICsgcnkgKiBNYXRoLnNpbihhbmdsZSksXG4gICAgICAgIH07XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDmoLnmja7mr5TkvovorqHnrpfliIfnur/op5LluqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geCDmpK3lnIbkuK3lv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5IOakreWchuS4reW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4IOakreWchiB4IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSDmpK3lnIYgeSDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdCDmjIflrprmr5TkvosgMCAtIDEg5LmL6Ze077yMeOi9tOaWueWQkeS4uiAw44CC5ZyoIDAtMSDojIPlm7TkuYvlpJbmmK/lvqrnjq/ov5jmmK/ov5Tlm54gbnVsbO+8jOi/mOmcgOimgeiwg+aVtFxuICAgICAqIEByZXR1cm4ge251bWJlcn0g6KeS5bqm77yM5ZyoIDAgLSAyUEkg5LmL6Ze0XG4gICAgICovXG4gICAgdGFuZ2VudEFuZ2xlOiBmdW5jdGlvbiAoeCwgeSwgcngsIHJ5LCB0KSB7XG4gICAgICAgIHZhciBhbmdsZSA9IDIgKiBNYXRoLlBJICogdDsgLy8g5oyJ54Wn6KeS5bqm6L+b6KGM6K6h566X77yM6ICM5LiN5oyJ54Wn5ZGo6ZW/6K6h566XXG4gICAgICAgIC8vIOebtOaOpeS9v+eUqCB4LHkg55qE5a+85pWw6K6h566X77yMIHgnID0gLXJ4ICogc2luKHQpOyB5JyA9IHJ5ICogY29zKHQpO1xuICAgICAgICB2YXIgdGFuZ2VudEFuZ2xlID0gTWF0aC5hdGFuMihyeSAqIE1hdGguY29zKGFuZ2xlKSwgLXJ4ICogTWF0aC5zaW4oYW5nbGUpKTtcbiAgICAgICAgLy8g5Lmf5Y+v5Lul5L2/55So5oyH5a6a54K555qE5YiH57q/5pa556iL6K6h566X77yM5oiQ5pys5pyJ5Lqb6auYXG4gICAgICAgIC8vIGNvbnN0IHBvaW50ID0gdGhpcy5wb2ludEF0KDAsIDAsIHJ4LCByeSwgdCk7IC8vIOakreWchueahOWIh+e6v+WQjOakreWchueahOS4reW/g+S4jeebuOWFs1xuICAgICAgICAvLyBsZXQgdGFuZ2VudEFuZ2xlID0gLTEgKiBNYXRoLmF0YW4oKHJ5ICogcnkgKiBwb2ludC54KSAvIChyeCAqIHJ4ICogcG9pbnQueSkpO1xuICAgICAgICAvLyBpZiAoYW5nbGUgPj0gMCAmJiBhbmdsZSA8PSBNYXRoLlBJKSB7XG4gICAgICAgIC8vICAgdGFuZ2VudEFuZ2xlICs9IE1hdGguUEk7XG4gICAgICAgIC8vIH1cbiAgICAgICAgcmV0dXJuIHV0aWxfMS5waU1vZCh0YW5nZW50QW5nbGUpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxsaXBzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xudmFyIHZlYzIgPSByZXF1aXJlKFwiZ2wtbWF0cml4L3ZlYzJcIik7XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgLyoqXG4gICAgICog6K6h566X57q/5q6155qE5YyF5Zu055uSXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkxIOi1t+Wni+eCuSB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgyIOe7k+adn+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gICAgICogQHJldHVybiB7b2JqZWN0fSDljIXlm7Tnm5Llr7nosaFcbiAgICAgKi9cbiAgICBib3g6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldEJCb3hCeUFycmF5KFt4MSwgeDJdLCBbeTEsIHkyXSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDnur/mrrXnmoTplb/luqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDIg57uT5p2f54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTIg57uT5p2f54K5IHlcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IOi3neemu1xuICAgICAqL1xuICAgIGxlbmd0aDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5q+U5L6L6I635Y+W54K5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkxIOi1t+Wni+eCuSB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgyIOe7k+adn+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5oyH5a6a5q+U5L6LXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDljIXlkKsgeCwgeSDnmoTngrlcbiAgICAgKi9cbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6ICgxIC0gdCkgKiB4MSArIHQgKiB4MixcbiAgICAgICAgICAgIHk6ICgxIC0gdCkgKiB5MSArIHQgKiB5MixcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOeCueWIsOe6v+auteeahOi3neemu1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MSDotbflp4vngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MiDnu5PmnZ/ngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmtYvor5XngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmtYvor5XngrkgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g6Led56a7XG4gICAgICovXG4gICAgcG9pbnREaXN0YW5jZTogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4LCB5KSB7XG4gICAgICAgIC8vIOaKleW9sei3neemuyB4MSwgeTEg55qE5ZCR6YeP77yM5YGH6K6+IHAsIHAxLCBwMiDkuInkuKrngrnvvIzmipXlvbHngrnkuLogYVxuICAgICAgICAvLyBwMWEgPSBwMXAucDFwMi98cDFwMnwgKiAocDFwIOeahOWNleS9jeWQkemHjylcbiAgICAgICAgdmFyIGNyb3NzID0gKHgyIC0geDEpICogKHggLSB4MSkgKyAoeTIgLSB5MSkgKiAoeSAtIHkxKTtcbiAgICAgICAgaWYgKGNyb3NzIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIHV0aWxfMS5kaXN0YW5jZSh4MSwgeTEsIHgsIHkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsZW5ndGhTcXVhcmUgPSAoeDIgLSB4MSkgKiAoeDIgLSB4MSkgKyAoeTIgLSB5MSkgKiAoeTIgLSB5MSk7XG4gICAgICAgIGlmIChjcm9zcyA+IGxlbmd0aFNxdWFyZSkge1xuICAgICAgICAgICAgcmV0dXJuIHV0aWxfMS5kaXN0YW5jZSh4MiwgeTIsIHgsIHkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnBvaW50VG9MaW5lKHgxLCB5MSwgeDIsIHkyLCB4LCB5KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOeCueWIsOebtOe6v+eahOi3neemu++8jOiAjOS4jeaYr+eCueWIsOe6v+auteeahOi3neemu1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MSDotbflp4vngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MiDnu5PmnZ/ngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmtYvor5XngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmtYvor5XngrkgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g6Led56a7XG4gICAgICovXG4gICAgcG9pbnRUb0xpbmU6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeCwgeSkge1xuICAgICAgICB2YXIgZCA9IFt4MiAtIHgxLCB5MiAtIHkxXTtcbiAgICAgICAgLy8g5aaC5p6c56uv54K555u4562J77yM5YiZ5Yik5a6a54K55Yiw54K555qE6Led56a7XG4gICAgICAgIGlmICh2ZWMyLmV4YWN0RXF1YWxzKGQsIFswLCAwXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnNxcnQoKHggLSB4MSkgKiAoeCAtIHgxKSArICh5IC0geTEpICogKHkgLSB5MSkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB1ID0gWy1kWzFdLCBkWzBdXTtcbiAgICAgICAgdmVjMi5ub3JtYWxpemUodSwgdSk7XG4gICAgICAgIHZhciBhID0gW3ggLSB4MSwgeSAtIHkxXTtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKHZlYzIuZG90KGEsIHUpKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOe6v+auteeahOinkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MSDotbflp4vngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MiDnu5PmnZ/ngrkgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g5a+85pWwXG4gICAgICovXG4gICAgdGFuZ2VudEFuZ2xlOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYXRhbjIoeTIgLSB5MSwgeDIgLSB4MSk7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHNlZ21lbnRzXzEgPSByZXF1aXJlKFwiLi9zZWdtZW50c1wiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICAgIC8qKlxuICAgICAqIOiuoeeul+WkmuaKmOe6v+eahOWMheWbtOebklxuICAgICAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIggW3gseV0g55qE5b2i5byPXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDljIXlm7Tnm5JcbiAgICAgKi9cbiAgICBib3g6IGZ1bmN0aW9uIChwb2ludHMpIHtcbiAgICAgICAgdmFyIHhBcnIgPSBbXTtcbiAgICAgICAgdmFyIHlBcnIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIHhBcnIucHVzaChwb2ludFswXSk7XG4gICAgICAgICAgICB5QXJyLnB1c2gocG9pbnRbMV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1dGlsXzEuZ2V0QkJveEJ5QXJyYXkoeEFyciwgeUFycik7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDorqHnrpflpJrmipjnur/nmoTplb/luqZcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIIFt4LHldIOeahOW9ouW8j1xuICAgICAqIEByZXR1cm4ge29iamVjdH0g5aSa5p2h6L6555qE6ZW/5bqmXG4gICAgICovXG4gICAgbGVuZ3RoOiBmdW5jdGlvbiAocG9pbnRzKSB7XG4gICAgICAgIHJldHVybiBzZWdtZW50c18xLmxlbmd0aE9mU2VnbWVudChwb2ludHMpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5q+U5L6L6I635Y+W5aSa5oqY57q/55qE54K5XG4gICAgICogQHBhcmFtIHthcnJheX0gcG9pbnRzIOeCueeahOmbhuWQiCBbeCx5XSDnmoTlvaLlvI9cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdCDlnKjlpJrmipjnur/nmoTplb/luqbkuIrnmoTmr5TkvotcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOagueaNruavlOS+i+WAvOiuoeeul+WHuuadpeeahOeCuVxuICAgICAqL1xuICAgIHBvaW50QXQ6IGZ1bmN0aW9uIChwb2ludHMsIHQpIHtcbiAgICAgICAgcmV0dXJuIHNlZ21lbnRzXzEucG9pbnRBdFNlZ21lbnRzKHBvaW50cywgdCk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDmjIflrprngrnliLDlpJrmipjnur/nmoTot53nprtcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIIFt4LHldIOeahOW9ouW8j1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4IOaMh+WumueCueeahCB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkg5oyH5a6a54K555qEIHlcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IOeCueWIsOWkmuaKmOe6v+eahOi3neemu1xuICAgICAqL1xuICAgIHBvaW50RGlzdGFuY2U6IGZ1bmN0aW9uIChwb2ludHMsIHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIHNlZ21lbnRzXzEuZGlzdGFuY2VBdFNlZ21lbnQocG9pbnRzLCB4LCB5KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOagueaNruavlOS+i+iOt+WPluWkmuaKmOe6v+eahOWIh+e6v+inkuW6plxuICAgICAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIggW3gseV0g55qE5b2i5byPXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5Zyo5aSa5oqY57q/55qE6ZW/5bqm5LiK55qE5q+U5L6LXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDmoLnmja7mr5TkvovlgLzorqHnrpflh7rmnaXnmoTop5LluqZcbiAgICAgKi9cbiAgICB0YW5nZW50QW5nbGU6IGZ1bmN0aW9uIChwb2ludHMsIHQpIHtcbiAgICAgICAgcmV0dXJuIHNlZ21lbnRzXzEuYW5nbGVBdFNlZ21lbnRzKHBvaW50cywgdCk7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2x5bGluZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBsaW5lXzEgPSByZXF1aXJlKFwiLi9saW5lXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG52YXIgYmV6aWVyXzEgPSByZXF1aXJlKFwiLi9iZXppZXJcIik7XG4vLyDlt67lgLzlhazlvI9cbmZ1bmN0aW9uIHF1YWRyYXRpY0F0KHAwLCBwMSwgcDIsIHQpIHtcbiAgICB2YXIgb25ldCA9IDEgLSB0O1xuICAgIHJldHVybiBvbmV0ICogb25ldCAqIHAwICsgMiAqIHQgKiBvbmV0ICogcDEgKyB0ICogdCAqIHAyO1xufVxuLy8g5rGC5p6B5YC8XG5mdW5jdGlvbiBleHRyZW1hKHAwLCBwMSwgcDIpIHtcbiAgICB2YXIgYSA9IHAwICsgcDIgLSAyICogcDE7XG4gICAgaWYgKHV0aWxfMS5pc051bWJlckVxdWFsKGEsIDApKSB7XG4gICAgICAgIHJldHVybiBbMC41XTtcbiAgICB9XG4gICAgdmFyIHJzdCA9IChwMCAtIHAxKSAvIGE7XG4gICAgaWYgKHJzdCA8PSAxICYmIHJzdCA+PSAwKSB7XG4gICAgICAgIHJldHVybiBbcnN0XTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xufVxuZnVuY3Rpb24gZGVyaXZhdGl2ZUF0KHAwLCBwMSwgcDIsIHQpIHtcbiAgICByZXR1cm4gMiAqICgxIC0gdCkgKiAocDEgLSBwMCkgKyAyICogdCAqIChwMiAtIHAxKTtcbn1cbi8vIOWIhuWJsui0neWhnuWwlOabsue6v1xuZnVuY3Rpb24gZGl2aWRlUXVhZHJhdGljKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHQpIHtcbiAgICAvLyDliJLliIbngrlcbiAgICB2YXIgeHQgPSBxdWFkcmF0aWNBdCh4MSwgeDIsIHgzLCB0KTtcbiAgICB2YXIgeXQgPSBxdWFkcmF0aWNBdCh5MSwgeTIsIHkzLCB0KTtcbiAgICAvLyDliIblibLnmoTnrKzkuIDmnaHmm7Lnur/nmoTmjqfliLbngrlcbiAgICB2YXIgY29udHJvbFBvaW50MSA9IGxpbmVfMS5kZWZhdWx0LnBvaW50QXQoeDEsIHkxLCB4MiwgeTIsIHQpO1xuICAgIC8vIOWIhuWJsueahOesrOS6jOadoeabsue6v+eahOaOp+WItueCuVxuICAgIHZhciBjb250cm9sUG9pbnQyID0gbGluZV8xLmRlZmF1bHQucG9pbnRBdCh4MiwgeTIsIHgzLCB5MywgdCk7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgW3gxLCB5MSwgY29udHJvbFBvaW50MS54LCBjb250cm9sUG9pbnQxLnksIHh0LCB5dF0sXG4gICAgICAgIFt4dCwgeXQsIGNvbnRyb2xQb2ludDIueCwgY29udHJvbFBvaW50Mi55LCB4MywgeTNdLFxuICAgIF07XG59XG4vLyDkvb/nlKjov63ku6Pms5Xlj5botJ3loZ7lsJTmm7Lnur/nmoTplb/luqZcbmZ1bmN0aW9uIHF1YWRyYXRpY0xlbmd0aCh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCBpdGVyYXRpb25Db3VudCkge1xuICAgIGlmIChpdGVyYXRpb25Db3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gKHV0aWxfMS5kaXN0YW5jZSh4MSwgeTEsIHgyLCB5MikgKyB1dGlsXzEuZGlzdGFuY2UoeDIsIHkyLCB4MywgeTMpICsgdXRpbF8xLmRpc3RhbmNlKHgxLCB5MSwgeDMsIHkzKSkgLyAyO1xuICAgIH1cbiAgICB2YXIgcXVhZHJhdGljcyA9IGRpdmlkZVF1YWRyYXRpYyh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCAwLjUpO1xuICAgIHZhciBsZWZ0ID0gcXVhZHJhdGljc1swXTtcbiAgICB2YXIgcmlnaHQgPSBxdWFkcmF0aWNzWzFdO1xuICAgIGxlZnQucHVzaChpdGVyYXRpb25Db3VudCAtIDEpO1xuICAgIHJpZ2h0LnB1c2goaXRlcmF0aW9uQ291bnQgLSAxKTtcbiAgICByZXR1cm4gcXVhZHJhdGljTGVuZ3RoLmFwcGx5KG51bGwsIGxlZnQpICsgcXVhZHJhdGljTGVuZ3RoLmFwcGx5KG51bGwsIHJpZ2h0KTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICBib3g6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gICAgICAgIHZhciB4RXh0cmVtYSA9IGV4dHJlbWEoeDEsIHgyLCB4MylbMF07XG4gICAgICAgIHZhciB5RXh0cmVtYSA9IGV4dHJlbWEoeTEsIHkyLCB5MylbMF07XG4gICAgICAgIC8vIOaOp+WItueCueS4jeWKoOWFpSBib3gg55qE6K6h566XXG4gICAgICAgIHZhciB4QXJyID0gW3gxLCB4M107XG4gICAgICAgIHZhciB5QXJyID0gW3kxLCB5M107XG4gICAgICAgIGlmICh4RXh0cmVtYSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB4QXJyLnB1c2gocXVhZHJhdGljQXQoeDEsIHgyLCB4MywgeEV4dHJlbWEpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoeUV4dHJlbWEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgeUFyci5wdXNoKHF1YWRyYXRpY0F0KHkxLCB5MiwgeTMsIHlFeHRyZW1hKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHV0aWxfMS5nZXRCQm94QnlBcnJheSh4QXJyLCB5QXJyKTtcbiAgICB9LFxuICAgIGxlbmd0aDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgICAgICAgcmV0dXJuIHF1YWRyYXRpY0xlbmd0aCh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCAzKTtcbiAgICB9LFxuICAgIG5lYXJlc3RQb2ludDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHgwLCB5MCkge1xuICAgICAgICByZXR1cm4gYmV6aWVyXzEubmVhcmVzdFBvaW50KFt4MSwgeDIsIHgzXSwgW3kxLCB5MiwgeTNdLCB4MCwgeTAsIHF1YWRyYXRpY0F0KTtcbiAgICB9LFxuICAgIHBvaW50RGlzdGFuY2U6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4MCwgeTApIHtcbiAgICAgICAgdmFyIHBvaW50ID0gdGhpcy5uZWFyZXN0UG9pbnQoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDAsIHkwKTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kaXN0YW5jZShwb2ludC54LCBwb2ludC55LCB4MCwgeTApO1xuICAgIH0sXG4gICAgaW50ZXJwb2xhdGlvbkF0OiBxdWFkcmF0aWNBdCxcbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgdCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogcXVhZHJhdGljQXQoeDEsIHgyLCB4MywgdCksXG4gICAgICAgICAgICB5OiBxdWFkcmF0aWNBdCh5MSwgeTIsIHkzLCB0KSxcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGRpdmlkZTogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHQpIHtcbiAgICAgICAgcmV0dXJuIGRpdmlkZVF1YWRyYXRpYyh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB0KTtcbiAgICB9LFxuICAgIHRhbmdlbnRBbmdsZTogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHQpIHtcbiAgICAgICAgdmFyIGR4ID0gZGVyaXZhdGl2ZUF0KHgxLCB4MiwgeDMsIHQpO1xuICAgICAgICB2YXIgZHkgPSBkZXJpdmF0aXZlQXQoeTEsIHkyLCB5MywgdCk7XG4gICAgICAgIHZhciBhbmdsZSA9IE1hdGguYXRhbjIoZHksIGR4KTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5waU1vZChhbmdsZSk7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1xdWFkcmF0aWMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRpc3RhbmNlQXRTZWdtZW50ID0gZXhwb3J0cy5hbmdsZUF0U2VnbWVudHMgPSBleHBvcnRzLnBvaW50QXRTZWdtZW50cyA9IGV4cG9ydHMubGVuZ3RoT2ZTZWdtZW50ID0gdm9pZCAwO1xudmFyIGxpbmVfMSA9IHJlcXVpcmUoXCIuL2xpbmVcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGFuYWx5emVQb2ludHMocG9pbnRzKSB7XG4gICAgLy8g6K6h566X5q+P5q6155qE6ZW/5bqm5ZKM5oC755qE6ZW/5bqmXG4gICAgdmFyIHRvdGFsTGVuZ3RoID0gMDtcbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgdmFyIGZyb20gPSBwb2ludHNbaV07XG4gICAgICAgIHZhciB0byA9IHBvaW50c1tpICsgMV07XG4gICAgICAgIHZhciBsZW5ndGhfMSA9IHV0aWxfMS5kaXN0YW5jZShmcm9tWzBdLCBmcm9tWzFdLCB0b1swXSwgdG9bMV0pO1xuICAgICAgICB2YXIgc2VnID0ge1xuICAgICAgICAgICAgZnJvbTogZnJvbSxcbiAgICAgICAgICAgIHRvOiB0byxcbiAgICAgICAgICAgIGxlbmd0aDogbGVuZ3RoXzEsXG4gICAgICAgIH07XG4gICAgICAgIHNlZ21lbnRzLnB1c2goc2VnKTtcbiAgICAgICAgdG90YWxMZW5ndGggKz0gbGVuZ3RoXzE7XG4gICAgfVxuICAgIHJldHVybiB7IHNlZ21lbnRzOiBzZWdtZW50cywgdG90YWxMZW5ndGg6IHRvdGFsTGVuZ3RoIH07XG59XG5mdW5jdGlvbiBsZW5ndGhPZlNlZ21lbnQocG9pbnRzKSB7XG4gICAgaWYgKHBvaW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICB2YXIgdG90YWxMZW5ndGggPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICB2YXIgZnJvbSA9IHBvaW50c1tpXTtcbiAgICAgICAgdmFyIHRvID0gcG9pbnRzW2kgKyAxXTtcbiAgICAgICAgdG90YWxMZW5ndGggKz0gdXRpbF8xLmRpc3RhbmNlKGZyb21bMF0sIGZyb21bMV0sIHRvWzBdLCB0b1sxXSk7XG4gICAgfVxuICAgIHJldHVybiB0b3RhbExlbmd0aDtcbn1cbmV4cG9ydHMubGVuZ3RoT2ZTZWdtZW50ID0gbGVuZ3RoT2ZTZWdtZW50O1xuLyoqXG4gKiDmjInnhafmr5TkvovlnKjmlbDmja7niYfmrrXkuK3ojrflj5bngrlcbiAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIhcbiAqIEBwYXJhbSB7bnVtYmVyfSB0IOeZvuWIhuavlCAwLTFcbiAqIEByZXR1cm4ge29iamVjdH0g54K555qE5Z2Q5qCHXG4gKi9cbmZ1bmN0aW9uIHBvaW50QXRTZWdtZW50cyhwb2ludHMsIHQpIHtcbiAgICAvLyDovrnnlYzliKTmlq1cbiAgICBpZiAodCA+IDEgfHwgdCA8IDAgfHwgcG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBfYSA9IGFuYWx5emVQb2ludHMocG9pbnRzKSwgc2VnbWVudHMgPSBfYS5zZWdtZW50cywgdG90YWxMZW5ndGggPSBfYS50b3RhbExlbmd0aDtcbiAgICAvLyDlpJrkuKrngrnmnInlj6/og73ph43lkIhcbiAgICBpZiAodG90YWxMZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHBvaW50c1swXVswXSxcbiAgICAgICAgICAgIHk6IHBvaW50c1swXVsxXSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8g6K6h566X5q+U5L6LXG4gICAgdmFyIHN0YXJ0UmF0aW8gPSAwO1xuICAgIHZhciBwb2ludCA9IG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VnID0gc2VnbWVudHNbaV07XG4gICAgICAgIHZhciBmcm9tID0gc2VnLmZyb20sIHRvID0gc2VnLnRvO1xuICAgICAgICB2YXIgY3VycmVudFJhdGlvID0gc2VnLmxlbmd0aCAvIHRvdGFsTGVuZ3RoO1xuICAgICAgICBpZiAodCA+PSBzdGFydFJhdGlvICYmIHQgPD0gc3RhcnRSYXRpbyArIGN1cnJlbnRSYXRpbykge1xuICAgICAgICAgICAgdmFyIGxvY2FsUmF0aW8gPSAodCAtIHN0YXJ0UmF0aW8pIC8gY3VycmVudFJhdGlvO1xuICAgICAgICAgICAgcG9pbnQgPSBsaW5lXzEuZGVmYXVsdC5wb2ludEF0KGZyb21bMF0sIGZyb21bMV0sIHRvWzBdLCB0b1sxXSwgbG9jYWxSYXRpbyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGFydFJhdGlvICs9IGN1cnJlbnRSYXRpbztcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50O1xufVxuZXhwb3J0cy5wb2ludEF0U2VnbWVudHMgPSBwb2ludEF0U2VnbWVudHM7XG4vKipcbiAqIOaMieeFp+avlOS+i+WcqOaVsOaNrueJh+auteS4reiOt+WPluWIh+e6v+eahOinkuW6plxuICogQHBhcmFtIHthcnJheX0gcG9pbnRzIOeCueeahOmbhuWQiFxuICogQHBhcmFtIHtudW1iZXJ9IHQg55m+5YiG5q+UIDAtMVxuICovXG5mdW5jdGlvbiBhbmdsZUF0U2VnbWVudHMocG9pbnRzLCB0KSB7XG4gICAgLy8g6L6555WM5Yik5patXG4gICAgaWYgKHQgPiAxIHx8IHQgPCAwIHx8IHBvaW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICB2YXIgX2EgPSBhbmFseXplUG9pbnRzKHBvaW50cyksIHNlZ21lbnRzID0gX2Euc2VnbWVudHMsIHRvdGFsTGVuZ3RoID0gX2EudG90YWxMZW5ndGg7XG4gICAgLy8g6K6h566X5q+U5L6LXG4gICAgdmFyIHN0YXJ0UmF0aW8gPSAwO1xuICAgIHZhciBhbmdsZSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VnID0gc2VnbWVudHNbaV07XG4gICAgICAgIHZhciBmcm9tID0gc2VnLmZyb20sIHRvID0gc2VnLnRvO1xuICAgICAgICB2YXIgY3VycmVudFJhdGlvID0gc2VnLmxlbmd0aCAvIHRvdGFsTGVuZ3RoO1xuICAgICAgICBpZiAodCA+PSBzdGFydFJhdGlvICYmIHQgPD0gc3RhcnRSYXRpbyArIGN1cnJlbnRSYXRpbykge1xuICAgICAgICAgICAgYW5nbGUgPSBNYXRoLmF0YW4yKHRvWzFdIC0gZnJvbVsxXSwgdG9bMF0gLSBmcm9tWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UmF0aW8gKz0gY3VycmVudFJhdGlvO1xuICAgIH1cbiAgICByZXR1cm4gYW5nbGU7XG59XG5leHBvcnRzLmFuZ2xlQXRTZWdtZW50cyA9IGFuZ2xlQXRTZWdtZW50cztcbmZ1bmN0aW9uIGRpc3RhbmNlQXRTZWdtZW50KHBvaW50cywgeCwgeSkge1xuICAgIHZhciBtaW5EaXN0YW5jZSA9IEluZmluaXR5O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgIHZhciBuZXh0UG9pbnQgPSBwb2ludHNbaSArIDFdO1xuICAgICAgICB2YXIgZGlzdGFuY2VfMSA9IGxpbmVfMS5kZWZhdWx0LnBvaW50RGlzdGFuY2UocG9pbnRbMF0sIHBvaW50WzFdLCBuZXh0UG9pbnRbMF0sIG5leHRQb2ludFsxXSwgeCwgeSk7XG4gICAgICAgIGlmIChkaXN0YW5jZV8xIDwgbWluRGlzdGFuY2UpIHtcbiAgICAgICAgICAgIG1pbkRpc3RhbmNlID0gZGlzdGFuY2VfMTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWluRGlzdGFuY2U7XG59XG5leHBvcnRzLmRpc3RhbmNlQXRTZWdtZW50ID0gZGlzdGFuY2VBdFNlZ21lbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZWdtZW50cy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucGlNb2QgPSBleHBvcnRzLmdldEJCb3hSYW5nZSA9IGV4cG9ydHMuZ2V0QkJveEJ5QXJyYXkgPSBleHBvcnRzLmlzTnVtYmVyRXF1YWwgPSBleHBvcnRzLmRpc3RhbmNlID0gdm9pZCAwO1xuZnVuY3Rpb24gbWluTnVtKGFycmF5KSB7XG4gICAgcmV0dXJuIE1hdGgubWluLmFwcGx5KG51bGwsIGFycmF5KTtcbn1cbmZ1bmN0aW9uIG1heE51bShhcnJheSkge1xuICAgIHJldHVybiBNYXRoLm1heC5hcHBseShudWxsLCBhcnJheSk7XG59XG4vKipcbiAqIOS4pOeCueS5i+mXtOeahOi3neemu1xuICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gKiBAcmV0dXJuIHtudW1iZXJ9IOi3neemu1xuICovXG5mdW5jdGlvbiBkaXN0YW5jZSh4MSwgeTEsIHgyLCB5Mikge1xuICAgIHZhciBkeCA9IHgxIC0geDI7XG4gICAgdmFyIGR5ID0geTEgLSB5MjtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbn1cbmV4cG9ydHMuZGlzdGFuY2UgPSBkaXN0YW5jZTtcbmZ1bmN0aW9uIGlzTnVtYmVyRXF1YWwodjEsIHYyKSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKHYxIC0gdjIpIDwgMC4wMDE7XG59XG5leHBvcnRzLmlzTnVtYmVyRXF1YWwgPSBpc051bWJlckVxdWFsO1xuZnVuY3Rpb24gZ2V0QkJveEJ5QXJyYXkoeEFyciwgeUFycikge1xuICAgIHZhciBtaW5YID0gbWluTnVtKHhBcnIpO1xuICAgIHZhciBtaW5ZID0gbWluTnVtKHlBcnIpO1xuICAgIHZhciBtYXhYID0gbWF4TnVtKHhBcnIpO1xuICAgIHZhciBtYXhZID0gbWF4TnVtKHlBcnIpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IG1pblgsXG4gICAgICAgIHk6IG1pblksXG4gICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICB9O1xufVxuZXhwb3J0cy5nZXRCQm94QnlBcnJheSA9IGdldEJCb3hCeUFycmF5O1xuZnVuY3Rpb24gZ2V0QkJveFJhbmdlKHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluWDogbWluTnVtKFt4MSwgeDJdKSxcbiAgICAgICAgbWF4WDogbWF4TnVtKFt4MSwgeDJdKSxcbiAgICAgICAgbWluWTogbWluTnVtKFt5MSwgeTJdKSxcbiAgICAgICAgbWF4WTogbWF4TnVtKFt5MSwgeTJdKSxcbiAgICB9O1xufVxuZXhwb3J0cy5nZXRCQm94UmFuZ2UgPSBnZXRCQm94UmFuZ2U7XG5mdW5jdGlvbiBwaU1vZChhbmdsZSkge1xuICAgIHJldHVybiAoYW5nbGUgKyBNYXRoLlBJICogMikgJSAoTWF0aC5QSSAqIDIpO1xufVxuZXhwb3J0cy5waU1vZCA9IHBpTW9kO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dXRpbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdfYmFzZV8xID0gcmVxdWlyZShcIkBhbnR2L2ctYmFzZVwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4vY29uc3RhbnRcIik7XG52YXIgZHJhd18xID0gcmVxdWlyZShcIi4vdXRpbC9kcmF3XCIpO1xudmFyIHN2Z18xID0gcmVxdWlyZShcIi4vdXRpbC9zdmdcIik7XG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi91dGlsL2RvbVwiKTtcbnZhciBTaGFwZSA9IHJlcXVpcmUoXCIuL3NoYXBlXCIpO1xudmFyIGdyb3VwXzEgPSByZXF1aXJlKFwiLi9ncm91cFwiKTtcbnZhciBkZWZzXzEgPSByZXF1aXJlKFwiLi9kZWZzXCIpO1xudmFyIENhbnZhcyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhDYW52YXMsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ2FudmFzKGNmZykge1xuICAgICAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IGF1dG9EcmF3OiB0cnVlLCBcbiAgICAgICAgICAgIC8vIOiuvue9rua4suafk+W8leaTjuS4uiBjYW52YXPvvIzlj6ror7vlsZ7mgKdcbiAgICAgICAgICAgIHJlbmRlcmVyOiAnc3ZnJyB9KSkgfHwgdGhpcztcbiAgICB9XG4gICAgQ2FudmFzLnByb3RvdHlwZS5nZXRTaGFwZUJhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBTaGFwZTtcbiAgICB9O1xuICAgIENhbnZhcy5wcm90b3R5cGUuZ2V0R3JvdXBCYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gZ3JvdXBfMS5kZWZhdWx0O1xuICAgIH07XG4gICAgLy8g6KaG55uWIENvbnRhaW5lciDkuK3pgJrov4fpgY3ljobnmoTmlrnlvI/ojrflj5Ygc2hhcGUg5a+56LGh55qE6YC76L6R77yM55u05o6l6LWwIFNWRyDnmoQgZG9tIOaLvuWPluWNs+WPr1xuICAgIENhbnZhcy5wcm90b3R5cGUuZ2V0U2hhcGUgPSBmdW5jdGlvbiAoeCwgeSwgZXYpIHtcbiAgICAgICAgdmFyIHRhcmdldCA9IGV2LnRhcmdldCB8fCBldi5zcmNFbGVtZW50O1xuICAgICAgICBpZiAoIWNvbnN0YW50XzEuU0hBUEVfVE9fVEFHU1t0YXJnZXQudGFnTmFtZV0pIHtcbiAgICAgICAgICAgIHZhciBwYXJlbnRfMSA9IHRhcmdldC5wYXJlbnROb2RlO1xuICAgICAgICAgICAgd2hpbGUgKHBhcmVudF8xICYmICFjb25zdGFudF8xLlNIQVBFX1RPX1RBR1NbcGFyZW50XzEudGFnTmFtZV0pIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRfMSA9IHBhcmVudF8xLnBhcmVudE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0YXJnZXQgPSBwYXJlbnRfMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5maW5kKGZ1bmN0aW9uIChjaGlsZCkgeyByZXR1cm4gY2hpbGQuZ2V0KCdlbCcpID09PSB0YXJnZXQ7IH0pO1xuICAgIH07XG4gICAgLy8g5aSN5YaZ5Z+657G755qE5pa55rOV55Sf5oiQ5qCH562+XG4gICAgQ2FudmFzLnByb3RvdHlwZS5jcmVhdGVEb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50ID0gZG9tXzEuY3JlYXRlU1ZHRWxlbWVudCgnc3ZnJyk7XG4gICAgICAgIHZhciBjb250ZXh0ID0gbmV3IGRlZnNfMS5kZWZhdWx0KGVsZW1lbnQpO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBcIlwiICsgdGhpcy5nZXQoJ3dpZHRoJykpO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgXCJcIiArIHRoaXMuZ2V0KCdoZWlnaHQnKSk7XG4gICAgICAgIC8vIOe8k+WtmCBjb250ZXh0IOWvueixoVxuICAgICAgICB0aGlzLnNldCgnY29udGV4dCcsIGNvbnRleHQpO1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOS4gOS6m+aWueazleiwg+eUqOS8muW8lei1t+eUu+W4g+WPmOWMllxuICAgICAqIEBwYXJhbSB7Q2hhbmdlVHlwZX0gY2hhbmdlVHlwZSDmlLnlj5jnmoTnsbvlnotcbiAgICAgKi9cbiAgICBDYW52YXMucHJvdG90eXBlLm9uQ2FudmFzQ2hhbmdlID0gZnVuY3Rpb24gKGNoYW5nZVR5cGUpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmdldCgnY29udGV4dCcpO1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgaWYgKGNoYW5nZVR5cGUgPT09ICdzb3J0Jykge1xuICAgICAgICAgICAgdmFyIGNoaWxkcmVuXzEgPSB0aGlzLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIGlmIChjaGlsZHJlbl8xICYmIGNoaWxkcmVuXzEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZG9tXzEuc29ydERvbSh0aGlzLCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRyZW5fMS5pbmRleE9mKGEpIC0gY2hpbGRyZW5fMS5pbmRleE9mKGIpID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY2hhbmdlVHlwZSA9PT0gJ2NsZWFyJykge1xuICAgICAgICAgICAgLy8gZWwgbWF5YmUgbnVsbCBmb3IgY2FudmFzXG4gICAgICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICAgICAgICAvLyDmuIXnqbogU1ZHIOWFg+e0oFxuICAgICAgICAgICAgICAgIGVsLmlubmVySFRNTCA9ICcnO1xuICAgICAgICAgICAgICAgIHZhciBkZWZzRWwgPSBjb250ZXh0LmVsO1xuICAgICAgICAgICAgICAgIC8vIOa4heepuiBkZWZzIOWFg+e0oFxuICAgICAgICAgICAgICAgIGRlZnNFbC5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgICAgICAgICAvLyDlsIbmuIXnqbrlkI7nmoQgZGVmcyDlhYPntKDmjILovb3liLAgZWwg5LiLXG4gICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQoZGVmc0VsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnbWF0cml4Jykge1xuICAgICAgICAgICAgc3ZnXzEuc2V0VHJhbnNmb3JtKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNoYW5nZVR5cGUgPT09ICdjbGlwJykge1xuICAgICAgICAgICAgc3ZnXzEuc2V0Q2xpcCh0aGlzLCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnY2hhbmdlU2l6ZScpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBcIlwiICsgdGhpcy5nZXQoJ3dpZHRoJykpO1xuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBcIlwiICsgdGhpcy5nZXQoJ2hlaWdodCcpKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5aSN5YaZ5Z+657G755qEIGRyYXcg5pa55rOVXG4gICAgQ2FudmFzLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGV4dCA9IHRoaXMuZ2V0KCdjb250ZXh0Jyk7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgc3ZnXzEuc2V0Q2xpcCh0aGlzLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgZHJhd18xLmRyYXdDaGlsZHJlbihjb250ZXh0LCBjaGlsZHJlbik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBDYW52YXM7XG59KGdfYmFzZV8xLkFic3RyYWN0Q2FudmFzKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDYW52YXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jYW52YXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlNIQVBFX1RPX1RBR1MgPSB7XG4gICAgcmVjdDogJ3BhdGgnLFxuICAgIGNpcmNsZTogJ2NpcmNsZScsXG4gICAgbGluZTogJ2xpbmUnLFxuICAgIHBhdGg6ICdwYXRoJyxcbiAgICBtYXJrZXI6ICdwYXRoJyxcbiAgICB0ZXh0OiAndGV4dCcsXG4gICAgcG9seWxpbmU6ICdwb2x5bGluZScsXG4gICAgcG9seWdvbjogJ3BvbHlnb24nLFxuICAgIGltYWdlOiAnaW1hZ2UnLFxuICAgIGVsbGlwc2U6ICdlbGxpcHNlJyxcbiAgICBkb206ICdmb3JlaWduT2JqZWN0Jyxcbn07XG5leHBvcnRzLlNWR19BVFRSX01BUCA9IHtcbiAgICBvcGFjaXR5OiAnb3BhY2l0eScsXG4gICAgZmlsbFN0eWxlOiAnZmlsbCcsXG4gICAgZmlsbDogJ2ZpbGwnLFxuICAgIGZpbGxPcGFjaXR5OiAnZmlsbC1vcGFjaXR5JyxcbiAgICBzdHJva2VTdHlsZTogJ3N0cm9rZScsXG4gICAgc3Ryb2tlT3BhY2l0eTogJ3N0cm9rZS1vcGFjaXR5JyxcbiAgICBzdHJva2U6ICdzdHJva2UnLFxuICAgIHg6ICd4JyxcbiAgICB5OiAneScsXG4gICAgcjogJ3InLFxuICAgIHJ4OiAncngnLFxuICAgIHJ5OiAncnknLFxuICAgIHdpZHRoOiAnd2lkdGgnLFxuICAgIGhlaWdodDogJ2hlaWdodCcsXG4gICAgeDE6ICd4MScsXG4gICAgeDI6ICd4MicsXG4gICAgeTE6ICd5MScsXG4gICAgeTI6ICd5MicsXG4gICAgbGluZUNhcDogJ3N0cm9rZS1saW5lY2FwJyxcbiAgICBsaW5lSm9pbjogJ3N0cm9rZS1saW5lam9pbicsXG4gICAgbGluZVdpZHRoOiAnc3Ryb2tlLXdpZHRoJyxcbiAgICBsaW5lRGFzaDogJ3N0cm9rZS1kYXNoYXJyYXknLFxuICAgIGxpbmVEYXNoT2Zmc2V0OiAnc3Ryb2tlLWRhc2hvZmZzZXQnLFxuICAgIG1pdGVyTGltaXQ6ICdzdHJva2UtbWl0ZXJsaW1pdCcsXG4gICAgZm9udDogJ2ZvbnQnLFxuICAgIGZvbnRTaXplOiAnZm9udC1zaXplJyxcbiAgICBmb250U3R5bGU6ICdmb250LXN0eWxlJyxcbiAgICBmb250VmFyaWFudDogJ2ZvbnQtdmFyaWFudCcsXG4gICAgZm9udFdlaWdodDogJ2ZvbnQtd2VpZ2h0JyxcbiAgICBmb250RmFtaWx5OiAnZm9udC1mYW1pbHknLFxuICAgIHN0YXJ0QXJyb3c6ICdtYXJrZXItc3RhcnQnLFxuICAgIGVuZEFycm93OiAnbWFya2VyLWVuZCcsXG4gICAgcGF0aDogJ2QnLFxuICAgIGNsYXNzOiAnY2xhc3MnLFxuICAgIGlkOiAnaWQnLFxuICAgIHN0eWxlOiAnc3R5bGUnLFxuICAgIHByZXNlcnZlQXNwZWN0UmF0aW86ICdwcmVzZXJ2ZUFzcGVjdFJhdGlvJyxcbn07XG5leHBvcnRzLkVWRU5UUyA9IFtcbiAgICAnY2xpY2snLFxuICAgICdtb3VzZWRvd24nLFxuICAgICdtb3VzZXVwJyxcbiAgICAnZGJsY2xpY2snLFxuICAgICdjb250ZXh0bWVudScsXG4gICAgJ21vdXNlZW50ZXInLFxuICAgICdtb3VzZWxlYXZlJyxcbiAgICAnbW91c2VvdmVyJyxcbiAgICAnbW91c2VvdXQnLFxuICAgICdtb3VzZW1vdmUnLFxuICAgICd3aGVlbCcsXG5dO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgYXJyb3dcbiAqIEBhdXRob3IgZGVuZ2Z1cGluZ19kZXZlbG9wQDE2My5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZG9tXCIpO1xudmFyIEFycm93ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEFycm93KGF0dHJzLCB0eXBlKSB7XG4gICAgICAgIHRoaXMuY2ZnID0ge307XG4gICAgICAgIHZhciBlbCA9IGRvbV8xLmNyZWF0ZVNWR0VsZW1lbnQoJ21hcmtlcicpO1xuICAgICAgICB2YXIgaWQgPSB1dGlsXzEudW5pcXVlSWQoJ21hcmtlcl8nKTtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdpZCcsIGlkKTtcbiAgICAgICAgdmFyIHNoYXBlID0gZG9tXzEuY3JlYXRlU1ZHRWxlbWVudCgncGF0aCcpO1xuICAgICAgICBzaGFwZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIGF0dHJzLnN0cm9rZSB8fCAnbm9uZScpO1xuICAgICAgICBzaGFwZS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBhdHRycy5maWxsIHx8ICdub25lJyk7XG4gICAgICAgIGVsLmFwcGVuZENoaWxkKHNoYXBlKTtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdvdmVyZmxvdycsICd2aXNpYmxlJyk7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnb3JpZW50JywgJ2F1dG8tc3RhcnQtcmV2ZXJzZScpO1xuICAgICAgICB0aGlzLmVsID0gZWw7XG4gICAgICAgIHRoaXMuY2hpbGQgPSBzaGFwZTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICB2YXIgY2ZnID0gYXR0cnNbdHlwZSA9PT0gJ21hcmtlci1zdGFydCcgPyAnc3RhcnRBcnJvdycgOiAnZW5kQXJyb3cnXTtcbiAgICAgICAgdGhpcy5zdHJva2UgPSBhdHRycy5zdHJva2UgfHwgJyMwMDAnO1xuICAgICAgICBpZiAoY2ZnID09PSB0cnVlKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXREZWZhdWx0UGF0aCh0eXBlLCBzaGFwZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNmZyA9IGNmZzsgLy8gd2hlbiBhcnJvdyBjb25maWcgZXhpc3RzXG4gICAgICAgICAgICB0aGlzLl9zZXRNYXJrZXIoYXR0cnMubGluZVdpZHRoLCBzaGFwZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIEFycm93LnByb3RvdHlwZS5tYXRjaCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgQXJyb3cucHJvdG90eXBlLl9zZXREZWZhdWx0UGF0aCA9IGZ1bmN0aW9uICh0eXBlLCBlbCkge1xuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy5lbDtcbiAgICAgICAgLy8g6buY6K6k566t5aS055qE6L656ZW/5Li6IDEw77yM5aS56KeS5Li6IDYwIOW6plxuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2QnLCBcIk0wLDAgTFwiICsgMTAgKiBNYXRoLmNvcyhNYXRoLlBJIC8gNikgKyBcIiw1IEwwLDEwXCIpO1xuICAgICAgICBwYXJlbnQuc2V0QXR0cmlidXRlKCdyZWZYJywgXCJcIiArIDEwICogTWF0aC5jb3MoTWF0aC5QSSAvIDYpKTtcbiAgICAgICAgcGFyZW50LnNldEF0dHJpYnV0ZSgncmVmWScsIFwiXCIgKyA1KTtcbiAgICB9O1xuICAgIEFycm93LnByb3RvdHlwZS5fc2V0TWFya2VyID0gZnVuY3Rpb24gKHIsIGVsKSB7XG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzLmVsO1xuICAgICAgICB2YXIgcGF0aCA9IHRoaXMuY2ZnLnBhdGg7XG4gICAgICAgIHZhciBkID0gdGhpcy5jZmcuZDtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KHBhdGgpKSB7XG4gICAgICAgICAgICBwYXRoID0gcGF0aFxuICAgICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKHNlZ21lbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VnbWVudC5qb2luKCcgJyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5qb2luKCcnKTtcbiAgICAgICAgfVxuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2QnLCBwYXRoKTtcbiAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgaWYgKGQpIHtcbiAgICAgICAgICAgIHBhcmVudC5zZXRBdHRyaWJ1dGUoJ3JlZlgnLCBcIlwiICsgZCAvIHIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBcnJvdy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGZpbGwpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jaGlsZDtcbiAgICAgICAgaWYgKGNoaWxkLmF0dHIpIHtcbiAgICAgICAgICAgIGNoaWxkLmF0dHIoJ2ZpbGwnLCBmaWxsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNoaWxkLnNldEF0dHJpYnV0ZSgnZmlsbCcsIGZpbGwpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gQXJyb3c7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJyb3c7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hcnJvdy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyBjbGlwXG4gKiBAYXV0aG9yIGRlbmdmdXBpbmdfZGV2ZWxvcEAxNjMuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi91dGlsL2RvbVwiKTtcbnZhciBDbGlwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENsaXAoY2ZnKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdjbGlwJztcbiAgICAgICAgdGhpcy5jZmcgPSB7fTtcbiAgICAgICAgdmFyIGVsID0gZG9tXzEuY3JlYXRlU1ZHRWxlbWVudCgnY2xpcFBhdGgnKTtcbiAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICB0aGlzLmlkID0gdXRpbF8xLnVuaXF1ZUlkKCdjbGlwXycpO1xuICAgICAgICBlbC5pZCA9IHRoaXMuaWQ7XG4gICAgICAgIHZhciBzaGFwZUVsID0gY2ZnLmNmZy5lbDtcbiAgICAgICAgZWwuYXBwZW5kQ2hpbGQoc2hhcGVFbCk7XG4gICAgICAgIHRoaXMuY2ZnID0gY2ZnO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgQ2xpcC5wcm90b3R5cGUubWF0Y2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIENsaXAucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5lbDtcbiAgICAgICAgZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XG4gICAgfTtcbiAgICByZXR1cm4gQ2xpcDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDbGlwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xpcC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyBncmFkaWVudFxuICogQGF1dGhvciBkZW5nZnVwaW5nX2RldmVsb3BAMTYzLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9kb21cIik7XG52YXIgcmVnZXhMRyA9IC9ebFxccypcXChcXHMqKFtcXGQuXSspXFxzKlxcKVxccyooLiopL2k7XG52YXIgcmVnZXhSRyA9IC9eclxccypcXChcXHMqKFtcXGQuXSspXFxzKixcXHMqKFtcXGQuXSspXFxzKixcXHMqKFtcXGQuXSspXFxzKlxcKVxccyooLiopL2k7XG52YXIgcmVnZXhDb2xvclN0b3AgPSAvW1xcZC5dKzooI1teXFxzXSt8W15cXCldK1xcKSkvZ2k7XG5mdW5jdGlvbiBhZGRTdG9wKHN0ZXBzKSB7XG4gICAgdmFyIGFyciA9IHN0ZXBzLm1hdGNoKHJlZ2V4Q29sb3JTdG9wKTtcbiAgICBpZiAoIWFycikge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHZhciBzdG9wcyA9ICcnO1xuICAgIGFyci5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIGEgPSBhLnNwbGl0KCc6Jyk7XG4gICAgICAgIGIgPSBiLnNwbGl0KCc6Jyk7XG4gICAgICAgIHJldHVybiBOdW1iZXIoYVswXSkgLSBOdW1iZXIoYlswXSk7XG4gICAgfSk7XG4gICAgdXRpbF8xLmVhY2goYXJyLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICBpdGVtID0gaXRlbS5zcGxpdCgnOicpO1xuICAgICAgICBzdG9wcyArPSBcIjxzdG9wIG9mZnNldD1cXFwiXCIgKyBpdGVtWzBdICsgXCJcXFwiIHN0b3AtY29sb3I9XFxcIlwiICsgaXRlbVsxXSArIFwiXFxcIj48L3N0b3A+XCI7XG4gICAgfSk7XG4gICAgcmV0dXJuIHN0b3BzO1xufVxuZnVuY3Rpb24gcGFyc2VMaW5lR3JhZGllbnQoY29sb3IsIGVsKSB7XG4gICAgdmFyIGFyciA9IHJlZ2V4TEcuZXhlYyhjb2xvcik7XG4gICAgdmFyIGFuZ2xlID0gdXRpbF8xLm1vZCh1dGlsXzEudG9SYWRpYW4ocGFyc2VGbG9hdChhcnJbMV0pKSwgTWF0aC5QSSAqIDIpO1xuICAgIHZhciBzdGVwcyA9IGFyclsyXTtcbiAgICB2YXIgc3RhcnQ7XG4gICAgdmFyIGVuZDtcbiAgICBpZiAoYW5nbGUgPj0gMCAmJiBhbmdsZSA8IDAuNSAqIE1hdGguUEkpIHtcbiAgICAgICAgc3RhcnQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgZW5kID0ge1xuICAgICAgICAgICAgeDogMSxcbiAgICAgICAgICAgIHk6IDEsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGVsc2UgaWYgKDAuNSAqIE1hdGguUEkgPD0gYW5nbGUgJiYgYW5nbGUgPCBNYXRoLlBJKSB7XG4gICAgICAgIHN0YXJ0ID0ge1xuICAgICAgICAgICAgeDogMSxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgIH07XG4gICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAxLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBlbHNlIGlmIChNYXRoLlBJIDw9IGFuZ2xlICYmIGFuZ2xlIDwgMS41ICogTWF0aC5QSSkge1xuICAgICAgICBzdGFydCA9IHtcbiAgICAgICAgICAgIHg6IDEsXG4gICAgICAgICAgICB5OiAxLFxuICAgICAgICB9O1xuICAgICAgICBlbmQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0ge1xuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDEsXG4gICAgICAgIH07XG4gICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgIHg6IDEsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICB2YXIgdGFuVGhldGEgPSBNYXRoLnRhbihhbmdsZSk7XG4gICAgdmFyIHRhblRoZXRhMiA9IHRhblRoZXRhICogdGFuVGhldGE7XG4gICAgdmFyIHggPSAoZW5kLnggLSBzdGFydC54ICsgdGFuVGhldGEgKiAoZW5kLnkgLSBzdGFydC55KSkgLyAodGFuVGhldGEyICsgMSkgKyBzdGFydC54O1xuICAgIHZhciB5ID0gKHRhblRoZXRhICogKGVuZC54IC0gc3RhcnQueCArIHRhblRoZXRhICogKGVuZC55IC0gc3RhcnQueSkpKSAvICh0YW5UaGV0YTIgKyAxKSArIHN0YXJ0Lnk7XG4gICAgZWwuc2V0QXR0cmlidXRlKCd4MScsIHN0YXJ0LngpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgneTEnLCBzdGFydC55KTtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ3gyJywgeCk7XG4gICAgZWwuc2V0QXR0cmlidXRlKCd5MicsIHkpO1xuICAgIGVsLmlubmVySFRNTCA9IGFkZFN0b3Aoc3RlcHMpO1xufVxuZnVuY3Rpb24gcGFyc2VSYWRpYWxHcmFkaWVudChjb2xvciwgc2VsZikge1xuICAgIHZhciBhcnIgPSByZWdleFJHLmV4ZWMoY29sb3IpO1xuICAgIHZhciBjeCA9IHBhcnNlRmxvYXQoYXJyWzFdKTtcbiAgICB2YXIgY3kgPSBwYXJzZUZsb2F0KGFyclsyXSk7XG4gICAgdmFyIHIgPSBwYXJzZUZsb2F0KGFyclszXSk7XG4gICAgdmFyIHN0ZXBzID0gYXJyWzRdO1xuICAgIHNlbGYuc2V0QXR0cmlidXRlKCdjeCcsIGN4KTtcbiAgICBzZWxmLnNldEF0dHJpYnV0ZSgnY3knLCBjeSk7XG4gICAgc2VsZi5zZXRBdHRyaWJ1dGUoJ3InLCByKTtcbiAgICBzZWxmLmlubmVySFRNTCA9IGFkZFN0b3Aoc3RlcHMpO1xufVxudmFyIEdyYWRpZW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdyYWRpZW50KGNmZykge1xuICAgICAgICB0aGlzLmNmZyA9IHt9O1xuICAgICAgICB2YXIgZWwgPSBudWxsO1xuICAgICAgICB2YXIgaWQgPSB1dGlsXzEudW5pcXVlSWQoJ2dyYWRpZW50XycpO1xuICAgICAgICBpZiAoY2ZnLnRvTG93ZXJDYXNlKClbMF0gPT09ICdsJykge1xuICAgICAgICAgICAgZWwgPSBkb21fMS5jcmVhdGVTVkdFbGVtZW50KCdsaW5lYXJHcmFkaWVudCcpO1xuICAgICAgICAgICAgcGFyc2VMaW5lR3JhZGllbnQoY2ZnLCBlbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlbCA9IGRvbV8xLmNyZWF0ZVNWR0VsZW1lbnQoJ3JhZGlhbEdyYWRpZW50Jyk7XG4gICAgICAgICAgICBwYXJzZVJhZGlhbEdyYWRpZW50KGNmZywgZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gICAgICAgIHRoaXMuZWwgPSBlbDtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICB0aGlzLmNmZyA9IGNmZztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIEdyYWRpZW50LnByb3RvdHlwZS5tYXRjaCA9IGZ1bmN0aW9uICh0eXBlLCBhdHRyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNmZyA9PT0gYXR0cjtcbiAgICB9O1xuICAgIHJldHVybiBHcmFkaWVudDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBHcmFkaWVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdyYWRpZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IGRlZnNcbiAqIEBhdXRob3IgZGVuZ2Z1cGluZ19kZXZlbG9wQDE2My5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdyYWRpZW50XzEgPSByZXF1aXJlKFwiLi9ncmFkaWVudFwiKTtcbnZhciBzaGFkb3dfMSA9IHJlcXVpcmUoXCIuL3NoYWRvd1wiKTtcbnZhciBhcnJvd18xID0gcmVxdWlyZShcIi4vYXJyb3dcIik7XG52YXIgY2xpcF8xID0gcmVxdWlyZShcIi4vY2xpcFwiKTtcbnZhciBwYXR0ZXJuXzEgPSByZXF1aXJlKFwiLi9wYXR0ZXJuXCIpO1xudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZG9tXCIpO1xudmFyIERlZnMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRGVmcyhjYW52YXMpIHtcbiAgICAgICAgdmFyIGVsID0gZG9tXzEuY3JlYXRlU1ZHRWxlbWVudCgnZGVmcycpO1xuICAgICAgICB2YXIgaWQgPSB1dGlsXzEudW5pcXVlSWQoJ2RlZnNfJyk7XG4gICAgICAgIGVsLmlkID0gaWQ7XG4gICAgICAgIGNhbnZhcy5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgIHRoaXMuY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgdGhpcy5kZWZhdWx0QXJyb3cgPSB7fTtcbiAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICB0aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICB9XG4gICAgRGVmcy5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uICh0eXBlLCBhdHRyKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG4gICAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5baV0ubWF0Y2godHlwZSwgYXR0cikpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjaGlsZHJlbltpXS5pZDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgRGVmcy5wcm90b3R5cGUuZmluZEJ5SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjtcbiAgICAgICAgdmFyIGZsYWcgPSBudWxsO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5baV0uaWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgZmxhZyA9IGNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbGFnO1xuICAgIH07XG4gICAgRGVmcy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGl0ZW0pO1xuICAgICAgICBpdGVtLmNhbnZhcyA9IHRoaXMuY2FudmFzO1xuICAgICAgICBpdGVtLnBhcmVudCA9IHRoaXM7XG4gICAgfTtcbiAgICBEZWZzLnByb3RvdHlwZS5nZXREZWZhdWx0QXJyb3cgPSBmdW5jdGlvbiAoYXR0cnMsIG5hbWUpIHtcbiAgICAgICAgdmFyIHN0cm9rZSA9IGF0dHJzLnN0cm9rZSB8fCBhdHRycy5zdHJva2VTdHlsZTtcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdEFycm93W3N0cm9rZV0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlZmF1bHRBcnJvd1tzdHJva2VdLmlkO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhcnJvdyA9IG5ldyBhcnJvd18xLmRlZmF1bHQoYXR0cnMsIG5hbWUpO1xuICAgICAgICB0aGlzLmRlZmF1bHRBcnJvd1tzdHJva2VdID0gYXJyb3c7XG4gICAgICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQoYXJyb3cuZWwpO1xuICAgICAgICB0aGlzLmFkZChhcnJvdyk7XG4gICAgICAgIHJldHVybiBhcnJvdy5pZDtcbiAgICB9O1xuICAgIERlZnMucHJvdG90eXBlLmFkZEdyYWRpZW50ID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB2YXIgZ3JhZGllbnQgPSBuZXcgZ3JhZGllbnRfMS5kZWZhdWx0KGNmZyk7XG4gICAgICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQoZ3JhZGllbnQuZWwpO1xuICAgICAgICB0aGlzLmFkZChncmFkaWVudCk7XG4gICAgICAgIHJldHVybiBncmFkaWVudC5pZDtcbiAgICB9O1xuICAgIERlZnMucHJvdG90eXBlLmFkZEFycm93ID0gZnVuY3Rpb24gKGF0dHJzLCBuYW1lKSB7XG4gICAgICAgIHZhciBhcnJvdyA9IG5ldyBhcnJvd18xLmRlZmF1bHQoYXR0cnMsIG5hbWUpO1xuICAgICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKGFycm93LmVsKTtcbiAgICAgICAgdGhpcy5hZGQoYXJyb3cpO1xuICAgICAgICByZXR1cm4gYXJyb3cuaWQ7XG4gICAgfTtcbiAgICBEZWZzLnByb3RvdHlwZS5hZGRTaGFkb3cgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHZhciBzaGFkb3cgPSBuZXcgc2hhZG93XzEuZGVmYXVsdChjZmcpO1xuICAgICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKHNoYWRvdy5lbCk7XG4gICAgICAgIHRoaXMuYWRkKHNoYWRvdyk7XG4gICAgICAgIHJldHVybiBzaGFkb3cuaWQ7XG4gICAgfTtcbiAgICBEZWZzLnByb3RvdHlwZS5hZGRQYXR0ZXJuID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IG5ldyBwYXR0ZXJuXzEuZGVmYXVsdChjZmcpO1xuICAgICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKHBhdHRlcm4uZWwpO1xuICAgICAgICB0aGlzLmFkZChwYXR0ZXJuKTtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4uaWQ7XG4gICAgfTtcbiAgICBEZWZzLnByb3RvdHlwZS5hZGRDbGlwID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB2YXIgY2xpcCA9IG5ldyBjbGlwXzEuZGVmYXVsdChjZmcpO1xuICAgICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKGNsaXAuZWwpO1xuICAgICAgICB0aGlzLmFkZChjbGlwKTtcbiAgICAgICAgcmV0dXJuIGNsaXAuaWQ7XG4gICAgfTtcbiAgICByZXR1cm4gRGVmcztcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEZWZzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgcGF0dGVyblxuICogQGF1dGhvciBkZW5nZnVwaW5nX2RldmVsb3BAMTYzLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9kb21cIik7XG52YXIgcmVnZXhQUiA9IC9ecFxccypcXChcXHMqKFtheHluXSlcXHMqXFwpXFxzKiguKikvaTtcbnZhciBQYXR0ZXJuID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFBhdHRlcm4oY2ZnKSB7XG4gICAgICAgIHRoaXMuY2ZnID0ge307XG4gICAgICAgIHZhciBlbCA9IGRvbV8xLmNyZWF0ZVNWR0VsZW1lbnQoJ3BhdHRlcm4nKTtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdwYXR0ZXJuVW5pdHMnLCAndXNlclNwYWNlT25Vc2UnKTtcbiAgICAgICAgdmFyIGNoaWxkID0gZG9tXzEuY3JlYXRlU1ZHRWxlbWVudCgnaW1hZ2UnKTtcbiAgICAgICAgZWwuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICAgICAgICB2YXIgaWQgPSB1dGlsXzEudW5pcXVlSWQoJ3BhdHRlcm5fJyk7XG4gICAgICAgIGVsLmlkID0gaWQ7XG4gICAgICAgIHRoaXMuZWwgPSBlbDtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICB0aGlzLmNmZyA9IGNmZztcbiAgICAgICAgdmFyIGFyciA9IHJlZ2V4UFIuZXhlYyhjZmcpO1xuICAgICAgICB2YXIgc291cmNlID0gYXJyWzJdO1xuICAgICAgICBjaGlsZC5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBzb3VyY2UpO1xuICAgICAgICB2YXIgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgICAgIGlmICghc291cmNlLm1hdGNoKC9eZGF0YTovaSkpIHtcbiAgICAgICAgICAgIGltZy5jcm9zc09yaWdpbiA9ICdBbm9ueW1vdXMnO1xuICAgICAgICB9XG4gICAgICAgIGltZy5zcmMgPSBzb3VyY2U7XG4gICAgICAgIGZ1bmN0aW9uIG9ubG9hZCgpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBcIlwiICsgaW1nLndpZHRoKTtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgXCJcIiArIGltZy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbWcuY29tcGxldGUpIHtcbiAgICAgICAgICAgIG9ubG9hZCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW1nLm9ubG9hZCA9IG9ubG9hZDtcbiAgICAgICAgICAgIC8vIEZpeCBvbmxvYWQoKSBidWcgaW4gSUU5XG4gICAgICAgICAgICBpbWcuc3JjID0gaW1nLnNyYztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgUGF0dGVybi5wcm90b3R5cGUubWF0Y2ggPSBmdW5jdGlvbiAodHlwZSwgYXR0cikge1xuICAgICAgICByZXR1cm4gdGhpcy5jZmcgPT09IGF0dHI7XG4gICAgfTtcbiAgICByZXR1cm4gUGF0dGVybjtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQYXR0ZXJuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0dGVybi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyBzaGFkb3dcbiAqIEBhdXRob3IgZGVuZ2Z1cGluZ19kZXZlbG9wQDE2My5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZG9tXCIpO1xudmFyIEFUVFJfTUFQID0ge1xuICAgIHNoYWRvd0NvbG9yOiAnY29sb3InLFxuICAgIHNoYWRvd09wYWNpdHk6ICdvcGFjaXR5JyxcbiAgICBzaGFkb3dCbHVyOiAnYmx1cicsXG4gICAgc2hhZG93T2Zmc2V0WDogJ2R4JyxcbiAgICBzaGFkb3dPZmZzZXRZOiAnZHknLFxufTtcbnZhciBTSEFET1dfRElNRU5TSU9OID0ge1xuICAgIHg6ICctNDAlJyxcbiAgICB5OiAnLTQwJScsXG4gICAgd2lkdGg6ICcyMDAlJyxcbiAgICBoZWlnaHQ6ICcyMDAlJyxcbn07XG52YXIgU2hhZG93ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFNoYWRvdyhjZmcpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2ZpbHRlcic7XG4gICAgICAgIHRoaXMuY2ZnID0ge307XG4gICAgICAgIHRoaXMudHlwZSA9ICdmaWx0ZXInO1xuICAgICAgICB2YXIgZWwgPSBkb21fMS5jcmVhdGVTVkdFbGVtZW50KCdmaWx0ZXInKTtcbiAgICAgICAgLy8gZXhwYW5kIHRoZSBmaWx0ZXIgcmVnaW9uIHRvIGZpbGwgaW4gc2hhZG93c1xuICAgICAgICB1dGlsXzEuZWFjaChTSEFET1dfRElNRU5TSU9OLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGssIHYpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICB0aGlzLmlkID0gdXRpbF8xLnVuaXF1ZUlkKCdmaWx0ZXJfJyk7XG4gICAgICAgIHRoaXMuZWwuaWQgPSB0aGlzLmlkO1xuICAgICAgICB0aGlzLmNmZyA9IGNmZztcbiAgICAgICAgdGhpcy5fcGFyc2VTaGFkb3coY2ZnLCBlbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBTaGFkb3cucHJvdG90eXBlLm1hdGNoID0gZnVuY3Rpb24gKHR5cGUsIGNmZykge1xuICAgICAgICBpZiAodGhpcy50eXBlICE9PSB0eXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZsYWcgPSB0cnVlO1xuICAgICAgICB2YXIgY29uZmlnID0gdGhpcy5jZmc7XG4gICAgICAgIHV0aWxfMS5lYWNoKE9iamVjdC5rZXlzKGNvbmZpZyksIGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnW2F0dHJdICE9PSBjZmdbYXR0cl0pIHtcbiAgICAgICAgICAgICAgICBmbGFnID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZsYWc7XG4gICAgfTtcbiAgICBTaGFkb3cucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgICAgICB2YXIgY29uZmlnID0gdGhpcy5jZmc7XG4gICAgICAgIGNvbmZpZ1tBVFRSX01BUFtuYW1lXV0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fcGFyc2VTaGFkb3coY29uZmlnLCB0aGlzLmVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBTaGFkb3cucHJvdG90eXBlLl9wYXJzZVNoYWRvdyA9IGZ1bmN0aW9uIChjb25maWcsIGVsKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IFwiPGZlRHJvcFNoYWRvd1xcbiAgICAgIGR4PVxcXCJcIiArIChjb25maWcuZHggfHwgMCkgKyBcIlxcXCJcXG4gICAgICBkeT1cXFwiXCIgKyAoY29uZmlnLmR5IHx8IDApICsgXCJcXFwiXFxuICAgICAgc3RkRGV2aWF0aW9uPVxcXCJcIiArIChjb25maWcuYmx1ciA/IGNvbmZpZy5ibHVyIC8gMTAgOiAwKSArIFwiXFxcIlxcbiAgICAgIGZsb29kLWNvbG9yPVxcXCJcIiArIChjb25maWcuY29sb3IgPyBjb25maWcuY29sb3IgOiAnIzAwMCcpICsgXCJcXFwiXFxuICAgICAgZmxvb2Qtb3BhY2l0eT1cXFwiXCIgKyAoY29uZmlnLm9wYWNpdHkgPyBjb25maWcub3BhY2l0eSA6IDEpICsgXCJcXFwiXFxuICAgICAgLz5cIjtcbiAgICAgICAgZWwuaW5uZXJIVE1MID0gY2hpbGQ7XG4gICAgfTtcbiAgICByZXR1cm4gU2hhZG93O1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNoYWRvdztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYWRvdy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdfYmFzZV8xID0gcmVxdWlyZShcIkBhbnR2L2ctYmFzZVwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBTaGFwZSA9IHJlcXVpcmUoXCIuL3NoYXBlXCIpO1xudmFyIGRyYXdfMSA9IHJlcXVpcmUoXCIuL3V0aWwvZHJhd1wiKTtcbnZhciBzdmdfMSA9IHJlcXVpcmUoXCIuL3V0aWwvc3ZnXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi9jb25zdGFudFwiKTtcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuL3V0aWwvZG9tXCIpO1xudmFyIEdyb3VwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEdyb3VwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyb3VwKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8vIFNWRyDkuK3liIbnu4Tlr7nlupTlrp7kvZPmoIfnrb4gPGc+XG4gICAgR3JvdXAucHJvdG90eXBlLmlzRW50aXR5R3JvdXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgR3JvdXAucHJvdG90eXBlLmNyZWF0ZURvbSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb21fMS5jcmVhdGVTVkdFbGVtZW50KCdnJyk7XG4gICAgICAgIHRoaXMuc2V0KCdlbCcsIGVsZW1lbnQpO1xuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy5nZXRQYXJlbnQoKTtcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnQuZ2V0KCdlbCcpO1xuICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gcGFyZW50Tm9kZSBtYXliZSBudWxsIGZvciBncm91cFxuICAgICAgICAgICAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnQuY3JlYXRlRG9tKCk7XG4gICAgICAgICAgICAgICAgcGFyZW50LnNldCgnZWwnLCBwYXJlbnROb2RlKTtcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH07XG4gICAgLy8g6KaG55uW5Z+657G755qEIGFmdGVyQXR0cnNDaGFuZ2Ug5pa55rOVXG4gICAgR3JvdXAucHJvdG90eXBlLmFmdGVyQXR0cnNDaGFuZ2UgPSBmdW5jdGlvbiAodGFyZ2V0QXR0cnMpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlckF0dHJzQ2hhbmdlLmNhbGwodGhpcywgdGFyZ2V0QXR0cnMpO1xuICAgICAgICB2YXIgY2FudmFzID0gdGhpcy5nZXQoJ2NhbnZhcycpO1xuICAgICAgICAvLyDlj6rmnInmjILovb3liLDnlLvluIPkuIvvvIzmiY3lr7nlhYPntKDov5vooYzlrp7pmYXmuLLmn5NcbiAgICAgICAgaWYgKGNhbnZhcyAmJiBjYW52YXMuZ2V0KCdhdXRvRHJhdycpKSB7XG4gICAgICAgICAgICB2YXIgY29udGV4dCA9IGNhbnZhcy5nZXQoJ2NvbnRleHQnKTtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlUGF0aChjb250ZXh0LCB0YXJnZXRBdHRycyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOS4gOS6m+aWueazleiwg+eUqOS8muW8lei1t+eUu+W4g+WPmOWMllxuICAgICAqIEBwYXJhbSB7Q2hhbmdlVHlwZX0gY2hhbmdlVHlwZSDmlLnlj5jnmoTnsbvlnotcbiAgICAgKi9cbiAgICBHcm91cC5wcm90b3R5cGUub25DYW52YXNDaGFuZ2UgPSBmdW5jdGlvbiAoY2hhbmdlVHlwZSkge1xuICAgICAgICBkcmF3XzEucmVmcmVzaEVsZW1lbnQodGhpcywgY2hhbmdlVHlwZSk7XG4gICAgfTtcbiAgICBHcm91cC5wcm90b3R5cGUuZ2V0U2hhcGVCYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gU2hhcGU7XG4gICAgfTtcbiAgICBHcm91cC5wcm90b3R5cGUuZ2V0R3JvdXBCYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gR3JvdXA7XG4gICAgfTtcbiAgICBHcm91cC5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIGlmICh0aGlzLmdldCgnZGVzdHJveWVkJykpIHtcbiAgICAgICAgICAgIGlmIChlbCkge1xuICAgICAgICAgICAgICAgIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFlbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlRG9tKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdmdfMS5zZXRDbGlwKHRoaXMsIGNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVQYXRoKGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRyYXdfMS5kcmF3Q2hpbGRyZW4oY29udGV4dCwgY2hpbGRyZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnu5jliLbliIbnu4TnmoTot6/lvoRcbiAgICAgKiBAcGFyYW0ge0RlZnN9IGNvbnRleHQg5LiK5LiL5paHXG4gICAgICogQHBhcmFtIHtTaGFwZUF0dHJzfSB0YXJnZXRBdHRycyDmuLLmn5PnmoTnm67moIflsZ7mgKdcbiAgICAgKi9cbiAgICBHcm91cC5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0LCB0YXJnZXRBdHRycykge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRhcmdldEF0dHJzIHx8IGF0dHJzLCBmdW5jdGlvbiAodmFsdWUsIGF0dHIpIHtcbiAgICAgICAgICAgIGlmIChjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgc3ZnXzEuc2V0VHJhbnNmb3JtKHRoaXMpO1xuICAgIH07XG4gICAgcmV0dXJuIEdyb3VwO1xufShnX2Jhc2VfMS5BYnN0cmFjdEdyb3VwKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBHcm91cDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdyb3VwLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIFNoYXBlID0gcmVxdWlyZShcIi4vc2hhcGVcIik7XG5leHBvcnRzLlNoYXBlID0gU2hhcGU7XG52YXIgcGtnID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJyk7XG5leHBvcnRzLnZlcnNpb24gPSBwa2cudmVyc2lvbjtcbnZhciBnX2Jhc2VfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2VcIik7XG5leHBvcnRzLkV2ZW50ID0gZ19iYXNlXzEuRXZlbnQ7XG52YXIgY2FudmFzXzEgPSByZXF1aXJlKFwiLi9jYW52YXNcIik7XG5leHBvcnRzLkNhbnZhcyA9IGNhbnZhc18xLmRlZmF1bHQ7XG52YXIgZ3JvdXBfMSA9IHJlcXVpcmUoXCIuL2dyb3VwXCIpO1xuZXhwb3J0cy5Hcm91cCA9IGdyb3VwXzEuZGVmYXVsdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ19iYXNlXzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlXCIpO1xudmFyIHN2Z18xID0gcmVxdWlyZShcIi4uL3V0aWwvc3ZnXCIpO1xudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZG9tXCIpO1xudmFyIGRyYXdfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2RyYXdcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBTaGFwZSA9IHJlcXVpcmUoXCIuL2luZGV4XCIpO1xudmFyIGdyb3VwXzEgPSByZXF1aXJlKFwiLi4vZ3JvdXBcIik7XG52YXIgaW5kZXhfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2UvbGliL2Jib3gvaW5kZXhcIik7XG52YXIgU2hhcGVCYXNlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFNoYXBlQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTaGFwZUJhc2UoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3N2Zyc7XG4gICAgICAgIF90aGlzLmNhbkZpbGwgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMuY2FuU3Ryb2tlID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzLmNhbGwodGhpcyk7XG4gICAgICAgIC8vIOiuvue9rum7mOiupOWAvFxuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgbGluZVdpZHRoOiAxLCBsaW5lQXBwZW5kV2lkdGg6IDAsIHN0cm9rZU9wYWNpdHk6IDEsIGZpbGxPcGFjaXR5OiAxIH0pO1xuICAgIH07XG4gICAgLy8g6KaG55uW5Z+657G755qEIGFmdGVyQXR0cnNDaGFuZ2Ug5pa55rOVXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5hZnRlckF0dHJzQ2hhbmdlID0gZnVuY3Rpb24gKHRhcmdldEF0dHJzKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJBdHRyc0NoYW5nZS5jYWxsKHRoaXMsIHRhcmdldEF0dHJzKTtcbiAgICAgICAgdmFyIGNhbnZhcyA9IHRoaXMuZ2V0KCdjYW52YXMnKTtcbiAgICAgICAgLy8g5Y+q5pyJ5oyC6L295Yiw55S75biD5LiL77yM5omN5a+55YWD57Sg6L+b6KGM5a6e6ZmF5riy5p+TXG4gICAgICAgIGlmIChjYW52YXMgJiYgY2FudmFzLmdldCgnYXV0b0RyYXcnKSkge1xuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0KCdjb250ZXh0Jyk7XG4gICAgICAgICAgICB0aGlzLmRyYXcoY29udGV4dCwgdGFyZ2V0QXR0cnMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmdldFNoYXBlQmFzZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFNoYXBlO1xuICAgIH07XG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5nZXRHcm91cEJhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBncm91cF8xLmRlZmF1bHQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDkuIDkupvmlrnms5XosIPnlKjkvJrlvJXotbfnlLvluIPlj5jljJZcbiAgICAgKiBAcGFyYW0ge0NoYW5nZVR5cGV9IGNoYW5nZVR5cGUg5pS55Y+Y55qE57G75Z6LXG4gICAgICovXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5vbkNhbnZhc0NoYW5nZSA9IGZ1bmN0aW9uIChjaGFuZ2VUeXBlKSB7XG4gICAgICAgIGRyYXdfMS5yZWZyZXNoRWxlbWVudCh0aGlzLCBjaGFuZ2VUeXBlKTtcbiAgICB9O1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuY2FsY3VsYXRlQkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHZhciBiYm94ID0gbnVsbDtcbiAgICAgICAgLy8g5YyF5Zu055uS6K6h566X5L6d6LWW5LqO57uY5Yi277yM5aaC5p6c6L+Y5rKh5pyJ55Sf5oiQ5a+55bqU55qEIERvbSDlhYPntKDvvIzliJnljIXlm7Tnm5LnmoTplb/lrr3lnYfkuLogMFxuICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICAgIGJib3ggPSBlbC5nZXRCQm94KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgYmJveE1ldGhvZCA9IGluZGV4XzEuZ2V0QkJveE1ldGhvZCh0aGlzLmdldCgndHlwZScpKTtcbiAgICAgICAgICAgIGlmIChiYm94TWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgYmJveCA9IGJib3hNZXRob2QodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJib3gpIHtcbiAgICAgICAgICAgIHZhciB4ID0gYmJveC54LCB5ID0gYmJveC55LCB3aWR0aCA9IGJib3gud2lkdGgsIGhlaWdodCA9IGJib3guaGVpZ2h0O1xuICAgICAgICAgICAgdmFyIGxpbmVXaWR0aCA9IHRoaXMuZ2V0SGl0TGluZVdpZHRoKCk7XG4gICAgICAgICAgICB2YXIgaGFsZldpZHRoID0gbGluZVdpZHRoIC8gMjtcbiAgICAgICAgICAgIHZhciBtaW5YID0geCAtIGhhbGZXaWR0aDtcbiAgICAgICAgICAgIHZhciBtaW5ZID0geSAtIGhhbGZXaWR0aDtcbiAgICAgICAgICAgIHZhciBtYXhYID0geCArIHdpZHRoICsgaGFsZldpZHRoO1xuICAgICAgICAgICAgdmFyIG1heFkgPSB5ICsgaGVpZ2h0ICsgaGFsZldpZHRoO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB4OiBtaW5YLFxuICAgICAgICAgICAgICAgIHk6IG1pblksXG4gICAgICAgICAgICAgICAgbWluWDogbWluWCxcbiAgICAgICAgICAgICAgICBtaW5ZOiBtaW5ZLFxuICAgICAgICAgICAgICAgIG1heFg6IG1heFgsXG4gICAgICAgICAgICAgICAgbWF4WTogbWF4WSxcbiAgICAgICAgICAgICAgICB3aWR0aDogd2lkdGggKyBsaW5lV2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBsaW5lV2lkdGgsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgIG1pblg6IDAsXG4gICAgICAgICAgICBtaW5ZOiAwLFxuICAgICAgICAgICAgbWF4WDogMCxcbiAgICAgICAgICAgIG1heFk6IDAsXG4gICAgICAgICAgICB3aWR0aDogMCxcbiAgICAgICAgICAgIGhlaWdodDogMCxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuaXNGaWxsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmF0dHIoKSwgZmlsbCA9IF9hLmZpbGwsIGZpbGxTdHlsZSA9IF9hLmZpbGxTdHlsZTtcbiAgICAgICAgcmV0dXJuIChmaWxsIHx8IGZpbGxTdHlsZSB8fCB0aGlzLmlzQ2xpcFNoYXBlKCkpICYmIHRoaXMuY2FuRmlsbDtcbiAgICB9O1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuaXNTdHJva2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuYXR0cigpLCBzdHJva2UgPSBfYS5zdHJva2UsIHN0cm9rZVN0eWxlID0gX2Euc3Ryb2tlU3R5bGU7XG4gICAgICAgIHJldHVybiAoc3Ryb2tlIHx8IHN0cm9rZVN0eWxlKSAmJiB0aGlzLmNhblN0cm9rZTtcbiAgICB9O1xuICAgIFNoYXBlQmFzZS5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uIChjb250ZXh0LCB0YXJnZXRBdHRycykge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KCdkZXN0cm95ZWQnKSkge1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoIWVsKSB7XG4gICAgICAgICAgICAgICAgZG9tXzEuY3JlYXRlRG9tKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3ZnXzEuc2V0Q2xpcCh0aGlzLCBjb250ZXh0KTtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlUGF0aChjb250ZXh0LCB0YXJnZXRBdHRycyk7XG4gICAgICAgICAgICB0aGlzLnNoYWRvdyhjb250ZXh0LCB0YXJnZXRBdHRycyk7XG4gICAgICAgICAgICB0aGlzLnN0cm9rZUFuZEZpbGwoY29udGV4dCwgdGFyZ2V0QXR0cnMpO1xuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0odGFyZ2V0QXR0cnMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICog57uY5Yi25Zu+5b2i55qE6Lev5b6EXG4gICAgICogQHBhcmFtIHtEZWZzfSBjb250ZXh0IOS4iuS4i+aWh1xuICAgICAqIEBwYXJhbSB7U2hhcGVBdHRyc30gdGFyZ2V0QXR0cnMg5riy5p+T55qE55uu5qCH5bGe5oCnXG4gICAgICovXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5jcmVhdGVQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQsIHRhcmdldEF0dHJzKSB7IH07XG4gICAgLy8gc3Ryb2tlIGFuZCBmaWxsXG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5zdHJva2VBbmRGaWxsID0gZnVuY3Rpb24gKGNvbnRleHQsIHRhcmdldEF0dHJzKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRhcmdldEF0dHJzIHx8IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgZmlsbCA9IGF0dHJzLmZpbGwsIGZpbGxTdHlsZSA9IGF0dHJzLmZpbGxTdHlsZSwgc3Ryb2tlID0gYXR0cnMuc3Ryb2tlLCBzdHJva2VTdHlsZSA9IGF0dHJzLnN0cm9rZVN0eWxlLCBmaWxsT3BhY2l0eSA9IGF0dHJzLmZpbGxPcGFjaXR5LCBzdHJva2VPcGFjaXR5ID0gYXR0cnMuc3Ryb2tlT3BhY2l0eSwgbGluZVdpZHRoID0gYXR0cnMubGluZVdpZHRoO1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgaWYgKHRoaXMuY2FuRmlsbCkge1xuICAgICAgICAgICAgLy8g5Yid5qyh5riy5p+T5ZKM5pu05paw5riy5p+T55qE6YC76L6R5pyJ5omA5LiN5ZCMOiDliJ3mrKHmuLLmn5PlgLzkuLrnqbrml7bvvIzpnIDopoHorr7nva7kuLogbm9uZe+8jOWQpuWImeWwseS8muaYr+m7keiJsu+8jOiAjOabtOaWsOa4suafk+WImeS4jemcgOimgVxuICAgICAgICAgICAgaWYgKCF0YXJnZXRBdHRycykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvbG9yKGNvbnRleHQsICdmaWxsJywgZmlsbCB8fCBmaWxsU3R5bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoJ2ZpbGwnIGluIGF0dHJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q29sb3IoY29udGV4dCwgJ2ZpbGwnLCBmaWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCdmaWxsU3R5bGUnIGluIGF0dHJzKSB7XG4gICAgICAgICAgICAgICAgLy8gY29tcGF0aWJsZSB3aXRoIGZpbGxTdHlsZVxuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvbG9yKGNvbnRleHQsICdmaWxsJywgZmlsbFN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmaWxsT3BhY2l0eSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFsnZmlsbE9wYWNpdHknXSwgZmlsbE9wYWNpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNhblN0cm9rZSAmJiBsaW5lV2lkdGggPiAwKSB7XG4gICAgICAgICAgICBpZiAoIXRhcmdldEF0dHJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q29sb3IoY29udGV4dCwgJ3N0cm9rZScsIHN0cm9rZSB8fCBzdHJva2VTdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICgnc3Ryb2tlJyBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvbG9yKGNvbnRleHQsICdzdHJva2UnLCBzdHJva2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoJ3N0cm9rZVN0eWxlJyBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgIC8vIGNvbXBhdGlibGUgd2l0aCBzdHJva2VTdHlsZVxuICAgICAgICAgICAgICAgIHRoaXMuX3NldENvbG9yKGNvbnRleHQsICdzdHJva2UnLCBzdHJva2VTdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc3Ryb2tlT3BhY2l0eSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFsnc3Ryb2tlT3BhY2l0eSddLCBzdHJva2VPcGFjaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsaW5lV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbJ2xpbmVXaWR0aCddLCBsaW5lV2lkdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLl9zZXRDb2xvciA9IGZ1bmN0aW9uIChjb250ZXh0LCBhdHRyLCB2YWx1ZSkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgLy8gbmVlZCB0byBzZXQgYG5vbmVgIHRvIGF2b2lkIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgJ25vbmUnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgaWYgKC9eW3IsUixMLGxdezF9W1xcc10qXFwoLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgdmFyIGlkID0gY29udGV4dC5maW5kKCdncmFkaWVudCcsIHZhbHVlKTtcbiAgICAgICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICAgICAgICBpZCA9IGNvbnRleHQuYWRkR3JhZGllbnQodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdLCBcInVybCgjXCIgKyBpZCArIFwiKVwiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgvXltwLFBdezF9W1xcc10qXFwoLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgdmFyIGlkID0gY29udGV4dC5maW5kKCdwYXR0ZXJuJywgdmFsdWUpO1xuICAgICAgICAgICAgaWYgKCFpZCkge1xuICAgICAgICAgICAgICAgIGlkID0gY29udGV4dC5hZGRQYXR0ZXJuKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgXCJ1cmwoI1wiICsgaWQgKyBcIilcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0sIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS5zaGFkb3cgPSBmdW5jdGlvbiAoY29udGV4dCwgdGFyZ2V0QXR0cnMpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBfYSA9IHRhcmdldEF0dHJzIHx8IGF0dHJzLCBzaGFkb3dPZmZzZXRYID0gX2Euc2hhZG93T2Zmc2V0WCwgc2hhZG93T2Zmc2V0WSA9IF9hLnNoYWRvd09mZnNldFksIHNoYWRvd0JsdXIgPSBfYS5zaGFkb3dCbHVyLCBzaGFkb3dDb2xvciA9IF9hLnNoYWRvd0NvbG9yO1xuICAgICAgICBpZiAoc2hhZG93T2Zmc2V0WCB8fCBzaGFkb3dPZmZzZXRZIHx8IHNoYWRvd0JsdXIgfHwgc2hhZG93Q29sb3IpIHtcbiAgICAgICAgICAgIHN2Z18xLnNldFNoYWRvdyh0aGlzLCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2hhcGVCYXNlLnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiAodGFyZ2V0QXR0cnMpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBtYXRyaXggPSAodGFyZ2V0QXR0cnMgfHwgYXR0cnMpLm1hdHJpeDtcbiAgICAgICAgaWYgKG1hdHJpeCkge1xuICAgICAgICAgICAgc3ZnXzEuc2V0VHJhbnNmb3JtKHRoaXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmlzSW5TaGFwZSA9IGZ1bmN0aW9uIChyZWZYLCByZWZZKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzUG9pbnRJblBhdGgocmVmWCwgcmVmWSk7XG4gICAgfTtcbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmlzUG9pbnRJblBhdGggPSBmdW5jdGlvbiAocmVmWCwgcmVmWSkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgdmFyIGNhbnZhcyA9IHRoaXMuZ2V0KCdjYW52YXMnKTtcbiAgICAgICAgdmFyIGJib3ggPSBjYW52YXMuZ2V0KCdlbCcpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB2YXIgY2xpZW50WCA9IHJlZlggKyBiYm94LmxlZnQ7XG4gICAgICAgIHZhciBjbGllbnRZID0gcmVmWSArIGJib3gudG9wO1xuICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoY2xpZW50WCwgY2xpZW50WSk7XG4gICAgICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQuaXNFcXVhbE5vZGUoZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bnur/mi77lj5bnmoTlrr3luqZcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSDnur/nmoTmi77lj5blrr3luqZcbiAgICAgKi9cbiAgICBTaGFwZUJhc2UucHJvdG90eXBlLmdldEhpdExpbmVXaWR0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRycywgbGluZVdpZHRoID0gX2EubGluZVdpZHRoLCBsaW5lQXBwZW5kV2lkdGggPSBfYS5saW5lQXBwZW5kV2lkdGg7XG4gICAgICAgIGlmICh0aGlzLmlzU3Ryb2tlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBsaW5lV2lkdGggKyBsaW5lQXBwZW5kV2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfTtcbiAgICByZXR1cm4gU2hhcGVCYXNlO1xufShnX2Jhc2VfMS5BYnN0cmFjdFNoYXBlKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTaGFwZUJhc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IGNpcmNsZVxuICogQGF1dGhvciBkZW5nZnVwaW5nX2RldmVsb3BAMTYzLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgQ2lyY2xlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENpcmNsZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDaXJjbGUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2NpcmNsZSc7XG4gICAgICAgIF90aGlzLmNhbkZpbGwgPSB0cnVlO1xuICAgICAgICBfdGhpcy5jYW5TdHJva2UgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIENpcmNsZS5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgcjogMCB9KTtcbiAgICB9O1xuICAgIENpcmNsZS5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0LCB0YXJnZXRBdHRycykge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRhcmdldEF0dHJzIHx8IGF0dHJzLCBmdW5jdGlvbiAodmFsdWUsIGF0dHIpIHtcbiAgICAgICAgICAgIC8vIOWchuWSjOakreWchueahOeCueWdkOagh+WxnuaAp+S4jeaYryB4LCB577yM6ICM5pivIGN4LCBjeVxuICAgICAgICAgICAgaWYgKGF0dHIgPT09ICd4JyB8fCBhdHRyID09PSAneScpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoXCJjXCIgKyBhdHRyLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBDaXJjbGU7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDaXJjbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaXJjbGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgZG9tXG4gKiBAYXV0aG9yIGRlbmdmdXBpbmdfZGV2ZWxvcEAxNjMuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBEb20gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRG9tLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERvbSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnZG9tJztcbiAgICAgICAgX3RoaXMuY2FuRmlsbCA9IGZhbHNlO1xuICAgICAgICBfdGhpcy5jYW5TdHJva2UgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBEb20ucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCwgdGFyZ2V0QXR0cnMpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0YXJnZXRBdHRycyB8fCBhdHRycywgZnVuY3Rpb24gKHZhbHVlLCBhdHRyKSB7XG4gICAgICAgICAgICBpZiAoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0pIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0sIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGVsLmlubmVySFRNTCA9IGF0dHJzWydodG1sJ107IC8vIHNldCBpbm5lckhUTUxcbiAgICB9O1xuICAgIHJldHVybiBEb207XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEb207XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kb20uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgZWxsaXBzZVxuICogQGF1dGhvciBkZW5nZnVwaW5nX2RldmVsb3BAMTYzLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgRWxsaXBzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGxpcHNlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEVsbGlwc2UoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2VsbGlwc2UnO1xuICAgICAgICBfdGhpcy5jYW5GaWxsID0gdHJ1ZTtcbiAgICAgICAgX3RoaXMuY2FuU3Ryb2tlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBFbGxpcHNlLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSwgeyB4OiAwLCB5OiAwLCByeDogMCwgcnk6IDAgfSk7XG4gICAgfTtcbiAgICBFbGxpcHNlLnByb3RvdHlwZS5jcmVhdGVQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQsIHRhcmdldEF0dHJzKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgdXRpbF8xLmVhY2godGFyZ2V0QXR0cnMgfHwgYXR0cnMsIGZ1bmN0aW9uICh2YWx1ZSwgYXR0cikge1xuICAgICAgICAgICAgLy8g5ZyG5ZKM5qSt5ZyG55qE54K55Z2Q5qCH5bGe5oCn5LiN5pivIHgsIHnvvIzogIzmmK8gY3gsIGN5XG4gICAgICAgICAgICBpZiAoYXR0ciA9PT0gJ3gnIHx8IGF0dHIgPT09ICd5Jykge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShcImNcIiArIGF0dHIsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEVsbGlwc2U7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGxpcHNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxsaXBzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGVvdmVydmlldyBpbWFnZVxuICogQGF1dGhvciBkZW5nZnVwaW5nX2RldmVsb3BAMTYzLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgSW1hZ2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSW1hZ2UsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gSW1hZ2UoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2ltYWdlJztcbiAgICAgICAgX3RoaXMuY2FuRmlsbCA9IGZhbHNlO1xuICAgICAgICBfdGhpcy5jYW5TdHJva2UgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBJbWFnZS5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCB9KTtcbiAgICB9O1xuICAgIEltYWdlLnByb3RvdHlwZS5jcmVhdGVQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQsIHRhcmdldEF0dHJzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgdXRpbF8xLmVhY2godGFyZ2V0QXR0cnMgfHwgYXR0cnMsIGZ1bmN0aW9uICh2YWx1ZSwgYXR0cikge1xuICAgICAgICAgICAgaWYgKGF0dHIgPT09ICdpbWcnKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX3NldEltYWdlKGF0dHJzLmltZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEltYWdlLnByb3RvdHlwZS5zZXRBdHRyID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYXR0cnNbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdpbWcnKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRJbWFnZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEltYWdlLnByb3RvdHlwZS5fc2V0SW1hZ2UgPSBmdW5jdGlvbiAoaW1nKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc1N0cmluZyhpbWcpKSB7XG4gICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBpbWcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGltZyBpbnN0YW5jZW9mIHdpbmRvdy5JbWFnZSkge1xuICAgICAgICAgICAgaWYgKCFhdHRycy53aWR0aCkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBpbWcud2lkdGgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXR0cignd2lkdGgnLCBpbWcud2lkdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhdHRycy5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGltZy5oZWlnaHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXR0cignaGVpZ2h0JywgaW1nLmhlaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBpbWcuc3JjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbWcgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB1dGlsXzEuaXNTdHJpbmcoaW1nLm5vZGVOYW1lKSAmJiBpbWcubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gJ0NBTlZBUycpIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnaHJlZicsIGltZy50b0RhdGFVUkwoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaW1nIGluc3RhbmNlb2YgSW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgICAgICBjYW52YXMuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFwiXCIgKyBpbWcud2lkdGgpO1xuICAgICAgICAgICAgY2FudmFzLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgXCJcIiArIGltZy5oZWlnaHQpO1xuICAgICAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJykucHV0SW1hZ2VEYXRhKGltZywgMCwgMCk7XG4gICAgICAgICAgICBpZiAoIWF0dHJzLndpZHRoKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFwiXCIgKyBpbWcud2lkdGgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXR0cignd2lkdGgnLCBpbWcud2lkdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhdHRycy5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIFwiXCIgKyBpbWcuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmF0dHIoJ2hlaWdodCcsIGltZy5oZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdocmVmJywgY2FudmFzLnRvRGF0YVVSTCgpKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIEltYWdlO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSW1hZ2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbWFnZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuZXhwb3J0cy5CYXNlID0gYmFzZV8xLmRlZmF1bHQ7XG52YXIgY2lyY2xlXzEgPSByZXF1aXJlKFwiLi9jaXJjbGVcIik7XG5leHBvcnRzLkNpcmNsZSA9IGNpcmNsZV8xLmRlZmF1bHQ7XG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi9kb21cIik7XG5leHBvcnRzLkRvbSA9IGRvbV8xLmRlZmF1bHQ7XG52YXIgZWxsaXBzZV8xID0gcmVxdWlyZShcIi4vZWxsaXBzZVwiKTtcbmV4cG9ydHMuRWxsaXBzZSA9IGVsbGlwc2VfMS5kZWZhdWx0O1xudmFyIGltYWdlXzEgPSByZXF1aXJlKFwiLi9pbWFnZVwiKTtcbmV4cG9ydHMuSW1hZ2UgPSBpbWFnZV8xLmRlZmF1bHQ7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIi4vbGluZVwiKTtcbmV4cG9ydHMuTGluZSA9IGxpbmVfMS5kZWZhdWx0O1xudmFyIG1hcmtlcl8xID0gcmVxdWlyZShcIi4vbWFya2VyXCIpO1xuZXhwb3J0cy5NYXJrZXIgPSBtYXJrZXJfMS5kZWZhdWx0O1xudmFyIHBhdGhfMSA9IHJlcXVpcmUoXCIuL3BhdGhcIik7XG5leHBvcnRzLlBhdGggPSBwYXRoXzEuZGVmYXVsdDtcbnZhciBwb2x5Z29uXzEgPSByZXF1aXJlKFwiLi9wb2x5Z29uXCIpO1xuZXhwb3J0cy5Qb2x5Z29uID0gcG9seWdvbl8xLmRlZmF1bHQ7XG52YXIgcG9seWxpbmVfMSA9IHJlcXVpcmUoXCIuL3BvbHlsaW5lXCIpO1xuZXhwb3J0cy5Qb2x5bGluZSA9IHBvbHlsaW5lXzEuZGVmYXVsdDtcbnZhciByZWN0XzEgPSByZXF1aXJlKFwiLi9yZWN0XCIpO1xuZXhwb3J0cy5SZWN0ID0gcmVjdF8xLmRlZmF1bHQ7XG52YXIgdGV4dF8xID0gcmVxdWlyZShcIi4vdGV4dFwiKTtcbmV4cG9ydHMuVGV4dCA9IHRleHRfMS5kZWZhdWx0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQGZpbGVvdmVydmlldyBsaW5lXG4gKiBAYXV0aG9yIGRlbmdmdXBpbmdfZGV2ZWxvcEAxNjMuY29tXG4gKi9cbnZhciBsaW5lXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi9saW5lXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBMaW5lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnbGluZSc7XG4gICAgICAgIF90aGlzLmNhbkZpbGwgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMuY2FuU3Ryb2tlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBMaW5lLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSwgeyB4MTogMCwgeTE6IDAsIHgyOiAwLCB5MjogMCwgc3RhcnRBcnJvdzogZmFsc2UsIGVuZEFycm93OiBmYWxzZSB9KTtcbiAgICB9O1xuICAgIExpbmUucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCwgdGFyZ2V0QXR0cnMpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0YXJnZXRBdHRycyB8fCBhdHRycywgZnVuY3Rpb24gKHZhbHVlLCBhdHRyKSB7XG4gICAgICAgICAgICBpZiAoYXR0ciA9PT0gJ3N0YXJ0QXJyb3cnIHx8IGF0dHIgPT09ICdlbmRBcnJvdycpIHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlkID0gdXRpbF8xLmlzT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBjb250ZXh0LmFkZEFycm93KGF0dHJzLCBjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDogY29udGV4dC5nZXREZWZhdWx0QXJyb3coYXR0cnMsIGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdKTtcbiAgICAgICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdLCBcInVybCgjXCIgKyBpZCArIFwiKVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0pIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0sIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBVc2UgbWF0aCBjYWxjdWxhdGlvbiB0byBnZXQgbGVuZ3RoIG9mIGxpbmVcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IGxlbmd0aFxuICAgICAqL1xuICAgIExpbmUucHJvdG90eXBlLmdldFRvdGFsTGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmF0dHIoKSwgeDEgPSBfYS54MSwgeTEgPSBfYS55MSwgeDIgPSBfYS54MiwgeTIgPSBfYS55MjtcbiAgICAgICAgcmV0dXJuIGxpbmVfMS5kZWZhdWx0Lmxlbmd0aCh4MSwgeTEsIHgyLCB5Mik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBVc2UgbWF0aCBjYWxjdWxhdGlvbiB0byBnZXQgcG9pbnQgYWNjb3JkaW5nIHRvIHJhdGlvIGFzIHNhbWUgc2EgQ2FudmFzIHZlcnNpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcmF0aW9cbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gcG9pbnRcbiAgICAgKi9cbiAgICBMaW5lLnByb3RvdHlwZS5nZXRQb2ludCA9IGZ1bmN0aW9uIChyYXRpbykge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmF0dHIoKSwgeDEgPSBfYS54MSwgeTEgPSBfYS55MSwgeDIgPSBfYS54MiwgeTIgPSBfYS55MjtcbiAgICAgICAgcmV0dXJuIGxpbmVfMS5kZWZhdWx0LnBvaW50QXQoeDEsIHkxLCB4MiwgeTIsIHJhdGlvKTtcbiAgICB9O1xuICAgIHJldHVybiBMaW5lO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgbWFya2VyXG4gKiBAYXV0aG9yIGRlbmdmdXBpbmdfZGV2ZWxvcEAxNjMuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIHN5bWJvbHNfMSA9IHJlcXVpcmUoXCIuL3N5bWJvbHNcIik7XG52YXIgTWFya2VyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKE1hcmtlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBNYXJrZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ21hcmtlcic7XG4gICAgICAgIF90aGlzLmNhbkZpbGwgPSB0cnVlO1xuICAgICAgICBfdGhpcy5jYW5TdHJva2UgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIE1hcmtlci5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLl9hc3NlbWJsZU1hcmtlcigpKTtcbiAgICB9O1xuICAgIE1hcmtlci5wcm90b3R5cGUuX2Fzc2VtYmxlTWFya2VyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZCA9IHRoaXMuX2dldFBhdGgoKTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KGQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZFxuICAgICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aC5qb2luKCcgJyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5qb2luKCcnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZDtcbiAgICB9O1xuICAgIE1hcmtlci5wcm90b3R5cGUuX2dldFBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgeCA9IGF0dHJzLngsIHkgPSBhdHRycy55O1xuICAgICAgICAvLyDlhbzlrrkgciDlkowgcmFkaXVzIOS4pOenjeWGmeazle+8jOaOqOiNkOS9v+eUqCByXG4gICAgICAgIHZhciByID0gYXR0cnMuciB8fCBhdHRycy5yYWRpdXM7XG4gICAgICAgIHZhciBzeW1ib2wgPSBhdHRycy5zeW1ib2wgfHwgJ2NpcmNsZSc7XG4gICAgICAgIHZhciBtZXRob2Q7XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzeW1ib2wpKSB7XG4gICAgICAgICAgICBtZXRob2QgPSBzeW1ib2w7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtZXRob2QgPSBzeW1ib2xzXzEuZGVmYXVsdC5nZXQoc3ltYm9sKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW1ldGhvZCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKG1ldGhvZCArIFwiIHN5bWJvbCBpcyBub3QgZXhpc3QuXCIpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1ldGhvZCh4LCB5LCByKTtcbiAgICB9O1xuICAgIC8vIOS9nOS4uuWFtumdmeaAgeWxnuaAp1xuICAgIE1hcmtlci5zeW1ib2xzRmFjdG9yeSA9IHN5bWJvbHNfMS5kZWZhdWx0O1xuICAgIHJldHVybiBNYXJrZXI7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBNYXJrZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBTeW1ib2xzID0ge1xuICAgIC8vIOWchlxuICAgIGNpcmNsZTogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCB4LCB5XSwgWydtJywgLXIsIDBdLCBbJ2EnLCByLCByLCAwLCAxLCAwLCByICogMiwgMF0sIFsnYScsIHIsIHIsIDAsIDEsIDAsIC1yICogMiwgMF1dO1xuICAgIH0sXG4gICAgLy8g5q2j5pa55b2iXG4gICAgc3F1YXJlOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICByZXR1cm4gW1snTScsIHggLSByLCB5IC0gcl0sIFsnTCcsIHggKyByLCB5IC0gcl0sIFsnTCcsIHggKyByLCB5ICsgcl0sIFsnTCcsIHggLSByLCB5ICsgcl0sIFsnWiddXTtcbiAgICB9LFxuICAgIC8vIOiPseW9olxuICAgIGRpYW1vbmQ6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbWydNJywgeCAtIHIsIHldLCBbJ0wnLCB4LCB5IC0gcl0sIFsnTCcsIHggKyByLCB5XSwgWydMJywgeCwgeSArIHJdLCBbJ1onXV07XG4gICAgfSxcbiAgICAvLyDkuInop5LlvaJcbiAgICB0cmlhbmdsZTogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgdmFyIGRpZmZZID0gciAqIE1hdGguc2luKCgxIC8gMykgKiBNYXRoLlBJKTtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSArIGRpZmZZXSwgWydMJywgeCwgeSAtIGRpZmZZXSwgWydMJywgeCArIHIsIHkgKyBkaWZmWV0sIFsneiddXTtcbiAgICB9LFxuICAgIC8vIOWAkuS4ieinkuW9olxuICAgIHRyaWFuZ2xlRG93bjogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgdmFyIGRpZmZZID0gciAqIE1hdGguc2luKCgxIC8gMykgKiBNYXRoLlBJKTtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSAtIGRpZmZZXSwgWydMJywgeCArIHIsIHkgLSBkaWZmWV0sIFsnTCcsIHgsIHkgKyBkaWZmWV0sIFsnWiddXTtcbiAgICB9LFxufTtcbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICBnZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIHJldHVybiBTeW1ib2xzW3R5cGVdO1xuICAgIH0sXG4gICAgcmVnaXN0ZXI6IGZ1bmN0aW9uICh0eXBlLCBmdW5jKSB7XG4gICAgICAgIFN5bWJvbHNbdHlwZV0gPSBmdW5jO1xuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICBkZWxldGUgU3ltYm9sc1t0eXBlXTtcbiAgICB9LFxuICAgIGdldEFsbDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gU3ltYm9scztcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN5bWJvbHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgUGF0aCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQYXRoLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBhdGgoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3BhdGgnO1xuICAgICAgICBfdGhpcy5jYW5GaWxsID0gdHJ1ZTtcbiAgICAgICAgX3RoaXMuY2FuU3Ryb2tlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBQYXRoLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhdHRycyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSwgeyBzdGFydEFycm93OiBmYWxzZSwgZW5kQXJyb3c6IGZhbHNlIH0pO1xuICAgIH07XG4gICAgUGF0aC5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0LCB0YXJnZXRBdHRycykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRhcmdldEF0dHJzIHx8IGF0dHJzLCBmdW5jdGlvbiAodmFsdWUsIGF0dHIpIHtcbiAgICAgICAgICAgIGlmIChhdHRyID09PSAncGF0aCcgJiYgdXRpbF8xLmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdkJywgX3RoaXMuX2Zvcm1hdFBhdGgodmFsdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGF0dHIgPT09ICdzdGFydEFycm93JyB8fCBhdHRyID09PSAnZW5kQXJyb3cnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZCA9IHV0aWxfMS5pc09iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgID8gY29udGV4dC5hZGRBcnJvdyhhdHRycywgY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0pXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGNvbnRleHQuZ2V0RGVmYXVsdEFycm93KGF0dHJzLCBjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgXCJ1cmwoI1wiICsgaWQgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoY29uc3RhbnRfMS5TVkdfQVRUUl9NQVBbYXR0cl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUGF0aC5wcm90b3R5cGUuX2Zvcm1hdFBhdGggPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gdmFsdWVcbiAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXRoLmpvaW4oJyAnKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKCcnKTtcbiAgICAgICAgaWYgKH5uZXdWYWx1ZS5pbmRleE9mKCdOYU4nKSkge1xuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdWYWx1ZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEdldCB0b3RhbCBsZW5ndGggb2YgcGF0aFxuICAgICAqIOWwveeuoemAmui/h+a1j+iniOWZqOeahCBTVkdQYXRoRWxlbWVudC5nZXRUb3RhbExlbmd0aCgpIOaOpeWPo+iOt+WPlueahCBwYXRoIOmVv+W6pu+8jFxuICAgICAqIOS4jiBDYW52YXMg54mI5pys6YCa6L+H5pWw5a2m6K6h566X55qE5pa55byP5b6X5Yiw55qE6ZW/5bqm5pyJ5LiA5Lqb57uG5b6u5beu5byC77yM5L2G5pyA5aSn6K+v5beu5Zyo5Liq5L2N5pWw5YOP57Sg77yM57K+5bqm5LiK5Y+v5Lul6IO95o6l5Y+XXG4gICAgICogQHJldHVybiB7bnVtYmVyfSBsZW5ndGhcbiAgICAgKi9cbiAgICBQYXRoLnByb3RvdHlwZS5nZXRUb3RhbExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHJldHVybiBlbCA/IGVsLmdldFRvdGFsTGVuZ3RoKCkgOiBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHBvaW50IGFjY29yZGluZyB0byByYXRpb1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpb1xuICAgICAqIEByZXR1cm4ge1BvaW50fSBwb2ludFxuICAgICAqL1xuICAgIFBhdGgucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKHJhdGlvKSB7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB2YXIgdG90YWxMZW5ndGggPSB0aGlzLmdldFRvdGFsTGVuZ3RoKCk7XG4gICAgICAgIHZhciBwb2ludCA9IGVsID8gZWwuZ2V0UG9pbnRBdExlbmd0aChyYXRpbyAqIHRvdGFsTGVuZ3RoKSA6IG51bGw7XG4gICAgICAgIHJldHVybiBwb2ludFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgeDogcG9pbnQueCxcbiAgICAgICAgICAgICAgICB5OiBwb2ludC55LFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIFBhdGg7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IHBvbHlnb25cbiAqIEBhdXRob3IgZGVuZ2Z1cGluZ19kZXZlbG9wQDE2My5jb21cbiAqL1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBQb2x5Z29uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBvbHlnb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUG9seWdvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAncG9seWdvbic7XG4gICAgICAgIF90aGlzLmNhbkZpbGwgPSB0cnVlO1xuICAgICAgICBfdGhpcy5jYW5TdHJva2UgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFBvbHlnb24ucHJvdG90eXBlLmNyZWF0ZVBhdGggPSBmdW5jdGlvbiAoY29udGV4dCwgdGFyZ2V0QXR0cnMpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gdGhpcy5hdHRyKCk7XG4gICAgICAgIHZhciBlbCA9IHRoaXMuZ2V0KCdlbCcpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0YXJnZXRBdHRycyB8fCBhdHRycywgZnVuY3Rpb24gKHZhbHVlLCBhdHRyKSB7XG4gICAgICAgICAgICBpZiAoYXR0ciA9PT0gJ3BvaW50cycgJiYgdXRpbF8xLmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdwb2ludHMnLCB2YWx1ZS5tYXAoZnVuY3Rpb24gKHBvaW50KSB7IHJldHVybiBwb2ludFswXSArIFwiLFwiICsgcG9pbnRbMV07IH0pLmpvaW4oJyAnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBQb2x5Z29uO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG9seWdvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbHlnb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBsaW5lXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi9saW5lXCIpO1xudmFyIHBvbHlsaW5lXzEgPSByZXF1aXJlKFwiQGFudHYvZy1tYXRoL2xpYi9wb2x5bGluZVwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG52YXIgUG9seWxpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUG9seWxpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUG9seWxpbmUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3BvbHlsaW5lJztcbiAgICAgICAgX3RoaXMuY2FuRmlsbCA9IHRydWU7XG4gICAgICAgIF90aGlzLmNhblN0cm9rZSA9IHRydWU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUG9seWxpbmUucHJvdG90eXBlLmdldERlZmF1bHRBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgYXR0cnMpLCB7IHN0YXJ0QXJyb3c6IGZhbHNlLCBlbmRBcnJvdzogZmFsc2UgfSk7XG4gICAgfTtcbiAgICAvLyDmm7TmlrDlsZ7mgKfml7bvvIzmo4DmtYvmmK/lkKbmm7TmlLnkuoYgcG9pbnRzXG4gICAgUG9seWxpbmUucHJvdG90eXBlLm9uQXR0ckNoYW5nZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkF0dHJDaGFuZ2UuY2FsbCh0aGlzLCBuYW1lLCB2YWx1ZSwgb3JpZ2luVmFsdWUpO1xuICAgICAgICBpZiAoWydwb2ludHMnXS5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fcmVzZXRDYWNoZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQb2x5bGluZS5wcm90b3R5cGUuX3Jlc2V0Q2FjaGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0KCd0b3RhbExlbmd0aCcsIG51bGwpO1xuICAgICAgICB0aGlzLnNldCgndENhY2hlJywgbnVsbCk7XG4gICAgfTtcbiAgICBQb2x5bGluZS5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0LCB0YXJnZXRBdHRycykge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRhcmdldEF0dHJzIHx8IGF0dHJzLCBmdW5jdGlvbiAodmFsdWUsIGF0dHIpIHtcbiAgICAgICAgICAgIGlmIChhdHRyID09PSAncG9pbnRzJyAmJiB1dGlsXzEuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIHZhbHVlLm1hcChmdW5jdGlvbiAocG9pbnQpIHsgcmV0dXJuIHBvaW50WzBdICsgXCIsXCIgKyBwb2ludFsxXTsgfSkuam9pbignICcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IGxlbmd0aCBvZiBwb2x5bGluZVxuICAgICAqIEByZXR1cm4ge251bWJlcn0gbGVuZ3RoXG4gICAgICovXG4gICAgUG9seWxpbmUucHJvdG90eXBlLmdldFRvdGFsTGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5hdHRyKCkucG9pbnRzO1xuICAgICAgICAvLyBnZXQgdG90YWxMZW5ndGggZnJvbSBjYWNoZVxuICAgICAgICB2YXIgdG90YWxMZW5ndGggPSB0aGlzLmdldCgndG90YWxMZW5ndGgnKTtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwodG90YWxMZW5ndGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdG90YWxMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXQoJ3RvdGFsTGVuZ3RoJywgcG9seWxpbmVfMS5kZWZhdWx0Lmxlbmd0aChwb2ludHMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCd0b3RhbExlbmd0aCcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHBvaW50IGFjY29yZGluZyB0byByYXRpb1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpb1xuICAgICAqIEByZXR1cm4ge1BvaW50fSBwb2ludFxuICAgICAqL1xuICAgIFBvbHlsaW5lLnByb3RvdHlwZS5nZXRQb2ludCA9IGZ1bmN0aW9uIChyYXRpbykge1xuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5hdHRyKCkucG9pbnRzO1xuICAgICAgICAvLyBnZXQgdENhY2hlIGZyb20gY2FjaGVcbiAgICAgICAgdmFyIHRDYWNoZSA9IHRoaXMuZ2V0KCd0Q2FjaGUnKTtcbiAgICAgICAgaWYgKCF0Q2FjaGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFRjYWNoZSgpO1xuICAgICAgICAgICAgdENhY2hlID0gdGhpcy5nZXQoJ3RDYWNoZScpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdWJ0O1xuICAgICAgICB2YXIgaW5kZXg7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRDYWNoZSwgZnVuY3Rpb24gKHYsIGkpIHtcbiAgICAgICAgICAgIGlmIChyYXRpbyA+PSB2WzBdICYmIHJhdGlvIDw9IHZbMV0pIHtcbiAgICAgICAgICAgICAgICBzdWJ0ID0gKHJhdGlvIC0gdlswXSkgLyAodlsxXSAtIHZbMF0pO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBsaW5lXzEuZGVmYXVsdC5wb2ludEF0KHBvaW50c1tpbmRleF1bMF0sIHBvaW50c1tpbmRleF1bMV0sIHBvaW50c1tpbmRleCArIDFdWzBdLCBwb2ludHNbaW5kZXggKyAxXVsxXSwgc3VidCk7XG4gICAgfTtcbiAgICBQb2x5bGluZS5wcm90b3R5cGUuX3NldFRjYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMuYXR0cigpLnBvaW50cztcbiAgICAgICAgaWYgKCFwb2ludHMgfHwgcG9pbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0b3RhbExlbmd0aCA9IHRoaXMuZ2V0VG90YWxMZW5ndGgoKTtcbiAgICAgICAgaWYgKHRvdGFsTGVuZ3RoIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGVtcExlbmd0aCA9IDA7XG4gICAgICAgIHZhciB0Q2FjaGUgPSBbXTtcbiAgICAgICAgdmFyIHNlZ21lbnRUO1xuICAgICAgICB2YXIgc2VnbWVudEw7XG4gICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHAsIGkpIHtcbiAgICAgICAgICAgIGlmIChwb2ludHNbaSArIDFdKSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudFQgPSBbXTtcbiAgICAgICAgICAgICAgICBzZWdtZW50VFswXSA9IHRlbXBMZW5ndGggLyB0b3RhbExlbmd0aDtcbiAgICAgICAgICAgICAgICBzZWdtZW50TCA9IGxpbmVfMS5kZWZhdWx0Lmxlbmd0aChwWzBdLCBwWzFdLCBwb2ludHNbaSArIDFdWzBdLCBwb2ludHNbaSArIDFdWzFdKTtcbiAgICAgICAgICAgICAgICB0ZW1wTGVuZ3RoICs9IHNlZ21lbnRMO1xuICAgICAgICAgICAgICAgIHNlZ21lbnRUWzFdID0gdGVtcExlbmd0aCAvIHRvdGFsTGVuZ3RoO1xuICAgICAgICAgICAgICAgIHRDYWNoZS5wdXNoKHNlZ21lbnRUKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0KCd0Q2FjaGUnLCB0Q2FjaGUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2V0IHN0YXJ0IHRhbmdlbnQgdmVjdG9yXG4gICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICovXG4gICAgUG9seWxpbmUucHJvdG90eXBlLmdldFN0YXJ0VGFuZ2VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMuYXR0cigpLnBvaW50cztcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICByZXN1bHQucHVzaChbcG9pbnRzWzFdWzBdLCBwb2ludHNbMV1bMV1dKTtcbiAgICAgICAgcmVzdWx0LnB1c2goW3BvaW50c1swXVswXSwgcG9pbnRzWzBdWzFdXSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBHZXQgZW5kIHRhbmdlbnQgdmVjdG9yXG4gICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICovXG4gICAgUG9seWxpbmUucHJvdG90eXBlLmdldEVuZFRhbmdlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLmF0dHIoKS5wb2ludHM7XG4gICAgICAgIHZhciBsID0gcG9pbnRzLmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgcmVzdWx0LnB1c2goW3BvaW50c1tsIC0gMV1bMF0sIHBvaW50c1tsIC0gMV1bMV1dKTtcbiAgICAgICAgcmVzdWx0LnB1c2goW3BvaW50c1tsXVswXSwgcG9pbnRzW2xdWzFdXSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICByZXR1cm4gUG9seWxpbmU7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQb2x5bGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbHlsaW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IHJlY3RcbiAqIEBhdXRob3IgZGVuZ2Z1cGluZ19kZXZlbG9wQDE2My5jb21cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGZvcm1hdF8xID0gcmVxdWlyZShcIi4uL3V0aWwvZm9ybWF0XCIpO1xudmFyIFJlY3QgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUmVjdCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSZWN0KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdyZWN0JztcbiAgICAgICAgX3RoaXMuY2FuRmlsbCA9IHRydWU7XG4gICAgICAgIF90aGlzLmNhblN0cm9rZSA9IHRydWU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUmVjdC5wcm90b3R5cGUuZ2V0RGVmYXVsdEF0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRBdHRycy5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhdHRycyksIHsgeDogMCwgeTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCwgcmFkaXVzOiAwIH0pO1xuICAgIH07XG4gICAgUmVjdC5wcm90b3R5cGUuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIChjb250ZXh0LCB0YXJnZXRBdHRycykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHIoKTtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5nZXQoJ2VsJyk7XG4gICAgICAgIC8vIOWKoOS4iueKtuaAgemHj++8jOeUqOadpeagh+iusCBwYXRoIOaYr+WQpuW3sue7hOijhVxuICAgICAgICB2YXIgY29tcGxldGVkID0gZmFsc2U7XG4gICAgICAgIC8vIOWSjOe7hOijhSBwYXRoIOebuOWFs+eahOe7mOWbvuWxnuaAp1xuICAgICAgICB2YXIgcGF0aFJlbGF0ZWRBdHRycyA9IFsneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCcsICdyYWRpdXMnXTtcbiAgICAgICAgdXRpbF8xLmVhY2godGFyZ2V0QXR0cnMgfHwgYXR0cnMsIGZ1bmN0aW9uICh2YWx1ZSwgYXR0cikge1xuICAgICAgICAgICAgaWYgKHBhdGhSZWxhdGVkQXR0cnMuaW5kZXhPZihhdHRyKSAhPT0gLTEgJiYgIWNvbXBsZXRlZCkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnZCcsIF90aGlzLl9hc3NlbWJsZVJlY3QoYXR0cnMpKTtcbiAgICAgICAgICAgICAgICBjb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocGF0aFJlbGF0ZWRBdHRycy5pbmRleE9mKGF0dHIpID09PSAtMSAmJiBjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSkge1xuICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShjb25zdGFudF8xLlNWR19BVFRSX01BUFthdHRyXSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFJlY3QucHJvdG90eXBlLl9hc3NlbWJsZVJlY3QgPSBmdW5jdGlvbiAoYXR0cnMpIHtcbiAgICAgICAgdmFyIHggPSBhdHRycy54O1xuICAgICAgICB2YXIgeSA9IGF0dHJzLnk7XG4gICAgICAgIHZhciB3ID0gYXR0cnMud2lkdGg7XG4gICAgICAgIHZhciBoID0gYXR0cnMuaGVpZ2h0O1xuICAgICAgICB2YXIgcmFkaXVzID0gYXR0cnMucmFkaXVzO1xuICAgICAgICBpZiAoIXJhZGl1cykge1xuICAgICAgICAgICAgcmV0dXJuIFwiTSBcIiArIHggKyBcIixcIiArIHkgKyBcIiBsIFwiICsgdyArIFwiLDAgbCAwLFwiICsgaCArIFwiIGxcIiArIC13ICsgXCIgMCB6XCI7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHIgPSBmb3JtYXRfMS5wYXJzZVJhZGl1cyhyYWRpdXMpO1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkocmFkaXVzKSkge1xuICAgICAgICAgICAgaWYgKHJhZGl1cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICByLnIxID0gci5yMiA9IHIucjMgPSByLnI0ID0gcmFkaXVzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgIHIucjEgPSByLnIzID0gcmFkaXVzWzBdO1xuICAgICAgICAgICAgICAgIHIucjIgPSByLnI0ID0gcmFkaXVzWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICAgICAgICAgIHIucjEgPSByYWRpdXNbMF07XG4gICAgICAgICAgICAgICAgci5yMiA9IHIucjQgPSByYWRpdXNbMV07XG4gICAgICAgICAgICAgICAgci5yMyA9IHJhZGl1c1syXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHIucjEgPSByYWRpdXNbMF07XG4gICAgICAgICAgICAgICAgci5yMiA9IHJhZGl1c1sxXTtcbiAgICAgICAgICAgICAgICByLnIzID0gcmFkaXVzWzJdO1xuICAgICAgICAgICAgICAgIHIucjQgPSByYWRpdXNbM107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByLnIxID0gci5yMiA9IHIucjMgPSByLnI0ID0gcmFkaXVzO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkID0gW1xuICAgICAgICAgICAgW1wiTSBcIiArICh4ICsgci5yMSkgKyBcIixcIiArIHldLFxuICAgICAgICAgICAgW1wibCBcIiArICh3IC0gci5yMSAtIHIucjIpICsgXCIsMFwiXSxcbiAgICAgICAgICAgIFtcImEgXCIgKyByLnIyICsgXCIsXCIgKyByLnIyICsgXCIsMCwwLDEsXCIgKyByLnIyICsgXCIsXCIgKyByLnIyXSxcbiAgICAgICAgICAgIFtcImwgMCxcIiArIChoIC0gci5yMiAtIHIucjMpXSxcbiAgICAgICAgICAgIFtcImEgXCIgKyByLnIzICsgXCIsXCIgKyByLnIzICsgXCIsMCwwLDEsXCIgKyAtci5yMyArIFwiLFwiICsgci5yM10sXG4gICAgICAgICAgICBbXCJsIFwiICsgKHIucjMgKyByLnI0IC0gdykgKyBcIiwwXCJdLFxuICAgICAgICAgICAgW1wiYSBcIiArIHIucjQgKyBcIixcIiArIHIucjQgKyBcIiwwLDAsMSxcIiArIC1yLnI0ICsgXCIsXCIgKyAtci5yNF0sXG4gICAgICAgICAgICBbXCJsIDAsXCIgKyAoci5yNCArIHIucjEgLSBoKV0sXG4gICAgICAgICAgICBbXCJhIFwiICsgci5yMSArIFwiLFwiICsgci5yMSArIFwiLDAsMCwxLFwiICsgci5yMSArIFwiLFwiICsgLXIucjFdLFxuICAgICAgICAgICAgWyd6J10sXG4gICAgICAgIF07XG4gICAgICAgIHJldHVybiBkLmpvaW4oJyAnKTtcbiAgICB9O1xuICAgIHJldHVybiBSZWN0O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlY3QuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlb3ZlcnZpZXcgdGV4dFxuICogQGF1dGhvciBkZW5nZnVwaW5nX2RldmVsb3BAMTYzLmNvbVxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkZXRlY3RfYnJvd3Nlcl8xID0gcmVxdWlyZShcImRldGVjdC1icm93c2VyXCIpO1xudmFyIHN2Z18xID0gcmVxdWlyZShcIi4uL3V0aWwvc3ZnXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBMRVRURVJfU1BBQ0lORyA9IDAuMztcbnZhciBCQVNFTElORV9NQVAgPSB7XG4gICAgdG9wOiAnYmVmb3JlLWVkZ2UnLFxuICAgIG1pZGRsZTogJ2NlbnRyYWwnLFxuICAgIGJvdHRvbTogJ2FmdGVyLWVkZ2UnLFxuICAgIGFscGhhYmV0aWM6ICdiYXNlbGluZScsXG4gICAgaGFuZ2luZzogJ2hhbmdpbmcnLFxufTtcbi8vIGZvciBGaXJlRm94XG52YXIgQkFTRUxJTkVfTUFQX0ZPUl9GSVJFRk9YID0ge1xuICAgIHRvcDogJ3RleHQtYmVmb3JlLWVkZ2UnLFxuICAgIG1pZGRsZTogJ2NlbnRyYWwnLFxuICAgIGJvdHRvbTogJ3RleHQtYWZ0ZXItZWRnZScsXG4gICAgYWxwaGFiZXRpYzogJ2FscGhhYmV0aWMnLFxuICAgIGhhbmdpbmc6ICdoYW5naW5nJyxcbn07XG52YXIgQU5DSE9SX01BUCA9IHtcbiAgICBsZWZ0OiAnbGVmdCcsXG4gICAgc3RhcnQ6ICdsZWZ0JyxcbiAgICBjZW50ZXI6ICdtaWRkbGUnLFxuICAgIHJpZ2h0OiAnZW5kJyxcbiAgICBlbmQ6ICdlbmQnLFxufTtcbnZhciBUZXh0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFRleHQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVGV4dCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAndGV4dCc7XG4gICAgICAgIF90aGlzLmNhbkZpbGwgPSB0cnVlO1xuICAgICAgICBfdGhpcy5jYW5TdHJva2UgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRleHQucHJvdG90eXBlLmdldERlZmF1bHRBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0QXR0cnMuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgYXR0cnMpLCB7IHg6IDAsIHk6IDAsIHRleHQ6IG51bGwsIGZvbnRTaXplOiAxMiwgZm9udEZhbWlseTogJ3NhbnMtc2VyaWYnLCBmb250U3R5bGU6ICdub3JtYWwnLCBmb250V2VpZ2h0OiAnbm9ybWFsJywgZm9udFZhcmlhbnQ6ICdub3JtYWwnLCB0ZXh0QWxpZ246ICdzdGFydCcsIHRleHRCYXNlbGluZTogJ2JvdHRvbScgfSk7XG4gICAgfTtcbiAgICBUZXh0LnByb3RvdHlwZS5jcmVhdGVQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQsIHRhcmdldEF0dHJzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBhdHRycyA9IHRoaXMuYXR0cigpO1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgdGhpcy5fc2V0Rm9udCgpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0YXJnZXRBdHRycyB8fCBhdHRycywgZnVuY3Rpb24gKHZhbHVlLCBhdHRyKSB7XG4gICAgICAgICAgICBpZiAoYXR0ciA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX3NldFRleHQoXCJcIiArIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGF0dHIgPT09ICdtYXRyaXgnICYmIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3ZnXzEuc2V0VHJhbnNmb3JtKF90aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGNvbnN0YW50XzEuU1ZHX0FUVFJfTUFQW2F0dHJdLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3BhaW50LW9yZGVyJywgJ3N0cm9rZScpO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJ3N0cm9rZS1saW5lY2FwOmJ1dHQ7IHN0cm9rZS1saW5lam9pbjptaXRlcjsnKTtcbiAgICB9O1xuICAgIFRleHQucHJvdG90eXBlLl9zZXRGb250ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRyKCksIHRleHRCYXNlbGluZSA9IF9hLnRleHRCYXNlbGluZSwgdGV4dEFsaWduID0gX2EudGV4dEFsaWduO1xuICAgICAgICB2YXIgYnJvd3NlciA9IGRldGVjdF9icm93c2VyXzEuZGV0ZWN0KCk7XG4gICAgICAgIGlmIChicm93c2VyICYmIGJyb3dzZXIubmFtZSA9PT0gJ2ZpcmVmb3gnKSB7XG4gICAgICAgICAgICAvLyBjb21wYXRpYmxlIHdpdGggRmlyZUZveCBicm93c2VyLCByZWY6IGh0dHBzOi8vZ2l0aHViLmNvbS9hbnR2aXMvZy9pc3N1ZXMvMTE5XG4gICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2RvbWluYW50LWJhc2VsaW5lJywgQkFTRUxJTkVfTUFQX0ZPUl9GSVJFRk9YW3RleHRCYXNlbGluZV0gfHwgJ2FscGhhYmV0aWMnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnYWxpZ25tZW50LWJhc2VsaW5lJywgQkFTRUxJTkVfTUFQW3RleHRCYXNlbGluZV0gfHwgJ2Jhc2VsaW5lJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCd0ZXh0LWFuY2hvcicsIEFOQ0hPUl9NQVBbdGV4dEFsaWduXSB8fCAnbGVmdCcpO1xuICAgIH07XG4gICAgVGV4dC5wcm90b3R5cGUuX3NldFRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzLmdldCgnZWwnKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5hdHRyKCksIHggPSBfYS54LCBfYiA9IF9hLnRleHRCYXNlbGluZSwgYmFzZWxpbmUgPSBfYiA9PT0gdm9pZCAwID8gJ2JvdHRvbScgOiBfYjtcbiAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgICBlbC5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh+dGV4dC5pbmRleE9mKCdcXG4nKSkge1xuICAgICAgICAgICAgdmFyIHRleHRBcnIgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcbiAgICAgICAgICAgIHZhciB0ZXh0TGVuXzEgPSB0ZXh0QXJyLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICB2YXIgYXJyXzEgPSAnJztcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHRleHRBcnIsIGZ1bmN0aW9uIChzZWdtZW50LCBpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2VsaW5lID09PSAnYWxwaGFiZXRpYycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycl8xICs9IFwiPHRzcGFuIHg9XFxcIlwiICsgeCArIFwiXFxcIiBkeT1cXFwiXCIgKyAtdGV4dExlbl8xICsgXCJlbVxcXCI+XCIgKyBzZWdtZW50ICsgXCI8L3RzcGFuPlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJhc2VsaW5lID09PSAndG9wJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJyXzEgKz0gXCI8dHNwYW4geD1cXFwiXCIgKyB4ICsgXCJcXFwiIGR5PVxcXCIwLjllbVxcXCI+XCIgKyBzZWdtZW50ICsgXCI8L3RzcGFuPlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJhc2VsaW5lID09PSAnbWlkZGxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJyXzEgKz0gXCI8dHNwYW4geD1cXFwiXCIgKyB4ICsgXCJcXFwiIGR5PVxcXCJcIiArIC0odGV4dExlbl8xIC0gMSkgLyAyICsgXCJlbVxcXCI+XCIgKyBzZWdtZW50ICsgXCI8L3RzcGFuPlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJhc2VsaW5lID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJyXzEgKz0gXCI8dHNwYW4geD1cXFwiXCIgKyB4ICsgXCJcXFwiIGR5PVxcXCItXCIgKyAodGV4dExlbl8xICsgTEVUVEVSX1NQQUNJTkcpICsgXCJlbVxcXCI+XCIgKyBzZWdtZW50ICsgXCI8L3RzcGFuPlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJhc2VsaW5lID09PSAnaGFuZ2luZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycl8xICs9IFwiPHRzcGFuIHg9XFxcIlwiICsgeCArIFwiXFxcIiBkeT1cXFwiXCIgKyAoLSh0ZXh0TGVuXzEgLSAxKSAtIExFVFRFUl9TUEFDSU5HKSArIFwiZW1cXFwiPlwiICsgc2VnbWVudCArIFwiPC90c3Bhbj5cIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXJyXzEgKz0gXCI8dHNwYW4geD1cXFwiXCIgKyB4ICsgXCJcXFwiIGR5PVxcXCIxZW1cXFwiPlwiICsgc2VnbWVudCArIFwiPC90c3Bhbj5cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGVsLmlubmVySFRNTCA9IGFycl8xO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFRleHQ7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xuLyoqXG4gKiDliJvlu7rlubbov5Tlm57lm77lvaLnmoQgc3ZnIOWFg+e0oFxuICogQHBhcmFtIHR5cGUgc3Zn57G75Z6LXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVNWR0VsZW1lbnQodHlwZSkge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgdHlwZSk7XG59XG5leHBvcnRzLmNyZWF0ZVNWR0VsZW1lbnQgPSBjcmVhdGVTVkdFbGVtZW50O1xuLyoqXG4gKiDliJvlu7rlubbov5Tlm57lm77lvaLnmoQgZG9tIOWFg+e0oFxuICogQHBhcmFtICB7SVNoYXBlfSBzaGFwZSDlm77lvaJcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURvbShzaGFwZSkge1xuICAgIHZhciB0eXBlID0gY29uc3RhbnRfMS5TSEFQRV9UT19UQUdTW3NoYXBlLnR5cGVdO1xuICAgIHZhciBwYXJlbnQgPSBzaGFwZS5nZXRQYXJlbnQoKTtcbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIHR5cGUgXCIgKyBzaGFwZS50eXBlICsgXCIgaXMgbm90IHN1cHBvcnRlZCBieSBzdmdcIik7XG4gICAgfVxuICAgIHZhciBlbGVtZW50ID0gY3JlYXRlU1ZHRWxlbWVudCh0eXBlKTtcbiAgICBpZiAoc2hhcGUuZ2V0KCdpZCcpKSB7XG4gICAgICAgIGVsZW1lbnQuaWQgPSBzaGFwZS5nZXQoJ2lkJyk7XG4gICAgfVxuICAgIHNoYXBlLnNldCgnZWwnLCBlbGVtZW50KTtcbiAgICBzaGFwZS5zZXQoJ2F0dHJzJywge30pO1xuICAgIC8vIOWvueS6jiBkZWZzIOS4i+eahCBkb20g6IqC54K577yMcGFyZW50IOS4uuepuu+8jOmAmui/hyBjb250ZXh0IOe7n+S4gOaMgui9veWIsCBkZWZzIOiKgueCueS4i1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnQuZ2V0KCdlbCcpO1xuICAgICAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHBhcmVudE5vZGUgbWF5YmUgbnVsbCBmb3IgZ3JvdXBcbiAgICAgICAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnQuY3JlYXRlRG9tKCk7XG4gICAgICAgICAgICBwYXJlbnQuc2V0KCdlbCcsIHBhcmVudE5vZGUpO1xuICAgICAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cbmV4cG9ydHMuY3JlYXRlRG9tID0gY3JlYXRlRG9tO1xuLyoqXG4gKiDlr7kgZG9tIOWFg+e0oOi/m+ihjOaOkuW6j1xuICogQHBhcmFtIHtJRWxlbWVudH0gZWxlbWVudCAg5YWD57SgXG4gKiBAcGFyYW0ge3NvcnRlcn0gICBmdW5jdGlvbiDmjpLluo/lh73mlbBcbiAqL1xuZnVuY3Rpb24gc29ydERvbShlbGVtZW50LCBzb3J0ZXIpIHtcbiAgICB2YXIgZWwgPSBlbGVtZW50LmdldCgnZWwnKTtcbiAgICB2YXIgY2hpbGRMaXN0ID0gdXRpbF8xLnRvQXJyYXkoZWwuY2hpbGRyZW4pLnNvcnQoc29ydGVyKTtcbiAgICAvLyBjcmVhdGUgZW1wdHkgZnJhZ21lbnRcbiAgICB2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgY2hpbGRMaXN0LmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgICB9KTtcbiAgICBlbC5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG59XG5leHBvcnRzLnNvcnREb20gPSBzb3J0RG9tO1xuLyoqXG4gKiDlsIYgZG9tIOWFg+e0oOenu+WKqOWIsOeItuWFg+e0oOS4i+eahOaMh+WumuS9jee9rlxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBlbGVtZW50ICAgICBkb20g5YWD57SgXG4gKiBAcGFyYW0ge251bWJlcn0gICAgIHRhcmdldEluZGV4IOebruagh+S9jee9rijku44gMCDlvIDlp4spXG4gKi9cbmZ1bmN0aW9uIG1vdmVUbyhlbGVtZW50LCB0YXJnZXRJbmRleCkge1xuICAgIHZhciBwYXJlbnROb2RlID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICAgIHZhciBzaWJsaW5ncyA9IEFycmF5LmZyb20ocGFyZW50Tm9kZS5jaGlsZE5vZGVzKS5maWx0ZXIoXG4gICAgLy8g6KaB5rGC5Li65YWD57Sg6IqC54K577yM5LiU5LiN6IO95Li6IGRlZnMg6IqC54K5XG4gICAgZnVuY3Rpb24gKG5vZGUpIHsgcmV0dXJuIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnZGVmcyc7IH0pO1xuICAgIC8vIOiOt+WPluebruagh+iKgueCuVxuICAgIHZhciB0YXJnZXQgPSBzaWJsaW5nc1t0YXJnZXRJbmRleF07XG4gICAgdmFyIGN1cnJlbnRJbmRleCA9IHNpYmxpbmdzLmluZGV4T2YoZWxlbWVudCk7XG4gICAgLy8g5aaC5p6c55uu5qCH6IqC54K55a2Y5ZyoXG4gICAgaWYgKHRhcmdldCkge1xuICAgICAgICAvLyDlvZPliY3ntKLlvJUgPiDnm67moIfntKLlvJXvvIznm7TmjqXmj5LlhaXliLDnm67moIfoioLngrnkuYvliY3ljbPlj69cbiAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA+IHRhcmdldEluZGV4KSB7XG4gICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50LCB0YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGN1cnJlbnRJbmRleCA8IHRhcmdldEluZGV4KSB7XG4gICAgICAgICAgICAvLyDlvZPliY3ntKLlvJUgPCDnm67moIfntKLlvJVcbiAgICAgICAgICAgIC8vIOiOt+WPluebruagh+iKgueCueeahOS4i+S4gOS4quiKgueCuVxuICAgICAgICAgICAgdmFyIHRhcmdldE5leHQgPSBzaWJsaW5nc1t0YXJnZXRJbmRleCArIDFdO1xuICAgICAgICAgICAgLy8g5aaC5p6c55uu5qCH6IqC54K555qE5LiL5LiA5Liq6IqC54K55a2Y5Zyo77yM5o+S5YWl5Yiw6K+l6IqC54K55LmL5YmNXG4gICAgICAgICAgICBpZiAodGFyZ2V0TmV4dCkge1xuICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIHRhcmdldE5leHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c6K+l6IqC54K55LiN5a2Y5Zyo77yM5YiZ6L+95Yqg5Yiw5pyr5bC+XG4gICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICB9XG59XG5leHBvcnRzLm1vdmVUbyA9IG1vdmVUbztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRvbS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBzdmdfMSA9IHJlcXVpcmUoXCIuL3N2Z1wiKTtcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuL2RvbVwiKTtcbmZ1bmN0aW9uIGRyYXdDaGlsZHJlbihjb250ZXh0LCBjaGlsZHJlbikge1xuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGNoaWxkLmRyYXcoY29udGV4dCk7XG4gICAgfSk7XG59XG5leHBvcnRzLmRyYXdDaGlsZHJlbiA9IGRyYXdDaGlsZHJlbjtcbi8qKlxuICog5pu05paw5YWD57Sg77yM5YyF5ousIGdyb3VwIOWSjCBzaGFwZVxuICogQHBhcmFtIHtJRWxlbWVudH0gZWxlbWVudCAgICAgICBTVkcg5YWD57SgXG4gKiBAcGFyYW0ge0NoYW5nZVR5cGV9IGNoYW5nZVR5cGUgIOabtOaWsOexu+Wei1xuICovXG5mdW5jdGlvbiByZWZyZXNoRWxlbWVudChlbGVtZW50LCBjaGFuZ2VUeXBlKSB7XG4gICAgLy8g5a+55LqO6L+Y5rKh5pyJ5oyC6L295Yiw55S75biD5LiL55qE5YWD57Sg77yMY2FudmFzIOWPr+iDveS4uuepulxuICAgIHZhciBjYW52YXMgPSBlbGVtZW50LmdldCgnY2FudmFzJyk7XG4gICAgLy8g5Y+q5pyJ5oyC6L295Yiw55S75biD5LiL77yM5omN5a+55YWD57Sg6L+b6KGM5a6e6ZmF5riy5p+TXG4gICAgaWYgKGNhbnZhcyAmJiBjYW52YXMuZ2V0KCdhdXRvRHJhdycpKSB7XG4gICAgICAgIHZhciBjb250ZXh0ID0gY2FudmFzLmdldCgnY29udGV4dCcpO1xuICAgICAgICB2YXIgcGFyZW50XzEgPSBlbGVtZW50LmdldFBhcmVudCgpO1xuICAgICAgICB2YXIgcGFyZW50Q2hpbGRyZW4gPSBwYXJlbnRfMSA/IHBhcmVudF8xLmdldENoaWxkcmVuKCkgOiBbY2FudmFzXTtcbiAgICAgICAgdmFyIGVsID0gZWxlbWVudC5nZXQoJ2VsJyk7XG4gICAgICAgIGlmIChjaGFuZ2VUeXBlID09PSAncmVtb3ZlJykge1xuICAgICAgICAgICAgdmFyIGlzQ2xpcFNoYXBlID0gZWxlbWVudC5nZXQoJ2lzQ2xpcFNoYXBlJyk7XG4gICAgICAgICAgICAvLyDlr7nkuo4gY2xpcO+8jOS4jeS7hemcgOimgeWwhiBjbGlwU2hhcGUg5a+55LqO55qEIFNWRyDlhYPntKDliKDpmaTvvIzov5jpnIDopoHlsIbkuIrlsYLnmoQgY2xpcFBhdGgg5YWD57Sg5Lmf5Yig6ZmkXG4gICAgICAgICAgICBpZiAoaXNDbGlwU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgY2xpcFBhdGhFbCA9IGVsICYmIGVsLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgdmFyIGRlZnNFbCA9IGNsaXBQYXRoRWwgJiYgY2xpcFBhdGhFbC5wYXJlbnROb2RlO1xuICAgICAgICAgICAgICAgIGlmIChjbGlwUGF0aEVsICYmIGRlZnNFbCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZzRWwucmVtb3ZlQ2hpbGQoY2xpcFBhdGhFbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZWwgJiYgZWwucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNoYW5nZVR5cGUgPT09ICdzaG93Jykge1xuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCd2aXNpYmlsaXR5JywgJ3Zpc2libGUnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnaGlkZScpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgndmlzaWJpbGl0eScsICdoaWRkZW4nKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnekluZGV4Jykge1xuICAgICAgICAgICAgZG9tXzEubW92ZVRvKGVsLCBwYXJlbnRDaGlsZHJlbi5pbmRleE9mKGVsZW1lbnQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnc29ydCcpIHtcbiAgICAgICAgICAgIHZhciBjaGlsZHJlbl8xID0gZWxlbWVudC5nZXQoJ2NoaWxkcmVuJyk7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5fMSAmJiBjaGlsZHJlbl8xLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRvbV8xLnNvcnREb20oZWxlbWVudCwgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkcmVuXzEuaW5kZXhPZihhKSAtIGNoaWxkcmVuXzEuaW5kZXhPZihiKSA/IDEgOiAwO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNoYW5nZVR5cGUgPT09ICdjbGVhcicpIHtcbiAgICAgICAgICAgIC8vIGVsIG1heWJlIG51bGwgZm9yIGdyb3VwXG4gICAgICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICAgICAgICBlbC5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnbWF0cml4Jykge1xuICAgICAgICAgICAgc3ZnXzEuc2V0VHJhbnNmb3JtKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNoYW5nZVR5cGUgPT09ICdjbGlwJykge1xuICAgICAgICAgICAgc3ZnXzEuc2V0Q2xpcChlbGVtZW50LCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjaGFuZ2VUeXBlID09PSAnYXR0cicpIHtcbiAgICAgICAgICAgIC8vIOW3suWcqCBhZnRlckF0dHJzQ2hhbmdlIOi/m+ihjOS6huWkhOeQhu+8jOatpOWkhCBkbyBub3RoaW5nXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY2hhbmdlVHlwZSA9PT0gJ2FkZCcpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuZHJhdyhjb250ZXh0KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydHMucmVmcmVzaEVsZW1lbnQgPSByZWZyZXNoRWxlbWVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRyYXcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcmVnZXhUYWdzID0gL1tNTEhWUVRDU0FaXShbXk1MSFZRVENTQVpdKikvZ2k7XG52YXIgcmVnZXhEb3QgPSAvW15cXHNcXCxdKy9naTtcbmZ1bmN0aW9uIHBhcnNlUmFkaXVzKHJhZGl1cykge1xuICAgIHZhciByMSA9IDA7XG4gICAgdmFyIHIyID0gMDtcbiAgICB2YXIgcjMgPSAwO1xuICAgIHZhciByNCA9IDA7XG4gICAgaWYgKHV0aWxfMS5pc0FycmF5KHJhZGl1cykpIHtcbiAgICAgICAgaWYgKHJhZGl1cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHIxID0gcjIgPSByMyA9IHI0ID0gcmFkaXVzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJhZGl1cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIHIxID0gcjMgPSByYWRpdXNbMF07XG4gICAgICAgICAgICByMiA9IHI0ID0gcmFkaXVzWzFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJhZGl1cy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICAgIHIxID0gcmFkaXVzWzBdO1xuICAgICAgICAgICAgcjIgPSByNCA9IHJhZGl1c1sxXTtcbiAgICAgICAgICAgIHIzID0gcmFkaXVzWzJdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcjEgPSByYWRpdXNbMF07XG4gICAgICAgICAgICByMiA9IHJhZGl1c1sxXTtcbiAgICAgICAgICAgIHIzID0gcmFkaXVzWzJdO1xuICAgICAgICAgICAgcjQgPSByYWRpdXNbM107XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHIxID0gcjIgPSByMyA9IHI0ID0gcmFkaXVzO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICByMTogcjEsXG4gICAgICAgIHIyOiByMixcbiAgICAgICAgcjM6IHIzLFxuICAgICAgICByNDogcjQsXG4gICAgfTtcbn1cbmV4cG9ydHMucGFyc2VSYWRpdXMgPSBwYXJzZVJhZGl1cztcbmZ1bmN0aW9uIHBhcnNlUGF0aChwYXRoKSB7XG4gICAgcGF0aCA9IHBhdGggfHwgW107XG4gICAgaWYgKHV0aWxfMS5pc0FycmF5KHBhdGgpKSB7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH1cbiAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHBhdGgpKSB7XG4gICAgICAgIHBhdGggPSBwYXRoLm1hdGNoKHJlZ2V4VGFncyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHBhdGgsIGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuICAgICAgICAgICAgaXRlbSA9IGl0ZW0ubWF0Y2gocmVnZXhEb3QpO1xuICAgICAgICAgICAgaWYgKGl0ZW1bMF0ubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSBpdGVtWzBdLmNoYXJBdCgwKTtcbiAgICAgICAgICAgICAgICBpdGVtLnNwbGljZSgxLCAwLCBpdGVtWzBdLnN1YnN0cigxKSk7XG4gICAgICAgICAgICAgICAgaXRlbVswXSA9IHRhZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGl0ZW0sIGZ1bmN0aW9uIChzdWIsIGkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzTmFOKHN1YikpIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbVtpXSA9ICtzdWI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwYXRoW2luZGV4XSA9IGl0ZW07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9XG59XG5leHBvcnRzLnBhcnNlUGF0aCA9IHBhcnNlUGF0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZvcm1hdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuL2RvbVwiKTtcbmZ1bmN0aW9uIHNldFNoYWRvdyhtb2RlbCwgY29udGV4dCkge1xuICAgIHZhciBlbCA9IG1vZGVsLmNmZy5lbDtcbiAgICB2YXIgYXR0cnMgPSBtb2RlbC5hdHRyKCk7XG4gICAgdmFyIGNmZyA9IHtcbiAgICAgICAgZHg6IGF0dHJzLnNoYWRvd09mZnNldFgsXG4gICAgICAgIGR5OiBhdHRycy5zaGFkb3dPZmZzZXRZLFxuICAgICAgICBibHVyOiBhdHRycy5zaGFkb3dCbHVyLFxuICAgICAgICBjb2xvcjogYXR0cnMuc2hhZG93Q29sb3IsXG4gICAgfTtcbiAgICBpZiAoIWNmZy5keCAmJiAhY2ZnLmR5ICYmICFjZmcuYmx1ciAmJiAhY2ZnLmNvbG9yKSB7XG4gICAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnZmlsdGVyJyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgaWQgPSBjb250ZXh0LmZpbmQoJ2ZpbHRlcicsIGNmZyk7XG4gICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICAgIGlkID0gY29udGV4dC5hZGRTaGFkb3coY2ZnKTtcbiAgICAgICAgfVxuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2ZpbHRlcicsIFwidXJsKCNcIiArIGlkICsgXCIpXCIpO1xuICAgIH1cbn1cbmV4cG9ydHMuc2V0U2hhZG93ID0gc2V0U2hhZG93O1xuZnVuY3Rpb24gc2V0VHJhbnNmb3JtKG1vZGVsKSB7XG4gICAgdmFyIG1hdHJpeCA9IG1vZGVsLmF0dHIoKS5tYXRyaXg7XG4gICAgaWYgKG1hdHJpeCkge1xuICAgICAgICB2YXIgZWwgPSBtb2RlbC5jZmcuZWw7XG4gICAgICAgIHZhciB0cmFuc2Zvcm0gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA5OyBpICs9IDMpIHtcbiAgICAgICAgICAgIHRyYW5zZm9ybS5wdXNoKG1hdHJpeFtpXSArIFwiLFwiICsgbWF0cml4W2kgKyAxXSk7XG4gICAgICAgIH1cbiAgICAgICAgdHJhbnNmb3JtID0gdHJhbnNmb3JtLmpvaW4oJywnKTtcbiAgICAgICAgaWYgKHRyYW5zZm9ybS5pbmRleE9mKCdOYU4nKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywgXCJtYXRyaXgoXCIgKyB0cmFuc2Zvcm0gKyBcIilcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2ludmFsaWQgbWF0cml4OicsIG1hdHJpeCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnRzLnNldFRyYW5zZm9ybSA9IHNldFRyYW5zZm9ybTtcbmZ1bmN0aW9uIHNldENsaXAobW9kZWwsIGNvbnRleHQpIHtcbiAgICB2YXIgY2xpcCA9IG1vZGVsLmdldENsaXAoKTtcbiAgICB2YXIgZWwgPSBtb2RlbC5nZXQoJ2VsJyk7XG4gICAgaWYgKCFjbGlwKSB7XG4gICAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnY2xpcC1wYXRoJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNsaXAgJiYgIWVsLmhhc0F0dHJpYnV0ZSgnY2xpcC1wYXRoJykpIHtcbiAgICAgICAgZG9tXzEuY3JlYXRlRG9tKGNsaXApO1xuICAgICAgICBjbGlwLmNyZWF0ZVBhdGgoY29udGV4dCk7XG4gICAgICAgIHZhciBpZCA9IGNvbnRleHQuYWRkQ2xpcChjbGlwKTtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGlwLXBhdGgnLCBcInVybCgjXCIgKyBpZCArIFwiKVwiKTtcbiAgICB9XG59XG5leHBvcnRzLnNldENsaXAgPSBzZXRDbGlwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3ZnLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fc3ByZWFkQXJyYXlzID0gKHRoaXMgJiYgdGhpcy5fX3NwcmVhZEFycmF5cykgfHwgZnVuY3Rpb24gKCkge1xuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcbiAgICByZXR1cm4gcjtcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgQnJvd3NlckluZm8gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQnJvd3NlckluZm8obmFtZSwgdmVyc2lvbiwgb3MpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcbiAgICAgICAgdGhpcy5vcyA9IG9zO1xuICAgIH1cbiAgICByZXR1cm4gQnJvd3NlckluZm87XG59KCkpO1xuZXhwb3J0cy5Ccm93c2VySW5mbyA9IEJyb3dzZXJJbmZvO1xudmFyIE5vZGVJbmZvID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIE5vZGVJbmZvKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcbiAgICAgICAgdGhpcy5uYW1lID0gJ25vZGUnO1xuICAgICAgICB0aGlzLm9zID0gcHJvY2Vzcy5wbGF0Zm9ybTtcbiAgICB9XG4gICAgcmV0dXJuIE5vZGVJbmZvO1xufSgpKTtcbmV4cG9ydHMuTm9kZUluZm8gPSBOb2RlSW5mbztcbnZhciBCb3RJbmZvID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJvdEluZm8oKSB7XG4gICAgICAgIHRoaXMuYm90ID0gdHJ1ZTsgLy8gTk9URTogZGVwcmVjYXRlZCB0ZXN0IG5hbWUgaW5zdGVhZFxuICAgICAgICB0aGlzLm5hbWUgPSAnYm90JztcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5vcyA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBCb3RJbmZvO1xufSgpKTtcbmV4cG9ydHMuQm90SW5mbyA9IEJvdEluZm87XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG52YXIgU0VBUkNIQk9YX1VBX1JFR0VYID0gL2FsZXhhfGJvdHxjcmF3bChlcnxpbmcpfGZhY2Vib29rZXh0ZXJuYWxoaXR8ZmVlZGJ1cm5lcnxnb29nbGUgd2ViIHByZXZpZXd8bmFnaW9zfHBvc3RyYW5rfHBpbmdkb218c2x1cnB8c3BpZGVyfHlhaG9vIXx5YW5kZXgvO1xudmFyIFNFQVJDSEJPVF9PU19SRUdFWCA9IC8obnVoayl8KEdvb2dsZWJvdCl8KFlhbW15Ym90KXwoT3BlbmJvdCl8KFNsdXJwKXwoTVNOQm90KXwoQXNrIEplZXZlc1xcL1Rlb21hKXwoaWFfYXJjaGl2ZXIpLztcbnZhciBSRVFVSVJFRF9WRVJTSU9OX1BBUlRTID0gMztcbnZhciB1c2VyQWdlbnRSdWxlcyA9IFtcbiAgICBbJ2FvbCcsIC9BT0xTaGllbGRcXC8oWzAtOVxcLl9dKykvXSxcbiAgICBbJ2VkZ2UnLCAvRWRnZVxcLyhbMC05XFwuX10rKS9dLFxuICAgIFsnZWRnZS1pb3MnLCAvRWRnaU9TXFwvKFswLTlcXC5fXSspL10sXG4gICAgWyd5YW5kZXhicm93c2VyJywgL1lhQnJvd3NlclxcLyhbMC05XFwuX10rKS9dLFxuICAgIFsndml2YWxkaScsIC9WaXZhbGRpXFwvKFswLTlcXC5dKykvXSxcbiAgICBbJ2tha2FvdGFsaycsIC9LQUtBT1RBTEtcXHMoWzAtOVxcLl0rKS9dLFxuICAgIFsnc2Ftc3VuZycsIC9TYW1zdW5nQnJvd3NlclxcLyhbMC05XFwuXSspL10sXG4gICAgWydzaWxrJywgL1xcYlNpbGtcXC8oWzAtOS5fLV0rKVxcYi9dLFxuICAgIFsnbWl1aScsIC9NaXVpQnJvd3NlclxcLyhbMC05XFwuXSspJC9dLFxuICAgIFsnYmVha2VyJywgL0JlYWtlckJyb3dzZXJcXC8oWzAtOVxcLl0rKS9dLFxuICAgIFsnZWRnZS1jaHJvbWl1bScsIC9FZGdcXC8oWzAtOVxcLl0rKS9dLFxuICAgIFtcbiAgICAgICAgJ2Nocm9taXVtLXdlYnZpZXcnLFxuICAgICAgICAvKD8hQ2hyb20uKk9QUil3dlxcKS4qQ2hyb20oPzplfGl1bSlcXC8oWzAtOVxcLl0rKSg6P1xcc3wkKS8sXG4gICAgXSxcbiAgICBbJ2Nocm9tZScsIC8oPyFDaHJvbS4qT1BSKUNocm9tKD86ZXxpdW0pXFwvKFswLTlcXC5dKykoOj9cXHN8JCkvXSxcbiAgICBbJ3BoYW50b21qcycsIC9QaGFudG9tSlNcXC8oWzAtOVxcLl0rKSg6P1xcc3wkKS9dLFxuICAgIFsnY3Jpb3MnLCAvQ3JpT1NcXC8oWzAtOVxcLl0rKSg6P1xcc3wkKS9dLFxuICAgIFsnZmlyZWZveCcsIC9GaXJlZm94XFwvKFswLTlcXC5dKykoPzpcXHN8JCkvXSxcbiAgICBbJ2Z4aW9zJywgL0Z4aU9TXFwvKFswLTlcXC5dKykvXSxcbiAgICBbJ29wZXJhLW1pbmknLCAvT3BlcmEgTWluaS4qVmVyc2lvblxcLyhbMC05XFwuXSspL10sXG4gICAgWydvcGVyYScsIC9PcGVyYVxcLyhbMC05XFwuXSspKD86XFxzfCQpL10sXG4gICAgWydvcGVyYScsIC9PUFJcXC8oWzAtOVxcLl0rKSg6P1xcc3wkKS9dLFxuICAgIFsnaWUnLCAvVHJpZGVudFxcLzdcXC4wLipydlxcOihbMC05XFwuXSspLipcXCkuKkdlY2tvJC9dLFxuICAgIFsnaWUnLCAvTVNJRVxccyhbMC05XFwuXSspOy4qVHJpZGVudFxcL1s0LTddLjAvXSxcbiAgICBbJ2llJywgL01TSUVcXHMoN1xcLjApL10sXG4gICAgWydiYjEwJywgL0JCMTA7XFxzVG91Y2guKlZlcnNpb25cXC8oWzAtOVxcLl0rKS9dLFxuICAgIFsnYW5kcm9pZCcsIC9BbmRyb2lkXFxzKFswLTlcXC5dKykvXSxcbiAgICBbJ2lvcycsIC9WZXJzaW9uXFwvKFswLTlcXC5fXSspLipNb2JpbGUuKlNhZmFyaS4qL10sXG4gICAgWydzYWZhcmknLCAvVmVyc2lvblxcLyhbMC05XFwuX10rKS4qU2FmYXJpL10sXG4gICAgWydmYWNlYm9vaycsIC9GQkFWXFwvKFswLTlcXC5dKykvXSxcbiAgICBbJ2luc3RhZ3JhbScsIC9JbnN0YWdyYW1cXHMoWzAtOVxcLl0rKS9dLFxuICAgIFsnaW9zLXdlYnZpZXcnLCAvQXBwbGVXZWJLaXRcXC8oWzAtOVxcLl0rKS4qTW9iaWxlL10sXG4gICAgWydpb3Mtd2VidmlldycsIC9BcHBsZVdlYktpdFxcLyhbMC05XFwuXSspLipHZWNrb1xcKSQvXSxcbiAgICBbJ3NlYXJjaGJvdCcsIFNFQVJDSEJPWF9VQV9SRUdFWF0sXG5dO1xudmFyIG9wZXJhdGluZ1N5c3RlbVJ1bGVzID0gW1xuICAgIFsnaU9TJywgL2lQKGhvbmV8b2R8YWQpL10sXG4gICAgWydBbmRyb2lkIE9TJywgL0FuZHJvaWQvXSxcbiAgICBbJ0JsYWNrQmVycnkgT1MnLCAvQmxhY2tCZXJyeXxCQjEwL10sXG4gICAgWydXaW5kb3dzIE1vYmlsZScsIC9JRU1vYmlsZS9dLFxuICAgIFsnQW1hem9uIE9TJywgL0tpbmRsZS9dLFxuICAgIFsnV2luZG93cyAzLjExJywgL1dpbjE2L10sXG4gICAgWydXaW5kb3dzIDk1JywgLyhXaW5kb3dzIDk1KXwoV2luOTUpfChXaW5kb3dzXzk1KS9dLFxuICAgIFsnV2luZG93cyA5OCcsIC8oV2luZG93cyA5OCl8KFdpbjk4KS9dLFxuICAgIFsnV2luZG93cyAyMDAwJywgLyhXaW5kb3dzIE5UIDUuMCl8KFdpbmRvd3MgMjAwMCkvXSxcbiAgICBbJ1dpbmRvd3MgWFAnLCAvKFdpbmRvd3MgTlQgNS4xKXwoV2luZG93cyBYUCkvXSxcbiAgICBbJ1dpbmRvd3MgU2VydmVyIDIwMDMnLCAvKFdpbmRvd3MgTlQgNS4yKS9dLFxuICAgIFsnV2luZG93cyBWaXN0YScsIC8oV2luZG93cyBOVCA2LjApL10sXG4gICAgWydXaW5kb3dzIDcnLCAvKFdpbmRvd3MgTlQgNi4xKS9dLFxuICAgIFsnV2luZG93cyA4JywgLyhXaW5kb3dzIE5UIDYuMikvXSxcbiAgICBbJ1dpbmRvd3MgOC4xJywgLyhXaW5kb3dzIE5UIDYuMykvXSxcbiAgICBbJ1dpbmRvd3MgMTAnLCAvKFdpbmRvd3MgTlQgMTAuMCkvXSxcbiAgICBbJ1dpbmRvd3MgTUUnLCAvV2luZG93cyBNRS9dLFxuICAgIFsnT3BlbiBCU0QnLCAvT3BlbkJTRC9dLFxuICAgIFsnU3VuIE9TJywgL1N1bk9TL10sXG4gICAgWydDaHJvbWUgT1MnLCAvQ3JPUy9dLFxuICAgIFsnTGludXgnLCAvKExpbnV4KXwoWDExKS9dLFxuICAgIFsnTWFjIE9TJywgLyhNYWNfUG93ZXJQQyl8KE1hY2ludG9zaCkvXSxcbiAgICBbJ1FOWCcsIC9RTlgvXSxcbiAgICBbJ0JlT1MnLCAvQmVPUy9dLFxuICAgIFsnT1MvMicsIC9PU1xcLzIvXSxcbiAgICBbJ1NlYXJjaCBCb3QnLCBTRUFSQ0hCT1RfT1NfUkVHRVhdLFxuXTtcbmZ1bmN0aW9uIGRldGVjdCh1c2VyQWdlbnQpIHtcbiAgICBpZiAoISF1c2VyQWdlbnQpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlVXNlckFnZW50KHVzZXJBZ2VudCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gcGFyc2VVc2VyQWdlbnQobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gICAgfVxuICAgIHJldHVybiBnZXROb2RlVmVyc2lvbigpO1xufVxuZXhwb3J0cy5kZXRlY3QgPSBkZXRlY3Q7XG5mdW5jdGlvbiBwYXJzZVVzZXJBZ2VudCh1YSkge1xuICAgIC8vIG9wdGVkIGZvciB1c2luZyByZWR1Y2UgaGVyZSByYXRoZXIgdGhhbiBBcnJheSNmaXJzdCB3aXRoIGEgcmVnZXgudGVzdCBjYWxsXG4gICAgLy8gdGhpcyBpcyBwcmltYXJpbHkgYmVjYXVzZSB1c2luZyB0aGUgcmVkdWNlIHdlIG9ubHkgcGVyZm9ybSB0aGUgcmVnZXhcbiAgICAvLyBleGVjdXRpb24gb25jZSByYXRoZXIgdGhhbiBvbmNlIGZvciB0aGUgdGVzdCBhbmQgZm9yIHRoZSBleGVjIGFnYWluIGJlbG93XG4gICAgLy8gcHJvYmFibHkgc29tZXRoaW5nIHRoYXQgbmVlZHMgdG8gYmUgYmVuY2htYXJrZWQgdGhvdWdoXG4gICAgdmFyIG1hdGNoZWRSdWxlID0gdWEgIT09ICcnICYmXG4gICAgICAgIHVzZXJBZ2VudFJ1bGVzLnJlZHVjZShmdW5jdGlvbiAobWF0Y2hlZCwgX2EpIHtcbiAgICAgICAgICAgIHZhciBicm93c2VyID0gX2FbMF0sIHJlZ2V4ID0gX2FbMV07XG4gICAgICAgICAgICBpZiAobWF0Y2hlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHVhTWF0Y2ggPSByZWdleC5leGVjKHVhKTtcbiAgICAgICAgICAgIHJldHVybiAhIXVhTWF0Y2ggJiYgW2Jyb3dzZXIsIHVhTWF0Y2hdO1xuICAgICAgICB9LCBmYWxzZSk7XG4gICAgaWYgKCFtYXRjaGVkUnVsZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIG5hbWUgPSBtYXRjaGVkUnVsZVswXSwgbWF0Y2ggPSBtYXRjaGVkUnVsZVsxXTtcbiAgICBpZiAobmFtZSA9PT0gJ3NlYXJjaGJvdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBCb3RJbmZvKCk7XG4gICAgfVxuICAgIHZhciB2ZXJzaW9uUGFydHMgPSBtYXRjaFsxXSAmJiBtYXRjaFsxXS5zcGxpdCgvWy5fXS8pLnNsaWNlKDAsIDMpO1xuICAgIGlmICh2ZXJzaW9uUGFydHMpIHtcbiAgICAgICAgaWYgKHZlcnNpb25QYXJ0cy5sZW5ndGggPCBSRVFVSVJFRF9WRVJTSU9OX1BBUlRTKSB7XG4gICAgICAgICAgICB2ZXJzaW9uUGFydHMgPSBfX3NwcmVhZEFycmF5cyh2ZXJzaW9uUGFydHMsIGNyZWF0ZVZlcnNpb25QYXJ0cyhSRVFVSVJFRF9WRVJTSU9OX1BBUlRTIC0gdmVyc2lvblBhcnRzLmxlbmd0aCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2ZXJzaW9uUGFydHMgPSBbXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBCcm93c2VySW5mbyhuYW1lLCB2ZXJzaW9uUGFydHMuam9pbignLicpLCBkZXRlY3RPUyh1YSkpO1xufVxuZXhwb3J0cy5wYXJzZVVzZXJBZ2VudCA9IHBhcnNlVXNlckFnZW50O1xuZnVuY3Rpb24gZGV0ZWN0T1ModWEpIHtcbiAgICBmb3IgKHZhciBpaSA9IDAsIGNvdW50ID0gb3BlcmF0aW5nU3lzdGVtUnVsZXMubGVuZ3RoOyBpaSA8IGNvdW50OyBpaSsrKSB7XG4gICAgICAgIHZhciBfYSA9IG9wZXJhdGluZ1N5c3RlbVJ1bGVzW2lpXSwgb3MgPSBfYVswXSwgcmVnZXggPSBfYVsxXTtcbiAgICAgICAgdmFyIG1hdGNoID0gcmVnZXgudGVzdCh1YSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgcmV0dXJuIG9zO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZXhwb3J0cy5kZXRlY3RPUyA9IGRldGVjdE9TO1xuZnVuY3Rpb24gZ2V0Tm9kZVZlcnNpb24oKSB7XG4gICAgdmFyIGlzTm9kZSA9IHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb247XG4gICAgcmV0dXJuIGlzTm9kZSA/IG5ldyBOb2RlSW5mbyhwcm9jZXNzLnZlcnNpb24uc2xpY2UoMSkpIDogbnVsbDtcbn1cbmV4cG9ydHMuZ2V0Tm9kZVZlcnNpb24gPSBnZXROb2RlVmVyc2lvbjtcbmZ1bmN0aW9uIGNyZWF0ZVZlcnNpb25QYXJ0cyhjb3VudCkge1xuICAgIHZhciBvdXRwdXQgPSBbXTtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgY291bnQ7IGlpKyspIHtcbiAgICAgICAgb3V0cHV0LnB1c2goJzAnKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJfX25wbWluc3RhbGxfZG9uZVwiOiBmYWxzZSxcbiAgXCJfYXJnc1wiOiBbXG4gICAgW1xuICAgICAgXCJAYW50di9nLXN2Z0AwLjQuN1wiLFxuICAgICAgXCJDOlxcXFx4YW1wcFxcXFxodGRvY3NcXFxcaWNlaHJtXFxcXHdlYlwiXG4gICAgXVxuICBdLFxuICBcIl9mcm9tXCI6IFwiQGFudHYvZy1zdmdAMC40LjdcIixcbiAgXCJfaWRcIjogXCJAYW50di9nLXN2Z0AwLjQuN1wiLFxuICBcIl9pbkJ1bmRsZVwiOiBmYWxzZSxcbiAgXCJfaW50ZWdyaXR5XCI6IFwic2hhNTEyLStscWxCSytxeWxQNHQvdnlVZ0VhUHRocDFYbVRpSW1ma1BsL1ptUnAzTDFrbkg2NE9JOVhUZk9HR3VCVUZBdDNKQnQ3VkhLZjZ0MEwvTUNmMEJSODhRPT1cIixcbiAgXCJfbG9jYXRpb25cIjogXCIvQGFudHYvZy1zdmdcIixcbiAgXCJfcGhhbnRvbUNoaWxkcmVuXCI6IHt9LFxuICBcIl9yZXF1ZXN0ZWRcIjoge1xuICAgIFwidHlwZVwiOiBcInZlcnNpb25cIixcbiAgICBcInJlZ2lzdHJ5XCI6IHRydWUsXG4gICAgXCJyYXdcIjogXCJAYW50di9nLXN2Z0AwLjQuN1wiLFxuICAgIFwibmFtZVwiOiBcIkBhbnR2L2ctc3ZnXCIsXG4gICAgXCJlc2NhcGVkTmFtZVwiOiBcIkBhbnR2JTJmZy1zdmdcIixcbiAgICBcInNjb3BlXCI6IFwiQGFudHZcIixcbiAgICBcInJhd1NwZWNcIjogXCIwLjQuN1wiLFxuICAgIFwic2F2ZVNwZWNcIjogbnVsbCxcbiAgICBcImZldGNoU3BlY1wiOiBcIjAuNC43XCJcbiAgfSxcbiAgXCJfcmVxdWlyZWRCeVwiOiBbXG4gICAgXCIvQGFudHYvZzJcIixcbiAgICBcIi9AYW50di9nMnBsb3RcIlxuICBdLFxuICBcIl9yZXNvbHZlZFwiOiBcImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL0BhbnR2L2ctc3ZnLy0vZy1zdmctMC40LjcudGd6XCIsXG4gIFwiX3NwZWNcIjogXCIwLjQuN1wiLFxuICBcIl93aGVyZVwiOiBcIkM6XFxcXHhhbXBwXFxcXGh0ZG9jc1xcXFxpY2Vocm1cXFxcd2ViXCIsXG4gIFwiYXV0aG9yXCI6IHtcbiAgICBcIm5hbWVcIjogXCJodHRwczovL2dpdGh1Yi5jb20vb3Jncy9hbnR2aXMvcGVvcGxlXCJcbiAgfSxcbiAgXCJidWdzXCI6IHtcbiAgICBcInVybFwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9hbnR2aXMvZy9pc3N1ZXNcIlxuICB9LFxuICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJAYW50di9nLWJhc2VcIjogXCJeMC40LjdcIixcbiAgICBcIkBhbnR2L2ctbWF0aFwiOiBcIl4wLjEuM1wiLFxuICAgIFwiQGFudHYvdXRpbFwiOiBcIn4yLjAuMFwiLFxuICAgIFwiZGV0ZWN0LWJyb3dzZXJcIjogXCJeNC42LjBcIlxuICB9LFxuICBcImRlc2NyaXB0aW9uXCI6IFwiQSBjYW52YXMgbGlicmFyeSB3aGljaCBwcm92aWRpbmcgMmRcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGFudHYvdG9yY2hcIjogXCJeMS4wLjBcIixcbiAgICBcImxlc3NcIjogXCJeMy45LjBcIixcbiAgICBcIm5wbS1ydW4tYWxsXCI6IFwiXjQuMS41XCIsXG4gICAgXCJ3ZWJwYWNrXCI6IFwiXjQuMzkuM1wiLFxuICAgIFwid2VicGFjay1jbGlcIjogXCJeMy4zLjdcIlxuICB9LFxuICBcImZpbGVzXCI6IFtcbiAgICBcInBhY2thZ2UuanNvblwiLFxuICAgIFwiZXNtXCIsXG4gICAgXCJsaWJcIixcbiAgICBcImRpc3RcIixcbiAgICBcIkxJQ0VOU0VcIixcbiAgICBcIlJFQURNRS5tZFwiXG4gIF0sXG4gIFwiZ2l0SGVhZFwiOiBcImViNmEyNTAzY2I3YmI4MTU0Njk3NTkyYjEwNjgwOTM5ZDk1NGEzMWFcIixcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9hbnR2aXMvZyNyZWFkbWVcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJ1dGlsXCIsXG4gICAgXCJhbnR2XCIsXG4gICAgXCJnXCJcbiAgXSxcbiAgXCJsaWNlbnNlXCI6IFwiSVNDXCIsXG4gIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLFxuICBcIm1vZHVsZVwiOiBcImVzbS9pbmRleC5qc1wiLFxuICBcIm5hbWVcIjogXCJAYW50di9nLXN2Z1wiLFxuICBcInB1Ymxpc2hDb25maWdcIjoge1xuICAgIFwiYWNjZXNzXCI6IFwicHVibGljXCJcbiAgfSxcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImdpdCtodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL2cuZ2l0XCJcbiAgfSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcImJ1aWxkXCI6IFwibnBtIHJ1biBjbGVhbiAmJiBydW4tcCBidWlsZDoqXCIsXG4gICAgXCJidWlsZDpjanNcIjogXCJ0c2MgLXAgdHNjb25maWcuanNvbiAtLXRhcmdldCBFUzUgLS1tb2R1bGUgY29tbW9uanMgLS1vdXREaXIgbGliXCIsXG4gICAgXCJidWlsZDplc21cIjogXCJ0c2MgLXAgdHNjb25maWcuanNvbiAtLXRhcmdldCBFUzUgLS1tb2R1bGUgRVNOZXh0IC0tb3V0RGlyIGVzbVwiLFxuICAgIFwiYnVpbGQ6dW1kXCI6IFwid2VicGFjayAtLWNvbmZpZyB3ZWJwYWNrLmNvbmZpZy5qcyAtLW1vZGUgcHJvZHVjdGlvblwiLFxuICAgIFwiY2xlYW5cIjogXCJybSAtcmYgZXNtIGxpYiBkaXN0XCIsXG4gICAgXCJjb3ZlcmFnZVwiOiBcIm5wbSBydW4gY292ZXJhZ2UtZ2VuZXJhdG9yICYmIG5wbSBydW4gY292ZXJhZ2Utdmlld2VyXCIsXG4gICAgXCJjb3ZlcmFnZS1nZW5lcmF0b3JcIjogXCJ0b3JjaCAtLWNvdmVyYWdlIC0tY29tcGlsZSAtLXNvdXJjZS1wYXR0ZXJuIHNyYy8qLmpzLHNyYy8qKi8qLmpzIC0tb3B0cyB0ZXN0cy9tb2NoYS5vcHRzXCIsXG4gICAgXCJjb3ZlcmFnZS12aWV3ZXJcIjogXCJ0b3JjaC1jb3ZlcmFnZVwiLFxuICAgIFwidGVzdFwiOiBcInRvcmNoIC0tcmVuZGVyZXIgLS1jb21waWxlIC0tb3B0cyB0ZXN0cy9tb2NoYS5vcHRzXCIsXG4gICAgXCJ0ZXN0LWxpdmVcIjogXCJ0b3JjaCAtLWNvbXBpbGUgLS1pbnRlcmFjdGl2ZSAtLW9wdHMgdGVzdHMvbW9jaGEub3B0c1wiLFxuICAgIFwidHNjXCI6IFwidHNjIC0tbm9FbWl0XCIsXG4gICAgXCJ0eXBlY2hlY2tcIjogXCJ0c2MgLS1ub0VtaXRcIlxuICB9LFxuICBcInR5cGVzXCI6IFwibGliL2luZGV4LmQudHNcIixcbiAgXCJ1bnBrZ1wiOiBcImRpc3QvZy5taW4uanNcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMC40LjdcIlxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmZhZGVPdXQgPSBleHBvcnRzLmZhZGVJbiA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog5Y2V5LiqIHNoYXBlIOWKqOeUu1xuICog5riQ546w5Yqo55S7XG4gKiBAcGFyYW0gc2hhcGUg5omn6KGM5Yqo55S755qE5Zu+5b2i5YWD57SgXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZyDliqjnlLvphY3nva5cbiAqIEBwYXJhbSBjZmcg6aKd5aSW5L+h5oGvXG4gKi9cbmZ1bmN0aW9uIGZhZGVJbihzaGFwZSwgYW5pbWF0ZUNmZywgY2ZnKSB7XG4gICAgdmFyIGVuZFN0YXRlID0ge1xuICAgICAgICBmaWxsT3BhY2l0eTogdXRpbF8xLmlzTmlsKHNoYXBlLmF0dHIoJ2ZpbGxPcGFjaXR5JykpID8gMSA6IHNoYXBlLmF0dHIoJ2ZpbGxPcGFjaXR5JyksXG4gICAgICAgIHN0cm9rZU9wYWNpdHk6IHV0aWxfMS5pc05pbChzaGFwZS5hdHRyKCdzdHJva2VPcGFjaXR5JykpID8gMSA6IHNoYXBlLmF0dHIoJ3N0cm9rZU9wYWNpdHknKSxcbiAgICAgICAgb3BhY2l0eTogdXRpbF8xLmlzTmlsKHNoYXBlLmF0dHIoJ29wYWNpdHknKSkgPyAxIDogc2hhcGUuYXR0cignb3BhY2l0eScpLFxuICAgIH07XG4gICAgc2hhcGUuYXR0cih7XG4gICAgICAgIGZpbGxPcGFjaXR5OiAwLFxuICAgICAgICBzdHJva2VPcGFjaXR5OiAwLFxuICAgICAgICBvcGFjaXR5OiAwLFxuICAgIH0pO1xuICAgIHNoYXBlLmFuaW1hdGUoZW5kU3RhdGUsIGFuaW1hdGVDZmcpO1xufVxuZXhwb3J0cy5mYWRlSW4gPSBmYWRlSW47XG4vKipcbiAqIEBpZ25vcmVcbiAqIOWNleS4qiBzaGFwZSDliqjnlLtcbiAqIOa4kOmakOWKqOeUu1xuICogQHBhcmFtIHNoYXBlIOaJp+ihjOWKqOeUu+eahOWbvuW9ouWFg+e0oFxuICogQHBhcmFtIGFuaW1hdGVDZmcg5Yqo55S76YWN572uXG4gKiBAcGFyYW0gY2ZnIOmineWkluS/oeaBr1xuICovXG5mdW5jdGlvbiBmYWRlT3V0KHNoYXBlLCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICB2YXIgZW5kU3RhdGUgPSB7XG4gICAgICAgIGZpbGxPcGFjaXR5OiAwLFxuICAgICAgICBzdHJva2VPcGFjaXR5OiAwLFxuICAgICAgICBvcGFjaXR5OiAwLFxuICAgIH07XG4gICAgdmFyIGVhc2luZyA9IGFuaW1hdGVDZmcuZWFzaW5nLCBkdXJhdGlvbiA9IGFuaW1hdGVDZmcuZHVyYXRpb24sIGRlbGF5ID0gYW5pbWF0ZUNmZy5kZWxheTtcbiAgICBzaGFwZS5hbmltYXRlKGVuZFN0YXRlLCBkdXJhdGlvbiwgZWFzaW5nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNoYXBlLnJlbW92ZSh0cnVlKTtcbiAgICB9LCBkZWxheSk7XG59XG5leHBvcnRzLmZhZGVPdXQgPSBmYWRlT3V0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmFkZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ3Jvd0luWFkgPSBleHBvcnRzLmdyb3dJblkgPSBleHBvcnRzLmdyb3dJblggPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog5YWl5Zy65Yqo55S7XG4gKiB4IOaWueWQkeeahOeUn+mVv1xuICogQHBhcmFtIGVsZW1lbnQg5omn6KGM5Yqo55S755qE5YWD57SgXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZyDliqjnlLvphY3nva5cbiAqIEBwYXJhbSBjZmcg6aKd5aSW5L+h5oGvXG4gKi9cbmZ1bmN0aW9uIGdyb3dJblgoZWxlbWVudCwgYW5pbWF0ZUNmZywgY2ZnKSB7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBjZmcuY29vcmRpbmF0ZSwgbWluWVBvaW50ID0gY2ZnLm1pbllQb2ludDtcbiAgICB1dGlsXzEuZG9TY2FsZUFuaW1hdGUoZWxlbWVudCwgYW5pbWF0ZUNmZywgY29vcmRpbmF0ZSwgbWluWVBvaW50LCAneCcpO1xufVxuZXhwb3J0cy5ncm93SW5YID0gZ3Jvd0luWDtcbi8qKlxuICogQGlnbm9yZVxuICog5YWl5Zy65Yqo55S7XG4gKiB5IOi9tOaWueWQkeS4iueahOeUn+mVv1xuICogQHBhcmFtIGVsZW1lbnQg5omn6KGM5Yqo55S755qE5YWD57SgXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZyDliqjnlLvphY3nva5cbiAqIEBwYXJhbSBjZmcg6aKd5aSW5L+h5oGvXG4gKi9cbmZ1bmN0aW9uIGdyb3dJblkoZWxlbWVudCwgYW5pbWF0ZUNmZywgY2ZnKSB7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBjZmcuY29vcmRpbmF0ZSwgbWluWVBvaW50ID0gY2ZnLm1pbllQb2ludDtcbiAgICB1dGlsXzEuZG9TY2FsZUFuaW1hdGUoZWxlbWVudCwgYW5pbWF0ZUNmZywgY29vcmRpbmF0ZSwgbWluWVBvaW50LCAneScpO1xufVxuZXhwb3J0cy5ncm93SW5ZID0gZ3Jvd0luWTtcbi8qKlxuICogQGlnbm9yZVxuICog5YWl5Zy6XG4gKiDkuK3lv4PngrnnmoTlkJHlm5vlkajnmoTnlJ/plb/liqjnlLtcbiAqIEBwYXJhbSBlbGVtZW50IOaJp+ihjOWKqOeUu+eahOWFg+e0oFxuICogQHBhcmFtIGFuaW1hdGVDZmcg5Yqo55S76YWN572uXG4gKiBAcGFyYW0gY2ZnIOmineWkluS/oeaBr1xuICovXG5mdW5jdGlvbiBncm93SW5YWShlbGVtZW50LCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICB2YXIgY29vcmRpbmF0ZSA9IGNmZy5jb29yZGluYXRlLCBtaW5ZUG9pbnQgPSBjZmcubWluWVBvaW50O1xuICAgIHV0aWxfMS5kb1NjYWxlQW5pbWF0ZShlbGVtZW50LCBhbmltYXRlQ2ZnLCBjb29yZGluYXRlLCBtaW5ZUG9pbnQsICd4eScpO1xufVxuZXhwb3J0cy5ncm93SW5YWSA9IGdyb3dJblhZO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z3Jvdy1pbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucmVnaXN0ZXJBbmltYXRpb24gPSBleHBvcnRzLmdldEFuaW1hdGlvbiA9IHZvaWQgMDtcbnZhciBBTklNQVRJT05TX01BUCA9IHt9O1xuLyoqXG4gKiDmoLnmja7lkI3np7Dojrflj5blr7nlupTnmoTliqjnlLvmiafooYzlh73mlbBcbiAqIEBwYXJhbSB0eXBlIOWKqOeUu+WHveaVsOWQjeensFxuICovXG5mdW5jdGlvbiBnZXRBbmltYXRpb24odHlwZSkge1xuICAgIHJldHVybiBBTklNQVRJT05TX01BUFt0eXBlLnRvTG93ZXJDYXNlKCldO1xufVxuZXhwb3J0cy5nZXRBbmltYXRpb24gPSBnZXRBbmltYXRpb247XG4vKipcbiAqIOazqOWGjOWKqOeUu+aJp+ihjOWHveaVsFxuICogQHBhcmFtIHR5cGUg5Yqo55S75omn6KGM5Ye95pWw5ZCN56ewXG4gKiBAcGFyYW0gYW5pbWF0aW9uIOWKqOeUu+aJp+ihjOWHveaVsFxuICovXG5mdW5jdGlvbiByZWdpc3RlckFuaW1hdGlvbih0eXBlLCBhbmltYXRpb24pIHtcbiAgICBBTklNQVRJT05TX01BUFt0eXBlLnRvTG93ZXJDYXNlKCldID0gYW5pbWF0aW9uO1xufVxuZXhwb3J0cy5yZWdpc3RlckFuaW1hdGlvbiA9IHJlZ2lzdGVyQW5pbWF0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnBhdGhJbiA9IHZvaWQgMDtcbi8qKlxuICogQGlnbm9yZVxuICog5YWl5Zy65Yqo55S7XG4gKiBwYXRoIOeahOWFpeWcuuWKqOeUu1xuICogQHBhcmFtIGVsZW1lbnQg5omn6KGM5Yqo55S755qE5YWD57SgXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZyDliqjnlLvphY3nva5cbiAqIEBwYXJhbSBjZmcg6aKd5aSW5L+h5oGvXG4gKi9cbmZ1bmN0aW9uIHBhdGhJbihlbGVtZW50LCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdmFyIGxlbmd0aCA9IGVsZW1lbnQuZ2V0VG90YWxMZW5ndGgoKTtcbiAgICAvLyDorr7nva7omZrnur/moLflvI9cbiAgICBlbGVtZW50LmF0dHIoJ2xpbmVEYXNoJywgW2xlbmd0aF0pO1xuICAgIGVsZW1lbnQuYW5pbWF0ZShmdW5jdGlvbiAocmF0aW8pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIOWvueiZmue6v+WBj+enu+mHj+WBmuWKqOeUu1xuICAgICAgICAgICAgbGluZURhc2hPZmZzZXQ6ICgxIC0gcmF0aW8pICogbGVuZ3RoLFxuICAgICAgICB9O1xuICAgIH0sIGFuaW1hdGVDZmcpO1xufVxuZXhwb3J0cy5wYXRoSW4gPSBwYXRoSW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXRoLWluLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5wb3NpdGlvblVwZGF0ZSA9IHZvaWQgMDtcbi8qKlxuICogQGlnbm9yZVxuICog5Z2Q5qCH56e75Yqo5Yqo55S7XG4gKiBAcGFyYW0gc2hhcGUg5Zu+5b2iXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZ1xuICogQHBhcmFtIGNmZ1xuICovXG5mdW5jdGlvbiBwb3NpdGlvblVwZGF0ZShzaGFwZSwgYW5pbWF0ZUNmZywgY2ZnKSB7XG4gICAgdmFyIHRvQXR0cnMgPSBjZmcudG9BdHRycztcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdmFyIHggPSB0b0F0dHJzLng7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHZhciB5ID0gdG9BdHRycy55O1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBkZWxldGUgdG9BdHRycy54O1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBkZWxldGUgdG9BdHRycy55O1xuICAgIHNoYXBlLmF0dHIodG9BdHRycyk7XG4gICAgc2hhcGUuYW5pbWF0ZSh7XG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgfSwgYW5pbWF0ZUNmZyk7XG59XG5leHBvcnRzLnBvc2l0aW9uVXBkYXRlID0gcG9zaXRpb25VcGRhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb3NpdGlvbi11cGRhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnNjYWxlSW5ZID0gZXhwb3J0cy5zY2FsZUluWCA9IHZvaWQgMDtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmsr/nnYAgeCDmlrnlkJHmlL7lpKfnmoTliqjnlLtcbiAqIEBwYXJhbSBzaGFwZVxuICogQHBhcmFtIGFuaW1hdGVDZmdcbiAqIEBwYXJhbSBzaGFwZU1vZGVsXG4gKi9cbmZ1bmN0aW9uIHNjYWxlSW5YKHNoYXBlLCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICB2YXIgYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgIHZhciBtYXBwaW5nRGF0YSA9IHNoYXBlLmdldCgnb3JpZ2luJykubWFwcGluZ0RhdGE7XG4gICAgdmFyIHBvaW50cyA9IG1hcHBpbmdEYXRhLnBvaW50cztcbiAgICAvLyB4IOaVsOWAvOWmguaenOS4uui0n+WAvO+8jOmCo+S5iOW6lOivpeS7juWPs+W+gOW3pueUn+mVv1xuICAgIHZhciB4ID0gcG9pbnRzWzBdLnkgLSBwb2ludHNbMV0ueSA+IDAgPyBib3gubWF4WCA6IGJveC5taW5YO1xuICAgIHZhciB5ID0gKGJveC5taW5ZICsgYm94Lm1heFkpIC8gMjtcbiAgICBzaGFwZS5hcHBseVRvTWF0cml4KFt4LCB5LCAxXSk7XG4gICAgdmFyIG1hdHJpeCA9IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShzaGFwZS5nZXRNYXRyaXgoKSwgW1xuICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICBbJ3MnLCAwLjAxLCAxXSxcbiAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgXSk7XG4gICAgc2hhcGUuc2V0TWF0cml4KG1hdHJpeCk7XG4gICAgc2hhcGUuYW5pbWF0ZSh7XG4gICAgICAgIG1hdHJpeDogbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHNoYXBlLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICAgICAgWydzJywgMTAwLCAxXSxcbiAgICAgICAgICAgIFsndCcsIHgsIHldLFxuICAgICAgICBdKSxcbiAgICB9LCBhbmltYXRlQ2ZnKTtcbn1cbmV4cG9ydHMuc2NhbGVJblggPSBzY2FsZUluWDtcbi8qKlxuICogQGlnbm9yZVxuICog5rK/552AIHkg5pa55ZCR5pS+5aSn55qE5Yqo55S7XG4gKiBAcGFyYW0gc2hhcGVcbiAqIEBwYXJhbSBhbmltYXRlQ2ZnXG4gKiBAcGFyYW0gc2hhcGVNb2RlbFxuICovXG5mdW5jdGlvbiBzY2FsZUluWShzaGFwZSwgYW5pbWF0ZUNmZywgY2ZnKSB7XG4gICAgdmFyIGJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICB2YXIgbWFwcGluZ0RhdGEgPSBzaGFwZS5nZXQoJ29yaWdpbicpLm1hcHBpbmdEYXRhO1xuICAgIHZhciB4ID0gKGJveC5taW5YICsgYm94Lm1heFgpIC8gMjtcbiAgICB2YXIgcG9pbnRzID0gbWFwcGluZ0RhdGEucG9pbnRzO1xuICAgIC8vIOaVsOWAvOWmguaenOS4uui0n+WAvO+8jOmCo+S5iOW6lOivpeS7juS4iuW+gOS4i+eUn+mVv++8jOmAmui/hyBzaGFwZSDnmoTlhbPplK7ngrnov5vooYzliKTmlq1cbiAgICB2YXIgeSA9IHBvaW50c1swXS55IC0gcG9pbnRzWzFdLnkgPD0gMCA/IGJveC5tYXhZIDogYm94Lm1pblk7XG4gICAgc2hhcGUuYXBwbHlUb01hdHJpeChbeCwgeSwgMV0pO1xuICAgIHZhciBtYXRyaXggPSBtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0oc2hhcGUuZ2V0TWF0cml4KCksIFtcbiAgICAgICAgWyd0JywgLXgsIC15XSxcbiAgICAgICAgWydzJywgMSwgMC4wMV0sXG4gICAgICAgIFsndCcsIHgsIHldLFxuICAgIF0pO1xuICAgIHNoYXBlLnNldE1hdHJpeChtYXRyaXgpO1xuICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICBtYXRyaXg6IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShzaGFwZS5nZXRNYXRyaXgoKSwgW1xuICAgICAgICAgICAgWyd0JywgLXgsIC15XSxcbiAgICAgICAgICAgIFsncycsIDEsIDEwMF0sXG4gICAgICAgICAgICBbJ3QnLCB4LCB5XSxcbiAgICAgICAgXSksXG4gICAgfSwgYW5pbWF0ZUNmZyk7XG59XG5leHBvcnRzLnNjYWxlSW5ZID0gc2NhbGVJblk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zY2FsZS1pbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuc2VjdG9yUGF0aFVwZGF0ZSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGFyY19wYXJhbXNfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJAYW50di9nLWNhbnZhcy9saWIvdXRpbC9hcmMtcGFyYW1zXCIpKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBncmFwaGljc18xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZ3JhcGhpY3NcIik7XG5mdW5jdGlvbiBnZXRBbmdsZShzdGFydFBvaW50LCBhcmNQYXRoKSB7XG4gICAgdmFyIF9hO1xuICAgIHZhciBfYiA9IGFyY19wYXJhbXNfMS5kZWZhdWx0KHN0YXJ0UG9pbnQsIGFyY1BhdGgpLCBzdGFydEFuZ2xlID0gX2Iuc3RhcnRBbmdsZSwgZW5kQW5nbGUgPSBfYi5lbmRBbmdsZTtcbiAgICBpZiAoIXV0aWxfMS5pc051bWJlckVxdWFsKHN0YXJ0QW5nbGUsIC1NYXRoLlBJICogMC41KSAmJiBzdGFydEFuZ2xlIDwgLU1hdGguUEkgKiAwLjUpIHtcbiAgICAgICAgc3RhcnRBbmdsZSArPSBNYXRoLlBJICogMjtcbiAgICB9XG4gICAgaWYgKCF1dGlsXzEuaXNOdW1iZXJFcXVhbChlbmRBbmdsZSwgLU1hdGguUEkgKiAwLjUpICYmIGVuZEFuZ2xlIDwgLU1hdGguUEkgKiAwLjUpIHtcbiAgICAgICAgZW5kQW5nbGUgKz0gTWF0aC5QSSAqIDI7XG4gICAgfVxuICAgIGlmIChhcmNQYXRoWzVdID09PSAwKSB7XG4gICAgICAgIC8vIOmAhuaXtumSiO+8jOmcgOimgeWwhiBzdGFydEFuZ2xlIOWSjCBlbmRBbmdsZSDovaznva7vvIzlm6DkuLogRzIg5p6B5Z2Q5qCH57O75Li66aG65pe26ZKI5pa55ZCRXG4gICAgICAgIF9hID0gW2VuZEFuZ2xlLCBzdGFydEFuZ2xlXSwgc3RhcnRBbmdsZSA9IF9hWzBdLCBlbmRBbmdsZSA9IF9hWzFdO1xuICAgIH1cbiAgICBpZiAodXRpbF8xLmlzTnVtYmVyRXF1YWwoc3RhcnRBbmdsZSwgTWF0aC5QSSAqIDEuNSkpIHtcbiAgICAgICAgc3RhcnRBbmdsZSA9IE1hdGguUEkgKiAtMC41O1xuICAgIH1cbiAgICBpZiAodXRpbF8xLmlzTnVtYmVyRXF1YWwoZW5kQW5nbGUsIE1hdGguUEkgKiAtMC41KSkge1xuICAgICAgICBlbmRBbmdsZSA9IE1hdGguUEkgKiAxLjU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsXG4gICAgICAgIGVuZEFuZ2xlOiBlbmRBbmdsZSxcbiAgICB9O1xufVxuZnVuY3Rpb24gZ2V0QXJjU3RhcnRQb2ludChwYXRoKSB7XG4gICAgdmFyIHN0YXJ0UG9pbnQ7XG4gICAgaWYgKHBhdGhbMF0gPT09ICdNJyB8fCBwYXRoWzBdID09PSAnTCcpIHtcbiAgICAgICAgc3RhcnRQb2ludCA9IFtwYXRoWzFdLCBwYXRoWzJdXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocGF0aFswXSA9PT0gJ2EnIHx8IHBhdGhbMF0gPT09ICdBJykge1xuICAgICAgICBzdGFydFBvaW50ID0gW3BhdGhbcGF0aC5sZW5ndGggLSAyXSwgcGF0aFtwYXRoLmxlbmd0aCAtIDFdXTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YXJ0UG9pbnQ7XG59XG4vKipcbiAqIHBhdGgg5a2Y5Zyo5Lul5LiL5oOF5Ya1XG4gKiAxLiDppbzlm77kuI3kuLrmlbTlnIbnmoQgcGF0aO+8jOWRveS7pOS4uiBNLCBMLCBBLCBMLCBaXG4gKiAyLiDppbzlm77kuLrmlbTlnIbnmoQgcGF0aO+8jOWRveS7pOS4uiBNLCBNLCBBLCBBLCBNLCBaXG4gKiAzLiDnjq/lm77kuI3kuLrmlbTlnIbnmoQgcGF0aO+8jOWRveS7pOS4uiBNLCBBLCBMLCBBLCBMLCBaXG4gKiA0LiDnjq/lm77kuLrmlbTlnIbnmoQgcGF0aO+8jOWRveS7pOS4uiBNLCBBLCBBLCBNLCBBLCBBLCBNLCBaXG4gKiA1LiByYWRpYWwtbGluZSwg5LiN5Li65pW05ZyG5pe255qEIHBhdGgsIOWRveS7pOS4uiBNLCBBLCBBLCBaXG4gKiA2LiByYWRpYWwtbGluZSwg5Li65pW05ZyG5pe255qEIHBhdGjvvIzlkb3ku6TkuLogTSwgQSwgQSwgQSwgQSwgWlxuICogQHBhcmFtIHBhdGggdGhldGEg5Z2Q5qCH57O75LiL5ZyG5byn55qEIHBhdGgg5ZG95LukXG4gKi9cbmZ1bmN0aW9uIGdldEFyY0luZm8ocGF0aCkge1xuICAgIHZhciBfYTtcbiAgICB2YXIgc3RhcnRBbmdsZTtcbiAgICB2YXIgZW5kQW5nbGU7XG4gICAgdmFyIGFyY1BhdGhzID0gcGF0aC5maWx0ZXIoZnVuY3Rpb24gKGNvbW1hbmQpIHtcbiAgICAgICAgcmV0dXJuIGNvbW1hbmRbMF0gPT09ICdBJyB8fCBjb21tYW5kWzBdID09PSAnYSc7XG4gICAgfSk7XG4gICAgdmFyIGZpcnN0QXJjUGF0aENvbW1hbmQgPSBhcmNQYXRoc1swXTtcbiAgICB2YXIgbGFzdEFyY1BhdGhDb21tYW5kID0gYXJjUGF0aHMubGVuZ3RoID4gMSA/IGFyY1BhdGhzWzFdIDogYXJjUGF0aHNbMF07XG4gICAgdmFyIGZpcnN0SW5kZXggPSBwYXRoLmluZGV4T2YoZmlyc3RBcmNQYXRoQ29tbWFuZCk7XG4gICAgdmFyIGxhc3RJbmRleCA9IHBhdGguaW5kZXhPZihsYXN0QXJjUGF0aENvbW1hbmQpO1xuICAgIHZhciBmaXJzdFN0YXJ0UG9pbnQgPSBnZXRBcmNTdGFydFBvaW50KHBhdGhbZmlyc3RJbmRleCAtIDFdKTtcbiAgICB2YXIgbGFzdFN0YXJ0UG9pbnQgPSBnZXRBcmNTdGFydFBvaW50KHBhdGhbbGFzdEluZGV4IC0gMV0pO1xuICAgIHZhciBfYiA9IGdldEFuZ2xlKGZpcnN0U3RhcnRQb2ludCwgZmlyc3RBcmNQYXRoQ29tbWFuZCksIGZpcnN0U3RhcnRBbmdsZSA9IF9iLnN0YXJ0QW5nbGUsIGZpcnN0RW5kQW5nbGUgPSBfYi5lbmRBbmdsZTtcbiAgICB2YXIgX2MgPSBnZXRBbmdsZShsYXN0U3RhcnRQb2ludCwgbGFzdEFyY1BhdGhDb21tYW5kKSwgbGFzdFN0YXJ0QW5nbGUgPSBfYy5zdGFydEFuZ2xlLCBsYXN0RW5kQW5nbGUgPSBfYy5lbmRBbmdsZTtcbiAgICBpZiAodXRpbF8xLmlzTnVtYmVyRXF1YWwoZmlyc3RTdGFydEFuZ2xlLCBsYXN0U3RhcnRBbmdsZSkgJiYgdXRpbF8xLmlzTnVtYmVyRXF1YWwoZmlyc3RFbmRBbmdsZSwgbGFzdEVuZEFuZ2xlKSkge1xuICAgICAgICBzdGFydEFuZ2xlID0gZmlyc3RTdGFydEFuZ2xlO1xuICAgICAgICBlbmRBbmdsZSA9IGZpcnN0RW5kQW5nbGU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzdGFydEFuZ2xlID0gTWF0aC5taW4oZmlyc3RTdGFydEFuZ2xlLCBsYXN0U3RhcnRBbmdsZSk7XG4gICAgICAgIGVuZEFuZ2xlID0gTWF0aC5tYXgoZmlyc3RFbmRBbmdsZSwgbGFzdEVuZEFuZ2xlKTtcbiAgICB9XG4gICAgdmFyIHJhZGl1cyA9IGZpcnN0QXJjUGF0aENvbW1hbmRbMV07XG4gICAgdmFyIGlubmVyUmFkaXVzID0gYXJjUGF0aHNbYXJjUGF0aHMubGVuZ3RoIC0gMV1bMV07XG4gICAgaWYgKHJhZGl1cyA8IGlubmVyUmFkaXVzKSB7XG4gICAgICAgIF9hID0gW2lubmVyUmFkaXVzLCByYWRpdXNdLCByYWRpdXMgPSBfYVswXSwgaW5uZXJSYWRpdXMgPSBfYVsxXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocmFkaXVzID09PSBpbm5lclJhZGl1cykge1xuICAgICAgICBpbm5lclJhZGl1cyA9IDA7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHN0YXJ0QW5nbGU6IHN0YXJ0QW5nbGUsXG4gICAgICAgIGVuZEFuZ2xlOiBlbmRBbmdsZSxcbiAgICAgICAgcmFkaXVzOiByYWRpdXMsXG4gICAgICAgIGlubmVyUmFkaXVzOiBpbm5lclJhZGl1cyxcbiAgICB9O1xufVxuLyoqXG4gKiBAaWdub3JlXG4gKiDppbzlm77mm7TmlrDliqjnlLtcbiAqIEBwYXJhbSBzaGFwZSDmlofmnKzlm77lvaJcbiAqIEBwYXJhbSBhbmltYXRlQ2ZnXG4gKiBAcGFyYW0gY2ZnXG4gKi9cbmZ1bmN0aW9uIHNlY3RvclBhdGhVcGRhdGUoc2hhcGUsIGFuaW1hdGVDZmcsIGNmZykge1xuICAgIHZhciB0b0F0dHJzID0gY2ZnLnRvQXR0cnMsIGNvb3JkaW5hdGUgPSBjZmcuY29vcmRpbmF0ZTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdmFyIHBhdGggPSB0b0F0dHJzLnBhdGg7XG4gICAgdmFyIHBhdGhDb21tYW5kcyA9IHBhdGgubWFwKGZ1bmN0aW9uIChjb21tYW5kKSB7IHJldHVybiBjb21tYW5kWzBdOyB9KTtcbiAgICB2YXIgX2EgPSBnZXRBcmNJbmZvKHBhdGgpLCBjdXJTdGFydEFuZ2xlID0gX2Euc3RhcnRBbmdsZSwgY3VyRW5kQW5nbGUgPSBfYS5lbmRBbmdsZSwgcmFkaXVzID0gX2EucmFkaXVzLCBpbm5lclJhZGl1cyA9IF9hLmlubmVyUmFkaXVzO1xuICAgIHZhciBfYiA9IGdldEFyY0luZm8oc2hhcGUuYXR0cigncGF0aCcpKSwgcHJlU3RhcnRBbmdsZSA9IF9iLnN0YXJ0QW5nbGUsIHByZUVuZEFuZ2xlID0gX2IuZW5kQW5nbGU7XG4gICAgdmFyIGNlbnRlciA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgdmFyIGRpZmZTdGFydEFuZ2xlID0gY3VyU3RhcnRBbmdsZSAtIHByZVN0YXJ0QW5nbGU7XG4gICAgdmFyIGRpZmZFbmRBbmdsZSA9IGN1ckVuZEFuZ2xlIC0gcHJlRW5kQW5nbGU7XG4gICAgc2hhcGUuYW5pbWF0ZShmdW5jdGlvbiAocmF0aW8pIHtcbiAgICAgICAgdmFyIG9uRnJhbWVTdGFydEFuZ2xlID0gcHJlU3RhcnRBbmdsZSArIHJhdGlvICogZGlmZlN0YXJ0QW5nbGU7XG4gICAgICAgIHZhciBvbkZyYW1lRW5kQW5nbGUgPSBwcmVFbmRBbmdsZSArIHJhdGlvICogZGlmZkVuZEFuZ2xlO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCB0b0F0dHJzKSwgeyBwYXRoOiBcbiAgICAgICAgICAgIC8vIGhhY2ssIOWFvOWuuSAvZXhhbXBsZXMvYmFyL2Jhc2ljL2RlbW8vcmFkaWFsLWxpbmUudHMg5Yqo55S7XG4gICAgICAgICAgICB1dGlsXzEuaXNFcXVhbChwYXRoQ29tbWFuZHMsIFsnTScsICdBJywgJ0EnLCAnWiddKVxuICAgICAgICAgICAgICAgID8gZ3JhcGhpY3NfMS5nZXRBcmNQYXRoKGNlbnRlci54LCBjZW50ZXIueSwgcmFkaXVzLCBvbkZyYW1lU3RhcnRBbmdsZSwgb25GcmFtZUVuZEFuZ2xlKVxuICAgICAgICAgICAgICAgIDogZ3JhcGhpY3NfMS5nZXRTZWN0b3JQYXRoKGNlbnRlci54LCBjZW50ZXIueSwgcmFkaXVzLCBvbkZyYW1lU3RhcnRBbmdsZSwgb25GcmFtZUVuZEFuZ2xlLCBpbm5lclJhZGl1cykgfSk7XG4gICAgfSwgdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhbmltYXRlQ2ZnKSwgeyBjYWxsYmFjazogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8g5bCGIHBhdGgg5L+d5oyB5Y6f5aeL5oCB77yM5ZCm5YiZ5Lya5b2x5ZONIHNldFN0YXRlKCkg55qE5Yqo55S7XG4gICAgICAgICAgICBzaGFwZS5hdHRyKCdwYXRoJywgcGF0aCk7XG4gICAgICAgIH0gfSkpO1xufVxuZXhwb3J0cy5zZWN0b3JQYXRoVXBkYXRlID0gc2VjdG9yUGF0aFVwZGF0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNlY3Rvci1wYXRoLXVwZGF0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZG9TY2FsZUFuaW1hdGUgPSBleHBvcnRzLnRyYW5zZm9ybVNoYXBlID0gdm9pZCAwO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOWvueWbvuW9ouWFg+e0oOi/m+ihjOefqemYteWPmOaNou+8jOWQjOaXtui/lOWbnuWPmOaNouWJjeeahOWbvuW9ouefqemYtVxuICogQHBhcmFtIHNoYXBlIOi/m+ihjOefqemYteWPmOaNoueahOWbvuW9olxuICogQHBhcmFtIHZlY3RvciDnn6npmLXlj5jmjaLnmoTkuK3lv4PngrlcbiAqIEBwYXJhbSBkaXJlY3Qg55+p6Zi15Y+Y5o2i55qE57G75Z6LXG4gKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybVNoYXBlKHNoYXBlLCB2ZWN0b3IsIGRpcmVjdCkge1xuICAgIHZhciBzY2FsZWRNYXRyaXg7XG4gICAgdmFyIHggPSB2ZWN0b3JbMF0sIHkgPSB2ZWN0b3JbMV07XG4gICAgc2hhcGUuYXBwbHlUb01hdHJpeChbeCwgeSwgMV0pO1xuICAgIGlmIChkaXJlY3QgPT09ICd4Jykge1xuICAgICAgICBzaGFwZS5zZXRNYXRyaXgobWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHNoYXBlLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICAgICAgWydzJywgMC4wMSwgMV0sXG4gICAgICAgICAgICBbJ3QnLCB4LCB5XSxcbiAgICAgICAgXSkpO1xuICAgICAgICBzY2FsZWRNYXRyaXggPSBtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0oc2hhcGUuZ2V0TWF0cml4KCksIFtcbiAgICAgICAgICAgIFsndCcsIC14LCAteV0sXG4gICAgICAgICAgICBbJ3MnLCAxMDAsIDFdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBlbHNlIGlmIChkaXJlY3QgPT09ICd5Jykge1xuICAgICAgICBzaGFwZS5zZXRNYXRyaXgobWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHNoYXBlLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICAgICAgWydzJywgMSwgMC4wMV0sXG4gICAgICAgICAgICBbJ3QnLCB4LCB5XSxcbiAgICAgICAgXSkpO1xuICAgICAgICBzY2FsZWRNYXRyaXggPSBtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0oc2hhcGUuZ2V0TWF0cml4KCksIFtcbiAgICAgICAgICAgIFsndCcsIC14LCAteV0sXG4gICAgICAgICAgICBbJ3MnLCAxLCAxMDBdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBlbHNlIGlmIChkaXJlY3QgPT09ICd4eScpIHtcbiAgICAgICAgc2hhcGUuc2V0TWF0cml4KG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShzaGFwZS5nZXRNYXRyaXgoKSwgW1xuICAgICAgICAgICAgWyd0JywgLXgsIC15XSxcbiAgICAgICAgICAgIFsncycsIDAuMDEsIDAuMDFdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pKTtcbiAgICAgICAgc2NhbGVkTWF0cml4ID0gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHNoYXBlLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICAgICAgWydzJywgMTAwLCAxMDBdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICByZXR1cm4gc2NhbGVkTWF0cml4O1xufVxuZXhwb3J0cy50cmFuc2Zvcm1TaGFwZSA9IHRyYW5zZm9ybVNoYXBlO1xuLyoqXG4gKiDlr7nlm77lvaLlhYPntKDov5vooYzliarliIfliqjnlLtcbiAqIEBwYXJhbSBlbGVtZW50IOi/m+ihjOWKqOeUu+eahOWbvuW9ouWFg+e0oFxuICogQHBhcmFtIGFuaW1hdGVDZmcg5Yqo55S76YWN572uXG4gKiBAcGFyYW0gY29vcmRpbmF0ZSDlvZPliY3lnZDmoIfns7tcbiAqIEBwYXJhbSB5TWluUG9pbnQgeSDovbTnmoTmnIDlsI/lgLzlr7nlupTnmoTlm77lvaLlnZDmoIfngrlcbiAqIEBwYXJhbSB0eXBlIOWJquWIh+WKqOeUu+eahOexu+Wei1xuICovXG5mdW5jdGlvbiBkb1NjYWxlQW5pbWF0ZShlbGVtZW50LCBhbmltYXRlQ2ZnLCBjb29yZGluYXRlLCB5TWluUG9pbnQsIHR5cGUpIHtcbiAgICB2YXIgc3RhcnQgPSBjb29yZGluYXRlLnN0YXJ0LCBlbmQgPSBjb29yZGluYXRlLmVuZDtcbiAgICB2YXIgd2lkdGggPSBjb29yZGluYXRlLmdldFdpZHRoKCk7XG4gICAgdmFyIGhlaWdodCA9IGNvb3JkaW5hdGUuZ2V0SGVpZ2h0KCk7XG4gICAgdmFyIHg7XG4gICAgdmFyIHk7XG4gICAgaWYgKHR5cGUgPT09ICd5Jykge1xuICAgICAgICB4ID0gc3RhcnQueCArIHdpZHRoIC8gMjtcbiAgICAgICAgeSA9IHlNaW5Qb2ludC55IDwgc3RhcnQueSA/IHlNaW5Qb2ludC55IDogc3RhcnQueTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSA9PT0gJ3gnKSB7XG4gICAgICAgIHggPSB5TWluUG9pbnQueCA+IHN0YXJ0LnggPyB5TWluUG9pbnQueCA6IHN0YXJ0Lng7XG4gICAgICAgIHkgPSBzdGFydC55ICsgaGVpZ2h0IC8gMjtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSA9PT0gJ3h5Jykge1xuICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgICAgICB4ID0gY29vcmRpbmF0ZS5nZXRDZW50ZXIoKS54O1xuICAgICAgICAgICAgeSA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCkueTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHggPSAoc3RhcnQueCArIGVuZC54KSAvIDI7XG4gICAgICAgICAgICB5ID0gKHN0YXJ0LnkgKyBlbmQueSkgLyAyO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciBlbmRNYXRyaXggPSB0cmFuc2Zvcm1TaGFwZShlbGVtZW50LCBbeCwgeV0sIHR5cGUpO1xuICAgIGVsZW1lbnQuYW5pbWF0ZSh7XG4gICAgICAgIG1hdHJpeDogZW5kTWF0cml4LFxuICAgIH0sIGFuaW1hdGVDZmcpO1xufVxuZXhwb3J0cy5kb1NjYWxlQW5pbWF0ZSA9IGRvU2NhbGVBbmltYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dXRpbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMud2F2ZUluID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY29vcmRpbmF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvY29vcmRpbmF0ZVwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog5pW05L2T5Yqo55S7XG4gKiDliJLlhaXlhaXlnLrliqjnlLvmlYjmnpxcbiAqIEB0b2RvIOaUvuS4pOW8oOebtOinkuWdkOagh+ezu+WSjOaegeWdkOagh+ezu+eahOWbvlxuICogQHBhcmFtIGVsZW1lbnQg5Y+C5LiO5Yqo55S755qE5Zu+5b2i5YWD57SgXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZyDliqjnlLvphY3nva5cbiAqIEBwYXJhbSBjZmcg6aKd5aSW5L+h5oGvXG4gKi9cbmZ1bmN0aW9uIHdhdmVJbihlbGVtZW50LCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICB2YXIgX2EgPSBjb29yZGluYXRlXzEuZ2V0Q29vcmRpbmF0ZUNsaXBDZmcoY2ZnLmNvb3JkaW5hdGUsIDIwKSwgdHlwZSA9IF9hLnR5cGUsIHN0YXJ0U3RhdGUgPSBfYS5zdGFydFN0YXRlLCBlbmRTdGF0ZSA9IF9hLmVuZFN0YXRlOyAvLyDmoLnmja7lnZDmoIfns7vnsbvlnovojrflj5bmlbTkvZPnmoTliarliIfljLrln5/phY3nva7kv6Hmga9cbiAgICB2YXIgY2xpcFNoYXBlID0gZWxlbWVudC5zZXRDbGlwKHtcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgYXR0cnM6IHN0YXJ0U3RhdGUsXG4gICAgfSk7IC8vIOS4uiBzaGFwZSDorr7nva7liarliIfljLrln59cbiAgICAvLyBcYuWvueWJquWIh+WbvuW9ouWBmuWKqOeUu1xuICAgIGNsaXBTaGFwZS5hbmltYXRlKGVuZFN0YXRlLCB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGFuaW1hdGVDZmcpLCB7IGNhbGxiYWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudCAmJiAhZWxlbWVudC5nZXQoJ2Rlc3Ryb3llZCcpKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5zZXQoJ2NsaXBTaGFwZScsIG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2xpcFNoYXBlLnJlbW92ZSh0cnVlKTsgLy8g5Yqo55S757uT5p2f6ZyA6KaB5bCG5Ymq5YiH5Zu+5b2i6ZSA5q+BXG4gICAgICAgIH0gfSkpO1xufVxuZXhwb3J0cy53YXZlSW4gPSB3YXZlSW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD13YXZlLWluLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy56b29tT3V0ID0gZXhwb3J0cy56b29tSW4gPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuZnVuY3Rpb24gZG9TaGFwZVpvb20oc2hhcGUsIGFuaW1hdGVDZmcsIHR5cGUpIHtcbiAgICBpZiAoc2hhcGUuaXNHcm91cCgpKSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlLmdldENoaWxkcmVuKCksIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgZG9TaGFwZVpvb20oY2hpbGQsIGFuaW1hdGVDZmcsIHR5cGUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgeCA9IChiYm94Lm1pblggKyBiYm94Lm1heFgpIC8gMjtcbiAgICAgICAgdmFyIHkgPSAoYmJveC5taW5ZICsgYmJveC5tYXhZKSAvIDI7XG4gICAgICAgIHNoYXBlLmFwcGx5VG9NYXRyaXgoW3gsIHksIDFdKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICd6b29tSW4nKSB7XG4gICAgICAgICAgICAvLyDmlL7lpKdcbiAgICAgICAgICAgIHZhciBtYXRyaXggPSBtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0oc2hhcGUuZ2V0TWF0cml4KCksIFtcbiAgICAgICAgICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICAgICAgICAgIFsncycsIDAuMDEsIDAuMDFdLFxuICAgICAgICAgICAgICAgIFsndCcsIHgsIHldLFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICBzaGFwZS5zZXRNYXRyaXgobWF0cml4KTtcbiAgICAgICAgICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgIG1hdHJpeDogbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHNoYXBlLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICAgICAgICAgIFsndCcsIC14LCAteV0sXG4gICAgICAgICAgICAgICAgICAgIFsncycsIDEwMCwgMTAwXSxcbiAgICAgICAgICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICB9LCBhbmltYXRlQ2ZnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgIG1hdHJpeDogbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHNoYXBlLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICAgICAgICAgIFsndCcsIC14LCAteV0sXG4gICAgICAgICAgICAgICAgICAgIFsncycsIDAuMDEsIDAuMDFdLFxuICAgICAgICAgICAgICAgICAgICBbJ3QnLCB4LCB5XSxcbiAgICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH0sIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgYW5pbWF0ZUNmZyksIHsgY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgc2hhcGUucmVtb3ZlKHRydWUpO1xuICAgICAgICAgICAgICAgIH0gfSkpO1xuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBAaWdub3JlXG4gKiDljZXkuKogc2hhcGUg5Yqo55S7XG4gKiBzaGFwZSDku6Xoh6rouqvkuK3lv4PngrnpgJDmuJDmlL7lpKfnmoTov5vlhaXliqjnlLtcbiAqIEBwYXJhbSBzaGFwZSDlj4LkuI7liqjnlLvnmoTlm77lvaLlhYPntKBcbiAqIEBwYXJhbSBhbmltYXRlQ2ZnIOWKqOeUu+mFjee9rlxuICogQHBhcmFtIGNmZyDpop3lpJbkv6Hmga9cbiAqL1xuZnVuY3Rpb24gem9vbUluKHNoYXBlLCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICBkb1NoYXBlWm9vbShzaGFwZSwgYW5pbWF0ZUNmZywgJ3pvb21JbicpO1xufVxuZXhwb3J0cy56b29tSW4gPSB6b29tSW47XG4vKipcbiAqIEBpZ25vcmVcbiAqIOWNleS4qiBzaGFwZSDliqjnlLtcbiAqIOa2iOWkseWKqOeUu++8jHNoYXBlIOS7peiHqui6q+S4uuS4reW/g+eCueeahOmAkOa4kOe8qeWwj1xuICogQHBhcmFtIHNoYXBlIOWPguS4juWKqOeUu+eahOWbvuW9ouWFg+e0oFxuICogQHBhcmFtIGFuaW1hdGVDZmcg5Yqo55S76YWN572uXG4gKiBAcGFyYW0gY2ZnIOmineWkluS/oeaBr1xuICovXG5mdW5jdGlvbiB6b29tT3V0KHNoYXBlLCBhbmltYXRlQ2ZnLCBjZmcpIHtcbiAgICBkb1NoYXBlWm9vbShzaGFwZSwgYW5pbWF0ZUNmZywgJ3pvb21PdXQnKTtcbn1cbmV4cG9ydHMuem9vbU91dCA9IHpvb21PdXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD16b29tLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kb0dyb3VwQXBwZWFyQW5pbWF0ZSA9IGV4cG9ydHMuZG9BbmltYXRlID0gZXhwb3J0cy5nZXREZWZhdWx0QW5pbWF0ZUNmZyA9IGV4cG9ydHMuREVGQVVMVF9BTklNQVRFX0NGRyA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgYW5pbWF0aW9uXzEgPSByZXF1aXJlKFwiLi9hbmltYXRpb25cIik7XG4vLyDpu5jorqTnmoTliqjnlLvlj4LmlbDphY3nva5cbmV4cG9ydHMuREVGQVVMVF9BTklNQVRFX0NGRyA9IHtcbiAgICBhcHBlYXI6IHtcbiAgICAgICAgZHVyYXRpb246IDQ1MCxcbiAgICAgICAgZWFzaW5nOiAnZWFzZVF1YWRPdXQnLFxuICAgIH0sXG4gICAgdXBkYXRlOiB7XG4gICAgICAgIGR1cmF0aW9uOiA0MDAsXG4gICAgICAgIGVhc2luZzogJ2Vhc2VRdWFkSW5PdXQnLFxuICAgIH0sXG4gICAgZW50ZXI6IHtcbiAgICAgICAgZHVyYXRpb246IDQwMCxcbiAgICAgICAgZWFzaW5nOiAnZWFzZVF1YWRJbk91dCcsXG4gICAgfSxcbiAgICBsZWF2ZToge1xuICAgICAgICBkdXJhdGlvbjogMzUwLFxuICAgICAgICBlYXNpbmc6ICdlYXNlUXVhZEluJyxcbiAgICB9LFxufTtcbi8vIOWQhOS4qiBHZW9tZXRyeSDpu5jorqTnmoTliqjnlLvmiafooYzlh73mlbBcbnZhciBHRU9NRVRSWV9BTklNQVRFX0NGRyA9IHtcbiAgICBpbnRlcnZhbDogZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVudGVyOiB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBjb29yZGluYXRlLmlzUmVjdCA/IChjb29yZGluYXRlLmlzVHJhbnNwb3NlZCA/ICdzY2FsZS1pbi14JyA6ICdzY2FsZS1pbi15JykgOiAnZmFkZS1pbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXBkYXRlOiB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBjb29yZGluYXRlLmlzUG9sYXIgJiYgY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQgPyAnc2VjdG9yLXBhdGgtdXBkYXRlJyA6IG51bGwsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVhdmU6IHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLW91dCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgbGluZToge1xuICAgICAgICBlbnRlcjoge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1pbicsXG4gICAgICAgIH0sXG4gICAgICAgIGxlYXZlOiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLW91dCcsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBwYXRoOiB7XG4gICAgICAgIGVudGVyOiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLWluJyxcbiAgICAgICAgfSxcbiAgICAgICAgbGVhdmU6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ2ZhZGUtb3V0JyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHBvaW50OiB7XG4gICAgICAgIGFwcGVhcjoge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnem9vbS1pbicsXG4gICAgICAgIH0sXG4gICAgICAgIGVudGVyOiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICd6b29tLWluJyxcbiAgICAgICAgfSxcbiAgICAgICAgbGVhdmU6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ3pvb20tb3V0JyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIGFyZWE6IHtcbiAgICAgICAgZW50ZXI6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ2ZhZGUtaW4nLFxuICAgICAgICB9LFxuICAgICAgICBsZWF2ZToge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1vdXQnLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgcG9seWdvbjoge1xuICAgICAgICBlbnRlcjoge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1pbicsXG4gICAgICAgIH0sXG4gICAgICAgIGxlYXZlOiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLW91dCcsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBzY2hlbWE6IHtcbiAgICAgICAgZW50ZXI6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ2ZhZGUtaW4nLFxuICAgICAgICB9LFxuICAgICAgICBsZWF2ZToge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1vdXQnLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgZWRnZToge1xuICAgICAgICBlbnRlcjoge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1pbicsXG4gICAgICAgIH0sXG4gICAgICAgIGxlYXZlOiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLW91dCcsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBsYWJlbDoge1xuICAgICAgICBhcHBlYXI6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ2ZhZGUtaW4nLFxuICAgICAgICAgICAgZGVsYXk6IDQ1MCxcbiAgICAgICAgfSxcbiAgICAgICAgZW50ZXI6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ2ZhZGUtaW4nLFxuICAgICAgICB9LFxuICAgICAgICB1cGRhdGU6IHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ3Bvc2l0aW9uLXVwZGF0ZScsXG4gICAgICAgIH0sXG4gICAgICAgIGxlYXZlOiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLW91dCcsXG4gICAgICAgIH0sXG4gICAgfSxcbn07XG4vLyDlkITkuKogR2VvbWV0cnkg6buY6K6k55qE576k57uE5Ye65Zy65Yqo55S7XG52YXIgR0VPTUVUUllfR1JPVVBfQVBQRUFSX0FOSU1BVElPTiA9IHtcbiAgICBsaW5lOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbmltYXRpb246ICd3YXZlLWluJyxcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGFyZWE6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogJ3dhdmUtaW4nLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgcGF0aDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1pbicsXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBpbnRlcnZhbDogZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICAgICAgdmFyIGFuaW1hdGlvbjtcbiAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNSZWN0KSB7XG4gICAgICAgICAgICBhbmltYXRpb24gPSBjb29yZGluYXRlLmlzVHJhbnNwb3NlZCA/ICdncm93LWluLXgnIDogJ2dyb3ctaW4teSc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhbmltYXRpb24gPSAnZ3Jvdy1pbi14eSc7XG4gICAgICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyICYmIGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgLy8gcGllIGNoYXJ0XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uID0gJ3dhdmUtaW4nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbmltYXRpb246IGFuaW1hdGlvbixcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIHNjaGVtYTogZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICAgICAgdmFyIGFuaW1hdGlvbjtcbiAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNSZWN0KSB7XG4gICAgICAgICAgICBhbmltYXRpb24gPSBjb29yZGluYXRlLmlzVHJhbnNwb3NlZCA/ICdncm93LWluLXgnIDogJ2dyb3ctaW4teSc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhbmltYXRpb24gPSAnZ3Jvdy1pbi14eSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogYW5pbWF0aW9uLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgcG9seWdvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1pbicsXG4gICAgICAgICAgICBkdXJhdGlvbjogNTAwLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgZWRnZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYW5pbWF0aW9uOiAnZmFkZS1pbicsXG4gICAgICAgIH07XG4gICAgfSxcbn07XG4vLyDop6PmnpDnlKjmiLfnmoTliqjnlLvphY3nva5cbmZ1bmN0aW9uIHBhcnNlQW5pbWF0ZUNvbmZpZyhhbmltYXRlQ2ZnLCBkYXRhKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGVsYXk6IHV0aWxfMS5pc0Z1bmN0aW9uKGFuaW1hdGVDZmcuZGVsYXkpID8gYW5pbWF0ZUNmZy5kZWxheShkYXRhKSA6IGFuaW1hdGVDZmcuZGVsYXksXG4gICAgICAgIGVhc2luZzogdXRpbF8xLmlzRnVuY3Rpb24oYW5pbWF0ZUNmZy5lYXNpbmcpID8gYW5pbWF0ZUNmZy5lYXNpbmcoZGF0YSkgOiBhbmltYXRlQ2ZnLmVhc2luZyxcbiAgICAgICAgZHVyYXRpb246IHV0aWxfMS5pc0Z1bmN0aW9uKGFuaW1hdGVDZmcuZHVyYXRpb24pID8gYW5pbWF0ZUNmZy5kdXJhdGlvbihkYXRhKSA6IGFuaW1hdGVDZmcuZHVyYXRpb24sXG4gICAgICAgIGNhbGxiYWNrOiBhbmltYXRlQ2ZnLmNhbGxiYWNrLFxuICAgIH07XG59XG4vKipcbiAqIEBpZ25vcmVcbiAqIOiOt+WPliBlbGVtZW50TmFtZSDlr7nlupTnmoTliqjnlLvphY3nva7vvIzlvZPlo7DmmI7kuoYgYGFuaW1hdGVUeXBlYO+8jOWImei/lOWbniBgYW5pbWF0ZVR5cGVgIOWvueW6lOeahOWKqOeUu+mFjee9rlxuICogQHBhcmFtIGVsZW1lbnROYW1lIOWFg+e0oOWQjeensFxuICogQHBhcmFtIGNvb3JkaW5hdGUg5YGa6KGo5byf57G75Z6LXG4gKiBAcGFyYW0gYW5pbWF0ZVR5cGUg5Y+v6YCJ77yM5Yqo55S757G75Z6LXG4gKi9cbmZ1bmN0aW9uIGdldERlZmF1bHRBbmltYXRlQ2ZnKGVsZW1lbnROYW1lLCBjb29yZGluYXRlLCBhbmltYXRlVHlwZSkge1xuICAgIHZhciBhbmltYXRlQ2ZnID0gR0VPTUVUUllfQU5JTUFURV9DRkdbZWxlbWVudE5hbWVdO1xuICAgIGlmIChhbmltYXRlQ2ZnKSB7XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihhbmltYXRlQ2ZnKSkge1xuICAgICAgICAgICAgYW5pbWF0ZUNmZyA9IGFuaW1hdGVDZmcoY29vcmRpbmF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYW5pbWF0ZUNmZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBleHBvcnRzLkRFRkFVTFRfQU5JTUFURV9DRkcsIGFuaW1hdGVDZmcpO1xuICAgICAgICBpZiAoYW5pbWF0ZVR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBhbmltYXRlQ2ZnW2FuaW1hdGVUeXBlXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYW5pbWF0ZUNmZztcbn1cbmV4cG9ydHMuZ2V0RGVmYXVsdEFuaW1hdGVDZmcgPSBnZXREZWZhdWx0QW5pbWF0ZUNmZztcbi8qKlxuICogQGlnbm9yZVxuICog5bel5YW35Ye95pWwXG4gKiDmoLnmja7nlKjmiLfkvKDlhaXnmoTphY3nva7kuLogc2hhcGUg5omn6KGM5Yqo55S7XG4gKiBAcGFyYW0gc2hhcGUg5omn6KGM5Yqo55S755qE5Zu+5b2i5YWD57SgXG4gKiBAcGFyYW0gYW5pbWF0ZUNmZyDliqjnlLvphY3nva5cbiAqIEBwYXJhbSBjZmcg6aKd5aSW55qE5L+h5oGvXG4gKi9cbmZ1bmN0aW9uIGRvQW5pbWF0ZShzaGFwZSwgYW5pbWF0ZUNmZywgY2ZnKSB7XG4gICAgdmFyIGRhdGEgPSB1dGlsXzEuZ2V0KHNoYXBlLmdldCgnb3JpZ2luJyksICdkYXRhJywgY29uc3RhbnRfMS5GSUVMRF9PUklHSU4pO1xuICAgIHZhciBhbmltYXRpb24gPSBhbmltYXRlQ2ZnLmFuaW1hdGlvbjsgLy8g6I635Y+W5Yqo55S75omn6KGM5Ye95pWwXG4gICAgdmFyIHBhcnNlZEFuaW1hdGVDZmcgPSBwYXJzZUFuaW1hdGVDb25maWcoYW5pbWF0ZUNmZywgZGF0YSk7XG4gICAgaWYgKGFuaW1hdGlvbikge1xuICAgICAgICAvLyDnlKjmiLflo7DmmI7kuobliqjnlLvmiafooYzlh73mlbBcbiAgICAgICAgdmFyIGFuaW1hdGVGdW5jdGlvbiA9IGFuaW1hdGlvbl8xLmdldEFuaW1hdGlvbihhbmltYXRpb24pO1xuICAgICAgICBpZiAoYW5pbWF0ZUZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBhbmltYXRlRnVuY3Rpb24oc2hhcGUsIHBhcnNlZEFuaW1hdGVDZmcsIGNmZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIOayoeacieWjsOaYju+8jOWImeagueaNriB0b0F0dHJzIOWBmuW3ruWAvOWKqOeUu1xuICAgICAgICBzaGFwZS5hbmltYXRlKGNmZy50b0F0dHJzLCBwYXJzZWRBbmltYXRlQ2ZnKTtcbiAgICB9XG59XG5leHBvcnRzLmRvQW5pbWF0ZSA9IGRvQW5pbWF0ZTtcbi8qKlxuICogQGlnbm9yZVxuICog5omn6KGMIEdlb21ldHJ5IOe+pOe7hOWFpeWcuuWKqOeUu1xuICogQHBhcmFtIGNvbnRhaW5lciDmiafooYznvqTnu4TliqjnlLvnmoTlm77lvaLlhYPntKBcbiAqIEBwYXJhbSBhbmltYXRlQ2ZnIOWKqOeUu+mFjee9rlxuICogQHBhcmFtIGdlb21ldHJ5VHlwZSBnZW9tZXRyeSDnsbvlnotcbiAqIEBwYXJhbSBjb29yZGluYXRlIOWdkOagh+ezu+WvueixoVxuICogQHBhcmFtIG1pbllQb2ludCB5IOi9tOacgOWwj+WAvOWvueW6lOeahOeUu+W4g+WdkOagh+eCuVxuICovXG5mdW5jdGlvbiBkb0dyb3VwQXBwZWFyQW5pbWF0ZShjb250YWluZXIsIGFuaW1hdGVDZmcsIGdlb21ldHJ5VHlwZSwgY29vcmRpbmF0ZSwgbWluWVBvaW50KSB7XG4gICAgaWYgKEdFT01FVFJZX0dST1VQX0FQUEVBUl9BTklNQVRJT05bZ2VvbWV0cnlUeXBlXSkge1xuICAgICAgICB2YXIgZGVmYXVsdENmZyA9IEdFT01FVFJZX0dST1VQX0FQUEVBUl9BTklNQVRJT05bZ2VvbWV0cnlUeXBlXShjb29yZGluYXRlKTtcbiAgICAgICAgdmFyIGFuaW1hdGlvbiA9IGFuaW1hdGlvbl8xLmdldEFuaW1hdGlvbih1dGlsXzEuZ2V0KGRlZmF1bHRDZmcsICdhbmltYXRpb24nLCAnJykpO1xuICAgICAgICBpZiAoYW5pbWF0aW9uKSB7XG4gICAgICAgICAgICB2YXIgY2ZnID0gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGV4cG9ydHMuREVGQVVMVF9BTklNQVRFX0NGRy5hcHBlYXIpLCBkZWZhdWx0Q2ZnKSwgYW5pbWF0ZUNmZyk7XG4gICAgICAgICAgICBjb250YWluZXIuc3RvcEFuaW1hdGUoKTsgLy8g5YWI57uT5p2f5b2T5YmNIGNvbnRhaW5lciDliqjnlLtcbiAgICAgICAgICAgIGFuaW1hdGlvbihjb250YWluZXIsIGNmZywge1xuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGU6IGNvb3JkaW5hdGUsXG4gICAgICAgICAgICAgICAgbWluWVBvaW50OiBtaW5ZUG9pbnQsXG4gICAgICAgICAgICAgICAgdG9BdHRyczogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy5kb0dyb3VwQXBwZWFyQW5pbWF0ZSA9IGRvR3JvdXBBcHBlYXJBbmltYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBldmVudF9lbWl0dGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiQGFudHYvZXZlbnQtZW1pdHRlclwiKSk7XG4vKipcbiAqIEcyIENoYXJ044CBVmlld+OAgUdlb21ldHJ5IOS7peWPiiBFbGVtZW50IOetieeahOWfuuexu++8jOaPkOS+m+S6i+S7tuS7peWPiuS4gOS6m+mAmueUqOeahOaWueazleOAglxuICovXG52YXIgQmFzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhCYXNlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhc2UoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIC8qKiDmoIfor4blr7nosaHmmK/lkKblt7LplIDmr4EgKi9cbiAgICAgICAgX3RoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIHZhciBfYSA9IGNmZy52aXNpYmxlLCB2aXNpYmxlID0gX2EgPT09IHZvaWQgMCA/IHRydWUgOiBfYTtcbiAgICAgICAgX3RoaXMudmlzaWJsZSA9IHZpc2libGU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5pi+56S644CCXG4gICAgICovXG4gICAgQmFzZS5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpc2libGUgPSB0aGlzLnZpc2libGU7XG4gICAgICAgIGlmICghdmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VWaXNpYmxlKHRydWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpmpDol4/jgIJcbiAgICAgKi9cbiAgICBCYXNlLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmlzaWJsZSA9IHRoaXMudmlzaWJsZTtcbiAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlVmlzaWJsZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOmUgOavgeOAglxuICAgICAqL1xuICAgIEJhc2UucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub2ZmKCk7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYvuekuuaIluiAhemakOiXj+OAglxuICAgICAqIEBwYXJhbSB2aXNpYmxlXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBCYXNlLnByb3RvdHlwZS5jaGFuZ2VWaXNpYmxlID0gZnVuY3Rpb24gKHZpc2libGUpIHtcbiAgICAgICAgaWYgKHRoaXMudmlzaWJsZSA9PT0gdmlzaWJsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHZpc2libGU7XG4gICAgfTtcbiAgICByZXR1cm4gQmFzZTtcbn0oZXZlbnRfZW1pdHRlcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJhc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBlbmdpbmVfMSA9IHJlcXVpcmUoXCIuLi9lbmdpbmVcIik7XG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9kb21cIik7XG52YXIgdmlld18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdmlld1wiKSk7XG4vKipcbiAqIENoYXJ0IOexu++8jOaYr+S9v+eUqCBHMiDov5vooYznu5jlm77nmoTlhaXlj6PjgIJcbiAqL1xudmFyIENoYXJ0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENoYXJ0LCBfc3VwZXIpO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBmdW5jdGlvbiBDaGFydChwcm9wcykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gcHJvcHMuY29udGFpbmVyLCB3aWR0aCA9IHByb3BzLndpZHRoLCBoZWlnaHQgPSBwcm9wcy5oZWlnaHQsIF9hID0gcHJvcHMuYXV0b0ZpdCwgYXV0b0ZpdCA9IF9hID09PSB2b2lkIDAgPyBmYWxzZSA6IF9hLCBwYWRkaW5nID0gcHJvcHMucGFkZGluZywgYXBwZW5kUGFkZGluZyA9IHByb3BzLmFwcGVuZFBhZGRpbmcsIF9iID0gcHJvcHMucmVuZGVyZXIsIHJlbmRlcmVyID0gX2IgPT09IHZvaWQgMCA/ICdjYW52YXMnIDogX2IsIHBpeGVsUmF0aW8gPSBwcm9wcy5waXhlbFJhdGlvLCBfYyA9IHByb3BzLmxvY2FsUmVmcmVzaCwgbG9jYWxSZWZyZXNoID0gX2MgPT09IHZvaWQgMCA/IHRydWUgOiBfYywgX2QgPSBwcm9wcy52aXNpYmxlLCB2aXNpYmxlID0gX2QgPT09IHZvaWQgMCA/IHRydWUgOiBfZCwgX2UgPSBwcm9wcy5kZWZhdWx0SW50ZXJhY3Rpb25zLCBkZWZhdWx0SW50ZXJhY3Rpb25zID0gX2UgPT09IHZvaWQgMCA/IFsndG9vbHRpcCcsICdsZWdlbmQtZmlsdGVyJywgJ2xlZ2VuZC1hY3RpdmUnLCAnY29udGludW91cy1maWx0ZXInLCAnZWxsaXBzaXMtdGV4dCddIDogX2UsIG9wdGlvbnMgPSBwcm9wcy5vcHRpb25zLCBsaW1pdEluUGxvdCA9IHByb3BzLmxpbWl0SW5QbG90LCB0aGVtZSA9IHByb3BzLnRoZW1lO1xuICAgICAgICB2YXIgZWxlID0gdXRpbF8xLmlzU3RyaW5nKGNvbnRhaW5lcikgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjb250YWluZXIpIDogY29udGFpbmVyO1xuICAgICAgICAvLyDnlJ/miJDlhoXpg6jmraPlvI/nu5jliLbnmoQgZGl2IOWFg+e0oFxuICAgICAgICB2YXIgd3JhcHBlckVsZW1lbnQgPSBkb21fMS5jcmVhdGVEb20oJzxkaXYgc3R5bGU9XCJwb3NpdGlvbjpyZWxhdGl2ZTtcIj48L2Rpdj4nKTtcbiAgICAgICAgZWxlLmFwcGVuZENoaWxkKHdyYXBwZXJFbGVtZW50KTtcbiAgICAgICAgLy8gaWYgYXV0b0ZpdCwgdXNlIHRoZSBjb250YWluZXIgc2l6ZSwgdG8gYXZvaWQgdGhlIGdyYXBoIHJlbmRlciB0d2ljZS5cbiAgICAgICAgdmFyIHNpemUgPSBkb21fMS5nZXRDaGFydFNpemUoZWxlLCBhdXRvRml0LCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgdmFyIEcgPSBlbmdpbmVfMS5nZXRFbmdpbmUocmVuZGVyZXIpO1xuICAgICAgICB2YXIgY2FudmFzID0gbmV3IEcuQ2FudmFzKHRzbGliXzEuX19hc3NpZ24oeyBjb250YWluZXI6IHdyYXBwZXJFbGVtZW50LCBwaXhlbFJhdGlvOiBwaXhlbFJhdGlvLFxuICAgICAgICAgICAgbG9jYWxSZWZyZXNoOiBsb2NhbFJlZnJlc2ggfSwgc2l6ZSkpO1xuICAgICAgICAvLyDosIPnlKggdmlldyDnmoTliJvlu7pcbiAgICAgICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICBjYW52YXM6IGNhbnZhcyxcbiAgICAgICAgICAgIC8vIGNyZWF0ZSAzIGdyb3VwIGxheWVycyBmb3Igdmlld3MuXG4gICAgICAgICAgICBiYWNrZ3JvdW5kR3JvdXA6IGNhbnZhcy5hZGRHcm91cCh7IHpJbmRleDogY29uc3RhbnRfMS5HUk9VUF9aX0lOREVYLkJHIH0pLFxuICAgICAgICAgICAgbWlkZGxlR3JvdXA6IGNhbnZhcy5hZGRHcm91cCh7IHpJbmRleDogY29uc3RhbnRfMS5HUk9VUF9aX0lOREVYLk1JRCB9KSxcbiAgICAgICAgICAgIGZvcmVncm91bmRHcm91cDogY2FudmFzLmFkZEdyb3VwKHsgekluZGV4OiBjb25zdGFudF8xLkdST1VQX1pfSU5ERVguRk9SRSB9KSxcbiAgICAgICAgICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgICAgICAgICBhcHBlbmRQYWRkaW5nOiBhcHBlbmRQYWRkaW5nLFxuICAgICAgICAgICAgdmlzaWJsZTogdmlzaWJsZSxcbiAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgICAgICAgICBsaW1pdEluUGxvdDogbGltaXRJblBsb3QsXG4gICAgICAgICAgICB0aGVtZTogdGhlbWUsXG4gICAgICAgIH0pIHx8IHRoaXM7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB3aGVuIGNvbnRhaW5lciBzaXplIGNoYW5nZWQsIGNoYW5nZSBjaGFydCBzaXplIHByb3BzLCBhbmQgcmUtcmVuZGVyLlxuICAgICAgICAgKi9cbiAgICAgICAgX3RoaXMub25SZXNpemUgPSB1dGlsXzEuZGVib3VuY2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuZm9yY2VGaXQoKTtcbiAgICAgICAgfSwgMzAwKTtcbiAgICAgICAgX3RoaXMuZWxlID0gZWxlO1xuICAgICAgICBfdGhpcy5jYW52YXMgPSBjYW52YXM7XG4gICAgICAgIF90aGlzLndpZHRoID0gc2l6ZS53aWR0aDtcbiAgICAgICAgX3RoaXMuaGVpZ2h0ID0gc2l6ZS5oZWlnaHQ7XG4gICAgICAgIF90aGlzLmF1dG9GaXQgPSBhdXRvRml0O1xuICAgICAgICBfdGhpcy5sb2NhbFJlZnJlc2ggPSBsb2NhbFJlZnJlc2g7XG4gICAgICAgIF90aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIF90aGlzLndyYXBwZXJFbGVtZW50ID0gd3JhcHBlckVsZW1lbnQ7XG4gICAgICAgIC8vIOiHqumAguW6lOWkp+Wwj1xuICAgICAgICBfdGhpcy51cGRhdGVDYW52YXNTdHlsZSgpO1xuICAgICAgICBfdGhpcy5iaW5kQXV0b0ZpdCgpO1xuICAgICAgICBfdGhpcy5pbml0RGVmYXVsdEludGVyYWN0aW9ucyhkZWZhdWx0SW50ZXJhY3Rpb25zKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBDaGFydC5wcm90b3R5cGUuaW5pdERlZmF1bHRJbnRlcmFjdGlvbnMgPSBmdW5jdGlvbiAoaW50ZXJhY3Rpb25zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGludGVyYWN0aW9ucywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICBfdGhpcy5pbnRlcmFjdGlvbihpbnRlcmFjdGlvbik7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5pS55Y+Y5Zu+6KGo5aSn5bCP77yM5ZCM5pe26YeN5paw5riy5p+T44CCXG4gICAgICogQHBhcmFtIHdpZHRoIOWbvuihqOWuveW6plxuICAgICAqIEBwYXJhbSBoZWlnaHQg5Zu+6KGo6auY5bqmXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBDaGFydC5wcm90b3R5cGUuY2hhbmdlU2l6ZSA9IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIC8vIOWmguaenOWuvemrmOS4gOiHtO+8jOmCo+S5iCBjaGFuZ2VTaXplIOS4jeaJp+ihjOS7u+S9leaTjeS9nFxuICAgICAgICBpZiAodGhpcy53aWR0aCA9PT0gd2lkdGggJiYgdGhpcy5oZWlnaHQgPT09IGhlaWdodCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgdGhpcy5jYW52YXMuY2hhbmdlU2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgLy8g6YeN5paw5riy5p+TXG4gICAgICAgIHRoaXMucmVuZGVyKHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOmUgOavgeWbvuihqO+8jOWQjOaXtuino+e7keS6i+S7tu+8jOmUgOavgeWIm+W7uueahCBHLkNhbnZhcyDlrp7kvovjgIJcbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgQ2hhcnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLnVuYmluZEF1dG9GaXQoKTtcbiAgICAgICAgdGhpcy5jYW52YXMuZGVzdHJveSgpO1xuICAgICAgICBkb21fMS5yZW1vdmVEb20odGhpcy53cmFwcGVyRWxlbWVudCk7XG4gICAgICAgIHRoaXMud3JhcHBlckVsZW1lbnQgPSBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5pi+56S65oiW6ZqQ6JeP5Zu+6KGoXG4gICAgICogQHBhcmFtIHZpc2libGUg5piv5ZCm5Y+v6KeB77yMdHJ1ZSDooajnpLrmmL7npLrvvIxmYWxzZSDooajnpLrpmpDol49cbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIENoYXJ0LnByb3RvdHlwZS5jaGFuZ2VWaXNpYmxlID0gZnVuY3Rpb24gKHZpc2libGUpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jaGFuZ2VWaXNpYmxlLmNhbGwodGhpcywgdmlzaWJsZSk7IC8vIOmcgOimgeabtOaWsCB2aXNpYmxlIOWPmOmHj1xuICAgICAgICB0aGlzLndyYXBwZXJFbGVtZW50LnN0eWxlLmRpc3BsYXkgPSB2aXNpYmxlID8gJycgOiAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6Ieq5Yqo5qC55o2u5a655Zmo5aSn5bCPIHJlc2l6ZSDnlLvluINcbiAgICAgKi9cbiAgICBDaGFydC5wcm90b3R5cGUuZm9yY2VGaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHNraXAgaWYgYWxyZWFkeSBkZXN0cm95ZWRcbiAgICAgICAgaWYgKCF0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgLy8g5rOo5oSP56ys5LqM5Y+C5pWw55SoIHRydWXvvIzmhI/mgJ3mmK/ljbPml7YgYXV0b0ZpdCA9IGZhbHNl77yMZm9yY2VGaXQoKSDosIPnlKjkuYvlkI7kuIDmoLfmmK/pgILphY3lrrnlmahcbiAgICAgICAgICAgIHZhciBfYSA9IGRvbV8xLmdldENoYXJ0U2l6ZSh0aGlzLmVsZSwgdHJ1ZSwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZVNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENoYXJ0LnByb3RvdHlwZS51cGRhdGVDYW52YXNTdHlsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZG9tXzEubW9kaWZ5Q1NTKHRoaXMuY2FudmFzLmdldCgnZWwnKSwge1xuICAgICAgICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaycsXG4gICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiAnbWlkZGxlJyxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDaGFydC5wcm90b3R5cGUuYmluZEF1dG9GaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmF1dG9GaXQpIHtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uUmVzaXplKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ2hhcnQucHJvdG90eXBlLnVuYmluZEF1dG9GaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmF1dG9GaXQpIHtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uUmVzaXplKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIENoYXJ0O1xufSh2aWV3XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2hhcnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFydC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIGFuaW1hdGVfMSA9IHJlcXVpcmUoXCIuLi8uLi9hbmltYXRlL1wiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uLy4uL2NvbnN0YW50XCIpO1xudmFyIGNvb3JkaW5hdGVfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2Nvb3JkaW5hdGVcIik7XG52YXIgaGVscGVyXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9oZWxwZXJcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbi8qKlxuICogQW5ub3RhdGlvbiBjb250cm9sbGVyLCDkuLvopoHkvZznlKg6XG4gKiAxLiDliJvlu7ogQW5ub3RhdGlvbjogbGluZeOAgXRleHTjgIFhcmMgLi4uXG4gKiAyLiDnlJ/lkb3lkajmnJ86IGluaXTjgIFsYXlvdXTjgIFyZW5kZXLjgIFjbGVhcuOAgWRlc3Ryb3lcbiAqL1xudmFyIEFubm90YXRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQW5ub3RhdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBbm5vdGF0aW9uKHZpZXcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdmlldykgfHwgdGhpcztcbiAgICAgICAgLyog57uE5Lu25pu05paw55qEIGNhY2hl77yM57uE5Lu26YWN572uIG9iamVjdCA6IOe7hOS7tiAqL1xuICAgICAgICBfdGhpcy5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgX3RoaXMuZm9yZWdyb3VuZENvbnRhaW5lciA9IF90aGlzLnZpZXcuZ2V0TGF5ZXIoY29uc3RhbnRfMS5MQVlFUi5GT1JFKS5hZGRHcm91cCgpO1xuICAgICAgICBfdGhpcy5iYWNrZ3JvdW5kQ29udGFpbmVyID0gX3RoaXMudmlldy5nZXRMYXllcihjb25zdGFudF8xLkxBWUVSLkJHKS5hZGRHcm91cCgpO1xuICAgICAgICBfdGhpcy5vcHRpb24gPSBbXTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQW5ub3RhdGlvbi5wcm90b3R5cGUsIFwibmFtZVwiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICdhbm5vdGF0aW9uJztcbiAgICAgICAgfSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuICAgIEFubm90YXRpb24ucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUubGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgY29tcG9uZW50cyA9IHRoaXMuZ2V0Q29tcG9uZW50cygpO1xuICAgICAgICB2YXIgdXBkYXRlQ29tcG9uZW50Rm4gPSBmdW5jdGlvbiAoY28pIHtcbiAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBjby5jb21wb25lbnQsIGV4dHJhID0gY28uZXh0cmE7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGV4dHJhLnR5cGU7XG4gICAgICAgICAgICB2YXIgdGhlbWUgPSBfdGhpcy5nZXRBbm5vdGF0aW9uVGhlbWUodHlwZSk7XG4gICAgICAgICAgICBjb21wb25lbnQudXBkYXRlKF90aGlzLmdldEFubm90YXRpb25DZmcodHlwZSwgZXh0cmEsIHRoZW1lKSk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBjcmVhdGVDb21wb25lbnRGbiA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgICAgIHZhciBjbyA9IF90aGlzLmNyZWF0ZUFubm90YXRpb24ob3B0aW9uKTtcbiAgICAgICAgICAgIGlmIChjbykge1xuICAgICAgICAgICAgICAgIGNvLmNvbXBvbmVudC5pbml0KCk7XG4gICAgICAgICAgICAgICAgLy8gTm90Ze+8mnJlZ2lvbkZpbHRlciDnibnmrorlpITnkIbvvIxyZWdpb25GaWx0ZXLpnIDopoHlj5bliLAgR2VvbWV0cnkg5Lit55qEIFNoYXBl77yM6ZyA6KaB5ZyoIHZpZXcgcmVuZGVyIOS5i+WQjuWkhOeQhlxuICAgICAgICAgICAgICAgIC8vIOWFtuS7lue7hOS7tuS9v+eUqOWkluWxgueahOe7n+S4gCByZW5kZXIg6YC76L6RXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbi50eXBlID09PSAncmVnaW9uRmlsdGVyJykge1xuICAgICAgICAgICAgICAgICAgICBjby5jb21wb25lbnQucmVuZGVyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOe8k+WtmOi1t+adpVxuICAgICAgICAgICAgICAgIF90aGlzLmNhY2hlLnNldChvcHRpb24sIGNvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGNvbXBvbmVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChjb21wb25lbnRzLCBmdW5jdGlvbiAoY28pIHtcbiAgICAgICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gY28uY29tcG9uZW50O1xuICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQuZ2V0KCd0eXBlJykgPT09ICdyZWdpb25GaWx0ZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlZ2lvbkZpbHRlciDkvp3otZbnu5jliLblkI7nmoQgR2VvbWV0cnkgU2hhcGVzXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnZpZXcuZ2V0Um9vdFZpZXcoKS5vbmNlKGNvbnN0YW50XzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9SRU5ERVIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudEZuKGNvKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVDb21wb25lbnRGbihjbyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLm9wdGlvbiwgZnVuY3Rpb24gKG9wdGlvbikge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb24udHlwZSA9PT0gJ3JlZ2lvbkZpbHRlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudmlldy5nZXRSb290VmlldygpLm9uY2UoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1JFTkRFUiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVnaW9uRmlsdGVyIOS+nei1lue7mOWItuWQjueahCBHZW9tZXRyeSBTaGFwZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbXBvbmVudEZuKG9wdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ29tcG9uZW50Rm4ob3B0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDlm6DkuLogQW5ub3RhdGlvbiDkuI3lj4LkuI7luIPlsYDvvIzkvYbmmK/muLLmn5PnmoTkvY3nva7kvp3otZbkuo7lnZDmoIfns7vvvIzmiYDku6Xlj6/ku6XlsIbnu5jliLbpmLbmrrXlu7bov5/liLAgbGF5b3V0KCkg6L+b6KGMXG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrBcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIC8vIOW3sue7j+WkhOeQhui/h+eahCBsZWdlbmRcbiAgICAgICAgdmFyIHVwZGF0ZWQgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB2YXIgdXBkYXRlQ29tcG9uZW50Rm4gPSBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IG9wdGlvbi50eXBlO1xuICAgICAgICAgICAgdmFyIHRoZW1lID0gX3RoaXMuZ2V0QW5ub3RhdGlvblRoZW1lKHR5cGUpO1xuICAgICAgICAgICAgdmFyIGNmZyA9IF90aGlzLmdldEFubm90YXRpb25DZmcodHlwZSwgb3B0aW9uLCB0aGVtZSk7XG4gICAgICAgICAgICB2YXIgZXhpc3RDbyA9IF90aGlzLmNhY2hlLmdldChvcHRpb24pO1xuICAgICAgICAgICAgLy8g5a2Y5Zyo77yM5YiZ5pu05pawXG4gICAgICAgICAgICBpZiAoZXhpc3RDbykge1xuICAgICAgICAgICAgICAgIC8vIOW/veeVpeaOieS4gOS6m+mFjee9rlxuICAgICAgICAgICAgICAgIGhlbHBlcl8xLm9taXQoY2ZnLCBbJ2NvbnRhaW5lciddKTtcbiAgICAgICAgICAgICAgICBleGlzdENvLmNvbXBvbmVudC51cGRhdGUoY2ZnKTtcbiAgICAgICAgICAgICAgICB1cGRhdGVkLnNldChvcHRpb24sIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo77yM5YiZ5Yib5bu6XG4gICAgICAgICAgICAgICAgdmFyIGNvID0gX3RoaXMuY3JlYXRlQW5ub3RhdGlvbihvcHRpb24pO1xuICAgICAgICAgICAgICAgIGlmIChjbykge1xuICAgICAgICAgICAgICAgICAgICBjby5jb21wb25lbnQuaW5pdCgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBOb3Rl77yacmVnaW9uRmlsdGVyIOeJueauiuWkhOeQhu+8jHJlZ2lvbkZpbHRlcumcgOimgeWPluWIsCBHZW9tZXRyeSDkuK3nmoQgU2hhcGXvvIzpnIDopoHlnKggdmlldyByZW5kZXIg5LmL5ZCO5aSE55CGXG4gICAgICAgICAgICAgICAgICAgIC8vIOWFtuS7lue7hOS7tuS9v+eUqOWkluWxgueahOe7n+S4gCByZW5kZXIg6YC76L6RXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb24udHlwZSA9PT0gJ3JlZ2lvbkZpbHRlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvLmNvbXBvbmVudC5yZW5kZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyDnvJPlrZjotbfmnaVcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuY2FjaGUuc2V0KG9wdGlvbiwgY28pO1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkLnNldChvcHRpb24sIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy52aWV3Lm9uY2UoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1JFTkRFUiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8g5YWI55yL5piv5ZCm5pyJIHJlZ2lvbkZpbHRlciDopoHmm7TmlrBcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKF90aGlzLm9wdGlvbiwgZnVuY3Rpb24gKG9wdGlvbikge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb24udHlwZSA9PT0gJ3JlZ2lvbkZpbHRlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlQ29tcG9uZW50Rm4ob3B0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIOWkhOeQhuWujOaIkOS5i+WQju+8jOmUgOavgeWIoOmZpOeahFxuICAgICAgICAgICAgLy8g5LiN5Zyo5aSE55CG5Lit55qEXG4gICAgICAgICAgICB2YXIgbmV3Q2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBfdGhpcy5jYWNoZS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICAgICAgaWYgKHVwZGF0ZWQuaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3Q2FjaGUuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo77yM5YiZ5piv5omA5pyJ6ZyA6KaB6KKr6ZSA5q+B55qE57uE5Lu2XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlLmNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyDmm7TmlrDnvJPlrZhcbiAgICAgICAgICAgIF90aGlzLmNhY2hlID0gbmV3Q2FjaGU7XG4gICAgICAgIH0pO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLm9wdGlvbiwgZnVuY3Rpb24gKG9wdGlvbikge1xuICAgICAgICAgICAgaWYgKG9wdGlvbi50eXBlICE9PSAncmVnaW9uRmlsdGVyJykge1xuICAgICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudEZuKG9wdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF56m6XG4gICAgICogQHBhcmFtIGluY2x1ZGVPcHRpb24g5piv5ZCm5riF56m6IG9wdGlvbiDphY3nva7poblcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIChpbmNsdWRlT3B0aW9uKSB7XG4gICAgICAgIGlmIChpbmNsdWRlT3B0aW9uID09PSB2b2lkIDApIHsgaW5jbHVkZU9wdGlvbiA9IGZhbHNlOyB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY2xlYXIuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5jYWNoZS5jbGVhcigpO1xuICAgICAgICB0aGlzLmZvcmVncm91bmRDb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kQ29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgIC8vIGNsZWFyIGFsbCBvcHRpb25cbiAgICAgICAgaWYgKGluY2x1ZGVPcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9uID0gW107XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEFubm90YXRpb24ucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIodHJ1ZSk7XG4gICAgICAgIHRoaXMuZm9yZWdyb3VuZENvbnRhaW5lci5yZW1vdmUodHJ1ZSk7XG4gICAgICAgIHRoaXMuYmFja2dyb3VuZENvbnRhaW5lci5yZW1vdmUodHJ1ZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlpI3lhpnln7rnsbvnmoTmlrnms5VcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRDb21wb25lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY28gPSBbXTtcbiAgICAgICAgdGhpcy5jYWNoZS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgY28ucHVzaCh2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY287XG4gICAgfTtcbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5jcmVhdGVBbm5vdGF0aW9uID0gZnVuY3Rpb24gKG9wdGlvbikge1xuICAgICAgICB2YXIgdHlwZSA9IG9wdGlvbi50eXBlO1xuICAgICAgICB2YXIgQ3RvciA9IGRlcGVuZGVudHNfMS5Bbm5vdGF0aW9uW3V0aWxfMS51cHBlckZpcnN0KHR5cGUpXTtcbiAgICAgICAgaWYgKEN0b3IpIHtcbiAgICAgICAgICAgIHZhciB0aGVtZSA9IHRoaXMuZ2V0QW5ub3RhdGlvblRoZW1lKHR5cGUpO1xuICAgICAgICAgICAgdmFyIGNmZyA9IHRoaXMuZ2V0QW5ub3RhdGlvbkNmZyh0eXBlLCBvcHRpb24sIHRoZW1lKTtcbiAgICAgICAgICAgIHZhciBhbm5vdGF0aW9uID0gbmV3IEN0b3IoY2ZnKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgY29tcG9uZW50OiBhbm5vdGF0aW9uLFxuICAgICAgICAgICAgICAgIGxheWVyOiB0aGlzLmlzVG9wKGNmZykgPyBjb25zdGFudF8xLkxBWUVSLkZPUkUgOiBjb25zdGFudF8xLkxBWUVSLkJHLFxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogY29uc3RhbnRfMS5ESVJFQ1RJT04uTk9ORSxcbiAgICAgICAgICAgICAgICB0eXBlOiBjb25zdGFudF8xLkNPTVBPTkVOVF9UWVBFLkFOTk9UQVRJT04sXG4gICAgICAgICAgICAgICAgZXh0cmE6IG9wdGlvbixcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIEFQSXMgZm9yIGNyZWF0aW5nIGFubm90YXRpb24gY29tcG9uZW50XG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUuYW5ub3RhdGlvbiA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdGhpcy5vcHRpb24ucHVzaChvcHRpb24pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu6IEFyY1xuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcmV0dXJucyBBbm5vdGF0aW9uQ29udHJvbGxlclxuICAgICAqL1xuICAgIEFubm90YXRpb24ucHJvdG90eXBlLmFyYyA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uKHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAnYXJjJyB9LCBvcHRpb24pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7ogaW1hZ2VcbiAgICAgKiBAcGFyYW0gb3B0aW9uXG4gICAgICogQHJldHVybnMgQW5ub3RhdGlvbkNvbnRyb2xsZXJcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5pbWFnZSA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uKHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAnaW1hZ2UnIH0sIG9wdGlvbikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWIm+W7uiBMaW5lXG4gICAgICogQHBhcmFtIG9wdGlvblxuICAgICAqIEByZXR1cm5zIEFubm90YXRpb25Db250cm9sbGVyXG4gICAgICovXG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUubGluZSA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uKHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAnbGluZScgfSwgb3B0aW9uKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu6IFJlZ2lvblxuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcmV0dXJucyBBbm5vdGF0aW9uQ29udHJvbGxlclxuICAgICAqL1xuICAgIEFubm90YXRpb24ucHJvdG90eXBlLnJlZ2lvbiA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uKHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAncmVnaW9uJyB9LCBvcHRpb24pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7ogVGV4dFxuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcmV0dXJucyBBbm5vdGF0aW9uQ29udHJvbGxlclxuICAgICAqL1xuICAgIEFubm90YXRpb24ucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbih0c2xpYl8xLl9fYXNzaWduKHsgdHlwZTogJ3RleHQnIH0sIG9wdGlvbikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWIm+W7uiBEYXRhTWFya2VyXG4gICAgICogQHBhcmFtIG9wdGlvblxuICAgICAqIEByZXR1cm5zIEFubm90YXRpb25Db250cm9sbGVyXG4gICAgICovXG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUuZGF0YU1hcmtlciA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uKHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAnZGF0YU1hcmtlcicgfSwgb3B0aW9uKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu6IERhdGFSZWdpb25cbiAgICAgKiBAcGFyYW0gb3B0aW9uXG4gICAgICogQHJldHVybnMgQW5ub3RhdGlvbkNvbnRyb2xsZXJcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5kYXRhUmVnaW9uID0gZnVuY3Rpb24gKG9wdGlvbikge1xuICAgICAgICB0aGlzLmFubm90YXRpb24odHNsaWJfMS5fX2Fzc2lnbih7IHR5cGU6ICdkYXRhUmVnaW9uJyB9LCBvcHRpb24pKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWIm+W7uiBSZWdpb25GaWx0ZXJcbiAgICAgKiBAcGFyYW0gb3B0aW9uXG4gICAgICogQHJldHVybnMgQW5ub3RhdGlvbkNvbnRyb2xsZXJcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5yZWdpb25GaWx0ZXIgPSBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbih0c2xpYl8xLl9fYXNzaWduKHsgdHlwZTogJ3JlZ2lvbkZpbHRlcicgfSwgb3B0aW9uKSk7XG4gICAgfTtcbiAgICAvLyBlbmQgQVBJXG4gICAgLyoqXG4gICAgICogcGFyc2UgdGhlIHBvaW50IHBvc2l0aW9uIHRvIFt4LCB5XVxuICAgICAqIEBwYXJhbSBwIFBvc2l0aW9uXG4gICAgICogQHJldHVybnMgeyB4LCB5IH1cbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5wYXJzZVBvc2l0aW9uID0gZnVuY3Rpb24gKHApIHtcbiAgICAgICAgdmFyIHhTY2FsZSA9IHRoaXMudmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgLy8g6L2s5oiQIG9iamVjdFxuICAgICAgICB2YXIgeVNjYWxlcyA9IHRoaXMudmlldy5nZXRTY2FsZXNCeURpbSgneScpO1xuICAgICAgICB2YXIgcG9zaXRpb24gPSB1dGlsXzEuaXNGdW5jdGlvbihwKSA/IHAuY2FsbChudWxsLCB4U2NhbGUsIHlTY2FsZXMpIDogcDtcbiAgICAgICAgdmFyIHggPSAwO1xuICAgICAgICB2YXIgeSA9IDA7XG4gICAgICAgIC8vIOWFpeWPguaYryBbMjQsIDI0XSDov5nnsbvml7ZcbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KHBvc2l0aW9uKSkge1xuICAgICAgICAgICAgdmFyIHhQb3MgPSBwb3NpdGlvblswXSwgeVBvcyA9IHBvc2l0aW9uWzFdO1xuICAgICAgICAgICAgLy8g5aaC5p6c5pWw5o2u5qC85byP5pivIFsnNTAlJywgJzUwJSddIOeahOagvOW8j1xuICAgICAgICAgICAgLy8gZml4OiDljp/lp4vmlbDmja7kuK3lj6/og73kvJrljIXlkKsgJ3h4eDUleHh4JyDov5nmoLfnmoTmlbDmja7vvIzpnIDopoHliKTmlq3kuIsgaHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy9mMi9pc3N1ZXMvNTkwXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHhQb3MpICYmIHhQb3MuaW5kZXhPZignJScpICE9PSAtMSAmJiAhaXNOYU4oeFBvcy5zbGljZSgwLCAtMSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VQZXJjZW50UG9zaXRpb24ocG9zaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeCA9IHRoaXMuZ2V0Tm9ybWFsaXplZFZhbHVlKHhQb3MsIHhTY2FsZSk7XG4gICAgICAgICAgICB5ID0gdGhpcy5nZXROb3JtYWxpemVkVmFsdWUoeVBvcywgT2JqZWN0LnZhbHVlcyh5U2NhbGVzKVswXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXV0aWxfMS5pc05pbChwb3NpdGlvbikpIHtcbiAgICAgICAgICAgIC8vIOWFpeWPguaYryBvYmplY3Qg57uT5p6E77yM5pWw5o2u54K5XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdXRpbF8xLmtleXMocG9zaXRpb24pOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBrZXkgPSBfYVtfaV07XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gcG9zaXRpb25ba2V5XTtcbiAgICAgICAgICAgICAgICBpZiAoa2V5ID09PSB4U2NhbGUuZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9IHRoaXMuZ2V0Tm9ybWFsaXplZFZhbHVlKHZhbHVlLCB4U2NhbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoeVNjYWxlc1trZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIHkgPSB0aGlzLmdldE5vcm1hbGl6ZWRWYWx1ZSh2YWx1ZSwgeVNjYWxlc1trZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRDb29yZGluYXRlKCkuY29udmVydCh7IHg6IHgsIHk6IHkgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBwYXJzZSBhbGwgdGhlIHBvaW50cyBiZXR3ZWVuIHN0YXJ0IGFuZCBlbmRcbiAgICAgKiBAcGFyYW0gc3RhcnRcbiAgICAgKiBAcGFyYW0gZW5kXG4gICAgICogQHJldHVybiBQb2ludFtdXG4gICAgICovXG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUuZ2V0UmVnaW9uUG9pbnRzID0gZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHhTY2FsZSA9IHRoaXMudmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgdmFyIHlTY2FsZXMgPSB0aGlzLnZpZXcuZ2V0U2NhbGVzQnlEaW0oJ3knKTtcbiAgICAgICAgdmFyIHlTY2FsZSA9IE9iamVjdC52YWx1ZXMoeVNjYWxlcylbMF07XG4gICAgICAgIHZhciB4RmllbGQgPSB4U2NhbGUuZmllbGQ7XG4gICAgICAgIHZhciB2aWV3RGF0YSA9IHRoaXMudmlldy5nZXREYXRhKCk7XG4gICAgICAgIHZhciBzdGFydFhWYWx1ZSA9IHV0aWxfMS5pc0FycmF5KHN0YXJ0KSA/IHN0YXJ0WzBdIDogc3RhcnRbeEZpZWxkXTtcbiAgICAgICAgdmFyIGVuZFhWYWx1ZSA9IHV0aWxfMS5pc0FycmF5KGVuZCkgPyBlbmRbMF0gOiBlbmRbeEZpZWxkXTtcbiAgICAgICAgdmFyIGFyciA9IFtdO1xuICAgICAgICB2YXIgc3RhcnRJbmRleDtcbiAgICAgICAgdXRpbF8xLmVhY2godmlld0RhdGEsIGZ1bmN0aW9uIChpdGVtLCBpZHgpIHtcbiAgICAgICAgICAgIGlmIChpdGVtW3hGaWVsZF0gPT09IHN0YXJ0WFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnRJbmRleCA9IGlkeDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpZHggPj0gc3RhcnRJbmRleCkge1xuICAgICAgICAgICAgICAgIHZhciBwb2ludCA9IF90aGlzLnBhcnNlUG9zaXRpb24oW2l0ZW1beEZpZWxkXSwgaXRlbVt5U2NhbGUuZmllbGRdXSk7XG4gICAgICAgICAgICAgICAgaWYgKHBvaW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHBvaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXRlbVt4RmllbGRdID09PSBlbmRYVmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogcGFyc2UgdGhlIHZhbHVlIHBvc2l0aW9uXG4gICAgICogQHBhcmFtIHZhbFxuICAgICAqIEBwYXJhbSBzY2FsZVxuICAgICAqL1xuICAgIEFubm90YXRpb24ucHJvdG90eXBlLmdldE5vcm1hbGl6ZWRWYWx1ZSA9IGZ1bmN0aW9uICh2YWwsIHNjYWxlKSB7XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIHZhciBzY2FsZWQ7XG4gICAgICAgIHN3aXRjaCAodmFsKSB7XG4gICAgICAgICAgICBjYXNlICdzdGFydCc6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gMDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2VuZCc6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21lZGlhbic6IHtcbiAgICAgICAgICAgICAgICBzY2FsZWQgPSBzY2FsZS5pc0NhdGVnb3J5ID8gKHNjYWxlLnZhbHVlcy5sZW5ndGggLSAxKSAvIDIgOiAoc2NhbGUubWluICsgc2NhbGUubWF4KSAvIDI7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gc2NhbGUuc2NhbGUoc2NhbGVkKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgJ21pbic6XG4gICAgICAgICAgICBjYXNlICdtYXgnOlxuICAgICAgICAgICAgICAgIGlmIChzY2FsZS5pc0NhdGVnb3J5KSB7XG4gICAgICAgICAgICAgICAgICAgIHNjYWxlZCA9IHZhbCA9PT0gJ21pbicgPyAwIDogc2NhbGUudmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzY2FsZWQgPSBzY2FsZVt2YWxdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHQgPSBzY2FsZS5zY2FsZShzY2FsZWQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBzY2FsZS5zY2FsZSh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBwYXJzZSBwZXJjZW50IHBvc2l0aW9uXG4gICAgICogQHBhcmFtIHBvc2l0aW9uXG4gICAgICovXG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUucGFyc2VQZXJjZW50UG9zaXRpb24gPSBmdW5jdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdmFyIHhQZXJjZW50ID0gcGFyc2VGbG9hdChwb3NpdGlvblswXSkgLyAxMDA7XG4gICAgICAgIHZhciB5UGVyY2VudCA9IHBhcnNlRmxvYXQocG9zaXRpb25bMV0pIC8gMTAwO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMudmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBzdGFydCA9IGNvb3JkaW5hdGUuc3RhcnQsIGVuZCA9IGNvb3JkaW5hdGUuZW5kO1xuICAgICAgICB2YXIgdG9wTGVmdCA9IHtcbiAgICAgICAgICAgIHg6IE1hdGgubWluKHN0YXJ0LngsIGVuZC54KSxcbiAgICAgICAgICAgIHk6IE1hdGgubWluKHN0YXJ0LnksIGVuZC55KSxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHggPSBjb29yZGluYXRlLmdldFdpZHRoKCkgKiB4UGVyY2VudCArIHRvcExlZnQueDtcbiAgICAgICAgdmFyIHkgPSBjb29yZGluYXRlLmdldEhlaWdodCgpICogeVBlcmNlbnQgKyB0b3BMZWZ0Lnk7XG4gICAgICAgIHJldHVybiB7IHg6IHgsIHk6IHkgfTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGdldCBjb29yZGluYXRlIGJib3hcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRDb29yZGluYXRlQkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLnZpZXcuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgc3RhcnQgPSBjb29yZGluYXRlLnN0YXJ0LCBlbmQgPSBjb29yZGluYXRlLmVuZDtcbiAgICAgICAgdmFyIHdpZHRoID0gY29vcmRpbmF0ZS5nZXRXaWR0aCgpO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gY29vcmRpbmF0ZS5nZXRIZWlnaHQoKTtcbiAgICAgICAgdmFyIHRvcExlZnQgPSB7XG4gICAgICAgICAgICB4OiBNYXRoLm1pbihzdGFydC54LCBlbmQueCksXG4gICAgICAgICAgICB5OiBNYXRoLm1pbihzdGFydC55LCBlbmQueSksXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB0b3BMZWZ0LngsXG4gICAgICAgICAgICB5OiB0b3BMZWZ0LnksXG4gICAgICAgICAgICBtaW5YOiB0b3BMZWZ0LngsXG4gICAgICAgICAgICBtaW5ZOiB0b3BMZWZ0LnksXG4gICAgICAgICAgICBtYXhYOiB0b3BMZWZ0LnggKyB3aWR0aCxcbiAgICAgICAgICAgIG1heFk6IHRvcExlZnQueSArIGhlaWdodCxcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICogZ2V0IGFubm90YXRpb24gY29tcG9uZW50IGNvbmZpZyBieSBkaWZmZXJlbnQgdHlwZVxuICAgICAqIEBwYXJhbSB0eXBlXG4gICAgICogQHBhcmFtIG9wdGlvbiDnlKjmiLfnmoTphY3nva5cbiAgICAgKiBAcGFyYW0gdGhlbWVcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRBbm5vdGF0aW9uQ2ZnID0gZnVuY3Rpb24gKHR5cGUsIG9wdGlvbiwgdGhlbWUpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLnZpZXcuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgbyA9IHt9O1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKG9wdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYXJjJykge1xuICAgICAgICAgICAgdmFyIF9hID0gb3B0aW9uLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgICAgICB2YXIgc3AgPSB0aGlzLnBhcnNlUG9zaXRpb24oc3RhcnQpO1xuICAgICAgICAgICAgdmFyIGVwID0gdGhpcy5wYXJzZVBvc2l0aW9uKGVuZCk7XG4gICAgICAgICAgICB2YXIgc3RhcnRBbmdsZSA9IGNvb3JkaW5hdGVfMS5nZXRBbmdsZUJ5UG9pbnQoY29vcmRpbmF0ZSwgc3ApO1xuICAgICAgICAgICAgdmFyIGVuZEFuZ2xlID0gY29vcmRpbmF0ZV8xLmdldEFuZ2xlQnlQb2ludChjb29yZGluYXRlLCBlcCk7XG4gICAgICAgICAgICBpZiAoc3RhcnRBbmdsZSA+IGVuZEFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgZW5kQW5nbGUgPSBNYXRoLlBJICogMiArIGVuZEFuZ2xlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbyA9IHtcbiAgICAgICAgICAgICAgICBjZW50ZXI6IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCksXG4gICAgICAgICAgICAgICAgcmFkaXVzOiBjb29yZGluYXRlXzEuZ2V0RGlzdGFuY2VUb0NlbnRlcihjb29yZGluYXRlLCBzcCksXG4gICAgICAgICAgICAgICAgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSxcbiAgICAgICAgICAgICAgICBlbmRBbmdsZTogZW5kQW5nbGUsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdpbWFnZScpIHtcbiAgICAgICAgICAgIHZhciBfYiA9IG9wdGlvbiwgc3RhcnQgPSBfYi5zdGFydCwgZW5kID0gX2IuZW5kO1xuICAgICAgICAgICAgbyA9IHtcbiAgICAgICAgICAgICAgICBzdGFydDogdGhpcy5wYXJzZVBvc2l0aW9uKHN0YXJ0KSxcbiAgICAgICAgICAgICAgICBlbmQ6IHRoaXMucGFyc2VQb3NpdGlvbihlbmQpLFxuICAgICAgICAgICAgICAgIHNyYzogb3B0aW9uLnNyYyxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2xpbmUnKSB7XG4gICAgICAgICAgICB2YXIgX2MgPSBvcHRpb24sIHN0YXJ0ID0gX2Muc3RhcnQsIGVuZCA9IF9jLmVuZDtcbiAgICAgICAgICAgIG8gPSB7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IHRoaXMucGFyc2VQb3NpdGlvbihzdGFydCksXG4gICAgICAgICAgICAgICAgZW5kOiB0aGlzLnBhcnNlUG9zaXRpb24oZW5kKSxcbiAgICAgICAgICAgICAgICB0ZXh0OiB1dGlsXzEuZ2V0KG9wdGlvbiwgJ3RleHQnLCBudWxsKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ3JlZ2lvbicpIHtcbiAgICAgICAgICAgIHZhciBfZCA9IG9wdGlvbiwgc3RhcnQgPSBfZC5zdGFydCwgZW5kID0gX2QuZW5kO1xuICAgICAgICAgICAgbyA9IHtcbiAgICAgICAgICAgICAgICBzdGFydDogdGhpcy5wYXJzZVBvc2l0aW9uKHN0YXJ0KSxcbiAgICAgICAgICAgICAgICBlbmQ6IHRoaXMucGFyc2VQb3NpdGlvbihlbmQpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICAgIHZhciBmaWx0ZXJlZERhdGEgPSB0aGlzLnZpZXcuZ2V0RGF0YSgpO1xuICAgICAgICAgICAgdmFyIF9lID0gb3B0aW9uLCBwb3NpdGlvbiA9IF9lLnBvc2l0aW9uLCBjb250ZW50ID0gX2UuY29udGVudCwgcmVzdCA9IHRzbGliXzEuX19yZXN0KF9lLCBbXCJwb3NpdGlvblwiLCBcImNvbnRlbnRcIl0pO1xuICAgICAgICAgICAgdmFyIHRleHRDb250ZW50ID0gY29udGVudDtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihjb250ZW50KSkge1xuICAgICAgICAgICAgICAgIHRleHRDb250ZW50ID0gY29udGVudChmaWx0ZXJlZERhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbyA9IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCB0aGlzLnBhcnNlUG9zaXRpb24ocG9zaXRpb24pKSwgcmVzdCksIHsgY29udGVudDogdGV4dENvbnRlbnQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2RhdGFNYXJrZXInKSB7XG4gICAgICAgICAgICB2YXIgX2YgPSBvcHRpb24sIHBvc2l0aW9uID0gX2YucG9zaXRpb24sIHBvaW50ID0gX2YucG9pbnQsIGxpbmUgPSBfZi5saW5lLCB0ZXh0ID0gX2YudGV4dCwgYXV0b0FkanVzdCA9IF9mLmF1dG9BZGp1c3QsIGRpcmVjdGlvbiA9IF9mLmRpcmVjdGlvbjtcbiAgICAgICAgICAgIG8gPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMucGFyc2VQb3NpdGlvbihwb3NpdGlvbikpLCB7IGNvb3JkaW5hdGVCQm94OiB0aGlzLmdldENvb3JkaW5hdGVCQm94KCksIHBvaW50OiBwb2ludCxcbiAgICAgICAgICAgICAgICBsaW5lOiBsaW5lLFxuICAgICAgICAgICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgICAgICAgICAgYXV0b0FkanVzdDogYXV0b0FkanVzdCxcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb246IGRpcmVjdGlvbiB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlID09PSAnZGF0YVJlZ2lvbicpIHtcbiAgICAgICAgICAgIHZhciBfZyA9IG9wdGlvbiwgc3RhcnQgPSBfZy5zdGFydCwgZW5kID0gX2cuZW5kLCByZWdpb24gPSBfZy5yZWdpb24sIHRleHQgPSBfZy50ZXh0LCBsaW5lTGVuZ3RoID0gX2cubGluZUxlbmd0aDtcbiAgICAgICAgICAgIG8gPSB7XG4gICAgICAgICAgICAgICAgcG9pbnRzOiB0aGlzLmdldFJlZ2lvblBvaW50cyhzdGFydCwgZW5kKSxcbiAgICAgICAgICAgICAgICByZWdpb246IHJlZ2lvbixcbiAgICAgICAgICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICAgICAgICAgIGxpbmVMZW5ndGg6IGxpbmVMZW5ndGgsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdyZWdpb25GaWx0ZXInKSB7XG4gICAgICAgICAgICB2YXIgX2ggPSBvcHRpb24sIHN0YXJ0ID0gX2guc3RhcnQsIGVuZCA9IF9oLmVuZCwgYXBwbHlfMSA9IF9oLmFwcGx5LCBjb2xvciA9IF9oLmNvbG9yO1xuICAgICAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLnZpZXcuZ2VvbWV0cmllcztcbiAgICAgICAgICAgIHZhciBzaGFwZXNfMSA9IFtdO1xuICAgICAgICAgICAgdmFyIGFkZFNoYXBlc18xID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5pc0dyb3VwKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5nZXRDaGlsZHJlbigpLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7IHJldHVybiBhZGRTaGFwZXNfMShjaGlsZCk7IH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVzXzEucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb20pIHtcbiAgICAgICAgICAgICAgICBpZiAoYXBwbHlfMSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmNvbnRhaW5zKGFwcGx5XzEsIGdlb20udHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGdlb20uZWxlbWVudHMsIGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU2hhcGVzXzEoZWxlbS5zaGFwZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdXRpbF8xLmVhY2goZ2VvbS5lbGVtZW50cywgZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZFNoYXBlc18xKGVsZW0uc2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG8gPSB7XG4gICAgICAgICAgICAgICAgY29sb3I6IGNvbG9yLFxuICAgICAgICAgICAgICAgIHNoYXBlczogc2hhcGVzXzEsXG4gICAgICAgICAgICAgICAgc3RhcnQ6IHRoaXMucGFyc2VQb3NpdGlvbihzdGFydCksXG4gICAgICAgICAgICAgICAgZW5kOiB0aGlzLnBhcnNlUG9zaXRpb24oZW5kKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8g5ZCI5bm25Li76aKY77yM55So5oi36YWN572u5LyY5YWI57qn6auY5LqO6buY6K6k5Li76aKYXG4gICAgICAgIHZhciBjZmcgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhlbWUsIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgbyksIHsgdG9wOiBvcHRpb24udG9wLCBzdHlsZTogb3B0aW9uLnN0eWxlLCBvZmZzZXRYOiBvcHRpb24ub2Zmc2V0WCwgb2Zmc2V0WTogb3B0aW9uLm9mZnNldFkgfSkpO1xuICAgICAgICBjZmcuY29udGFpbmVyID0gdGhpcy5nZXRDb21wb25lbnRDb250YWluZXIoY2ZnKTtcbiAgICAgICAgY2ZnLmFuaW1hdGUgPSB0aGlzLnZpZXcuZ2V0T3B0aW9ucygpLmFuaW1hdGUgJiYgY2ZnLmFuaW1hdGUgJiYgdXRpbF8xLmdldChvcHRpb24sICdhbmltYXRlJywgY2ZnLmFuaW1hdGUpOyAvLyDlpoLmnpwgdmlldyDlhbPpl63liqjnlLvvvIzliJnkuI3miafooYxcbiAgICAgICAgY2ZnLmFuaW1hdGVPcHRpb24gPSB1dGlsXzEuZGVlcE1peCh7fSwgYW5pbWF0ZV8xLkRFRkFVTFRfQU5JTUFURV9DRkcsIGNmZy5hbmltYXRlT3B0aW9uLCBvcHRpb24uYW5pbWF0ZU9wdGlvbik7XG4gICAgICAgIHJldHVybiBjZmc7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBpcyBhbm5vdGF0aW9uIHJlbmRlciBvbiB0b3BcbiAgICAgKiBAcGFyYW0gb3B0aW9uXG4gICAgICogQHJldHVybiB3aGV0aGUgb24gdG9wXG4gICAgICovXG4gICAgQW5ub3RhdGlvbi5wcm90b3R5cGUuaXNUb3AgPSBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZ2V0KG9wdGlvbiwgJ3RvcCcsIHRydWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBjb250YWluZXIgYnkgb3B0aW9uLnRvcFxuICAgICAqIGRlZmF1bHQgaXMgb24gdG9wXG4gICAgICogQHBhcmFtIG9wdGlvblxuICAgICAqIEByZXR1cm5zIHRoZSBjb250YWluZXJcbiAgICAgKi9cbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRDb21wb25lbnRDb250YWluZXIgPSBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzVG9wKG9wdGlvbikgPyB0aGlzLmZvcmVncm91bmRDb250YWluZXIgOiB0aGlzLmJhY2tncm91bmRDb250YWluZXI7XG4gICAgfTtcbiAgICBBbm5vdGF0aW9uLnByb3RvdHlwZS5nZXRBbm5vdGF0aW9uVGhlbWUgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldCh0aGlzLnZpZXcuZ2V0VGhlbWUoKSwgWydjb21wb25lbnRzJywgJ2Fubm90YXRpb24nLCB0eXBlXSwge30pO1xuICAgIH07XG4gICAgcmV0dXJuIEFubm90YXRpb247XG59KGJhc2VfMS5Db250cm9sbGVyKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBbm5vdGF0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5ub3RhdGlvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vLi4vY29uc3RhbnRcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgYW5pbWF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL2FuaW1hdGUvXCIpO1xudmFyIGF4aXNfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2F4aXNcIik7XG52YXIgYXhpc18yID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvYXhpc1wiKTtcbnZhciBncmlkXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ncmlkXCIpO1xudmFyIGhlbHBlcl8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvaGVscGVyXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG4vLyB1cGRhdGUg57uE5Lu255qE5pe25YCZ77yM5b+955Wl55qE5pWw5o2u5pu05pawXG52YXIgT01JVF9DRkcgPSBbJ2NvbnRhaW5lciddO1xuLy8g5Z2Q5qCH6L206buY6K6k5Yqo55S76YWN572uXG52YXIgQVhJU19ERUZBVUxUX0FOSU1BVEVfQ0ZHID0gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBhbmltYXRlXzEuREVGQVVMVF9BTklNQVRFX0NGRyksIHsgYXBwZWFyOiBudWxsIH0pO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBHMiBBeGlzIGNvbnRyb2xsZXIsIHdpbGw6XG4gKiAgLSBjcmVhdGUgY29tcG9uZW50XG4gKiAgICAtIGF4aXNcbiAqICAgIC0gZ3JpZFxuICogIC0gbGlmZSBjaXJjbGVcbiAqL1xudmFyIEF4aXMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQXhpcywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBeGlzKHZpZXcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdmlldykgfHwgdGhpcztcbiAgICAgICAgLyoqIOS9v+eUqCBvYmplY3Qg5a2Y5YKo57uE5Lu2ICovXG4gICAgICAgIF90aGlzLmNhY2hlID0gbmV3IE1hcCgpO1xuICAgICAgICAvLyDlhYjliJvlu7ogZ3JpZENvbnRhaW5lcu+8jOWwhiBncmlkIOaUvuWIsCBheGlzIOW6leWxglxuICAgICAgICBfdGhpcy5ncmlkQ29udGFpbmVyID0gX3RoaXMudmlldy5nZXRMYXllcihjb25zdGFudF8xLkxBWUVSLkJHKS5hZGRHcm91cCgpO1xuICAgICAgICBfdGhpcy5heGlzQ29udGFpbmVyID0gX3RoaXMudmlldy5nZXRMYXllcihjb25zdGFudF8xLkxBWUVSLkJHKS5hZGRHcm91cCgpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBeGlzLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2F4aXMnO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgQXhpcy5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICBBeGlzLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrDnu4Tku7bluIPlsYDvvIzkvY3nva7lpKflsI9cbiAgICAgKi9cbiAgICBBeGlzLnByb3RvdHlwZS5sYXlvdXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5nZXRDb21wb25lbnRzKCksIGZ1bmN0aW9uIChjbykge1xuICAgICAgICAgICAgdmFyIGNvbXBvbmVudCA9IGNvLmNvbXBvbmVudCwgZGlyZWN0aW9uID0gY28uZGlyZWN0aW9uLCB0eXBlID0gY28udHlwZSwgZXh0cmEgPSBjby5leHRyYTtcbiAgICAgICAgICAgIHZhciBkaW0gPSBleHRyYS5kaW0sIHNjYWxlID0gZXh0cmEuc2NhbGUsIGFsaWduVGljayA9IGV4dHJhLmFsaWduVGljaztcbiAgICAgICAgICAgIHZhciB1cGRhdGVkO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuQVhJUykge1xuICAgICAgICAgICAgICAgIGlmIChjb29yZGluYXRlLmlzUG9sYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRpbSA9PT0gJ3gnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGF4aXNfMS5nZXRBeGlzUmVnaW9uKGNvb3JkaW5hdGUsIGRpcmVjdGlvbilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGF4aXNfMS5nZXRDaXJjbGVBeGlzQ2VudGVyUmFkaXVzKGNvb3JkaW5hdGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpbSA9PT0gJ3knKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGF4aXNfMS5nZXRDaXJjbGVBeGlzQ2VudGVyUmFkaXVzKGNvb3JkaW5hdGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBheGlzXzEuZ2V0QXhpc1JlZ2lvbihjb29yZGluYXRlLCBkaXJlY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkID0gYXhpc18xLmdldEF4aXNSZWdpb24oY29vcmRpbmF0ZSwgZGlyZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlID09PSBjb25zdGFudF8xLkNPTVBPTkVOVF9UWVBFLkdSSUQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltID09PSAneCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBncmlkXzEuZ2V0Q2lyY2xlR3JpZEl0ZW1zKGNvb3JkaW5hdGUsIF90aGlzLnZpZXcuZ2V0WVNjYWxlcygpWzBdLCBzY2FsZSwgYWxpZ25UaWNrLCBkaW0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZ3JpZF8xLmdldExpbmVHcmlkSXRlbXMoY29vcmRpbmF0ZSwgc2NhbGUsIGRpbSwgYWxpZ25UaWNrKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0gPT09ICd4J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGdyaWRfMS5nZXRMaW5lR3JpZEl0ZW1zKGNvb3JkaW5hdGUsIHNjYWxlLCBkaW0sIGFsaWduVGljaylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBncmlkXzEuZ2V0Q2lyY2xlR3JpZEl0ZW1zKGNvb3JkaW5hdGUsIF90aGlzLnZpZXcuZ2V0WFNjYWxlKCksIHNjYWxlLCBhbGlnblRpY2ssIGRpbSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zOiBpdGVtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvb3JkaW5hdGUg5pu05paw5LmL5ZCO77yMY2VudGVyIOS5n+WPmOWMluS6hlxuICAgICAgICAgICAgICAgICAgICAgICAgY2VudGVyOiBfdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKS5nZXRDZW50ZXIoKSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWQgPSB7IGl0ZW1zOiBncmlkXzEuZ2V0TGluZUdyaWRJdGVtcyhjb29yZGluYXRlLCBzY2FsZSwgZGltLCBhbGlnblRpY2spIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29tcG9uZW50LnVwZGF0ZSh1cGRhdGVkKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrAgYXhpcyDnu4Tku7ZcbiAgICAgKi9cbiAgICBBeGlzLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3B0aW9uID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5heGVzO1xuICAgICAgICB2YXIgdXBkYXRlZENhY2hlID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZVhBeGVzKHVwZGF0ZWRDYWNoZSk7XG4gICAgICAgIHRoaXMudXBkYXRlWUF4ZXModXBkYXRlZENhY2hlKTtcbiAgICAgICAgLy8g5aSE55CG5a6M5oiQ5LmL5ZCO77yM6ZSA5q+B5Yig6Zmk55qEXG4gICAgICAgIC8vIOS4jeWcqOWkhOeQhuS4reeahFxuICAgICAgICB2YXIgbmV3Q2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMuY2FjaGUuZm9yRWFjaChmdW5jdGlvbiAoY28sIGtleSkge1xuICAgICAgICAgICAgaWYgKHVwZGF0ZWRDYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgIG5ld0NhY2hlLnNldChrZXksIGNvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOS4jeWtmOWcqO+8jOWImeaYr+aJgOaciemcgOimgeiiq+mUgOavgeeahOe7hOS7tlxuICAgICAgICAgICAgICAgIGNvLmNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDmm7TmlrDnvJPlrZhcbiAgICAgICAgdGhpcy5jYWNoZSA9IG5ld0NhY2hlO1xuICAgIH07XG4gICAgQXhpcy5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY2xlYXIuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5jYWNoZS5jbGVhcigpO1xuICAgICAgICB0aGlzLmdyaWRDb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5heGlzQ29udGFpbmVyLmNsZWFyKCk7XG4gICAgfTtcbiAgICBBeGlzLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5ncmlkQ29udGFpbmVyLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgdGhpcy5heGlzQ29udGFpbmVyLnJlbW92ZSh0cnVlKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIEF4aXMucHJvdG90eXBlLmdldENvbXBvbmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjbyA9IFtdO1xuICAgICAgICB0aGlzLmNhY2hlLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBjby5wdXNoKHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOabtOaWsCB4IGF4aXNcbiAgICAgKiBAcGFyYW0gdXBkYXRlZENhY2hlXG4gICAgICovXG4gICAgQXhpcy5wcm90b3R5cGUudXBkYXRlWEF4ZXMgPSBmdW5jdGlvbiAodXBkYXRlZENhY2hlKSB7XG4gICAgICAgIC8vIHggYXhpc1xuICAgICAgICB2YXIgc2NhbGUgPSB0aGlzLnZpZXcuZ2V0WFNjYWxlKCk7XG4gICAgICAgIGlmICghc2NhbGUgfHwgc2NhbGUuaXNJZGVudGl0eSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB4QXhpc09wdGlvbiA9IGF4aXNfMi5nZXRBeGlzT3B0aW9uKHRoaXMub3B0aW9uLCBzY2FsZS5maWVsZCk7XG4gICAgICAgIGlmICh4QXhpc09wdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGlyZWN0aW9uID0gYXhpc18xLmdldEF4aXNEaXJlY3Rpb24oeEF4aXNPcHRpb24sIGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTSk7XG4gICAgICAgIHZhciBsYXllciA9IGNvbnN0YW50XzEuTEFZRVIuQkc7XG4gICAgICAgIHZhciBkaW0gPSAneCc7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIGF4aXNJZCA9IHRoaXMuZ2V0SWQoJ2F4aXMnLCBzY2FsZS5maWVsZCk7XG4gICAgICAgIHZhciBncmlkSWQgPSB0aGlzLmdldElkKCdncmlkJywgc2NhbGUuZmllbGQpO1xuICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1JlY3QpIHtcbiAgICAgICAgICAgIC8vIDEuIGRvIGF4aXMgdXBkYXRlXG4gICAgICAgICAgICB2YXIgYXhpcyA9IHRoaXMuY2FjaGUuZ2V0KGF4aXNJZCk7XG4gICAgICAgICAgICAvLyDlrZjlnKjliJnmm7TmlrBcbiAgICAgICAgICAgIGlmIChheGlzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNmZyA9IHRoaXMuZ2V0TGluZUF4aXNDZmcoc2NhbGUsIHhBeGlzT3B0aW9uLCBkaXJlY3Rpb24pO1xuICAgICAgICAgICAgICAgIGhlbHBlcl8xLm9taXQoY2ZnLCBPTUlUX0NGRyk7XG4gICAgICAgICAgICAgICAgYXhpcy5jb21wb25lbnQudXBkYXRlKGNmZyk7XG4gICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChheGlzSWQsIGF4aXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo77yM5YiZ5Yib5bu6XG4gICAgICAgICAgICAgICAgYXhpcyA9IHRoaXMuY3JlYXRlTGluZUF4aXMoc2NhbGUsIHhBeGlzT3B0aW9uLCBsYXllciwgZGlyZWN0aW9uLCBkaW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChheGlzSWQsIGF4aXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gMi4gZG8gZ3JpZCB1cGRhdGVcbiAgICAgICAgICAgIHZhciBncmlkID0gdGhpcy5jYWNoZS5nZXQoZ3JpZElkKTtcbiAgICAgICAgICAgIC8vIOWtmOWcqOWImeabtOaWsFxuICAgICAgICAgICAgaWYgKGdyaWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5nZXRMaW5lR3JpZENmZyhzY2FsZSwgeEF4aXNPcHRpb24sIGRpcmVjdGlvbiwgZGltKTtcbiAgICAgICAgICAgICAgICBoZWxwZXJfMS5vbWl0KGNmZywgT01JVF9DRkcpO1xuICAgICAgICAgICAgICAgIGdyaWQuY29tcG9uZW50LnVwZGF0ZShjZmcpO1xuICAgICAgICAgICAgICAgIHVwZGF0ZWRDYWNoZS5zZXQoZ3JpZElkLCBncmlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOS4jeWtmOWcqOWImeWIm+W7ulxuICAgICAgICAgICAgICAgIGdyaWQgPSB0aGlzLmNyZWF0ZUxpbmVHcmlkKHNjYWxlLCB4QXhpc09wdGlvbiwgbGF5ZXIsIGRpcmVjdGlvbiwgZGltKTtcbiAgICAgICAgICAgICAgICBpZiAoZ3JpZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLnNldChncmlkSWQsIGdyaWQpO1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkQ2FjaGUuc2V0KGdyaWRJZCwgZ3JpZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvb3JkaW5hdGUuaXNQb2xhcikge1xuICAgICAgICAgICAgLy8gMS4gZG8gYXhpcyB1cGRhdGVcbiAgICAgICAgICAgIHZhciBheGlzID0gdGhpcy5jYWNoZS5nZXQoYXhpc0lkKTtcbiAgICAgICAgICAgIC8vIOWtmOWcqOWImeabtOaWsFxuICAgICAgICAgICAgaWYgKGF4aXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgY2ZnID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLmdldExpbmVBeGlzQ2ZnKHNjYWxlLCB4QXhpc09wdGlvbiwgY29uc3RhbnRfMS5ESVJFQ1RJT04uUkFESVVTKVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuZ2V0Q2lyY2xlQXhpc0NmZyhzY2FsZSwgeEF4aXNPcHRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgICAgICAgICAgaGVscGVyXzEub21pdChjZmcsIE9NSVRfQ0ZHKTtcbiAgICAgICAgICAgICAgICBheGlzLmNvbXBvbmVudC51cGRhdGUoY2ZnKTtcbiAgICAgICAgICAgICAgICB1cGRhdGVkQ2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyDkuI3lrZjlnKjvvIzliJnliJvlu7pcbiAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc1VuZGVmaW5lZCh4QXhpc09wdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOm7mOiupOS4jea4suafk+i9rOe9ruaegeWdkOagh+S4i+eahOWdkOagh+i9tFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c55So5oi35omT5byA5LqG6ZqQ6JeP55qE5Z2Q5qCH6L20IGNoYXJ0LmF4aXModHJ1ZSkvY2hhcnQuYXhpcygneCcsIHRydWUpXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDpgqPkuYjlr7nkuo7ovaznva7kuobnmoTmnoHlnZDmoIfvvIzljYrlvoTovbTmmL7npLrnmoTmmK8geCDovbTlr7nlupTnmoTmlbDmja5cbiAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMgPSB0aGlzLmNyZWF0ZUxpbmVBeGlzKHNjYWxlLCB4QXhpc09wdGlvbiwgbGF5ZXIsIGNvbnN0YW50XzEuRElSRUNUSU9OLlJBRElVUywgZGltKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXhpcyA9IHRoaXMuY3JlYXRlQ2lyY2xlQXhpcyhzY2FsZSwgeEF4aXNPcHRpb24sIGxheWVyLCBkaXJlY3Rpb24sIGRpbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChheGlzSWQsIGF4aXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gMi4gZG8gZ3JpZCB1cGRhdGVcbiAgICAgICAgICAgIHZhciBncmlkID0gdGhpcy5jYWNoZS5nZXQoZ3JpZElkKTtcbiAgICAgICAgICAgIC8vIOWtmOWcqOWImeabtOaWsFxuICAgICAgICAgICAgaWYgKGdyaWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgY2ZnID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLmdldENpcmNsZUdyaWRDZmcoc2NhbGUsIHhBeGlzT3B0aW9uLCBjb25zdGFudF8xLkRJUkVDVElPTi5SQURJVVMsIGRpbSlcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmdldExpbmVHcmlkQ2ZnKHNjYWxlLCB4QXhpc09wdGlvbiwgY29uc3RhbnRfMS5ESVJFQ1RJT04uQ0lSQ0xFLCBkaW0pO1xuICAgICAgICAgICAgICAgIGhlbHBlcl8xLm9taXQoY2ZnLCBPTUlUX0NGRyk7XG4gICAgICAgICAgICAgICAgZ3JpZC5jb21wb25lbnQudXBkYXRlKGNmZyk7XG4gICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChncmlkSWQsIGdyaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo5YiZ5Yib5bu6XG4gICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNVbmRlZmluZWQoeEF4aXNPcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBncmlkID0gdGhpcy5jcmVhdGVDaXJjbGVHcmlkKHNjYWxlLCB4QXhpc09wdGlvbiwgbGF5ZXIsIGNvbnN0YW50XzEuRElSRUNUSU9OLlJBRElVUywgZGltKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ3JpZO+8jOaegeWdkOagh+S4i+eahCB4IOi9tOe9keagvOe6v+ayv+edgOWNiuW+hOaWueWQkee7mOWItlxuICAgICAgICAgICAgICAgICAgICBncmlkID0gdGhpcy5jcmVhdGVMaW5lR3JpZChzY2FsZSwgeEF4aXNPcHRpb24sIGxheWVyLCBjb25zdGFudF8xLkRJUkVDVElPTi5DSVJDTEUsIGRpbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChncmlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0KGdyaWRJZCwgZ3JpZCk7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRDYWNoZS5zZXQoZ3JpZElkLCBncmlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBoZWxpeCBhbmQgb3RoZXIsIGRvIG5vdCBkcmF3IGF4aXNcbiAgICAgICAgfVxuICAgIH07XG4gICAgQXhpcy5wcm90b3R5cGUudXBkYXRlWUF4ZXMgPSBmdW5jdGlvbiAodXBkYXRlZENhY2hlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIC8vIHkgYXhlc1xuICAgICAgICB2YXIgeVNjYWxlcyA9IHRoaXMudmlldy5nZXRZU2NhbGVzKCk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHlTY2FsZXMsIGZ1bmN0aW9uIChzY2FsZSwgaWR4KSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBpZiAoIXNjYWxlIHx8IHNjYWxlLmlzSWRlbnRpdHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZmllbGQgPSBzY2FsZS5maWVsZDtcbiAgICAgICAgICAgIHZhciB5QXhpc09wdGlvbiA9IGF4aXNfMi5nZXRBeGlzT3B0aW9uKF90aGlzLm9wdGlvbiwgZmllbGQpO1xuICAgICAgICAgICAgaWYgKHlBeGlzT3B0aW9uICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHZhciBsYXllciA9IGNvbnN0YW50XzEuTEFZRVIuQkc7XG4gICAgICAgICAgICAgICAgdmFyIGRpbSA9ICd5JztcbiAgICAgICAgICAgICAgICB2YXIgYXhpc0lkID0gX3RoaXMuZ2V0SWQoJ2F4aXMnLCBmaWVsZCk7XG4gICAgICAgICAgICAgICAgdmFyIGdyaWRJZCA9IF90aGlzLmdldElkKCdncmlkJywgZmllbGQpO1xuICAgICAgICAgICAgICAgIHZhciBjb29yZGluYXRlID0gX3RoaXMudmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNSZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSBheGlzXzEuZ2V0QXhpc0RpcmVjdGlvbih5QXhpc09wdGlvbiwgaWR4ID09PSAwID8gY29uc3RhbnRfMS5ESVJFQ1RJT04uTEVGVCA6IGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gMS4gZG8gYXhpcyB1cGRhdGVcbiAgICAgICAgICAgICAgICAgICAgdmFyIGF4aXMgPSBfdGhpcy5jYWNoZS5nZXQoYXhpc0lkKTtcbiAgICAgICAgICAgICAgICAgICAgLy8g5a2Y5Zyo5YiZ5pu05pawXG4gICAgICAgICAgICAgICAgICAgIGlmIChheGlzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ZnID0gX3RoaXMuZ2V0TGluZUF4aXNDZmcoc2NhbGUsIHlBeGlzT3B0aW9uLCBkaXJlY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGVscGVyXzEub21pdChjZmcsIE9NSVRfQ0ZHKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMuY29tcG9uZW50LnVwZGF0ZShjZmcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChheGlzSWQsIGF4aXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo77yM5YiZ5Yib5bu6XG4gICAgICAgICAgICAgICAgICAgICAgICBheGlzID0gX3RoaXMuY3JlYXRlTGluZUF4aXMoc2NhbGUsIHlBeGlzT3B0aW9uLCBsYXllciwgZGlyZWN0aW9uLCBkaW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkQ2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gMi4gZG8gZ3JpZCB1cGRhdGVcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdyaWQgPSBfdGhpcy5jYWNoZS5nZXQoZ3JpZElkKTtcbiAgICAgICAgICAgICAgICAgICAgLy8g5a2Y5Zyo5YiZ5pu05pawXG4gICAgICAgICAgICAgICAgICAgIGlmIChncmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ZnID0gX3RoaXMuZ2V0TGluZUdyaWRDZmcoc2NhbGUsIHlBeGlzT3B0aW9uLCBkaXJlY3Rpb24sIGRpbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoZWxwZXJfMS5vbWl0KGNmZywgT01JVF9DRkcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ3JpZC5jb21wb25lbnQudXBkYXRlKGNmZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkQ2FjaGUuc2V0KGdyaWRJZCwgZ3JpZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDkuI3lrZjlnKjliJnliJvlu7pcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyaWQgPSBfdGhpcy5jcmVhdGVMaW5lR3JpZChzY2FsZSwgeUF4aXNPcHRpb24sIGxheWVyLCBkaXJlY3Rpb24sIGRpbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JpZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmNhY2hlLnNldChncmlkSWQsIGdyaWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRDYWNoZS5zZXQoZ3JpZElkLCBncmlkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjb29yZGluYXRlLmlzUG9sYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMS4gZG8gYXhpcyB1cGRhdGVcbiAgICAgICAgICAgICAgICAgICAgdmFyIGF4aXMgPSBfdGhpcy5jYWNoZS5nZXQoYXhpc0lkKTtcbiAgICAgICAgICAgICAgICAgICAgLy8g5a2Y5Zyo5YiZ5pu05pawXG4gICAgICAgICAgICAgICAgICAgIGlmIChheGlzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ZnID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF90aGlzLmdldENpcmNsZUF4aXNDZmcoc2NhbGUsIHlBeGlzT3B0aW9uLCBjb25zdGFudF8xLkRJUkVDVElPTi5DSVJDTEUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdGhpcy5nZXRMaW5lQXhpc0NmZyhzY2FsZSwgeUF4aXNPcHRpb24sIGNvbnN0YW50XzEuRElSRUNUSU9OLlJBRElVUyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWxwZXJfMS5vbWl0KGNmZywgT01JVF9DRkcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy5jb21wb25lbnQudXBkYXRlKGNmZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkQ2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDkuI3lrZjlnKjvvIzliJnliJvlu7pcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29yZGluYXRlLmlzVHJhbnNwb3NlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNVbmRlZmluZWQoeUF4aXNPcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMgPSBfdGhpcy5jcmVhdGVDaXJjbGVBeGlzKHNjYWxlLCB5QXhpc09wdGlvbiwgbGF5ZXIsIGNvbnN0YW50XzEuRElSRUNUSU9OLkNJUkNMRSwgZGltKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzID0gX3RoaXMuY3JlYXRlTGluZUF4aXMoc2NhbGUsIHlBeGlzT3B0aW9uLCBsYXllciwgY29uc3RhbnRfMS5ESVJFQ1RJT04uUkFESVVTLCBkaW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkQ2FjaGUuc2V0KGF4aXNJZCwgYXhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gMi4gZG8gZ3JpZCB1cGRhdGVcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdyaWQgPSBfdGhpcy5jYWNoZS5nZXQoZ3JpZElkKTtcbiAgICAgICAgICAgICAgICAgICAgLy8g5a2Y5Zyo5YiZ5pu05pawXG4gICAgICAgICAgICAgICAgICAgIGlmIChncmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ZnID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF90aGlzLmdldExpbmVHcmlkQ2ZnKHNjYWxlLCB5QXhpc09wdGlvbiwgY29uc3RhbnRfMS5ESVJFQ1RJT04uQ0lSQ0xFLCBkaW0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdGhpcy5nZXRDaXJjbGVHcmlkQ2ZnKHNjYWxlLCB5QXhpc09wdGlvbiwgY29uc3RhbnRfMS5ESVJFQ1RJT04uUkFESVVTLCBkaW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGVscGVyXzEub21pdChjZmcsIE9NSVRfQ0ZHKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyaWQuY29tcG9uZW50LnVwZGF0ZShjZmcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChncmlkSWQsIGdyaWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo5YiZ5Yib5bu6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzVW5kZWZpbmVkKHlBeGlzT3B0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmlkID0gX3RoaXMuY3JlYXRlTGluZUdyaWQoc2NhbGUsIHlBeGlzT3B0aW9uLCBsYXllciwgY29uc3RhbnRfMS5ESVJFQ1RJT04uQ0lSQ0xFLCBkaW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyaWQgPSBfdGhpcy5jcmVhdGVDaXJjbGVHcmlkKHNjYWxlLCB5QXhpc09wdGlvbiwgbGF5ZXIsIGNvbnN0YW50XzEuRElSRUNUSU9OLlJBRElVUywgZGltKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY2FjaGUuc2V0KGdyaWRJZCwgZ3JpZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZENhY2hlLnNldChncmlkSWQsIGdyaWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBoZWxpeCBhbmQgb3RoZXIsIGRvIG5vdCBkcmF3IGF4aXNcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu6IGxpbmUgYXhpc1xuICAgICAqIEBwYXJhbSBzY2FsZVxuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcGFyYW0gbGF5ZXJcbiAgICAgKiBAcGFyYW0gZGlyZWN0aW9uXG4gICAgICogQHBhcmFtIGRpbVxuICAgICAqL1xuICAgIEF4aXMucHJvdG90eXBlLmNyZWF0ZUxpbmVBeGlzID0gZnVuY3Rpb24gKHNjYWxlLCBvcHRpb24sIGxheWVyLCBkaXJlY3Rpb24sIGRpbSkge1xuICAgICAgICAvLyBheGlzXG4gICAgICAgIHZhciBheGlzID0ge1xuICAgICAgICAgICAgY29tcG9uZW50OiBuZXcgZGVwZW5kZW50c18xLkxpbmVBeGlzKHRoaXMuZ2V0TGluZUF4aXNDZmcoc2NhbGUsIG9wdGlvbiwgZGlyZWN0aW9uKSksXG4gICAgICAgICAgICBsYXllcjogbGF5ZXIsXG4gICAgICAgICAgICBkaXJlY3Rpb246IGRpcmVjdGlvbiA9PT0gY29uc3RhbnRfMS5ESVJFQ1RJT04uUkFESVVTID8gY29uc3RhbnRfMS5ESVJFQ1RJT04uTk9ORSA6IGRpcmVjdGlvbixcbiAgICAgICAgICAgIHR5cGU6IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuQVhJUyxcbiAgICAgICAgICAgIGV4dHJhOiB7IGRpbTogZGltLCBzY2FsZTogc2NhbGUgfSxcbiAgICAgICAgfTtcbiAgICAgICAgYXhpcy5jb21wb25lbnQuc2V0KCdmaWVsZCcsIHNjYWxlLmZpZWxkKTtcbiAgICAgICAgYXhpcy5jb21wb25lbnQuaW5pdCgpO1xuICAgICAgICByZXR1cm4gYXhpcztcbiAgICB9O1xuICAgIEF4aXMucHJvdG90eXBlLmNyZWF0ZUxpbmVHcmlkID0gZnVuY3Rpb24gKHNjYWxlLCBvcHRpb24sIGxheWVyLCBkaXJlY3Rpb24sIGRpbSkge1xuICAgICAgICB2YXIgY2ZnID0gdGhpcy5nZXRMaW5lR3JpZENmZyhzY2FsZSwgb3B0aW9uLCBkaXJlY3Rpb24sIGRpbSk7XG4gICAgICAgIGlmIChjZmcpIHtcbiAgICAgICAgICAgIHZhciBncmlkID0ge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudDogbmV3IGRlcGVuZGVudHNfMS5MaW5lR3JpZChjZmcpLFxuICAgICAgICAgICAgICAgIGxheWVyOiBsYXllcixcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb246IGNvbnN0YW50XzEuRElSRUNUSU9OLk5PTkUsXG4gICAgICAgICAgICAgICAgdHlwZTogY29uc3RhbnRfMS5DT01QT05FTlRfVFlQRS5HUklELFxuICAgICAgICAgICAgICAgIGV4dHJhOiB7XG4gICAgICAgICAgICAgICAgICAgIGRpbTogZGltLFxuICAgICAgICAgICAgICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIGFsaWduVGljazogdXRpbF8xLmdldChjZmcsICdhbGlnblRpY2snLCB0cnVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGdyaWQuY29tcG9uZW50LmluaXQoKTtcbiAgICAgICAgICAgIHJldHVybiBncmlkO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBeGlzLnByb3RvdHlwZS5jcmVhdGVDaXJjbGVBeGlzID0gZnVuY3Rpb24gKHNjYWxlLCBvcHRpb24sIGxheWVyLCBkaXJlY3Rpb24sIGRpbSkge1xuICAgICAgICB2YXIgYXhpcyA9IHtcbiAgICAgICAgICAgIGNvbXBvbmVudDogbmV3IGRlcGVuZGVudHNfMS5DaXJjbGVBeGlzKHRoaXMuZ2V0Q2lyY2xlQXhpc0NmZyhzY2FsZSwgb3B0aW9uLCBkaXJlY3Rpb24pKSxcbiAgICAgICAgICAgIGxheWVyOiBsYXllcixcbiAgICAgICAgICAgIGRpcmVjdGlvbjogZGlyZWN0aW9uLFxuICAgICAgICAgICAgdHlwZTogY29uc3RhbnRfMS5DT01QT05FTlRfVFlQRS5BWElTLFxuICAgICAgICAgICAgZXh0cmE6IHsgZGltOiBkaW0sIHNjYWxlOiBzY2FsZSB9LFxuICAgICAgICB9O1xuICAgICAgICBheGlzLmNvbXBvbmVudC5zZXQoJ2ZpZWxkJywgc2NhbGUuZmllbGQpO1xuICAgICAgICBheGlzLmNvbXBvbmVudC5pbml0KCk7XG4gICAgICAgIHJldHVybiBheGlzO1xuICAgIH07XG4gICAgQXhpcy5wcm90b3R5cGUuY3JlYXRlQ2lyY2xlR3JpZCA9IGZ1bmN0aW9uIChzY2FsZSwgb3B0aW9uLCBsYXllciwgZGlyZWN0aW9uLCBkaW0pIHtcbiAgICAgICAgdmFyIGNmZyA9IHRoaXMuZ2V0Q2lyY2xlR3JpZENmZyhzY2FsZSwgb3B0aW9uLCBkaXJlY3Rpb24sIGRpbSk7XG4gICAgICAgIGlmIChjZmcpIHtcbiAgICAgICAgICAgIHZhciBncmlkID0ge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudDogbmV3IGRlcGVuZGVudHNfMS5DaXJjbGVHcmlkKGNmZyksXG4gICAgICAgICAgICAgICAgbGF5ZXI6IGxheWVyLFxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogY29uc3RhbnRfMS5ESVJFQ1RJT04uTk9ORSxcbiAgICAgICAgICAgICAgICB0eXBlOiBjb25zdGFudF8xLkNPTVBPTkVOVF9UWVBFLkdSSUQsXG4gICAgICAgICAgICAgICAgZXh0cmE6IHtcbiAgICAgICAgICAgICAgICAgICAgZGltOiBkaW0sXG4gICAgICAgICAgICAgICAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgYWxpZ25UaWNrOiB1dGlsXzEuZ2V0KGNmZywgJ2FsaWduVGljaycsIHRydWUpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ3JpZC5jb21wb25lbnQuaW5pdCgpO1xuICAgICAgICAgICAgcmV0dXJuIGdyaWQ7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGdlbmVyYXRlIGxpbmUgYXhpcyBjZmdcbiAgICAgKiBAcGFyYW0gc2NhbGVcbiAgICAgKiBAcGFyYW0gYXhpc09wdGlvblxuICAgICAqIEBwYXJhbSBkaXJlY3Rpb25cbiAgICAgKiBAcmV0dXJuIGxpbmUgYXhpcyBjZmdcbiAgICAgKi9cbiAgICBBeGlzLnByb3RvdHlwZS5nZXRMaW5lQXhpc0NmZyA9IGZ1bmN0aW9uIChzY2FsZSwgYXhpc09wdGlvbiwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmF4aXNDb250YWluZXI7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHJlZ2lvbiA9IGF4aXNfMS5nZXRBeGlzUmVnaW9uKGNvb3JkaW5hdGUsIGRpcmVjdGlvbik7XG4gICAgICAgIHZhciB0aXRsZVRleHQgPSBheGlzXzEuZ2V0QXhpc1RpdGxlVGV4dChzY2FsZSwgYXhpc09wdGlvbik7XG4gICAgICAgIHZhciBheGlzVGhlbWVDZmcgPSBheGlzXzEuZ2V0QXhpc1RoZW1lQ2ZnKHRoaXMudmlldy5nZXRUaGVtZSgpLCBkaXJlY3Rpb24pO1xuICAgICAgICAvLyB0aGUgY2ZnIG9yZGVyIHNob3VsZCBiZSBlbnN1cmVcbiAgICAgICAgdmFyIG9wdGlvbldpdGhUaXRsZSA9IHV0aWxfMS5nZXQoYXhpc09wdGlvbiwgWyd0aXRsZSddKVxuICAgICAgICAgICAgPyB1dGlsXzEuZGVlcE1peCh7IHRpdGxlOiB7IHN0eWxlOiB7IHRleHQ6IHRpdGxlVGV4dCB9IH0gfSwgYXhpc09wdGlvbilcbiAgICAgICAgICAgIDogYXhpc09wdGlvbjtcbiAgICAgICAgdmFyIGNmZyA9IHV0aWxfMS5kZWVwTWl4KHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IGNvbnRhaW5lcjogY29udGFpbmVyIH0sIHJlZ2lvbiksIHsgdGlja3M6IHNjYWxlLmdldFRpY2tzKCkubWFwKGZ1bmN0aW9uICh0aWNrKSB7IHJldHVybiAoeyBpZDogXCJcIiArIHRpY2sudGlja1ZhbHVlLCBuYW1lOiB0aWNrLnRleHQsIHZhbHVlOiB0aWNrLnZhbHVlIH0pOyB9KSwgdmVydGljYWxGYWN0b3I6IGNvb3JkaW5hdGUuaXNQb2xhclxuICAgICAgICAgICAgICAgID8gYXhpc18xLmdldEF4aXNGYWN0b3JCeVJlZ2lvbihyZWdpb24sIGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCkpICogLTFcbiAgICAgICAgICAgICAgICA6IGF4aXNfMS5nZXRBeGlzRmFjdG9yQnlSZWdpb24ocmVnaW9uLCBjb29yZGluYXRlLmdldENlbnRlcigpKSB9KSwgYXhpc1RoZW1lQ2ZnLCBvcHRpb25XaXRoVGl0bGUpO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldEFuaW1hdGVDZmcoY2ZnKSwgYW5pbWF0ZSA9IF9hLmFuaW1hdGUsIGFuaW1hdGVPcHRpb24gPSBfYS5hbmltYXRlT3B0aW9uO1xuICAgICAgICBjZmcuYW5pbWF0ZU9wdGlvbiA9IGFuaW1hdGVPcHRpb247XG4gICAgICAgIGNmZy5hbmltYXRlID0gYW5pbWF0ZTtcbiAgICAgICAgLy8g6K6h566XIHZlcnRpY2FsTGltaXRMZW5ndGhcbiAgICAgICAgdmFyIGlzQXhpc1ZlcnRpY2FsID0gYXhpc18xLmlzVmVydGljYWwocmVnaW9uKTtcbiAgICAgICAgLy8gVE9ETzogMSAvIDMg562J6buY6K6k5YC86ZyA6KaB5pyJ5LiA5Liq5YWo5bGA55qE6YWN572u55qE5Zyw5pa5XG4gICAgICAgIHZhciB2ZXJ0aWNhbExpbWl0TGVuZ3RoID0gdXRpbF8xLmdldChjZmcsICd2ZXJ0aWNhbExpbWl0TGVuZ3RoJywgaXNBeGlzVmVydGljYWwgPyAxIC8gMyA6IDEgLyAyKTtcbiAgICAgICAgaWYgKHZlcnRpY2FsTGltaXRMZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgLy8g6YWN572u55qE55u45a+55YC877yM55u45a+55LqO55S75biDXG4gICAgICAgICAgICB2YXIgY2FudmFzV2lkdGggPSB0aGlzLnZpZXcuZ2V0Q2FudmFzKCkuZ2V0KCd3aWR0aCcpO1xuICAgICAgICAgICAgdmFyIGNhbnZhc0hlaWdodCA9IHRoaXMudmlldy5nZXRDYW52YXMoKS5nZXQoJ2hlaWdodCcpO1xuICAgICAgICAgICAgY2ZnLnZlcnRpY2FsTGltaXRMZW5ndGggPSB2ZXJ0aWNhbExpbWl0TGVuZ3RoICogKGlzQXhpc1ZlcnRpY2FsID8gY2FudmFzV2lkdGggOiBjYW52YXNIZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjZmc7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBnZW5lcmF0ZSBsaW5lIGdyaWQgY2ZnXG4gICAgICogQHBhcmFtIHNjYWxlXG4gICAgICogQHBhcmFtIGF4aXNPcHRpb25cbiAgICAgKiBAcGFyYW0gZGlyZWN0aW9uXG4gICAgICogQHBhcmFtIGRpbVxuICAgICAqIEByZXR1cm4gbGluZSBncmlkIGNmZ1xuICAgICAqL1xuICAgIEF4aXMucHJvdG90eXBlLmdldExpbmVHcmlkQ2ZnID0gZnVuY3Rpb24gKHNjYWxlLCBheGlzT3B0aW9uLCBkaXJlY3Rpb24sIGRpbSkge1xuICAgICAgICBpZiAoIWdyaWRfMS5zaG93R3JpZChheGlzXzEuZ2V0QXhpc1RoZW1lQ2ZnKHRoaXMudmlldy5nZXRUaGVtZSgpLCBkaXJlY3Rpb24pLCBheGlzT3B0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZ3JpZFRoZW1lQ2ZnID0gZ3JpZF8xLmdldEdyaWRUaGVtZUNmZyh0aGlzLnZpZXcuZ2V0VGhlbWUoKSwgZGlyZWN0aW9uKTtcbiAgICAgICAgLy8gdGhlIGNmZyBvcmRlciBzaG91bGQgYmUgZW5zdXJlXG4gICAgICAgIC8vIGdyaWQg5Yqo55S75LulIGF4aXMg5Li65YeGXG4gICAgICAgIHZhciBncmlkQ2ZnID0gdXRpbF8xLmRlZXBNaXgoe1xuICAgICAgICAgICAgY29udGFpbmVyOiB0aGlzLmdyaWRDb250YWluZXIsXG4gICAgICAgIH0sIGdyaWRUaGVtZUNmZywgdXRpbF8xLmdldChheGlzT3B0aW9uLCAnZ3JpZCcpLCB0aGlzLmdldEFuaW1hdGVDZmcoYXhpc09wdGlvbikpO1xuICAgICAgICBncmlkQ2ZnLml0ZW1zID0gZ3JpZF8xLmdldExpbmVHcmlkSXRlbXModGhpcy52aWV3LmdldENvb3JkaW5hdGUoKSwgc2NhbGUsIGRpbSwgdXRpbF8xLmdldChncmlkQ2ZnLCAnYWxpZ25UaWNrJywgdHJ1ZSkpO1xuICAgICAgICByZXR1cm4gZ3JpZENmZztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGdlbmVyYXRlIGNpcmNsZSBheGlzIGNmZ1xuICAgICAqIEBwYXJhbSBzY2FsZVxuICAgICAqIEBwYXJhbSBheGlzT3B0aW9uXG4gICAgICogQHBhcmFtIGRpcmVjdGlvblxuICAgICAqIEByZXR1cm4gY2lyY2xlIGF4aXMgY2ZnXG4gICAgICovXG4gICAgQXhpcy5wcm90b3R5cGUuZ2V0Q2lyY2xlQXhpc0NmZyA9IGZ1bmN0aW9uIChzY2FsZSwgYXhpc09wdGlvbiwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmF4aXNDb250YWluZXI7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHRpY2tzID0gc2NhbGUuZ2V0VGlja3MoKS5tYXAoZnVuY3Rpb24gKHRpY2spIHsgcmV0dXJuICh7IGlkOiBcIlwiICsgdGljay50aWNrVmFsdWUsIG5hbWU6IHRpY2sudGV4dCwgdmFsdWU6IHRpY2sudmFsdWUgfSk7IH0pO1xuICAgICAgICBpZiAoIXNjYWxlLmlzQ2F0ZWdvcnkgJiYgTWF0aC5hYnMoY29vcmRpbmF0ZS5lbmRBbmdsZSAtIGNvb3JkaW5hdGUuc3RhcnRBbmdsZSkgPT09IE1hdGguUEkgKiAyKSB7XG4gICAgICAgICAgICAvLyB4IOi9tOWvueW6lOeahOWAvOWmguaenOaYr+mdniBjYXQg57G75Z6L77yM5Zyo5pW05ZyG55qE5oOF5Ya15LiL5Z2Q5qCH6L2056ys5LiA5Liq5ZKM5pyA5ZCO5LiA5Liq5paH5pys5Lya6YeN5Y+g77yM6buY6K6k5Y+q5bGV56S656ys5LiA5Liq5paH5pysXG4gICAgICAgICAgICB0aWNrcy5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGl0bGVUZXh0ID0gYXhpc18xLmdldEF4aXNUaXRsZVRleHQoc2NhbGUsIGF4aXNPcHRpb24pO1xuICAgICAgICB2YXIgYXhpc1RoZW1lQ2ZnID0gYXhpc18xLmdldEF4aXNUaGVtZUNmZyh0aGlzLnZpZXcuZ2V0VGhlbWUoKSwgY29uc3RhbnRfMS5ESVJFQ1RJT04uQ0lSQ0xFKTtcbiAgICAgICAgLy8gdGhlIGNmZyBvcmRlciBzaG91bGQgYmUgZW5zdXJlXG4gICAgICAgIHZhciBvcHRpb25XaXRoVGl0bGUgPSB1dGlsXzEuZ2V0KGF4aXNPcHRpb24sIFsndGl0bGUnXSlcbiAgICAgICAgICAgID8gdXRpbF8xLmRlZXBNaXgoeyB0aXRsZTogeyBzdHlsZTogeyB0ZXh0OiB0aXRsZVRleHQgfSB9IH0sIGF4aXNPcHRpb24pXG4gICAgICAgICAgICA6IGF4aXNPcHRpb247XG4gICAgICAgIHZhciBjZmcgPSB1dGlsXzEuZGVlcE1peCh0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyBjb250YWluZXI6IGNvbnRhaW5lciB9LCBheGlzXzEuZ2V0Q2lyY2xlQXhpc0NlbnRlclJhZGl1cyh0aGlzLnZpZXcuZ2V0Q29vcmRpbmF0ZSgpKSksIHsgdGlja3M6IHRpY2tzLCB2ZXJ0aWNhbEZhY3RvcjogMSB9KSwgYXhpc1RoZW1lQ2ZnLCBvcHRpb25XaXRoVGl0bGUpO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldEFuaW1hdGVDZmcoY2ZnKSwgYW5pbWF0ZSA9IF9hLmFuaW1hdGUsIGFuaW1hdGVPcHRpb24gPSBfYS5hbmltYXRlT3B0aW9uO1xuICAgICAgICBjZmcuYW5pbWF0ZSA9IGFuaW1hdGU7XG4gICAgICAgIGNmZy5hbmltYXRlT3B0aW9uID0gYW5pbWF0ZU9wdGlvbjtcbiAgICAgICAgcmV0dXJuIGNmZztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGdlbmVyYXRlIGNpcmNsZSBncmlkIGNmZ1xuICAgICAqIEBwYXJhbSBzY2FsZVxuICAgICAqIEBwYXJhbSBheGlzT3B0aW9uXG4gICAgICogQHBhcmFtIGRpcmVjdGlvblxuICAgICAqIEByZXR1cm4gY2lyY2xlIGdyaWQgY2ZnXG4gICAgICovXG4gICAgQXhpcy5wcm90b3R5cGUuZ2V0Q2lyY2xlR3JpZENmZyA9IGZ1bmN0aW9uIChzY2FsZSwgYXhpc09wdGlvbiwgZGlyZWN0aW9uLCBkaW0pIHtcbiAgICAgICAgaWYgKCFncmlkXzEuc2hvd0dyaWQoYXhpc18xLmdldEF4aXNUaGVtZUNmZyh0aGlzLnZpZXcuZ2V0VGhlbWUoKSwgZGlyZWN0aW9uKSwgYXhpc09wdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlIGNmZyBvcmRlciBzaG91bGQgYmUgZW5zdXJlXG4gICAgICAgIC8vIGdyaWQg5Yqo55S75LulIGF4aXMg5Li65YeGXG4gICAgICAgIHZhciBncmlkVGhlbWVDZmcgPSBncmlkXzEuZ2V0R3JpZFRoZW1lQ2ZnKHRoaXMudmlldy5nZXRUaGVtZSgpLCBjb25zdGFudF8xLkRJUkVDVElPTi5SQURJVVMpO1xuICAgICAgICB2YXIgZ3JpZENmZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5ncmlkQ29udGFpbmVyLFxuICAgICAgICAgICAgY2VudGVyOiB0aGlzLnZpZXcuZ2V0Q29vcmRpbmF0ZSgpLmdldENlbnRlcigpLFxuICAgICAgICB9LCBncmlkVGhlbWVDZmcsIHV0aWxfMS5nZXQoYXhpc09wdGlvbiwgJ2dyaWQnKSwgdGhpcy5nZXRBbmltYXRlQ2ZnKGF4aXNPcHRpb24pKTtcbiAgICAgICAgdmFyIGFsaWduVGljayA9IHV0aWxfMS5nZXQoZ3JpZENmZywgJ2FsaWduVGljaycsIHRydWUpO1xuICAgICAgICB2YXIgdmVydGljYWxTY2FsZSA9IGRpbSA9PT0gJ3gnID8gdGhpcy52aWV3LmdldFlTY2FsZXMoKVswXSA6IHRoaXMudmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgZ3JpZENmZy5pdGVtcyA9IGdyaWRfMS5nZXRDaXJjbGVHcmlkSXRlbXModGhpcy52aWV3LmdldENvb3JkaW5hdGUoKSwgdmVydGljYWxTY2FsZSwgc2NhbGUsIGFsaWduVGljaywgZGltKTtcbiAgICAgICAgLy8gdGhlIGNmZyBvcmRlciBzaG91bGQgYmUgZW5zdXJlXG4gICAgICAgIC8vIGdyaWQg5Yqo55S75LulIGF4aXMg5Li65YeGXG4gICAgICAgIHJldHVybiBncmlkQ2ZnO1xuICAgIH07XG4gICAgQXhpcy5wcm90b3R5cGUuZ2V0SWQgPSBmdW5jdGlvbiAobmFtZSwga2V5KSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgLy8g5Z2Q5qCH57O757G75Z6L5Lmf5L2c5Li657uE5Lu255qEIGtleVxuICAgICAgICByZXR1cm4gbmFtZSArIFwiLVwiICsga2V5ICsgXCItXCIgKyBjb29yZGluYXRlLnR5cGU7XG4gICAgfTtcbiAgICBBeGlzLnByb3RvdHlwZS5nZXRBbmltYXRlQ2ZnID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYW5pbWF0ZTogdGhpcy52aWV3LmdldE9wdGlvbnMoKS5hbmltYXRlICYmIHV0aWxfMS5nZXQoY2ZnLCAnYW5pbWF0ZScpLFxuICAgICAgICAgICAgYW5pbWF0ZU9wdGlvbjogY2ZnICYmIGNmZy5hbmltYXRlT3B0aW9uID8gdXRpbF8xLmRlZXBNaXgoe30sIEFYSVNfREVGQVVMVF9BTklNQVRFX0NGRywgY2ZnLmFuaW1hdGVPcHRpb24pIDogQVhJU19ERUZBVUxUX0FOSU1BVEVfQ0ZHLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIEF4aXM7XG59KGJhc2VfMS5Db250cm9sbGVyKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBeGlzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXhpcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQ29udHJvbGxlciA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKlxuICogQ29tcG9uZW50IENvbnRyb2xsZXIg6KeE6IyD6ZyA6KaB5a6a5LmJ55qE5Z+657G7XG4gKiAxLiDop4TojIPnmoQgb3B0aW9uIOi+k+WFpVxuICogMi4g57uf5LiA55qE5L+h5oGv6I635Y+WIEFQSVxuICogMy4g5piO56Gu5a6a5LmJ55qE57uE5Lu25LqL5Lu277yI5ZCN56ew44CB5pWw5o2u77yJXG4gKi9cbnZhciBDb250cm9sbGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbnRyb2xsZXIodmlldykge1xuICAgICAgICAvKiog5piv5ZCm5Y+v6KeBICovXG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHRydWU7XG4gICAgICAgIC8qKiDmiYDmnInnmoQgY29tcG9uZW50ICovXG4gICAgICAgIHRoaXMuY29tcG9uZW50cyA9IFtdO1xuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhclxuICAgICAqL1xuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBkZXN0cm95IGFsbCBjb21wb25lbnRzXG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuY29tcG9uZW50cywgZnVuY3Rpb24gKGNvKSB7XG4gICAgICAgICAgICBjby5jb21wb25lbnQuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gY2xlYXIgYWxsIGNvbXBvbmVudCBpbnN0YW5jZVxuICAgICAgICB0aGlzLmNvbXBvbmVudHMgPSBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGRlc3Ryb3kgdGhlIGNvbXBvbmVudFxuICAgICAqL1xuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGdldCBhbGwgY29tcG9uZW50c1xuICAgICAqIEByZXR1cm5zIGNvbXBvbmVudHMgYXJyYXlcbiAgICAgKi9cbiAgICBDb250cm9sbGVyLnByb3RvdHlwZS5nZXRDb21wb25lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wb25lbnRzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogY2hhbmdlIHZpc2liaWxpdHkgb2YgY29tcG9uZW50XG4gICAgICogQHBhcmFtIHZpc2libGVcbiAgICAgKi9cbiAgICBDb250cm9sbGVyLnByb3RvdHlwZS5jaGFuZ2VWaXNpYmxlID0gZnVuY3Rpb24gKHZpc2libGUpIHtcbiAgICAgICAgaWYgKHRoaXMudmlzaWJsZSA9PT0gdmlzaWJsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29tcG9uZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChjbykge1xuICAgICAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICAgICAgICBjby5jb21wb25lbnQuc2hvdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY28uY29tcG9uZW50LmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHZpc2libGU7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udHJvbGxlcjtcbn0oKSk7XG5leHBvcnRzLkNvbnRyb2xsZXIgPSBDb250cm9sbGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xuLyoqXG4gKiBjb29yZGluYXRlIGNvbnRyb2xsZXLvvIzogYzotKPvvJpcbiAqIDEuIOWIm+W7uuWunuS+i1xuICogMi4g5pqC5a2Y6YWN572uXG4gKi9cbnZhciBDb29yZGluYXRlQ29udHJvbGxlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb29yZGluYXRlQ29udHJvbGxlcihvcHRpb24pIHtcbiAgICAgICAgLy8g6K6+572u6buY6K6k5YC877yM5bm25a2Y5YKo6YWN572uXG4gICAgICAgIHRoaXMub3B0aW9uID0gdGhpcy53cmFwcGVyT3B0aW9uKG9wdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOabtOaWsOmFjee9rlxuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKi9cbiAgICBDb29yZGluYXRlQ29udHJvbGxlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKG9wdGlvbikge1xuICAgICAgICB0aGlzLm9wdGlvbiA9IHRoaXMud3JhcHBlck9wdGlvbihvcHRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYr+WQpuWtmOWcqOafkOS4gOS4qiBhY3Rpb25cbiAgICAgKiBAcGFyYW0gYWN0aW9uTmFtZVxuICAgICAqL1xuICAgIENvb3JkaW5hdGVDb250cm9sbGVyLnByb3RvdHlwZS5oYXNBY3Rpb24gPSBmdW5jdGlvbiAoYWN0aW9uTmFtZSkge1xuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMub3B0aW9uLmFjdGlvbnM7XG4gICAgICAgIHJldHVybiB1dGlsXzEuc29tZShhY3Rpb25zLCBmdW5jdGlvbiAoYWN0aW9uKSB7IHJldHVybiBhY3Rpb25bMF0gPT09IGFjdGlvbk5hbWU7IH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu65Z2Q5qCH57O75a+56LGhXG4gICAgICogQHBhcmFtIHN0YXJ0IOi1t+Wni+S9jee9rlxuICAgICAqIEBwYXJhbSBlbmQgICDnu5PmnZ/kvY3nva5cbiAgICAgKiBAcmV0dXJuIOWdkOagh+ezu+WunuS+i1xuICAgICAqL1xuICAgIENvb3JkaW5hdGVDb250cm9sbGVyLnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbiwgdHlwZSA9IF9hLnR5cGUsIGNmZyA9IF9hLmNmZztcbiAgICAgICAgdmFyIGlzVGhldGEgPSB0eXBlID09PSAndGhldGEnO1xuICAgICAgICAvLyAxLiDotbflp4vkvY3nva5cbiAgICAgICAgdmFyIHByb3BzID0gdHNsaWJfMS5fX2Fzc2lnbih7IHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogZW5kIH0sIGNmZyk7XG4gICAgICAgIC8vIDIuIOWIm+W7uuWunuS+i1xuICAgICAgICB2YXIgQyA9IGRlcGVuZGVudHNfMS5nZXRDb29yZGluYXRlKGlzVGhldGEgPyAncG9sYXInIDogdHlwZSk7XG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZSA9IG5ldyBDKHByb3BzKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZSBGSVhNRSBjb29yZGluYXRlIOWMhemXrumimOWvvOiHtCB0eXBlIOS4jeato+ehrlxuICAgICAgICB0aGlzLmNvb3JkaW5hdGUudHlwZSA9IHR5cGU7XG4gICAgICAgIC8vIDMuIOa3u+WKoOm7mOiupCBhY3Rpb25cbiAgICAgICAgaWYgKGlzVGhldGEpIHtcbiAgICAgICAgICAgIC8vIOS4jeWtmOWcqCB0cmFuc3Bvc2XvvIzkuLrlhbboh6rliqjorr7nva7kuIDkuKogYWN0aW9uXG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFzQWN0aW9uKCd0cmFuc3Bvc2UnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gNC4g5omn6KGMIGFjdGlvblxuICAgICAgICB0aGlzLmV4ZWNBY3Rpb25zKCk7XG4gICAgICAgIHJldHVybiB0aGlzLmNvb3JkaW5hdGU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrDlnZDmoIfns7vlr7nosaFcbiAgICAgKiBAcGFyYW0gc3RhcnQg6LW35aeL5L2N572uXG4gICAgICogQHBhcmFtIGVuZCAgIOe7k+adn+S9jee9rlxuICAgICAqIEByZXR1cm4g5Z2Q5qCH57O75a6e5L6LXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLmFkanVzdCA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZS51cGRhdGUoe1xuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBlbmQsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyDmm7TmlrDlnZDmoIfns7vlpKflsI/nmoTml7blgJnvvIzpnIDopoHvvJpcbiAgICAgICAgLy8gMS4g6YeN572uIG1hdHJpeFxuICAgICAgICAvLyAyLiDph43mlrDmiafooYzkvZznlKjkuo4gbWF0cml4IOeahCBhY3Rpb25cbiAgICAgICAgdGhpcy5jb29yZGluYXRlLnJlc2V0TWF0cml4KCk7XG4gICAgICAgIHRoaXMuZXhlY0FjdGlvbnMoWydzY2FsZScsICdyb3RhdGUnLCAndHJhbnNsYXRlJ10pO1xuICAgICAgICByZXR1cm4gdGhpcy5jb29yZGluYXRlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5peL6L2s5byn5bqmXG4gICAgICogQHBhcmFtIGFuZ2xlXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLnJvdGF0ZSA9IGZ1bmN0aW9uIChhbmdsZSkge1xuICAgICAgICB0aGlzLm9wdGlvbi5hY3Rpb25zLnB1c2goWydyb3RhdGUnLCBhbmdsZV0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOmVnOWDj1xuICAgICAqIEBwYXJhbSBkaW1cbiAgICAgKi9cbiAgICBDb29yZGluYXRlQ29udHJvbGxlci5wcm90b3R5cGUucmVmbGVjdCA9IGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgdGhpcy5vcHRpb24uYWN0aW9ucy5wdXNoKFsncmVmbGVjdCcsIGRpbV0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIHNjYWxlXG4gICAgICogQHBhcmFtIHN4XG4gICAgICogQHBhcmFtIHN5XG4gICAgICovXG4gICAgQ29vcmRpbmF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKHN4LCBzeSkge1xuICAgICAgICB0aGlzLm9wdGlvbi5hY3Rpb25zLnB1c2goWydzY2FsZScsIHN4LCBzeV0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWvueinkuWPmOaNolxuICAgICAqL1xuICAgIENvb3JkaW5hdGVDb250cm9sbGVyLnByb3RvdHlwZS50cmFuc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3B0aW9uLmFjdGlvbnMucHVzaChbJ3RyYW5zcG9zZSddKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bphY3nva5cbiAgICAgKi9cbiAgICBDb29yZGluYXRlQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0T3B0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb247XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflvpcgY29vcmRpbmF0ZSDlrp7kvotcbiAgICAgKi9cbiAgICBDb29yZGluYXRlQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29vcmRpbmF0ZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWMheijhemFjee9rueahOm7mOiupOWAvFxuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKi9cbiAgICBDb29yZGluYXRlQ29udHJvbGxlci5wcm90b3R5cGUud3JhcHBlck9wdGlvbiA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAncmVjdCcsIGFjdGlvbnM6IFtdLCBjZmc6IHt9IH0sIG9wdGlvbik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBjb29yZGluYXRlIOWunuS+i+aJp+ihjCBhY3Rpb25zXG4gICAgICogQHBhcmFtcyBpbmNsdWRlQWN0aW9ucyDlpoLmnpzmsqHmnInmjIflrprvvIzliJnmiafooYzlhajpg6jvvIzlkKbliJnvvIzmiafooYzmjIflrprnmoQgYWN0aW9uXG4gICAgICovXG4gICAgQ29vcmRpbmF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLmV4ZWNBY3Rpb25zID0gZnVuY3Rpb24gKGluY2x1ZGVBY3Rpb25zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBhY3Rpb25zID0gdGhpcy5vcHRpb24uYWN0aW9ucztcbiAgICAgICAgdXRpbF8xLmVhY2goYWN0aW9ucywgZnVuY3Rpb24gKGFjdGlvbikge1xuICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgdmFyIGFjdGlvbk5hbWUgPSBhY3Rpb25bMF0sIGFyZ3MgPSBhY3Rpb24uc2xpY2UoMSk7XG4gICAgICAgICAgICB2YXIgc2hvdWxkRXhlYyA9IHV0aWxfMS5pc05pbChpbmNsdWRlQWN0aW9ucykgPyB0cnVlIDogaW5jbHVkZUFjdGlvbnMuaW5jbHVkZXMoYWN0aW9uTmFtZSk7XG4gICAgICAgICAgICBpZiAoc2hvdWxkRXhlYykge1xuICAgICAgICAgICAgICAgIChfYSA9IF90aGlzLmNvb3JkaW5hdGUpW2FjdGlvbk5hbWVdLmFwcGx5KF9hLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQ29vcmRpbmF0ZUNvbnRyb2xsZXI7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29vcmRpbmF0ZUNvbnRyb2xsZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb29yZGluYXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBQUkVTU19ERUxBWSA9IDI1MDtcbi8vIOiuoeeul+a7keWKqOeahOaWueWQkVxudmFyIGNhbGNEaXJlY3Rpb24gPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICAgIHZhciB4RGlzdGFuY2UgPSBlbmQueCAtIHN0YXJ0Lng7XG4gICAgdmFyIHlEaXN0YW5jZSA9IGVuZC55IC0gc3RhcnQueTtcbiAgICAvLyB4IOeahOi3neemu+Wkp+S6jnkg6K+05piO5piv5qiq5ZCR77yM5ZCm5YiZ5bCx5piv57q15ZCRXG4gICAgaWYgKE1hdGguYWJzKHhEaXN0YW5jZSkgPiBNYXRoLmFicyh5RGlzdGFuY2UpKSB7XG4gICAgICAgIHJldHVybiB4RGlzdGFuY2UgPiAwID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICB9XG4gICAgcmV0dXJuIHlEaXN0YW5jZSA+IDAgPyAnZG93bicgOiAndXAnO1xufTtcbi8vIOiuoeeulzLngrnkuYvpl7TnmoTot53nprtcbnZhciBjYWxjRGlzdGFuY2UgPSBmdW5jdGlvbiAocG9pbnQxLCBwb2ludDIpIHtcbiAgICB2YXIgeERpc3RhbmNlID0gTWF0aC5hYnMocG9pbnQyLnggLSBwb2ludDEueCk7XG4gICAgdmFyIHlEaXN0YW5jZSA9IE1hdGguYWJzKHBvaW50Mi55IC0gcG9pbnQxLnkpO1xuICAgIHJldHVybiBNYXRoLnNxcnQoeERpc3RhbmNlICogeERpc3RhbmNlICsgeURpc3RhbmNlICogeURpc3RhbmNlKTtcbn07XG52YXIgZ2V0Q2VudGVyID0gZnVuY3Rpb24gKHBvaW50MSwgcG9pbnQyKSB7XG4gICAgdmFyIHggPSAocG9pbnQxLnggKyBwb2ludDIueCkgLyAyO1xuICAgIHZhciB5ID0gKHBvaW50MS55ICsgcG9pbnQyLnkpIC8gMjtcbiAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG59O1xudmFyIGNvbnZlcnRQb2ludHMgPSBmdW5jdGlvbiAodG91Y2hlcywgY2FudmFzKSB7XG4gICAgaWYgKCF0b3VjaGVzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHBvaW50cyA9IFtdO1xuICAgIHZhciBsZW4gPSB0b3VjaGVzLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciB0b3VjaCA9IHRvdWNoZXNbaV07XG4gICAgICAgIC8vIHgsIHk6IOebuOWvuWNhbnZhc+WOn+eCueeahOS9jee9ru+8jGNsaWVudFgsIGNsaWVudFkg55u45a+55LqO5Y+v6KeG56qX5Y+j55qE5L2N572uXG4gICAgICAgIHZhciBjbGllbnRYID0gdG91Y2guY2xpZW50WCwgY2xpZW50WSA9IHRvdWNoLmNsaWVudFk7XG4gICAgICAgIHZhciBwb2ludCA9IGNhbnZhcy5nZXRQb2ludEJ5Q2xpZW50KGNsaWVudFgsIGNsaWVudFkpO1xuICAgICAgICBwb2ludHMucHVzaChwb2ludCk7XG4gICAgfVxuICAgIHJldHVybiBwb2ludHM7XG59O1xudmFyIEdlc3R1cmVDb250cm9sbGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEdlc3R1cmVDb250cm9sbGVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdlc3R1cmVDb250cm9sbGVyKHZpZXcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdmlldykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMucHJvY2Vzc0V2ZW50ID0ge307XG4gICAgICAgIF90aGlzLnRvdWNoU3RhcnQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBwb2ludHMgPSBjb252ZXJ0UG9pbnRzKGV2Lm9yaWdpbmFsRXZlbnQudG91Y2hlcywgX3RoaXMuY2FudmFzKTtcbiAgICAgICAgICAgIGlmICghcG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXYucG9pbnRzID0gcG9pbnRzO1xuICAgICAgICAgICAgLy8g6Ziy5q2i5LiK5qyh55qE5YaF5a655rKh5pyJ5riF55CG5o6J77yM6YeN5pawcmVzZXTkuItcbiAgICAgICAgICAgIF90aGlzLnJlc2V0KCk7XG4gICAgICAgICAgICAvLyDorrDlvZV0b3VjaCBzdGFydCDnmoTml7bpl7RcbiAgICAgICAgICAgIF90aGlzLnN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAvLyDorrDlvZV0b3VjaCBzdGFydCDnmoTngrlcbiAgICAgICAgICAgIF90aGlzLnN0YXJ0UG9pbnRzID0gcG9pbnRzO1xuICAgICAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc3RhcnREaXN0YW5jZSA9IGNhbGNEaXN0YW5jZShwb2ludHNbMF0sIHBvaW50c1sxXSk7XG4gICAgICAgICAgICAgICAgX3RoaXMuY2VudGVyID0gZ2V0Q2VudGVyKHBvaW50c1swXSwgcG9pbnRzWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenHRvdWNoc3RhcnTlkI7lgZzpob8yNTBtcywg5YiZ5Lmf6Kem5Y+RcHJlc3Pkuovku7ZcbiAgICAgICAgICAgICAgICBfdGhpcy5wcmVzc1RpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g6L+Z6YeM5Zu65a6a6Kem5Y+RcHJlc3Pkuovku7ZcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50VHlwZSA9ICdwcmVzcyc7XG4gICAgICAgICAgICAgICAgICAgIGV2LmRpcmVjdGlvbiA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuZW1pdFN0YXJ0KGV2ZW50VHlwZSwgZXYpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5lbWl0RXZlbnQoZXZlbnRUeXBlLCBldik7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmV2ZW50VHlwZSA9IGV2ZW50VHlwZTtcbiAgICAgICAgICAgICAgICB9LCBQUkVTU19ERUxBWSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIF90aGlzLnRvdWNoTW92ZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgdmFyIHBvaW50cyA9IGNvbnZlcnRQb2ludHMoZXYub3JpZ2luYWxFdmVudC50b3VjaGVzLCBfdGhpcy5jYW52YXMpO1xuICAgICAgICAgICAgaWYgKCFwb2ludHMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5jbGVhclByZXNzVGltZW91dCgpO1xuICAgICAgICAgICAgZXYucG9pbnRzID0gcG9pbnRzO1xuICAgICAgICAgICAgdmFyIHN0YXJ0UG9pbnRzID0gX3RoaXMuc3RhcnRQb2ludHM7XG4gICAgICAgICAgICBpZiAoIXN0YXJ0UG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5aSa5oyH6Kem5o6nXG4gICAgICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAvLyB0b3VjaHN0YXJ055qE6Led56a7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0RGlzdGFuY2UgPSBfdGhpcy5zdGFydERpc3RhbmNlO1xuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50RGlzdGFuY2UgPSBjYWxjRGlzdGFuY2UocG9pbnRzWzBdLCBwb2ludHNbMV0pO1xuICAgICAgICAgICAgICAgIGV2Lnpvb20gPSBjdXJyZW50RGlzdGFuY2UgLyBzdGFydERpc3RhbmNlO1xuICAgICAgICAgICAgICAgIGV2LmNlbnRlciA9IF90aGlzLmNlbnRlcjtcbiAgICAgICAgICAgICAgICAvLyDop6blj5HnvKnmlL7kuovku7ZcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0U3RhcnQoJ3BpbmNoJywgZXYpO1xuICAgICAgICAgICAgICAgIF90aGlzLmVtaXRFdmVudCgncGluY2gnLCBldik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVsdGFYID0gcG9pbnRzWzBdLnggLSBzdGFydFBvaW50c1swXS54O1xuICAgICAgICAgICAgICAgIHZhciBkZWx0YVkgPSBwb2ludHNbMF0ueSAtIHN0YXJ0UG9pbnRzWzBdLnk7XG4gICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IF90aGlzLmRpcmVjdGlvbiB8fCBjYWxjRGlyZWN0aW9uKHN0YXJ0UG9pbnRzWzBdLCBwb2ludHNbMF0pO1xuICAgICAgICAgICAgICAgIF90aGlzLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICAgICAgICAgICAgICAvLyDojrflj5ZwcmVzc+aIluiAhXBhbueahOS6i+S7tuexu+Wei1xuICAgICAgICAgICAgICAgIC8vIHByZXNzIOaMieS9j+a7keWKqCwgcGFu6KGo56S65bmz56e7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6cc3RhcnTlkI7nq4vliLttb3Zl77yM5YiZ6Kem5Y+RcGFuLCDlpoLmnpzmnInlgZzpob/vvIzliJnop6blj5FwcmVzc1xuICAgICAgICAgICAgICAgIHZhciBldmVudFR5cGUgPSBfdGhpcy5nZXRFdmVudFR5cGUocG9pbnRzKTtcbiAgICAgICAgICAgICAgICBldi5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgICAgICAgICAgICAgZXYuZGVsdGFYID0gZGVsdGFYO1xuICAgICAgICAgICAgICAgIGV2LmRlbHRhWSA9IGRlbHRhWTtcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0U3RhcnQoZXZlbnRUeXBlLCBldik7XG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdEV2ZW50KGV2ZW50VHlwZSwgZXYpO1xuICAgICAgICAgICAgICAgIC8vIOiusOW9leacgOWQjjLmrKFtb3Zl55qE5pe26Ze05ZKM5Z2Q5qCH77yM5Li65LqG57uZc3dpcGXkuovku7bnlKhcbiAgICAgICAgICAgICAgICB2YXIgcHJldk1vdmVUaW1lID0gX3RoaXMubGFzdE1vdmVUaW1lO1xuICAgICAgICAgICAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIC8vIOacgOWQjjLmrKHnmoTml7bpl7Tpl7TpmpTkuIDlrpropoHlpKfkuo4w77yM5ZCm5YiZc3dpcGXmsqHlj5HorqHnrpdcbiAgICAgICAgICAgICAgICBpZiAobm93IC0gcHJldk1vdmVUaW1lID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcmV2TW92ZVRpbWUgPSBwcmV2TW92ZVRpbWU7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnByZXZNb3ZlUG9pbnRzID0gX3RoaXMubGFzdE1vdmVQb2ludHM7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmxhc3RNb3ZlVGltZSA9IG5vdztcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubGFzdE1vdmVQb2ludHMgPSBwb2ludHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBfdGhpcy50b3VjaEVuZCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgX3RoaXMuZW1pdEVuZChldik7XG4gICAgICAgICAgICAvLyBzd2lwZeS6i+S7tuWkhOeQhiwg5ZyodG91Y2hlbmTkuYvlkI7op6blj5FcbiAgICAgICAgICAgIHZhciBsYXN0TW92ZVRpbWUgPSBfdGhpcy5sYXN0TW92ZVRpbWU7XG4gICAgICAgICAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgIC8vIOWBmui/meS4quWIpOaWreaYr+S4uuS6huacgOWQjuS4gOasoXRvdWNobW92ZeWQjuWIsGVuZOWJje+8jOi/mOacieS4gOS4quWBnOmhv+eahOi/h+eoi1xuICAgICAgICAgICAgLy8gMTAwIOaYr+aLjeeahOS4gOS4quWAvO+8jOeQhuiuuui/meS4quWAvOS8muW+iOefre+8jOS4gOiIrOS4jeWNoemhv+eahOivneWcqDEwbXPku6XlhoVcbiAgICAgICAgICAgIGlmIChub3cgLSBsYXN0TW92ZVRpbWUgPCAxMDApIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJldk1vdmVUaW1lID0gX3RoaXMucHJldk1vdmVUaW1lIHx8IF90aGlzLnN0YXJ0VGltZTtcbiAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWxUaW1lID0gbGFzdE1vdmVUaW1lIC0gcHJldk1vdmVUaW1lO1xuICAgICAgICAgICAgICAgIC8vIOaXtumXtOmXtOmalOS4gOWumuimgeWkp+S6jjAsIOWQpuWImeiuoeeul+ayoeaEj+S5iVxuICAgICAgICAgICAgICAgIGlmIChpbnRlcnZhbFRpbWUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmV2TW92ZVBvaW50cyA9IF90aGlzLnByZXZNb3ZlUG9pbnRzIHx8IF90aGlzLnN0YXJ0UG9pbnRzO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGFzdE1vdmVQb2ludHMgPSBfdGhpcy5sYXN0TW92ZVBvaW50cztcbiAgICAgICAgICAgICAgICAgICAgLy8gbW92ZemAn+eOh1xuICAgICAgICAgICAgICAgICAgICB2YXIgdmVsb2NpdHkgPSBjYWxjRGlzdGFuY2UocHJldk1vdmVQb2ludHNbMF0sIGxhc3RNb3ZlUG9pbnRzWzBdKSAvIGludGVydmFsVGltZTtcbiAgICAgICAgICAgICAgICAgICAgLy8gMC4zIOaYr+WPguiAg2hhbW1lcmpz55qE6K6+572uXG4gICAgICAgICAgICAgICAgICAgIGlmICh2ZWxvY2l0eSA+IDAuMykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXYudmVsb2NpdHkgPSB2ZWxvY2l0eTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2LmRpcmVjdGlvbiA9IGNhbGNEaXJlY3Rpb24ocHJldk1vdmVQb2ludHNbMF0sIGxhc3RNb3ZlUG9pbnRzWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmVtaXRFdmVudCgnc3dpcGUnLCBldik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgdmFyIHRvdWNoZXMgPSBldi50b3VjaGVzO1xuICAgICAgICAgICAgLy8g5b2T5aSa5oyH5Y+q6YeK5pS+5LqGMeaMh+aXtuS5n+S8muinpuWPkWVuZCwg6L+Z5pe26YeN5paw6Kem5Y+R5LiA5qyhc3RhcnRcbiAgICAgICAgICAgIGlmICh0b3VjaGVzICYmIHRvdWNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIF90aGlzLnRvdWNoU3RhcnQoZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5jYW52YXMgPSB2aWV3LmdldENhbnZhcygpO1xuICAgICAgICBfdGhpcy5kZWxlZ2F0ZUV2ZW50KCk7XG4gICAgICAgIC8vIOeUqOadpeiusOW9leW9k+WJjeinpuWPkeeahOS6i+S7tlxuICAgICAgICBfdGhpcy5wcm9jZXNzRXZlbnQgPSB7fTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoR2VzdHVyZUNvbnRyb2xsZXIucHJvdG90eXBlLCBcIm5hbWVcIiwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiAnZ2VzdHVyZSc7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBHZXN0dXJlQ29udHJvbGxlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICBHZXN0dXJlQ29udHJvbGxlci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5sYXlvdXQgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgR2VzdHVyZUNvbnRyb2xsZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICBHZXN0dXJlQ29udHJvbGxlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICB0aGlzLm9mZkV2ZW50KCk7XG4gICAgICAgIHRoaXMucHJvY2Vzc0V2ZW50ID0gbnVsbDtcbiAgICB9O1xuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5kZWxlZ2F0ZUV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDku6PnkIbov5nlh6DkuKrkuovku7ZcbiAgICAgICAgdGhpcy5jYW52YXMub24oJ3RvdWNoc3RhcnQnLCB0aGlzLnRvdWNoU3RhcnQpO1xuICAgICAgICB0aGlzLmNhbnZhcy5vbigndG91Y2htb3ZlJywgdGhpcy50b3VjaE1vdmUpO1xuICAgICAgICB0aGlzLmNhbnZhcy5vbigndG91Y2hlbmQnLCB0aGlzLnRvdWNoRW5kKTtcbiAgICB9O1xuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5vZmZFdmVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jYW52YXMub2ZmKCd0b3VjaHN0YXJ0JywgdGhpcy50b3VjaFN0YXJ0KTtcbiAgICAgICAgdGhpcy5jYW52YXMub2ZmKCd0b3VjaG1vdmUnLCB0aGlzLnRvdWNoTW92ZSk7XG4gICAgICAgIHRoaXMuY2FudmFzLm9mZigndG91Y2hlbmQnLCB0aGlzLnRvdWNoRW5kKTtcbiAgICB9O1xuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5lbWl0RXZlbnQgPSBmdW5jdGlvbiAodHlwZSwgZXYpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZpZXcuZW1pdCh0eXBlLCBldik7XG4gICAgfTtcbiAgICAvLyDop6blj5FzdGFydOS6i+S7tlxuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5lbWl0U3RhcnQgPSBmdW5jdGlvbiAodHlwZSwgZXYpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNQcm9jZXNzKHR5cGUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbmFibGUodHlwZSk7XG4gICAgICAgIHRoaXMuZW1pdEV2ZW50KHR5cGUgKyBcInN0YXJ0XCIsIGV2KTtcbiAgICB9O1xuICAgIC8vIOinpuWPkWVuZOS6i+S7tlxuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5lbWl0RW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwcm9jZXNzRXZlbnQgPSB0aGlzLnByb2Nlc3NFdmVudDtcbiAgICAgICAgT2JqZWN0LmtleXMocHJvY2Vzc0V2ZW50KS5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgICAgICBfdGhpcy5lbWl0RXZlbnQodHlwZSArIFwiZW5kXCIsIGV2KTtcbiAgICAgICAgICAgIGRlbGV0ZSBwcm9jZXNzRXZlbnRbdHlwZV07XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgR2VzdHVyZUNvbnRyb2xsZXIucHJvdG90eXBlLmVuYWJsZSA9IGZ1bmN0aW9uIChldmVudFR5cGUpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzRXZlbnRbZXZlbnRUeXBlXSA9IHRydWU7XG4gICAgfTtcbiAgICAvLyDmmK/lkKbov5vooYzkuK3nmoTkuovku7ZcbiAgICBHZXN0dXJlQ29udHJvbGxlci5wcm90b3R5cGUuaXNQcm9jZXNzID0gZnVuY3Rpb24gKGV2ZW50VHlwZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzRXZlbnRbZXZlbnRUeXBlXTtcbiAgICB9O1xuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jbGVhclByZXNzVGltZW91dCgpO1xuICAgICAgICB0aGlzLnN0YXJ0VGltZSA9IDA7XG4gICAgICAgIHRoaXMuc3RhcnRQb2ludHMgPSBudWxsO1xuICAgICAgICB0aGlzLnN0YXJ0RGlzdGFuY2UgPSAwO1xuICAgICAgICB0aGlzLmRpcmVjdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMuZXZlbnRUeXBlID0gbnVsbDtcbiAgICAgICAgdGhpcy5wcmV2TW92ZVRpbWUgPSAwO1xuICAgICAgICB0aGlzLnByZXZNb3ZlUG9pbnRzID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0TW92ZVRpbWUgPSAwO1xuICAgICAgICB0aGlzLmxhc3RNb3ZlUG9pbnRzID0gbnVsbDtcbiAgICB9O1xuICAgIEdlc3R1cmVDb250cm9sbGVyLnByb3RvdHlwZS5jbGVhclByZXNzVGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucHJlc3NUaW1lb3V0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wcmVzc1RpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5wcmVzc1RpbWVvdXQgPSAwO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBHZXN0dXJlQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0RXZlbnRUeXBlID0gZnVuY3Rpb24gKHBvaW50cykge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBldmVudFR5cGUgPSBfYS5ldmVudFR5cGUsIHZpZXcgPSBfYS52aWV3LCBzdGFydFRpbWUgPSBfYS5zdGFydFRpbWUsIHN0YXJ0UG9pbnRzID0gX2Euc3RhcnRQb2ludHM7XG4gICAgICAgIGlmIChldmVudFR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudFR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGU7XG4gICAgICAgIHZhciBwYW5FdmVudExpc3RlbmVycyA9IHZpZXcuZ2V0RXZlbnRzKCkucGFuO1xuICAgICAgICAvLyDlpoLmnpwgdmlldyDkuIrmsqHmnIkgcGFuIOS6i+S7tueahOebkeWQrO+8jOm7mOiupOmDveaYryBwcmVzc1xuICAgICAgICBpZiAoIXBhbkV2ZW50TGlzdGVuZXJzIHx8ICFwYW5FdmVudExpc3RlbmVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHR5cGUgPSAncHJlc3MnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5aaC5p6c5pyJcGFu5LqL5Lu255qE5aSE55CG77yMcHJlc3PliJnpnIDopoHlgZzpob8yNTBtcywg5LiU56e75Yqo6Led56a75bCP5LqOMTBcbiAgICAgICAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgaWYgKG5vdyAtIHN0YXJ0VGltZSA+IFBSRVNTX0RFTEFZICYmIGNhbGNEaXN0YW5jZShzdGFydFBvaW50c1swXSwgcG9pbnRzWzBdKSA8IDEwKSB7XG4gICAgICAgICAgICAgICAgdHlwZSA9ICdwcmVzcyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ3Bhbic7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ldmVudFR5cGUgPSB0eXBlO1xuICAgICAgICByZXR1cm4gdHlwZTtcbiAgICB9O1xuICAgIHJldHVybiBHZXN0dXJlQ29udHJvbGxlcjtcbn0oYmFzZV8xLkNvbnRyb2xsZXIpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdlc3R1cmVDb250cm9sbGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2VzdHVyZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0Q29tcG9uZW50Q29udHJvbGxlciA9IGV4cG9ydHMuZ2V0Q29tcG9uZW50Q29udHJvbGxlck5hbWVzID0gZXhwb3J0cy51bnJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlciA9IGV4cG9ydHMucmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyID0gdm9pZCAwO1xudmFyIExPQURfQ09NUE9ORU5UX0NPTlRST0xMRVJTID0ge307XG4vKipcbiAqIOWFqOWxgOazqOWGjOe7hOS7tuOAglxuICogQHBhcmFtIG5hbWUg57uE5Lu25ZCN56ewXG4gKiBAcGFyYW0gcGx1Z2luIOazqOWGjOeahOe7hOS7tuexu1xuICogQHJldHVybnMgdm9pZFxuICovXG5mdW5jdGlvbiByZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXIobmFtZSwgcGx1Z2luKSB7XG4gICAgTE9BRF9DT01QT05FTlRfQ09OVFJPTExFUlNbbmFtZV0gPSBwbHVnaW47XG59XG5leHBvcnRzLnJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlciA9IHJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlcjtcbi8qKlxuICog5Yig6Zmk5YWo5bGA57uE5Lu244CCXG4gKiBAcGFyYW0gbmFtZSDnu4Tku7blkI1cbiAqIEByZXR1cm5zIHZvaWRcbiAqL1xuZnVuY3Rpb24gdW5yZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXIobmFtZSkge1xuICAgIGRlbGV0ZSBMT0FEX0NPTVBPTkVOVF9DT05UUk9MTEVSU1tuYW1lXTtcbn1cbmV4cG9ydHMudW5yZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXIgPSB1bnJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlcjtcbi8qKlxuICog6I635Y+W5Lul5rOo5YaM55qE57uE5Lu25ZCN44CCXG4gKiBAcmV0dXJucyBzdHJpbmdbXSDov5Tlm57lt7Lms6jlhoznmoTnu4Tku7blkI3np7BcbiAqL1xuZnVuY3Rpb24gZ2V0Q29tcG9uZW50Q29udHJvbGxlck5hbWVzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhMT0FEX0NPTVBPTkVOVF9DT05UUk9MTEVSUyk7XG59XG5leHBvcnRzLmdldENvbXBvbmVudENvbnRyb2xsZXJOYW1lcyA9IGdldENvbXBvbmVudENvbnRyb2xsZXJOYW1lcztcbi8qKlxuICog5qC55o2u57uE5Lu25ZCN6I635Y+W57uE5Lu257G744CCXG4gKiBAcGFyYW0gbmFtZSDnu4Tku7blkI1cbiAqIEByZXR1cm5zIOi/lOWbnue7hOS7tuexu1xuICovXG5mdW5jdGlvbiBnZXRDb21wb25lbnRDb250cm9sbGVyKG5hbWUpIHtcbiAgICByZXR1cm4gTE9BRF9DT01QT05FTlRfQ09OVFJPTExFUlNbbmFtZV07XG59XG5leHBvcnRzLmdldENvbXBvbmVudENvbnRyb2xsZXIgPSBnZXRDb21wb25lbnRDb250cm9sbGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uLy4uL2NvbnN0YW50XCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIGFuaW1hdGVfMSA9IHJlcXVpcmUoXCIuLi8uLi9hbmltYXRlXCIpO1xudmFyIGJib3hfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2Jib3hcIik7XG52YXIgZGlyZWN0aW9uXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9kaXJlY3Rpb25cIik7XG52YXIgaGVscGVyXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9oZWxwZXJcIik7XG52YXIgbGVnZW5kXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9sZWdlbmRcIik7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3NjYWxlXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG4vKipcbiAqIOS7jumFjee9ruS4reiOt+WPluWNleS4quWtl+auteeahCBsZWdlbmQg6YWN572uXG4gKiBAcGFyYW0gbGVnZW5kc1xuICogQHBhcmFtIGZpZWxkXG4gKiBAcmV0dXJucyB0aGUgb3B0aW9uIG9mIG9uZSBsZWdlbmQgZmllbGRcbiAqL1xuZnVuY3Rpb24gZ2V0TGVnZW5kT3B0aW9uKGxlZ2VuZHMsIGZpZWxkKSB7XG4gICAgaWYgKHV0aWxfMS5pc0Jvb2xlYW4obGVnZW5kcykpIHtcbiAgICAgICAgcmV0dXJuIGxlZ2VuZHMgPT09IGZhbHNlID8gZmFsc2UgOiB7fTtcbiAgICB9XG4gICAgcmV0dXJuIHV0aWxfMS5nZXQobGVnZW5kcywgW2ZpZWxkXSwgbGVnZW5kcyk7XG59XG5mdW5jdGlvbiBnZXREaXJlY3Rpb24obGVnZW5kT3B0aW9uKSB7XG4gICAgcmV0dXJuIHV0aWxfMS5nZXQobGVnZW5kT3B0aW9uLCAncG9zaXRpb24nLCBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT00pO1xufVxuLyoqXG4gKiBAaWdub3JlXG4gKiBsZWdlbmQgQ29udHJvbGxlclxuICovXG52YXIgTGVnZW5kID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExlZ2VuZCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMZWdlbmQodmlldykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB2aWV3KSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5jb250YWluZXIgPSBfdGhpcy52aWV3LmdldExheWVyKGNvbnN0YW50XzEuTEFZRVIuRk9SRSkuYWRkR3JvdXAoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTGVnZW5kLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2xlZ2VuZCc7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBMZWdlbmQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgLyoqXG4gICAgICogcmVuZGVyIHRoZSBsZWdlbmQgY29tcG9uZW50IGJ5IGxlZ2VuZCBvcHRpb25zXG4gICAgICovXG4gICAgTGVnZW5kLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMub3B0aW9uID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5sZWdlbmRzO1xuICAgICAgICB2YXIgZG9FYWNoTGVnZW5kID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSkge1xuICAgICAgICAgICAgdmFyIGxlZ2VuZCA9IF90aGlzLmNyZWF0ZUZpZWxkTGVnZW5kKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSk7XG4gICAgICAgICAgICBpZiAobGVnZW5kKSB7XG4gICAgICAgICAgICAgICAgbGVnZW5kLmNvbXBvbmVudC5pbml0KCk7XG4gICAgICAgICAgICAgICAgX3RoaXMuY29tcG9uZW50cy5wdXNoKGxlZ2VuZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8vIOWFqOWxgOiHquWumuS5ieWbvuS+i1xuICAgICAgICBpZiAodXRpbF8xLmdldCh0aGlzLm9wdGlvbiwgJ2N1c3RvbScpKSB7XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jcmVhdGVDdXN0b21MZWdlbmQodW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcy5vcHRpb24pO1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5pbml0KCk7XG4gICAgICAgICAgICAgICAgdmFyIGxheWVyID0gY29uc3RhbnRfMS5MQVlFUi5GT1JFO1xuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSBnZXREaXJlY3Rpb24odGhpcy5vcHRpb24pO1xuICAgICAgICAgICAgICAgIHRoaXMuY29tcG9uZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6ICdnbG9iYWwtY3VzdG9tJyxcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgIGxheWVyOiBsYXllcixcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuTEVHRU5ELFxuICAgICAgICAgICAgICAgICAgICBleHRyYTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g6YGN5Y6G5aSE55CG5q+P5LiA5Liq5Yib5bu66YC76L6RXG4gICAgICAgICAgICB0aGlzLmxvb3BMZWdlbmRzKGRvRWFjaExlZ2VuZCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGxheW91dCBsZWdlbmRcbiAgICAgKiDorqHnrpflh7ogbGVnZW5kIOeahCBkaXJlY3Rpb24g5L2N572uIHgsIHlcbiAgICAgKi9cbiAgICBMZWdlbmQucHJvdG90eXBlLmxheW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5sYXlvdXRCQm94ID0gdGhpcy52aWV3LnZpZXdCQm94O1xuICAgICAgICB2YXIgbWFyZ2luID0gdXRpbF8xLmdldCh0aGlzLnZpZXcuZ2V0VGhlbWUoKSwgWydjb21wb25lbnRzJywgJ2xlZ2VuZCcsICdtYXJnaW4nXSwgWzAsIDAsIDAsIDBdKTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5jb21wb25lbnRzLCBmdW5jdGlvbiAoY28pIHtcbiAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBjby5jb21wb25lbnQsIGRpcmVjdGlvbiA9IGNvLmRpcmVjdGlvbjtcbiAgICAgICAgICAgIHZhciBsYXlvdXQgPSBsZWdlbmRfMS5nZXRMZWdlbmRMYXlvdXQoZGlyZWN0aW9uKTtcbiAgICAgICAgICAgIHZhciBtYXhTaXplID0gX3RoaXMuZ2V0Q2F0ZWdvcnlMZWdlbmRTaXplQ2ZnKGxheW91dCk7XG4gICAgICAgICAgICB2YXIgbWF4V2lkdGggPSBjb21wb25lbnQuZ2V0KCdtYXhXaWR0aCcpO1xuICAgICAgICAgICAgdmFyIG1heEhlaWdodCA9IGNvbXBvbmVudC5nZXQoJ21heEhlaWdodCcpO1xuICAgICAgICAgICAgLy8g5YWI5pu05pawIG1heFNpemXvvIzmm7TmlrAgbGF5b3V0QkJveO+8jOS7peS+v+iuoeeul+ato+ehrueahCB4IHlcbiAgICAgICAgICAgIGNvbXBvbmVudC51cGRhdGUoe1xuICAgICAgICAgICAgICAgIG1heFdpZHRoOiBNYXRoLm1pbihtYXhTaXplLm1heFdpZHRoLCBtYXhXaWR0aCB8fCAwKSxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IE1hdGgubWluKG1heFNpemUubWF4SGVpZ2h0LCBtYXhIZWlnaHQgfHwgMCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBiYm94T2JqZWN0ID0gY29tcG9uZW50LmdldExheW91dEJCb3goKTsgLy8g6L+Z6YeM5Y+q6ZyA6KaB5LuW55qEIHdpZHRo44CBaGVpZ2h0IOS/oeaBr+WBmuS9jee9ruiwg+aVtFxuICAgICAgICAgICAgdmFyIGJib3ggPSBuZXcgYmJveF8xLkJCb3goYmJveE9iamVjdC54LCBiYm94T2JqZWN0LnksIGJib3hPYmplY3Qud2lkdGgsIGJib3hPYmplY3QuaGVpZ2h0KTtcbiAgICAgICAgICAgIHZhciBfYSA9IGRpcmVjdGlvbl8xLmRpcmVjdGlvblRvUG9zaXRpb24oX3RoaXMudmlldy52aWV3QkJveCwgYmJveCwgZGlyZWN0aW9uKSwgeDEgPSBfYVswXSwgeTEgPSBfYVsxXTtcbiAgICAgICAgICAgIHZhciBfYiA9IGRpcmVjdGlvbl8xLmRpcmVjdGlvblRvUG9zaXRpb24oX3RoaXMubGF5b3V0QkJveCwgYmJveCwgZGlyZWN0aW9uKSwgeDIgPSBfYlswXSwgeTIgPSBfYlsxXTtcbiAgICAgICAgICAgIHZhciB4ID0gMDtcbiAgICAgICAgICAgIHZhciB5ID0gMDtcbiAgICAgICAgICAgIC8vIOWboOS4uiBsZWdlbmQgeCB5IOimgeWSjCBjb29yZGluYXRlQkJveCDlr7npvZDvvIzmiYDku6XopoHlgZrkuIDkuKrnroDljZXnmoTliKTmlq1cbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb24uc3RhcnRzV2l0aCgndG9wJykgfHwgZGlyZWN0aW9uLnN0YXJ0c1dpdGgoJ2JvdHRvbScpKSB7XG4gICAgICAgICAgICAgICAgeCA9IHgxO1xuICAgICAgICAgICAgICAgIHkgPSB5MjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHggPSB4MjtcbiAgICAgICAgICAgICAgICB5ID0geTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDliqDkuIogbWFyZ2luXG4gICAgICAgICAgICBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ2xlZnQnKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgeCArPSBtYXJnaW5bM107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3JpZ2h0JykgPj0gMCkge1xuICAgICAgICAgICAgICAgIHggLT0gbWFyZ2luWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCd0b3AnKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgeSArPSBtYXJnaW5bMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ2JvdHRvbScpID49IDApIHtcbiAgICAgICAgICAgICAgICB5IC09IG1hcmdpblsyXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIOabtOaWsOS9jee9rlxuICAgICAgICAgICAgY29tcG9uZW50LnVwZGF0ZSh7XG4gICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBfdGhpcy5sYXlvdXRCQm94ID0gX3RoaXMubGF5b3V0QkJveC5jdXQoYmJveCwgZGlyZWN0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBsZWdlbmQg55qE5pu05paw6YC76L6RXG4gICAgICovXG4gICAgTGVnZW5kLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMub3B0aW9uID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5sZWdlbmRzO1xuICAgICAgICAvLyDlt7Lnu4/lpITnkIbov4fnmoQgbGVnZW5kXG4gICAgICAgIHZhciB1cGRhdGVkID0ge307XG4gICAgICAgIHZhciBlYWNoTGVnZW5kID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSkge1xuICAgICAgICAgICAgdmFyIGlkID0gX3RoaXMuZ2V0SWQoc2NhbGUuZmllbGQpO1xuICAgICAgICAgICAgdmFyIGV4aXN0Q28gPSBfdGhpcy5nZXRDb21wb25lbnRCeUlkKGlkKTtcbiAgICAgICAgICAgIC8vIOWtmOWcqOWImSB1cGRhdGVcbiAgICAgICAgICAgIGlmIChleGlzdENvKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNmZyA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICB2YXIgbGVnZW5kT3B0aW9uID0gZ2V0TGVnZW5kT3B0aW9uKF90aGlzLm9wdGlvbiwgc2NhbGUuZmllbGQpO1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBsZWdlbmQgb3B0aW9uIGlzIG5vdCBmYWxzZSwgbWVhbnMgbGVnZW5kIHNob3VsZCBiZSBjcmVhdGVkLlxuICAgICAgICAgICAgICAgIGlmIChsZWdlbmRPcHRpb24gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuZ2V0KGxlZ2VuZE9wdGlvbiwgJ2N1c3RvbScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjZmcgPSBfdGhpcy5nZXRDYXRlZ29yeUNmZyhnZW9tZXRyeSwgYXR0ciwgc2NhbGUsIGxlZ2VuZE9wdGlvbiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NhbGUuaXNMaW5lYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsaW5lYXIgZmllbGQsIGNyZWF0ZSBjb250aW51b3VzIGxlZ2VuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmZyA9IF90aGlzLmdldENvbnRpbnVvdXNDZmcoZ2VvbWV0cnksIGF0dHIsIHNjYWxlLCBsZWdlbmRPcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2NhbGUuaXNDYXRlZ29yeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhdGVnb3J5IGZpZWxkLCBjcmVhdGUgY2F0ZWdvcnkgbGVnZW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ZnID0gX3RoaXMuZ2V0Q2F0ZWdvcnlDZmcoZ2VvbWV0cnksIGF0dHIsIHNjYWxlLCBsZWdlbmRPcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOWmguaenCBjZmcg5Li656m677yM5YiZ5LiN5ZyoIHVwZGF0ZWQg5qCH6K6w77yM6YKj5LmI5Lya5Zyo5ZCO6Z2i6YC76L6R5Lit5Yig6ZmkXG4gICAgICAgICAgICAgICAgaWYgKGNmZykge1xuICAgICAgICAgICAgICAgICAgICAvLyBvbWl0IOaOieS4gOS6m+WxnuaAp++8jOavlOWmgiBjb250YWluZXIg562JXG4gICAgICAgICAgICAgICAgICAgIGhlbHBlcl8xLm9taXQoY2ZnLCBbJ2NvbnRhaW5lciddKTtcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RDby5kaXJlY3Rpb24gPSBnZXREaXJlY3Rpb24obGVnZW5kT3B0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RDby5jb21wb25lbnQudXBkYXRlKGNmZyk7XG4gICAgICAgICAgICAgICAgICAgIC8vIOagh+iusOS4uuaWsOeahFxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkW2lkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo5YiZIGNyZWF0ZVxuICAgICAgICAgICAgICAgIHZhciBsZWdlbmQgPSBfdGhpcy5jcmVhdGVGaWVsZExlZ2VuZChnZW9tZXRyeSwgYXR0ciwgc2NhbGUpO1xuICAgICAgICAgICAgICAgIGlmIChsZWdlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmNvbXBvbmVudC5pbml0KCk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNvbXBvbmVudHMucHVzaChsZWdlbmQpO1xuICAgICAgICAgICAgICAgICAgICAvLyDmoIforrDkuLrmlrDnmoRcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFtpZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgLy8g5YWo5bGA6Ieq5a6a5LmJ5Zu+5L6LXG4gICAgICAgIGlmICh1dGlsXzEuZ2V0KHRoaXMub3B0aW9uLCAnY3VzdG9tJykpIHtcbiAgICAgICAgICAgIHZhciBpZCA9ICdnbG9iYWwtY3VzdG9tJztcbiAgICAgICAgICAgIHZhciBleGlzdENvID0gdGhpcy5nZXRDb21wb25lbnRCeUlkKGlkKTtcbiAgICAgICAgICAgIGlmIChleGlzdENvKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1c3RvbUNmZyA9IHRoaXMuZ2V0Q2F0ZWdvcnlDZmcodW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcy5vcHRpb24sIHRydWUpO1xuICAgICAgICAgICAgICAgIGhlbHBlcl8xLm9taXQoY3VzdG9tQ2ZnLCBbJ2NvbnRhaW5lciddKTtcbiAgICAgICAgICAgICAgICBleGlzdENvLmNvbXBvbmVudC51cGRhdGUoY3VzdG9tQ2ZnKTtcbiAgICAgICAgICAgICAgICB1cGRhdGVkW2lkXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jcmVhdGVDdXN0b21MZWdlbmQodW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcy5vcHRpb24pO1xuICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50LmluaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxheWVyID0gY29uc3RhbnRfMS5MQVlFUi5GT1JFO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gZ2V0RGlyZWN0aW9uKHRoaXMub3B0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wb25lbnRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBsYXllcjogbGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IGRpcmVjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuTEVHRU5ELFxuICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmE6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIOagh+iusOS4uuabtOaWsFxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkW2lkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g6YGN5Y6G5aSE55CG5q+P5LiA5Liq5Yib5bu66YC76L6RXG4gICAgICAgICAgICB0aGlzLmxvb3BMZWdlbmRzKGVhY2hMZWdlbmQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWkhOeQhuWujOaIkOS5i+WQju+8jOmUgOavgeWIoOmZpOeahFxuICAgICAgICAvLyDkuI3lnKjlpITnkIbkuK3nmoRcbiAgICAgICAgdmFyIGNvbXBvbmVudHMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5nZXRDb21wb25lbnRzKCksIGZ1bmN0aW9uIChjbykge1xuICAgICAgICAgICAgaWYgKHVwZGF0ZWRbY28uaWRdKSB7XG4gICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKGNvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvLmNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDmm7TmlrDlvZPliY3lt7LmnInnmoQgY29tcG9uZW50c1xuICAgICAgICB0aGlzLmNvbXBvbmVudHMgPSBjb21wb25lbnRzO1xuICAgIH07XG4gICAgTGVnZW5kLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jbGVhci5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgIH07XG4gICAgTGVnZW5kLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKHRydWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6YCS5b2S6I635Y+W5omA5pyJ55qEIEdlb21ldHJ5XG4gICAgICovXG4gICAgTGVnZW5kLnByb3RvdHlwZS5nZXRHZW9tZXRyaWVzID0gZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB2aWV3Lmdlb21ldHJpZXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHZpZXcudmlld3MsIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICBnZW9tZXRyaWVzID0gZ2VvbWV0cmllcy5jb25jYXQoX3RoaXMuZ2V0R2VvbWV0cmllcyh2KSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZ2VvbWV0cmllcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOmBjeWOhiBHZW9tZXRyee+8jOWkhOeQhiBsZWdlbmQg6YC76L6RXG4gICAgICogQHBhcmFtIGRvRWFjaCDmr4/kuKogbG9vcCDkuK3nmoTlpITnkIbmlrnms5VcbiAgICAgKi9cbiAgICBMZWdlbmQucHJvdG90eXBlLmxvb3BMZWdlbmRzID0gZnVuY3Rpb24gKGRvRWFjaCkge1xuICAgICAgICB2YXIgaXNSb290VmlldyA9IHRoaXMudmlldy5nZXRSb290VmlldygpID09PSB0aGlzLnZpZXc7XG4gICAgICAgIC8vIOmdnuaguSB2aWV377yM5LiN5aSE55CGIGxlZ2VuZFxuICAgICAgICBpZiAoIWlzUm9vdFZpZXcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyDpgJLlvZIgdmlldyDkuK3miYDmnInnmoQgR2VvbWV0cnnvvIzov5vooYzliJvlu7ogbGVnZW5kXG4gICAgICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZXRHZW9tZXRyaWVzKHRoaXMudmlldyk7XG4gICAgICAgIHZhciBsb29wZWQgPSB7fTsgLy8g6Ziy5q2i5LiA5Liq5a2X5q615Yib5bu65Lik5LiqIGxlZ2VuZFxuICAgICAgICB1dGlsXzEuZWFjaChnZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gZ2VvbWV0cnkuZ2V0R3JvdXBBdHRyaWJ1dGVzKCk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChhdHRyaWJ1dGVzLCBmdW5jdGlvbiAoYXR0cikge1xuICAgICAgICAgICAgICAgIHZhciBzY2FsZSA9IGF0dHIuZ2V0U2NhbGUoYXR0ci50eXBlKTtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzlnKjop4bop4npgJrpgZPkuIrmmKDlsITluLjph4/lgLzvvIzlpoIgc2l6ZSgyKSBzaGFwZSgnY2lyY2xlJykg5LiN5Yib5bu6IGxlZ2VuZFxuICAgICAgICAgICAgICAgIGlmICghc2NhbGUgfHwgc2NhbGUudHlwZSA9PT0gJ2lkZW50aXR5JyB8fCBsb29wZWRbc2NhbGUuZmllbGRdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9FYWNoKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSk7XG4gICAgICAgICAgICAgICAgbG9vcGVkW3NjYWxlLmZpZWxkXSA9IHRydWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7rkuIDkuKogbGVnZW5kXG4gICAgICogQHBhcmFtIGdlb21ldHJ5XG4gICAgICogQHBhcmFtIGF0dHJcbiAgICAgKiBAcGFyYW0gc2NhbGVcbiAgICAgKi9cbiAgICBMZWdlbmQucHJvdG90eXBlLmNyZWF0ZUZpZWxkTGVnZW5kID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSkge1xuICAgICAgICB2YXIgY29tcG9uZW50O1xuICAgICAgICB2YXIgbGVnZW5kT3B0aW9uID0gZ2V0TGVnZW5kT3B0aW9uKHRoaXMub3B0aW9uLCBzY2FsZS5maWVsZCk7XG4gICAgICAgIHZhciBsYXllciA9IGNvbnN0YW50XzEuTEFZRVIuRk9SRTtcbiAgICAgICAgdmFyIGRpcmVjdGlvbiA9IGdldERpcmVjdGlvbihsZWdlbmRPcHRpb24pO1xuICAgICAgICAvLyBpZiB0aGUgbGVnZW5kIG9wdGlvbiBpcyBub3QgZmFsc2UsIG1lYW5zIGxlZ2VuZCBzaG91bGQgYmUgY3JlYXRlZC5cbiAgICAgICAgaWYgKGxlZ2VuZE9wdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuZ2V0KGxlZ2VuZE9wdGlvbiwgJ2N1c3RvbScpKSB7XG4gICAgICAgICAgICAgICAgY29tcG9uZW50ID0gdGhpcy5jcmVhdGVDdXN0b21MZWdlbmQoZ2VvbWV0cnksIGF0dHIsIHNjYWxlLCBsZWdlbmRPcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHNjYWxlLmlzTGluZWFyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxpbmVhciBmaWVsZCwgY3JlYXRlIGNvbnRpbnVvdXMgbGVnZW5kXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudCA9IHRoaXMuY3JlYXRlQ29udGludW91c0xlZ2VuZChnZW9tZXRyeSwgYXR0ciwgc2NhbGUsIGxlZ2VuZE9wdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNjYWxlLmlzQ2F0ZWdvcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY2F0ZWdvcnkgZmllbGQsIGNyZWF0ZSBjYXRlZ29yeSBsZWdlbmRcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50ID0gdGhpcy5jcmVhdGVDYXRlZ29yeUxlZ2VuZChnZW9tZXRyeSwgYXR0ciwgc2NhbGUsIGxlZ2VuZE9wdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGNvbXBvbmVudC5zZXQoJ2ZpZWxkJywgc2NhbGUuZmllbGQpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpZDogdGhpcy5nZXRJZChzY2FsZS5maWVsZCksXG4gICAgICAgICAgICAgICAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAgICAgICAgICAgbGF5ZXI6IGxheWVyLFxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogZGlyZWN0aW9uLFxuICAgICAgICAgICAgICAgIHR5cGU6IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuTEVHRU5ELFxuICAgICAgICAgICAgICAgIGV4dHJhOiB7IHNjYWxlOiBzY2FsZSB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6Ieq5a6a5LmJ5Zu+5L6L5L2/55SoIGNhdGVnb3J5IOWbvuS+i+WOu+a4suafk1xuICAgICAqIEBwYXJhbSBnZW9tZXRyeVxuICAgICAqIEBwYXJhbSBhdHRyXG4gICAgICogQHBhcmFtIHNjYWxlXG4gICAgICogQHBhcmFtIGxlZ2VuZE9wdGlvblxuICAgICAqL1xuICAgIExlZ2VuZC5wcm90b3R5cGUuY3JlYXRlQ3VzdG9tTGVnZW5kID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSwgbGVnZW5kT3B0aW9uKSB7XG4gICAgICAgIC8vIOebtOaOpeS9v+eUqCDliIbnsbvlm77kvovmuLLmn5NcbiAgICAgICAgdmFyIGNmZyA9IHRoaXMuZ2V0Q2F0ZWdvcnlDZmcoZ2VvbWV0cnksIGF0dHIsIHNjYWxlLCBsZWdlbmRPcHRpb24sIHRydWUpO1xuICAgICAgICByZXR1cm4gbmV3IGRlcGVuZGVudHNfMS5DYXRlZ29yeUxlZ2VuZChjZmcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu66L+e57ut5Zu+5L6LXG4gICAgICogQHBhcmFtIGdlb21ldHJ5XG4gICAgICogQHBhcmFtIGF0dHJcbiAgICAgKiBAcGFyYW0gc2NhbGVcbiAgICAgKiBAcGFyYW0gbGVnZW5kT3B0aW9uXG4gICAgICovXG4gICAgTGVnZW5kLnByb3RvdHlwZS5jcmVhdGVDb250aW51b3VzTGVnZW5kID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSwgbGVnZW5kT3B0aW9uKSB7XG4gICAgICAgIHZhciBjZmcgPSB0aGlzLmdldENvbnRpbnVvdXNDZmcoZ2VvbWV0cnksIGF0dHIsIHNjYWxlLCBsZWdlbmRPcHRpb24pO1xuICAgICAgICByZXR1cm4gbmV3IGRlcGVuZGVudHNfMS5Db250aW51b3VzTGVnZW5kKGNmZyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7rliIbnsbvlm77kvotcbiAgICAgKiBAcGFyYW0gZ2VvbWV0cnlcbiAgICAgKiBAcGFyYW0gYXR0clxuICAgICAqIEBwYXJhbSBzY2FsZVxuICAgICAqIEBwYXJhbSBsZWdlbmRPcHRpb25cbiAgICAgKi9cbiAgICBMZWdlbmQucHJvdG90eXBlLmNyZWF0ZUNhdGVnb3J5TGVnZW5kID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSwgbGVnZW5kT3B0aW9uKSB7XG4gICAgICAgIHZhciBjZmcgPSB0aGlzLmdldENhdGVnb3J5Q2ZnKGdlb21ldHJ5LCBhdHRyLCBzY2FsZSwgbGVnZW5kT3B0aW9uKTtcbiAgICAgICAgcmV0dXJuIG5ldyBkZXBlbmRlbnRzXzEuQ2F0ZWdvcnlMZWdlbmQoY2ZnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+W+l+i/nue7reWbvuS+i+eahOmFjee9rlxuICAgICAqIEBwYXJhbSBnZW9tZXRyeVxuICAgICAqIEBwYXJhbSBhdHRyXG4gICAgICogQHBhcmFtIHNjYWxlXG4gICAgICogQHBhcmFtIGxlZ2VuZE9wdGlvblxuICAgICAqL1xuICAgIExlZ2VuZC5wcm90b3R5cGUuZ2V0Q29udGludW91c0NmZyA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgYXR0ciwgc2NhbGUsIGxlZ2VuZE9wdGlvbikge1xuICAgICAgICB2YXIgdGlja3MgPSBzY2FsZS5nZXRUaWNrcygpO1xuICAgICAgICB2YXIgY29udGFpbk1pbiA9IHV0aWxfMS5maW5kKHRpY2tzLCBmdW5jdGlvbiAodGljaykgeyByZXR1cm4gdGljay52YWx1ZSA9PT0gMDsgfSk7XG4gICAgICAgIHZhciBjb250YWluTWF4ID0gdXRpbF8xLmZpbmQodGlja3MsIGZ1bmN0aW9uICh0aWNrKSB7IHJldHVybiB0aWNrLnZhbHVlID09PSAxOyB9KTtcbiAgICAgICAgdmFyIGl0ZW1zID0gdGlja3MubWFwKGZ1bmN0aW9uICh0aWNrKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB0aWNrLnZhbHVlLCB0aWNrVmFsdWUgPSB0aWNrLnRpY2tWYWx1ZTtcbiAgICAgICAgICAgIHZhciBhdHRyVmFsdWUgPSBhdHRyLm1hcHBpbmcoc2NhbGUuaW52ZXJ0KHZhbHVlKSkuam9pbignJyk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHZhbHVlOiB0aWNrVmFsdWUsXG4gICAgICAgICAgICAgICAgYXR0clZhbHVlOiBhdHRyVmFsdWUsXG4gICAgICAgICAgICAgICAgY29sb3I6IGF0dHJWYWx1ZSxcbiAgICAgICAgICAgICAgICBzY2FsZVZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWNvbnRhaW5NaW4pIHtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgIHZhbHVlOiBzY2FsZS5taW4sXG4gICAgICAgICAgICAgICAgYXR0clZhbHVlOiBhdHRyLm1hcHBpbmcoc2NhbGUuaW52ZXJ0KDApKS5qb2luKCcnKSxcbiAgICAgICAgICAgICAgICBjb2xvcjogYXR0ci5tYXBwaW5nKHNjYWxlLmludmVydCgwKSkuam9pbignJyksXG4gICAgICAgICAgICAgICAgc2NhbGVWYWx1ZTogMCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29udGFpbk1heCkge1xuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHNjYWxlLm1heCxcbiAgICAgICAgICAgICAgICBhdHRyVmFsdWU6IGF0dHIubWFwcGluZyhzY2FsZS5pbnZlcnQoMSkpLmpvaW4oJycpLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBhdHRyLm1hcHBpbmcoc2NhbGUuaW52ZXJ0KDEpKS5qb2luKCcnKSxcbiAgICAgICAgICAgICAgICBzY2FsZVZhbHVlOiAxLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5o6S5bqPXG4gICAgICAgIGl0ZW1zLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEudmFsdWUgLSBiLnZhbHVlOyB9KTtcbiAgICAgICAgLy8g6LefIGF0dHIg55u45YWz55qE6YWN572uXG4gICAgICAgIC8vIHNpemUgY29sb3Ig5Yy65Yir55qE6YWN572uXG4gICAgICAgIHZhciBhdHRyTGVnZW5kQ2ZnID0ge1xuICAgICAgICAgICAgbWluOiB1dGlsXzEuaGVhZChpdGVtcykudmFsdWUsXG4gICAgICAgICAgICBtYXg6IHV0aWxfMS5sYXN0KGl0ZW1zKS52YWx1ZSxcbiAgICAgICAgICAgIGNvbG9yczogW10sXG4gICAgICAgICAgICByYWlsOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogYXR0ci50eXBlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyYWNrOiB7fSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGF0dHIudHlwZSA9PT0gJ3NpemUnKSB7XG4gICAgICAgICAgICBhdHRyTGVnZW5kQ2ZnLnRyYWNrID0ge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNpemUg55qE6YCJ5Lit5YmN5pmv6Imy77yM5a+55LqOIGNvbG9y77yM5YiZ55u05o6l5L2/55SoIGNvbG9yIOagh+ivhlxuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IGF0dHIudHlwZSA9PT0gJ3NpemUnID8gdGhpcy52aWV3LmdldFRoZW1lKCkuZGVmYXVsdENvbG9yIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChhdHRyLnR5cGUgPT09ICdjb2xvcicpIHtcbiAgICAgICAgICAgIGF0dHJMZWdlbmRDZmcuY29sb3JzID0gaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtLmF0dHJWYWx1ZTsgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICAvLyBpZiBwb3NpdGlvbiBpcyBub3Qgc2V0LCB1c2UgdG9wIGFzIGRlZmF1bHRcbiAgICAgICAgdmFyIGRpcmVjdGlvbiA9IGdldERpcmVjdGlvbihsZWdlbmRPcHRpb24pO1xuICAgICAgICB2YXIgbGF5b3V0ID0gbGVnZW5kXzEuZ2V0TGVnZW5kTGF5b3V0KGRpcmVjdGlvbik7XG4gICAgICAgIHZhciB0aXRsZSA9IHV0aWxfMS5nZXQobGVnZW5kT3B0aW9uLCAndGl0bGUnKTtcbiAgICAgICAgaWYgKHRpdGxlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBzY2FsZV8xLmdldE5hbWUoc2NhbGUpLFxuICAgICAgICAgICAgfSwgdGl0bGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWfuuehgOmFjee9ru+8jOS7juW9k+WJjeaVsOaNruS4reivu+WIsOeahOmFjee9rlxuICAgICAgICBhdHRyTGVnZW5kQ2ZnLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgYXR0ckxlZ2VuZENmZy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgICAgIGF0dHJMZWdlbmRDZmcudGl0bGUgPSB0aXRsZTtcbiAgICAgICAgYXR0ckxlZ2VuZENmZy5hbmltYXRlT3B0aW9uID0gYW5pbWF0ZV8xLkRFRkFVTFRfQU5JTUFURV9DRkc7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHRoaXMubWVyZ2VMZWdlbmRDZmcoYXR0ckxlZ2VuZENmZywgbGVnZW5kT3B0aW9uLCAnY29udGludW91cycpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5YiG57G75Zu+5L6L55qE6YWN572u6aG5XG4gICAgICogQHBhcmFtIGdlb21ldHJ5XG4gICAgICogQHBhcmFtIGF0dHJcbiAgICAgKiBAcGFyYW0gc2NhbGVcbiAgICAgKiBAcGFyYW0gY3VzdG9tXG4gICAgICogQHBhcmFtIGxlZ2VuZE9wdGlvblxuICAgICAqL1xuICAgIExlZ2VuZC5wcm90b3R5cGUuZ2V0Q2F0ZWdvcnlDZmcgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGF0dHIsIHNjYWxlLCBsZWdlbmRPcHRpb24sIGN1c3RvbSkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XG4gICAgICAgIC8vIGlmIHBvc2l0aW9uIGlzIG5vdCBzZXQsIHVzZSB0b3AgYXMgZGVmYXVsdFxuICAgICAgICB2YXIgZGlyZWN0aW9uID0gdXRpbF8xLmdldChsZWdlbmRPcHRpb24sICdwb3NpdGlvbicsIGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTSk7XG4gICAgICAgIC8vIHRoZSBkZWZhdWx0IG1hcmtlciBzdHlsZVxuICAgICAgICB2YXIgdGhlbWVNYXJrZXIgPSB1dGlsXzEuZ2V0KHRoaXMudmlldy5nZXRUaGVtZSgpLCBbJ2NvbXBvbmVudHMnLCAnbGVnZW5kJywgZGlyZWN0aW9uLCAnbWFya2VyJ10pO1xuICAgICAgICB2YXIgdXNlck1hcmtlciA9IHV0aWxfMS5nZXQobGVnZW5kT3B0aW9uLCAnbWFya2VyJyk7XG4gICAgICAgIHZhciBsYXlvdXQgPSBsZWdlbmRfMS5nZXRMZWdlbmRMYXlvdXQoZGlyZWN0aW9uKTtcbiAgICAgICAgdmFyIGl0ZW1zID0gY3VzdG9tXG4gICAgICAgICAgICA/IGxlZ2VuZF8xLmdldEN1c3RvbUxlZ2VuZEl0ZW1zKHRoZW1lTWFya2VyLCB1c2VyTWFya2VyLCBsZWdlbmRPcHRpb24uaXRlbXMpXG4gICAgICAgICAgICA6IGxlZ2VuZF8xLmdldExlZ2VuZEl0ZW1zKHRoaXMudmlldywgZ2VvbWV0cnksIGF0dHIsIHRoZW1lTWFya2VyLCB1c2VyTWFya2VyKTtcbiAgICAgICAgdmFyIHRpdGxlID0gdXRpbF8xLmdldChsZWdlbmRPcHRpb24sICd0aXRsZScpO1xuICAgICAgICBpZiAodGl0bGUpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdXRpbF8xLmRlZXBNaXgoe1xuICAgICAgICAgICAgICAgIHRleHQ6IHNjYWxlID8gc2NhbGVfMS5nZXROYW1lKHNjYWxlKSA6ICcnLFxuICAgICAgICAgICAgfSwgdGl0bGUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiYXNlQ2ZnID0gdGhpcy5nZXRDYXRlZ29yeUxlZ2VuZFNpemVDZmcobGF5b3V0KTtcbiAgICAgICAgYmFzZUNmZy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICAgIGJhc2VDZmcubGF5b3V0ID0gbGF5b3V0O1xuICAgICAgICBiYXNlQ2ZnLml0ZW1zID0gaXRlbXM7XG4gICAgICAgIGJhc2VDZmcudGl0bGUgPSB0aXRsZTtcbiAgICAgICAgYmFzZUNmZy5hbmltYXRlT3B0aW9uID0gYW5pbWF0ZV8xLkRFRkFVTFRfQU5JTUFURV9DRkc7XG4gICAgICAgIHZhciBjYXRlZ29yeUNmZyA9IHRoaXMubWVyZ2VMZWdlbmRDZmcoYmFzZUNmZywgbGVnZW5kT3B0aW9uLCBkaXJlY3Rpb24pO1xuICAgICAgICBpZiAoY2F0ZWdvcnlDZmcucmV2ZXJzZWQpIHtcbiAgICAgICAgICAgIC8vIOWbvuS+i+mhuemcgOimgemAhuW6j1xuICAgICAgICAgICAgY2F0ZWdvcnlDZmcuaXRlbXMucmV2ZXJzZSgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYXhJdGVtV2lkdGggPSB1dGlsXzEuZ2V0KGNhdGVnb3J5Q2ZnLCAnbWF4SXRlbVdpZHRoJyk7XG4gICAgICAgIGlmIChtYXhJdGVtV2lkdGggJiYgbWF4SXRlbVdpZHRoIDw9IDEpIHtcbiAgICAgICAgICAgIC8vIOi9rOaNouaIkOWDj+e0oOWAvFxuICAgICAgICAgICAgY2F0ZWdvcnlDZmcubWF4SXRlbVdpZHRoID0gdGhpcy52aWV3LnZpZXdCQm94LndpZHRoICogbWF4SXRlbVdpZHRoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYXRlZ29yeUNmZztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGdldCBsZWdlbmQgY29uZmlnLCB1c2Ugb3B0aW9uID4gc3VnZ2VzdGlvbiA+IHRoZW1lXG4gICAgICogQHBhcmFtIGJhc2VDZmdcbiAgICAgKiBAcGFyYW0gbGVnZW5kT3B0aW9uXG4gICAgICogQHBhcmFtIGRpcmVjdGlvblxuICAgICAqL1xuICAgIExlZ2VuZC5wcm90b3R5cGUubWVyZ2VMZWdlbmRDZmcgPSBmdW5jdGlvbiAoYmFzZUNmZywgbGVnZW5kT3B0aW9uLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gZGlyZWN0aW9uLnNwbGl0KCctJylbMF07XG4gICAgICAgIHZhciB0aGVtZU9iamVjdCA9IHV0aWxfMS5nZXQodGhpcy52aWV3LmdldFRoZW1lKCksIFsnY29tcG9uZW50cycsICdsZWdlbmQnLCBwb3NpdGlvbl0sIHt9KTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCB0aGVtZU9iamVjdCwgYmFzZUNmZywgbGVnZW5kT3B0aW9uKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOeUn+aIkCBpZFxuICAgICAqIEBwYXJhbSBrZXlcbiAgICAgKi9cbiAgICBMZWdlbmQucHJvdG90eXBlLmdldElkID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lICsgXCItXCIgKyBrZXk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmoLnmja4gaWQg5p2l6I635Y+W57uE5Lu2XG4gICAgICogQHBhcmFtIGlkXG4gICAgICovXG4gICAgTGVnZW5kLnByb3RvdHlwZS5nZXRDb21wb25lbnRCeUlkID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmluZCh0aGlzLmNvbXBvbmVudHMsIGZ1bmN0aW9uIChjbykgeyByZXR1cm4gY28uaWQgPT09IGlkOyB9KTtcbiAgICB9O1xuICAgIExlZ2VuZC5wcm90b3R5cGUuZ2V0Q2F0ZWdvcnlMZWdlbmRTaXplQ2ZnID0gZnVuY3Rpb24gKGxheW91dCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLnZpZXcudmlld0JCb3gsIHZ3ID0gX2Eud2lkdGgsIHZoID0gX2EuaGVpZ2h0O1xuICAgICAgICAvLyDnm67liY0gbGVnZW5kIOeahOW4g+WxgOaYr+S7pSB2aWV3QkJveCDkuLrlj4LnhadcbiAgICAgICAgLy8gY29uc3QgeyB3aWR0aDogY3csIGhlaWdodDogY2ggfSA9IHRoaXMudmlldy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgcmV0dXJuIGxheW91dCA9PT0gJ3ZlcnRpY2FsJ1xuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHZ3ICogY29uc3RhbnRfMS5DT01QT05FTlRfTUFYX1ZJRVdfUEVSQ0VOVEFHRSxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHZoLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IHZ3LFxuICAgICAgICAgICAgICAgIG1heEhlaWdodDogdmggKiBjb25zdGFudF8xLkNPTVBPTkVOVF9NQVhfVklFV19QRVJDRU5UQUdFLFxuICAgICAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBMZWdlbmQ7XG59KGJhc2VfMS5Db250cm9sbGVyKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMZWdlbmQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sZWdlbmQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uLy4uL2NvbnN0YW50XCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIGJib3hfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2Jib3hcIik7XG52YXIgZGlyZWN0aW9uXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9kaXJlY3Rpb25cIik7XG52YXIgaGVscGVyXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9oZWxwZXJcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbi8qKlxuICogQGlnbm9yZVxuICogc2xpZGVyIENvbnRyb2xsZXJcbiAqL1xudmFyIFNsaWRlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTbGlkZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2xpZGVyKHZpZXcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdmlldykgfHwgdGhpcztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOa7keWdl+a7keWKqOeahOaXtuWAmeWHuuWPkVxuICAgICAgICAgKiBAcGFyYW0gdlxuICAgICAgICAgKi9cbiAgICAgICAgX3RoaXMub25WYWx1ZUNoYW5nZWQgPSBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgdmFyIG1pbiA9IHZbMF0sIG1heCA9IHZbMV07XG4gICAgICAgICAgICBfdGhpcy51cGRhdGVNaW5NYXhUZXh0KG1pbiwgbWF4KTtcbiAgICAgICAgICAgIF90aGlzLnZpZXcucmVuZGVyKHRydWUpO1xuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5jb250YWluZXIgPSBfdGhpcy52aWV3LmdldExheWVyKGNvbnN0YW50XzEuTEFZRVIuRk9SRSkuYWRkR3JvdXAoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU2xpZGVyLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3NsaWRlcic7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICAvKipcbiAgICAgKiDliJ3lp4vljJZcbiAgICAgKi9cbiAgICBTbGlkZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgLyoqXG4gICAgICog5riy5p+TXG4gICAgICovXG4gICAgU2xpZGVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3B0aW9uID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5zbGlkZXI7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbikge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2xpZGVyKSB7XG4gICAgICAgICAgICAgICAgLy8gZXhpc3QsIHVwZGF0ZVxuICAgICAgICAgICAgICAgIHRoaXMuc2xpZGVyID0gdGhpcy51cGRhdGVTbGlkZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIG5vdCBleGlzdCwgY3JlYXRlXG4gICAgICAgICAgICAgICAgdGhpcy5zbGlkZXIgPSB0aGlzLmNyZWF0ZVNsaWRlcigpO1xuICAgICAgICAgICAgICAgIC8vIOebkeWQrOS6i+S7tu+8jOe7keWumuS6pOS6klxuICAgICAgICAgICAgICAgIHRoaXMuc2xpZGVyLmNvbXBvbmVudC5vbignc2xpZGVyY2hhbmdlJywgdGhpcy5vblZhbHVlQ2hhbmdlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBjaGFuZ2VEYXRhIOeahOaXtuWAmeWQjOagt+mcgOimgeabtOaWsFxuICAgICAgICAgICAgLy8g6K6+572u5Yid5aeL55qEIHRleHRcbiAgICAgICAgICAgIHZhciBtaW4gPSB0aGlzLnNsaWRlci5jb21wb25lbnQuZ2V0KCdzdGFydCcpIHx8IDA7XG4gICAgICAgICAgICB2YXIgbWF4ID0gdGhpcy5zbGlkZXIuY29tcG9uZW50LmdldCgnZW5kJykgfHwgMTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTWluTWF4VGV4dChtaW4sIG1heCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zbGlkZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBleGlzdCwgZGVzdHJveVxuICAgICAgICAgICAgICAgIHRoaXMuc2xpZGVyLmNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zbGlkZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOW4g+WxgFxuICAgICAqL1xuICAgIFNsaWRlci5wcm90b3R5cGUubGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5zbGlkZXIpIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IHRoaXMudmlldy5jb29yZGluYXRlQkJveC53aWR0aDtcbiAgICAgICAgICAgIC8vIOiOt+WPlue7hOS7tueahCBsYXlvdXQgYmJveFxuICAgICAgICAgICAgdmFyIGJib3hPYmplY3QgPSB0aGlzLnNsaWRlci5jb21wb25lbnQuZ2V0TGF5b3V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIGJib3ggPSBuZXcgYmJveF8xLkJCb3goYmJveE9iamVjdC54LCBiYm94T2JqZWN0LnksIE1hdGgubWluKGJib3hPYmplY3Qud2lkdGgsIHdpZHRoKSwgYmJveE9iamVjdC5oZWlnaHQpO1xuICAgICAgICAgICAgdmFyIF9hID0gZGlyZWN0aW9uXzEuZGlyZWN0aW9uVG9Qb3NpdGlvbih0aGlzLnZpZXcudmlld0JCb3gsIGJib3gsIGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTSksIHgxID0gX2FbMF0sIHkxID0gX2FbMV07XG4gICAgICAgICAgICB2YXIgX2IgPSBkaXJlY3Rpb25fMS5kaXJlY3Rpb25Ub1Bvc2l0aW9uKHRoaXMudmlldy5jb29yZGluYXRlQkJveCwgYmJveCwgY29uc3RhbnRfMS5ESVJFQ1RJT04uQk9UVE9NKSwgeDIgPSBfYlswXSwgeTIgPSBfYlsxXTtcbiAgICAgICAgICAgIC8vIOm7mOiupOaUvuWcqCBib3R0b21cbiAgICAgICAgICAgIHRoaXMuc2xpZGVyLmNvbXBvbmVudC51cGRhdGUoe1xuICAgICAgICAgICAgICAgIHg6IHgyLFxuICAgICAgICAgICAgICAgIHk6IHkxLFxuICAgICAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrBcbiAgICAgKi9cbiAgICBTbGlkZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g6YC76L6R5ZKMIHJlbmRlciDkv53mjIHkuIDoh7RcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWIm+W7uiBzbGlkZXIg57uE5Lu2XG4gICAgICovXG4gICAgU2xpZGVyLnByb3RvdHlwZS5jcmVhdGVTbGlkZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSB0aGlzLmdldFNsaWRlckNmZygpO1xuICAgICAgICAvLyDmt7vliqAgc2xpZGVyIOe7hOS7tlxuICAgICAgICB2YXIgY29tcG9uZW50ID0gbmV3IGRlcGVuZGVudHNfMS5TbGlkZXIodHNsaWJfMS5fX2Fzc2lnbih7IGNvbnRhaW5lcjogdGhpcy5jb250YWluZXIgfSwgY2ZnKSk7XG4gICAgICAgIGNvbXBvbmVudC5pbml0KCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb21wb25lbnQ6IGNvbXBvbmVudCxcbiAgICAgICAgICAgIGxheWVyOiBjb25zdGFudF8xLkxBWUVSLkZPUkUsXG4gICAgICAgICAgICBkaXJlY3Rpb246IGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTSxcbiAgICAgICAgICAgIHR5cGU6IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuT1RIRVIsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrDphY3nva5cbiAgICAgKi9cbiAgICBTbGlkZXIucHJvdG90eXBlLnVwZGF0ZVNsaWRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNmZyA9IHRoaXMuZ2V0U2xpZGVyQ2ZnKCk7XG4gICAgICAgIGhlbHBlcl8xLm9taXQoY2ZnLCBbJ3gnLCAneScsICd3aWR0aCcsICdzdGFydCcsICdlbmQnLCAnbWluVGV4dCcsICdtYXhUZXh0J10pO1xuICAgICAgICB0aGlzLnNsaWRlci5jb21wb25lbnQudXBkYXRlKGNmZyk7XG4gICAgICAgIHJldHVybiB0aGlzLnNsaWRlcjtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOeUn+aIkCBzbGlkZXIg6YWN572uXG4gICAgICovXG4gICAgU2xpZGVyLnByb3RvdHlwZS5nZXRTbGlkZXJDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh1dGlsXzEuaXNPYmplY3QodGhpcy5vcHRpb24pKSB7XG4gICAgICAgICAgICAvLyDnlKjmiLfphY3nva7nmoTmlbDmja7vvIzkvJjlhYjnuqfmm7Tpq5hcbiAgICAgICAgICAgIHZhciB0cmVuZENmZyA9IHRzbGliXzEuX19hc3NpZ24oeyBkYXRhOiB0aGlzLmdldERhdGEoKSB9LCB1dGlsXzEuZ2V0KHRoaXMub3B0aW9uLCAndHJlbmRDZmcnLCB7fSkpO1xuICAgICAgICAgICAgLy8g5Yid5aeL55qE5L2N572u5aSn5bCP5L+h5oGvXG4gICAgICAgICAgICB2YXIgeCA9IDA7XG4gICAgICAgICAgICB2YXIgeSA9IDA7XG4gICAgICAgICAgICB2YXIgd2lkdGggPSB0aGlzLnZpZXcuY29vcmRpbmF0ZUJCb3gud2lkdGg7XG4gICAgICAgICAgICAvLyDlm6DkuLrmnInmoLflvI/vvIzmiYDku6Xmt7HlsYLopobnm5ZcbiAgICAgICAgICAgIHZhciBjZmcgPSB1dGlsXzEuZGVlcE1peCh7fSwgeyB4OiB4LCB5OiB5LCB3aWR0aDogd2lkdGggfSwgdGhpcy5vcHRpb24pO1xuICAgICAgICAgICAgLy8gdHJlbmRDZmcg5Zug5Li65pyJ5pWw5o2u5pWw57uE77yM5omA5Lul5L2/55So5rWF5pu/5o2iXG4gICAgICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IHRyZW5kQ2ZnOiB0cmVuZENmZyB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge307XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDku44gdmlldyDkuK3ojrflj5bmlbDmja7vvIznvKnnlaXovbTkvb/nlKjlhajph4/nmoTmlbDmja5cbiAgICAgKi9cbiAgICBTbGlkZXIucHJvdG90eXBlLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5kYXRhO1xuICAgICAgICB2YXIgeVNjYWxlID0gdGhpcy52aWV3LmdldFlTY2FsZXMoKVswXTtcbiAgICAgICAgdmFyIGdyb3VwU2NhbGVzID0gdGhpcy52aWV3LmdldEdyb3VwU2NhbGVzKCk7XG4gICAgICAgIGlmIChncm91cFNjYWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IGdyb3VwU2NhbGVzWzBdLCBmaWVsZF8xID0gX2EuZmllbGQsIHRpY2tzXzEgPSBfYS50aWNrcztcbiAgICAgICAgICAgIHJldHVybiBkYXRhLnJlZHVjZShmdW5jdGlvbiAocHJlLCBjdXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VyW2ZpZWxkXzFdID09PSB0aWNrc18xWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZS5wdXNoKGN1clt5U2NhbGUuZmllbGRdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByZTtcbiAgICAgICAgICAgIH0sIFtdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YS5tYXAoZnVuY3Rpb24gKGRhdHVtKSB7IHJldHVybiBkYXR1bVt5U2NhbGUuZmllbGRdIHx8IDA7IH0pO1xuICAgIH07XG4gICAgU2xpZGVyLnByb3RvdHlwZS51cGRhdGVNaW5NYXhUZXh0ID0gZnVuY3Rpb24gKG1pbiwgbWF4KSB7XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5kYXRhO1xuICAgICAgICB2YXIgeFNjYWxlID0gdGhpcy52aWV3LmdldFhTY2FsZSgpO1xuICAgICAgICB2YXIgZGF0YVNpemUgPSB1dGlsXzEuc2l6ZShkYXRhKTtcbiAgICAgICAgaWYgKCF4U2NhbGUgfHwgIWRhdGFTaXplKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHggPSB4U2NhbGUuZmllbGQ7XG4gICAgICAgIC8vIHgg6L205Yi75bqmXG4gICAgICAgIHZhciB4VGlja3MgPSBkYXRhLnJlZHVjZShmdW5jdGlvbiAocHJlLCBkYXR1bSkge1xuICAgICAgICAgICAgaWYgKCFwcmUuaW5jbHVkZXMoZGF0dW1beF0pKVxuICAgICAgICAgICAgICAgIHByZS5wdXNoKGRhdHVtW3hdKTtcbiAgICAgICAgICAgIHJldHVybiBwcmU7XG4gICAgICAgIH0sIFtdKTtcbiAgICAgICAgdmFyIHhUaWNrQ291bnQgPSB1dGlsXzEuc2l6ZSh4VGlja3MpO1xuICAgICAgICB2YXIgbWluSW5kZXggPSBNYXRoLmZsb29yKG1pbiAqICh4VGlja0NvdW50IC0gMSkpO1xuICAgICAgICB2YXIgbWF4SW5kZXggPSBNYXRoLmZsb29yKG1heCAqICh4VGlja0NvdW50IC0gMSkpO1xuICAgICAgICB2YXIgbWluVGV4dCA9IHV0aWxfMS5nZXQoeFRpY2tzLCBbbWluSW5kZXhdKTtcbiAgICAgICAgdmFyIG1heFRleHQgPSB1dGlsXzEuZ2V0KHhUaWNrcywgW21heEluZGV4XSk7XG4gICAgICAgIHZhciBmb3JtYXR0ZXIgPSB0aGlzLmdldFNsaWRlckNmZygpLmZvcm1hdHRlcjtcbiAgICAgICAgaWYgKGZvcm1hdHRlcikge1xuICAgICAgICAgICAgbWluVGV4dCA9IGZvcm1hdHRlcihtaW5UZXh0LCBkYXRhW21pbkluZGV4XSwgbWluSW5kZXgpO1xuICAgICAgICAgICAgbWF4VGV4dCA9IGZvcm1hdHRlcihtYXhUZXh0LCBkYXRhW21heEluZGV4XSwgbWF4SW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOabtOaWsOaWh+acrFxuICAgICAgICB0aGlzLnNsaWRlci5jb21wb25lbnQudXBkYXRlKHtcbiAgICAgICAgICAgIG1pblRleHQ6IG1pblRleHQsXG4gICAgICAgICAgICBtYXhUZXh0OiBtYXhUZXh0LFxuICAgICAgICAgICAgc3RhcnQ6IG1pbixcbiAgICAgICAgICAgIGVuZDogbWF4LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8g5aKe5YqgIHgg6L2055qE6L+H5ruk5ZmoXG4gICAgICAgIHRoaXMudmlldy5maWx0ZXIoeFNjYWxlLmZpZWxkLCBmdW5jdGlvbiAodmFsdWUsIGRhdHVtKSB7XG4gICAgICAgICAgICB2YXIgaWR4ID0geFRpY2tzLmluZGV4T2YodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIGlkeCA+IC0xID8gaGVscGVyXzEuaXNCZXR3ZWVuKGlkeCwgbWluSW5kZXgsIG1heEluZGV4KSA6IHRydWU7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6KaG5YaZ54i257G75pa55rOVXG4gICAgICovXG4gICAgU2xpZGVyLnByb3RvdHlwZS5nZXRDb21wb25lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zbGlkZXIgPyBbdGhpcy5zbGlkZXJdIDogW107XG4gICAgfTtcbiAgICByZXR1cm4gU2xpZGVyO1xufShiYXNlXzEuQ29udHJvbGxlcikpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU2xpZGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2xpZGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgY29vcmRpbmF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvY29vcmRpbmF0ZVwiKTtcbnZhciBncmFwaGljc18xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZ3JhcGhpY3NcIik7XG52YXIgdG9vbHRpcF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvdG9vbHRpcFwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuLy8gRmlsdGVyIGR1cGxpY2F0ZXMsIHVzZSBgbmFtZWAsIGBjb2xvcmAsIGB2YWx1ZWAgYW5kIGB0aXRsZWAgcHJvcGVydHkgdmFsdWVzIGFzIGNvbmRpdGlvblxuZnVuY3Rpb24gdW5pcShpdGVtcykge1xuICAgIHZhciB1bmlxSXRlbXMgPSBbXTtcbiAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICB2YXIgaXRlbSA9IGl0ZW1zW2luZGV4XTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHV0aWxfMS5maW5kKHVuaXFJdGVtcywgZnVuY3Rpb24gKHN1Ykl0ZW0pIHtcbiAgICAgICAgICAgIHJldHVybiAoc3ViSXRlbS5jb2xvciA9PT0gaXRlbS5jb2xvciAmJlxuICAgICAgICAgICAgICAgIHN1Ykl0ZW0ubmFtZSA9PT0gaXRlbS5uYW1lICYmXG4gICAgICAgICAgICAgICAgc3ViSXRlbS52YWx1ZSA9PT0gaXRlbS52YWx1ZSAmJlxuICAgICAgICAgICAgICAgIHN1Ykl0ZW0udGl0bGUgPT09IGl0ZW0udGl0bGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgIHVuaXFJdGVtcy5wdXNoKGl0ZW0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIF9sb29wXzEoaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gdW5pcUl0ZW1zO1xufVxuLyoqIEBpZ25vcmUgKi9cbnZhciBUb29sdGlwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFRvb2x0aXAsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVG9vbHRpcCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmlzTG9ja2VkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvb2x0aXAucHJvdG90eXBlLCBcIm5hbWVcIiwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiAndG9vbHRpcCc7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIFRvb2x0aXAucHJvdG90eXBlLmlzVmlzaWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbiA9IHRoaXMudmlldy5nZXRPcHRpb25zKCkudG9vbHRpcDtcbiAgICAgICAgcmV0dXJuIG9wdGlvbiAhPT0gZmFsc2U7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgLyoqXG4gICAgICogU2hvd3MgdG9vbHRpcFxuICAgICAqIEBwYXJhbSBwb2ludFxuICAgICAqL1xuICAgIFRvb2x0aXAucHJvdG90eXBlLnNob3dUb29sdGlwID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHRoaXMucG9pbnQgPSBwb2ludDtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmlzaWJsZSgpKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzorr7nva4gdG9vbHRpcChmYWxzZSkg5YiZ5aeL57uI5LiN5pi+56S6XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZhciBpdGVtcyA9IHRoaXMuZ2V0VG9vbHRpcEl0ZW1zKHBvaW50KTtcbiAgICAgICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIOaXoOWGheWuueWImeS4jeWxleekuu+8jOWQjOaXtiB0b29sdGlwIOmcgOimgemakOiXj1xuICAgICAgICAgICAgdGhpcy5oaWRlVG9vbHRpcCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aXRsZSA9IHRoaXMuZ2V0VGl0bGUoaXRlbXMpO1xuICAgICAgICB2YXIgZGF0YVBvaW50ID0ge1xuICAgICAgICAgICAgeDogaXRlbXNbMF0ueCxcbiAgICAgICAgICAgIHk6IGl0ZW1zWzBdLnksXG4gICAgICAgIH07IC8vIOaVsOaNrueCueS9jee9rlxuICAgICAgICB2aWV3LmVtaXQoJ3Rvb2x0aXA6c2hvdycsIHRzbGliXzEuX19hc3NpZ24oeyBpdGVtczogaXRlbXMsXG4gICAgICAgICAgICB0aXRsZTogdGl0bGUgfSwgcG9pbnQpKTtcbiAgICAgICAgdmFyIGNmZyA9IHRoaXMuZ2V0VG9vbHRpcENmZygpO1xuICAgICAgICB2YXIgZm9sbG93ID0gY2ZnLmZvbGxvdywgc2hvd01hcmtlcnMgPSBjZmcuc2hvd01hcmtlcnMsIHNob3dDcm9zc2hhaXJzID0gY2ZnLnNob3dDcm9zc2hhaXJzLCBzaG93Q29udGVudCA9IGNmZy5zaG93Q29udGVudCwgbWFya2VyID0gY2ZnLm1hcmtlcjtcbiAgICAgICAgdmFyIGxhc3RJdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgIHZhciBsYXN0VGl0bGUgPSB0aGlzLnRpdGxlO1xuICAgICAgICBpZiAoIXV0aWxfMS5pc0VxdWFsKGxhc3RUaXRsZSwgdGl0bGUpIHx8ICF1dGlsXzEuaXNFcXVhbChsYXN0SXRlbXMsIGl0ZW1zKSkge1xuICAgICAgICAgICAgLy8g5YaF5a655Y+R55Sf5Y+Y5YyW5LqG5pu05pawIHRvb2x0aXBcbiAgICAgICAgICAgIHZpZXcuZW1pdCgndG9vbHRpcDpjaGFuZ2UnLCB0c2xpYl8xLl9fYXNzaWduKHsgaXRlbXM6IGl0ZW1zLFxuICAgICAgICAgICAgICAgIHRpdGxlOiB0aXRsZSB9LCBwb2ludCkpO1xuICAgICAgICAgICAgaWYgKHNob3dDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgLy8g5bGV56S6IHRvb2x0aXAg5YaF5a655qGG5omN5riy5p+TIHRvb2x0aXBcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMudG9vbHRpcCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlu7bov5/nlJ/miJBcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJUb29sdGlwKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudG9vbHRpcC51cGRhdGUodXRpbF8xLm1peCh7fSwgY2ZnLCB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zOiBpdGVtcyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgICAgIH0sIGZvbGxvdyA/IHBvaW50IDoge30pKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRvb2x0aXAuc2hvdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNob3dNYXJrZXJzKSB7XG4gICAgICAgICAgICAgICAgLy8g5bGV56S6IHRvb2x0aXBNYXJrZXJz77yMdG9vbHRpcE1hcmtlcnMg6Lef6ZqP5pWw5o2uXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJUb29sdGlwTWFya2VycyhpdGVtcywgbWFya2VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOWGheWuueacquWPkeeUn+WPmOWMlu+8jOWImeabtOaWsOS9jee9rlxuICAgICAgICAgICAgaWYgKHRoaXMudG9vbHRpcCAmJiBmb2xsb3cpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvb2x0aXAudXBkYXRlKHBvaW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLnRvb2x0aXAuc2hvdygpOyAvLyB0b29sdGlwIOacieWPr+iDveiiq+makOiXj++8jOmcgOimgeS/neivgeaYvuekuueKtuaAgVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMudG9vbHRpcE1hcmtlcnNHcm91cCkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9vbHRpcE1hcmtlcnNHcm91cC5zaG93KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pdGVtcyA9IGl0ZW1zO1xuICAgICAgICB0aGlzLnRpdGxlID0gdGl0bGU7XG4gICAgICAgIGlmIChzaG93Q3Jvc3NoYWlycykge1xuICAgICAgICAgICAgLy8g5bGV56S6IHRvb2x0aXAg6L6F5Yqp57q/XG4gICAgICAgICAgICB2YXIgaXNDcm9zc2hhaXJzRm9sbG93Q3Vyc29yID0gdXRpbF8xLmdldChjZmcsIFsnY3Jvc3NoYWlycycsICdmb2xsb3cnXSwgZmFsc2UpOyAvLyDovoXliqnnur/mmK/lkKbopoHot5/pmo/pvKDmoIdcbiAgICAgICAgICAgIHRoaXMucmVuZGVyQ3Jvc3NoYWlycyhpc0Nyb3NzaGFpcnNGb2xsb3dDdXJzb3IgPyBwb2ludCA6IGRhdGFQb2ludCwgY2ZnKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuaGlkZVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmb2xsb3cgPSB0aGlzLmdldFRvb2x0aXBDZmcoKS5mb2xsb3c7XG4gICAgICAgIGlmICghZm9sbG93KSB7XG4gICAgICAgICAgICB0aGlzLnBvaW50ID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBoaWRlIHRoZSB0b29sdGlwTWFya2Vyc1xuICAgICAgICB2YXIgdG9vbHRpcE1hcmtlcnNHcm91cCA9IHRoaXMudG9vbHRpcE1hcmtlcnNHcm91cDtcbiAgICAgICAgaWYgKHRvb2x0aXBNYXJrZXJzR3JvdXApIHtcbiAgICAgICAgICAgIHRvb2x0aXBNYXJrZXJzR3JvdXAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZGUgY3Jvc3NoYWlyc1xuICAgICAgICB2YXIgeENyb3NzaGFpciA9IHRoaXMueENyb3NzaGFpcjtcbiAgICAgICAgdmFyIHlDcm9zc2hhaXIgPSB0aGlzLnlDcm9zc2hhaXI7XG4gICAgICAgIGlmICh4Q3Jvc3NoYWlyKSB7XG4gICAgICAgICAgICB4Q3Jvc3NoYWlyLmhpZGUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoeUNyb3NzaGFpcikge1xuICAgICAgICAgICAgeUNyb3NzaGFpci5oaWRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRvb2x0aXAgPSB0aGlzLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwKSB7XG4gICAgICAgICAgICB0b29sdGlwLmhpZGUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXcuZW1pdCgndG9vbHRpcDpoaWRlJywge30pO1xuICAgICAgICB0aGlzLnBvaW50ID0gbnVsbDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGxvY2tUb29sdGlwXG4gICAgICovXG4gICAgVG9vbHRpcC5wcm90b3R5cGUubG9ja1Rvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaXNMb2NrZWQgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy50b29sdGlwKSB7XG4gICAgICAgICAgICAvLyB0b29sdGlwIGNvbnRpYW5lciDlj6/mjZXojrfkuovku7ZcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcC5zZXRDYXB0dXJlKHRydWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiB1bmxvY2tUb29sdGlwXG4gICAgICovXG4gICAgVG9vbHRpcC5wcm90b3R5cGUudW5sb2NrVG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pc0xvY2tlZCA9IGZhbHNlO1xuICAgICAgICB2YXIgY2ZnID0gdGhpcy5nZXRUb29sdGlwQ2ZnKCk7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXApIHtcbiAgICAgICAgICAgIC8vIOmHjee9riBjYXB0dXJlIOWxnuaAp1xuICAgICAgICAgICAgdGhpcy50b29sdGlwLnNldENhcHR1cmUoY2ZnLmNhcHR1cmUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBpc1Rvb2x0aXBMb2NrZWRcbiAgICAgKi9cbiAgICBUb29sdGlwLnByb3RvdHlwZS5pc1Rvb2x0aXBMb2NrZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzTG9ja2VkO1xuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIHRvb2x0aXAgPSBfYS50b29sdGlwLCB4Q3Jvc3NoYWlyID0gX2EueENyb3NzaGFpciwgeUNyb3NzaGFpciA9IF9hLnlDcm9zc2hhaXIsIHRvb2x0aXBNYXJrZXJzR3JvdXAgPSBfYS50b29sdGlwTWFya2Vyc0dyb3VwO1xuICAgICAgICBpZiAodG9vbHRpcCkge1xuICAgICAgICAgICAgdG9vbHRpcC5oaWRlKCk7XG4gICAgICAgICAgICB0b29sdGlwLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHhDcm9zc2hhaXIpIHtcbiAgICAgICAgICAgIHhDcm9zc2hhaXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoeUNyb3NzaGFpcikge1xuICAgICAgICAgICAgeUNyb3NzaGFpci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwTWFya2Vyc0dyb3VwKSB7XG4gICAgICAgICAgICB0b29sdGlwTWFya2Vyc0dyb3VwLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRvb2x0aXAucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnRvb2x0aXApIHtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcC5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMueENyb3NzaGFpcikge1xuICAgICAgICAgICAgdGhpcy54Q3Jvc3NoYWlyLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy55Q3Jvc3NoYWlyKSB7XG4gICAgICAgICAgICB0aGlzLnlDcm9zc2hhaXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmd1aWRlR3JvdXApIHtcbiAgICAgICAgICAgIHRoaXMuZ3VpZGVHcm91cC5yZW1vdmUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pdGVtcyA9IG51bGw7XG4gICAgICAgIHRoaXMudGl0bGUgPSBudWxsO1xuICAgICAgICB0aGlzLnRvb2x0aXBNYXJrZXJzR3JvdXAgPSBudWxsO1xuICAgICAgICB0aGlzLnRvb2x0aXBDcm9zc2hhaXJzR3JvdXAgPSBudWxsO1xuICAgICAgICB0aGlzLnhDcm9zc2hhaXIgPSBudWxsO1xuICAgICAgICB0aGlzLnlDcm9zc2hhaXIgPSBudWxsO1xuICAgICAgICB0aGlzLnRvb2x0aXAgPSBudWxsO1xuICAgICAgICB0aGlzLmd1aWRlR3JvdXAgPSBudWxsO1xuICAgICAgICB0aGlzLmlzTG9ja2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucG9pbnQgPSBudWxsO1xuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuY2hhbmdlVmlzaWJsZSA9IGZ1bmN0aW9uICh2aXNpYmxlKSB7XG4gICAgICAgIGlmICh0aGlzLnZpc2libGUgPT09IHZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgX2EgPSB0aGlzLCB0b29sdGlwID0gX2EudG9vbHRpcCwgdG9vbHRpcE1hcmtlcnNHcm91cCA9IF9hLnRvb2x0aXBNYXJrZXJzR3JvdXAsIHhDcm9zc2hhaXIgPSBfYS54Q3Jvc3NoYWlyLCB5Q3Jvc3NoYWlyID0gX2EueUNyb3NzaGFpcjtcbiAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICAgIGlmICh0b29sdGlwKSB7XG4gICAgICAgICAgICAgICAgdG9vbHRpcC5zaG93KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodG9vbHRpcE1hcmtlcnNHcm91cCkge1xuICAgICAgICAgICAgICAgIHRvb2x0aXBNYXJrZXJzR3JvdXAuc2hvdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHhDcm9zc2hhaXIpIHtcbiAgICAgICAgICAgICAgICB4Q3Jvc3NoYWlyLnNob3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh5Q3Jvc3NoYWlyKSB7XG4gICAgICAgICAgICAgICAgeUNyb3NzaGFpci5zaG93KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAodG9vbHRpcCkge1xuICAgICAgICAgICAgICAgIHRvb2x0aXAuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRvb2x0aXBNYXJrZXJzR3JvdXApIHtcbiAgICAgICAgICAgICAgICB0b29sdGlwTWFya2Vyc0dyb3VwLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh4Q3Jvc3NoYWlyKSB7XG4gICAgICAgICAgICAgICAgeENyb3NzaGFpci5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeUNyb3NzaGFpcikge1xuICAgICAgICAgICAgICAgIHlDcm9zc2hhaXIuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHZpc2libGU7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5nZXRUb29sdGlwSXRlbXMgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5maW5kSXRlbXNGcm9tVmlldyh0aGlzLnZpZXcsIHBvaW50KTtcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8g5LiJ5bGCXG4gICAgICAgICAgICBpdGVtcyA9IHV0aWxfMS5mbGF0dGVuKGl0ZW1zKTtcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgaXRlbXNfMSA9IGl0ZW1zOyBfaSA8IGl0ZW1zXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW1BcnIgPSBpdGVtc18xW19pXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfYSA9IDAsIGl0ZW1BcnJfMSA9IGl0ZW1BcnI7IF9hIDwgaXRlbUFycl8xLmxlbmd0aDsgX2ErKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGl0ZW1BcnJfMVtfYV07XG4gICAgICAgICAgICAgICAgICAgIHZhciBfYiA9IGl0ZW0ubWFwcGluZ0RhdGEsIHggPSBfYi54LCB5ID0gX2IueTtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS54ID0gdXRpbF8xLmlzQXJyYXkoeCkgPyB4W3gubGVuZ3RoIC0gMV0gOiB4O1xuICAgICAgICAgICAgICAgICAgICBpdGVtLnkgPSB1dGlsXzEuaXNBcnJheSh5KSA/IHlbeS5sZW5ndGggLSAxXSA6IHk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHNoYXJlZCA9IHRoaXMuZ2V0VG9vbHRpcENmZygpLnNoYXJlZDtcbiAgICAgICAgICAgIC8vIHNoYXJlZDogZmFsc2Ug5Luj6KGo5Y+q5pi+56S65b2T5YmN5ou+5Y+W5Yiw55qEIHNoYXBlIOeahOaVsOaNru+8jOS9huaYr+S4gOS4qiB2aWV3IOS8muacieWkmuS4qiBHZW9tZXRyee+8jOaJgOS7peacieWPr+iDveS8muaLvuWPluWIsOWkmuS4qiBzaGFwZVxuICAgICAgICAgICAgaWYgKHNoYXJlZCA9PT0gZmFsc2UgJiYgaXRlbXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIHZhciBzbmFwSXRlbSA9IGl0ZW1zWzBdO1xuICAgICAgICAgICAgICAgIHZhciBtaW4gPSBNYXRoLmFicyhwb2ludC55IC0gc25hcEl0ZW1bMF0ueSk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2MgPSAwLCBpdGVtc18yID0gaXRlbXM7IF9jIDwgaXRlbXNfMi5sZW5ndGg7IF9jKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFJdGVtID0gaXRlbXNfMltfY107XG4gICAgICAgICAgICAgICAgICAgIHZhciB5RGlzdGFuY2UgPSBNYXRoLmFicyhwb2ludC55IC0gYUl0ZW1bMF0ueSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh5RGlzdGFuY2UgPD0gbWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzbmFwSXRlbSA9IGFJdGVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluID0geURpc3RhbmNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGl0ZW1zID0gW3NuYXBJdGVtXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB1bmlxKHV0aWxfMS5mbGF0dGVuKGl0ZW1zKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUubGF5b3V0ID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIFRvb2x0aXAucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucG9pbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd1Rvb2x0aXAodGhpcy5wb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudG9vbHRpcCkge1xuICAgICAgICAgICAgLy8gIzIyNzkg5L+u5aSNcmVzaXpl5LmL5ZCOdG9vbHRpcOi2iueVjOeahOmXrumimFxuICAgICAgICAgICAgLy8g56Gu5L+ddG9vbHRpcOW3sue7j+WIm+W7uueahOaDheWGteS4i1xuICAgICAgICAgICAgdmFyIGNhbnZhcyA9IHRoaXMudmlldy5nZXRDYW52YXMoKTtcbiAgICAgICAgICAgIC8vIOabtOaWsCByZWdpb25cbiAgICAgICAgICAgIHRoaXMudG9vbHRpcC5zZXQoJ3JlZ2lvbicsIHtcbiAgICAgICAgICAgICAgICBzdGFydDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgICAgICAgICAgZW5kOiB7IHg6IGNhbnZhcy5nZXQoJ3dpZHRoJyksIHk6IGNhbnZhcy5nZXQoJ2hlaWdodCcpIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g6I635Y+WIHRvb2x0aXAg6YWN572u77yM5Zug5Li655So5oi35Y+v6IO95Lya6YCa6L+HIHZpZXcudG9vbHRpcCgpIOmHjeaWsOmFjee9riB0b29sdGlw77yM5omA5Lul5bCx5LiN5YGa57yT5a2Y77yM5q+P5qyh55u05o6l6K+75Y+WXG4gICAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0VG9vbHRpcENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZhciBvcHRpb24gPSB2aWV3LmdldE9wdGlvbnMoKS50b29sdGlwO1xuICAgICAgICB2YXIgdGhlbWUgPSB2aWV3LmdldFRoZW1lKCk7XG4gICAgICAgIHZhciBkZWZhdWx0Q2ZnID0gdXRpbF8xLmdldCh0aGVtZSwgWydjb21wb25lbnRzJywgJ3Rvb2x0aXAnXSwge30pO1xuICAgICAgICB2YXIgZW50ZXJhYmxlID0gdXRpbF8xLmlzVW5kZWZpbmVkKHV0aWxfMS5nZXQob3B0aW9uLCAnZW50ZXJhYmxlJykpID8gZGVmYXVsdENmZy5lbnRlcmFibGUgOiB1dGlsXzEuZ2V0KG9wdGlvbiwgJ2VudGVyYWJsZScpO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRDZmcsIG9wdGlvbiwge1xuICAgICAgICAgICAgY2FwdHVyZTogZW50ZXJhYmxlIHx8IHRoaXMuaXNMb2NrZWQgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0VGl0bGUgPSBmdW5jdGlvbiAoaXRlbXMpIHtcbiAgICAgICAgdmFyIHRpdGxlID0gaXRlbXNbMF0udGl0bGUgfHwgaXRlbXNbMF0ubmFtZTtcbiAgICAgICAgdGhpcy50aXRsZSA9IHRpdGxlO1xuICAgICAgICByZXR1cm4gdGl0bGU7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZW5kZXJUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2FudmFzID0gdGhpcy52aWV3LmdldENhbnZhcygpO1xuICAgICAgICB2YXIgcmVnaW9uID0ge1xuICAgICAgICAgICAgc3RhcnQ6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICAgICAgZW5kOiB7IHg6IGNhbnZhcy5nZXQoJ3dpZHRoJyksIHk6IGNhbnZhcy5nZXQoJ2hlaWdodCcpIH0sXG4gICAgICAgIH07XG4gICAgICAgIHZhciBjZmcgPSB0aGlzLmdldFRvb2x0aXBDZmcoKTtcbiAgICAgICAgdmFyIHRvb2x0aXAgPSBuZXcgZGVwZW5kZW50c18xLkh0bWxUb29sdGlwKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IHBhcmVudDogY2FudmFzLmdldCgnZWwnKS5wYXJlbnROb2RlLCByZWdpb246IHJlZ2lvbiB9LCBjZmcpLCB7IHZpc2libGU6IGZhbHNlLCBjcm9zc2hhaXJzOiBudWxsIH0pKTtcbiAgICAgICAgdG9vbHRpcC5pbml0KCk7XG4gICAgICAgIHRoaXMudG9vbHRpcCA9IHRvb2x0aXA7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZW5kZXJUb29sdGlwTWFya2VycyA9IGZ1bmN0aW9uIChpdGVtcywgbWFya2VyKSB7XG4gICAgICAgIHZhciB0b29sdGlwTWFya2Vyc0dyb3VwID0gdGhpcy5nZXRUb29sdGlwTWFya2Vyc0dyb3VwKCk7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgaXRlbXNfMyA9IGl0ZW1zOyBfaSA8IGl0ZW1zXzMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IGl0ZW1zXzNbX2ldO1xuICAgICAgICAgICAgdmFyIHggPSBpdGVtLngsIHkgPSBpdGVtLnk7XG4gICAgICAgICAgICB2YXIgYXR0cnMgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyBmaWxsOiBpdGVtLmNvbG9yLCBzeW1ib2w6ICdjaXJjbGUnLCBzaGFkb3dDb2xvcjogaXRlbS5jb2xvciB9LCBtYXJrZXIpLCB7IHg6IHgsXG4gICAgICAgICAgICAgICAgeTogeSB9KTtcbiAgICAgICAgICAgIHRvb2x0aXBNYXJrZXJzR3JvdXAuYWRkU2hhcGUoJ21hcmtlcicsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogYXR0cnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVG9vbHRpcC5wcm90b3R5cGUucmVuZGVyQ3Jvc3NoYWlycyA9IGZ1bmN0aW9uIChwb2ludCwgY2ZnKSB7XG4gICAgICAgIHZhciBjcm9zc2hhaXJzVHlwZSA9IHV0aWxfMS5nZXQoY2ZnLCBbJ2Nyb3NzaGFpcnMnLCAndHlwZSddLCAneCcpOyAvLyDpu5jorqTlsZXnpLogeCDovbTkuIrnmoTovoXliqnnur9cbiAgICAgICAgaWYgKGNyb3NzaGFpcnNUeXBlID09PSAneCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnlDcm9zc2hhaXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnlDcm9zc2hhaXIuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJYQ3Jvc3NoYWlycyhwb2ludCwgY2ZnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjcm9zc2hhaXJzVHlwZSA9PT0gJ3knKSB7XG4gICAgICAgICAgICBpZiAodGhpcy54Q3Jvc3NoYWlyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy54Q3Jvc3NoYWlyLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVuZGVyWUNyb3NzaGFpcnMocG9pbnQsIGNmZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY3Jvc3NoYWlyc1R5cGUgPT09ICd4eScpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyWENyb3NzaGFpcnMocG9pbnQsIGNmZyk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcllDcm9zc2hhaXJzKHBvaW50LCBjZmcpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmuLLmn5MgeCDovbTkuIrnmoQgdG9vbHRpcCDovoXliqnnur9cbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZW5kZXJYQ3Jvc3NoYWlycyA9IGZ1bmN0aW9uIChwb2ludCwgdG9vbHRpcENmZykge1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Vmlld1dpdGhHZW9tZXRyeSh0aGlzLnZpZXcpLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgaWYgKCFjb29yZGluYXRlXzEuaXNQb2ludEluQ29vcmRpbmF0ZShjb29yZGluYXRlLCBwb2ludCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RhcnQ7XG4gICAgICAgIHZhciBlbmQ7XG4gICAgICAgIGlmIChjb29yZGluYXRlLmlzUmVjdCkge1xuICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGNvb3JkaW5hdGUuc3RhcnQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogcG9pbnQueSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogY29vcmRpbmF0ZS5lbmQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogcG9pbnQueSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHBvaW50LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IGNvb3JkaW5hdGUuZW5kLnksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBlbmQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHBvaW50LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IGNvb3JkaW5hdGUuc3RhcnQueSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5p6B5Z2Q5qCH5LiLIHgg6L205LiK55qEIGNyb3NzaGFpcnMg6KGo546w5Li65Y2K5b6EXG4gICAgICAgICAgICB2YXIgYW5nbGUgPSBjb29yZGluYXRlXzEuZ2V0QW5nbGVCeVBvaW50KGNvb3JkaW5hdGUsIHBvaW50KTtcbiAgICAgICAgICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlLmdldENlbnRlcigpO1xuICAgICAgICAgICAgdmFyIHJhZGl1cyA9IGNvb3JkaW5hdGUuZ2V0UmFkaXVzKCk7XG4gICAgICAgICAgICBlbmQgPSBncmFwaGljc18xLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyLngsIGNlbnRlci55LCByYWRpdXMsIGFuZ2xlKTtcbiAgICAgICAgICAgIHN0YXJ0ID0gY2VudGVyO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjZmcgPSB1dGlsXzEuZGVlcE1peCh7XG4gICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IGVuZCxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5nZXRUb29sdGlwQ3Jvc3NoYWlyc0dyb3VwKCksXG4gICAgICAgIH0sIHV0aWxfMS5nZXQodG9vbHRpcENmZywgJ2Nyb3NzaGFpcnMnLCB7fSksIHRoaXMuZ2V0Q3Jvc3NoYWlyc1RleHQoJ3gnLCBwb2ludCwgdG9vbHRpcENmZykpO1xuICAgICAgICBkZWxldGUgY2ZnLnR5cGU7IC8vIOS4jiBDcm9zc2hhaXJzIOe7hOS7tueahCB0eXBlIOWGsueqgeaVheWIoOmZpFxuICAgICAgICB2YXIgeENyb3NzaGFpciA9IHRoaXMueENyb3NzaGFpcjtcbiAgICAgICAgaWYgKHhDcm9zc2hhaXIpIHtcbiAgICAgICAgICAgIHhDcm9zc2hhaXIudXBkYXRlKGNmZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB4Q3Jvc3NoYWlyID0gbmV3IGRlcGVuZGVudHNfMS5Dcm9zc2hhaXIuTGluZShjZmcpO1xuICAgICAgICAgICAgeENyb3NzaGFpci5pbml0KCk7XG4gICAgICAgIH1cbiAgICAgICAgeENyb3NzaGFpci5yZW5kZXIoKTtcbiAgICAgICAgeENyb3NzaGFpci5zaG93KCk7XG4gICAgICAgIHRoaXMueENyb3NzaGFpciA9IHhDcm9zc2hhaXI7XG4gICAgfTtcbiAgICAvLyDmuLLmn5MgeSDovbTkuIrnmoTovoXliqnnur9cbiAgICBUb29sdGlwLnByb3RvdHlwZS5yZW5kZXJZQ3Jvc3NoYWlycyA9IGZ1bmN0aW9uIChwb2ludCwgdG9vbHRpcENmZykge1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Vmlld1dpdGhHZW9tZXRyeSh0aGlzLnZpZXcpLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgaWYgKCFjb29yZGluYXRlXzEuaXNQb2ludEluQ29vcmRpbmF0ZShjb29yZGluYXRlLCBwb2ludCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2ZnO1xuICAgICAgICB2YXIgdHlwZTtcbiAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNSZWN0KSB7XG4gICAgICAgICAgICB2YXIgc3RhcnQgPSB2b2lkIDA7XG4gICAgICAgICAgICB2YXIgZW5kID0gdm9pZCAwO1xuICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHBvaW50LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IGNvb3JkaW5hdGUuZW5kLnksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBlbmQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHBvaW50LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IGNvb3JkaW5hdGUuc3RhcnQueSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGNvb3JkaW5hdGUuc3RhcnQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogcG9pbnQueSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGVuZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogY29vcmRpbmF0ZS5lbmQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogcG9pbnQueSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2ZnID0ge1xuICAgICAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgICAgICBlbmQ6IGVuZCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0eXBlID0gJ0xpbmUnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5p6B5Z2Q5qCH5LiLIHkg6L205LiK55qEIGNyb3NzaGFpcnMg6KGo546w5Li65ZyG5bynXG4gICAgICAgICAgICBjZmcgPSB7XG4gICAgICAgICAgICAgICAgY2VudGVyOiBjb29yZGluYXRlLmdldENlbnRlcigpLFxuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICByYWRpdXM6IGNvb3JkaW5hdGVfMS5nZXREaXN0YW5jZVRvQ2VudGVyKGNvb3JkaW5hdGUsIHBvaW50KSxcbiAgICAgICAgICAgICAgICBzdGFydEFuZ2xlOiBjb29yZGluYXRlLnN0YXJ0QW5nbGUsXG4gICAgICAgICAgICAgICAgZW5kQW5nbGU6IGNvb3JkaW5hdGUuZW5kQW5nbGUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdHlwZSA9ICdDaXJjbGUnO1xuICAgICAgICB9XG4gICAgICAgIGNmZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5nZXRUb29sdGlwQ3Jvc3NoYWlyc0dyb3VwKCksXG4gICAgICAgIH0sIGNmZywgdXRpbF8xLmdldCh0b29sdGlwQ2ZnLCAnY3Jvc3NoYWlycycsIHt9KSwgdGhpcy5nZXRDcm9zc2hhaXJzVGV4dCgneScsIHBvaW50LCB0b29sdGlwQ2ZnKSk7XG4gICAgICAgIGRlbGV0ZSBjZmcudHlwZTsgLy8g5LiOIENyb3NzaGFpcnMg57uE5Lu255qEIHR5cGUg5Yay56qB5pWF5Yig6ZmkXG4gICAgICAgIHZhciB5Q3Jvc3NoYWlyID0gdGhpcy55Q3Jvc3NoYWlyO1xuICAgICAgICBpZiAoeUNyb3NzaGFpcikge1xuICAgICAgICAgICAgLy8g5aaC5p6c5Z2Q5qCH57O75Y+R55Sf55u06KeS5Z2Q5qCH57O75LiO5p6B5Z2Q5qCH55qE5YiH5o2i5pON5L2cXG4gICAgICAgICAgICBpZiAoKGNvb3JkaW5hdGUuaXNSZWN0ICYmIHlDcm9zc2hhaXIuZ2V0KCd0eXBlJykgPT09ICdjaXJjbGUnKSB8fFxuICAgICAgICAgICAgICAgICghY29vcmRpbmF0ZS5pc1JlY3QgJiYgeUNyb3NzaGFpci5nZXQoJ3R5cGUnKSA9PT0gJ2xpbmUnKSkge1xuICAgICAgICAgICAgICAgIHlDcm9zc2hhaXIgPSBuZXcgZGVwZW5kZW50c18xLkNyb3NzaGFpclt0eXBlXShjZmcpO1xuICAgICAgICAgICAgICAgIHlDcm9zc2hhaXIuaW5pdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgeUNyb3NzaGFpci51cGRhdGUoY2ZnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHlDcm9zc2hhaXIgPSBuZXcgZGVwZW5kZW50c18xLkNyb3NzaGFpclt0eXBlXShjZmcpO1xuICAgICAgICAgICAgeUNyb3NzaGFpci5pbml0KCk7XG4gICAgICAgIH1cbiAgICAgICAgeUNyb3NzaGFpci5yZW5kZXIoKTtcbiAgICAgICAgeUNyb3NzaGFpci5zaG93KCk7XG4gICAgICAgIHRoaXMueUNyb3NzaGFpciA9IHlDcm9zc2hhaXI7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5nZXRDcm9zc2hhaXJzVGV4dCA9IGZ1bmN0aW9uICh0eXBlLCBwb2ludCwgdG9vbHRpcENmZykge1xuICAgICAgICB2YXIgdGV4dENmZyA9IHV0aWxfMS5nZXQodG9vbHRpcENmZywgWydjcm9zc2hhaXJzJywgJ3RleHQnXSk7XG4gICAgICAgIHZhciBmb2xsb3cgPSB1dGlsXzEuZ2V0KHRvb2x0aXBDZmcsIFsnY3Jvc3NoYWlycycsICdmb2xsb3cnXSk7XG4gICAgICAgIHZhciBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgIGlmICh0ZXh0Q2ZnKSB7XG4gICAgICAgICAgICB2YXIgdmlldyA9IHRoaXMuZ2V0Vmlld1dpdGhHZW9tZXRyeSh0aGlzLnZpZXcpO1xuICAgICAgICAgICAgLy8g6ZyA6KaB5bGV56S65paH5pysXG4gICAgICAgICAgICB2YXIgZmlyc3RJdGVtID0gaXRlbXNbMF07XG4gICAgICAgICAgICB2YXIgeFNjYWxlID0gdmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgICAgIHZhciB5U2NhbGUgPSB2aWV3LmdldFlTY2FsZXMoKVswXTtcbiAgICAgICAgICAgIHZhciB4VmFsdWUgPSB2b2lkIDA7XG4gICAgICAgICAgICB2YXIgeVZhbHVlID0gdm9pZCAwO1xuICAgICAgICAgICAgaWYgKGZvbGxvdykge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOmcgOimgei3n+maj+m8oOagh+enu+WKqO+8jOWwsemcgOimgeWwhuW9k+WJjem8oOagh+WdkOagh+eCuei9rOaNouS4uuWvueW6lOeahOaVsOWAvFxuICAgICAgICAgICAgICAgIHZhciBpbnZlcnRQb2ludCA9IHRoaXMudmlldy5nZXRDb29yZGluYXRlKCkuaW52ZXJ0KHBvaW50KTtcbiAgICAgICAgICAgICAgICB4VmFsdWUgPSB4U2NhbGUuaW52ZXJ0KGludmVydFBvaW50LngpOyAvLyDovazmjaLkuLrljp/lp4vlgLxcbiAgICAgICAgICAgICAgICB5VmFsdWUgPSB5U2NhbGUuaW52ZXJ0KGludmVydFBvaW50LnkpOyAvLyDovazmjaLkuLrljp/lp4vlgLxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHhWYWx1ZSA9IGZpcnN0SXRlbS5kYXRhW3hTY2FsZS5maWVsZF07XG4gICAgICAgICAgICAgICAgeVZhbHVlID0gZmlyc3RJdGVtLmRhdGFbeVNjYWxlLmZpZWxkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBjb250ZW50ID0gdHlwZSA9PT0gJ3gnID8geFZhbHVlIDogeVZhbHVlO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHRleHRDZmcpKSB7XG4gICAgICAgICAgICAgICAgdGV4dENmZyA9IHRleHRDZmcodHlwZSwgY29udGVudCwgaXRlbXMsIHBvaW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRleHRDZmcuY29udGVudCA9IGNvbnRlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRleHQ6IHRleHRDZmcsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDojrflj5blrZjlgqggdG9vbHRpcE1hcmtlcnMg5ZKMIGNyb3NzaGFpcnMg55qE5a655ZmoXG4gICAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0R3VpZGVHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmd1aWRlR3JvdXApIHtcbiAgICAgICAgICAgIHZhciBmb3JlZ3JvdW5kR3JvdXAgPSB0aGlzLnZpZXcuZm9yZWdyb3VuZEdyb3VwO1xuICAgICAgICAgICAgdGhpcy5ndWlkZUdyb3VwID0gZm9yZWdyb3VuZEdyb3VwLmFkZEdyb3VwKHtcbiAgICAgICAgICAgICAgICBuYW1lOiAndG9vbHRpcEd1aWRlJyxcbiAgICAgICAgICAgICAgICBjYXB0dXJlOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmd1aWRlR3JvdXA7XG4gICAgfTtcbiAgICAvLyDojrflj5YgdG9vbHRpcE1hcmtlcnMg5a2Y5YKo55qE5a655ZmoXG4gICAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0VG9vbHRpcE1hcmtlcnNHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRvb2x0aXBNYXJrZXJzR3JvdXAgPSB0aGlzLnRvb2x0aXBNYXJrZXJzR3JvdXA7XG4gICAgICAgIGlmICh0b29sdGlwTWFya2Vyc0dyb3VwICYmICF0b29sdGlwTWFya2Vyc0dyb3VwLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgdG9vbHRpcE1hcmtlcnNHcm91cC5jbGVhcigpO1xuICAgICAgICAgICAgdG9vbHRpcE1hcmtlcnNHcm91cC5zaG93KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0b29sdGlwTWFya2Vyc0dyb3VwID0gdGhpcy5nZXRHdWlkZUdyb3VwKCkuYWRkR3JvdXAoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICd0b29sdGlwTWFya2Vyc0dyb3VwJyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdG9vbHRpcE1hcmtlcnNHcm91cC50b0Zyb250KCk7XG4gICAgICAgICAgICB0aGlzLnRvb2x0aXBNYXJrZXJzR3JvdXAgPSB0b29sdGlwTWFya2Vyc0dyb3VwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0b29sdGlwTWFya2Vyc0dyb3VwO1xuICAgIH07XG4gICAgLy8g6I635Y+WIHRvb2x0aXAgY3Jvc3NoYWlycyDlrZjlgqjnmoTlrrnlmahcbiAgICBUb29sdGlwLnByb3RvdHlwZS5nZXRUb29sdGlwQ3Jvc3NoYWlyc0dyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdG9vbHRpcENyb3NzaGFpcnNHcm91cCA9IHRoaXMudG9vbHRpcENyb3NzaGFpcnNHcm91cDtcbiAgICAgICAgaWYgKCF0b29sdGlwQ3Jvc3NoYWlyc0dyb3VwKSB7XG4gICAgICAgICAgICB0b29sdGlwQ3Jvc3NoYWlyc0dyb3VwID0gdGhpcy5nZXRHdWlkZUdyb3VwKCkuYWRkR3JvdXAoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICd0b29sdGlwQ3Jvc3NoYWlyc0dyb3VwJyxcbiAgICAgICAgICAgICAgICBjYXB0dXJlOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdG9vbHRpcENyb3NzaGFpcnNHcm91cC50b0JhY2soKTtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcENyb3NzaGFpcnNHcm91cCA9IHRvb2x0aXBDcm9zc2hhaXJzR3JvdXA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvb2x0aXBDcm9zc2hhaXJzR3JvdXA7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5nZXRUb29sdGlwSXRlbXNCeUhpdFNoYXBlID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBwb2ludCwgdGl0bGUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gZ2VvbWV0cnkuY29udGFpbmVyO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuZ2V0U2hhcGUocG9pbnQueCwgcG9pbnQueSk7XG4gICAgICAgIGlmIChzaGFwZSAmJiBzaGFwZS5nZXQoJ3Zpc2libGUnKSAmJiBzaGFwZS5nZXQoJ29yaWdpbicpKSB7XG4gICAgICAgICAgICB2YXIgbWFwcGluZ0RhdGEgPSBzaGFwZS5nZXQoJ29yaWdpbicpLm1hcHBpbmdEYXRhO1xuICAgICAgICAgICAgdmFyIGl0ZW1zID0gdG9vbHRpcF8xLmdldFRvb2x0aXBJdGVtcyhtYXBwaW5nRGF0YSwgZ2VvbWV0cnksIHRpdGxlKTtcbiAgICAgICAgICAgIGlmIChpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChpdGVtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICAgIFRvb2x0aXAucHJvdG90eXBlLmdldFRvb2x0aXBJdGVtc0J5RmluZERhdGEgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIHBvaW50LCB0aXRsZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIHZhciBkYXRhQXJyYXkgPSBnZW9tZXRyeS5kYXRhQXJyYXk7XG4gICAgICAgIGdlb21ldHJ5LnNvcnQoZGF0YUFycmF5KTsgLy8g5YWI6L+b6KGM5o6S5bqP77yM5L6/5LqOIHRvb2x0aXAg5p+l5om+XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgZGF0YUFycmF5XzEgPSBkYXRhQXJyYXk7IF9pIDwgZGF0YUFycmF5XzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IGRhdGFBcnJheV8xW19pXTtcbiAgICAgICAgICAgIHZhciByZWNvcmQgPSB0b29sdGlwXzEuZmluZERhdGFCeVBvaW50KHBvaW50LCBkYXRhLCBnZW9tZXRyeSk7XG4gICAgICAgICAgICBpZiAocmVjb3JkKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRJZCA9IGdlb21ldHJ5LmdldEVsZW1lbnRJZChyZWNvcmQpO1xuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZ2VvbWV0cnkuZWxlbWVudHNNYXBbZWxlbWVudElkXTtcbiAgICAgICAgICAgICAgICBpZiAoZ2VvbWV0cnkudHlwZSA9PT0gJ2hlYXRtYXAnIHx8IGVsZW1lbnQudmlzaWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBIZWF0bWFwIOayoeaciSBFbGVtZW50XG4gICAgICAgICAgICAgICAgICAgIC8vIOWmguaenOWbvuW9ouWFg+e0oOmakOiXj+S6hu+8jOaAjuS4jeWGjSB0b29sdGlwIOS4iuWxleekuuebuOWFs+aVsOaNrlxuICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbXMgPSB0b29sdGlwXzEuZ2V0VG9vbHRpcEl0ZW1zKHJlY29yZCwgZ2VvbWV0cnksIHRpdGxlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goaXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICBUb29sdGlwLnByb3RvdHlwZS5maW5kSXRlbXNGcm9tVmlldyA9IGZ1bmN0aW9uICh2aWV3LCBwb2ludCkge1xuICAgICAgICBpZiAodmlldy5nZXRPcHRpb25zKCkudG9vbHRpcCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8vIOWmguaenCB2aWV3IOWFs+mXreS6hiB0b29sdGlwXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAvLyDlhYjku44gdmlldyDmnKzouqvmn6Xmib5cbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB2aWV3Lmdlb21ldHJpZXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0VG9vbHRpcENmZygpLCBzaGFyZWQgPSBfYS5zaGFyZWQsIHRpdGxlID0gX2EudGl0bGU7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgZ2VvbWV0cmllc18xID0gZ2VvbWV0cmllczsgX2kgPCBnZW9tZXRyaWVzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnkgPSBnZW9tZXRyaWVzXzFbX2ldO1xuICAgICAgICAgICAgaWYgKGdlb21ldHJ5LnZpc2libGUgJiYgZ2VvbWV0cnkudG9vbHRpcE9wdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAvLyBnZW9tZXRyeSDlj6/op4HlkIzml7bmnKrlhbPpl60gdG9vbHRpcFxuICAgICAgICAgICAgICAgIHZhciBnZW9tZXRyeVR5cGUgPSBnZW9tZXRyeS50eXBlO1xuICAgICAgICAgICAgICAgIHZhciB0b29sdGlwSXRlbXMgPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgaWYgKFsncG9pbnQnLCAnZWRnZScsICdwb2x5Z29uJ10uaW5jbHVkZXMoZ2VvbWV0cnlUeXBlKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlp4vnu4jpgJrov4flm77lvaLmi77lj5ZcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcEl0ZW1zID0gdGhpcy5nZXRUb29sdGlwSXRlbXNCeUhpdFNoYXBlKGdlb21ldHJ5LCBwb2ludCwgdGl0bGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChbJ2FyZWEnLCAnbGluZScsICdwYXRoJywgJ2hlYXRtYXAnXS5pbmNsdWRlcyhnZW9tZXRyeVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOWmguaenOaYryAnYXJlYScsICdsaW5lJywgJ3BhdGgn77yM5aeL57uI6YCa6L+H5pWw5o2u5p+l5om+5pa55rOV5p+l5om+IHRvb2x0aXBcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcEl0ZW1zID0gdGhpcy5nZXRUb29sdGlwSXRlbXNCeUZpbmREYXRhKGdlb21ldHJ5LCBwb2ludCwgdGl0bGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNoYXJlZCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBJdGVtcyA9IHRoaXMuZ2V0VG9vbHRpcEl0ZW1zQnlGaW5kRGF0YShnZW9tZXRyeSwgcG9pbnQsIHRpdGxlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBJdGVtcyA9IHRoaXMuZ2V0VG9vbHRpcEl0ZW1zQnlIaXRTaGFwZShnZW9tZXRyeSwgcG9pbnQsIHRpdGxlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodG9vbHRpcEl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZW9tZXRyeSDmnInlj6/og73kvJrmnInlpJrkuKogaXRlbe+8jOWboOS4uueUqOaIt+WPr+S7peiuvue9riBnZW9tZXRyeS50b29sdGlwKCd4KnkqeicpXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRvb2x0aXBJdGVtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOmAkuW9kuafpeaJvu+8jOW5tuWQiOW5tue7k+aenFxuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIF9jID0gdmlldy52aWV3czsgX2IgPCBfYy5sZW5ndGg7IF9iKyspIHtcbiAgICAgICAgICAgIHZhciBjaGlsZFZpZXcgPSBfY1tfYl07XG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuY29uY2F0KHRoaXMuZmluZEl0ZW1zRnJvbVZpZXcoY2hpbGRWaWV3LCBwb2ludCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICAvLyBGSVhNRTogaGFjayDmlrnms5VcbiAgICAvLyDlm6DkuLogdG9vbHRpcCDnmoTkuqTkupLmmK/mjILovb3lnKggQ2hhcnQg5LiK77yM5omA5Lul5b2TY2hhcnQg5LiK5rKh5pyJ57uY5Yi2IEdlb21ldHJ5IOeahOaXtuWAme+8jOWwseafpeaJvuS4jeWIsOaVsOaNru+8jOW5tuS4lOe7mOWbvuWMuuWfn+WQjOWtkCBWaWV3IOeahOWMuuWfn+S4jeWQjFxuICAgIFRvb2x0aXAucHJvdG90eXBlLmdldFZpZXdXaXRoR2VvbWV0cnkgPSBmdW5jdGlvbiAodmlldykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICBpZiAodmlldy5nZW9tZXRyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHZpZXc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHV0aWxfMS5maW5kKHZpZXcudmlld3MsIGZ1bmN0aW9uIChjaGlsZFZpZXcpIHsgcmV0dXJuIF90aGlzLmdldFZpZXdXaXRoR2VvbWV0cnkoY2hpbGRWaWV3KTsgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gVG9vbHRpcDtcbn0oYmFzZV8xLkNvbnRyb2xsZXIpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRvb2x0aXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10b29sdGlwLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiBAdG9kbyBXaGV0aGVyIGl0IGNhbihvciBuZWNlc3NhcnkgdG8pIGtlZXAgY29uc2lzdGVudCB3aXRoIHRoZSBzdHJ1Y3R1cmUgb2YgRy5FdmVudCBvciBkaXJlY3RseSB1c2UgdGhlIHN0cnVjdHVyZSBvZiBHLkV2ZW50XG4gKiBHMiDkuovku7bnmoTkuovku7bljIXoo4XnsbvvvIzln7rkuo4gRy5FdmVudFxuICovXG52YXIgRXZlbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRXZlbnQodmlldywgZ0V2ZW50LCBkYXRhKSB7XG4gICAgICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgICAgIHRoaXMuZ0V2ZW50ID0gZ0V2ZW50O1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB0aGlzLnR5cGUgPSBnRXZlbnQudHlwZTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJ0YXJnZXRcIiwge1xuICAgICAgICAvLyBiZWxvdyBwcm9wcyBhcmUgcHJveHkgcHJvcHMgb2YgRy5ldmVudCBjb252ZW5pZW50XG4gICAgICAgIC8qKiB0aGUgcmVhbCB0cmlnZ2VyIHNoYXBlIG9mIHRoZSBldmVudCAqL1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIEB0b2RvIEcg5Lit5LqL5Lu25a6a5LmJ5Li6IG9iamVjdCDkuI3mraPnoa7vvIzov5nph4zlhYggaWdub3JlXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nRXZlbnQudGFyZ2V0O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJldmVudFwiLCB7XG4gICAgICAgIC8qKiDojrflj5blr7nlupTnmoQgZG9tIOWOn+eUn+aXtumXtCAqL1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdFdmVudC5vcmlnaW5hbEV2ZW50O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJ4XCIsIHtcbiAgICAgICAgLyoqIHgg55S75biD5Z2Q5qCHICovXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ0V2ZW50Lng7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnQucHJvdG90eXBlLCBcInlcIiwge1xuICAgICAgICAvKiogeSDnlLvluIPlnZDmoIcgKi9cbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nRXZlbnQueTtcbiAgICAgICAgfSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudC5wcm90b3R5cGUsIFwiY2xpZW50WFwiLCB7XG4gICAgICAgIC8qKiB4IOeql+WPo+WdkOaghyAqL1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdFdmVudC5jbGllbnRYO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJjbGllbnRZXCIsIHtcbiAgICAgICAgLyoqIHkg56qX5Y+j5Z2Q5qCHICovXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ0V2ZW50LmNsaWVudFk7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICAvLyBlbmQgZm9yIHByb3h5IGV2ZW50c1xuICAgIC8qKlxuICAgICAqIGV2ZW50IHN0cmluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ1xuICAgICAqL1xuICAgIEV2ZW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFwiW0V2ZW50ICh0eXBlPVwiICsgdGhpcy50eXBlICsgXCIpXVwiO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogY2xvbmUgYSBuZXcgZXZlbnQgd2l0aCBzYW1lIGF0dHJpYnV0ZXNcbiAgICAgKiBAcmV0dXJucyBbW0V2ZW50XV1cbiAgICAgKi9cbiAgICBFdmVudC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgRXZlbnQodGhpcy52aWV3LCB0aGlzLmdFdmVudCwgdGhpcy5kYXRhKTtcbiAgICB9O1xuICAgIHJldHVybiBFdmVudDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFdmVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGNoYXJ0XzEgPSByZXF1aXJlKFwiLi9jaGFydFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNoYXJ0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjaGFydF8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgdmlld18xID0gcmVxdWlyZShcIi4vdmlld1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlZpZXdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZpZXdfMS5kZWZhdWx0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJHZW9tZXRyeVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdmlld18xLnJlZ2lzdGVyR2VvbWV0cnk7IH0gfSk7XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuL2V2ZW50XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuZGVmYXVsdDsgfSB9KTtcbnZhciBjb250cm9sbGVyXzEgPSByZXF1aXJlKFwiLi9jb250cm9sbGVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250cm9sbGVyXzEucmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyOyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNhbGN1bGF0ZVBhZGRpbmcgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi8uLi9jb25zdGFudFwiKTtcbnZhciBiYm94XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9iYm94XCIpO1xudmFyIHBhZGRpbmdfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3BhZGRpbmdcIik7XG52YXIgcGFkZGluZ19jYWxfMSA9IHJlcXVpcmUoXCIuL3BhZGRpbmctY2FsXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmoLnmja4gdmlldyDkuK3nmoTnu4Tku7bvvIzorqHnrpflrp7pmYXnmoQgcGFkZGluZyDmlbDlgLxcbiAqIEBwYXJhbSB2aWV3XG4gKi9cbmZ1bmN0aW9uIGNhbGN1bGF0ZVBhZGRpbmcodmlldykge1xuICAgIHZhciBwYWRkaW5nID0gdmlldy5wYWRkaW5nO1xuICAgIC8vIOWmguaenOS4jeaYryBhdXRvIHBhZGRpbmfvvIzpgqPkuYjnm7TmjqXop6PmnpDkuYvlkI7ov5Tlm55cbiAgICBpZiAoIXBhZGRpbmdfMS5pc0F1dG9QYWRkaW5nKHBhZGRpbmcpKSB7XG4gICAgICAgIHJldHVybiBwYWRkaW5nXzEucGFyc2VQYWRkaW5nKHBhZGRpbmcpO1xuICAgIH1cbiAgICAvLyDmmK8gYXV0byBwYWRkaW5n77yM5qC55o2u57uE5Lu255qE5oOF5Ya177yM5p2l6K6h566XIHBhZGRpbmdcbiAgICB2YXIgdmlld0JCb3ggPSB2aWV3LnZpZXdCQm94LCBhdXRvUGFkZGluZyA9IHZpZXcuYXV0b1BhZGRpbmc7XG4gICAgdmFyIHBhZGRpbmdDYWwgPSBuZXcgcGFkZGluZ19jYWxfMS5QYWRkaW5nQ2FsKCk7XG4gICAgdXRpbF8xLmVhY2godmlldy5nZXRDb21wb25lbnRzKCksIGZ1bmN0aW9uIChjbykge1xuICAgICAgICB2YXIgY29tcG9uZW50ID0gY28uY29tcG9uZW50LCB0eXBlID0gY28udHlwZTtcbiAgICAgICAgLy8gZ3JpZCwgdG9vbHRpcCDkuI3lj4LlhaUgcGFkZGluZyDluIPlsYBcbiAgICAgICAgaWYgKHR5cGUgPT09IGNvbnN0YW50XzEuQ09NUE9ORU5UX1RZUEUuR1JJRCB8fCB0eXBlID09PSBjb25zdGFudF8xLkNPTVBPTkVOVF9UWVBFLlRPT0xUSVApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYmJveE9iamVjdCA9IGNvbXBvbmVudC5nZXRMYXlvdXRCQm94KCk7XG4gICAgICAgIHZhciBjb21wb25lbnRCQm94ID0gbmV3IGJib3hfMS5CQm94KGJib3hPYmplY3QueCwgYmJveE9iamVjdC55LCBiYm94T2JqZWN0LndpZHRoLCBiYm94T2JqZWN0LmhlaWdodCk7XG4gICAgICAgIGlmICh0eXBlID09PSBjb25zdGFudF8xLkNPTVBPTkVOVF9UWVBFLkFYSVMpIHtcbiAgICAgICAgICAgIHZhciBleGNlZWQgPSBjb21wb25lbnRCQm94LmV4Y2VlZCh2aWV3QkJveCk7XG4gICAgICAgICAgICBwYWRkaW5nQ2FsLnNocmluayhleGNlZWQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5oyJ54Wn5pa55ZCR6K6h566XIHBhZGRpbmdcbiAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSBjby5kaXJlY3Rpb247XG4gICAgICAgICAgICAvLyBjb25zdCBkaXJlY3Rpb24gPVxuICAgICAgICAgICAgLy8gICB0eXBlID09PSBDT01QT05FTlRfVFlQRS5BWElTID8gZ2V0VHJhbnNsYXRlRGlyZWN0aW9uKGNvLmRpcmVjdGlvbiwgdmlldy5nZXRDb29yZGluYXRlKCkpIDogY28uZGlyZWN0aW9uO1xuICAgICAgICAgICAgcGFkZGluZ0NhbC5pbmMoY29tcG9uZW50QkJveCwgZGlyZWN0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHZhciBjYWxjdWxhdGVkUGFkZGluZyA9IHBhZGRpbmdDYWwuZ2V0UGFkZGluZygpO1xuICAgIGlmIChhdXRvUGFkZGluZykge1xuICAgICAgICB2YXIgYXBwZW5kUGFkZGluZyA9IHBhZGRpbmdfMS5wYXJzZVBhZGRpbmcodmlldy5hcHBlbmRQYWRkaW5nKTtcbiAgICAgICAgLy8g5Y+W5LiK5LiA5qyh5Lul5Y+K5b2T5YmN6K6h566X57uT5p6c55qE5pyA5aSn5Yy66Ze0XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBNYXRoLm1heChhdXRvUGFkZGluZ1swXSAtIGFwcGVuZFBhZGRpbmdbMF0sIGNhbGN1bGF0ZWRQYWRkaW5nWzBdKSxcbiAgICAgICAgICAgIE1hdGgubWF4KGF1dG9QYWRkaW5nWzFdIC0gYXBwZW5kUGFkZGluZ1sxXSwgY2FsY3VsYXRlZFBhZGRpbmdbMV0pLFxuICAgICAgICAgICAgTWF0aC5tYXgoYXV0b1BhZGRpbmdbMl0gLSBhcHBlbmRQYWRkaW5nWzJdLCBjYWxjdWxhdGVkUGFkZGluZ1syXSksXG4gICAgICAgICAgICBNYXRoLm1heChhdXRvUGFkZGluZ1szXSAtIGFwcGVuZFBhZGRpbmdbM10sIGNhbGN1bGF0ZWRQYWRkaW5nWzNdKSxcbiAgICAgICAgXTtcbiAgICB9XG4gICAgcmV0dXJuIGNhbGN1bGF0ZWRQYWRkaW5nO1xufVxuZXhwb3J0cy5jYWxjdWxhdGVQYWRkaW5nID0gY2FsY3VsYXRlUGFkZGluZztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1dG8uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgcGFkZGluZ18xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvcGFkZGluZ1wiKTtcbnZhciBhdXRvXzEgPSByZXF1aXJlKFwiLi9hdXRvXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBHMiDpu5jorqTmj5DkvpvnmoQgbGF5b3V0IOWHveaVsFxuICog5YaF572u5biD5bGA5Ye95pWw5aSE55CG55qE6YC76L6R77yaXG4gKlxuICogMS4g5aaC5p6cIHBhZGRpbmcgPSAnYXV0byfvvIzpgqPkuYjoh6rliqjmoLnmja7nu4Tku7bnmoQgZGlyZWN0aW9uIOadpeiuoeeulyBwYWRkaW5nIOaVsOe7hFxuICogMi4g5qC55o2uIHBhZGRpbmcg5ZKMIGRpcmVjdGlvbiDljrvliIbphY3lr7nlupTmlrnlkJHnmoQgcGFkZGluZyDmlbDlgLxcbiAqIDMuIOenu+WKqOe7hOS7tuS9jee9rlxuICpcbiAqIOWvueS6jue7hOS7tuWTjeW6lOW8j+W4g+WxgO+8jOWPr+S7peWwneivleS9v+eUqOe6puadn+W4g+WxgOeahOaWueW8j+WOu+axguino+S9jee9ruS/oeaBr+OAglxuICogQHBhcmFtIHZpZXdcbiAqL1xuZnVuY3Rpb24gZGVmYXVsdExheW91dCh2aWV3KSB7XG4gICAgdmFyIGF4aXMgPSB2aWV3LmdldENvbnRyb2xsZXIoJ2F4aXMnKTtcbiAgICB2YXIgbGVnZW5kID0gdmlldy5nZXRDb250cm9sbGVyKCdsZWdlbmQnKTtcbiAgICB2YXIgYW5ub3RhdGlvbiA9IHZpZXcuZ2V0Q29udHJvbGxlcignYW5ub3RhdGlvbicpO1xuICAgIHZhciBzbGlkZXIgPSB2aWV3LmdldENvbnRyb2xsZXIoJ3NsaWRlcicpO1xuICAgIC8vIDEuIOiHquWKqOWKoCBhdXRvIHBhZGRpbmcgLT4gYWJzb2x1dGUgcGFkZGluZ1xuICAgIHZhciBwYWRkaW5nID0gYXV0b18xLmNhbGN1bGF0ZVBhZGRpbmcodmlldyk7XG4gICAgLy8gMi4g6K6h566X5Ye65paw55qEIGNvb3JkaW5hdGVCQm94XG4gICAgdmlldy5jb29yZGluYXRlQkJveCA9IHZpZXcudmlld0JCb3guc2hyaW5rKHBhZGRpbmcpLnNocmluayhwYWRkaW5nXzEucGFyc2VQYWRkaW5nKHZpZXcuYXBwZW5kUGFkZGluZykpO1xuICAgIHZpZXcuYWRqdXN0Q29vcmRpbmF0ZSgpO1xuICAgIC8vIDMuIOagueaNruacgOaWsOeahCBjb29yZGluYXRlIOmHjeaWsOW4g+WxgOe7hOS7tlxuICAgIFtheGlzLCBzbGlkZXIsIGxlZ2VuZCwgYW5ub3RhdGlvbl0uZm9yRWFjaChmdW5jdGlvbiAoY29udHJvbGxlcikge1xuICAgICAgICBpZiAoY29udHJvbGxlcikge1xuICAgICAgICAgICAgY29udHJvbGxlci5sYXlvdXQoKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZGVmYXVsdExheW91dDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5QYWRkaW5nQ2FsID0gdm9pZCAwO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vLi4vY29uc3RhbnRcIik7XG4vKiogQGlnbm9yZSAqL1xudmFyIFBhZGRpbmdDYWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICog5Yid5aeL55qEIHBhZGRpbmcg5pWw5o2uXG4gICAgICogQHBhcmFtIHRvcFxuICAgICAqIEBwYXJhbSByaWdodFxuICAgICAqIEBwYXJhbSBib3R0b21cbiAgICAgKiBAcGFyYW0gbGVmdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFBhZGRpbmdDYWwodG9wLCByaWdodCwgYm90dG9tLCBsZWZ0KSB7XG4gICAgICAgIGlmICh0b3AgPT09IHZvaWQgMCkgeyB0b3AgPSAwOyB9XG4gICAgICAgIGlmIChyaWdodCA9PT0gdm9pZCAwKSB7IHJpZ2h0ID0gMDsgfVxuICAgICAgICBpZiAoYm90dG9tID09PSB2b2lkIDApIHsgYm90dG9tID0gMDsgfVxuICAgICAgICBpZiAobGVmdCA9PT0gdm9pZCAwKSB7IGxlZnQgPSAwOyB9XG4gICAgICAgIHRoaXMudG9wID0gdG9wO1xuICAgICAgICB0aGlzLnJpZ2h0ID0gcmlnaHQ7XG4gICAgICAgIHRoaXMuYm90dG9tID0gYm90dG9tO1xuICAgICAgICB0aGlzLmxlZnQgPSBsZWZ0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDlm5vlkajlop7liqAgcGFkZGluZ1xuICAgICAqIEBwYXJhbSBwYWRkaW5nXG4gICAgICovXG4gICAgUGFkZGluZ0NhbC5wcm90b3R5cGUuc2hyaW5rID0gZnVuY3Rpb24gKHBhZGRpbmcpIHtcbiAgICAgICAgdmFyIHRvcCA9IHBhZGRpbmdbMF0sIHJpZ2h0ID0gcGFkZGluZ1sxXSwgYm90dG9tID0gcGFkZGluZ1syXSwgbGVmdCA9IHBhZGRpbmdbM107XG4gICAgICAgIHRoaXMudG9wICs9IHRvcDtcbiAgICAgICAgdGhpcy5yaWdodCArPSByaWdodDtcbiAgICAgICAgdGhpcy5ib3R0b20gKz0gYm90dG9tO1xuICAgICAgICB0aGlzLmxlZnQgKz0gbGVmdDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlnKjmn5DkuIDkuKrmlrnlkJHlop7liqAgcGFkZGluZ1xuICAgICAqIEBwYXJhbSBiYm94XG4gICAgICogQHBhcmFtIGRpcmVjdGlvblxuICAgICAqL1xuICAgIFBhZGRpbmdDYWwucHJvdG90eXBlLmluYyA9IGZ1bmN0aW9uIChiYm94LCBkaXJlY3Rpb24pIHtcbiAgICAgICAgdmFyIHdpZHRoID0gYmJveC53aWR0aCwgaGVpZ2h0ID0gYmJveC5oZWlnaHQ7XG4gICAgICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUDpcbiAgICAgICAgICAgIGNhc2UgY29uc3RhbnRfMS5ESVJFQ1RJT04uVE9QX0xFRlQ6XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUF9SSUdIVDpcbiAgICAgICAgICAgICAgICB0aGlzLnRvcCArPSBoZWlnaHQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVF9UT1A6XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUX0JPVFRPTTpcbiAgICAgICAgICAgICAgICB0aGlzLnJpZ2h0ICs9IHdpZHRoO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT006XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTV9MRUZUOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT01fUklHSFQ6XG4gICAgICAgICAgICAgICAgdGhpcy5ib3R0b20gKz0gaGVpZ2h0O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUX1RPUDpcbiAgICAgICAgICAgIGNhc2UgY29uc3RhbnRfMS5ESVJFQ1RJT04uTEVGVF9CT1RUT006XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0ICs9IHdpZHRoO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+W+l+acgOe7iOeahCBwYWRkaW5nXG4gICAgICovXG4gICAgUGFkZGluZ0NhbC5wcm90b3R5cGUuZ2V0UGFkZGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFt0aGlzLnRvcCwgdGhpcy5yaWdodCwgdGhpcy5ib3R0b20sIHRoaXMubGVmdF07XG4gICAgfTtcbiAgICByZXR1cm4gUGFkZGluZ0NhbDtcbn0oKSk7XG5leHBvcnRzLlBhZGRpbmdDYWwgPSBQYWRkaW5nQ2FsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFkZGluZy1jYWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlNjYWxlUG9vbCA9IHZvaWQgMDtcbi8qKlxuICogdmlldyDkuK3nvJPlrZggc2NhbGUg55qE57G7XG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvc2NhbGVcIik7XG4vKiogQGlnbm9yZSAqL1xudmFyIFNjYWxlUG9vbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTY2FsZVBvb2woKSB7XG4gICAgICAgIC8qKiDmiYDmnInnmoQgc2NhbGVzICovXG4gICAgICAgIHRoaXMuc2NhbGVzID0gbmV3IE1hcCgpO1xuICAgICAgICAvKiog6ZyA6KaB5ZCM5q2l55qEIHNjYWxlIOWIhue7hO+8jCBrZXk6IHNjYWxlS2V5QXJyYXkgKi9cbiAgICAgICAgdGhpcy5zeW5jU2NhbGVzID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDliJvlu7ogc2NhbGVcbiAgICAgKiBAcGFyYW0gZmllbGRcbiAgICAgKiBAcGFyYW0gZGF0YVxuICAgICAqIEBwYXJhbSBzY2FsZURlZlxuICAgICAqIEBwYXJhbSBrZXlcbiAgICAgKi9cbiAgICBTY2FsZVBvb2wucHJvdG90eXBlLmNyZWF0ZVNjYWxlID0gZnVuY3Rpb24gKGZpZWxkLCBkYXRhLCBzY2FsZURlZiwga2V5KSB7XG4gICAgICAgIHZhciBmaW5hbFNjYWxlRGVmID0gc2NhbGVEZWY7XG4gICAgICAgIHZhciBjYWNoZVNjYWxlTWV0YSA9IHRoaXMuZ2V0U2NhbGVNZXRhKGtleSk7XG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCAmJiBjYWNoZVNjYWxlTWV0YSkge1xuICAgICAgICAgICAgLy8g5Zyo5pu05paw6L+H56iL5Lit5pWw5o2u5Y+Y5Li656m677yM5ZCM5pe2IGtleSDlr7nlupTnmoQgc2NhbGUg5bey5a2Y5Zyo5YiZ5L+d5oyBIHNjYWxlIOWQjOexu+Wei1xuICAgICAgICAgICAgdmFyIGNhY2hlU2NhbGUgPSBjYWNoZVNjYWxlTWV0YS5zY2FsZTtcbiAgICAgICAgICAgIHZhciBjYWNoZVNjYWxlRGVmID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6IGNhY2hlU2NhbGUudHlwZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY2FjaGVTY2FsZS5pc0NhdGVnb3J5KSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5piv5YiG57G757G75Z6L77yM5L+d5oyBIHZhbHVlc1xuICAgICAgICAgICAgICAgIGNhY2hlU2NhbGVEZWYudmFsdWVzID0gY2FjaGVTY2FsZS52YWx1ZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbFNjYWxlRGVmID0gdXRpbF8xLmRlZXBNaXgoY2FjaGVTY2FsZURlZiwgY2FjaGVTY2FsZU1ldGEuc2NhbGVEZWYsIHNjYWxlRGVmKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2NhbGUgPSBzY2FsZV8xLmNyZWF0ZVNjYWxlQnlGaWVsZChmaWVsZCwgZGF0YSwgZmluYWxTY2FsZURlZik7XG4gICAgICAgIC8vIOe8k+WtmOi1t+adpVxuICAgICAgICB0aGlzLmNhY2hlU2NhbGUoc2NhbGUsIHNjYWxlRGVmLCBrZXkpO1xuICAgICAgICByZXR1cm4gc2NhbGU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlkIzmraUgc2NhbGVcbiAgICAgKi9cbiAgICBTY2FsZVBvb2wucHJvdG90eXBlLnN5bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIC8vIOWvueS6jiBzeW5jU2NhbGVzIOS4reavj+S4gOS4qiBzeW5jS2V5IOS4i+mdoueahCBzY2FsZSDmlbDnu4Tov5vooYzlkIzmraXlpITnkIZcbiAgICAgICAgdGhpcy5zeW5jU2NhbGVzLmZvckVhY2goZnVuY3Rpb24gKHNjYWxlS2V5cywgc3luY0tleSkge1xuICAgICAgICAgICAgLy8gbWluLCBtYXgsIHZhbHVlc1xuICAgICAgICAgICAgdmFyIG1pbiA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgICAgICAgICAgdmFyIG1heCA9IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSO1xuICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgICAgICAgLy8gMS4g6YGN5Y6G5rGC5b6X5pyA5aSn5pyA5bCP5YC877yMdmFsdWVzIOetiVxuICAgICAgICAgICAgdXRpbF8xLmVhY2goc2NhbGVLZXlzLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgdmFyIHNjYWxlID0gX3RoaXMuZ2V0U2NhbGUoa2V5KTtcbiAgICAgICAgICAgICAgICBtYXggPSB1dGlsXzEuaXNOdW1iZXIoc2NhbGUubWF4KSA/IE1hdGgubWF4KG1heCwgc2NhbGUubWF4KSA6IG1heDtcbiAgICAgICAgICAgICAgICBtaW4gPSB1dGlsXzEuaXNOdW1iZXIoc2NhbGUubWluKSA/IE1hdGgubWluKG1pbiwgc2NhbGUubWluKSA6IG1pbjtcbiAgICAgICAgICAgICAgICAvLyDljrvph41cbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChzY2FsZS52YWx1ZXMsIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVzLmluY2x1ZGVzKHYpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCh2KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyAyLiDlkIzmraVcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHNjYWxlS2V5cywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgIHZhciBzY2FsZSA9IF90aGlzLmdldFNjYWxlKGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKHNjYWxlLmlzQ29udGludW91cykge1xuICAgICAgICAgICAgICAgICAgICBzY2FsZS5jaGFuZ2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluOiBtaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXg6IG1heCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoc2NhbGUuaXNDYXRlZ29yeSkge1xuICAgICAgICAgICAgICAgICAgICBzY2FsZS5jaGFuZ2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe8k+WtmOS4gOS4qiBzY2FsZVxuICAgICAqIEBwYXJhbSBzY2FsZVxuICAgICAqIEBwYXJhbSBzY2FsZURlZlxuICAgICAqIEBwYXJhbSBrZXlcbiAgICAgKi9cbiAgICBTY2FsZVBvb2wucHJvdG90eXBlLmNhY2hlU2NhbGUgPSBmdW5jdGlvbiAoc2NhbGUsIHNjYWxlRGVmLCBrZXkpIHtcbiAgICAgICAgLy8gMS4g57yT5a2Y5YiwIHNjYWxlc1xuICAgICAgICB2YXIgc20gPSB0aGlzLmdldFNjYWxlTWV0YShrZXkpO1xuICAgICAgICAvLyDlrZjlnKjliJnmm7TmlrDvvIzlkIzml7bmo4DmtYvnsbvlnovmmK/lkKbkuIDoh7RcbiAgICAgICAgaWYgKHNtICYmIHNtLnNjYWxlLnR5cGUgPT09IHNjYWxlLnR5cGUpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuc3luY1NjYWxlKHNtLnNjYWxlLCBzY2FsZSk7XG4gICAgICAgICAgICBzbS5zY2FsZURlZiA9IHNjYWxlRGVmO1xuICAgICAgICAgICAgLy8g5pu05pawIHNjYWxlRGVmXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzbSA9IHtcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgICAgICAgICAgc2NhbGVEZWY6IHNjYWxlRGVmLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuc2NhbGVzLnNldChrZXksIHNtKTtcbiAgICAgICAgfVxuICAgICAgICAvLyAyLiDnvJPlrZjliLAgc3luY1NjYWxlc++8jOaehOmAoCBSZWNvcmQ8c3luYywgc3RyaW5nW10+IOaVsOaNrue7k+aehFxuICAgICAgICB2YXIgc3luY0tleSA9IHRoaXMuZ2V0U3luY0tleShzbSk7XG4gICAgICAgIHNtLnN5bmNLZXkgPSBzeW5jS2V5OyAvLyDorr7nva4gc3luYyDlkIzmraXnmoQga2V5XG4gICAgICAgIC8vIOWboOS4uuWtmOWcqOabtOaWsCBzY2FsZSDmnLrliLbvvIzmiYDku6XlnKjnvJPlrZjkuYvliY3vvIzlhYjku47ljp8gc3luY1NjYWxlcyDkuK3ljrvpmaQgc3luYyDnmoTnvJPlrZjlvJXnlKhcbiAgICAgICAgdGhpcy5yZW1vdmVGcm9tU3luY1NjYWxlcyhrZXkpO1xuICAgICAgICAvLyDlrZjlnKggc3luYyDmoIforrDmiY3ov5vooYwgc3luY1xuICAgICAgICBpZiAoc3luY0tleSkge1xuICAgICAgICAgICAgLy8g5LiN5a2Y5Zyo6L+Z5LiqIHN5bmNLZXnvvIzliJnliJvlu7rkuIDkuKrnqbrmlbDnu4RcbiAgICAgICAgICAgIHZhciBzY2FsZUtleXMgPSB0aGlzLnN5bmNTY2FsZXMuZ2V0KHN5bmNLZXkpO1xuICAgICAgICAgICAgaWYgKCFzY2FsZUtleXMpIHtcbiAgICAgICAgICAgICAgICBzY2FsZUtleXMgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLnN5bmNTY2FsZXMuc2V0KHN5bmNLZXksIHNjYWxlS2V5cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzY2FsZUtleXMucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpgJrov4cga2V5IOiOt+WPliBzY2FsZVxuICAgICAqIEBwYXJhbSBrZXlcbiAgICAgKi9cbiAgICBTY2FsZVBvb2wucHJvdG90eXBlLmdldFNjYWxlID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgc2NhbGVNZXRhID0gdGhpcy5nZXRTY2FsZU1ldGEoa2V5KTtcbiAgICAgICAgaWYgKCFzY2FsZU1ldGEpIHtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IHV0aWxfMS5sYXN0KGtleS5zcGxpdCgnLScpKTtcbiAgICAgICAgICAgIHZhciBzY2FsZUtleXMgPSB0aGlzLnN5bmNTY2FsZXMuZ2V0KGZpZWxkKTtcbiAgICAgICAgICAgIGlmIChzY2FsZUtleXMgJiYgc2NhbGVLZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHNjYWxlTWV0YSA9IHRoaXMuZ2V0U2NhbGVNZXRhKHNjYWxlS2V5c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjYWxlTWV0YSAmJiBzY2FsZU1ldGEuc2NhbGU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlnKggdmlldyDplIDmr4HnmoTml7blgJnvvIzliKDpmaQgc2NhbGUg5a6e5L6L77yM6Ziy5q2i5YaF5a2Y5rOE6ZyyXG4gICAgICogQHBhcmFtIGtleVxuICAgICAqL1xuICAgIFNjYWxlUG9vbC5wcm90b3R5cGUuZGVsZXRlU2NhbGUgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciBzY2FsZU1ldGEgPSB0aGlzLmdldFNjYWxlTWV0YShrZXkpO1xuICAgICAgICBpZiAoc2NhbGVNZXRhKSB7XG4gICAgICAgICAgICB2YXIgc3luY0tleSA9IHNjYWxlTWV0YS5zeW5jS2V5O1xuICAgICAgICAgICAgdmFyIHNjYWxlS2V5cyA9IHRoaXMuc3luY1NjYWxlcy5nZXQoc3luY0tleSk7XG4gICAgICAgICAgICAvLyDnp7vpmaTlkIzmraXnmoTlhbPns7tcbiAgICAgICAgICAgIGlmIChzY2FsZUtleXMgJiYgc2NhbGVLZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHZhciBpZHggPSBzY2FsZUtleXMuaW5kZXhPZihrZXkpO1xuICAgICAgICAgICAgICAgIGlmIChpZHggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjYWxlS2V5cy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Yig6ZmkIHNjYWxlIOWunuS+i1xuICAgICAgICB0aGlzLnNjYWxlcy5kZWxldGUoa2V5KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOa4heepulxuICAgICAqL1xuICAgIFNjYWxlUG9vbC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2NhbGVzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuc3luY1NjYWxlcy5jbGVhcigpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yig6ZmkIHN5bmMgc2NhbGUg5byV55SoXG4gICAgICogQHBhcmFtIGtleVxuICAgICAqL1xuICAgIFNjYWxlUG9vbC5wcm90b3R5cGUucmVtb3ZlRnJvbVN5bmNTY2FsZXMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuc3luY1NjYWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChzY2FsZUtleXMsIHN5bmNLZXkpIHtcbiAgICAgICAgICAgIHZhciBpZHggPSBzY2FsZUtleXMuaW5kZXhPZihrZXkpO1xuICAgICAgICAgICAgaWYgKGlkeCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBzY2FsZUtleXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgICAgLy8g5Yig6Zmk56m65pWw57uE5YC8XG4gICAgICAgICAgICAgICAgaWYgKHNjYWxlS2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc3luY1NjYWxlcy5kZWxldGUoc3luY0tleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8g6Lez5Ye65b6q546vXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogZ2V0IHN5bmMga2V5XG4gICAgICogQHBhcmFtIHNtXG4gICAgICovXG4gICAgU2NhbGVQb29sLnByb3RvdHlwZS5nZXRTeW5jS2V5ID0gZnVuY3Rpb24gKHNtKSB7XG4gICAgICAgIHZhciBzY2FsZSA9IHNtLnNjYWxlLCBzY2FsZURlZiA9IHNtLnNjYWxlRGVmO1xuICAgICAgICB2YXIgZmllbGQgPSBzY2FsZS5maWVsZDtcbiAgICAgICAgdmFyIHN5bmMgPSB1dGlsXzEuZ2V0KHNjYWxlRGVmLCBbJ3N5bmMnXSk7XG4gICAgICAgIC8vIOWmguaenCBzeW5jID0gdHJ1Ze+8jOWImeebtOaOpeS9v+eUqOWtl+auteWQjeS9nOS4uiBzeW5jS2V5XG4gICAgICAgIHJldHVybiBzeW5jID09PSB0cnVlID8gZmllbGQgOiBzeW5jID09PSBmYWxzZSA/IHVuZGVmaW5lZCA6IHN5bmM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpgJrov4cga2V5IOiOt+WPliBzY2FsZVxuICAgICAqIEBwYXJhbSBrZXlcbiAgICAgKi9cbiAgICBTY2FsZVBvb2wucHJvdG90eXBlLmdldFNjYWxlTWV0YSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2NhbGVzLmdldChrZXkpO1xuICAgIH07XG4gICAgcmV0dXJuIFNjYWxlUG9vbDtcbn0oKSk7XG5leHBvcnRzLlNjYWxlUG9vbCA9IFNjYWxlUG9vbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNjYWxlLXBvb2wuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyR2VvbWV0cnkgPSBleHBvcnRzLlZpZXcgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciBmYWNldF8xID0gcmVxdWlyZShcIi4uL2ZhY2V0XCIpO1xudmFyIGludGVyYWN0aW9uXzEgPSByZXF1aXJlKFwiLi4vaW50ZXJhY3Rpb25cIik7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi90aGVtZVwiKTtcbnZhciBiYm94XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9iYm94XCIpO1xudmFyIGNvb3JkaW5hdGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2Nvb3JkaW5hdGVcIik7XG52YXIgaGVscGVyXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9oZWxwZXJcIik7XG52YXIgdG9vbHRpcF8xID0gcmVxdWlyZShcIi4uL3V0aWwvdG9vbHRpcFwiKTtcbnZhciBjb250cm9sbGVyXzEgPSByZXF1aXJlKFwiLi9jb250cm9sbGVyXCIpO1xudmFyIGNvb3JkaW5hdGVfMiA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbnRyb2xsZXIvY29vcmRpbmF0ZVwiKSk7XG52YXIgZXZlbnRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnZhciBsYXlvdXRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheW91dFwiKSk7XG52YXIgc2NhbGVfcG9vbF8xID0gcmVxdWlyZShcIi4vdXRpbC9zY2FsZS1wb29sXCIpO1xudmFyIHBhZGRpbmdfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3BhZGRpbmdcIik7XG4vKipcbiAqIEcyIOinhuWbviBWaWV3IOexu1xuICovXG52YXIgVmlldyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhWaWV3LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFZpZXcocHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgeyB2aXNpYmxlOiBwcm9wcy52aXNpYmxlIH0pIHx8IHRoaXM7XG4gICAgICAgIC8qKiB2aWV3IGlk77yM5YWo5bGA5ZSv5LiA44CCICovXG4gICAgICAgIF90aGlzLmlkID0gdXRpbF8xLnVuaXF1ZUlkKCd2aWV3Jyk7XG4gICAgICAgIC8qKiDmiYDmnInnmoTlrZAgdmlld+OAgiAqL1xuICAgICAgICBfdGhpcy52aWV3cyA9IFtdO1xuICAgICAgICAvKiog5omA5pyJ55qEIGdlb21ldHJ5IOWunuS+i+OAgiAqL1xuICAgICAgICBfdGhpcy5nZW9tZXRyaWVzID0gW107XG4gICAgICAgIC8qKiDmiYDmnInnmoTnu4Tku7YgY29udHJvbGxlcnPjgIIgKi9cbiAgICAgICAgX3RoaXMuY29udHJvbGxlcnMgPSBbXTtcbiAgICAgICAgLyoqIOaJgOacieeahCBJbnRlcmFjdGlvbiDlrp7kvovjgIIgKi9cbiAgICAgICAgX3RoaXMuaW50ZXJhY3Rpb25zID0ge307XG4gICAgICAgIC8qKiDmmK/lkKblr7notoXlh7rlnZDmoIfns7vojIPlm7TnmoQgR2VvbWV0cnkg6L+b6KGM5Ymq5YiHICovXG4gICAgICAgIF90aGlzLmxpbWl0SW5QbG90ID0gZmFsc2U7XG4gICAgICAgIC8vIOmFjee9ruS/oeaBr+WtmOWCqFxuICAgICAgICBfdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICBhbmltYXRlOiB0cnVlLFxuICAgICAgICB9OyAvLyDliJ3lp4vljJbkuLrnqbpcbiAgICAgICAgLyoqIOmFjee9ruW8gOWQr+eahOe7hOS7tuaPkuS7tu+8jOm7mOiupOS4uuWFqOWxgOmFjee9rueahOe7hOS7tuOAgiAqL1xuICAgICAgICBfdGhpcy51c2VkQ29udHJvbGxlcnMgPSBjb250cm9sbGVyXzEuZ2V0Q29tcG9uZW50Q29udHJvbGxlck5hbWVzKCk7XG4gICAgICAgIC8qKiDmiYDmnInnmoQgc2NhbGVzICovXG4gICAgICAgIF90aGlzLnNjYWxlUG9vbCA9IG5ldyBzY2FsZV9wb29sXzEuU2NhbGVQb29sKCk7XG4gICAgICAgIC8qKiDluIPlsYDlh73mlbAgKi9cbiAgICAgICAgX3RoaXMubGF5b3V0RnVuYyA9IGxheW91dF8xLmRlZmF1bHQ7XG4gICAgICAgIC8qKiDlvZPliY3pvKDmoIfmmK/lkKblnKggcGxvdCDlhoXvvIhDb29yZGluYXRlQkJveO+8iSAqL1xuICAgICAgICBfdGhpcy5pc1ByZU1vdXNlSW5QbG90ID0gZmFsc2U7XG4gICAgICAgIC8qKiDpu5jorqTmoIfor4bkvY3vvIznlKjkuo7liKTlrprmlbDmja7mmK/lkKbmm7TmlrAgKi9cbiAgICAgICAgX3RoaXMuaXNEYXRhQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICAvKiog55So5LqO5Yik5pat5Z2Q5qCH57O76IyD5Zu05piv5ZCm5Y+R55Sf5Y+Y5YyW55qE5qCH5b+X5L2NICovXG4gICAgICAgIF90aGlzLmlzQ29vcmRpbmF0ZUNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqIOS7juW9k+WJjei/meS4qiB2aWV3IOWIm+W7uueahCBzY2FsZSBrZXkgKi9cbiAgICAgICAgX3RoaXMuY3JlYXRlZFNjYWxlS2V5cyA9IG5ldyBNYXAoKTtcbiAgICAgICAgX3RoaXMub25DYW52YXNFdmVudCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgICAgIHZhciBuYW1lID0gZXZ0Lm5hbWU7XG4gICAgICAgICAgICBpZiAoIW5hbWUuaW5jbHVkZXMoJzonKSkge1xuICAgICAgICAgICAgICAgIC8vIOmdnuWnlOaJmOS6i+S7tlxuICAgICAgICAgICAgICAgIHZhciBlID0gX3RoaXMuY3JlYXRlVmlld0V2ZW50KGV2dCk7XG4gICAgICAgICAgICAgICAgLy8g5aSE55CGIHBsb3Qg5LqL5Lu2XG4gICAgICAgICAgICAgICAgX3RoaXMuZG9QbG90RXZlbnQoZSk7XG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdChuYW1lLCBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOinpuWPkeS6i+S7tuS5i+WQjlxuICAgICAgICAgKiBAcGFyYW0gZXZ0XG4gICAgICAgICAqL1xuICAgICAgICBfdGhpcy5vbkRlbGVnYXRlRXZlbnRzID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICAgICAgLy8g6Zi75q2i57un57ut5YaS5rOh77yM6Ziy5q2i6YeN5aSN5LqL5Lu26Kem5Y+RXG4gICAgICAgICAgICAvLyBldnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHZhciBuYW1lID0gZXZ0Lm5hbWU7XG4gICAgICAgICAgICBpZiAoIW5hbWUuaW5jbHVkZXMoJzonKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIOS6i+S7tuWcqCB2aWV3IOW1jOWll+S4reWGkuazoe+8iOaaguS4jeaPkOS+m+mYu+atouWGkuazoeeahOacuuWItu+8iVxuICAgICAgICAgICAgdmFyIGUgPSBfdGhpcy5jcmVhdGVWaWV3RXZlbnQoZXZ0KTtcbiAgICAgICAgICAgIC8vIOWMheWQq+acieWfuuacrOS6i+S7tuOAgee7hOWQiOS6i+S7tlxuICAgICAgICAgICAgX3RoaXMuZW1pdChuYW1lLCBlKTtcbiAgICAgICAgICAgIC8vIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBldnQuY3VycmVudFRhcmdldCBhcyBJU2hhcGU7XG4gICAgICAgICAgICAvLyBjb25zdCBpbmhlcml0TmFtZXMgPSBjdXJyZW50VGFyZ2V0LmdldCgnaW5oZXJpdE5hbWVzJyk7XG4gICAgICAgICAgICAvLyBpZiAoZXZ0LmRlbGVnYXRlT2JqZWN0IHx8IGluaGVyaXROYW1lcykge1xuICAgICAgICAgICAgLy8gICBjb25zdCBldmVudHMgPSB0aGlzLmdldEV2ZW50cygpO1xuICAgICAgICAgICAgLy8gICBlYWNoKGluaGVyaXROYW1lcywgKHN1Yk5hbWUpID0+IHtcbiAgICAgICAgICAgIC8vICAgICBjb25zdCBldmVudE5hbWUgPSBgJHtzdWJOYW1lfToke3R5cGV9YDtcbiAgICAgICAgICAgIC8vICAgICBpZiAoZXZlbnRzW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgICAgIC8vICAgICAgIHRoaXMuZW1pdChldmVudE5hbWUsIGUpO1xuICAgICAgICAgICAgLy8gICAgIH1cbiAgICAgICAgICAgIC8vICAgfSk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH07XG4gICAgICAgIHZhciBwYXJlbnQgPSBwcm9wcy5wYXJlbnQsIGNhbnZhcyA9IHByb3BzLmNhbnZhcywgYmFja2dyb3VuZEdyb3VwID0gcHJvcHMuYmFja2dyb3VuZEdyb3VwLCBtaWRkbGVHcm91cCA9IHByb3BzLm1pZGRsZUdyb3VwLCBmb3JlZ3JvdW5kR3JvdXAgPSBwcm9wcy5mb3JlZ3JvdW5kR3JvdXAsIF9hID0gcHJvcHMucmVnaW9uLCByZWdpb24gPSBfYSA9PT0gdm9pZCAwID8geyBzdGFydDogeyB4OiAwLCB5OiAwIH0sIGVuZDogeyB4OiAxLCB5OiAxIH0gfSA6IF9hLCBwYWRkaW5nID0gcHJvcHMucGFkZGluZywgYXBwZW5kUGFkZGluZyA9IHByb3BzLmFwcGVuZFBhZGRpbmcsIHRoZW1lID0gcHJvcHMudGhlbWUsIG9wdGlvbnMgPSBwcm9wcy5vcHRpb25zLCBsaW1pdEluUGxvdCA9IHByb3BzLmxpbWl0SW5QbG90O1xuICAgICAgICBfdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIF90aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICAgICAgX3RoaXMuYmFja2dyb3VuZEdyb3VwID0gYmFja2dyb3VuZEdyb3VwO1xuICAgICAgICBfdGhpcy5taWRkbGVHcm91cCA9IG1pZGRsZUdyb3VwO1xuICAgICAgICBfdGhpcy5mb3JlZ3JvdW5kR3JvdXAgPSBmb3JlZ3JvdW5kR3JvdXA7XG4gICAgICAgIF90aGlzLnJlZ2lvbiA9IHJlZ2lvbjtcbiAgICAgICAgX3RoaXMucGFkZGluZyA9IHBhZGRpbmc7XG4gICAgICAgIF90aGlzLmFwcGVuZFBhZGRpbmcgPSBhcHBlbmRQYWRkaW5nO1xuICAgICAgICAvLyDmjqXlj5fniLYgdmlldyDkvKDlhaXnmoTlj4LmlbBcbiAgICAgICAgX3RoaXMub3B0aW9ucyA9IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgX3RoaXMub3B0aW9ucyksIG9wdGlvbnMpO1xuICAgICAgICBfdGhpcy5saW1pdEluUGxvdCA9IGxpbWl0SW5QbG90O1xuICAgICAgICAvLyDliJ3lp4vljJYgdGhlbWVcbiAgICAgICAgX3RoaXMudGhlbWVPYmplY3QgPSB1dGlsXzEuaXNPYmplY3QodGhlbWUpID8gdXRpbF8xLmRlZXBNaXgoe30sIHRoZW1lXzEuZ2V0VGhlbWUoJ2RlZmF1bHQnKSwgdGhlbWUpIDogdGhlbWVfMS5nZXRUaGVtZSh0aGVtZSk7XG4gICAgICAgIF90aGlzLmluaXQoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDorr7nva4gbGF5b3V0IOW4g+WxgOWHveaVsFxuICAgICAqIEBwYXJhbSBsYXlvdXQg5biD5bGA5Ye95pWwXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLnNldExheW91dCA9IGZ1bmN0aW9uIChsYXlvdXQpIHtcbiAgICAgICAgdGhpcy5sYXlvdXRGdW5jID0gbGF5b3V0O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog55Sf5ZG95ZGo5pyf77ya5Yid5aeL5YyWXG4gICAgICogQHJldHVybnMgdm9pZHNcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDorqHnrpfnlLvluIPnmoQgdmlld0JCb3hcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVWaWV3QkJveCgpO1xuICAgICAgICAvLyDkuovku7blp5TmiZjmnLrliLZcbiAgICAgICAgdGhpcy5pbml0RXZlbnRzKCk7XG4gICAgICAgIC8vIOWIneWni+WMlue7hOS7tiBjb250cm9sbGVyXG4gICAgICAgIHRoaXMuaW5pdENvbXBvbmVudENvbnRyb2xsZXIoKTtcbiAgICAgICAgLy8g5Yib5bu6IGNvb3JkaW5hdGUgY29udHJvbGxlclxuICAgICAgICB0aGlzLmNvb3JkaW5hdGVDb250cm9sbGVyID0gbmV3IGNvb3JkaW5hdGVfMi5kZWZhdWx0KHRoaXMub3B0aW9ucy5jb29yZGluYXRlKTtcbiAgICAgICAgdGhpcy5pbml0T3B0aW9ucygpO1xuICAgICAgICAvLyDpgJLlvZLliJ3lp4vljJblrZAgdmlld1xuICAgICAgICB2YXIgdmlld3MgPSB0aGlzLnZpZXdzO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2aWV3c1tpXS5pbml0KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOeUn+WRveWRqOacn++8mua4suafk+a1geeoi++8jOa4suafk+i/h+eoi+mcgOimgeWkhOeQhuaVsOaNruabtOaWsOeahOaDheWGteOAglxuICAgICAqIHJlbmRlciDlh73mlbDku4Xku4XkvJrlpITnkIYgdmlldyDlkozlrZAgdmlld+OAglxuICAgICAqIEBwYXJhbSBpc1VwZGF0ZSDmmK/lkKbop6blj5Hmm7TmlrDmtYHnqIvjgIJcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKGlzVXBkYXRlID09PSB2b2lkIDApIHsgaXNVcGRhdGUgPSBmYWxzZTsgfVxuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkJFRk9SRV9SRU5ERVIpO1xuICAgICAgICAvLyDpgJLlvZLmuLLmn5NcbiAgICAgICAgdGhpcy5wYWludChpc1VwZGF0ZSk7XG4gICAgICAgIHRoaXMuZW1pdChjb25zdGFudF8xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUkVOREVSKTtcbiAgICAgICAgaWYgKHRoaXMudmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8vIOeUqOaIt+WcqOWIneWni+WMlueahOaXtuWAmeWjsOaYjiB2aXNpYmxlOiBmYWxzZVxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VWaXNpYmxlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog55Sf5ZG95ZGo5pyf77ya5riF56m65Zu+6KGo5LiK5omA5pyJ55qE57uY5Yi25YaF5a6577yM5L2G5piv5LiN6ZSA5q+B5Zu+6KGo77yMY2hhcnQg5LuN5Y+v5L2/55So44CCXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkJFRk9SRV9DTEVBUik7XG4gICAgICAgIC8vIDEuIOa4heepuue8k+WtmOWSjOiuoeeul+aVsOaNrlxuICAgICAgICB0aGlzLmZpbHRlcmVkRGF0YSA9IFtdO1xuICAgICAgICB0aGlzLmNvb3JkaW5hdGVJbnN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5pc0RhdGFDaGFuZ2VkID0gZmFsc2U7IC8vIOWkjeS9jVxuICAgICAgICB0aGlzLmlzQ29vcmRpbmF0ZUNoYW5nZWQgPSBmYWxzZTsgLy8g5aSN5L2NXG4gICAgICAgIC8vIDIuIOa4heepuiBnZW9tZXRyaWVzXG4gICAgICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdlb21ldHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGdlb21ldHJpZXNbaV0uY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdlb21ldHJpZXMgPSBbXTtcbiAgICAgICAgLy8gMy4g5riF56m6IGNvbnRyb2xsZXJzXG4gICAgICAgIHZhciBjb250cm9sbGVycyA9IHRoaXMuY29udHJvbGxlcnM7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29udHJvbGxlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXJzW2ldLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNC4g5Yig6ZmkIHNjYWxlIOe8k+WtmFxuICAgICAgICB0aGlzLmNyZWF0ZWRTY2FsZUtleXMuZm9yRWFjaChmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgX3RoaXMuZ2V0Um9vdFZpZXcoKS5zY2FsZVBvb2wuZGVsZXRlU2NhbGUoayk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNyZWF0ZWRTY2FsZUtleXMuY2xlYXIoKTtcbiAgICAgICAgLy8g6YCS5b2S5aSE55CG5a2QIHZpZXdcbiAgICAgICAgdmFyIHZpZXdzID0gdGhpcy52aWV3cztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2aWV3cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmlld3NbaV0uY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX0NMRUFSKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOeUn+WRveWRqOacn++8mumUgOavge+8jOWujOWFqOaXoOazleS9v+eUqOOAglxuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDplIDmr4HliY3kuovku7bvvIzplIDmr4HkuYvlkI7lt7Lnu4/msqHmnInmhI/kuYnkuobvvIzmiYDku6XkuI3mipvlh7rkuovku7ZcbiAgICAgICAgdGhpcy5lbWl0KGNvbnN0YW50XzEuVklFV19MSUZFX0NJUkNMRS5CRUZPUkVfREVTVFJPWSk7XG4gICAgICAgIHZhciBpbnRlcmFjdGlvbnMgPSB0aGlzLmludGVyYWN0aW9ucztcbiAgICAgICAgLy8g6ZSA5q+BIGludGVyYWN0aW9uc1xuICAgICAgICB1dGlsXzEuZWFjaChpbnRlcmFjdGlvbnMsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgLy8g5pyJ5Y+v6IO95bey57uP6ZSA5q+B77yM6K6+572u5LqGIHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgLy8g6ZSA5q+BIGNvbnRyb2xsZXIg5Lit55qE57uE5Lu2XG4gICAgICAgIHZhciBjb250cm9sbGVycyA9IHRoaXMuY29udHJvbGxlcnM7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjb250cm9sbGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGNvbnRyb2xsZXIgPSBjb250cm9sbGVyc1tpXTtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYmFja2dyb3VuZEdyb3VwLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgdGhpcy5taWRkbGVHcm91cC5yZW1vdmUodHJ1ZSk7XG4gICAgICAgIHRoaXMuZm9yZWdyb3VuZEdyb3VwLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICAvKiBlbmQg55Sf5ZG95ZGo5pyf5Ye95pWwICovXG4gICAgLyoqXG4gICAgICog5pi+56S65oiW6ICF6ZqQ6JeP5pW05LiqIHZpZXfjgIJcbiAgICAgKiBAcGFyYW0gdmlzaWJsZSDmmK/lkKblj6/op4FcbiAgICAgKiBAcmV0dXJucyBWaWV3XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuY2hhbmdlVmlzaWJsZSA9IGZ1bmN0aW9uICh2aXNpYmxlKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY2hhbmdlVmlzaWJsZS5jYWxsKHRoaXMsIHZpc2libGUpO1xuICAgICAgICB2YXIgZ2VvbWV0cmllcyA9IHRoaXMuZ2VvbWV0cmllcztcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IGdlb21ldHJpZXNbaV07XG4gICAgICAgICAgICBnZW9tZXRyeS5jaGFuZ2VWaXNpYmxlKHZpc2libGUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb250cm9sbGVycyA9IHRoaXMuY29udHJvbGxlcnM7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjb250cm9sbGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGNvbnRyb2xsZXIgPSBjb250cm9sbGVyc1tpXTtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuY2hhbmdlVmlzaWJsZSh2aXNpYmxlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcmVncm91bmRHcm91cC5zZXQoJ3Zpc2libGUnLCB2aXNpYmxlKTtcbiAgICAgICAgdGhpcy5taWRkbGVHcm91cC5zZXQoJ3Zpc2libGUnLCB2aXNpYmxlKTtcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kR3JvdXAuc2V0KCd2aXNpYmxlJywgdmlzaWJsZSk7XG4gICAgICAgIC8vIGdyb3VwLnNldCgndmlzaWJsZScsIHZpc2libGUpIOS4jeS8muinpuWPkeiHquWKqOWIt+aWsFxuICAgICAgICB0aGlzLmdldENhbnZhcygpLmRyYXcoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDoo4Xovb3mlbDmja7mupDjgIJcbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogdmlldy5kYXRhKFt7IGNpdHk6ICfmna3lt54nLCBzYWxlOiAxMDAgfSwgeyBjaXR5OiAn5LiK5rW3Jywgc2FsZTogMTEwIH0gXSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZGF0YSDmlbDmja7mupDvvIxqc29uIOaVsOe7hOOAglxuICAgICAqIEByZXR1cm5zIFZpZXdcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5kYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdXRpbF8xLnNldCh0aGlzLm9wdGlvbnMsICdkYXRhJywgZGF0YSk7XG4gICAgICAgIHRoaXMuaXNEYXRhQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgYXQgRzIgVjQuMS4gUmVwbGFjZWQgYnkge0BsaW5rICNkYXRhKGRhdGEpfVxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLnNvdXJjZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVGhpcyBtZXRob2Qgd2lsbCBiZSByZW1vdmVkIGF0IEcyIFY0LjEuIFBsZWFzZSB1c2UgY2hhcnQuZGF0YSgpIGluc3RlYWQuJyk7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEoZGF0YSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7mlbDmja7nrZvpgInop4TliJnjgIJcbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogdmlldy5maWx0ZXIoJ2NpdHknLCAodmFsdWU6IGFueSwgZGF0dW06IERhdHVtKSA9PiB2YWx1ZSAhPT0gJ+adreW3nicpO1xuICAgICAqXG4gICAgICogLy8g5Yig6ZmkICdjaXR5JyDlrZfmrrXlr7nlupTnmoTnrZvpgInop4TliJnjgIJcbiAgICAgKiB2aWV3LmZpbHRlcignY2l0eScsIG51bGwpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGZpZWxkIOaVsOaNruWtl+autVxuICAgICAqIEBwYXJhbSBjb25kaXRpb24g562b6YCJ6KeE5YiZXG4gICAgICogQHJldHVybnMgVmlld1xuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmZpbHRlciA9IGZ1bmN0aW9uIChmaWVsZCwgY29uZGl0aW9uKSB7XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihjb25kaXRpb24pKSB7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KHRoaXMub3B0aW9ucywgWydmaWx0ZXJzJywgZmllbGRdLCBjb25kaXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29uZGl0aW9uIOS4uuepuu+8jOWImeihqOekuuWIoOmZpOi/h+a7pOadoeS7tlxuICAgICAgICBpZiAoIWNvbmRpdGlvbiAmJiB1dGlsXzEuZ2V0KHRoaXMub3B0aW9ucywgWydmaWx0ZXJzJywgZmllbGRdKSkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMub3B0aW9ucy5maWx0ZXJzW2ZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIFZpZXcucHJvdG90eXBlLmF4aXMgPSBmdW5jdGlvbiAoZmllbGQsIGF4aXNPcHRpb24pIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Jvb2xlYW4oZmllbGQpKSB7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KHRoaXMub3B0aW9ucywgWydheGVzJ10sIGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHV0aWxfMS5zZXQodGhpcy5vcHRpb25zLCBbJ2F4ZXMnLCBmaWVsZF0sIGF4aXNPcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgVmlldy5wcm90b3R5cGUubGVnZW5kID0gZnVuY3Rpb24gKGZpZWxkLCBsZWdlbmRPcHRpb24pIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Jvb2xlYW4oZmllbGQpKSB7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KHRoaXMub3B0aW9ucywgWydsZWdlbmRzJ10sIGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNTdHJpbmcoZmllbGQpKSB7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KHRoaXMub3B0aW9ucywgWydsZWdlbmRzJywgZmllbGRdLCBsZWdlbmRPcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g6K6+572u5YWo5bGA55qEIGxlZ2VuZCDphY3nva5cbiAgICAgICAgICAgIHV0aWxfMS5zZXQodGhpcy5vcHRpb25zLCBbJ2xlZ2VuZHMnXSwgZmllbGQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgVmlldy5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoZmllbGQsIHNjYWxlT3B0aW9uKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcoZmllbGQpKSB7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KHRoaXMub3B0aW9ucywgWydzY2FsZXMnLCBmaWVsZF0sIHNjYWxlT3B0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNPYmplY3QoZmllbGQpKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChmaWVsZCwgZnVuY3Rpb24gKHYsIGspIHtcbiAgICAgICAgICAgICAgICB1dGlsXzEuc2V0KF90aGlzLm9wdGlvbnMsIFsnc2NhbGVzJywga10sIHYpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiB0b29sdGlwIOaPkOekuuS/oeaBr+mFjee9ruOAglxuICAgICAqXG4gICAgICogYGBgdHNcbiAgICAgKiB2aWV3LnRvb2x0aXAoZmFsc2UpOyAvLyDlhbPpl60gdG9vbHRpcFxuICAgICAqXG4gICAgICogdmlldy50b29sdGlwKHtcbiAgICAgKiAgIHNoYXJlZDogdHJ1ZVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGNmZyBUb29sdGlwIOmFjee9ru+8jOabtOivpue7hueahOmFjee9rumhueWPguiAg++8mmh0dHBzOi8vZ2l0aHViLmNvbS9hbnR2aXMvY29tcG9uZW50I3Rvb2x0aXBcbiAgICAgKiBAcmV0dXJucyBWaWV3XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUudG9vbHRpcCA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgdXRpbF8xLnNldCh0aGlzLm9wdGlvbnMsICd0b29sdGlwJywgY2ZnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDovoXliqnmoIforrDphY3nva7jgIJcbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogdmlldy5hbm5vdGF0aW9uKCkubGluZSh7XG4gICAgICogICBzdGFydDogWydtaW4nLCA4NV0sXG4gICAgICogICBlbmQ6IFsnbWF4JywgODVdLFxuICAgICAqICAgc3R5bGU6IHtcbiAgICAgKiAgICAgc3Ryb2tlOiAnIzU5NTk1OScsXG4gICAgICogICAgIGxpbmVXaWR0aDogMSxcbiAgICAgKiAgICAgbGluZURhc2g6IFszLCAzXSxcbiAgICAgKiAgIH0sXG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICog5pu06K+m57uG55qE6YWN572u6aG577yaaHR0cHM6Ly9naXRodWIuY29tL2FudHZpcy9jb21wb25lbnQjYW5ub3RhdGlvblxuICAgICAqIEByZXR1cm5zIFtbQW5ub3RhdGlvbl1dXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuYW5ub3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29udHJvbGxlcignYW5ub3RhdGlvbicpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgYXQgRzIgVjQuMS4gUmVwbGFjZWQgYnkge0BsaW5rICNndWlkZSgpfVxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmd1aWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1RoaXMgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBhdCBHMiBWNC4xLiBQbGVhc2UgdXNlIGNoYXJ0LmFubm90YXRpb24oKSBpbnN0ZWFkLicpO1xuICAgICAgICByZXR1cm4gdGhpcy5hbm5vdGF0aW9uKCk7XG4gICAgfTtcbiAgICBWaWV3LnByb3RvdHlwZS5jb29yZGluYXRlID0gZnVuY3Rpb24gKHR5cGUsIGNvb3JkaW5hdGVDZmcpIHtcbiAgICAgICAgLy8g5o+Q5L6b6K+t5rOV57OW77yM5L2/55So5pu0566A5Y2VXG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcodHlwZSkpIHtcbiAgICAgICAgICAgIHV0aWxfMS5zZXQodGhpcy5vcHRpb25zLCAnY29vcmRpbmF0ZScsIHsgdHlwZTogdHlwZSwgY2ZnOiBjb29yZGluYXRlQ2ZnIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdXRpbF8xLnNldCh0aGlzLm9wdGlvbnMsICdjb29yZGluYXRlJywgdHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5pu05pawIGNvb3JkaW5hdGUg6YWN572uXG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZUNvbnRyb2xsZXIudXBkYXRlKHRoaXMub3B0aW9ucy5jb29yZGluYXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29vcmRpbmF0ZUNvbnRyb2xsZXI7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBhdCBHMiBWNC4xLiBSZXBsYWNlZCBieSB7QGxpbmsgI2Nvb3JkaW5hdGUoKX1cbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICh0eXBlLCBjb29yZGluYXRlQ2ZnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVGhpcyBtZXRob2Qgd2lsbCBiZSByZW1vdmVkIGF0IEcyIFY0LjEuIFBsZWFzZSB1c2UgY2hhcnQuY29vcmRpbmF0ZSgpIGluc3RlYWQuJyk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHRoaXMuY29vcmRpbmF0ZSh0eXBlLCBjb29yZGluYXRlQ2ZnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIHZpZXcg5YiG6Z2i57uY5Yi244CCXG4gICAgICpcbiAgICAgKiBgYGB0c1xuICAgICAqIHZpZXcuZmFjZXQoJ3JlY3QnLCB7XG4gICAgICogICByb3dGaWVsZDogJ3Byb3ZpbmNlJyxcbiAgICAgKiAgIGNvbHVtbkZpZWxkOiAnY2F0ZWdvcnknLFxuICAgICAqICAgZWFjaFZpZXc6IChpbm5lclZpZXc6IFZpZXcsIGZhY2V0PzogRmFjZXREYXRhKSA9PiB7XG4gICAgICogICAgIGlubmVyVmlldy5saW5lKCkucG9zaXRpb24oJ2NpdHkqc2FsZScpO1xuICAgICAqICAgfSxcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0eXBlIOWIhumdouexu+Wei1xuICAgICAqIEBwYXJhbSBjZmcg5YiG6Z2i6YWN572u77yMIFtbRmFjZXRDZmdNYXBdXVxuICAgICAqIEByZXR1cm5zIFZpZXdcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5mYWNldCA9IGZ1bmN0aW9uICh0eXBlLCBjZmcpIHtcbiAgICAgICAgLy8g5YWI6ZSA5q+B5o6J5LmL5YmN55qE5YiG6Z2iXG4gICAgICAgIGlmICh0aGlzLmZhY2V0SW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuZmFjZXRJbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Yib5bu65paw55qE5YiG6Z2iXG4gICAgICAgIHZhciBDdG9yID0gZmFjZXRfMS5nZXRGYWNldCh0eXBlKTtcbiAgICAgICAgaWYgKCFDdG9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmYWNldCAnXCIgKyB0eXBlICsgXCInIGlzIG5vdCBleGlzdCFcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mYWNldEluc3RhbmNlID0gbmV3IEN0b3IodGhpcywgdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBjZmcpLCB7IHR5cGU6IHR5cGUgfSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXG4gICAgICog5byA5ZCv5oiW6ICF5YWz6Zet5Yqo55S744CCXG4gICAgICpcbiAgICAgKiBgYGB0c1xuICAgICAqIHZpZXcuYW5pbWF0ZShmYWxzZSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3RhdHVzIOWKqOeUu+eKtuaAge+8jHRydWUg6KGo56S65byA5aeL77yMZmFsc2Ug6KGo56S65YWz6ZetXG4gICAgICogQHJldHVybnMgVmlld1xuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmFuaW1hdGUgPSBmdW5jdGlvbiAoc3RhdHVzKSB7XG4gICAgICAgIHV0aWxfMS5zZXQodGhpcy5vcHRpb25zLCAnYW5pbWF0ZScsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5pu05paw6YWN572u6aG577yM55So5LqO6YWN572u6aG55byP5aOw5piO44CCXG4gICAgICogQHBhcmFtIG9wdGlvbnMg6YWN572u6aG5XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUudXBkYXRlT3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTsgLy8g5riF56m6XG4gICAgICAgIHV0aWxfMS5taXgodGhpcy5vcHRpb25zLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5pbml0T3B0aW9ucygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOW+gCBgdmlldy5vcHRpb25zYCDlsZ7mgKfkuK3lrZjlgqjphY3nva7pobnjgIJcbiAgICAgKiBAcGFyYW0gbmFtZSDlsZ7mgKflkI3np7BcbiAgICAgKiBAcGFyYW0gb3B0IOWxnuaAp+WAvFxuICAgICAqIEByZXR1cm5zIHZpZXdcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5vcHRpb24gPSBmdW5jdGlvbiAobmFtZSwgb3B0KSB7XG4gICAgICAgIC8vIOWvueS6juWGhee9rueahCBvcHRpb27vvIzpgb/lhY3opobnm5bjgIJcbiAgICAgICAgLy8gbmFtZSDlnKjljp/lnovkuIrvvIzor7TmmI7lj6/og73mmK/lhoXnva4gQVBJ77yM5a2Y5ZyoIG9wdGlvbiDooqvopobnm5bnmoTpo47pmanvvIzkuI3lpITnkIZcbiAgICAgICAgaWYgKFZpZXcucHJvdG90eXBlW25hbWVdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgYnVpbHQgaW4gdmFyaWFibGUgbmFtZSBcXFwiXCIgKyBuYW1lICsgXCJcXFwiLCBwbGVhc2UgY2hhbmdlIGFub3RoZXIgb25lLlwiKTtcbiAgICAgICAgfVxuICAgICAgICAvLyDlrZjlhaXliLAgb3B0aW9uIOS4rVxuICAgICAgICB1dGlsXzEuc2V0KHRoaXMub3B0aW9ucywgbmFtZSwgb3B0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7kuLvpopjjgIJcbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogdmlldy50aGVtZSgnZGFyaycpOyAvLyAnZGFyaycg6ZyA6KaB5LqL5YWI6YCa6L+HIGByZWdpc3RlclRoZW1lKClgIOaOpeWPo+azqOWGjOWujOaIkFxuICAgICAqXG4gICAgICogdmlldy50aGVtZSh7IGRlZmF1bHRDb2xvcjogJ3JlZCcgfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGhlbWUg5Li76aKY5ZCN5oiW6ICF5Li76aKY6YWN572uXG4gICAgICogQHJldHVybnMgVmlld1xuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLnRoZW1lID0gZnVuY3Rpb24gKHRoZW1lKSB7XG4gICAgICAgIHRoaXMudGhlbWVPYmplY3QgPSB1dGlsXzEuaXNPYmplY3QodGhlbWUpID8gdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMudGhlbWVPYmplY3QsIHRoZW1lKSA6IHRoZW1lXzEuZ2V0VGhlbWUodGhlbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qIGVuZCDkuIDns7vliJfkvKDlhaXphY3nva7nmoQgQVBJICovXG4gICAgLyoqXG4gICAgICogQ2FsbCB0aGUgaW50ZXJhY3Rpb24gYmFzZWQgb24gdGhlIGludGVyYWN0aW9uIG5hbWVcbiAgICAgKlxuICAgICAqIGBgYHRzXG4gICAgICogdmlldy5pbnRlcmFjdGlvbignbXktaW50ZXJhY3Rpb24nLCB7IGV4dHJhOiAnaGVsbG8gd29ybGQnIH0pO1xuICAgICAqIGBgYFxuICAgICAqIOivpue7huaWh+aho+WPr+S7peWPguiAg++8mmh0dHBzOi8vZzIuYW50di52aXNpb24vemgvZG9jcy9tYW51YWwvdHV0b3JpYWwvaW50ZXJhY3Rpb25cbiAgICAgKiBAcGFyYW0gbmFtZSBpbnRlcmFjdGlvbiBuYW1lXG4gICAgICogQHBhcmFtIGNmZyBpbnRlcmFjdGlvbiBjb25maWdcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmludGVyYWN0aW9uID0gZnVuY3Rpb24gKG5hbWUsIGNmZykge1xuICAgICAgICB2YXIgZXhpc3RJbnRlcmFjdGlvbiA9IHRoaXMuaW50ZXJhY3Rpb25zW25hbWVdO1xuICAgICAgICAvLyDlrZjlnKjliJnlhYjplIDmr4Hlt7LmnInnmoRcbiAgICAgICAgaWYgKGV4aXN0SW50ZXJhY3Rpb24pIHtcbiAgICAgICAgICAgIGV4aXN0SW50ZXJhY3Rpb24uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOaWsOW7uuS6pOS6kuWunuS+i1xuICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbl8xLmNyZWF0ZUludGVyYWN0aW9uKG5hbWUsIHRoaXMsIGNmZyk7XG4gICAgICAgIGlmIChpbnRlcmFjdGlvbikge1xuICAgICAgICAgICAgaW50ZXJhY3Rpb24uaW5pdCgpO1xuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnNbbmFtZV0gPSBpbnRlcmFjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOenu+mZpOW9k+WJjSBWaWV3IOeahCBpbnRlcmFjdGlvblxuICAgICAqIGBgYHRzXG4gICAgICogdmlldy5yZW1vdmVJbnRlcmFjdGlvbignbXktaW50ZXJhY3Rpb24nKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcGFyYW0gbmFtZSBpbnRlcmFjdGlvbiBuYW1lXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUucmVtb3ZlSW50ZXJhY3Rpb24gPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB2YXIgZXhpc3RJbnRlcmFjdGlvbiA9IHRoaXMuaW50ZXJhY3Rpb25zW25hbWVdO1xuICAgICAgICAvLyDlrZjlnKjliJnlhYjplIDmr4Hlt7LmnInnmoRcbiAgICAgICAgaWYgKGV4aXN0SW50ZXJhY3Rpb24pIHtcbiAgICAgICAgICAgIGV4aXN0SW50ZXJhY3Rpb24uZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnNbbmFtZV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOS/ruaUueaVsOaNru+8jOaVsOaNruabtOaWsOmAu+i+ke+8jOaVsOaNruabtOaWsOS7heS7heW9seWTjeW9k+WJjei/meS4gOWxgueahCB2aWV3XG4gICAgICpcbiAgICAgKiBgYGB0c1xuICAgICAqIHZpZXcuY2hhbmdlRGF0YShbeyBjaXR5OiAn5YyX5LqsJywgc2FsZTogJzIwMCcgfV0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuY2hhbmdlRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHRoaXMuaXNEYXRhQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuZW1pdChjb25zdGFudF8xLlZJRVdfTElGRV9DSVJDTEUuQkVGT1JFX0NIQU5HRV9EQVRBKTtcbiAgICAgICAgLy8gMS4g5L+d5a2Y5pWw5o2uXG4gICAgICAgIHRoaXMuZGF0YShkYXRhKTtcbiAgICAgICAgLy8gMi4g5riy5p+TXG4gICAgICAgIHRoaXMucGFpbnQodHJ1ZSk7XG4gICAgICAgIC8vIDMuIOmBjeWOhuWtkCB2aWV3IOi/m+ihjCBjaGFuZ2UgZGF0YVxuICAgICAgICB2YXIgdmlld3MgPSB0aGlzLnZpZXdzO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdmlld3MubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciB2aWV3ID0gdmlld3NbaV07XG4gICAgICAgICAgICAvLyBGSVhNRSDlrZAgdmlldyDmnInoh6rlt7HnmoTmlbDmja7nmoTmg4XlhrXvvIzor6XlpoLkvZXlpITnkIbvvJ9cbiAgICAgICAgICAgIHZpZXcuY2hhbmdlRGF0YShkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX0NIQU5HRV9EQVRBKTtcbiAgICB9O1xuICAgIC8qIFZpZXcg566h55CG55u45YWz55qEIEFQSSAqL1xuICAgIC8qKlxuICAgICAqIOWIm+W7uuWtkCB2aWV3XG4gICAgICpcbiAgICAgKiBgYGB0c1xuICAgICAqIGNvbnN0IGlubmVyVmlldyA9IHZpZXcuY3JlYXRlVmlldyh7XG4gICAgICogICBzdGFydDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICogICBlbmQ6IHsgeDogMC41LCB5OiAwLjUgfSxcbiAgICAgKiAgIHBhZGRpbmc6IDgsXG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2ZnXG4gICAgICogQHJldHVybnMgVmlld1xuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmNyZWF0ZVZpZXcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIC8vIOWtkCB2aWV3IOWFseS6qyBvcHRpb25zIOmFjee9ruaVsOaNrlxuICAgICAgICB2YXIgc2hhcmVkT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGRhdGE6IHRoaXMub3B0aW9ucy5kYXRhLFxuICAgICAgICAgICAgc2NhbGVzOiB1dGlsXzEuY2xvbmUodGhpcy5vcHRpb25zLnNjYWxlcyksXG4gICAgICAgICAgICBheGVzOiB1dGlsXzEuY2xvbmUodGhpcy5vcHRpb25zLmF4ZXMpLFxuICAgICAgICAgICAgY29vcmRpbmF0ZTogdXRpbF8xLmNsb25lKHRoaXMuY29vcmRpbmF0ZUNvbnRyb2xsZXIuZ2V0T3B0aW9uKCkpLFxuICAgICAgICAgICAgdG9vbHRpcDogdXRpbF8xLmNsb25lKHRoaXMub3B0aW9ucy50b29sdGlwKSxcbiAgICAgICAgICAgIGxlZ2VuZHM6IHV0aWxfMS5jbG9uZSh0aGlzLm9wdGlvbnMubGVnZW5kcyksXG4gICAgICAgICAgICBhbmltYXRlOiB0aGlzLm9wdGlvbnMuYW5pbWF0ZSxcbiAgICAgICAgICAgIHZpc2libGU6IHRoaXMudmlzaWJsZSxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHYgPSBuZXcgVmlldyh0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyBwYXJlbnQ6IHRoaXMsIGNhbnZhczogdGhpcy5jYW52YXMsIFxuICAgICAgICAgICAgLy8g5a2QIHZpZXcg5YWx55So5LiJ5bGCIGdyb3VwXG4gICAgICAgICAgICBiYWNrZ3JvdW5kR3JvdXA6IHRoaXMuYmFja2dyb3VuZEdyb3VwLmFkZEdyb3VwKHsgekluZGV4OiBjb25zdGFudF8xLkdST1VQX1pfSU5ERVguQkcgfSksIG1pZGRsZUdyb3VwOiB0aGlzLm1pZGRsZUdyb3VwLmFkZEdyb3VwKHsgekluZGV4OiBjb25zdGFudF8xLkdST1VQX1pfSU5ERVguTUlEIH0pLCBmb3JlZ3JvdW5kR3JvdXA6IHRoaXMuZm9yZWdyb3VuZEdyb3VwLmFkZEdyb3VwKHsgekluZGV4OiBjb25zdGFudF8xLkdST1VQX1pfSU5ERVguRk9SRSB9KSwgdGhlbWU6IHRoaXMudGhlbWVPYmplY3QsIHBhZGRpbmc6IHRoaXMucGFkZGluZyB9LCBjZmcpLCB7IG9wdGlvbnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcmVkT3B0aW9ucyksIHV0aWxfMS5nZXQoY2ZnLCAnb3B0aW9ucycsIHt9KSkgfSkpO1xuICAgICAgICB0aGlzLnZpZXdzLnB1c2godik7XG4gICAgICAgIHJldHVybiB2O1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgYXQgRzIgVjQuMS4gUmVwbGFjZWQgYnkge0BsaW5rICNjcmVhdGVWaWV3KCl9XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUudmlldyA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgYXQgRzIgVjQuMS4gUGxlYXNlIHVzZSBjaGFydC5jcmVhdGVWaWV3KCkgaW5zdGVhZC4nKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVmlldyhjZmcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yig6Zmk5LiA5Liq5a2QIHZpZXdcbiAgICAgKiBAcGFyYW0gdmlld1xuICAgICAqIEByZXR1cm4gcmVtb3ZlZFZpZXdcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5yZW1vdmVWaWV3ID0gZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgdmFyIHJlbW92ZWRWaWV3ID0gdXRpbF8xLnJlbW92ZSh0aGlzLnZpZXdzLCBmdW5jdGlvbiAodikgeyByZXR1cm4gdiA9PT0gdmlldzsgfSlbMF07XG4gICAgICAgIGlmIChyZW1vdmVkVmlldykge1xuICAgICAgICAgICAgcmVtb3ZlZFZpZXcuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZW1vdmVkVmlldztcbiAgICB9O1xuICAgIC8qIGVuZCBWaWV3IOeuoeeQhuebuOWFs+eahCBBUEkgKi9cbiAgICAvLyDkuIDkupsgZ2V0IOaWueazlVxuICAgIC8qKlxuICAgICAqIOiOt+WPluW9k+WJjeWdkOagh+ezu+WunuS+i+OAglxuICAgICAqIEByZXR1cm5zIFtbQ29vcmRpbmF0ZV1dXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29vcmRpbmF0ZUluc3RhbmNlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5b2T5YmNIHZpZXcg55qE5Li76aKY6YWN572u44CCXG4gICAgICogQHJldHVybnMgdGhlbWVPYmplY3RcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRUaGVtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGhlbWVPYmplY3Q7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflvpcgeCDovbTlrZfmrrXnmoQgc2NhbGUg5a6e5L6L44CCXG4gICAgICogQHJldHVybnMgdmlldyDkuK0gR2VvbWV0cnkg5a+55LqO55qEIHggc2NhbGVcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRYU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOaLv+esrOS4gOS4qiBHZW9tZXRyeSDnmoQgWCBzY2FsZVxuICAgICAgICAvLyDpmpDol4/pgLvovpHvvJrkuIDkuKogdmlldyDkuK3nmoQgR2VvbWV0cnkg5b+F6aG7IHgg5a2X5q615LiA6Ie0XG4gICAgICAgIHZhciBnID0gdGhpcy5nZW9tZXRyaWVzWzBdO1xuICAgICAgICByZXR1cm4gZyA/IGcuZ2V0WFNjYWxlKCkgOiBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+WIHkg6L205a2X5q6155qEIHNjYWxlcyDlrp7kvovjgIJcbiAgICAgKiBAcmV0dXJucyB2aWV3IOS4rSBHZW9tZXRyeSDlr7nkuo7nmoQgeSBzY2FsZSDmlbDnu4RcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRZU2NhbGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDmi7/liLDmiYDmnInnmoQgR2VvbWV0cnkg55qEIFkgc2NhbGXvvIznhLblkI7ljrvph41cbiAgICAgICAgdmFyIHRtcE1hcCA9IHt9O1xuICAgICAgICByZXR1cm4gdGhpcy5nZW9tZXRyaWVzLm1hcChmdW5jdGlvbiAoZykge1xuICAgICAgICAgICAgdmFyIHlTY2FsZSA9IGcuZ2V0WVNjYWxlKCk7XG4gICAgICAgICAgICB2YXIgZmllbGQgPSB5U2NhbGUuZmllbGQ7XG4gICAgICAgICAgICBpZiAoIXRtcE1hcFtmaWVsZF0pIHtcbiAgICAgICAgICAgICAgICB0bXBNYXBbZmllbGRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4geVNjYWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPliB4IOi9tOaIluiAhSB5IOi9tOWvueW6lOeahOaJgOaciSBzY2FsZSDlrp7kvovjgIJcbiAgICAgKiBAcGFyYW0gZGltVHlwZSB4IHwgeVxuICAgICAqIEByZXR1cm5zIHgg6L205oiW6ICFIHkg6L205a+55bqU55qE5omA5pyJIHNjYWxlIOWunuS+i+OAglxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmdldFNjYWxlc0J5RGltID0gZnVuY3Rpb24gKGRpbVR5cGUpIHtcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXM7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IGdlb21ldHJpZXNbaV07XG4gICAgICAgICAgICB2YXIgc2NhbGUgPSBkaW1UeXBlID09PSAneCcgPyBnZW9tZXRyeS5nZXRYU2NhbGUoKSA6IGdlb21ldHJ5LmdldFlTY2FsZSgpO1xuICAgICAgICAgICAgaWYgKHNjYWxlICYmICFzY2FsZXNbc2NhbGUuZmllbGRdKSB7XG4gICAgICAgICAgICAgICAgc2NhbGVzW3NjYWxlLmZpZWxkXSA9IHNjYWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmoLnmja7lrZfmrrXlkI3ljrvojrflj5Ygc2NhbGUg5a6e5L6L44CCXG4gICAgICogQHBhcmFtIGZpZWxkIOaVsOaNruWtl+auteWQjeensFxuICAgICAqIEBwYXJhbSBrZXkgaWRcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRTY2FsZUJ5RmllbGQgPSBmdW5jdGlvbiAoZmllbGQsIGtleSkge1xuICAgICAgICB2YXIgZGVmYXVsdEtleSA9IGtleSA/IGtleSA6IHRoaXMuZ2V0U2NhbGVLZXkoZmllbGQpO1xuICAgICAgICAvLyDosIPnlKjmoLnoioLngrkgdmlldyDnmoTmlrnms5Xojrflj5ZcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Um9vdFZpZXcoKS5zY2FsZVBvb2wuZ2V0U2NhbGUoZGVmYXVsdEtleSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDov5Tlm57miYDmnInphY3nva7kv6Hmga/jgIJcbiAgICAgKiBAcmV0dXJucyDmiYDmnInnmoQgdmlldyBBUEkg6YWN572u44CCXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPliB2aWV3IOeahOaVsOaNru+8iOi/h+a7pOWQjueahOaVsOaNru+8ieOAglxuICAgICAqIEByZXR1cm5zIOWkhOeQhui/h+a7pOWZqOS5i+WQjueahOaVsOaNruOAglxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZpbHRlcmVkRGF0YTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+W+l+e7mOWItueahOWxgue6pyBncm91cOOAglxuICAgICAqIEBwYXJhbSBsYXllciDlsYLnuqflkI3np7DjgIJcbiAgICAgKiBAcmV0dXJucyDlr7nlupTlsYLnuqfnmoQgR3JvdXDjgIJcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRMYXllciA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICByZXR1cm4gbGF5ZXIgPT09IGNvbnN0YW50XzEuTEFZRVIuQkdcbiAgICAgICAgICAgID8gdGhpcy5iYWNrZ3JvdW5kR3JvdXBcbiAgICAgICAgICAgIDogbGF5ZXIgPT09IGNvbnN0YW50XzEuTEFZRVIuTUlEXG4gICAgICAgICAgICAgICAgPyB0aGlzLm1pZGRsZUdyb3VwXG4gICAgICAgICAgICAgICAgOiBsYXllciA9PT0gY29uc3RhbnRfMS5MQVlFUi5GT1JFXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy5mb3JlZ3JvdW5kR3JvdXBcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmZvcmVncm91bmRHcm91cDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWvueWkluaatOmcsuaWueazle+8jOWIpOaWreS4gOS4queCueaYr+WQpuWcqOe7mOWbvuWMuuWfn++8iOWNs+WdkOagh+ezu+iMg+WbtO+8ieWGhemDqOOAglxuICAgICAqIEBwYXJhbSBwb2ludCDlnZDmoIfngrlcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5pc1BvaW50SW5QbG90ID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHJldHVybiBjb29yZGluYXRlXzEuaXNQb2ludEluQ29vcmRpbmF0ZSh0aGlzLmdldENvb3JkaW5hdGUoKSwgcG9pbnQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635b6X5omA5pyJ55qEIGxlZ2VuZCDlr7nlupTnmoQgYXR0cmlidXRlIOWunuS+i+OAglxuICAgICAqIEByZXR1cm5zIOe7tOW6puWtl+auteeahCBBdHRyaWJ1dGUg5pWw57uEXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0TGVnZW5kQXR0cmlidXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5mbGF0dGVuKHRoaXMuZ2VvbWV0cmllcy5tYXAoZnVuY3Rpb24gKGcpIHsgcmV0dXJuIGcuZ2V0R3JvdXBBdHRyaWJ1dGVzKCk7IH0pKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluaJgOacieeahOWIhue7hOWtl+auteeahCBzY2FsZSDlrp7kvovjgIJcbiAgICAgKiBAcmV0dXJucyDojrflvpfliIbnu4TlrZfmrrXnmoQgc2NhbGUg5a6e5L6L5pWw57uE44CCXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0R3JvdXBTY2FsZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOaLv+WIsOaJgOacieeahCBHZW9tZXRyeSDnmoQg5YiG57uE5a2X5q61IHNjYWxl77yM54S25ZCO5omT5bmz5Y676YeNXG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmdlb21ldHJpZXMubWFwKGZ1bmN0aW9uIChnKSB7IHJldHVybiBnLmdldEdyb3VwU2NhbGVzKCk7IH0pO1xuICAgICAgICByZXR1cm4gaGVscGVyXzEudW5pcSh1dGlsXzEuZmxhdHRlbihzY2FsZXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPliBHLkNhbnZhcyDlrp7kvovjgIJcbiAgICAgKiBAcmV0dXJucyBHLkNhbnZhcyDnlLvluIPlrp7kvovjgIJcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRDYW52YXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFJvb3RWaWV3KCkuY2FudmFzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635b6X5qC56IqC54K5IHZpZXfjgIJcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRSb290VmlldyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHYgPSB0aGlzO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgaWYgKHYucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgdiA9IHYucGFyZW50O1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHY7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bor6XmlbDmja7lnKjlj6/op4bljJblkI7vvIzlr7nlupTnmoTnlLvluIPlnZDmoIfngrnjgIJcbiAgICAgKiBAcGFyYW0gZGF0YSDljp/lp4vmlbDmja7orrDlvZVcbiAgICAgKiBAcmV0dXJucyDlr7nlupTnmoTnlLvluIPlnZDmoIfngrlcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5nZXRYWSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciB4U2NhbGVzID0gdGhpcy5nZXRTY2FsZXNCeURpbSgneCcpO1xuICAgICAgICB2YXIgeVNjYWxlcyA9IHRoaXMuZ2V0U2NhbGVzQnlEaW0oJ3knKTtcbiAgICAgICAgdmFyIHg7XG4gICAgICAgIHZhciB5O1xuICAgICAgICB1dGlsXzEuZWFjaChkYXRhLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgaWYgKHhTY2FsZXNba2V5XSkge1xuICAgICAgICAgICAgICAgIHggPSB4U2NhbGVzW2tleV0uc2NhbGUodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHlTY2FsZXNba2V5XSkge1xuICAgICAgICAgICAgICAgIHkgPSB5U2NhbGVzW2tleV0uc2NhbGUodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoeCkgJiYgIXV0aWxfMS5pc05pbCh5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGUuY29udmVydCh7IHg6IHgsIHk6IHkgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPliBuYW1lIOWvueW6lOeahCBjb250cm9sbGVyIOWunuS+i1xuICAgICAqIEBwYXJhbSBuYW1lXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0Q29udHJvbGxlciA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmluZCh0aGlzLmNvbnRyb2xsZXJzLCBmdW5jdGlvbiAoYykgeyByZXR1cm4gYy5uYW1lID09PSBuYW1lOyB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYvuekuiBwb2ludCDlnZDmoIfngrnlr7nlupTnmoQgdG9vbHRpcOOAglxuICAgICAqIEBwYXJhbSBwb2ludCDnlLvluIPlnZDmoIfngrlcbiAgICAgKiBAcmV0dXJucyBWaWV3XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuc2hvd1Rvb2x0aXAgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIHRvb2x0aXAgPSB0aGlzLmdldENvbnRyb2xsZXIoJ3Rvb2x0aXAnKTtcbiAgICAgICAgaWYgKHRvb2x0aXApIHtcbiAgICAgICAgICAgIHRvb2x0aXAuc2hvd1Rvb2x0aXAocG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZqQ6JePIHRvb2x0aXDjgIJcbiAgICAgKiBAcmV0dXJucyBWaWV3XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuaGlkZVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b29sdGlwID0gdGhpcy5nZXRDb250cm9sbGVyKCd0b29sdGlwJyk7XG4gICAgICAgIGlmICh0b29sdGlwKSB7XG4gICAgICAgICAgICB0b29sdGlwLmhpZGVUb29sdGlwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIYgdG9vbHRpcCDplIHlrprliLDlvZPliY3kvY3nva7kuI3og73np7vliqjjgIJcbiAgICAgKiBAcmV0dXJucyBWaWV3XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUubG9ja1Rvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b29sdGlwID0gdGhpcy5nZXRDb250cm9sbGVyKCd0b29sdGlwJyk7XG4gICAgICAgIGlmICh0b29sdGlwKSB7XG4gICAgICAgICAgICB0b29sdGlwLmxvY2tUb29sdGlwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIYgdG9vbHRpcCDplIHlrprop6PpmaTjgIJcbiAgICAgKiBAcmV0dXJucyBWaWV3XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUudW5sb2NrVG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRvb2x0aXAgPSB0aGlzLmdldENvbnRyb2xsZXIoJ3Rvb2x0aXAnKTtcbiAgICAgICAgaWYgKHRvb2x0aXApIHtcbiAgICAgICAgICAgIHRvb2x0aXAudW5sb2NrVG9vbHRpcCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm6ZSB5a6aIHRvb2x0aXDjgIJcbiAgICAgKiBAcmV0dXJucyDmmK/lkKbplIHlrppcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5pc1Rvb2x0aXBMb2NrZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b29sdGlwID0gdGhpcy5nZXRDb250cm9sbGVyKCd0b29sdGlwJyk7XG4gICAgICAgIHJldHVybiB0b29sdGlwICYmIHRvb2x0aXAuaXNUb29sdGlwTG9ja2VkKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blvZPliY0gcG9pbnQg5a+55bqU55qEIHRvb2x0aXAg5pWw5o2u6aG544CCXG4gICAgICogQHBhcmFtIHBvaW50IOWdkOagh+eCuVxuICAgICAqIEByZXR1cm5zIHRvb2x0aXAg5pWw5o2u6aG5XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0VG9vbHRpcEl0ZW1zID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciB0b29sdGlwID0gdGhpcy5nZXRDb250cm9sbGVyKCd0b29sdGlwJyk7XG4gICAgICAgIHJldHVybiB0b29sdGlwID8gdG9vbHRpcC5nZXRUb29sdGlwSXRlbXMocG9pbnQpIDogW107XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bpgLzov5HnmoTngrnnmoTmlbDmja7pm4blkIhcbiAgICAgKiBAcGFyYW0gcG9pbnQg5b2T5YmN5Z2Q5qCH54K5XG4gICAgICogQHJldHVybnMgIOaVsOaNrlxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmdldFNuYXBSZWNvcmRzID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzO1xuICAgICAgICB2YXIgcnN0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBnZW9tZXRyaWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbSA9IGdlb21ldHJpZXNbaV07XG4gICAgICAgICAgICB2YXIgZGF0YUFycmF5ID0gZ2VvbS5kYXRhQXJyYXk7XG4gICAgICAgICAgICBnZW9tLnNvcnQoZGF0YUFycmF5KTsgLy8g5YWI6L+b6KGM5o6S5bqP77yM5L6/5LqOIHRvb2x0aXAg5p+l5om+XG4gICAgICAgICAgICB2YXIgcmVjb3JkID0gdm9pZCAwO1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGRhdGFMZW4gPSBkYXRhQXJyYXkubGVuZ3RoOyBqIDwgZGF0YUxlbjsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBkYXRhQXJyYXlbal07XG4gICAgICAgICAgICAgICAgcmVjb3JkID0gdG9vbHRpcF8xLmZpbmREYXRhQnlQb2ludChwb2ludCwgZGF0YSwgZ2VvbSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlY29yZCkge1xuICAgICAgICAgICAgICAgICAgICByc3QucHVzaChyZWNvcmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyDlkIzmoLfpgJLlvZLlpITnkIblrZAgdmlld3NcbiAgICAgICAgdmFyIHZpZXdzID0gdGhpcy52aWV3cztcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHZpZXdzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgdmlldyA9IHZpZXdzW2ldO1xuICAgICAgICAgICAgdmFyIHNuYXBSZWNvcmRzID0gdmlldy5nZXRTbmFwUmVjb3Jkcyhwb2ludCk7XG4gICAgICAgICAgICByc3QgPSByc3QuY29uY2F0KHNuYXBSZWNvcmRzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5omA5pyJ55qEIHB1cmUgY29tcG9uZW50IOe7hOS7tu+8jOeUqOS6juW4g+WxgOOAglxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmdldENvbXBvbmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb21wb25lbnRzID0gW107XG4gICAgICAgIHZhciBjb250cm9sbGVycyA9IHRoaXMuY29udHJvbGxlcnM7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjb250cm9sbGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGNvbnRyb2xsZXIgPSBjb250cm9sbGVyc1tpXTtcbiAgICAgICAgICAgIGNvbXBvbmVudHMgPSBjb21wb25lbnRzLmNvbmNhdChjb250cm9sbGVyLmdldENvbXBvbmVudHMoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudHM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIYgZGF0YSDmlbDmja7ov5vooYzov4fmu6TjgIJcbiAgICAgKiBAcGFyYW0gZGF0YVxuICAgICAqIEByZXR1cm5zIOi/h+a7pOS5i+WQjueahOaVsOaNrlxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmZpbHRlckRhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgZmlsdGVycyA9IHRoaXMub3B0aW9ucy5maWx0ZXJzO1xuICAgICAgICAvLyDkuI3lrZjlnKggZmlsdGVyc++8jOWImeS4jemcgOimgei/m+ihjOaVsOaNrui/h+a7pFxuICAgICAgICBpZiAodXRpbF8xLnNpemUoZmlsdGVycykgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWtmOWcqOi/h+a7pOWZqO+8jOWImemAkOS4quaJp+ihjOi/h+a7pO+8jOi/h+a7pOWZqOS5i+mXtOaYryDkuI4g55qE5YWz57O7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmlsdGVyKGRhdGEsIGZ1bmN0aW9uIChkYXR1bSwgaWR4KSB7XG4gICAgICAgICAgICAvLyDmiYDmnInnmoQgZmlsdGVyIOWtl+autVxuICAgICAgICAgICAgdmFyIGZpZWxkcyA9IE9iamVjdC5rZXlzKGZpbHRlcnMpO1xuICAgICAgICAgICAgLy8g5omA5pyJ55qE5p2h5Lu26YO96YCa6L+H77yM5omN566X6YCa6L+HXG4gICAgICAgICAgICByZXR1cm4gZmllbGRzLmV2ZXJ5KGZ1bmN0aW9uIChmaWVsZCkge1xuICAgICAgICAgICAgICAgIHZhciBjb25kaXRpb24gPSBmaWx0ZXJzW2ZpZWxkXTtcbiAgICAgICAgICAgICAgICAvLyBjb25kaXRpb24g6L+U5ZueIHRydWXvvIzliJnkv53nlZlcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uZGl0aW9uKGRhdHVtW2ZpZWxkXSwgZGF0dW0sIGlkeCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlr7nmn5DkuIDkuKrlrZfmrrXov5vooYzov4fmu6RcbiAgICAgKiBAcGFyYW0gZmllbGRcbiAgICAgKiBAcGFyYW0gZGF0YVxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmZpbHRlckZpZWxkRGF0YSA9IGZ1bmN0aW9uIChmaWVsZCwgZGF0YSkge1xuICAgICAgICB2YXIgZmlsdGVycyA9IHRoaXMub3B0aW9ucy5maWx0ZXJzO1xuICAgICAgICB2YXIgY29uZGl0aW9uID0gdXRpbF8xLmdldChmaWx0ZXJzLCBmaWVsZCk7XG4gICAgICAgIGlmICh1dGlsXzEuaXNVbmRlZmluZWQoY29uZGl0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGEuZmlsdGVyKGZ1bmN0aW9uIChkYXR1bSwgaWR4KSB7IHJldHVybiBjb25kaXRpb24oZGF0dW1bZmllbGRdLCBkYXR1bSwgaWR4KTsgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDosIPmlbQgY29vcmRpbmF0ZSDnmoTlnZDmoIfojIPlm7TjgIJcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5hZGp1c3RDb29yZGluYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldENvb3JkaW5hdGUoKSwgY3VyU3RhcnQgPSBfYS5zdGFydCwgY3VyRW5kID0gX2EuZW5kO1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmNvb3JkaW5hdGVCQm94LmJsO1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5jb29yZGluYXRlQkJveC50cjtcbiAgICAgICAgLy8g5ZyoIGRlZmF1bHRMYXlvdXRGbiDkuK3lj6rkvJrlnKggY29vcmRpbmF0ZUJCb3gg5Y+R55Sf5Y+Y5YyW55qE5pe25YCZ5Lya6LCD55SoIGFkanVzdENvb3JpbmF0ZSgp77yM5omA5Lul5LiN55So5ouF5b+D6KKr572u5L2NXG4gICAgICAgIGlmICh1dGlsXzEuaXNFcXVhbChjdXJTdGFydCwgc3RhcnQpICYmIHV0aWxfMS5pc0VxdWFsKGN1ckVuZCwgZW5kKSkge1xuICAgICAgICAgICAgdGhpcy5pc0Nvb3JkaW5hdGVDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAvLyDlpoLmnpzlpKflsI/msqHmnInlj5jljJbliJnkuI3mm7TmlrBcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzQ29vcmRpbmF0ZUNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmNvb3JkaW5hdGVJbnN0YW5jZSA9IHRoaXMuY29vcmRpbmF0ZUNvbnRyb2xsZXIuYWRqdXN0KHN0YXJ0LCBlbmQpO1xuICAgIH07XG4gICAgVmlldy5wcm90b3R5cGUucGFpbnQgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJEYXRhUmVjdXJzaXZlKGlzVXBkYXRlKTtcbiAgICAgICAgLy8g5aSE55CGIHN5bmMgc2NhbGUg55qE6YC76L6RXG4gICAgICAgIHRoaXMuc3luY1NjYWxlKCk7XG4gICAgICAgIHRoaXMuZW1pdChjb25zdGFudF8xLlZJRVdfTElGRV9DSVJDTEUuQkVGT1JFX1BBSU5UKTtcbiAgICAgICAgdGhpcy5yZW5kZXJCYWNrZ3JvdW5kU3R5bGVTaGFwZSgpO1xuICAgICAgICB0aGlzLnJlbmRlckxheW91dFJlY3Vyc2l2ZShpc1VwZGF0ZSk7XG4gICAgICAgIHRoaXMucmVuZGVyUGFpbnRSZWN1cnNpdmUoaXNVcGRhdGUpO1xuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1BBSU5UKTtcbiAgICAgICAgdGhpcy5pc0RhdGFDaGFuZ2VkID0gZmFsc2U7IC8vIOa4suafk+WujOavleWkjeS9jVxuICAgIH07XG4gICAgLyoqIOa4suafk+iDjOaZr+agt+W8j+eahCBzaGFwZSAqL1xuICAgIFZpZXcucHJvdG90eXBlLnJlbmRlckJhY2tncm91bmRTdHlsZVNoYXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDlj6rmnInmoLnoioLngrnmiY3lpITnkIZcbiAgICAgICAgaWYgKCF0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdmFyIGJhY2tncm91bmQgPSB1dGlsXzEuZ2V0KHRoaXMudGhlbWVPYmplY3QsICdiYWNrZ3JvdW5kJyk7XG4gICAgICAgICAgICAvLyAxLiDphY3nva7kuobog4zmma/oibJcbiAgICAgICAgICAgIGlmIChiYWNrZ3JvdW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gMS4g5LiN5a2Y5Zyo5YiZ5Yib5bu6XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmJhY2tncnVvbmRTdHlsZVJlY3RTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJhY2tncnVvbmRTdHlsZVJlY3RTaGFwZSA9IHRoaXMuYmFja2dyb3VuZEdyb3VwLmFkZFNoYXBlKCdyZWN0Jywge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXg6IC0xLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIDIuIOacieS6hiBzaGFwZSDkuYvlkI7orr7nva7og4zmma/vvIzkvY3nva7vvIjmm7TmlrDnmoTml7blgJnvvIlcbiAgICAgICAgICAgICAgICB2YXIgX2EgPSB0aGlzLnZpZXdCQm94LCB4ID0gX2EueCwgeSA9IF9hLnksIHdpZHRoID0gX2Eud2lkdGgsIGhlaWdodCA9IF9hLmhlaWdodDtcbiAgICAgICAgICAgICAgICB0aGlzLmJhY2tncnVvbmRTdHlsZVJlY3RTaGFwZS5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogYmFja2dyb3VuZCxcbiAgICAgICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOayoeaciemFjee9ruiDjOaZr+iJslxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmJhY2tncnVvbmRTdHlsZVJlY3RTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJhY2tncnVvbmRTdHlsZVJlY3RTaGFwZS5yZW1vdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmFja2dydW9uZFN0eWxlUmVjdFNoYXBlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5pu/5o2i5aSE55CGIHZpZXcg55qE5biD5bGA77yM5pyA57uI5piv6K6h566X5ZCE5LiqIHZpZXcg55qEIGNvb3JkaW5hdGVCQm94IOWSjCBjb29yZGluYXRlSW5zdGFuY2VcbiAgICAgKiBAcGFyYW0gaXNVcGRhdGVcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5yZW5kZXJMYXlvdXRSZWN1cnNpdmUgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgLy8gMS4g5a2QIHZpZXcg5aSn5bCP55u45a+5IGNvb3JkaW5hdGVCQm9477yMY2hhbmdlU2l6ZSDnmoTml7blgJnpnIDopoHph43mlrDorqHnrpdcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVWaWV3QkJveCgpO1xuICAgICAgICAvLyAyLiDmm7TmlrAgY29vcmRpbmF0ZVxuICAgICAgICB0aGlzLmFkanVzdENvb3JkaW5hdGUoKTtcbiAgICAgICAgLy8gMy4g5Yid5aeL5YyW57uE5Lu2IGNvbXBvbmVudFxuICAgICAgICB0aGlzLmluaXRDb21wb25lbnRzKGlzVXBkYXRlKTtcbiAgICAgICAgLy8gNC4g6L+b6KGM5biD5bGA77yM6K6h566XIGNvb3JkaW5hdGVCQm9477yM6L+b6KGM57uE5Lu25biD5bGA77yMdXBkYXRlIOS9jee9rlxuICAgICAgICB0aGlzLmRvTGF5b3V0KCk7XG4gICAgICAgIC8vIDUuIOabtOaWsOW5tuWtmOWCqOacgOe7iOeahCBwYWRkaW5nIOWAvFxuICAgICAgICB2YXIgdmlld0JCb3ggPSB0aGlzLnZpZXdCQm94O1xuICAgICAgICB2YXIgY29vcmRpbmF0ZUJCb3ggPSB0aGlzLmNvb3JkaW5hdGVCQm94O1xuICAgICAgICBpZiAocGFkZGluZ18xLmlzQXV0b1BhZGRpbmcodGhpcy5wYWRkaW5nKSkge1xuICAgICAgICAgICAgLy8g55So5oi35pyq6K6+572uIHBhZGRpbmcg5pe277yM5bCG6Ieq5Yqo6K6h566X55qEIHBhZGRpbmcg5L+d5a2Y6IezIGF1dG9QYWRkaW5nIOWxnuaAp+S4rVxuICAgICAgICAgICAgdGhpcy5hdXRvUGFkZGluZyA9IFtcbiAgICAgICAgICAgICAgICBjb29yZGluYXRlQkJveC50bC55IC0gdmlld0JCb3gudGwueSxcbiAgICAgICAgICAgICAgICB2aWV3QkJveC50ci54IC0gY29vcmRpbmF0ZUJCb3gudHIueCxcbiAgICAgICAgICAgICAgICB2aWV3QkJveC5ibC55IC0gY29vcmRpbmF0ZUJCb3guYmwueSxcbiAgICAgICAgICAgICAgICBjb29yZGluYXRlQkJveC50bC54IC0gdmlld0JCb3gudGwueCxcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgLy8g5ZCM5qC36YCS5b2S5aSE55CG5a2QIHZpZXdzXG4gICAgICAgIHZhciB2aWV3cyA9IHRoaXMudmlld3M7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB2aWV3cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIHZpZXcgPSB2aWV3c1tpXTtcbiAgICAgICAgICAgIHZpZXcucmVuZGVyTGF5b3V0UmVjdXJzaXZlKGlzVXBkYXRlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5pyA57uI6YCS5b2S57uY5Yi257uE5Lu25ZKM5Zu+5b2iXG4gICAgICogQHBhcmFtIGlzVXBkYXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUucmVuZGVyUGFpbnRSZWN1cnNpdmUgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKHRoaXMubGltaXRJblBsb3QpIHtcbiAgICAgICAgICAgIHZhciBtaWRkbGVHcm91cCA9IHRoaXMubWlkZGxlR3JvdXA7XG4gICAgICAgICAgICB2YXIgX2EgPSBjb29yZGluYXRlXzEuZ2V0Q29vcmRpbmF0ZUNsaXBDZmcodGhpcy5jb29yZGluYXRlSW5zdGFuY2UpLCB0eXBlID0gX2EudHlwZSwgYXR0cnMgPSBfYS5hdHRycztcbiAgICAgICAgICAgIG1pZGRsZUdyb3VwLnNldENsaXAoe1xuICAgICAgICAgICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgICAgICAgICAgYXR0cnM6IGF0dHJzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMS4g5riy5p+T5Yeg5L2V5qCH6K6wXG4gICAgICAgIHRoaXMucGFpbnRHZW9tZXRyaWVzKGlzVXBkYXRlKTtcbiAgICAgICAgLy8gMi4g57uY5Yi257uE5Lu2XG4gICAgICAgIHRoaXMucmVuZGVyQ29tcG9uZW50cyhpc1VwZGF0ZSk7XG4gICAgICAgIC8vIOWQjOagt+mAkuW9kuWkhOeQhuWtkCB2aWV3c1xuICAgICAgICB2YXIgdmlld3MgPSB0aGlzLnZpZXdzO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdmlld3MubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciB2aWV3ID0gdmlld3NbaV07XG4gICAgICAgICAgICB2aWV3LnJlbmRlclBhaW50UmVjdXJzaXZlKGlzVXBkYXRlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8gZW5kIEdldCDmlrnms5VcbiAgICAvKipcbiAgICAgKiDliJvlu7ogc2NhbGXvvIzpgJLlvZLliLDpobblsYIgdmlldyDljrvliJvlu7rlkoznvJPlrZggc2NhbGVcbiAgICAgKiBAcGFyYW0gZmllbGRcbiAgICAgKiBAcGFyYW0gZGF0YVxuICAgICAqIEBwYXJhbSBzY2FsZURlZlxuICAgICAqIEBwYXJhbSBrZXlcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5jcmVhdGVTY2FsZSA9IGZ1bmN0aW9uIChmaWVsZCwgZGF0YSwgc2NhbGVEZWYsIGtleSkge1xuICAgICAgICAvLyAxLiDlkIjlubYgZmllbGQg5a+55bqU55qEIHNjYWxlRGVm77yM5ZCI5bm25Y6f5YiZ5piv5bqV5bGC6KaG55uW6aG25bGC77yI5bCx6L+R5Y6f5YiZ77yJXG4gICAgICAgIHZhciBjdXJyZW50U2NhbGVEZWYgPSB1dGlsXzEuZ2V0KHRoaXMub3B0aW9ucy5zY2FsZXMsIFtmaWVsZF0pO1xuICAgICAgICB2YXIgbWVyZ2VkU2NhbGVEZWYgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGN1cnJlbnRTY2FsZURlZiksIHNjYWxlRGVmKTtcbiAgICAgICAgLy8gMi4g5piv5ZCm5a2Y5Zyo54i2IHZpZXfvvIzlnKjliJnpgJLlvZLvvIzlkKbliJnliJvlu7pcbiAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuY3JlYXRlU2NhbGUoZmllbGQsIGRhdGEsIG1lcmdlZFNjYWxlRGVmLCBrZXkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuIOWcqOagueiKgueCuSB2aWV3IOmAmui/hyBzY2FsZVBvb2wg5Yib5bu6XG4gICAgICAgIHJldHVybiB0aGlzLnNjYWxlUG9vbC5jcmVhdGVTY2FsZShmaWVsZCwgZGF0YSwgbWVyZ2VkU2NhbGVEZWYsIGtleSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpgJLlvZLmuLLmn5PkuK3nmoTmlbDmja7lpITnkIZcbiAgICAgKiBAcGFyYW0gaXNVcGRhdGVcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5yZW5kZXJEYXRhUmVjdXJzaXZlID0gZnVuY3Rpb24gKGlzVXBkYXRlKSB7XG4gICAgICAgIC8vIDEuIOWkhOeQhuaVsOaNrlxuICAgICAgICB0aGlzLmRvRmlsdGVyRGF0YSgpO1xuICAgICAgICAvLyAyLiDliJvlu7rlrp7kvotcbiAgICAgICAgdGhpcy5jcmVhdGVDb29yZGluYXRlKCk7XG4gICAgICAgIC8vIDMuIOWIneWni+WMliBHZW9tZXRyeVxuICAgICAgICB0aGlzLmluaXRHZW9tZXRyaWVzKGlzVXBkYXRlKTtcbiAgICAgICAgLy8gNC4g5aSE55CG5YiG6Z2i6YC76L6R77yM5pyA57uI6YO95piv55Sf5oiQ5a2QIHZpZXcg5ZKMIGdlb21ldHJ5XG4gICAgICAgIHRoaXMucmVuZGVyRmFjZXQoaXNVcGRhdGUpO1xuICAgICAgICAvLyDlkIzmoLfpgJLlvZLlpITnkIblrZAgdmlld3NcbiAgICAgICAgdmFyIHZpZXdzID0gdGhpcy52aWV3cztcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHZpZXdzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgdmlldyA9IHZpZXdzW2ldO1xuICAgICAgICAgICAgdmlldy5yZW5kZXJEYXRhUmVjdXJzaXZlKGlzVXBkYXRlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6h566XIHJlZ2lvbu+8jOiuoeeul+WunumZheeahOWDj+e0oOiMg+WbtOWdkOagh1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuY2FsY3VsYXRlVmlld0JCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4O1xuICAgICAgICB2YXIgeTtcbiAgICAgICAgdmFyIHdpZHRoO1xuICAgICAgICB2YXIgaGVpZ2h0O1xuICAgICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gdGhpcy5wYXJlbnQuY29vcmRpbmF0ZUJCb3g7XG4gICAgICAgICAgICAvLyDlrZjlnKggcGFyZW5077yMIOmCo+S5iOWwseaYr+mAmui/h+eItuWuueWZqOWkp+Wwj+iuoeeul1xuICAgICAgICAgICAgeCA9IGJib3gueDtcbiAgICAgICAgICAgIHkgPSBiYm94Lnk7XG4gICAgICAgICAgICB3aWR0aCA9IGJib3gud2lkdGg7XG4gICAgICAgICAgICBoZWlnaHQgPSBiYm94LmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOmhtuWxguWuueWZqO+8jOS7jiBjYW52YXMg5Lit5Y+W5YC8IOWuvemrmFxuICAgICAgICAgICAgeCA9IDA7XG4gICAgICAgICAgICB5ID0gMDtcbiAgICAgICAgICAgIHdpZHRoID0gdGhpcy5jYW52YXMuZ2V0KCd3aWR0aCcpO1xuICAgICAgICAgICAgaGVpZ2h0ID0gdGhpcy5jYW52YXMuZ2V0KCdoZWlnaHQnKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgX2EgPSB0aGlzLnJlZ2lvbiwgc3RhcnQgPSBfYS5zdGFydCwgZW5kID0gX2EuZW5kO1xuICAgICAgICAvLyDmoLnmja4gcmVnaW9uIOiuoeeul+W9k+WJjSB2aWV3IOeahCBiYm94IOWkp+Wwj+OAglxuICAgICAgICB2YXIgdmlld0JCb3ggPSBuZXcgYmJveF8xLkJCb3goeCArIHdpZHRoICogc3RhcnQueCwgeSArIGhlaWdodCAqIHN0YXJ0LnksIHdpZHRoICogKGVuZC54IC0gc3RhcnQueCksIGhlaWdodCAqIChlbmQueSAtIHN0YXJ0LnkpKTtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdCQm94IHx8ICF0aGlzLnZpZXdCQm94LmlzRXF1YWwodmlld0JCb3gpKSB7XG4gICAgICAgICAgICAvLyB2aWV3QkJveCDlj5HnlJ/lj5jljJbnmoTml7blgJnov5vooYzmm7TmlrBcbiAgICAgICAgICAgIHRoaXMudmlld0JCb3ggPSBuZXcgYmJveF8xLkJCb3goeCArIHdpZHRoICogc3RhcnQueCwgeSArIGhlaWdodCAqIHN0YXJ0LnksIHdpZHRoICogKGVuZC54IC0gc3RhcnQueCksIGhlaWdodCAqIChlbmQueSAtIHN0YXJ0LnkpKTtcbiAgICAgICAgICAgIC8vIOWIneWni+eahCBjb29yZGluYXRlIGJib3gg5aSn5bCPXG4gICAgICAgICAgICB0aGlzLmNvb3JkaW5hdGVCQm94ID0gdGhpcy52aWV3QkJveDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yid5aeL5YyW5LqL5Lu25py65Yi277yaRyA0LjAg5bqV5bGC5YaF572u5pSv5oyBIG5hbWU6ZXZlbnQg55qE5py65Yi277yM6YKj5LmI5Y+q6KaB5omA5pyJ57uE5Lu26YO95pyJ6Ieq5bex55qEIG5hbWUg5Y2z5Y+v44CCXG4gICAgICpcbiAgICAgKiBHMiDnmoTkuovku7blj6rmmK/ojrflj5bkuovku7blp5TmiZjvvIznhLblkI7lnKggdmlldyDltYzlpZfnu5PmnoTkuK3vvIzlvaLmiJDkuovku7blhpLms6HmnLrliLbjgIJcbiAgICAgKiDlvZPliY0gdmlldyDlj6rlp5TmiZjoh6rlt7EgdmlldyDkuK3nmoQgQ29tcG9uZW50IOWSjCBHZW9tZXRyeSDkuovku7bvvIzlubblkJHkuIrlhpLms6FcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmluaXRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOS4ieWxgiBncm91cCDkuK3nmoQgc2hhcGUg5LqL5Lu26YO95Lya6YCa6L+HIEcg5YaS5rOh5LiK5p2l55qEXG4gICAgICAgIHRoaXMuZm9yZWdyb3VuZEdyb3VwLm9uKCcqJywgdGhpcy5vbkRlbGVnYXRlRXZlbnRzKTtcbiAgICAgICAgdGhpcy5taWRkbGVHcm91cC5vbignKicsIHRoaXMub25EZWxlZ2F0ZUV2ZW50cyk7XG4gICAgICAgIHRoaXMuYmFja2dyb3VuZEdyb3VwLm9uKCcqJywgdGhpcy5vbkRlbGVnYXRlRXZlbnRzKTtcbiAgICAgICAgdGhpcy5jYW52YXMub24oJyonLCB0aGlzLm9uQ2FudmFzRXZlbnQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yid5aeL5YyW5o+S5Lu2XG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuaW5pdENvbXBvbmVudENvbnRyb2xsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB1c2VkQ29udHJvbGxlcnMgPSB0aGlzLnVzZWRDb250cm9sbGVycztcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHVzZWRDb250cm9sbGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGNvbnRyb2xsZXJOYW1lID0gdXNlZENvbnRyb2xsZXJzW2ldO1xuICAgICAgICAgICAgdmFyIEN0b3IgPSBjb250cm9sbGVyXzEuZ2V0Q29tcG9uZW50Q29udHJvbGxlcihjb250cm9sbGVyTmFtZSk7XG4gICAgICAgICAgICBpZiAoQ3Rvcikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcnMucHVzaChuZXcgQ3Rvcih0aGlzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFZpZXcucHJvdG90eXBlLmNyZWF0ZVZpZXdFdmVudCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgdmFyIHNoYXBlID0gZXZ0LnNoYXBlLCBuYW1lID0gZXZ0Lm5hbWU7XG4gICAgICAgIHZhciBkYXRhID0gc2hhcGUgPyBzaGFwZS5nZXQoJ29yaWdpbicpIDogbnVsbDtcbiAgICAgICAgLy8g5LqL5Lu25ZyoIHZpZXcg5bWM5aWX5Lit5YaS5rOh77yI5pqC5LiN5o+Q5L6b6Zi75q2i5YaS5rOh55qE5py65Yi277yJXG4gICAgICAgIHZhciBlID0gbmV3IGV2ZW50XzEuZGVmYXVsdCh0aGlzLCBldnQsIGRhdGEpO1xuICAgICAgICBlLnR5cGUgPSBuYW1lO1xuICAgICAgICByZXR1cm4gZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWkhOeQhiBQTE9UX0VWRU5UU1xuICAgICAqIHBsb3QgZXZlbnQg6ZyA6KaB5aSE55CG5omA5pyJ55qE5Z+656GA5LqL5Lu277yM5bm25Yik5pat5piv5ZCm5Zyo55S75biD5Lit77yM54S25ZCO5YaN5Yaz5a6a5piv5ZCm6KaBIGVtaXTjgIJcbiAgICAgKiDlr7nkuo4gbW91c2VlbnRlcuOAgW1vdXNlbGVhdmUg5q+U6L6D54m55q6K77yM6ZyA6KaB5YGa5LiA5LiL5pWw5a2m5q+U6L6D44CCXG4gICAgICogQHBhcmFtIGVcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5kb1Bsb3RFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB0eXBlID0gZS50eXBlLCB4ID0gZS54LCB5ID0gZS55O1xuICAgICAgICB2YXIgcG9pbnQgPSB7IHg6IHgsIHk6IHkgfTtcbiAgICAgICAgdmFyIEFMTF9FVkVOVFMgPSBbXG4gICAgICAgICAgICAnbW91c2Vkb3duJyxcbiAgICAgICAgICAgICdtb3VzZXVwJyxcbiAgICAgICAgICAgICdtb3VzZW1vdmUnLFxuICAgICAgICAgICAgJ21vdXNlbGVhdmUnLFxuICAgICAgICAgICAgJ21vdXNld2hlZWwnLFxuICAgICAgICAgICAgJ3RvdWNoc3RhcnQnLFxuICAgICAgICAgICAgJ3RvdWNobW92ZScsXG4gICAgICAgICAgICAndG91Y2hlbmQnLFxuICAgICAgICAgICAgJ3RvdWNoY2FuY2VsJyxcbiAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAnZGJsY2xpY2snLFxuICAgICAgICAgICAgJ2NvbnRleHRtZW51JyxcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKEFMTF9FVkVOVFMuaW5jbHVkZXModHlwZSkpIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50SW5QbG90ID0gdGhpcy5pc1BvaW50SW5QbG90KHBvaW50KTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50SW5QbG90KSB7XG4gICAgICAgICAgICAgICAgdmFyIFRZUEUgPSBcInBsb3Q6XCIgKyB0eXBlOyAvLyDnu4TlkIggcGxvdCDkuovku7ZcbiAgICAgICAgICAgICAgICBlLnR5cGUgPSBUWVBFO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChUWVBFLCBlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlbGVhdmUnIHx8IHR5cGUgPT09ICd0b3VjaGVuZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5ZyocGxvdCDlhoXpg6jljbTnprvlvIDnlLvluINcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1ByZU1vdXNlSW5QbG90ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5a+55LqOIG1vdXNlZW50ZXIsIG1vdXNlbGVhdmUg55qE6K6h566X5aSE55CGXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlbW92ZScgfHwgdHlwZSA9PT0gJ3RvdWNobW92ZScpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1ByZU1vdXNlSW5QbG90ICYmICFjdXJyZW50SW5QbG90KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnbW91c2Vtb3ZlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZS50eXBlID0gY29uc3RhbnRfMS5QTE9UX0VWRU5UUy5NT1VTRV9MRUFWRTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChjb25zdGFudF8xLlBMT1RfRVZFTlRTLk1PVVNFX0xFQVZFLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlLnR5cGUgPSBjb25zdGFudF8xLlBMT1RfRVZFTlRTLkxFQVZFO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5QTE9UX0VWRU5UUy5MRUFWRSwgZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCF0aGlzLmlzUHJlTW91c2VJblBsb3QgJiYgY3VycmVudEluUGxvdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ21vdXNlbW92ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGUudHlwZSA9IGNvbnN0YW50XzEuUExPVF9FVkVOVFMuTU9VU0VfRU5URVI7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5QTE9UX0VWRU5UUy5NT1VTRV9FTlRFUiwgZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZS50eXBlID0gY29uc3RhbnRfMS5QTE9UX0VWRU5UUy5FTlRFUjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KGNvbnN0YW50XzEuUExPVF9FVkVOVFMuRU5URVIsIGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyDotYvmlrDnmoTnirbmgIHlgLxcbiAgICAgICAgICAgICAgICB0aGlzLmlzUHJlTW91c2VJblBsb3QgPSBjdXJyZW50SW5QbG90O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ21vdXNlbGVhdmUnIHx8IHR5cGUgPT09ICd0b3VjaGVuZCcpIHtcbiAgICAgICAgICAgICAgICAvLyDlj6/og73kuI3lnKggY3VycmVudEluUGxvdCDkuK1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1ByZU1vdXNlSW5QbG90KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnbW91c2VsZWF2ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGUudHlwZSA9IGNvbnN0YW50XzEuUExPVF9FVkVOVFMuTU9VU0VfTEVBVkU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRfMS5QTE9UX0VWRU5UUy5NT1VTRV9MRUFWRSwgZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZS50eXBlID0gY29uc3RhbnRfMS5QTE9UX0VWRU5UUy5MRUFWRTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KGNvbnN0YW50XzEuUExPVF9FVkVOVFMuTEVBVkUsIGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUHJlTW91c2VJblBsb3QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIHZpZXcg55Sf5ZG95ZGo5pyfIOKAlOKAlCDmuLLmn5PmtYHnqItcbiAgICAvKipcbiAgICAgKiDlpITnkIbnrZvpgInlmajvvIznrZvpgInmlbDmja5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmRvRmlsdGVyRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLm9wdGlvbnMuZGF0YTtcbiAgICAgICAgdGhpcy5maWx0ZXJlZERhdGEgPSB0aGlzLmZpbHRlckRhdGEoZGF0YSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJ3lp4vljJYgR2VvbWV0cmllc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuaW5pdEdlb21ldHJpZXMgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgLy8g5Yid5aeL5YyW5Zu+5b2i55qE5LmL5YmN77yM5YWI5Yib5bu6IC8g5pu05pawIHNjYWxlc1xuICAgICAgICB0aGlzLmNyZWF0ZU9yVXBkYXRlU2NhbGVzKCk7XG4gICAgICAgIC8vIOWunuS+i+WMliBHZW9tZXRyee+8jOeEtuWQjiB2aWV3IOWwhuaJgOacieeahCBzY2FsZSDnrqHnkIbotbfmnaVcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHNjYWxlRGVmcyA9IHV0aWxfMS5nZXQodGhpcy5vcHRpb25zLCAnc2NhbGVzJywge30pO1xuICAgICAgICB2YXIgZ2VvbWV0cmllcyA9IHRoaXMuZ2VvbWV0cmllcztcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IGdlb21ldHJpZXNbaV07XG4gICAgICAgICAgICAvLyDkv53mjIEgc2NhbGVzIOW8leeUqOS4jeimgeWPmOWMllxuICAgICAgICAgICAgZ2VvbWV0cnkuc2NhbGVzID0gdGhpcy5nZXRHZW9tZXRyeVNjYWxlcygpO1xuICAgICAgICAgICAgdmFyIGNmZyA9IHtcbiAgICAgICAgICAgICAgICBjb29yZGluYXRlOiBjb29yZGluYXRlLFxuICAgICAgICAgICAgICAgIHNjYWxlRGVmczogc2NhbGVEZWZzLFxuICAgICAgICAgICAgICAgIGRhdGE6IHRoaXMuZmlsdGVyZWREYXRhLFxuICAgICAgICAgICAgICAgIHRoZW1lOiB0aGlzLnRoZW1lT2JqZWN0LFxuICAgICAgICAgICAgICAgIGlzRGF0YUNoYW5nZWQ6IHRoaXMuaXNEYXRhQ2hhbmdlZCxcbiAgICAgICAgICAgICAgICBpc0Nvb3JkaW5hdGVDaGFuZ2VkOiB0aGlzLmlzQ29vcmRpbmF0ZUNoYW5nZWQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGlzVXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgLy8g5pWw5o2u5Y+R55Sf5pu05pawXG4gICAgICAgICAgICAgICAgZ2VvbWV0cnkudXBkYXRlKGNmZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBnZW9tZXRyeS5pbml0KGNmZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gR2VvbWV0cnkg5Yid5aeL5YyW5LmL5ZCO77yM55Sf5oiQ5LqGIHNjYWxl77yM54S25ZCO6L+b6KGM6LCD5pW0IHNjYWxlIOmFjee9rlxuICAgICAgICB0aGlzLmFkanVzdFNjYWxlcygpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5qC55o2uIEdlb21ldHJ5IOeahOaJgOacieWtl+auteWIm+W7uiBzY2FsZXNcbiAgICAgKiDlpoLmnpzlrZjlnKjvvIzliJnmm7TmlrDvvIzkuI3lrZjlnKjliJnliJvlu7pcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5jcmVhdGVPclVwZGF0ZVNjYWxlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZpZWxkcyA9IHRoaXMuZ2V0U2NhbGVGaWVsZHMoKTtcbiAgICAgICAgdmFyIGdyb3VwZWRGaWVsZHMgPSB0aGlzLmdldEdyb3VwZWRGaWVsZHMoKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRPcHRpb25zKCksIGRhdGEgPSBfYS5kYXRhLCBfYiA9IF9hLnNjYWxlcywgc2NhbGVzID0gX2IgPT09IHZvaWQgMCA/IHt9IDogX2I7XG4gICAgICAgIHZhciBmaWx0ZXJlZERhdGEgPSB0aGlzLmZpbHRlcmVkRGF0YTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGZpZWxkcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGZpZWxkID0gZmllbGRzW2ldO1xuICAgICAgICAgICAgdmFyIHNjYWxlRGVmID0gc2NhbGVzW2ZpZWxkXTtcbiAgICAgICAgICAgIC8vIOiwg+eUqOaWueazle+8jOmAkuW9kuWOu+WIm+W7ulxuICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuZ2V0U2NhbGVLZXkoZmllbGQpO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVTY2FsZShmaWVsZCwgXG4gICAgICAgICAgICAvLyDliIbnu4TlrZfmrrXnmoQgc2NhbGUg5L2/55So5pyq6L+H5ruk55qE5pWw5o2u5Yib5bu6XG4gICAgICAgICAgICBncm91cGVkRmllbGRzLmluY2x1ZGVzKGZpZWxkKSA/IGRhdGEgOiBmaWx0ZXJlZERhdGEsIHNjYWxlRGVmLCBrZXkpO1xuICAgICAgICAgICAgLy8g57yT5a2Y5LuO5b2T5YmNIHZpZXcg5Yib5bu655qEIHNjYWxlIGtleVxuICAgICAgICAgICAgdGhpcy5jcmVhdGVkU2NhbGVLZXlzLnNldChrZXksIHRydWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlpITnkIYgc2NhbGUg5ZCM5q2l6YC76L6RXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuc3luY1NjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDmnIDnu4josIPnlKggcm9vdCB2aWV3IOeahFxuICAgICAgICB0aGlzLmdldFJvb3RWaWV3KCkuc2NhbGVQb29sLnN5bmMoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+W+lyBHZW9tZXRyeSDkuK3nmoQgc2NhbGUg5a+56LGhXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0R2VvbWV0cnlTY2FsZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmaWVsZHMgPSB0aGlzLmdldFNjYWxlRmllbGRzKCk7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IGZpZWxkc1tpXTtcbiAgICAgICAgICAgIHNjYWxlc1tmaWVsZF0gPSB0aGlzLmdldFNjYWxlQnlGaWVsZChmaWVsZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjYWxlcztcbiAgICB9O1xuICAgIFZpZXcucHJvdG90eXBlLmdldFNjYWxlRmllbGRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmllbGRzID0gW107XG4gICAgICAgIHZhciB0bXBNYXAgPSB7fTtcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXM7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvbWV0cmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGdlb21ldHJ5ID0gZ2VvbWV0cmllc1tpXTtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeVNjYWxlcyA9IGdlb21ldHJ5LmdldFNjYWxlRmllbGRzKCk7XG4gICAgICAgICAgICBoZWxwZXJfMS51bmlxKGdlb21ldHJ5U2NhbGVzLCBmaWVsZHMsIHRtcE1hcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICB9O1xuICAgIFZpZXcucHJvdG90eXBlLmdldEdyb3VwZWRGaWVsZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmaWVsZHMgPSBbXTtcbiAgICAgICAgdmFyIHRtcE1hcCA9IHt9O1xuICAgICAgICB2YXIgZ2VvbWV0cmllcyA9IHRoaXMuZ2VvbWV0cmllcztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnZW9tZXRyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnkgPSBnZW9tZXRyaWVzW2ldO1xuICAgICAgICAgICAgdmFyIGdyb3VwRmllbGRzID0gZ2VvbWV0cnkuZ2V0R3JvdXBGaWVsZHMoKTtcbiAgICAgICAgICAgIGhlbHBlcl8xLnVuaXEoZ3JvdXBGaWVsZHMsIGZpZWxkcywgdG1wTWFwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6LCD5pW0IHNjYWxlIOmFjee9rlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuYWRqdXN0U2NhbGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDosIPmlbTnm67liY3ljIXmi6zvvJpcbiAgICAgICAgLy8g5YiG57G7IHNjYWxl77yM6LCD5pW0IHJhbmdlIOiMg+WbtFxuICAgICAgICB0aGlzLmFkanVzdENhdGVnb3J5U2NhbGVSYW5nZSgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6LCD5pW05YiG57G7IHNjYWxlIOeahCByYW5nZe+8jOmYsuatoui2heWHuuWdkOagh+ezu+WklumdolxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuYWRqdXN0Q2F0ZWdvcnlTY2FsZVJhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgeHlTY2FsZXMgPSB0c2xpYl8xLl9fc3ByZWFkQXJyYXlzKFt0aGlzLmdldFhTY2FsZSgpXSwgdGhpcy5nZXRZU2NhbGVzKCkpLmZpbHRlcihmdW5jdGlvbiAoZSkgeyByZXR1cm4gISFlOyB9KTtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHNjYWxlT3B0aW9ucyA9IHRoaXMub3B0aW9ucy5zY2FsZXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHh5U2NhbGVzLCBmdW5jdGlvbiAoc2NhbGUpIHtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IHNjYWxlLmZpZWxkLCB2YWx1ZXMgPSBzY2FsZS52YWx1ZXMsIGlzQ2F0ZWdvcnkgPSBzY2FsZS5pc0NhdGVnb3J5LCBpc0lkZW50aXR5ID0gc2NhbGUuaXNJZGVudGl0eTtcbiAgICAgICAgICAgIC8vIOWIhuexu+aIluiAhSBpZGVudGl0eSDnmoQgc2NhbGUg5omN6L+b6KGM5aSE55CGXG4gICAgICAgICAgICBpZiAoaXNDYXRlZ29yeSB8fCBpc0lkZW50aXR5KSB7XG4gICAgICAgICAgICAgICAgLy8g5a2Y5ZyoIHZhbHVlIOWAvO+8jOS4lOeUqOaIt+ayoeaciemFjee9riByYW5nZSDphY3nva5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWVzICYmICF1dGlsXzEuZ2V0KHNjYWxlT3B0aW9ucywgW2ZpZWxkLCAncmFuZ2UnXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvdW50ID0gdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlID0gWzAuNSwgMV07IC8vIOWPquacieS4gOS4quWIhuexu+aXtizpmLLmraLorqHnrpflh7rnjrAgWzAuNSwwLjVdIOeahOeKtuaAgVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoUmF0aW8gPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZV8xLmlzRnVsbENpcmNsZShjb29yZGluYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSBbMCwgMSAtIDEgLyBjb3VudF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aFJhdGlvID0gdXRpbF8xLmdldChfdGhpcy50aGVtZSwgJ3dpZHRoUmF0aW8ubXVsdGlwbGVQaWUnLCAxIC8gMS4zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gKDEgLyBjb3VudCkgKiB3aWR0aFJhdGlvO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSA9IFtvZmZzZXQgLyAyLCAxIC0gb2Zmc2V0IC8gMl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMSAvIGNvdW50IC8gMjsgLy8g5Lik6L6555WZ5LiL5YiG57G756m66Ze055qE5LiA5Y2KXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSBbb2Zmc2V0LCAxIC0gb2Zmc2V0XTsgLy8g5Z2Q5qCH6L205pyA5YmN6Z2i5ZKM5pyA5ZCO6Z2i55WZ5LiL56m655m96Ziy5q2i57uY5Yi25p+x54q25Zu+5pe2XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8g5pu05pawIHJhbmdlXG4gICAgICAgICAgICAgICAgICAgIHNjYWxlLnJhbmdlID0gcmFuZ2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNriBvcHRpb25zIOmFjee9ruOAgUdlb21ldHJ5IOWtl+autemFjee9ru+8jOiHquWKqOeUn+aIkCBjb21wb25lbnRzXG4gICAgICogQHBhcmFtIGlzVXBkYXRlIOaYr+WQpuaYr+abtOaWsFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuaW5pdENvbXBvbmVudHMgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgLy8g5YWI5YWo6YOo5riF56m677yM54S25ZCOIHJlbmRlclxuICAgICAgICB2YXIgY29udHJvbGxlcnMgPSB0aGlzLmNvbnRyb2xsZXJzO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbnRyb2xsZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgY29udHJvbGxlciA9IGNvbnRyb2xsZXJzW2ldO1xuICAgICAgICAgICAgLy8g5pu05paw5YiZ6LWw5pu05paw6YC76L6R77yb5ZCm5YiZ5riF56m66L296YeN57uYXG4gICAgICAgICAgICBpZiAoaXNVcGRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5jbGVhcigpO1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIucmVuZGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFZpZXcucHJvdG90eXBlLmRvTGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmxheW91dEZ1bmModGhpcyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7rlnZDmoIfns7tcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIFZpZXcucHJvdG90eXBlLmNyZWF0ZUNvb3JkaW5hdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuY29vcmRpbmF0ZUJCb3guYmw7XG4gICAgICAgIHZhciBlbmQgPSB0aGlzLmNvb3JkaW5hdGVCQm94LnRyO1xuICAgICAgICB0aGlzLmNvb3JkaW5hdGVJbnN0YW5jZSA9IHRoaXMuY29vcmRpbmF0ZUNvbnRyb2xsZXIuY3JlYXRlKHN0YXJ0LCBlbmQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5qC55o2uIG9wdGlvbnMg6YWN572u6Ieq5Yqo5riy5p+TIGdlb21ldHJ5XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5wYWludEdlb21ldHJpZXMgPSBmdW5jdGlvbiAoaXNVcGRhdGUpIHtcbiAgICAgICAgdmFyIGRvQW5pbWF0aW9uID0gdGhpcy5vcHRpb25zLmFuaW1hdGU7XG4gICAgICAgIC8vIGdlb21ldHJ5IOeahCBwYWludCDpmLbmrrVcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIGNhbnZhc1JlZ2lvbiA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMudmlld0JCb3gueCxcbiAgICAgICAgICAgIHk6IHRoaXMudmlld0JCb3gueSxcbiAgICAgICAgICAgIG1pblg6IHRoaXMudmlld0JCb3gubWluWCxcbiAgICAgICAgICAgIG1pblk6IHRoaXMudmlld0JCb3gubWluWSxcbiAgICAgICAgICAgIG1heFg6IHRoaXMudmlld0JCb3gubWF4WCxcbiAgICAgICAgICAgIG1heFk6IHRoaXMudmlld0JCb3gubWF4WSxcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLnZpZXdCQm94LndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnZpZXdCQm94LmhlaWdodCxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXM7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvbWV0cmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGdlb21ldHJ5ID0gZ2VvbWV0cmllc1tpXTtcbiAgICAgICAgICAgIGdlb21ldHJ5LmNvb3JkaW5hdGUgPSBjb29yZGluYXRlO1xuICAgICAgICAgICAgZ2VvbWV0cnkuY2FudmFzUmVnaW9uID0gY2FudmFzUmVnaW9uO1xuICAgICAgICAgICAgaWYgKCFkb0FuaW1hdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenCB2aWV3IOS4jeaJp+ihjOWKqOeUu++8jOmCo+S5iCB2aWV3IOS4i+aJgOacieeahCBnZW9tZXRyeSDpg73kuI3miafooYzliqjnlLtcbiAgICAgICAgICAgICAgICBnZW9tZXRyeS5hbmltYXRlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGdlb21ldHJ5LnBhaW50KGlzVXBkYXRlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5pyA5ZCO55qE57uY5Yi257uE5Lu2XG4gICAgICogQHBhcmFtIGlzVXBkYXRlXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUucmVuZGVyQ29tcG9uZW50cyA9IGZ1bmN0aW9uIChpc1VwZGF0ZSkge1xuICAgICAgICAvLyDlhYjlhajpg6jmuIXnqbrvvIznhLblkI4gcmVuZGVyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5nZXRDb21wb25lbnRzKCkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjbyA9IHRoaXMuZ2V0Q29tcG9uZW50cygpW2ldO1xuICAgICAgICAgICAgY28uY29tcG9uZW50LnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuLLmn5PliIbpnaLvvIzkvJrlnKjlhbbkuK3ov5vooYzmlbDmja7liIbpnaLvvIznhLblkI7ov5vooYzlrZAgdmlldyDliJvlu7pcbiAgICAgKiBAcGFyYW0gaXNVcGRhdGVcbiAgICAgKi9cbiAgICBWaWV3LnByb3RvdHlwZS5yZW5kZXJGYWNldCA9IGZ1bmN0aW9uIChpc1VwZGF0ZSkge1xuICAgICAgICBpZiAodGhpcy5mYWNldEluc3RhbmNlKSB7XG4gICAgICAgICAgICBpZiAoaXNVcGRhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZhY2V0SW5zdGFuY2UudXBkYXRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZhY2V0SW5zdGFuY2UuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAvLyDorqHnrpfliIbpnaLmlbDmja5cbiAgICAgICAgICAgICAgICB0aGlzLmZhY2V0SW5zdGFuY2UuaW5pdCgpO1xuICAgICAgICAgICAgICAgIC8vIOa4suafk+e7hOS7tuWSjCB2aWV3c1xuICAgICAgICAgICAgICAgIHRoaXMuZmFjZXRJbnN0YW5jZS5yZW5kZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgVmlldy5wcm90b3R5cGUuaW5pdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgX2IgPSBfYS5nZW9tZXRyaWVzLCBnZW9tZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IFtdIDogX2IsIF9jID0gX2EuaW50ZXJhY3Rpb25zLCBpbnRlcmFjdGlvbnMgPSBfYyA9PT0gdm9pZCAwID8gW10gOiBfYywgX2QgPSBfYS52aWV3cywgdmlld3MgPSBfZCA9PT0gdm9pZCAwID8gW10gOiBfZCwgX2UgPSBfYS5hbm5vdGF0aW9ucywgYW5ub3RhdGlvbnMgPSBfZSA9PT0gdm9pZCAwID8gW10gOiBfZTtcbiAgICAgICAgLy8g5Yib5bu6IGdlb21ldHJ5IOWunuS+i1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdlb21ldHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeU9wdGlvbiA9IGdlb21ldHJpZXNbaV07XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUdlb21ldHJ5KGdlb21ldHJ5T3B0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICAvLyDliJvlu7ogaW50ZXJhY3Rpb25zIOWunuS+i1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGludGVyYWN0aW9ucy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgdmFyIGludGVyYWN0aW9uT3B0aW9uID0gaW50ZXJhY3Rpb25zW2pdO1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBpbnRlcmFjdGlvbk9wdGlvbi50eXBlLCBjZmcgPSBpbnRlcmFjdGlvbk9wdGlvbi5jZmc7XG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uKHR5cGUsIGNmZyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Yib5bu6IHZpZXcg5a6e5L6LXG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgdmlld3MubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgIHZhciB2aWV3T3B0aW9uID0gdmlld3Nba107XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZXcodmlld09wdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6K6+572uIGFubm90YXRpb25cbiAgICAgICAgdmFyIGFubm90YXRpb25Db21wb25lbnQgPSB0aGlzLmdldENvbnRyb2xsZXIoJ2Fubm90YXRpb24nKTtcbiAgICAgICAgZm9yICh2YXIgbCA9IDA7IGwgPCBhbm5vdGF0aW9ucy5sZW5ndGg7IGwrKykge1xuICAgICAgICAgICAgdmFyIGFubm90YXRpb25PcHRpb24gPSBhbm5vdGF0aW9uc1tsXTtcbiAgICAgICAgICAgIGFubm90YXRpb25Db21wb25lbnQuYW5ub3RhdGlvbihhbm5vdGF0aW9uT3B0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVmlldy5wcm90b3R5cGUuY3JlYXRlR2VvbWV0cnkgPSBmdW5jdGlvbiAoZ2VvbWV0cnlPcHRpb24pIHtcbiAgICAgICAgdmFyIHR5cGUgPSBnZW9tZXRyeU9wdGlvbi50eXBlLCBfYSA9IGdlb21ldHJ5T3B0aW9uLmNmZywgY2ZnID0gX2EgPT09IHZvaWQgMCA/IHt9IDogX2E7XG4gICAgICAgIGlmICh0aGlzW3R5cGVdKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnlfMSA9IHRoaXNbdHlwZV0oY2ZnKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGdlb21ldHJ5T3B0aW9uLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihnZW9tZXRyeV8xW2tdKSkge1xuICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeV8xW2tdKHYpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBzY2FsZSBrZXkg55qE5Yib5bu65pa55byPXG4gICAgICogQHBhcmFtIGZpZWxkXG4gICAgICovXG4gICAgVmlldy5wcm90b3R5cGUuZ2V0U2NhbGVLZXkgPSBmdW5jdGlvbiAoZmllbGQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQgKyBcIi1cIiArIGZpZWxkO1xuICAgIH07XG4gICAgcmV0dXJuIFZpZXc7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLlZpZXcgPSBWaWV3O1xuLyoqXG4gKiDms6jlhowgZ2VvbWV0cnkg57uE5Lu2XG4gKiBAcGFyYW0gbmFtZVxuICogQHBhcmFtIEN0b3JcbiAqIEByZXR1cm5zIEdlb21ldHJ5XG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyR2VvbWV0cnkobmFtZSwgQ3Rvcikge1xuICAgIC8vIOivreazleezlu+8jOWcqCB2aWV3IEFQSSDkuIrlop7liqDljp/lnovmlrnms5VcbiAgICBWaWV3LnByb3RvdHlwZVtuYW1lLnRvTG93ZXJDYXNlKCldID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICBpZiAoY2ZnID09PSB2b2lkIDApIHsgY2ZnID0ge307IH1cbiAgICAgICAgdmFyIHByb3BzID0gdHNsaWJfMS5fX2Fzc2lnbih7IFxuICAgICAgICAgICAgLyoqIOWbvuW9ouWuueWZqCAqL1xuICAgICAgICAgICAgY29udGFpbmVyOiB0aGlzLm1pZGRsZUdyb3VwLmFkZEdyb3VwKCksIGxhYmVsc0NvbnRhaW5lcjogdGhpcy5mb3JlZ3JvdW5kR3JvdXAuYWRkR3JvdXAoKSB9LCBjZmcpO1xuICAgICAgICB2YXIgZ2VvbWV0cnkgPSBuZXcgQ3Rvcihwcm9wcyk7XG4gICAgICAgIHRoaXMuZ2VvbWV0cmllcy5wdXNoKGdlb21ldHJ5KTtcbiAgICAgICAgcmV0dXJuIGdlb21ldHJ5O1xuICAgIH07XG59XG5leHBvcnRzLnJlZ2lzdGVyR2VvbWV0cnkgPSByZWdpc3Rlckdlb21ldHJ5O1xuZXhwb3J0cy5kZWZhdWx0ID0gVmlldztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZpZXcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBhbmltYXRlXzEgPSByZXF1aXJlKFwiLi4vYW5pbWF0ZVwiKTtcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4uL2dlb21ldHJ5L2xhYmVsXCIpO1xudmFyIGdyYXBoaWNzXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9ncmFwaGljc1wiKTtcbnZhciB0cmFuc2Zvcm1fMSA9IHJlcXVpcmUoXCIuLi91dGlsL3RyYW5zZm9ybVwiKTtcbi8qKlxuICogR2VvbWV0cnkgbGFiZWxzIOa4suafk+e7hOS7tlxuICovXG52YXIgTGFiZWxzID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIExhYmVscyhjZmcpIHtcbiAgICAgICAgLyoqIOWtmOWCqOW9k+WJjSBzaGFwZSDnmoTmmKDlsITooajvvIzplK7lgLzkuLogc2hhcGUgaWQgKi9cbiAgICAgICAgdGhpcy5zaGFwZXNNYXAgPSB7fTtcbiAgICAgICAgdGhpcy5sYXN0U2hhcGVzTWFwID0ge307XG4gICAgICAgIHZhciBsYXlvdXQgPSBjZmcubGF5b3V0LCBjb250YWluZXIgPSBjZmcuY29udGFpbmVyO1xuICAgICAgICB0aGlzLmxheW91dCA9IGxheW91dDtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOa4suafk+aWh+acrFxuICAgICAqL1xuICAgIExhYmVscy5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKGl0ZW1zLCBzaGFwZXMsIGlzVXBkYXRlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmIChpc1VwZGF0ZSA9PT0gdm9pZCAwKSB7IGlzVXBkYXRlID0gZmFsc2U7IH1cbiAgICAgICAgdGhpcy5zaGFwZXNNYXAgPSB7fTtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICB2YXIgb2Zmc2NyZWVuR3JvdXAgPSB0aGlzLmNyZWF0ZU9mZnNjcmVlbkdyb3VwKCk7IC8vIOWIm+W7uuiZmuaLn+WIhue7hFxuICAgICAgICBpZiAoaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpwgaXRlbXMg56m655qE6K+d5bCx5LiN6L+b6KGM57uY5Yi26LCD5pW05pON5L2cXG4gICAgICAgICAgICAvLyBzdGVwIDE6IOWcqOiZmuaLnyBncm91cCDkuK3liJvlu7ogc2hhcGVzXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGl0ZW1zXzEgPSBpdGVtczsgX2kgPCBpdGVtc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBpdGVtID0gaXRlbXNfMVtfaV07XG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJMYWJlbChpdGVtLCBvZmZzY3JlZW5Hcm91cCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gc3RlcCAyOiDmoLnmja7luIPlsYDvvIzosIPmlbQgbGFiZWxzXG4gICAgICAgICAgICB0aGlzLmRvTGF5b3V0KGl0ZW1zLCBzaGFwZXMpO1xuICAgICAgICAgICAgLy8gc3RlcCAzOiDnu5jliLYgbGFiZWxMaW5lXG4gICAgICAgICAgICB0aGlzLnJlbmRlckxhYmVsTGluZShpdGVtcyk7XG4gICAgICAgICAgICAvLyBzdGVwIDQ6IOagueaNrueUqOaIt+iuvue9rueahOWBj+enu+mHj+iwg+aVtCBsYWJlbFxuICAgICAgICAgICAgdGhpcy5hZGp1c3RMYWJlbChpdGVtcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6L+b6KGM5re75Yqg44CB5pu05paw44CB6ZSA5q+B5pON5L2cXG4gICAgICAgIHZhciBsYXN0U2hhcGVzTWFwID0gdGhpcy5sYXN0U2hhcGVzTWFwO1xuICAgICAgICB2YXIgc2hhcGVzTWFwID0gdGhpcy5zaGFwZXNNYXA7XG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlc01hcCwgZnVuY3Rpb24gKHNoYXBlLCBpZCkge1xuICAgICAgICAgICAgaWYgKHNoYXBlLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgICAgIC8vIGxhYmVsIOWcqOW4g+WxgOiwg+aVtOeOr+iKguiiq+WIoOmZpOS6hu+8iGRvTGF5b3V077yJXG4gICAgICAgICAgICAgICAgZGVsZXRlIHNoYXBlc01hcFtpZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAobGFzdFNoYXBlc01hcFtpZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5Zu+5b2i5Y+R55Sf5pu05pawXG4gICAgICAgICAgICAgICAgICAgIHZhciBkYXRhXzEgPSBzaGFwZS5nZXQoJ2RhdGEnKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdpbl8xID0gc2hhcGUuZ2V0KCdvcmlnaW4nKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVfMSA9IHNoYXBlLmdldCgnY29vcmRpbmF0ZScpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNoYXBlID0gbGFzdFNoYXBlc01hcFtpZF07IC8vIOW3sue7j+WcqOa4suafk+agkeS4iueahCBzaGFwZVxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudEFuaW1hdGVDZmdfMSA9IHNoYXBlLmdldCgnYW5pbWF0ZUNmZycpO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50U2hhcGUuc2V0KCdkYXRhJywgZGF0YV8xKTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFNoYXBlLnNldCgnb3JpZ2luJywgb3JpZ2luXzEpO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50U2hhcGUuc2V0KCdhbmltYXRlQ2ZnJywgY3VycmVudEFuaW1hdGVDZmdfMSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTaGFwZS5zZXQoJ2Nvb3JkaW5hdGUnLCBjb29yZGluYXRlXzEpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlQW5pbWF0ZUNmZ18xID0gdXRpbF8xLmdldChjdXJyZW50QW5pbWF0ZUNmZ18xLCAndXBkYXRlJyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50Q2hpbGRyZW5fMSA9IGN1cnJlbnRTaGFwZS5nZXRDaGlsZHJlbigpO1xuICAgICAgICAgICAgICAgICAgICBzaGFwZS5nZXRDaGlsZHJlbigpLm1hcChmdW5jdGlvbiAoY2hpbGQsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudENoaWxkID0gY3VycmVudENoaWxkcmVuXzFbaW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENoaWxkLnNldCgnZGF0YScsIGRhdGFfMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2hpbGQuc2V0KCdvcmlnaW4nLCBvcmlnaW5fMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2hpbGQuc2V0KCdhbmltYXRlQ2ZnJywgY3VycmVudEFuaW1hdGVDZmdfMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2hpbGQuc2V0KCdjb29yZGluYXRlJywgY29vcmRpbmF0ZV8xKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdBdHRycyA9IGdyYXBoaWNzXzEuZ2V0UmVwbGFjZUF0dHJzKGN1cnJlbnRDaGlsZCwgY2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVwZGF0ZUFuaW1hdGVDZmdfMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGVfMS5kb0FuaW1hdGUoY3VycmVudENoaWxkLCB1cGRhdGVBbmltYXRlQ2ZnXzEsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9BdHRyczogbmV3QXR0cnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGU6IGNvb3JkaW5hdGVfMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDaGlsZC5hdHRyKG5ld0F0dHJzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNoYXBlc01hcFtpZF0gPSBjdXJyZW50U2hhcGU7IC8vIOS/neWtmOW8leeUqFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5paw55Sf5oiQ55qEIHNoYXBlXG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci5hZGQoc2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYW5pbWF0ZUNmZyA9IHV0aWxfMS5nZXQoc2hhcGUuZ2V0KCdhbmltYXRlQ2ZnJyksIGlzVXBkYXRlID8gJ2VudGVyJyA6ICdhcHBlYXInKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGVDZmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGVfMS5kb0FuaW1hdGUoc2hhcGUsIGFuaW1hdGVDZmcsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b0F0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHt9LCBzaGFwZS5hdHRyKCkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGU6IHNoYXBlLmdldCgnY29vcmRpbmF0ZScpLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIGxhc3RTaGFwZXNNYXBbaWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8g56e76ZmkXG4gICAgICAgIHV0aWxfMS5lYWNoKGxhc3RTaGFwZXNNYXAsIGZ1bmN0aW9uIChkZWxldGVTaGFwZSkge1xuICAgICAgICAgICAgdmFyIGFuaW1hdGVDZmcgPSB1dGlsXzEuZ2V0KGRlbGV0ZVNoYXBlLmdldCgnYW5pbWF0ZUNmZycpLCAnbGVhdmUnKTtcbiAgICAgICAgICAgIGlmIChhbmltYXRlQ2ZnKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0ZV8xLmRvQW5pbWF0ZShkZWxldGVTaGFwZSwgYW5pbWF0ZUNmZywge1xuICAgICAgICAgICAgICAgICAgICB0b0F0dHJzOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlOiBkZWxldGVTaGFwZS5nZXQoJ2Nvb3JkaW5hdGUnKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRlbGV0ZVNoYXBlLnJlbW92ZSh0cnVlKTsgLy8g56e76ZmkXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxhc3RTaGFwZXNNYXAgPSBzaGFwZXNNYXA7XG4gICAgICAgIG9mZnNjcmVlbkdyb3VwLmRlc3Ryb3koKTtcbiAgICB9O1xuICAgIC8qKiDmuIXmpZrlvZPliY0gbGFiZWxzICovXG4gICAgTGFiZWxzLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zaGFwZXNNYXAgPSB7fTtcbiAgICAgICAgdGhpcy5sYXN0U2hhcGVzTWFwID0ge307XG4gICAgfTtcbiAgICAvKiog6ZSA5q+BICovXG4gICAgTGFiZWxzLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuc2hhcGVzTWFwID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0U2hhcGVzTWFwID0gbnVsbDtcbiAgICB9O1xuICAgIExhYmVscy5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIGlkID0gY2ZnLmlkLCBkYXRhID0gY2ZnLmRhdGEsIG1hcHBpbmdEYXRhID0gY2ZnLm1hcHBpbmdEYXRhLCBjb29yZGluYXRlID0gY2ZnLmNvb3JkaW5hdGUsIGFuaW1hdGUgPSBjZmcuYW5pbWF0ZSwgY29udGVudCA9IGNmZy5jb250ZW50O1xuICAgICAgICB2YXIgc2hhcGVBcHBlbmRDZmcgPSB7XG4gICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgb3JpZ2luOiBtYXBwaW5nRGF0YSxcbiAgICAgICAgICAgIGNvb3JkaW5hdGU6IGNvb3JkaW5hdGUsXG4gICAgICAgIH07XG4gICAgICAgIHZhciBsYWJlbEdyb3VwID0gY29udGFpbmVyLmFkZEdyb3VwKHRzbGliXzEuX19hc3NpZ24oeyBuYW1lOiAnbGFiZWwnLCBcbiAgICAgICAgICAgIC8vIOWmguaenCB0aGlzLmFuaW1hdGUgPT09IGZhbHNlIOaIluiAhSBjZmcuYW5pbWF0ZSA9PT0gZmFsc2UvbnVsbCDliJnkuI3ov5vooYzliqjnlLvvvIzlkKbliJnov5vooYzliqjnlLvphY3nva7nmoTlkIjlubZcbiAgICAgICAgICAgIGFuaW1hdGVDZmc6IHRoaXMuYW5pbWF0ZSA9PT0gZmFsc2UgfHwgYW5pbWF0ZSA9PT0gbnVsbCB8fCBhbmltYXRlID09PSBmYWxzZSA/IGZhbHNlIDogdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMuYW5pbWF0ZSwgYW5pbWF0ZSkgfSwgc2hhcGVBcHBlbmRDZmcpKTtcbiAgICAgICAgdmFyIGxhYmVsU2hhcGU7XG4gICAgICAgIGlmICgoY29udGVudC5pc0dyb3VwICYmIGNvbnRlbnQuaXNHcm91cCgpKSB8fCAoY29udGVudC5pc1NoYXBlICYmIGNvbnRlbnQuaXNTaGFwZSgpKSkge1xuICAgICAgICAgICAgLy8g5aaC5p6cIGNvbnRlbnQg5pivIEdyb3VwIOaIluiAhSBTaGFwZe+8jOagueaNriB0ZXh0QWxpZ24g6LCD5pW05L2N572u5ZCO77yM55u05o6l5bCG5YW25Yqg5YWlIGxhYmVsR3JvdXBcbiAgICAgICAgICAgIHZhciBfYSA9IGNvbnRlbnQuZ2V0Q2FudmFzQkJveCgpLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgICAgICB2YXIgdGV4dEFsaWduID0gdXRpbF8xLmdldChjZmcsICd0ZXh0QWxpZ24nLCAnbGVmdCcpO1xuICAgICAgICAgICAgdmFyIHggPSBjZmcueDtcbiAgICAgICAgICAgIHZhciB5ID0gY2ZnLnkgLSBoZWlnaHQgLyAyO1xuICAgICAgICAgICAgaWYgKHRleHRBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgICAgICB4ID0geCAtIHdpZHRoIC8gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRleHRBbGlnbiA9PT0gJ3JpZ2h0JyB8fCB0ZXh0QWxpZ24gPT09ICdlbmQnKSB7XG4gICAgICAgICAgICAgICAgeCA9IHggLSB3aWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyYW5zZm9ybV8xLnRyYW5zbGF0ZShjb250ZW50LCB4LCB5KTsgLy8g5bCGIGxhYmVsIOW5s+enu+iHsyB4LCB5IOaMh+WumueahOS9jee9rlxuICAgICAgICAgICAgbGFiZWxTaGFwZSA9IGNvbnRlbnQ7XG4gICAgICAgICAgICBsYWJlbEdyb3VwLmFkZChjb250ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxhYmVsU2hhcGUgPSBsYWJlbEdyb3VwLmFkZFNoYXBlKCd0ZXh0JywgdHNsaWJfMS5fX2Fzc2lnbih7IGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogY2ZnLngsIHk6IGNmZy55LCB0ZXh0QWxpZ246IGNmZy50ZXh0QWxpZ24sIHRleHRCYXNlbGluZTogdXRpbF8xLmdldChjZmcsICd0ZXh0QmFzZWxpbmUnLCAnbWlkZGxlJyksIHRleHQ6IGNmZy5jb250ZW50IH0sIGNmZy5zdHlsZSkgfSwgc2hhcGVBcHBlbmRDZmcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2ZnLnJvdGF0ZSkge1xuICAgICAgICAgICAgdHJhbnNmb3JtXzEucm90YXRlKGxhYmVsU2hhcGUsIGNmZy5yb3RhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2hhcGVzTWFwW2lkXSA9IGxhYmVsR3JvdXA7XG4gICAgfTtcbiAgICAvLyDmoLnmja50eXBl5a+5bGFiZWzluIPlsYBcbiAgICBMYWJlbHMucHJvdG90eXBlLmRvTGF5b3V0ID0gZnVuY3Rpb24gKGl0ZW1zLCBzaGFwZXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICAgICAgICB2YXIgbGF5b3V0cyA9IHV0aWxfMS5pc0FycmF5KHRoaXMubGF5b3V0KSA/IHRoaXMubGF5b3V0IDogW3RoaXMubGF5b3V0XTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGxheW91dHMsIGZ1bmN0aW9uIChsYXlvdXQpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGF5b3V0Rm4gPSBsYWJlbF8xLmdldEdlb21ldHJ5TGFiZWxMYXlvdXQodXRpbF8xLmdldChsYXlvdXQsICd0eXBlJywgJycpKTtcbiAgICAgICAgICAgICAgICBpZiAobGF5b3V0Rm4pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxhYmVsU2hhcGVzXzEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdlb21ldHJ5U2hhcGVzXzEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdXRpbF8xLmVhY2goX3RoaXMuc2hhcGVzTWFwLCBmdW5jdGlvbiAobGFiZWxTaGFwZSwgaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsU2hhcGVzXzEucHVzaChsYWJlbFNoYXBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5U2hhcGVzXzEucHVzaChzaGFwZXNbaWRdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGxheW91dEZuKGl0ZW1zLCBsYWJlbFNoYXBlc18xLCBnZW9tZXRyeVNoYXBlc18xLCBfdGhpcy5yZWdpb24sIGxheW91dC5jZmcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMYWJlbHMucHJvdG90eXBlLnJlbmRlckxhYmVsTGluZSA9IGZ1bmN0aW9uIChsYWJlbEl0ZW1zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGxhYmVsSXRlbXMsIGZ1bmN0aW9uIChsYWJlbEl0ZW0pIHtcbiAgICAgICAgICAgIHZhciBjb29yZGluYXRlID0gdXRpbF8xLmdldChsYWJlbEl0ZW0sICdjb29yZGluYXRlJyk7XG4gICAgICAgICAgICBpZiAoIWxhYmVsSXRlbSB8fCAhY29vcmRpbmF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlLmdldENlbnRlcigpO1xuICAgICAgICAgICAgdmFyIHJhZGl1cyA9IGNvb3JkaW5hdGUuZ2V0UmFkaXVzKCk7XG4gICAgICAgICAgICBpZiAoIWxhYmVsSXRlbS5sYWJlbExpbmUpIHtcbiAgICAgICAgICAgICAgICAvLyBsYWJlbExpbmU6IG51bGwgfCBmYWxzZe+8jOWFs+mXrSBsYWJlbCDlr7nlupTnmoQgbGFiZWxMaW5lXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGxhYmVsTGluZUNmZyA9IHV0aWxfMS5nZXQobGFiZWxJdGVtLCAnbGFiZWxMaW5lJywge30pO1xuICAgICAgICAgICAgdmFyIGlkID0gbGFiZWxJdGVtLmlkO1xuICAgICAgICAgICAgdmFyIHBhdGggPSBsYWJlbExpbmVDZmcucGF0aDtcbiAgICAgICAgICAgIGlmICghcGF0aCkge1xuICAgICAgICAgICAgICAgIHZhciBzdGFydCA9IGdyYXBoaWNzXzEucG9sYXJUb0NhcnRlc2lhbihjZW50ZXIueCwgY2VudGVyLnksIHJhZGl1cywgbGFiZWxJdGVtLmFuZ2xlKTtcbiAgICAgICAgICAgICAgICBwYXRoID0gW1xuICAgICAgICAgICAgICAgICAgICBbJ00nLCBzdGFydC54LCBzdGFydC55XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgbGFiZWxJdGVtLngsIGxhYmVsSXRlbS55XSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGxhYmVsR3JvdXAgPSBfdGhpcy5zaGFwZXNNYXBbaWRdO1xuICAgICAgICAgICAgaWYgKCFsYWJlbEdyb3VwLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgICAgIGxhYmVsR3JvdXAuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICAgICAgICAgIGNhcHR1cmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IHBhdGgsIHN0cm9rZTogbGFiZWxJdGVtLmNvbG9yID8gbGFiZWxJdGVtLmNvbG9yIDogdXRpbF8xLmdldChsYWJlbEl0ZW0sIFsnc3R5bGUnLCAnZmlsbCddLCAnIzAwMCcpLCBmaWxsOiBudWxsIH0sIGxhYmVsTGluZUNmZy5zdHlsZSksXG4gICAgICAgICAgICAgICAgICAgIGlkOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luOiBsYWJlbEl0ZW0ubWFwcGluZ0RhdGEsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGxhYmVsSXRlbS5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlOiBsYWJlbEl0ZW0uY29vcmRpbmF0ZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBMYWJlbHMucHJvdG90eXBlLmNyZWF0ZU9mZnNjcmVlbkdyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XG4gICAgICAgIHZhciBHcm91cENsYXNzID0gY29udGFpbmVyLmdldEdyb3VwQmFzZSgpOyAvLyDojrflj5bliIbnu4TnmoTmnoTpgKDlh73mlbBcbiAgICAgICAgdmFyIG5ld0dyb3VwID0gbmV3IEdyb3VwQ2xhc3Moe30pO1xuICAgICAgICByZXR1cm4gbmV3R3JvdXA7XG4gICAgfTtcbiAgICBMYWJlbHMucHJvdG90eXBlLmFkanVzdExhYmVsID0gZnVuY3Rpb24gKGl0ZW1zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICB2YXIgaWQgPSBpdGVtLmlkO1xuICAgICAgICAgICAgICAgIHZhciBsYWJlbEdyb3VwID0gX3RoaXMuc2hhcGVzTWFwW2lkXTtcbiAgICAgICAgICAgICAgICBpZiAoIWxhYmVsR3JvdXAuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbFNoYXBlID0gbGFiZWxHcm91cC5maW5kKGZ1bmN0aW9uIChlbGUpIHsgcmV0dXJuIGVsZS5nZXQoJ3R5cGUnKSA9PT0gJ3RleHQnOyB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsU2hhcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLm9mZnNldFgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFNoYXBlLmF0dHIoJ3gnLCBsYWJlbFNoYXBlLmF0dHIoJ3gnKSArIGl0ZW0ub2Zmc2V0WCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS5vZmZzZXRZKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxTaGFwZS5hdHRyKCd5JywgbGFiZWxTaGFwZS5hdHRyKCd5JykgKyBpdGVtLm9mZnNldFkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBMYWJlbHM7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGFiZWxzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWxzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5DT01QT05FTlRfTUFYX1ZJRVdfUEVSQ0VOVEFHRSA9IGV4cG9ydHMuTUlOX0NIQVJUX0hFSUdIVCA9IGV4cG9ydHMuTUlOX0NIQVJUX1dJRFRIID0gZXhwb3J0cy5GSUVMRF9PUklHSU4gPSBleHBvcnRzLkdST1VQX0FUVFJTID0gZXhwb3J0cy5FTEVNRU5UX1NUQVRFID0gZXhwb3J0cy5QTE9UX0VWRU5UUyA9IGV4cG9ydHMuVklFV19MSUZFX0NJUkNMRSA9IGV4cG9ydHMuR1JPVVBfWl9JTkRFWCA9IGV4cG9ydHMuQ09NUE9ORU5UX1RZUEUgPSBleHBvcnRzLkRJUkVDVElPTiA9IGV4cG9ydHMuTEFZRVIgPSB2b2lkIDA7XG4vKipcbiAqIHZpZXcg5Lit5LiJ5bGCIGdyb3VwIOWIhuWxgiBrZXlcbiAqL1xudmFyIExBWUVSO1xuKGZ1bmN0aW9uIChMQVlFUikge1xuICAgIC8qKiDliY3mma/lsYIgKi9cbiAgICBMQVlFUltcIkZPUkVcIl0gPSBcImZvcmVcIjtcbiAgICAvKiog5Lit6Ze05bGCICovXG4gICAgTEFZRVJbXCJNSURcIl0gPSBcIm1pZFwiO1xuICAgIC8qKiDog4zmma/lsYIgKi9cbiAgICBMQVlFUltcIkJHXCJdID0gXCJiZ1wiO1xufSkoTEFZRVIgPSBleHBvcnRzLkxBWUVSIHx8IChleHBvcnRzLkxBWUVSID0ge30pKTtcbi8qKlxuICog57uE5Lu25Zyo55S75biD55qE5biD5bGA5pa55L2NIDEyIOaWueS9jVxuICovXG52YXIgRElSRUNUSU9OO1xuKGZ1bmN0aW9uIChESVJFQ1RJT04pIHtcbiAgICBESVJFQ1RJT05bXCJUT1BcIl0gPSBcInRvcFwiO1xuICAgIERJUkVDVElPTltcIlRPUF9MRUZUXCJdID0gXCJ0b3AtbGVmdFwiO1xuICAgIERJUkVDVElPTltcIlRPUF9SSUdIVFwiXSA9IFwidG9wLXJpZ2h0XCI7XG4gICAgRElSRUNUSU9OW1wiUklHSFRcIl0gPSBcInJpZ2h0XCI7XG4gICAgRElSRUNUSU9OW1wiUklHSFRfVE9QXCJdID0gXCJyaWdodC10b3BcIjtcbiAgICBESVJFQ1RJT05bXCJSSUdIVF9CT1RUT01cIl0gPSBcInJpZ2h0LWJvdHRvbVwiO1xuICAgIERJUkVDVElPTltcIkxFRlRcIl0gPSBcImxlZnRcIjtcbiAgICBESVJFQ1RJT05bXCJMRUZUX1RPUFwiXSA9IFwibGVmdC10b3BcIjtcbiAgICBESVJFQ1RJT05bXCJMRUZUX0JPVFRPTVwiXSA9IFwibGVmdC1ib3R0b21cIjtcbiAgICBESVJFQ1RJT05bXCJCT1RUT01cIl0gPSBcImJvdHRvbVwiO1xuICAgIERJUkVDVElPTltcIkJPVFRPTV9MRUZUXCJdID0gXCJib3R0b20tbGVmdFwiO1xuICAgIERJUkVDVElPTltcIkJPVFRPTV9SSUdIVFwiXSA9IFwiYm90dG9tLXJpZ2h0XCI7XG4gICAgRElSRUNUSU9OW1wiUkFESVVTXCJdID0gXCJyYWRpdXNcIjtcbiAgICBESVJFQ1RJT05bXCJDSVJDTEVcIl0gPSBcImNpcmNsZVwiO1xuICAgIC8vIG5vIGRpcmVjdGlvbiBpbmZvcm1hdGlvblxuICAgIERJUkVDVElPTltcIk5PTkVcIl0gPSBcIm5vbmVcIjtcbn0pKERJUkVDVElPTiA9IGV4cG9ydHMuRElSRUNUSU9OIHx8IChleHBvcnRzLkRJUkVDVElPTiA9IHt9KSk7XG4vKipcbiAqIOe7hOS7tueahOexu+Wei++8jOWPr+iDveS8muW9seWTjeWIsOW4g+WxgOeul+azlVxuICovXG52YXIgQ09NUE9ORU5UX1RZUEU7XG4oZnVuY3Rpb24gKENPTVBPTkVOVF9UWVBFKSB7XG4gICAgLyoqIGF4aXMg57uE5Lu2ICovXG4gICAgQ09NUE9ORU5UX1RZUEVbXCJBWElTXCJdID0gXCJheGlzXCI7XG4gICAgLyoqIGdyaWQg57uE5Lu2ICovXG4gICAgQ09NUE9ORU5UX1RZUEVbXCJHUklEXCJdID0gXCJncmlkXCI7XG4gICAgLyoqIGxlZ2VuZCDnu4Tku7YgKi9cbiAgICBDT01QT05FTlRfVFlQRVtcIkxFR0VORFwiXSA9IFwibGVnZW5kXCI7XG4gICAgLyoqIHRvb2x0aXAg57uE5Lu2ICovXG4gICAgQ09NUE9ORU5UX1RZUEVbXCJUT09MVElQXCJdID0gXCJ0b29sdGlwXCI7XG4gICAgLyoqIGFubm90YXRpb24g57uE5Lu2ICovXG4gICAgQ09NUE9ORU5UX1RZUEVbXCJBTk5PVEFUSU9OXCJdID0gXCJhbm5vdGF0aW9uXCI7XG4gICAgLyoqIOWFtuS7lue7hOS7tu+8jOiHquWumuS5iee7hOS7tiAqL1xuICAgIENPTVBPTkVOVF9UWVBFW1wiT1RIRVJcIl0gPSBcIm90aGVyXCI7XG59KShDT01QT05FTlRfVFlQRSA9IGV4cG9ydHMuQ09NUE9ORU5UX1RZUEUgfHwgKGV4cG9ydHMuQ09NUE9ORU5UX1RZUEUgPSB7fSkpO1xuLyoqXG4gKiDkuInlsYIgZ3JvdXAg55qEIHogaW5kZXhcbiAqL1xuZXhwb3J0cy5HUk9VUF9aX0lOREVYID0ge1xuICAgIEZPUkU6IDMsXG4gICAgTUlEOiAyLFxuICAgIEJHOiAxLFxufTtcbi8qKlxuICogVmlldyDnmoTnlJ/lkb3lkajmnJ/pmLbmrrXvvIjlkowgMy54IOeahOeUn+WRveWRqOacn+eVpeacieS4jeWQjO+8iVxuICog5oiR5Lus6ZyA6KaB5YWI56Gu5a6a5Zyo6YKj5YaZ5Zy65pmv6ZyA6KaB55So5Yiw55Sf5ZG95ZGo5pyf77yM5aaC5p6c5Y+q5piv5Li65LqG5Zyo55Sf5ZG95ZGo5pyf5o+S5YWl5LiA5LiL5LuA5LmI57uE5Lu25LmL57G755qE77yM6YKj5LmI5Zyo546w5pyJ5p625p6E5bCx5piv5LiN6ZyA6KaB55qEXG4gKi9cbnZhciBWSUVXX0xJRkVfQ0lSQ0xFO1xuKGZ1bmN0aW9uIChWSUVXX0xJRkVfQ0lSQ0xFKSB7XG4gICAgVklFV19MSUZFX0NJUkNMRVtcIkJFRk9SRV9SRU5ERVJcIl0gPSBcImJlZm9yZXJlbmRlclwiO1xuICAgIFZJRVdfTElGRV9DSVJDTEVbXCJBRlRFUl9SRU5ERVJcIl0gPSBcImFmdGVycmVuZGVyXCI7XG4gICAgVklFV19MSUZFX0NJUkNMRVtcIkJFRk9SRV9QQUlOVFwiXSA9IFwiYmVmb3JlcGFpbnRcIjtcbiAgICBWSUVXX0xJRkVfQ0lSQ0xFW1wiQUZURVJfUEFJTlRcIl0gPSBcImFmdGVycGFpbnRcIjtcbiAgICBWSUVXX0xJRkVfQ0lSQ0xFW1wiQkVGT1JFX0NIQU5HRV9EQVRBXCJdID0gXCJiZWZvcmVjaGFuZ2VkYXRhXCI7XG4gICAgVklFV19MSUZFX0NJUkNMRVtcIkFGVEVSX0NIQU5HRV9EQVRBXCJdID0gXCJhZnRlcmNoYW5nZWRhdGFcIjtcbiAgICBWSUVXX0xJRkVfQ0lSQ0xFW1wiQkVGT1JFX0NMRUFSXCJdID0gXCJiZWZvcmVjbGVhclwiO1xuICAgIFZJRVdfTElGRV9DSVJDTEVbXCJBRlRFUl9DTEVBUlwiXSA9IFwiYWZ0ZXJjbGVhclwiO1xuICAgIFZJRVdfTElGRV9DSVJDTEVbXCJCRUZPUkVfREVTVFJPWVwiXSA9IFwiYmVmb3JlZGVzdHJveVwiO1xufSkoVklFV19MSUZFX0NJUkNMRSA9IGV4cG9ydHMuVklFV19MSUZFX0NJUkNMRSB8fCAoZXhwb3J0cy5WSUVXX0xJRkVfQ0lSQ0xFID0ge30pKTtcbi8qKlxuICog57uY5Zu+5Yy655qE5LqL5Lu25YiX6KGoXG4gKi9cbnZhciBQTE9UX0VWRU5UUztcbihmdW5jdGlvbiAoUExPVF9FVkVOVFMpIHtcbiAgICAvLyBtb3VzZSDkuovku7ZcbiAgICBQTE9UX0VWRU5UU1tcIk1PVVNFX0VOVEVSXCJdID0gXCJwbG90Om1vdXNlZW50ZXJcIjtcbiAgICBQTE9UX0VWRU5UU1tcIk1PVVNFX0RPV05cIl0gPSBcInBsb3Q6bW91c2Vkb3duXCI7XG4gICAgUExPVF9FVkVOVFNbXCJNT1VTRV9NT1ZFXCJdID0gXCJwbG90Om1vdXNlbW92ZVwiO1xuICAgIFBMT1RfRVZFTlRTW1wiTU9VU0VfVVBcIl0gPSBcInBsb3Q6bW91c2V1cFwiO1xuICAgIFBMT1RfRVZFTlRTW1wiTU9VU0VfTEVBVkVcIl0gPSBcInBsb3Q6bW91c2VsZWF2ZVwiO1xuICAgIC8vIOenu+WKqOerr+S6i+S7tlxuICAgIFBMT1RfRVZFTlRTW1wiVE9VQ0hfU1RBUlRcIl0gPSBcInBsb3Q6dG91Y2hzdGFydFwiO1xuICAgIFBMT1RfRVZFTlRTW1wiVE9VQ0hfTU9WRVwiXSA9IFwicGxvdDp0b3VjaG1vdmVcIjtcbiAgICBQTE9UX0VWRU5UU1tcIlRPVUNIX0VORFwiXSA9IFwicGxvdDp0b3VjaGVuZFwiO1xuICAgIFBMT1RfRVZFTlRTW1wiVE9VQ0hfQ0FOQ0VMXCJdID0gXCJwbG90OnRvdWNoY2FuY2VsXCI7XG4gICAgLy8gY2xpY2sg5LqL5Lu2XG4gICAgUExPVF9FVkVOVFNbXCJDTElDS1wiXSA9IFwicGxvdDpjbGlja1wiO1xuICAgIFBMT1RfRVZFTlRTW1wiREJMQ0xJQ0tcIl0gPSBcInBsb3Q6ZGJsY2xpY2tcIjtcbiAgICBQTE9UX0VWRU5UU1tcIkNPTlRFWFRNRU5VXCJdID0gXCJwbG90OmNvbnRleHRtZW51XCI7XG4gICAgUExPVF9FVkVOVFNbXCJMRUFWRVwiXSA9IFwicGxvdDpsZWF2ZVwiO1xuICAgIFBMT1RfRVZFTlRTW1wiRU5URVJcIl0gPSBcInBsb3Q6ZW50ZXJcIjtcbn0pKFBMT1RfRVZFTlRTID0gZXhwb3J0cy5QTE9UX0VWRU5UUyB8fCAoZXhwb3J0cy5QTE9UX0VWRU5UUyA9IHt9KSk7XG4vKipcbiAqIEVsZW1lbnQg5Zu+5b2i5Lqk5LqS54q25oCBXG4gKi9cbnZhciBFTEVNRU5UX1NUQVRFO1xuKGZ1bmN0aW9uIChFTEVNRU5UX1NUQVRFKSB7XG4gICAgRUxFTUVOVF9TVEFURVtcIkFDVElWRVwiXSA9IFwiYWN0aXZlXCI7XG4gICAgRUxFTUVOVF9TVEFURVtcIklOQUNUSVZFXCJdID0gXCJpbmFjdGl2ZVwiO1xuICAgIEVMRU1FTlRfU1RBVEVbXCJTRUxFQ1RFRFwiXSA9IFwic2VsZWN0ZWRcIjtcbiAgICBFTEVNRU5UX1NUQVRFW1wiREVGQVVMVFwiXSA9IFwiZGVmYXVsdFwiO1xufSkoRUxFTUVOVF9TVEFURSA9IGV4cG9ydHMuRUxFTUVOVF9TVEFURSB8fCAoZXhwb3J0cy5FTEVNRU5UX1NUQVRFID0ge30pKTtcbi8qKiDlj4LkuI7liIbnu4TnmoTlm77lvaLlsZ7mgKflkI0gKi9cbmV4cG9ydHMuR1JPVVBfQVRUUlMgPSBbJ2NvbG9yJywgJ3NoYXBlJywgJ3NpemUnXTtcbi8qKiDlrZjlgqjljp/lp4vmlbDmja7nmoTlrZfmrrXlkI0gKi9cbmV4cG9ydHMuRklFTERfT1JJR0lOID0gJ19vcmlnaW4nO1xuLyoqIOacgOWwj+eahOWbvuihqOWuveW6piAqL1xuZXhwb3J0cy5NSU5fQ0hBUlRfV0lEVEggPSAxO1xuLyoqIOacgOWwj+eahOWbvuihqOmrmOW6piAqL1xuZXhwb3J0cy5NSU5fQ0hBUlRfSEVJR0hUID0gMTtcbi8qKiDovoXliqnnu4Tku7bljaDlm77ooajnmoTlsLrlr7jnmoTmnIDlpKfmr5TkvovvvJrlpoLlm77ooajkuIrmlrnnmoTlm77kvovmnIDlpJrljaDlm77ooajpq5jluqbnmoQyNSUgKi9cbmV4cG9ydHMuQ09NUE9ORU5UX01BWF9WSUVXX1BFUkNFTlRBR0UgPSAwLjI1O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKiBHMiDnmoTkuIDkuKrlo7PlrZDvvIzkuI3ljIXlkKsgR2VvbWV0cnnvvIznlLHlvIDlj5HogIXoh6rlt7HlrprkuYnlkozlvJXlhaUgKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuVHlwZXMgPSBleHBvcnRzLlZFUlNJT04gPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbmV4cG9ydHMuVkVSU0lPTiA9ICc0LjAuMTUnO1xuLy8g5qC45b+D5Z+657G75a+85Ye6XG52YXIgY2hhcnRfMSA9IHJlcXVpcmUoXCIuL2NoYXJ0XCIpOyAvLyBDaGFydCwgVmlldyDnsbtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNoYXJ0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjaGFydF8xLkNoYXJ0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVmlld1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY2hhcnRfMS5WaWV3OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNoYXJ0XzEuRXZlbnQ7IH0gfSk7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vY2hhcnQvY29udHJvbGxlci9iYXNlXCIpOyAvLyBHMiDnu4Tku7bln7rnsbtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbXBvbmVudENvbnRyb2xsZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfMS5Db250cm9sbGVyOyB9IH0pO1xudmFyIGJhc2VfMiA9IHJlcXVpcmUoXCIuL2dlb21ldHJ5L2Jhc2VcIik7IC8vIEdlb21ldHJ5IOWfuuexu1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiR2VvbWV0cnlcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfMi5kZWZhdWx0OyB9IH0pO1xudmFyIGJhc2VfMyA9IHJlcXVpcmUoXCIuL2dlb21ldHJ5L2xhYmVsL2Jhc2VcIik7IC8vIEdlb21ldHJ5IExhYmVsIOWfuuexu1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiR2VvbWV0cnlMYWJlbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYmFzZV8zLmRlZmF1bHQ7IH0gfSk7XG52YXIgaW50ZXJhY3Rpb25fMSA9IHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uXCIpOyAvLyBJbnRlcmFjdGlvbiDln7rnsbtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkludGVyYWN0aW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbnRlcmFjdGlvbl8xLkludGVyYWN0aW9uOyB9IH0pO1xudmFyIGZhY2V0XzEgPSByZXF1aXJlKFwiLi9mYWNldFwiKTsgLy8gRmFjZXQg5Z+657G7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJGYWNldFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFjZXRfMS5GYWNldDsgfSB9KTtcbnZhciBiYXNlXzQgPSByZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vYmFzZVwiKTsgLy8gSW50ZXJhY3Rpb24gQWN0aW9uIOWfuuexu1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiSW50ZXJhY3Rpb25BY3Rpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfNC5kZWZhdWx0OyB9IH0pO1xuLy8g5rOo5YaMIENvbXBvbmVudENvbnRyb2xsZXJcbnZhciBjaGFydF8yID0gcmVxdWlyZShcIi4vY2hhcnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNoYXJ0XzIucmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyOyB9IH0pO1xuLy8g5rOo5YaMIEdlb21ldHJ5XG52YXIgY2hhcnRfMyA9IHJlcXVpcmUoXCIuL2NoYXJ0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJHZW9tZXRyeVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY2hhcnRfMy5yZWdpc3Rlckdlb21ldHJ5OyB9IH0pO1xuLy8g5rOo5YaMIEdlb21ldHJ5IFNoYXBlXG52YXIgYmFzZV81ID0gcmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvYmFzZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyU2hhcGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfNS5yZWdpc3RlclNoYXBlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJTaGFwZUZhY3RvcnlcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfNS5yZWdpc3RlclNoYXBlRmFjdG9yeTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFNoYXBlRmFjdG9yeVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYmFzZV81LmdldFNoYXBlRmFjdG9yeTsgfSB9KTtcbi8vIOazqOWGjCBHZW9tZXRyeSBsYWJlbCDku6Xlj4ogR2VvbWV0cnkgTGFiZWwg5biD5bGA5Ye95pWwXG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2dlb21ldHJ5L2xhYmVsXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJHZW9tZXRyeUxhYmVsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsYWJlbF8xLnJlZ2lzdGVyR2VvbWV0cnlMYWJlbDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyR2VvbWV0cnlMYWJlbExheW91dFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGFiZWxfMS5yZWdpc3Rlckdlb21ldHJ5TGFiZWxMYXlvdXQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRHZW9tZXRyeUxhYmVsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsYWJlbF8xLmdldEdlb21ldHJ5TGFiZWw7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRHZW9tZXRyeUxhYmVsTGF5b3V0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsYWJlbF8xLmdldEdlb21ldHJ5TGFiZWxMYXlvdXQ7IH0gfSk7XG4vLyDms6jlhowgaW50ZXJhY3Rpb25cbnZhciBpbnRlcmFjdGlvbl8yID0gcmVxdWlyZShcIi4vaW50ZXJhY3Rpb25cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRJbnRlcmFjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaW50ZXJhY3Rpb25fMi5nZXRJbnRlcmFjdGlvbjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVySW50ZXJhY3Rpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGludGVyYWN0aW9uXzIucmVnaXN0ZXJJbnRlcmFjdGlvbjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyQWN0aW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbnRlcmFjdGlvbl8yLnJlZ2lzdGVyQWN0aW9uOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0QWN0aW9uQ2xhc3NcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGludGVyYWN0aW9uXzIuZ2V0QWN0aW9uQ2xhc3M7IH0gfSk7XG4vLyDms6jlhowgZmFjZXRcbnZhciBmYWNldF8yID0gcmVxdWlyZShcIi4vZmFjZXRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRGYWNldFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFjZXRfMi5nZXRGYWNldDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyRmFjZXRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY2V0XzIucmVnaXN0ZXJGYWNldDsgfSB9KTtcbi8vIOazqOWGjOS4u+mimFxudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi90aGVtZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFRoZW1lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGVtZV8xLmdldFRoZW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJUaGVtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhlbWVfMS5yZWdpc3RlclRoZW1lOyB9IH0pO1xuLy8gRyBlbmdpbmUg566h55CG55u45YWzXG52YXIgZW5naW5lXzEgPSByZXF1aXJlKFwiLi9lbmdpbmVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckVuZ2luZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZW5naW5lXzEucmVnaXN0ZXJFbmdpbmU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRFbmdpbmVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGVuZ2luZV8xLmdldEVuZ2luZTsgfSB9KTtcbi8vIOazqOWGjOWKqOeUu+WHveaVsFxudmFyIGFuaW1hdGlvbl8xID0gcmVxdWlyZShcIi4vYW5pbWF0ZS9hbmltYXRpb25cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckFuaW1hdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYW5pbWF0aW9uXzEucmVnaXN0ZXJBbmltYXRpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRBbmltYXRpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFuaW1hdGlvbl8xLmdldEFuaW1hdGlvbjsgfSB9KTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4vY29uc3RhbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJMQVlFUlwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRfMS5MQVlFUjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkRJUkVDVElPTlwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRfMS5ESVJFQ1RJT047IH0gfSk7XG4vLyDlm6DkuLogdHlwZXNjcmlwdCDpg6jliIbniYjmnKzkuI3mlK/mjIEgZXhwb3J0ICogYXMg6K+t5rOV44CCXG52YXIgVHlwZXMgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi9pbnRlcmZhY2VcIikpO1xuZXhwb3J0cy5UeXBlcyA9IFR5cGVzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29yZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qIOS+nei1lueahOaooeWdl++8jOWcqOi/memHjOe7n+S4gOW8leWFpe+8jOaWueS+v+aJk+WMheS8mOWMliAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TbGlkZXIgPSBleHBvcnRzLkh0bWxUb29sdGlwID0gZXhwb3J0cy5Db250aW51b3VzTGVnZW5kID0gZXhwb3J0cy5DYXRlZ29yeUxlZ2VuZCA9IGV4cG9ydHMuQ2lyY2xlR3JpZCA9IGV4cG9ydHMuTGluZUdyaWQgPSBleHBvcnRzLkNpcmNsZUF4aXMgPSBleHBvcnRzLkxpbmVBeGlzID0gZXhwb3J0cy5Bbm5vdGF0aW9uID0gZXhwb3J0cy5Dcm9zc2hhaXIgPSBleHBvcnRzLkNvbXBvbmVudCA9IGV4cG9ydHMuR3JvdXBDb21wb25lbnQgPSBleHBvcnRzLkh0bWxDb21wb25lbnQgPSB2b2lkIDA7XG52YXIgZ19iYXNlXzEgPSByZXF1aXJlKFwiQGFudHYvZy1iYXNlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfYmFzZV8xLkV2ZW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQWJzdHJhY3RHcm91cFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZ19iYXNlXzEuQWJzdHJhY3RHcm91cDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkFic3RyYWN0U2hhcGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfYmFzZV8xLkFic3RyYWN0U2hhcGU7IH0gfSk7XG4vLyBhZGp1c3RcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiQGFudHYvYWRqdXN0L2xpYi9mYWN0b3J5XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJBZGp1c3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY3RvcnlfMS5yZWdpc3RlckFkanVzdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldEFkanVzdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFjdG9yeV8xLmdldEFkanVzdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkFkanVzdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFjdG9yeV8xLkFkanVzdDsgfSB9KTtcbi8vIGF0dHJcbnZhciBmYWN0b3J5XzIgPSByZXF1aXJlKFwiQGFudHYvYXR0ci9saWIvZmFjdG9yeVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldEF0dHJpYnV0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFjdG9yeV8yLmdldEF0dHJpYnV0ZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkF0dHJpYnV0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFjdG9yeV8yLkF0dHJpYnV0ZTsgfSB9KTtcbnZhciBhdHRyXzEgPSByZXF1aXJlKFwiQGFudHYvYXR0clwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbG9yXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBhdHRyXzEuQ29sb3I7IH0gfSk7XG4vLyBjb29yZGluYXRlXG52YXIgY29vcmRfMSA9IHJlcXVpcmUoXCJAYW50di9jb29yZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldENvb3JkaW5hdGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvb3JkXzEuZ2V0Q29vcmRpbmF0ZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyQ29vcmRpbmF0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29vcmRfMS5yZWdpc3RlckNvb3JkaW5hdGU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDb29yZGluYXRlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb29yZF8xLkNvb3JkaW5hdGU7IH0gfSk7XG4vLyBzY2FsZVxudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiQGFudHYvc2NhbGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRTY2FsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2NhbGVfMS5nZXRTY2FsZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyU2NhbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNjYWxlXzEucmVnaXN0ZXJTY2FsZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNjYWxlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzY2FsZV8xLlNjYWxlOyB9IH0pO1xuLy8gY29tcG9uZW50XG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiQGFudHYvY29tcG9uZW50XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQW5ub3RhdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29tcG9uZW50XzEuQW5ub3RhdGlvbjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbXBvbmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29tcG9uZW50XzEuQ29tcG9uZW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ3Jvc3NoYWlyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb21wb25lbnRfMS5Dcm9zc2hhaXI7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcm91cENvbXBvbmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29tcG9uZW50XzEuR3JvdXBDb21wb25lbnQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJIdG1sQ29tcG9uZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb21wb25lbnRfMS5IdG1sQ29tcG9uZW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU2xpZGVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb21wb25lbnRfMS5TbGlkZXI7IH0gfSk7XG4vLyBheGlzXG52YXIgTGluZUF4aXMgPSBjb21wb25lbnRfMS5BeGlzLkxpbmUsIENpcmNsZUF4aXMgPSBjb21wb25lbnRfMS5BeGlzLkNpcmNsZTtcbmV4cG9ydHMuTGluZUF4aXMgPSBMaW5lQXhpcztcbmV4cG9ydHMuQ2lyY2xlQXhpcyA9IENpcmNsZUF4aXM7XG4vLyBncmlkXG52YXIgTGluZUdyaWQgPSBjb21wb25lbnRfMS5HcmlkLkxpbmUsIENpcmNsZUdyaWQgPSBjb21wb25lbnRfMS5HcmlkLkNpcmNsZTtcbmV4cG9ydHMuTGluZUdyaWQgPSBMaW5lR3JpZDtcbmV4cG9ydHMuQ2lyY2xlR3JpZCA9IENpcmNsZUdyaWQ7XG4vLyBsZWdlbmRcbnZhciBDYXRlZ29yeUxlZ2VuZCA9IGNvbXBvbmVudF8xLkxlZ2VuZC5DYXRlZ29yeSwgQ29udGludW91c0xlZ2VuZCA9IGNvbXBvbmVudF8xLkxlZ2VuZC5Db250aW51b3VzO1xuZXhwb3J0cy5DYXRlZ29yeUxlZ2VuZCA9IENhdGVnb3J5TGVnZW5kO1xuZXhwb3J0cy5Db250aW51b3VzTGVnZW5kID0gQ29udGludW91c0xlZ2VuZDtcbi8vIFRvb2x0aXBcbnZhciBIdG1sVG9vbHRpcCA9IGNvbXBvbmVudF8xLlRvb2x0aXAuSHRtbDtcbmV4cG9ydHMuSHRtbFRvb2x0aXAgPSBIdG1sVG9vbHRpcDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlcGVuZGVudHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyRW5naW5lID0gZXhwb3J0cy5nZXRFbmdpbmUgPSB2b2lkIDA7XG52YXIgRU5HSU5FUyA9IHt9O1xuLyoqXG4gKiDpgJrov4flkI3lrZfojrflj5bmuLLmn5MgZW5naW5lXG4gKiBAcGFyYW0gbmFtZSDmuLLmn5PlvJXmk47lkI3lrZdcbiAqIEByZXR1cm5zIEcgZW5naW5lXG4gKi9cbmZ1bmN0aW9uIGdldEVuZ2luZShuYW1lKSB7XG4gICAgdmFyIEcgPSBFTkdJTkVTW25hbWVdO1xuICAgIGlmICghRykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJHIGVuZ2luZSAnXCIgKyBuYW1lICsgXCInIGlzIG5vdCBleGlzdCwgcGxlYXNlIHJlZ2lzdGVyIGl0IGF0IGZpcnN0LlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIEc7XG59XG5leHBvcnRzLmdldEVuZ2luZSA9IGdldEVuZ2luZTtcbi8qKlxuICog5rOo5YaM5riy5p+T5byV5pOOXG4gKiBAcGFyYW0gbmFtZVxuICogQHBhcmFtIGVuZ2luZVxuICovXG5mdW5jdGlvbiByZWdpc3RlckVuZ2luZShuYW1lLCBlbmdpbmUpIHtcbiAgICBFTkdJTkVTW25hbWVdID0gZW5naW5lO1xufVxuZXhwb3J0cy5yZWdpc3RlckVuZ2luZSA9IHJlZ2lzdGVyRW5naW5lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGZhY2V0XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9mYWNldFwiKTtcbnZhciBmYWNldF8yID0gcmVxdWlyZShcIi4vZmFjZXRcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOmVnOWDj+WIhumdolxuICovXG52YXIgQ2lyY2xlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENpcmNsZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDaXJjbGUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQ2lyY2xlLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB0eXBlOiAnY2lyY2xlJyxcbiAgICAgICAgICAgIHNob3dUaXRsZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpdGxlOiBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRUaXRsZUNmZy5jYWxsKHRoaXMpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENpcmNsZS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5jZmcuc2hvd1RpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclRpdGxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNruaAu+aVsOWSjOW9k+WJjee0ouW8le+8jOiuoeeul+WIhumdoueahCByZWdpb25cbiAgICAgKiBAcGFyYW0gY291bnRcbiAgICAgKiBAcGFyYW0gaW5kZXhcbiAgICAgKi9cbiAgICBDaXJjbGUucHJvdG90eXBlLmdldFJlZ2lvbiA9IGZ1bmN0aW9uIChjb3VudCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIHIgPSAxIC8gMjsgLy8g55S75biD5Y2K5b6EXG4gICAgICAgIC8vIOeUu+W4g+WchuW/g1xuICAgICAgICB2YXIgY2VudGVyID0geyB4OiAwLjUsIHk6IDAuNSB9O1xuICAgICAgICAvLyDmr4/pmpTliIbpnaLpl7TpmpTnmoTlvKfluqZcbiAgICAgICAgdmFyIGF2Z0FuZ2xlID0gKE1hdGguUEkgKiAyKSAvIGNvdW50O1xuICAgICAgICAvLyDlvZPliY3liIbpnaLmiYDlnKjnmoTlvKfluqZcbiAgICAgICAgdmFyIGFuZ2xlID0gKC0xICogTWF0aC5QSSkgLyAyICsgYXZnQW5nbGUgKiBpbmRleDtcbiAgICAgICAgLy8gVE9ETyDmsqHnnIvmh4JcbiAgICAgICAgdmFyIGZhY2V0UiA9IHIgLyAoMSArIDEgLyBNYXRoLnNpbihhdmdBbmdsZSAvIDIpKTtcbiAgICAgICAgLy8g5YiG6Z2i55qE5Lit5b+D54K5XG4gICAgICAgIHZhciBtaWRkbGUgPSBmYWNldF8xLmdldEFuZ2xlUG9pbnQoY2VudGVyLCByIC0gZmFjZXRSLCBhbmdsZSk7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gKE1hdGguUEkgKiA1KSAvIDQ7IC8vIOWPs+S4iuinklxuICAgICAgICB2YXIgZW5kQW5nbGUgPSAoTWF0aC5QSSAqIDEpIC8gNDsgLy8g5bem5LiL6KeSXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGFydDogZmFjZXRfMS5nZXRBbmdsZVBvaW50KG1pZGRsZSwgZmFjZXRSLCBzdGFydEFuZ2xlKSxcbiAgICAgICAgICAgIGVuZDogZmFjZXRfMS5nZXRBbmdsZVBvaW50KG1pZGRsZSwgZmFjZXRSLCBlbmRBbmdsZSksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBDaXJjbGUucHJvdG90eXBlLmFmdGVyRWFjaFZpZXcgPSBmdW5jdGlvbiAodmlldywgZmFjZXQpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzQXhpcyh2aWV3LCBmYWNldCk7XG4gICAgfTtcbiAgICBDaXJjbGUucHJvdG90eXBlLmJlZm9yZUVhY2hWaWV3ID0gZnVuY3Rpb24gKHZpZXcsIGZhY2V0KSB7IH07XG4gICAgQ2lyY2xlLnByb3RvdHlwZS5nZW5lcmF0ZUZhY2V0cyA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCBmaWVsZHMgPSBfYS5maWVsZHMsIHR5cGUgPSBfYS50eXBlO1xuICAgICAgICB2YXIgZmllbGQgPSBmaWVsZHNbMF07XG4gICAgICAgIGlmICghZmllbGQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYGZpZWxkc2Agc3BlY2lmaWVkIScpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2YWx1ZXMgPSB0aGlzLmdldEZpZWxkVmFsdWVzKGRhdGEsIGZpZWxkKTtcbiAgICAgICAgdmFyIGNvdW50ID0gdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgY29uZGl0aW9ucyA9IFt7IGZpZWxkOiBmaWVsZCwgdmFsdWU6IHZhbHVlLCB2YWx1ZXM6IHZhbHVlcyB9XTtcbiAgICAgICAgICAgIHZhciBmYWNldERhdGEgPSB1dGlsXzEuZmlsdGVyKGRhdGEsIF90aGlzLmdldEZhY2V0RGF0YUZpbHRlcihjb25kaXRpb25zKSk7XG4gICAgICAgICAgICB2YXIgZmFjZXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICAgICAgICBkYXRhOiBmYWNldERhdGEsXG4gICAgICAgICAgICAgICAgcmVnaW9uOiBfdGhpcy5nZXRSZWdpb24oY291bnQsIGluZGV4KSxcbiAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgY29sdW1uRmllbGQ6IGZpZWxkLFxuICAgICAgICAgICAgICAgIGNvbHVtbkluZGV4OiBpbmRleCxcbiAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGg6IGNvdW50LFxuICAgICAgICAgICAgICAgIHJvd1ZhbHVlOiBudWxsLFxuICAgICAgICAgICAgICAgIHJvd0ZpZWxkOiBudWxsLFxuICAgICAgICAgICAgICAgIHJvd0luZGV4OiAwLFxuICAgICAgICAgICAgICAgIHJvd1ZhbHVlc0xlbmd0aDogMSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByc3QucHVzaChmYWNldCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgQ2lyY2xlLnByb3RvdHlwZS5nZXRYQXhpc09wdGlvbiA9IGZ1bmN0aW9uICh4LCBheGVzLCBvcHRpb24sIGZhY2V0KSB7XG4gICAgICAgIC8vIOS4jeWBmuS7u+S9leWkhOeQhlxuICAgICAgICByZXR1cm4gb3B0aW9uO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572uIHkg5Z2Q5qCH6L2055qE5paH5pys44CBdGl0bGUg5piv5ZCm5pi+56S6XG4gICAgICogQHBhcmFtIHlcbiAgICAgKiBAcGFyYW0gYXhlc1xuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcGFyYW0gZmFjZXRcbiAgICAgKi9cbiAgICBDaXJjbGUucHJvdG90eXBlLmdldFlBeGlzT3B0aW9uID0gZnVuY3Rpb24gKHksIGF4ZXMsIG9wdGlvbiwgZmFjZXQpIHtcbiAgICAgICAgLy8g5LiN5YGa5Lu75L2V5aSE55CGXG4gICAgICAgIHJldHVybiBvcHRpb247XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBmYWNldCB0aXRsZVxuICAgICAqL1xuICAgIENpcmNsZS5wcm90b3R5cGUucmVuZGVyVGl0bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZmFjZXRzLCBmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgICAgICAgIHZhciBjb2x1bW5WYWx1ZSA9IGZhY2V0LmNvbHVtblZhbHVlLCB2aWV3ID0gZmFjZXQudmlldztcbiAgICAgICAgICAgIHZhciBmb3JtYXR0ZXIgPSB1dGlsXzEuZ2V0KF90aGlzLmNmZy50aXRsZSwgJ2Zvcm1hdHRlcicpO1xuICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogWyc1MCUnLCAnMCUnXSxcbiAgICAgICAgICAgICAgICBjb250ZW50OiBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIoY29sdW1uVmFsdWUpIDogY29sdW1uVmFsdWUsXG4gICAgICAgICAgICB9LCBmYWNldF8xLmdldEZhY3RUaXRsZUNvbmZpZyhjb25zdGFudF8xLkRJUkVDVElPTi5UT1ApLCBfdGhpcy5jZmcudGl0bGUpO1xuICAgICAgICAgICAgdmlldy5hbm5vdGF0aW9uKCkudGV4dChjb25maWcpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBDaXJjbGU7XG59KGZhY2V0XzIuRmFjZXQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IENpcmNsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNpcmNsZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuRmFjZXQgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBheGlzXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9heGlzXCIpO1xuLyoqXG4gKiBmYWNldCDln7rnsbtcbiAqICAtIOWumuS5ieeUn+WRveWRqOacn++8jOaWueS+v+iHquWumuS5iSBmYWNldFxuICogIC0g5o+Q5L6b5Z+656GA55qE55Sf5ZG95rWB56iL5pa55rOVXG4gKlxuICog55Sf5ZG95ZGo5pyf77yaXG4gKlxuICog5Yid5aeL5YyWIGluaXRcbiAqIDEuIOWIneWni+WMluWuueWZqFxuICogMi4g5pWw5o2u5YiG6Z2i77yM55Sf5oiQ5YiG6Z2i5biD5bGA5L+h5oGvXG4gKlxuICog5riy5p+T6Zi25q61IHJlbmRlclxuICogMS4gdmlldyDliJvlu7pcbiAqIDIuIHRpdGxlXG4gKiAzLiBheGlzXG4gKlxuICog5riF6Zmk6Zi25q61IGNsZWFyXG4gKiAxLiDmuIXpmaQgdmlld1xuICpcbiAqIOmUgOavgemYtuautSBkZXN0cm95XG4gKiAxLiBjbGVhclxuICogMi4g5riF6Zmk5LqL5Lu2XG4gKiAzLiDmuIXpmaQgZ3JvdXBcbiAqL1xudmFyIEZhY2V0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZhY2V0KHZpZXcsIGNmZykge1xuICAgICAgICAvKiog5piv5ZCm6ZSA5q+BICovXG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIC8qKiDliIbpnaLkuYvlkI7nmoTmiYDmnInliIbpnaLmlbDmja7nu5PmnoQgKi9cbiAgICAgICAgdGhpcy5mYWNldHMgPSBbXTtcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdGhpcy5jZmcgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5nZXREZWZhdWx0Q2ZnKCksIGNmZyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOWIneWni+WMlui/h+eoi1xuICAgICAqL1xuICAgIEZhY2V0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDliJ3lp4vljJblrrnlmahcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLmNyZWF0ZUNvbnRhaW5lcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOeUn+aIkOWIhumdouW4g+WxgOS/oeaBr1xuICAgICAgICB2YXIgZGF0YSA9IHRoaXMudmlldy5nZXREYXRhKCk7XG4gICAgICAgIHRoaXMuZmFjZXRzID0gdGhpcy5nZW5lcmF0ZUZhY2V0cyhkYXRhKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOa4suafk+WIhumdou+8jOeUseS4iuWxgiB2aWV3IOiwg+eUqOOAguWMheaLrO+8mlxuICAgICAqICAtIOWIhumdoiB2aWV3XG4gICAgICogIC0g6L20XG4gICAgICogIC0gdGl0bGVcbiAgICAgKlxuICAgICAqICDlrZDnsbvlj6/ku6XlpI3lhpnvvIzmt7vliqDkuIDkupvlhbbku5bnu4Tku7bvvIzmr5TlpoLmu5rliqjmnaHnrYlcbiAgICAgKi9cbiAgICBGYWNldC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlbmRlclZpZXdzKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmm7TmlrAgZmFjZXRcbiAgICAgKi9cbiAgICBGYWNldC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDlhbblrp7kuI3nlKjlgZrku7vkvZXkuovmg4XvvIzlm6DkuLogZmFjZXQg5pyA57uI55Sf5oiQ55qEIFZpZXcg5ZKMIEdlb21ldHJ5IOmDveWcqOeItiB2aWV3IOeahOabtOaWsOS4reWkhOeQhuS6hlxuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF56m677yMY2xlYXIg5LmL5ZCO5aaC5p6c6L+Y6ZyA6KaB5L2/55So77yM6ZyA6KaB6YeN5paw6LCD55SoIGluaXQg5Yid5aeL5YyW6L+H56iLXG4gICAgICog5LiA6Iis5Zyo5pWw5o2u5pyJ5Y+Y5pu055qE5pe25YCZ6LCD55So77yM6YeN5paw6L+b6KGM5pWw5o2u55qE5YiG6Z2i6YC76L6RXG4gICAgICovXG4gICAgRmFjZXQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNsZWFyRmFjZXRWaWV3cygpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZSA5q+BXG4gICAgICovXG4gICAgRmFjZXQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgICAgIHRoaXMudmlldyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5mYWNldHMgPSBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNriBmYWNldCDnlJ/miJAgdmlld++8jOWPr+S7pee7meS4iuWxguiHquWumuS5ieS9v+eUqFxuICAgICAqIEBwYXJhbSBmYWNldFxuICAgICAqL1xuICAgIEZhY2V0LnByb3RvdHlwZS5mYWNldFRvVmlldyA9IGZ1bmN0aW9uIChmYWNldCkge1xuICAgICAgICB2YXIgcmVnaW9uID0gZmFjZXQucmVnaW9uLCBkYXRhID0gZmFjZXQuZGF0YSwgX2EgPSBmYWNldC5wYWRkaW5nLCBwYWRkaW5nID0gX2EgPT09IHZvaWQgMCA/IHRoaXMuY2ZnLnBhZGRpbmcgOiBfYTtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXcuY3JlYXRlVmlldyh7XG4gICAgICAgICAgICByZWdpb246IHJlZ2lvbixcbiAgICAgICAgICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyDorr7nva7liIbpnaLnmoTmlbDmja5cbiAgICAgICAgdmlldy5kYXRhKGRhdGEgfHwgW10pO1xuICAgICAgICBmYWNldC52aWV3ID0gdmlldztcbiAgICAgICAgLy8g5YmN572u6ZKp5a2QXG4gICAgICAgIHRoaXMuYmVmb3JlRWFjaFZpZXcodmlldywgZmFjZXQpO1xuICAgICAgICB2YXIgZWFjaFZpZXcgPSB0aGlzLmNmZy5lYWNoVmlldztcbiAgICAgICAgaWYgKGVhY2hWaWV3KSB7XG4gICAgICAgICAgICBlYWNoVmlldyh2aWV3LCBmYWNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5ZCO572u6ZKp5a2QXG4gICAgICAgIHRoaXMuYWZ0ZXJFYWNoVmlldyh2aWV3LCBmYWNldCk7XG4gICAgICAgIHJldHVybiB2aWV3O1xuICAgIH07XG4gICAgLy8g5Yib5bu65a655ZmoXG4gICAgRmFjZXQucHJvdG90eXBlLmNyZWF0ZUNvbnRhaW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZvcmVncm91bmRHcm91cCA9IHRoaXMudmlldy5nZXRMYXllcihjb25zdGFudF8xLkxBWUVSLkZPUkUpO1xuICAgICAgICByZXR1cm4gZm9yZWdyb3VuZEdyb3VwLmFkZEdyb3VwKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJ3lp4vljJYgdmlld1xuICAgICAqL1xuICAgIEZhY2V0LnByb3RvdHlwZS5yZW5kZXJWaWV3cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVGYWNldFZpZXdzKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7og5YiG6Z2iIHZpZXdcbiAgICAgKi9cbiAgICBGYWNldC5wcm90b3R5cGUuY3JlYXRlRmFjZXRWaWV3cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgLy8g5L2/55So5YiG6Z2i5pWw5o2uIOWIm+W7uuWIhumdoiB2aWV3XG4gICAgICAgIHJldHVybiB0aGlzLmZhY2V0cy5tYXAoZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZmFjZXRUb1ZpZXcoZmFjZXQpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOS7jiB2aWV3IOS4rea4hemZpCBmYWNldFZpZXdcbiAgICAgKi9cbiAgICBGYWNldC5wcm90b3R5cGUuY2xlYXJGYWNldFZpZXdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAvLyDku44gdmlldyDkuK3np7vpmaTliIbpnaIgdmlld1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmZhY2V0cywgZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAgICAgICBpZiAoZmFjZXQudmlldykge1xuICAgICAgICAgICAgICAgIF90aGlzLnZpZXcucmVtb3ZlVmlldyhmYWNldC52aWV3KTtcbiAgICAgICAgICAgICAgICBmYWNldC52aWV3ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOWFtuS7luS4gOS6m+aPkOS+m+e7meWtkOexu+S9v+eUqOeahOaWueazlVxuICAgIC8qKlxuICAgICAqIOiOt+WPlui/meS4quWtl+auteWvueW6lOeahOaJgOacieWAvO+8jOaVsOe7hFxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAcGFyYW0gZGF0YSDmlbDmja5cbiAgICAgKiBAcGFyYW0gZmllbGQg5a2X5q615ZCNXG4gICAgICogQHJldHVybiDlrZfmrrXlr7nlupTnmoTlgLxcbiAgICAgKi9cbiAgICBGYWNldC5wcm90b3R5cGUuZ2V0RmllbGRWYWx1ZXMgPSBmdW5jdGlvbiAoZGF0YSwgZmllbGQpIHtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICB2YXIgY2FjaGUgPSB7fTtcbiAgICAgICAgLy8g5Y676YeN44CB5Y676ZmkIE5pbCDlgLxcbiAgICAgICAgdXRpbF8xLmVhY2goZGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGRbZmllbGRdO1xuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwodmFsdWUpICYmICFjYWNoZVt2YWx1ZV0pIHtcbiAgICAgICAgICAgICAgICByc3QucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgY2FjaGVbdmFsdWVdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflvpfmr4/kuKrliIbpnaLnmoQgcmVnaW9u77yM5bmz5YiG5Yy65Z+fXG4gICAgICogQHBhcmFtIHJvd3Mgcm93IOaAu+aVsFxuICAgICAqIEBwYXJhbSBjb2xzIGNvbCDmgLvmlbBcbiAgICAgKiBAcGFyYW0geEluZGV4IHgg5pa55ZCRIGluZGV4XG4gICAgICogQHBhcmFtIHlJbmRleCB5IOaWueWQkSBpbmRleFxuICAgICAqL1xuICAgIEZhY2V0LnByb3RvdHlwZS5nZXRSZWdpb24gPSBmdW5jdGlvbiAocm93cywgY29scywgeEluZGV4LCB5SW5kZXgpIHtcbiAgICAgICAgLy8geCwgeSDmlrnlkJHlnYfliIYgMTAwJSDlrr3pq5hcbiAgICAgICAgdmFyIHhSYXRpbyA9IDEgLyAoY29scyA9PT0gMCA/IDEgOiBjb2xzKTtcbiAgICAgICAgdmFyIHlSYXRpbyA9IDEgLyAocm93cyA9PT0gMCA/IDEgOiByb3dzKTtcbiAgICAgICAgdmFyIHN0YXJ0ID0ge1xuICAgICAgICAgICAgeDogeFJhdGlvICogeEluZGV4LFxuICAgICAgICAgICAgeTogeVJhdGlvICogeUluZGV4LFxuICAgICAgICB9O1xuICAgICAgICB2YXIgZW5kID0ge1xuICAgICAgICAgICAgeDogeFJhdGlvICogKHhJbmRleCArIDEpLFxuICAgICAgICAgICAgeTogeVJhdGlvICogKHlJbmRleCArIDEpLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBlbmQsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBGYWNldC5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVhY2hWaWV3OiB1bmRlZmluZWQsXG4gICAgICAgICAgICBzaG93VGl0bGU6IHRydWUsXG4gICAgICAgICAgICBwYWRkaW5nOiAxMCxcbiAgICAgICAgICAgIGZpZWxkczogW10sXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpu5jorqTnmoQgdGl0bGUg5qC35byP77yM5Zug5Li65pyJ55qE5YiG6Z2i5pivIHRpdGxl77yM5pyJ55qE5YiG6Z2i6YWN572u5pivIGNvbHVtblRpdGxl44CBcm93VGl0bGVcbiAgICAgKi9cbiAgICBGYWNldC5wcm90b3R5cGUuZ2V0RGVmYXVsdFRpdGxlQ2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHZhciBmb250RmFtaWx5ID0gdGhpcy52aWV3LmdldFRoZW1lKCkuZm9udEZhbWlseTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZm9udFNpemU6IDE0LFxuICAgICAgICAgICAgICAgIGZpbGw6ICcjNjY2JyxcbiAgICAgICAgICAgICAgICBmb250RmFtaWx5OiBmb250RmFtaWx5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWkhOeQhiBheGlzIOeahOm7mOiupOmFjee9rlxuICAgICAqIEBwYXJhbSB2aWV3XG4gICAgICogQHBhcmFtIGZhY2V0XG4gICAgICovXG4gICAgRmFjZXQucHJvdG90eXBlLnByb2Nlc3NBeGlzID0gZnVuY3Rpb24gKHZpZXcsIGZhY2V0KSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdmlldy5nZXRPcHRpb25zKCk7XG4gICAgICAgIHZhciBjb29yZGluYXRlT3B0aW9uID0gb3B0aW9ucy5jb29yZGluYXRlO1xuICAgICAgICB2YXIgZ2VvbWV0cmllcyA9IHZpZXcuZ2VvbWV0cmllcztcbiAgICAgICAgdmFyIGNvb3JkaW5hdGVUeXBlID0gdXRpbF8xLmdldChjb29yZGluYXRlT3B0aW9uLCAndHlwZScsICdyZWN0Jyk7XG4gICAgICAgIGlmIChjb29yZGluYXRlVHlwZSA9PT0gJ3JlY3QnICYmIGdlb21ldHJpZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzTmlsKG9wdGlvbnMuYXhlcykpIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5heGVzID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYXhlcyA9IG9wdGlvbnMuYXhlcztcbiAgICAgICAgICAgIHZhciBfYSA9IGdlb21ldHJpZXNbMF0uZ2V0WFlGaWVsZHMoKSwgeCA9IF9hWzBdLCB5ID0gX2FbMV07XG4gICAgICAgICAgICB2YXIgeE9wdGlvbiA9IGF4aXNfMS5nZXRBeGlzT3B0aW9uKGF4ZXMsIHgpO1xuICAgICAgICAgICAgdmFyIHlPcHRpb24gPSBheGlzXzEuZ2V0QXhpc09wdGlvbihheGVzLCB5KTtcbiAgICAgICAgICAgIGlmICh4T3B0aW9uICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuYXhlc1t4XSA9IHRoaXMuZ2V0WEF4aXNPcHRpb24oeCwgYXhlcywgeE9wdGlvbiwgZmFjZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHlPcHRpb24gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5heGVzW3ldID0gdGhpcy5nZXRZQXhpc09wdGlvbih5LCBheGVzLCB5T3B0aW9uLCBmYWNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluWIhumdouaVsOaNrlxuICAgICAqIEBwYXJhbSBjb25kaXRpb25zXG4gICAgICovXG4gICAgRmFjZXQucHJvdG90eXBlLmdldEZhY2V0RGF0YUZpbHRlciA9IGZ1bmN0aW9uIChjb25kaXRpb25zKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZGF0dW0pIHtcbiAgICAgICAgICAgIC8vIOi/h+a7pOWHuuWFqOmDqOa7oei2s+adoeS7tueahOaVsOaNrlxuICAgICAgICAgICAgcmV0dXJuIHV0aWxfMS5ldmVyeShjb25kaXRpb25zLCBmdW5jdGlvbiAoY29uZGl0aW9uKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gY29uZGl0aW9uLmZpZWxkLCB2YWx1ZSA9IGNvbmRpdGlvbi52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWxfMS5pc05pbCh2YWx1ZSkgJiYgZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdHVtW2ZpZWxkXSA9PT0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gRmFjZXQ7XG59KCkpO1xuZXhwb3J0cy5GYWNldCA9IEZhY2V0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmFjZXQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyRmFjZXQgPSBleHBvcnRzLmdldEZhY2V0ID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGZhY2V0XzEgPSByZXF1aXJlKFwiLi9mYWNldFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkZhY2V0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBmYWNldF8xLkZhY2V0OyB9IH0pO1xuLyoqXG4gKiDmiYDmnInnmoQgRmFjZXQg57G7XG4gKi9cbnZhciBGYWNldHMgPSB7fTtcbi8qKlxuICog5qC55o2uIHR5cGUg6I635Y+WIGZhY2V0IOexu1xuICogQHBhcmFtIHR5cGUg5YiG6Z2i57G75Z6LXG4gKi9cbmV4cG9ydHMuZ2V0RmFjZXQgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgIHJldHVybiBGYWNldHNbdXRpbF8xLmxvd2VyQ2FzZSh0eXBlKV07XG59O1xuLyoqXG4gKiDms6jlhozkuIDkuKogRmFjZXQg57G7XG4gKiBAcGFyYW0gdHlwZSDliIbpnaLnsbvlnotcbiAqIEBwYXJhbSBjdG9yIOWIhumdouexu1xuICovXG5leHBvcnRzLnJlZ2lzdGVyRmFjZXQgPSBmdW5jdGlvbiAodHlwZSwgY3Rvcikge1xuICAgIEZhY2V0c1t1dGlsXzEubG93ZXJDYXNlKHR5cGUpXSA9IGN0b3I7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGZhY2V0XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9mYWNldFwiKTtcbnZhciBmYWNldF8yID0gcmVxdWlyZShcIi4vZmFjZXRcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOmVnOWDj+WIhumdolxuICovXG52YXIgTGlzdCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaXN0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIExpc3QoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTGlzdC5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRDZmcuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgdHlwZTogJ2xpc3QnLFxuICAgICAgICAgICAgY29sczogbnVsbCxcbiAgICAgICAgICAgIHNob3dUaXRsZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpdGxlOiBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRUaXRsZUNmZy5jYWxsKHRoaXMpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExpc3QucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5yZW5kZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMuY2ZnLnNob3dUaXRsZSkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJUaXRsZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMaXN0LnByb3RvdHlwZS5hZnRlckVhY2hWaWV3ID0gZnVuY3Rpb24gKHZpZXcsIGZhY2V0KSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc0F4aXModmlldywgZmFjZXQpO1xuICAgIH07XG4gICAgTGlzdC5wcm90b3R5cGUuYmVmb3JlRWFjaFZpZXcgPSBmdW5jdGlvbiAodmlldywgZmFjZXQpIHsgfTtcbiAgICBMaXN0LnByb3RvdHlwZS5nZW5lcmF0ZUZhY2V0cyA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBmaWVsZHMgPSB0aGlzLmNmZy5maWVsZHM7XG4gICAgICAgIHZhciBjb2xzID0gdGhpcy5jZmcuY29scztcbiAgICAgICAgdmFyIGNvbHVtbkZpZWxkID0gZmllbGRzWzBdO1xuICAgICAgICBpZiAoIWNvbHVtbkZpZWxkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGBmaWVsZHNgIHNwZWNpZmllZCEnKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29sVmFsdWVzID0gdGhpcy5nZXRGaWVsZFZhbHVlcyhkYXRhLCBjb2x1bW5GaWVsZCk7XG4gICAgICAgIHZhciBjb3VudCA9IGNvbFZhbHVlcy5sZW5ndGg7XG4gICAgICAgIGNvbHMgPSBjb2xzIHx8IGNvdW50OyAvLyDmr4/ooYzmnInlh6DliJfmlbDmja5cbiAgICAgICAgLy8g5oC75YWx5pyJ5Yeg6KGMXG4gICAgICAgIHZhciByb3dzID0gdGhpcy5nZXRQYWdlQ291bnQoY291bnQsIGNvbHMpO1xuICAgICAgICB2YXIgcnN0ID0gW107XG4gICAgICAgIGNvbFZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGluZGV4KSB7XG4gICAgICAgICAgICAvLyDlvZPliY0gaW5kZXgg5Zyo6YKj5Liq6KGM5YiXXG4gICAgICAgICAgICB2YXIgX2EgPSBfdGhpcy5nZXRSb3dDb2woaW5kZXgsIGNvbHMpLCByb3cgPSBfYS5yb3csIGNvbCA9IF9hLmNvbDtcbiAgICAgICAgICAgIHZhciBjb25kaXRpb25zID0gW3sgZmllbGQ6IGNvbHVtbkZpZWxkLCB2YWx1ZTogdmFsLCB2YWx1ZXM6IGNvbFZhbHVlcyB9XTtcbiAgICAgICAgICAgIHZhciBmYWNldERhdGEgPSB1dGlsXzEuZmlsdGVyKGRhdGEsIF90aGlzLmdldEZhY2V0RGF0YUZpbHRlcihjb25kaXRpb25zKSk7XG4gICAgICAgICAgICB2YXIgZmFjZXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogX3RoaXMuY2ZnLnR5cGUsXG4gICAgICAgICAgICAgICAgZGF0YTogZmFjZXREYXRhLFxuICAgICAgICAgICAgICAgIHJlZ2lvbjogX3RoaXMuZ2V0UmVnaW9uKHJvd3MsIGNvbHMsIGNvbCwgcm93KSxcbiAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZTogdmFsLFxuICAgICAgICAgICAgICAgIHJvd1ZhbHVlOiB2YWwsXG4gICAgICAgICAgICAgICAgY29sdW1uRmllbGQ6IGNvbHVtbkZpZWxkLFxuICAgICAgICAgICAgICAgIHJvd0ZpZWxkOiBudWxsLFxuICAgICAgICAgICAgICAgIGNvbHVtbkluZGV4OiBjb2wsXG4gICAgICAgICAgICAgICAgcm93SW5kZXg6IHJvdyxcbiAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGg6IGNvbHMsXG4gICAgICAgICAgICAgICAgcm93VmFsdWVzTGVuZ3RoOiByb3dzLFxuICAgICAgICAgICAgICAgIHRvdGFsOiBjb3VudCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByc3QucHVzaChmYWNldCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572uIHgg5Z2Q5qCH6L2055qE5paH5pys44CBdGl0bGUg5piv5ZCm5pi+56S6XG4gICAgICogQHBhcmFtIHhcbiAgICAgKiBAcGFyYW0gYXhlc1xuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcGFyYW0gZmFjZXRcbiAgICAgKi9cbiAgICBMaXN0LnByb3RvdHlwZS5nZXRYQXhpc09wdGlvbiA9IGZ1bmN0aW9uICh4LCBheGVzLCBvcHRpb24sIGZhY2V0KSB7XG4gICAgICAgIC8vIOW9k+aYr+acgOWQjuS4gOihjOaIluiAheS4i+mdouayoeaciSB2aWV3IOaXtuaWh+acrOS4jeaYvuekulxuICAgICAgICBpZiAoZmFjZXQucm93SW5kZXggIT09IGZhY2V0LnJvd1ZhbHVlc0xlbmd0aCAtIDEgJiZcbiAgICAgICAgICAgIGZhY2V0LmNvbHVtblZhbHVlc0xlbmd0aCAqIGZhY2V0LnJvd0luZGV4ICsgZmFjZXQuY29sdW1uSW5kZXggKyAxICsgZmFjZXQuY29sdW1uVmFsdWVzTGVuZ3RoIDw9IGZhY2V0LnRvdGFsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBvcHRpb24pLCB7IGxhYmVsOiBudWxsLCB0aXRsZTogbnVsbCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3B0aW9uO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572uIHkg5Z2Q5qCH6L2055qE5paH5pys44CBdGl0bGUg5piv5ZCm5pi+56S6XG4gICAgICogQHBhcmFtIHlcbiAgICAgKiBAcGFyYW0gYXhlc1xuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcGFyYW0gZmFjZXRcbiAgICAgKi9cbiAgICBMaXN0LnByb3RvdHlwZS5nZXRZQXhpc09wdGlvbiA9IGZ1bmN0aW9uICh5LCBheGVzLCBvcHRpb24sIGZhY2V0KSB7XG4gICAgICAgIGlmIChmYWNldC5jb2x1bW5JbmRleCAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3B0aW9uKSwgeyB0aXRsZTogbnVsbCwgbGFiZWw6IG51bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGZhY2V0IHRpdGxlXG4gICAgICovXG4gICAgTGlzdC5wcm90b3R5cGUucmVuZGVyVGl0bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZmFjZXRzLCBmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgICAgICAgIHZhciBjb2x1bW5WYWx1ZSA9IGZhY2V0LmNvbHVtblZhbHVlLCB2aWV3ID0gZmFjZXQudmlldztcbiAgICAgICAgICAgIHZhciBmb3JtYXR0ZXIgPSB1dGlsXzEuZ2V0KF90aGlzLmNmZy50aXRsZSwgJ2Zvcm1hdHRlcicpO1xuICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogWyc1MCUnLCAnMCUnXSxcbiAgICAgICAgICAgICAgICBjb250ZW50OiBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIoY29sdW1uVmFsdWUpIDogY29sdW1uVmFsdWUsXG4gICAgICAgICAgICB9LCBmYWNldF8xLmdldEZhY3RUaXRsZUNvbmZpZyhjb25zdGFudF8xLkRJUkVDVElPTi5UT1ApLCBfdGhpcy5jZmcudGl0bGUpO1xuICAgICAgICAgICAgdmlldy5hbm5vdGF0aW9uKCkudGV4dChjb25maWcpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiuoeeul+WIhumhteaVsFxuICAgICAqIEBwYXJhbSB0b3RhbFxuICAgICAqIEBwYXJhbSBwYWdlU2l6ZVxuICAgICAqL1xuICAgIExpc3QucHJvdG90eXBlLmdldFBhZ2VDb3VudCA9IGZ1bmN0aW9uICh0b3RhbCwgcGFnZVNpemUpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKHRvdGFsICsgcGFnZVNpemUgLSAxKSAvIHBhZ2VTaXplKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe0ouW8leWAvOWcqOWTquS4gOmhtVxuICAgICAqIEBwYXJhbSBpbmRleFxuICAgICAqIEBwYXJhbSBwYWdlU2l6ZVxuICAgICAqL1xuICAgIExpc3QucHJvdG90eXBlLmdldFJvd0NvbCA9IGZ1bmN0aW9uIChpbmRleCwgcGFnZVNpemUpIHtcbiAgICAgICAgdmFyIHJvdyA9IE1hdGguZmxvb3IoaW5kZXggLyBwYWdlU2l6ZSk7XG4gICAgICAgIHZhciBjb2wgPSBpbmRleCAlIHBhZ2VTaXplO1xuICAgICAgICByZXR1cm4geyByb3c6IHJvdywgY29sOiBjb2wgfTtcbiAgICB9O1xuICAgIHJldHVybiBMaXN0O1xufShmYWNldF8yLkZhY2V0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMaXN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGlzdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgZmFjZXRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2ZhY2V0XCIpO1xudmFyIGZhY2V0XzIgPSByZXF1aXJlKFwiLi9mYWNldFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog6ZWc5YOP5YiG6Z2iXG4gKi9cbnZhciBNYXRyaXggPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTWF0cml4LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIE1hdHJpeCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBNYXRyaXgucHJvdG90eXBlLmdldERlZmF1bHRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHR5cGU6ICdtYXRyaXgnLFxuICAgICAgICAgICAgc2hvd1RpdGxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbHVtblRpdGxlOiB0c2xpYl8xLl9fYXNzaWduKHt9LCBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRUaXRsZUNmZy5jYWxsKHRoaXMpKSxcbiAgICAgICAgICAgIHJvd1RpdGxlOiB0c2xpYl8xLl9fYXNzaWduKHt9LCBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRUaXRsZUNmZy5jYWxsKHRoaXMpKSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBNYXRyaXgucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5yZW5kZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMuY2ZnLnNob3dUaXRsZSkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJUaXRsZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNYXRyaXgucHJvdG90eXBlLmFmdGVyRWFjaFZpZXcgPSBmdW5jdGlvbiAodmlldywgZmFjZXQpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzQXhpcyh2aWV3LCBmYWNldCk7XG4gICAgfTtcbiAgICBNYXRyaXgucHJvdG90eXBlLmJlZm9yZUVhY2hWaWV3ID0gZnVuY3Rpb24gKHZpZXcsIGZhY2V0KSB7IH07XG4gICAgTWF0cml4LnByb3RvdHlwZS5nZW5lcmF0ZUZhY2V0cyA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY2ZnLCBmaWVsZHMgPSBfYS5maWVsZHMsIHR5cGUgPSBfYS50eXBlO1xuICAgICAgICAvLyDnn6npmLXkuK3ooYzliJfnm7jnrYnvvIznrYnkuo7mjIflrprnmoTlrZfmrrXkuKrmlbBcbiAgICAgICAgdmFyIHJvd1ZhbHVlc0xlbmd0aCA9IGZpZWxkcy5sZW5ndGg7XG4gICAgICAgIHZhciBjb2x1bW5WYWx1ZXNMZW5ndGggPSByb3dWYWx1ZXNMZW5ndGg7XG4gICAgICAgIHZhciByc3QgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb2x1bW5WYWx1ZXNMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGNvbHVtbkZpZWxkID0gZmllbGRzW2ldO1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCByb3dWYWx1ZXNMZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIHZhciByb3dGaWVsZCA9IGZpZWxkc1tqXTtcbiAgICAgICAgICAgICAgICB2YXIgZmFjZXQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbjogdGhpcy5nZXRSZWdpb24ocm93VmFsdWVzTGVuZ3RoLCBjb2x1bW5WYWx1ZXNMZW5ndGgsIGksIGopLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZTogY29sdW1uRmllbGQsXG4gICAgICAgICAgICAgICAgICAgIHJvd1ZhbHVlOiByb3dGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uRmllbGQ6IGNvbHVtbkZpZWxkLFxuICAgICAgICAgICAgICAgICAgICByb3dGaWVsZDogcm93RmllbGQsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkluZGV4OiBpLFxuICAgICAgICAgICAgICAgICAgICByb3dJbmRleDogaixcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uVmFsdWVzTGVuZ3RoOiBjb2x1bW5WYWx1ZXNMZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIHJvd1ZhbHVlc0xlbmd0aDogcm93VmFsdWVzTGVuZ3RoLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcnN0LnB1c2goZmFjZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva4geCDlnZDmoIfovbTnmoTmlofmnKzjgIF0aXRsZSDmmK/lkKbmmL7npLpcbiAgICAgKiBAcGFyYW0geFxuICAgICAqIEBwYXJhbSBheGVzXG4gICAgICogQHBhcmFtIG9wdGlvblxuICAgICAqIEBwYXJhbSBmYWNldFxuICAgICAqL1xuICAgIE1hdHJpeC5wcm90b3R5cGUuZ2V0WEF4aXNPcHRpb24gPSBmdW5jdGlvbiAoeCwgYXhlcywgb3B0aW9uLCBmYWNldCkge1xuICAgICAgICAvLyDmnIDlkI7kuIDooYzmmL7npLpcbiAgICAgICAgaWYgKGZhY2V0LnJvd0luZGV4ICE9PSBmYWNldC5yb3dWYWx1ZXNMZW5ndGggLSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBvcHRpb24pLCB7IGxhYmVsOiBudWxsLCB0aXRsZTogbnVsbCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3B0aW9uO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572uIHkg5Z2Q5qCH6L2055qE5paH5pys44CBdGl0bGUg5piv5ZCm5pi+56S6XG4gICAgICogQHBhcmFtIHlcbiAgICAgKiBAcGFyYW0gYXhlc1xuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcGFyYW0gZmFjZXRcbiAgICAgKi9cbiAgICBNYXRyaXgucHJvdG90eXBlLmdldFlBeGlzT3B0aW9uID0gZnVuY3Rpb24gKHksIGF4ZXMsIG9wdGlvbiwgZmFjZXQpIHtcbiAgICAgICAgLy8g56ys5LiA5YiX5pi+56S6XG4gICAgICAgIGlmIChmYWNldC5jb2x1bW5JbmRleCAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3B0aW9uKSwgeyB0aXRsZTogbnVsbCwgbGFiZWw6IG51bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGZhY2V0IHRpdGxlXG4gICAgICovXG4gICAgTWF0cml4LnByb3RvdHlwZS5yZW5kZXJUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5mYWNldHMsIGZ1bmN0aW9uIChmYWNldCwgZmFjZXRJbmRleCkge1xuICAgICAgICAgICAgdmFyIGNvbHVtbkluZGV4ID0gZmFjZXQuY29sdW1uSW5kZXgsIHJvd0luZGV4ID0gZmFjZXQucm93SW5kZXgsIGNvbHVtblZhbHVlc0xlbmd0aCA9IGZhY2V0LmNvbHVtblZhbHVlc0xlbmd0aCwgcm93VmFsdWVzTGVuZ3RoID0gZmFjZXQucm93VmFsdWVzTGVuZ3RoLCBjb2x1bW5WYWx1ZSA9IGZhY2V0LmNvbHVtblZhbHVlLCByb3dWYWx1ZSA9IGZhY2V0LnJvd1ZhbHVlLCB2aWV3ID0gZmFjZXQudmlldztcbiAgICAgICAgICAgIC8vIHRvcFxuICAgICAgICAgICAgaWYgKHJvd0luZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IHV0aWxfMS5nZXQoX3RoaXMuY2ZnLmNvbHVtblRpdGxlLCAnZm9ybWF0dGVyJyk7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFsnNTAlJywgJzAlJ10sXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGZvcm1hdHRlciA/IGZvcm1hdHRlcihjb2x1bW5WYWx1ZSkgOiBjb2x1bW5WYWx1ZSxcbiAgICAgICAgICAgICAgICB9LCBmYWNldF8xLmdldEZhY3RUaXRsZUNvbmZpZyhjb25zdGFudF8xLkRJUkVDVElPTi5UT1ApLCBfdGhpcy5jZmcuY29sdW1uVGl0bGUpO1xuICAgICAgICAgICAgICAgIHZpZXcuYW5ub3RhdGlvbigpLnRleHQoY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJpZ2h0XG4gICAgICAgICAgICBpZiAoY29sdW1uSW5kZXggPT09IGNvbHVtblZhbHVlc0xlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgZm9ybWF0dGVyID0gdXRpbF8xLmdldChfdGhpcy5jZmcucm93VGl0bGUsICdmb3JtYXR0ZXInKTtcbiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0gdXRpbF8xLmRlZXBNaXgoe1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogWycxMDAlJywgJzUwJSddLFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIocm93VmFsdWUpIDogcm93VmFsdWUsXG4gICAgICAgICAgICAgICAgfSwgZmFjZXRfMS5nZXRGYWN0VGl0bGVDb25maWcoY29uc3RhbnRfMS5ESVJFQ1RJT04uUklHSFQpLCBfdGhpcy5jZmcucm93VGl0bGUpO1xuICAgICAgICAgICAgICAgIHZpZXcuYW5ub3RhdGlvbigpLnRleHQoY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gTWF0cml4O1xufShmYWNldF8yLkZhY2V0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBNYXRyaXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXRyaXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGZhY2V0XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9mYWNldFwiKTtcbnZhciBmYWNldF8yID0gcmVxdWlyZShcIi4vZmFjZXRcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOmVnOWDj+WIhumdolxuICovXG52YXIgTWlycm9yID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKE1pcnJvciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBNaXJyb3IoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTWlycm9yLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB0eXBlOiAnbWlycm9yJyxcbiAgICAgICAgICAgIHNob3dUaXRsZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpdGxlOiBfc3VwZXIucHJvdG90eXBlLmdldERlZmF1bHRUaXRsZUNmZy5jYWxsKHRoaXMpLFxuICAgICAgICAgICAgdHJhbnNwb3NlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBNaXJyb3IucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5yZW5kZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMuY2ZnLnNob3dUaXRsZSkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJUaXRsZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNaXJyb3IucHJvdG90eXBlLmJlZm9yZUVhY2hWaWV3ID0gZnVuY3Rpb24gKHZpZXcsIGZhY2V0KSB7XG4gICAgICAgIC8vIOWBmuS4gOS4i+WdkOagh+ezu+i9rOWMllxuICAgICAgICBpZiAodGhpcy5jZmcudHJhbnNwb3NlKSB7XG4gICAgICAgICAgICBpZiAoZmFjZXQuY29sdW1uSW5kZXggJSAyID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdmlldy5jb29yZGluYXRlKCkudHJhbnNwb3NlKCkucmVmbGVjdCgneCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmlldy5jb29yZGluYXRlKCkudHJhbnNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoZmFjZXQucm93SW5kZXggJSAyICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgdmlldy5jb29yZGluYXRlKCkucmVmbGVjdCgneScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBNaXJyb3IucHJvdG90eXBlLmFmdGVyRWFjaFZpZXcgPSBmdW5jdGlvbiAodmlldywgZmFjZXQpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzQXhpcyh2aWV3LCBmYWNldCk7XG4gICAgfTtcbiAgICBNaXJyb3IucHJvdG90eXBlLmdlbmVyYXRlRmFjZXRzID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGYgPSB0aGlzLmNmZy5maWVsZHNbMF07XG4gICAgICAgIHZhciByc3QgPSBbXTtcbiAgICAgICAgdmFyIGNvbHVtblZhbHVlc0xlbmd0aCA9IDE7XG4gICAgICAgIHZhciByb3dWYWx1ZXNMZW5ndGggPSAxO1xuICAgICAgICB2YXIgY29sdW1uVmFsdWVzID0gWycnXTtcbiAgICAgICAgdmFyIHJvd1ZhbHVlcyA9IFsnJ107XG4gICAgICAgIHZhciBjb2x1bW5GaWVsZDtcbiAgICAgICAgdmFyIHJvd0ZpZWxkO1xuICAgICAgICBpZiAodGhpcy5jZmcudHJhbnNwb3NlKSB7XG4gICAgICAgICAgICBjb2x1bW5GaWVsZCA9IGY7XG4gICAgICAgICAgICBjb2x1bW5WYWx1ZXMgPSB0aGlzLmdldEZpZWxkVmFsdWVzKGRhdGEsIGNvbHVtbkZpZWxkKS5zbGljZSgwLCAyKTsgLy8g6ZWc5YOP5pyA5aSa5Lik5LiqXG4gICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGggPSBjb2x1bW5WYWx1ZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcm93RmllbGQgPSBmO1xuICAgICAgICAgICAgcm93VmFsdWVzID0gdGhpcy5nZXRGaWVsZFZhbHVlcyhkYXRhLCByb3dGaWVsZCkuc2xpY2UoMCwgMik7IC8vIOmVnOWDj+acgOWkmuS4pOS4qlxuICAgICAgICAgICAgcm93VmFsdWVzTGVuZ3RoID0gcm93VmFsdWVzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICAvLyDojrflj5bmr4/kuKrnu7Tluqblr7nlupTnmoTmlbDmja7phY3nva7niYfmrrVcbiAgICAgICAgY29sdW1uVmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHhWYWwsIHhJbmRleCkge1xuICAgICAgICAgICAgcm93VmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHlWYWwsIHlJbmRleCkge1xuICAgICAgICAgICAgICAgIHZhciBjb25kaXRpb25zID0gW1xuICAgICAgICAgICAgICAgICAgICB7IGZpZWxkOiBjb2x1bW5GaWVsZCwgdmFsdWU6IHhWYWwsIHZhbHVlczogY29sdW1uVmFsdWVzIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgZmllbGQ6IHJvd0ZpZWxkLCB2YWx1ZTogeVZhbCwgdmFsdWVzOiByb3dWYWx1ZXMgfSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIHZhciBmYWNldERhdGEgPSB1dGlsXzEuZmlsdGVyKGRhdGEsIF90aGlzLmdldEZhY2V0RGF0YUZpbHRlcihjb25kaXRpb25zKSk7XG4gICAgICAgICAgICAgICAgdmFyIGZhY2V0ID0ge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBfdGhpcy5jZmcudHlwZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogZmFjZXREYXRhLFxuICAgICAgICAgICAgICAgICAgICByZWdpb246IF90aGlzLmdldFJlZ2lvbihyb3dWYWx1ZXNMZW5ndGgsIGNvbHVtblZhbHVlc0xlbmd0aCwgeEluZGV4LCB5SW5kZXgpLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZTogeFZhbCxcbiAgICAgICAgICAgICAgICAgICAgcm93VmFsdWU6IHlWYWwsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkZpZWxkOiBjb2x1bW5GaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgcm93RmllbGQ6IHJvd0ZpZWxkLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5JbmRleDogeEluZGV4LFxuICAgICAgICAgICAgICAgICAgICByb3dJbmRleDogeUluZGV4LFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGg6IGNvbHVtblZhbHVlc0xlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgcm93VmFsdWVzTGVuZ3RoOiByb3dWYWx1ZXNMZW5ndGgsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByc3QucHVzaChmYWNldCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva4geCDlnZDmoIfovbTnmoTmlofmnKzjgIF0aXRsZSDmmK/lkKbmmL7npLpcbiAgICAgKiBAcGFyYW0geFxuICAgICAqIEBwYXJhbSBheGVzXG4gICAgICogQHBhcmFtIG9wdGlvblxuICAgICAqIEBwYXJhbSBmYWNldFxuICAgICAqL1xuICAgIE1pcnJvci5wcm90b3R5cGUuZ2V0WEF4aXNPcHRpb24gPSBmdW5jdGlvbiAoeCwgYXhlcywgb3B0aW9uLCBmYWNldCkge1xuICAgICAgICAvLyDpnZ7mnIDlkI7kuIDooYxcbiAgICAgICAgLy8g5b2T5piv5pyA5ZCO5LiA6KGM5oiW6ICF5LiL6Z2i5rKh5pyJIHZpZXcg5pe25paH5pys5LiN5pi+56S6XG4gICAgICAgIGlmIChmYWNldC5jb2x1bW5JbmRleCA9PT0gMSB8fCBmYWNldC5yb3dJbmRleCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3B0aW9uKSwgeyBsYWJlbDogbnVsbCwgdGl0bGU6IG51bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiuvue9riB5IOWdkOagh+i9tOeahOaWh+acrOOAgXRpdGxlIOaYr+WQpuaYvuekulxuICAgICAqIEBwYXJhbSB5XG4gICAgICogQHBhcmFtIGF4ZXNcbiAgICAgKiBAcGFyYW0gb3B0aW9uXG4gICAgICogQHBhcmFtIGZhY2V0XG4gICAgICovXG4gICAgTWlycm9yLnByb3RvdHlwZS5nZXRZQXhpc09wdGlvbiA9IGZ1bmN0aW9uICh5LCBheGVzLCBvcHRpb24sIGZhY2V0KSB7XG4gICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9O1xuICAgIE1pcnJvci5wcm90b3R5cGUucmVuZGVyVGl0bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZmFjZXRzLCBmdW5jdGlvbiAoZmFjZXQsIGZhY2V0SW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBjb2x1bW5WYWx1ZSA9IGZhY2V0LmNvbHVtblZhbHVlLCByb3dWYWx1ZSA9IGZhY2V0LnJvd1ZhbHVlLCB2aWV3ID0gZmFjZXQudmlldztcbiAgICAgICAgICAgIHZhciBmb3JtYXR0ZXIgPSB1dGlsXzEuZ2V0KF90aGlzLmNmZy50aXRsZSwgJ2Zvcm1hdHRlcicpO1xuICAgICAgICAgICAgaWYgKF90aGlzLmNmZy50cmFuc3Bvc2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0gdXRpbF8xLmRlZXBNaXgoe1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogWyc1MCUnLCAnMCUnXSxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogZm9ybWF0dGVyID8gZm9ybWF0dGVyKGNvbHVtblZhbHVlKSA6IGNvbHVtblZhbHVlLFxuICAgICAgICAgICAgICAgIH0sIGZhY2V0XzEuZ2V0RmFjdFRpdGxlQ29uZmlnKGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUCksIF90aGlzLmNmZy50aXRsZSk7XG4gICAgICAgICAgICAgICAgdmlldy5hbm5vdGF0aW9uKCkudGV4dChjb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFsnMTAwJScsICc1MCUnXSxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogZm9ybWF0dGVyID8gZm9ybWF0dGVyKHJvd1ZhbHVlKSA6IHJvd1ZhbHVlLFxuICAgICAgICAgICAgICAgIH0sIGZhY2V0XzEuZ2V0RmFjdFRpdGxlQ29uZmlnKGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUKSwgX3RoaXMuY2ZnLnRpdGxlKTtcbiAgICAgICAgICAgICAgICB2aWV3LmFubm90YXRpb24oKS50ZXh0KGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIE1pcnJvcjtcbn0oZmFjZXRfMi5GYWNldCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTWlycm9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWlycm9yLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBmYWNldF8xID0gcmVxdWlyZShcIi4uL3V0aWwvZmFjZXRcIik7XG52YXIgZmFjZXRfMiA9IHJlcXVpcmUoXCIuL2ZhY2V0XCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDnn6npmLXliIbpnaJcbiAqL1xudmFyIFJlY3QgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUmVjdCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSZWN0KCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFJlY3QucHJvdG90eXBlLmFmdGVyRWFjaFZpZXcgPSBmdW5jdGlvbiAodmlldywgZmFjZXQpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzQXhpcyh2aWV3LCBmYWNldCk7XG4gICAgfTtcbiAgICBSZWN0LnByb3RvdHlwZS5iZWZvcmVFYWNoVmlldyA9IGZ1bmN0aW9uICh2aWV3LCBmYWNldCkge1xuICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgfTtcbiAgICBSZWN0LnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICBjb2x1bW5UaXRsZTogdHNsaWJfMS5fX2Fzc2lnbih7fSwgX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0VGl0bGVDZmcuY2FsbCh0aGlzKSksXG4gICAgICAgICAgICByb3dUaXRsZTogdHNsaWJfMS5fX2Fzc2lnbih7fSwgX3N1cGVyLnByb3RvdHlwZS5nZXREZWZhdWx0VGl0bGVDZmcuY2FsbCh0aGlzKSksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUmVjdC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5jZmcuc2hvd1RpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclRpdGxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOeUn+aIkOefqemYteWIhumdoueahOWIhumdouaVsOaNrlxuICAgICAqIEBwYXJhbSBkYXRhXG4gICAgICovXG4gICAgUmVjdC5wcm90b3R5cGUuZ2VuZXJhdGVGYWNldHMgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmNmZy5maWVsZHMsIGNvbHVtbkZpZWxkID0gX2FbMF0sIHJvd0ZpZWxkID0gX2FbMV07XG4gICAgICAgIHZhciByc3QgPSBbXTtcbiAgICAgICAgdmFyIGNvbHVtblZhbHVlc0xlbmd0aCA9IDE7XG4gICAgICAgIHZhciByb3dWYWx1ZXNMZW5ndGggPSAxO1xuICAgICAgICB2YXIgY29sdW1uVmFsdWVzID0gWycnXTtcbiAgICAgICAgdmFyIHJvd1ZhbHVlcyA9IFsnJ107XG4gICAgICAgIGlmIChjb2x1bW5GaWVsZCkge1xuICAgICAgICAgICAgY29sdW1uVmFsdWVzID0gdGhpcy5nZXRGaWVsZFZhbHVlcyhkYXRhLCBjb2x1bW5GaWVsZCk7XG4gICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGggPSBjb2x1bW5WYWx1ZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyb3dGaWVsZCkge1xuICAgICAgICAgICAgcm93VmFsdWVzID0gdGhpcy5nZXRGaWVsZFZhbHVlcyhkYXRhLCByb3dGaWVsZCk7XG4gICAgICAgICAgICByb3dWYWx1ZXNMZW5ndGggPSByb3dWYWx1ZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIC8vIOiOt+WPluavj+S4que7tOW6puWvueW6lOeahOaVsOaNrumFjee9rueJh+autVxuICAgICAgICBjb2x1bW5WYWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAoeFZhbCwgeEluZGV4KSB7XG4gICAgICAgICAgICByb3dWYWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAoeVZhbCwgeUluZGV4KSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmRpdGlvbnMgPSBbXG4gICAgICAgICAgICAgICAgICAgIHsgZmllbGQ6IGNvbHVtbkZpZWxkLCB2YWx1ZTogeFZhbCwgdmFsdWVzOiBjb2x1bW5WYWx1ZXMgfSxcbiAgICAgICAgICAgICAgICAgICAgeyBmaWVsZDogcm93RmllbGQsIHZhbHVlOiB5VmFsLCB2YWx1ZXM6IHJvd1ZhbHVlcyB9LFxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgdmFyIGZhY2V0RGF0YSA9IHV0aWxfMS5maWx0ZXIoZGF0YSwgX3RoaXMuZ2V0RmFjZXREYXRhRmlsdGVyKGNvbmRpdGlvbnMpKTtcbiAgICAgICAgICAgICAgICB2YXIgZmFjZXQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IF90aGlzLmNmZy50eXBlLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiBmYWNldERhdGEsXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbjogX3RoaXMuZ2V0UmVnaW9uKHJvd1ZhbHVlc0xlbmd0aCwgY29sdW1uVmFsdWVzTGVuZ3RoLCB4SW5kZXgsIHlJbmRleCksXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtblZhbHVlOiB4VmFsLFxuICAgICAgICAgICAgICAgICAgICByb3dWYWx1ZTogeVZhbCxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uRmllbGQ6IGNvbHVtbkZpZWxkLFxuICAgICAgICAgICAgICAgICAgICByb3dGaWVsZDogcm93RmllbGQsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkluZGV4OiB4SW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIHJvd0luZGV4OiB5SW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtblZhbHVlc0xlbmd0aDogY29sdW1uVmFsdWVzTGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICByb3dWYWx1ZXNMZW5ndGg6IHJvd1ZhbHVlc0xlbmd0aCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJzdC5wdXNoKGZhY2V0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9O1xuICAgIFJlY3QucHJvdG90eXBlLnJlbmRlclRpdGxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmZhY2V0cywgZnVuY3Rpb24gKGZhY2V0LCBmYWNldEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgY29sdW1uSW5kZXggPSBmYWNldC5jb2x1bW5JbmRleCwgcm93SW5kZXggPSBmYWNldC5yb3dJbmRleCwgY29sdW1uVmFsdWVzTGVuZ3RoID0gZmFjZXQuY29sdW1uVmFsdWVzTGVuZ3RoLCBjb2x1bW5WYWx1ZSA9IGZhY2V0LmNvbHVtblZhbHVlLCByb3dWYWx1ZSA9IGZhY2V0LnJvd1ZhbHVlLCB2aWV3ID0gZmFjZXQudmlldztcbiAgICAgICAgICAgIC8vIHRvcFxuICAgICAgICAgICAgaWYgKHJvd0luZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IHV0aWxfMS5nZXQoX3RoaXMuY2ZnLmNvbHVtblRpdGxlLCAnZm9ybWF0dGVyJyk7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFsnNTAlJywgJzAlJ10sXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGZvcm1hdHRlciA/IGZvcm1hdHRlcihjb2x1bW5WYWx1ZSkgOiBjb2x1bW5WYWx1ZSxcbiAgICAgICAgICAgICAgICB9LCBmYWNldF8xLmdldEZhY3RUaXRsZUNvbmZpZyhjb25zdGFudF8xLkRJUkVDVElPTi5UT1ApLCBfdGhpcy5jZmcuY29sdW1uVGl0bGUpO1xuICAgICAgICAgICAgICAgIHZpZXcuYW5ub3RhdGlvbigpLnRleHQoY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJpZ2h0XG4gICAgICAgICAgICBpZiAoY29sdW1uSW5kZXggPT09IGNvbHVtblZhbHVlc0xlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgZm9ybWF0dGVyID0gdXRpbF8xLmdldChfdGhpcy5jZmcucm93VGl0bGUsICdmb3JtYXR0ZXInKTtcbiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0gdXRpbF8xLmRlZXBNaXgoe1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogWycxMDAlJywgJzUwJSddLFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIocm93VmFsdWUpIDogcm93VmFsdWUsXG4gICAgICAgICAgICAgICAgfSwgZmFjZXRfMS5nZXRGYWN0VGl0bGVDb25maWcoY29uc3RhbnRfMS5ESVJFQ1RJT04uUklHSFQpLCBfdGhpcy5jZmcucm93VGl0bGUpO1xuICAgICAgICAgICAgICAgIHZpZXcuYW5ub3RhdGlvbigpLnRleHQoY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva4geCDlnZDmoIfovbTnmoTmlofmnKzjgIF0aXRsZSDmmK/lkKbmmL7npLpcbiAgICAgKiBAcGFyYW0geFxuICAgICAqIEBwYXJhbSBheGVzXG4gICAgICogQHBhcmFtIG9wdGlvblxuICAgICAqIEBwYXJhbSBmYWNldFxuICAgICAqL1xuICAgIFJlY3QucHJvdG90eXBlLmdldFhBeGlzT3B0aW9uID0gZnVuY3Rpb24gKHgsIGF4ZXMsIG9wdGlvbiwgZmFjZXQpIHtcbiAgICAgICAgLy8g6Z2e5pyA5ZCO5LiA6KGMXG4gICAgICAgIGlmIChmYWNldC5yb3dJbmRleCAhPT0gZmFjZXQucm93VmFsdWVzTGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3B0aW9uKSwgeyB0aXRsZTogbnVsbCwgbGFiZWw6IG51bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZmFjZXQuY29sdW1uSW5kZXggIT09IE1hdGguZmxvb3IoKGZhY2V0LmNvbHVtblZhbHVlc0xlbmd0aCAtIDEpIC8gMikpIHtcbiAgICAgICAgICAgIC8vIOS4jeaYr+S4remXtOWIl1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3B0aW9uKSwgeyB0aXRsZTogbnVsbCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3B0aW9uO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572uIHkg5Z2Q5qCH6L2055qE5paH5pys44CBdGl0bGUg5piv5ZCm5pi+56S6XG4gICAgICogQHBhcmFtIHlcbiAgICAgKiBAcGFyYW0gYXhlc1xuICAgICAqIEBwYXJhbSBvcHRpb25cbiAgICAgKiBAcGFyYW0gZmFjZXRcbiAgICAgKi9cbiAgICBSZWN0LnByb3RvdHlwZS5nZXRZQXhpc09wdGlvbiA9IGZ1bmN0aW9uICh5LCBheGVzLCBvcHRpb24sIGZhY2V0KSB7XG4gICAgICAgIGlmIChmYWNldC5jb2x1bW5JbmRleCAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3B0aW9uKSwgeyB0aXRsZTogbnVsbCwgbGFiZWw6IG51bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZmFjZXQucm93SW5kZXggIT09IE1hdGguZmxvb3IoKGZhY2V0LnJvd1ZhbHVlc0xlbmd0aCAtIDEpIC8gMikpIHtcbiAgICAgICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIG9wdGlvbiksIHsgdGl0bGU6IG51bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9O1xuICAgIHJldHVybiBSZWN0O1xufShmYWNldF8yLkZhY2V0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTEwXG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGZhY2V0XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9mYWNldFwiKTtcbnZhciBmYWNldF8yID0gcmVxdWlyZShcIi4vZmFjZXRcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIFRyZWUgRmFjZXRcbiAqL1xudmFyIFRyZWUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVHJlZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUcmVlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuYWZ0ZXJDaGFydFJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5mYWNldHMgJiYgX3RoaXMuY2ZnLmxpbmUpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5kcmF3TGluZXMoX3RoaXMuZmFjZXRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUcmVlLnByb3RvdHlwZS5hZnRlckVhY2hWaWV3ID0gZnVuY3Rpb24gKHZpZXcsIGZhY2V0KSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc0F4aXModmlldywgZmFjZXQpO1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUuYmVmb3JlRWFjaFZpZXcgPSBmdW5jdGlvbiAodmlldywgZmFjZXQpIHsgfTtcbiAgICBUcmVlLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy52aWV3Lm9uKGNvbnN0YW50XzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9SRU5ERVIsIHRoaXMuYWZ0ZXJDaGFydFJlbmRlcik7XG4gICAgfTtcbiAgICBUcmVlLnByb3RvdHlwZS5nZXREZWZhdWx0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB0eXBlOiAndHJlZScsXG4gICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjZGRkJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNtb290aDogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2hvd1RpdGxlOiB0cnVlLFxuICAgICAgICAgICAgdGl0bGU6IF9zdXBlci5wcm90b3R5cGUuZ2V0RGVmYXVsdFRpdGxlQ2ZnLmNhbGwodGhpcyksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUuZ2VuZXJhdGVGYWNldHMgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgZmllbGRzID0gdGhpcy5jZmcuZmllbGRzO1xuICAgICAgICBpZiAoIWZpZWxkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHNwZWNpZnkgZm9yIHRoZSBmaWVsZHMgZm9yIHJvb3RGYWNldCEnKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcnN0ID0gW107XG4gICAgICAgIHZhciByb290RmFjZXQgPSB7XG4gICAgICAgICAgICB0eXBlOiB0aGlzLmNmZy50eXBlLFxuICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgIHJlZ2lvbjogbnVsbCxcbiAgICAgICAgICAgIHJvd1ZhbHVlc0xlbmd0aDogdGhpcy5nZXRSb3dzKCksXG4gICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGg6IDEsXG4gICAgICAgICAgICByb3dJbmRleDogMCxcbiAgICAgICAgICAgIGNvbHVtbkluZGV4OiAwLFxuICAgICAgICAgICAgcm93RmllbGQ6ICcnLFxuICAgICAgICAgICAgY29sdW1uRmllbGQ6ICcnLFxuICAgICAgICAgICAgcm93VmFsdWU6ICcnLFxuICAgICAgICAgICAgY29sdW1uVmFsdWU6ICcnLFxuICAgICAgICB9O1xuICAgICAgICByc3QucHVzaChyb290RmFjZXQpO1xuICAgICAgICByb290RmFjZXQuY2hpbGRyZW4gPSB0aGlzLmdldENoaWxkRmFjZXRzKGRhdGEsIDEsIHJzdCk7XG4gICAgICAgIHRoaXMuc2V0UmVnaW9uKHJzdCk7XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICBUcmVlLnByb3RvdHlwZS5zZXRSZWdpb24gPSBmdW5jdGlvbiAoZmFjZXRzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuZm9yY2VDb2xJbmRleChmYWNldHMpO1xuICAgICAgICBmYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUg5YWB6K646LCD5pW0XG4gICAgICAgICAgICBmYWNldC5yZWdpb24gPSBfdGhpcy5nZXRSZWdpb24oZmFjZXQucm93VmFsdWVzTGVuZ3RoLCBmYWNldC5jb2x1bW5WYWx1ZXNMZW5ndGgsIGZhY2V0LmNvbHVtbkluZGV4LCBmYWNldC5yb3dJbmRleCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUuZ2V0UmVnaW9uID0gZnVuY3Rpb24gKHJvd3MsIGNvbHMsIHhJbmRleCwgeUluZGV4KSB7XG4gICAgICAgIHZhciB4V2lkdGggPSAxIC8gY29sczsgLy8geOi9tOaWueWQkeeahOavj+S4quWIhumdoueahOWBj+enu1xuICAgICAgICB2YXIgeVdpZHRoID0gMSAvIHJvd3M7IC8vIHnovbTmlrnlkJHnmoTmr4/kuKrliIbpnaLnmoTlgY/np7tcbiAgICAgICAgdmFyIHN0YXJ0ID0ge1xuICAgICAgICAgICAgeDogeFdpZHRoICogeEluZGV4LFxuICAgICAgICAgICAgeTogeVdpZHRoICogeUluZGV4LFxuICAgICAgICB9O1xuICAgICAgICB2YXIgZW5kID0ge1xuICAgICAgICAgICAgeDogc3RhcnQueCArIHhXaWR0aCxcbiAgICAgICAgICAgIHk6IHN0YXJ0LnkgKyAoeVdpZHRoICogMikgLyAzLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBlbmQsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBUcmVlLnByb3RvdHlwZS5mb3JjZUNvbEluZGV4ID0gZnVuY3Rpb24gKGZhY2V0cykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbGVhZnMgPSBbXTtcbiAgICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMuaXNMZWFmKGZhY2V0KSkge1xuICAgICAgICAgICAgICAgIGxlYWZzLnB1c2goZmFjZXQpO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUg5YWB6K646LCD5pW0XG4gICAgICAgICAgICAgICAgZmFjZXQuY29sdW1uSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgbGVhZnMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGZhY2V0LmNvbHVtblZhbHVlc0xlbmd0aCA9IGxlYWZzLmxlbmd0aDtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBtYXhMZXZlbCA9IHRoaXMuY2ZnLmZpZWxkcy5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSBtYXhMZXZlbCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICB2YXIgbGV2ZWxGYWNldHMgPSB0aGlzLmdldEZhY2V0c0J5TGV2ZWwoZmFjZXRzLCBpKTtcbiAgICAgICAgICAgIC8vIHZhciB5SW5kZXggPSBtYXhMZXZlbCAtIGk7XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGxldmVsRmFjZXRzXzEgPSBsZXZlbEZhY2V0czsgX2kgPCBsZXZlbEZhY2V0c18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBmYWNldCA9IGxldmVsRmFjZXRzXzFbX2ldO1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0xlYWYoZmFjZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZhY2V0Lm9yaWdpbkNvbEluZGV4ID0gZmFjZXQuY29sdW1uSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgZmFjZXQuY29sdW1uSW5kZXggPSB0aGlzLmdldFJlZ2lvbkluZGV4KGZhY2V0LmNoaWxkcmVuKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICBmYWNldC5jb2x1bW5WYWx1ZXNMZW5ndGggPSBsZWFmcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyBnZXQgZmFjZXQgdXNlIGxldmVsXG4gICAgVHJlZS5wcm90b3R5cGUuZ2V0RmFjZXRzQnlMZXZlbCA9IGZ1bmN0aW9uIChmYWNldHMsIGxldmVsKSB7XG4gICAgICAgIHZhciByc3QgPSBbXTtcbiAgICAgICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAgICAgICBpZiAoZmFjZXQucm93SW5kZXggPT09IGxldmVsKSB7XG4gICAgICAgICAgICAgICAgcnN0LnB1c2goZmFjZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9O1xuICAgIC8vIGlmIHRoZSBmYWNldCBoYXMgY2hpbGRyZW4gLCBtYWtlIGl0J3MgY29sdW1uIGluZGV4IGluIHRoZSBtaWRkbGUgb2YgaXQncyBjaGlsZHJlblxuICAgIFRyZWUucHJvdG90eXBlLmdldFJlZ2lvbkluZGV4ID0gZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgIHZhciBmaXJzdCA9IGNoaWxkcmVuWzBdO1xuICAgICAgICB2YXIgbGFzdCA9IGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdO1xuICAgICAgICByZXR1cm4gKGxhc3QuY29sdW1uSW5kZXggLSBmaXJzdC5jb2x1bW5JbmRleCkgLyAyICsgZmlyc3QuY29sdW1uSW5kZXg7XG4gICAgfTtcbiAgICAvLyBpcyAgYSBsZWFmIHdpdGhvdXQgY2hpbGRyZW5cbiAgICBUcmVlLnByb3RvdHlwZS5pc0xlYWYgPSBmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgICAgcmV0dXJuICFmYWNldC5jaGlsZHJlbiB8fCAhZmFjZXQuY2hpbGRyZW4ubGVuZ3RoO1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUuZ2V0Um93cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2ZnLmZpZWxkcy5sZW5ndGggKyAxO1xuICAgIH07XG4gICAgLy8gZ2V0IGNoaWxkXG4gICAgVHJlZS5wcm90b3R5cGUuZ2V0Q2hpbGRGYWNldHMgPSBmdW5jdGlvbiAoZGF0YSwgbGV2ZWwsIGFycikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAvLyBbICdncmFkZScsICdjbGFzcycgXVxuICAgICAgICB2YXIgZmllbGRzID0gdGhpcy5jZmcuZmllbGRzO1xuICAgICAgICB2YXIgbGVuZ3RoID0gZmllbGRzLmxlbmd0aDtcbiAgICAgICAgaWYgKGxlbmd0aCA8IGxldmVsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICAvLyBnZXQgZmlzdCBsZXZlbCBleGNlcHQgcm9vdCBub2RlXG4gICAgICAgIHZhciBmaWVsZCA9IGZpZWxkc1tsZXZlbCAtIDFdO1xuICAgICAgICAvLyBnZXQgZmllbGQgdmFsdWVcbiAgICAgICAgdmFyIHZhbHVlcyA9IHRoaXMuZ2V0RmllbGRWYWx1ZXMoZGF0YSwgZmllbGQpO1xuICAgICAgICB2YWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgY29uZGl0aW9ucyA9IFt7IGZpZWxkOiBmaWVsZCwgdmFsdWU6IHZhbHVlLCB2YWx1ZXM6IHZhbHVlcyB9XTtcbiAgICAgICAgICAgIHZhciBzdWJEYXRhID0gZGF0YS5maWx0ZXIoX3RoaXMuZ2V0RmFjZXREYXRhRmlsdGVyKGNvbmRpdGlvbnMpKTtcbiAgICAgICAgICAgIGlmIChzdWJEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHZhciBmYWNldCA9IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogX3RoaXMuY2ZnLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHN1YkRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uVmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByb3dWYWx1ZTogJycsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkZpZWxkOiBmaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgcm93RmllbGQ6ICcnLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5JbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIHJvd1ZhbHVlc0xlbmd0aDogX3RoaXMuZ2V0Um93cygpLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5WYWx1ZXNMZW5ndGg6IDEsXG4gICAgICAgICAgICAgICAgICAgIHJvd0luZGV4OiBsZXZlbCxcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IF90aGlzLmdldENoaWxkRmFjZXRzKHN1YkRhdGEsIGxldmVsICsgMSwgYXJyKSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJzdC5wdXNoKGZhY2V0KTtcbiAgICAgICAgICAgICAgICBhcnIucHVzaChmYWNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5jZmcuc2hvd1RpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclRpdGxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRyZWUucHJvdG90eXBlLnJlbmRlclRpdGxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmZhY2V0cywgZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAgICAgICB2YXIgY29sdW1uVmFsdWUgPSBmYWNldC5jb2x1bW5WYWx1ZSwgdmlldyA9IGZhY2V0LnZpZXc7XG4gICAgICAgICAgICB2YXIgZm9ybWF0dGVyID0gdXRpbF8xLmdldChfdGhpcy5jZmcudGl0bGUsICdmb3JtYXR0ZXInKTtcbiAgICAgICAgICAgIHZhciBjb25maWcgPSB1dGlsXzEuZGVlcE1peCh7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246IFsnNTAlJywgJzAlJ10sXG4gICAgICAgICAgICAgICAgY29udGVudDogZm9ybWF0dGVyID8gZm9ybWF0dGVyKGNvbHVtblZhbHVlKSA6IGNvbHVtblZhbHVlLFxuICAgICAgICAgICAgfSwgZmFjZXRfMS5nZXRGYWN0VGl0bGVDb25maWcoY29uc3RhbnRfMS5ESVJFQ1RJT04uVE9QKSwgX3RoaXMuY2ZnLnRpdGxlKTtcbiAgICAgICAgICAgIHZpZXcuYW5ub3RhdGlvbigpLnRleHQoY29uZmlnKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBUcmVlLnByb3RvdHlwZS5kcmF3TGluZXMgPSBmdW5jdGlvbiAoZmFjZXRzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmYWNldCkge1xuICAgICAgICAgICAgaWYgKCFfdGhpcy5pc0xlYWYoZmFjZXQpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gZmFjZXQuY2hpbGRyZW47XG4gICAgICAgICAgICAgICAgX3RoaXMuYWRkRmFjZXRMaW5lcyhmYWNldCwgY2hpbGRyZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIGFkZCBsaW5lcyB3aXRoIGl0J3MgY2hpbGRyZW5cbiAgICBUcmVlLnByb3RvdHlwZS5hZGRGYWNldExpbmVzID0gZnVuY3Rpb24gKGZhY2V0LCBjaGlsZHJlbikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdmlldyA9IGZhY2V0LnZpZXc7XG4gICAgICAgIHZhciByZWdpb24gPSB2aWV3LmNvb3JkaW5hdGVCQm94O1xuICAgICAgICAvLyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcbiAgICAgICAgdmFyIHN0YXJ0ID0ge1xuICAgICAgICAgICAgeDogcmVnaW9uLnggKyByZWdpb24ud2lkdGggLyAyLFxuICAgICAgICAgICAgeTogcmVnaW9uLnkgKyByZWdpb24uaGVpZ2h0LFxuICAgICAgICB9O1xuICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChzdWJGYWNldCkge1xuICAgICAgICAgICAgdmFyIHN1YlJlZ2lvbiA9IHN1YkZhY2V0LnZpZXcuY29vcmRpbmF0ZUJCb3g7XG4gICAgICAgICAgICB2YXIgZW5kID0ge1xuICAgICAgICAgICAgICAgIHg6IHN1YlJlZ2lvbi5ibC54ICsgKHN1YlJlZ2lvbi50ci54IC0gc3ViUmVnaW9uLmJsLngpIC8gMixcbiAgICAgICAgICAgICAgICB5OiBzdWJSZWdpb24udHIueSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB2YXIgbWlkZGxlMSA9IHtcbiAgICAgICAgICAgICAgICB4OiBzdGFydC54LFxuICAgICAgICAgICAgICAgIHk6IHN0YXJ0LnkgKyAoZW5kLnkgLSBzdGFydC55KSAvIDIsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIG1pZGRsZTIgPSB7XG4gICAgICAgICAgICAgICAgeDogZW5kLngsXG4gICAgICAgICAgICAgICAgeTogbWlkZGxlMS55LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIF90aGlzLmRyYXdMaW5lKFtzdGFydCwgbWlkZGxlMSwgbWlkZGxlMiwgZW5kXSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUuZ2V0UGF0aCA9IGZ1bmN0aW9uIChwb2ludHMpIHtcbiAgICAgICAgdmFyIHBhdGggPSBbXTtcbiAgICAgICAgdmFyIHNtb290aCA9IHRoaXMuY2ZnLmxpbmUuc21vb3RoO1xuICAgICAgICBpZiAoc21vb3RoKSB7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydNJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydDJywgcG9pbnRzWzFdLngsIHBvaW50c1sxXS55LCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnksIHBvaW50c1szXS54LCBwb2ludHNbM10ueV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRzLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBwYXRoLnB1c2goWydNJywgcG9pbnQueCwgcG9pbnQueV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHBvaW50LngsIHBvaW50LnldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIC8vIGRyYXcgbGluZSB3aWR0aCBwb2ludHNcbiAgICBUcmVlLnByb3RvdHlwZS5kcmF3TGluZSA9IGZ1bmN0aW9uIChwb2ludHMpIHtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldFBhdGgocG9pbnRzKTtcbiAgICAgICAgdmFyIGxpbmUgPSB0aGlzLmNmZy5saW5lLnN0eWxlO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEuYXNzaWduKHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgIH0sIGxpbmUpLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRyZWUucHJvdG90eXBlLmdldFhBeGlzT3B0aW9uID0gZnVuY3Rpb24gKHgsIGF4ZXMsIG9wdGlvbiwgZmFjZXQpIHtcbiAgICAgICAgaWYgKGZhY2V0LnJvd0luZGV4ICE9PSBmYWNldC5yb3dWYWx1ZXNMZW5ndGggLSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBvcHRpb24pLCB7IHRpdGxlOiBudWxsLCBsYWJlbDogbnVsbCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3B0aW9uO1xuICAgIH07XG4gICAgVHJlZS5wcm90b3R5cGUuZ2V0WUF4aXNPcHRpb24gPSBmdW5jdGlvbiAoeSwgYXhlcywgb3B0aW9uLCBmYWNldCkge1xuICAgICAgICBpZiAoZmFjZXQub3JpZ2luQ29sSW5kZXggIT09IDAgJiYgZmFjZXQuY29sdW1uSW5kZXggIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIG9wdGlvbiksIHsgdGl0bGU6IG51bGwsIGxhYmVsOiBudWxsIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcHRpb247XG4gICAgfTtcbiAgICByZXR1cm4gVHJlZTtcbn0oZmFjZXRfMi5GYWNldCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVHJlZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRyZWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIHBhdGhfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3BhdGhcIikpO1xucmVxdWlyZShcIi4vc2hhcGUvYXJlYVwiKTtcbi8qKlxuICogQXJlYSDlh6DkvZXmoIforrDnsbvjgIJcbiAqIOW4uOeUqOS6jue7mOWItumdouenr+WbvuOAglxuICovXG52YXIgQXJlYSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhBcmVhLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEFyZWEoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNmZykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdhcmVhJztcbiAgICAgICAgX3RoaXMuc2hhcGVUeXBlID0gJ2FyZWEnO1xuICAgICAgICAvKiog55Sf5oiQ5Zu+5b2i5YWz6ZSu54K5ICovXG4gICAgICAgIF90aGlzLmdlbmVyYXRlUG9pbnRzID0gdHJ1ZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOmdouenr+WbvuaYr+WQpuS7jiAwIOWfuuWHhue6v+W8gOWni+Whq+WFheOAglxuICAgICAgICAgKiAxLiDpu5jorqTlgLzkuLogYHRydWVg77yM6KGo546w5aaC5LiL77yaXG4gICAgICAgICAqICFbaW1hZ2VdKGh0dHBzOi8vZ3cuYWxpcGF5b2JqZWN0cy5jb20vem9zL3Jtc3BvcnRhbC9aUXF3VUNjemFscktxR2dhZ09WcC5wbmcpXG4gICAgICAgICAqIDIuIOW9k+WAvOS4uiBgZmFsc2VgIOaXtu+8jOihqOeOsOWmguS4i++8mlxuICAgICAgICAgKiAhW2ltYWdlXShodHRwczovL2d3LmFsaXBheW9iamVjdHMuY29tL3pvcy9ybXNwb3J0YWwveVBzd2thWHZVcENZT2Rob2NHd0IucG5nKVxuICAgICAgICAgKi9cbiAgICAgICAgX3RoaXMuc3RhcnRPblplcm8gPSB0cnVlO1xuICAgICAgICB2YXIgX2EgPSBjZmcuc3RhcnRPblplcm8sIHN0YXJ0T25aZXJvID0gX2EgPT09IHZvaWQgMCA/IHRydWUgOiBfYSwgX2IgPSBjZmcuc29ydGFibGUsIHNvcnRhYmxlID0gX2IgPT09IHZvaWQgMCA/IHRydWUgOiBfYiwgX2MgPSBjZmcuc2hvd1NpbmdsZVBvaW50LCBzaG93U2luZ2xlUG9pbnQgPSBfYyA9PT0gdm9pZCAwID8gZmFsc2UgOiBfYztcbiAgICAgICAgX3RoaXMuc3RhcnRPblplcm8gPSBzdGFydE9uWmVybzsgLy8g6buY6K6k5Li6IHRydWVcbiAgICAgICAgX3RoaXMuc29ydGFibGUgPSBzb3J0YWJsZTsgLy8gQXJlYSDpu5jorqTkvJrlr7nmlbDmja7mjInnhacgeCDovbTlrZfmrrXov5vooYzmraPlkJHmjpLluo9cbiAgICAgICAgX3RoaXMuc2hvd1NpbmdsZVBvaW50ID0gc2hvd1NpbmdsZVBvaW50O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOiOt+WPluWbvuW9oue7mOWItueahOWFs+mUrueCueS7peWPiuaVsOaNrlxuICAgICAqIEBwYXJhbSBtYXBwaW5nRGF0YSDmmKDlsITlkI7nmoTmlbDmja5cbiAgICAgKi9cbiAgICBBcmVhLnByb3RvdHlwZS5nZXRQb2ludHNBbmREYXRhID0gZnVuY3Rpb24gKG1hcHBpbmdEYXRhKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSBbXTtcbiAgICAgICAgdmFyIGRhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG1hcHBpbmdEYXRhLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgb2JqID0gbWFwcGluZ0RhdGFbaV07XG4gICAgICAgICAgICBwb2ludHMucHVzaChvYmoucG9pbnRzKTtcbiAgICAgICAgICAgIGRhdGEucHVzaChvYmpbY29uc3RhbnRfMS5GSUVMRF9PUklHSU5dKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcG9pbnRzOiBwb2ludHMsXG4gICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+WIFkg6L205LiK55qE5pyA5bCP5YC8XG4gICAgICogQHJldHVybnMgeSDlrZfmrrXmnIDlsI/lgLxcbiAgICAgKi9cbiAgICBBcmVhLnByb3RvdHlwZS5nZXRZTWluVmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXJ0T25aZXJvKSB7XG4gICAgICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRZTWluVmFsdWUuY2FsbCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgeVNjYWxlID0gdGhpcy5nZXRZU2NhbGUoKTtcbiAgICAgICAgcmV0dXJuIHlTY2FsZS5taW47XG4gICAgfTtcbiAgICByZXR1cm4gQXJlYTtcbn0ocGF0aF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEFyZWE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hcmVhLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYWRqdXN0XzEgPSByZXF1aXJlKFwiQGFudHYvYWRqdXN0XCIpO1xudmFyIGF0dHJfMSA9IHJlcXVpcmUoXCJAYW50di9hdHRyXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGFuaW1hdGVfMSA9IHJlcXVpcmUoXCIuLi9hbmltYXRlXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIGhlbHBlcl8xID0gcmVxdWlyZShcIi4uL3V0aWwvaGVscGVyXCIpO1xudmFyIGVsZW1lbnRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2VsZW1lbnRcIikpO1xudmFyIGxhYmVsXzEgPSByZXF1aXJlKFwiLi9sYWJlbFwiKTtcbnZhciBiYXNlXzIgPSByZXF1aXJlKFwiLi9zaGFwZS9iYXNlXCIpO1xudmFyIGdyb3VwX2RhdGFfMSA9IHJlcXVpcmUoXCIuL3V0aWwvZ3JvdXAtZGF0YVwiKTtcbnZhciBpc19tb2RlbF9jaGFuZ2VfMSA9IHJlcXVpcmUoXCIuL3V0aWwvaXMtbW9kZWwtY2hhbmdlXCIpO1xudmFyIHBhcnNlX2ZpZWxkc18xID0gcmVxdWlyZShcIi4vdXRpbC9wYXJzZS1maWVsZHNcIik7XG4vLyDmoLnmja4gZWxlbWVudElkIOafpeaJvuWvueW6lOeahCBsYWJlbO+8jOWboOS4uuacieWPr+iDveS4gOS4qiBlbGVtZW50IOWvueW6lOWkmuS4qiBsYWJlbHPvvIzmiYDku6XlnKjnu5kgbGFiZWxzIOaJk+agh+ivhuaXtuWBmuS6huWkhOeQhlxuLy8g5omT5qCH6KeE5YiZ6K+m6KeBIC4vbGFiZWwvYmFzZS50cyNMMjYzXG5mdW5jdGlvbiBmaWx0ZXJMYWJlbHNCeUlkKGlkLCBsYWJlbHNNYXApIHtcbiAgICB2YXIgbGFiZWxzID0gW107XG4gICAgdXRpbF8xLmVhY2gobGFiZWxzTWFwLCBmdW5jdGlvbiAobGFiZWwsIGxhYmVsSWQpIHtcbiAgICAgICAgdmFyIGVsZW1lbnRJZCA9IGxhYmVsSWQuc3BsaXQoJyAnKVswXTtcbiAgICAgICAgaWYgKGVsZW1lbnRJZCA9PT0gaWQpIHtcbiAgICAgICAgICAgIGxhYmVscy5wdXNoKGxhYmVsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBsYWJlbHM7XG59XG4vKipcbiAqIEdlb21ldHJ5IOWHoOS9leagh+iusOWfuuexu++8jOS4u+imgei0n+i0o+aVsOaNruWIsOWbvuW9ouWxnuaAp+eahOaYoOWwhOS7peWPiue7mOWItumAu+i+keOAglxuICovXG52YXIgR2VvbWV0cnkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR2VvbWV0cnksIF9zdXBlcik7XG4gICAgLyoqXG4gICAgICog5Yib5bu6IEdlb21ldHJ5IOWunuS+i+OAglxuICAgICAqIEBwYXJhbSBjZmdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBHZW9tZXRyeShjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICAvKiogR2VvbWV0cnkg5Yeg5L2V5qCH6K6w57G75Z6L44CCICovXG4gICAgICAgIF90aGlzLnR5cGUgPSAnYmFzZSc7XG4gICAgICAgIC8vIOWGhemDqOS6p+eUn+eahOWxnuaAp1xuICAgICAgICAvKiogQXR0cmlidXRlIG1hcCAgKi9cbiAgICAgICAgX3RoaXMuYXR0cmlidXRlcyA9IHt9O1xuICAgICAgICAvKiogRWxlbWVudCBtYXAgKi9cbiAgICAgICAgX3RoaXMuZWxlbWVudHMgPSBbXTtcbiAgICAgICAgLyoqIOS9v+eUqCBrZXktdmFsdWUg57uT5p6E5a2Y5YKoIEVsZW1lbnTvvIxrZXkg5Li65q+P5LiqIEVsZW1lbnQg5a6e5L6L5a+55bqU55qE5ZSv5LiAIElEICovXG4gICAgICAgIF90aGlzLmVsZW1lbnRzTWFwID0ge307XG4gICAgICAgIC8qKiBhbmltYXRlIOmFjee9rumhuSAqL1xuICAgICAgICBfdGhpcy5hbmltYXRlT3B0aW9uID0gdHJ1ZTtcbiAgICAgICAgLyoqIOWbvuW9ouWxnuaAp+aYoOWwhOmFjee9riAqL1xuICAgICAgICBfdGhpcy5hdHRyaWJ1dGVPcHRpb24gPSB7fTtcbiAgICAgICAgLyoqIOWtmOWCqOS4iuS4gOasoea4suafk+aXtueahCBlbGVtZW50IOaYoOWwhOihqO+8jOeUqOS6juabtOaWsOmAu+i+kSAqL1xuICAgICAgICBfdGhpcy5sYXN0RWxlbWVudHNNYXAgPSB7fTtcbiAgICAgICAgLyoqIOaYr+WQpueUn+aIkOWkmuS4queCueadpee7mOWItuWbvuW9ouOAgiAqL1xuICAgICAgICBfdGhpcy5nZW5lcmF0ZVBvaW50cyA9IGZhbHNlO1xuICAgICAgICAvKiog5a2Y5YKo5Y+R55Sf5Zu+5b2i5bGe5oCn5pig5bCE5YmN55qE5pWw5o2uICovXG4gICAgICAgIF90aGlzLmJlZm9yZU1hcHBpbmdEYXRhID0gbnVsbDtcbiAgICAgICAgX3RoaXMuYWRqdXN0cyA9IHt9O1xuICAgICAgICBfdGhpcy5pZEZpZWxkcyA9IFtdO1xuICAgICAgICBfdGhpcy5oYXNTb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMuaXNDb29yZGluYXRlQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gY2ZnLmNvbnRhaW5lciwgbGFiZWxzQ29udGFpbmVyID0gY2ZnLmxhYmVsc0NvbnRhaW5lciwgY29vcmRpbmF0ZSA9IGNmZy5jb29yZGluYXRlLCBkYXRhID0gY2ZnLmRhdGEsIF9hID0gY2ZnLnNvcnRhYmxlLCBzb3J0YWJsZSA9IF9hID09PSB2b2lkIDAgPyBmYWxzZSA6IF9hLCBfYiA9IGNmZy52aXNpYmxlLCB2aXNpYmxlID0gX2IgPT09IHZvaWQgMCA/IHRydWUgOiBfYiwgdGhlbWUgPSBjZmcudGhlbWUsIF9jID0gY2ZnLnNjYWxlcywgc2NhbGVzID0gX2MgPT09IHZvaWQgMCA/IHt9IDogX2MsIF9kID0gY2ZnLnNjYWxlRGVmcywgc2NhbGVEZWZzID0gX2QgPT09IHZvaWQgMCA/IHt9IDogX2Q7XG4gICAgICAgIF90aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgX3RoaXMubGFiZWxzQ29udGFpbmVyID0gbGFiZWxzQ29udGFpbmVyO1xuICAgICAgICBfdGhpcy5jb29yZGluYXRlID0gY29vcmRpbmF0ZTtcbiAgICAgICAgX3RoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIF90aGlzLnNvcnRhYmxlID0gc29ydGFibGU7XG4gICAgICAgIF90aGlzLnZpc2libGUgPSB2aXNpYmxlO1xuICAgICAgICBfdGhpcy51c2VyVGhlbWUgPSB0aGVtZTtcbiAgICAgICAgX3RoaXMuc2NhbGVzID0gc2NhbGVzO1xuICAgICAgICBfdGhpcy5zY2FsZURlZnMgPSBzY2FsZURlZnM7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog6YWN572uIHBvc2l0aW9uIOmAmumBk+aYoOWwhOinhOWImeOAglxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8g5pWw5o2u57uT5p6EOiBbeyB4OiAnQScsIHk6IDEwLCBjb2xvcjogJ3JlZCcgfV1cbiAgICAgKiBnZW9tZXRyeS5wb3NpdGlvbigneCp5Jyk7XG4gICAgICogZ2VvbWV0cnkucG9zaXRpb24oWyAneCcsICd5JyBdKTtcbiAgICAgKiBnZW9tZXRyeS5wb3NpdGlvbih7XG4gICAgICogICBmaWVsZHM6IFsgJ3gnLCAneScgXSxcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSBjZmcg5pig5bCE6KeE5YiZXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUucG9zaXRpb24gPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHZhciBwb3NpdGlvbkNmZyA9IGNmZztcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNQbGFpbk9iamVjdChjZmcpKSB7XG4gICAgICAgICAgICAvLyDlrZfnrKbkuLLlrZfmrrXmiJbogIXmlbDnu4TlrZfmrrVcbiAgICAgICAgICAgIHBvc2l0aW9uQ2ZnID0ge1xuICAgICAgICAgICAgICAgIGZpZWxkczogcGFyc2VfZmllbGRzXzEucGFyc2VGaWVsZHMoY2ZnKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZpZWxkcyA9IHV0aWxfMS5nZXQocG9zaXRpb25DZmcsICdmaWVsZHMnKTtcbiAgICAgICAgaWYgKGZpZWxkcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIC8vIOm7mOiupOWhq+WFheS4gOe7tCAxKnh4XG4gICAgICAgICAgICBmaWVsZHMudW5zaGlmdCgnMScpO1xuICAgICAgICAgICAgdXRpbF8xLnNldChwb3NpdGlvbkNmZywgJ2ZpZWxkcycsIGZpZWxkcyk7XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLnNldCh0aGlzLmF0dHJpYnV0ZU9wdGlvbiwgJ3Bvc2l0aW9uJywgcG9zaXRpb25DZmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5jb2xvciA9IGZ1bmN0aW9uIChmaWVsZCwgY2ZnKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlQXR0ck9wdGlvbignY29sb3InLCBmaWVsZCwgY2ZnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuc2hhcGUgPSBmdW5jdGlvbiAoZmllbGQsIGNmZykge1xuICAgICAgICB0aGlzLmNyZWF0ZUF0dHJPcHRpb24oJ3NoYXBlJywgZmllbGQsIGNmZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgR2VvbWV0cnkucHJvdG90eXBlLnNpemUgPSBmdW5jdGlvbiAoZmllbGQsIGNmZykge1xuICAgICAgICB0aGlzLmNyZWF0ZUF0dHJPcHRpb24oJ3NpemUnLCBmaWVsZCwgY2ZnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7mlbDmja7osIPmlbTmlrnlvI/jgIJHMiDnm67liY3lhoXnva7kuoblm5vnp43nsbvlnovvvJpcbiAgICAgKiAxLiBkb2RnZVxuICAgICAqIDIuIHN0YWNrXG4gICAgICogMy4gc3ltbWV0cmljXG4gICAgICogNC4gaml0dGVyXG4gICAgICpcbiAgICAgKlxuICAgICAqICoqVGlwKipcbiAgICAgKiArIOWvueS6jiAnZG9kZ2UnIOexu+Wei++8jOWPr+S7pemineWklui/m+ihjOWmguS4i+WxnuaAp+eahOmFjee9rjpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogZ2VvbWV0cnkuYWRqdXN0KCdkb2RnZScsIHtcbiAgICAgKiAgIG1hcmdpblJhdGlvOiAwLCAvLyDlj5YgMCDliLAgMSDojIPlm7TnmoTlgLzvvIjnm7jlr7nkuo7mr4/kuKrmn7HlrZDlrr3luqbvvInvvIznlKjkuo7mjqfliLbkuIDkuKrliIbnu4TkuK3mn7HlrZDkuYvpl7TnmoTpl7Tot51cbiAgICAgKiAgIGRvZGdlQnk6ICd4JywgLy8g6K+l5bGe5oCn5Y+q5a+5ICdkb2RnZScg57G75Z6L55Sf5pWI77yM5aOw5piO5Lul5ZOq5Liq5pWw5o2u5a2X5q615Li65YiG57uE5L6d5o2uXG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiArIOWvueS6jiAnc3RhY2snIOexu+Wei++8jOWPr+S7pemineWklui/m+ihjOWmguS4i+WxnuaAp+eahOmFjee9rjpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogZ2VvbWV0cnkuYWRqdXN0KCdzdGFjaycsIHtcbiAgICAgKiAgIHJldmVyc2VPcmRlcjogZmFsc2UsIC8vIOeUqOS6juaOp+WItuaYr+WQpuWvueaVsOaNrui/m+ihjOWPjeW6j+aTjeS9nFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogZ2VvbWV0cnkuYWRqdXN0KCdzdGFjaycpO1xuICAgICAqXG4gICAgICogZ2VvbWV0cnkuYWRqdXN0KHtcbiAgICAgKiAgIHR5cGU6ICdzdGFjaycsXG4gICAgICogICByZXZlcnNlT3JkZXI6IGZhbHNlLFxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8g57uE5ZCI5L2/55SoIGFkanVzdFxuICAgICAqIGdlb21ldHJ5LmFkanVzdChbICdzdGFjaycsICdkb2RnZScgXSk7XG4gICAgICpcbiAgICAgKiBnZW9tZXRyeS5hZGp1c3QoW1xuICAgICAqICAgeyB0eXBlOiAnc3RhY2snIH0sXG4gICAgICogICB7IHR5cGU6ICdkb2RnZScsIGRvZGdlQnk6ICd4JyB9LFxuICAgICAqIF0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGFkanVzdENmZyDmlbDmja7osIPmlbTphY3nva5cbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5hZGp1c3QgPSBmdW5jdGlvbiAoYWRqdXN0Q2ZnKSB7XG4gICAgICAgIHZhciBhZGp1c3RzID0gYWRqdXN0Q2ZnO1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGFkanVzdENmZykgfHwgdXRpbF8xLmlzUGxhaW5PYmplY3QoYWRqdXN0Q2ZnKSkge1xuICAgICAgICAgICAgYWRqdXN0cyA9IFthZGp1c3RDZmddO1xuICAgICAgICB9XG4gICAgICAgIHV0aWxfMS5lYWNoKGFkanVzdHMsIGZ1bmN0aW9uIChhZGp1c3QsIGluZGV4KSB7XG4gICAgICAgICAgICBpZiAoIXV0aWxfMS5pc09iamVjdChhZGp1c3QpKSB7XG4gICAgICAgICAgICAgICAgYWRqdXN0c1tpbmRleF0gPSB7IHR5cGU6IGFkanVzdCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hZGp1c3RPcHRpb24gPSBhZGp1c3RzO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5zdHlsZSA9IGZ1bmN0aW9uIChmaWVsZCwgc3R5bGVGdW5jKSB7XG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcoZmllbGQpKSB7XG4gICAgICAgICAgICB2YXIgZmllbGRzID0gcGFyc2VfZmllbGRzXzEucGFyc2VGaWVsZHMoZmllbGQpO1xuICAgICAgICAgICAgdGhpcy5zdHlsZU9wdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IGZpZWxkcyxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogc3R5bGVGdW5jLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBfYSA9IGZpZWxkLCBmaWVsZHMgPSBfYS5maWVsZHMsIGNhbGxiYWNrID0gX2EuY2FsbGJhY2ssIGNmZyA9IF9hLmNmZztcbiAgICAgICAgICAgIGlmIChmaWVsZHMgfHwgY2FsbGJhY2sgfHwgY2ZnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHlsZU9wdGlvbiA9IGZpZWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHlsZU9wdGlvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2ZnOiBmaWVsZCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgR2VvbWV0cnkucHJvdG90eXBlLnRvb2x0aXAgPSBmdW5jdGlvbiAoZmllbGQsIGNmZykge1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGZpZWxkKSkge1xuICAgICAgICAgICAgdmFyIGZpZWxkcyA9IHBhcnNlX2ZpZWxkc18xLnBhcnNlRmllbGRzKGZpZWxkKTtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcE9wdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IGZpZWxkcyxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogY2ZnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcE9wdGlvbiA9IGZpZWxkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogR2VvbWV0cnkg5Yqo55S76YWN572u44CCXG4gICAgICpcbiAgICAgKiArIGBhbmltYXRlKGZhbHNlKWAg5YWz6Zet5Yqo55S7XG4gICAgICogKyBgYW5pbWF0ZSh0cnVlKWAg5byA5ZCv5Yqo55S777yM6buY6K6k5byA5ZCv44CCXG4gICAgICpcbiAgICAgKiDmiJHku6zlsIbliqjnlLvliIbkuLrlm5vkuKrlnLrmma/vvJpcbiAgICAgKiAxLiBhcHBlYXI6IOWbvuihqOesrOS4gOasoeWKoOi9veaXtueahOWFpeWcuuWKqOeUu++8m1xuICAgICAqIDIuIGVudGVyOiDlm77ooajnu5jliLblrozmiJDvvIzlj5HnlJ/mm7TmlrDlkI7vvIzkuqfnlJ/nmoTmlrDlm77lvaLnmoTov5vlnLrliqjnlLvvvJtcbiAgICAgKiAzLiB1cGRhdGU6IOWbvuihqOe7mOWItuWujOaIkO+8jOaVsOaNruWPkeeUn+WPmOabtOWQju+8jOacieeKtuaAgeWPmOabtOeahOWbvuW9oueahOabtOaWsOWKqOeUu++8m1xuICAgICAqIDQuIGxlYXZlOiDlm77ooajnu5jliLblrozmiJDvvIzmlbDmja7lj5HnlJ/lj5jmm7TlkI7vvIzooqvplIDmr4Hlm77lvaLnmoTplIDmr4HliqjnlLvjgIJcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGFuaW1hdGUoe1xuICAgICAqICAgZW50ZXI6IHtcbiAgICAgKiAgICAgZHVyYXRpb246IDEwMDAsIC8vIGVudGVyIOWKqOeUu+aJp+ihjOaXtumXtFxuICAgICAqICAgfSxcbiAgICAgKiAgIGxlYXZlOiBmYWxzZSwgLy8g5YWz6ZetIGxlYXZlIOmUgOavgeWKqOeUu1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGNmZyDliqjnlLvphY3nva5cbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5hbmltYXRlID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB0aGlzLmFuaW1hdGVPcHRpb24gPSBjZmc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmxhYmVsID0gZnVuY3Rpb24gKGZpZWxkLCBzZWNvbmRQYXJhbSwgdGhpcmRQYXJhbSkge1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGZpZWxkKSkge1xuICAgICAgICAgICAgdmFyIGxhYmVsT3B0aW9uID0ge307XG4gICAgICAgICAgICB2YXIgZmllbGRzID0gcGFyc2VfZmllbGRzXzEucGFyc2VGaWVsZHMoZmllbGQpO1xuICAgICAgICAgICAgbGFiZWxPcHRpb24uZmllbGRzID0gZmllbGRzO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHNlY29uZFBhcmFtKSkge1xuICAgICAgICAgICAgICAgIGxhYmVsT3B0aW9uLmNhbGxiYWNrID0gc2Vjb25kUGFyYW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNQbGFpbk9iamVjdChzZWNvbmRQYXJhbSkpIHtcbiAgICAgICAgICAgICAgICBsYWJlbE9wdGlvbi5jZmcgPSBzZWNvbmRQYXJhbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlyZFBhcmFtKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxPcHRpb24uY2ZnID0gdGhpcmRQYXJhbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubGFiZWxPcHRpb24gPSBsYWJlbE9wdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubGFiZWxPcHRpb24gPSBmaWVsZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiuvue9rueKtuaAgeWvueW6lOeahOagt+W8j+OAglxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGB0c1xuICAgICAqIGNoYXJ0LmludGVydmFsKCkuc3RhdGUoe1xuICAgICAqICAgc2VsZWN0ZWQ6IHtcbiAgICAgKiAgICAgYW5pbWF0ZTogeyBkdXJhdGlvbjogMTAwLCBlYXNpbmc6ICdlYXNlTGluZWFyJyB9LFxuICAgICAqICAgICBzdHlsZToge1xuICAgICAqICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgKiAgICAgICBzdHJva2U6ICcjMDAwJyxcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgIH0sXG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiDlpoLmnpzlm77lvaIgc2hhcGUg5piv55Sx5aSa5LiqIHNoYXBlIOe7hOaIkO+8jOWNs+S4uuS4gOS4qiBHLkdyb3VwIOWvueixoe+8jOmCo+S5iOmSiOWvuSBncm91cCDkuK3nmoTmr4/kuKogc2hhcGXvvIzmiJHku6zpnIDopoHkvb/nlKjkuIvliJfmlrnlvI/ov5vooYznirbmgIHmoLflvI/orr7nva7vvJpcbiAgICAgKiDlpoLmnpzmiJHku6zkuLogZ3JvdXAg5Lit55qE5q+P5LiqIHNoYXBlIOiuvue9ruS6hiAnbmFtZScg5bGe5oCnKHNoYXBlLnNldCgnbmFtZScsICd4eCcpKe+8jOWImeS7pSAnbmFtZScg5L2c5Li6IGtlee+8jOWQpuWImem7mOiupOS7pee0ouW8leWAvO+8iOWNsyBzaGFwZSDnmoQg5re75Yqg6aG65bqP77yJ5Li6IGtleeOAglxuICAgICAqXG4gICAgICogYGBgdHNcbiAgICAgKiBjaGFydC5pbnRlcnZhbCgpLnNoYXBlKCdncm91cFNoYXBlJykuc3RhdGUoe1xuICAgICAqICAgc2VsZWN0ZWQ6IHtcbiAgICAgKiAgICAgc3R5bGU6IHtcbiAgICAgKiAgICAgICAwOiB7IGxpbmVXaWR0aDogMiB9LFxuICAgICAqICAgICAgIDE6IHsgZmlsbE9wYWNpdHk6IDEgfSxcbiAgICAgKiAgICAgfVxuICAgICAqICAgfVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGNmZyDnirbmgIHmoLflvI9cbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuc3RhdGUgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHRoaXMuc3RhdGVPcHRpb24gPSBjZmc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yid5aeL5YyWIEdlb210cnkg5a6e5L6L77yaXG4gICAgICog5Yib5bu6IFtbQXR0cmlidXRlXV0gYW5kIFtbU2NhbGVdXSDlrp7kvovvvIzov5vooYzmlbDmja7lpITnkIbvvIzljIXmi6zliIbnu4TjgIHmlbDlgLzljJbku6Xlj4rmlbDmja7osIPmlbTjgIJcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgaWYgKGNmZyA9PT0gdm9pZCAwKSB7IGNmZyA9IHt9OyB9XG4gICAgICAgIHRoaXMuc2V0Q2ZnKGNmZyk7XG4gICAgICAgIHRoaXMuaW5pdEF0dHJpYnV0ZXMoKTsgLy8g5Yib5bu65Zu+5b2i5bGe5oCnXG4gICAgICAgIC8vIOaVsOaNruWKoOW3pe+8muWIhue7hCAtPiDmlbDlrZfljJYgLT4gYWRqdXN0XG4gICAgICAgIHRoaXMucHJvY2Vzc0RhdGEodGhpcy5kYXRhKTtcbiAgICAgICAgLy8g6LCD5pW0IHNjYWxlXG4gICAgICAgIHRoaXMuYWRqdXN0U2NhbGUoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEdlb21ldHJ5IOabtOaWsOOAglxuICAgICAqIEBwYXJhbSBbY2ZnXSDmm7TmlrDnmoTphY3nva5cbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICBpZiAoY2ZnID09PSB2b2lkIDApIHsgY2ZnID0ge307IH1cbiAgICAgICAgdmFyIGRhdGEgPSBjZmcuZGF0YSwgaXNEYXRhQ2hhbmdlZCA9IGNmZy5pc0RhdGFDaGFuZ2VkLCBpc0Nvb3JkaW5hdGVDaGFuZ2VkID0gY2ZnLmlzQ29vcmRpbmF0ZUNoYW5nZWQ7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIGF0dHJpYnV0ZU9wdGlvbiA9IF9hLmF0dHJpYnV0ZU9wdGlvbiwgbGFzdEF0dHJpYnV0ZU9wdGlvbiA9IF9hLmxhc3RBdHRyaWJ1dGVPcHRpb247XG4gICAgICAgIGlmICghdXRpbF8xLmlzRXF1YWwoYXR0cmlidXRlT3B0aW9uLCBsYXN0QXR0cmlidXRlT3B0aW9uKSkge1xuICAgICAgICAgICAgLy8g5pig5bCE5Y+R55Sf5pS55Y+Y77yM5YiZ6YeN5paw5Yib5bu65Zu+5b2i5bGe5oCnXG4gICAgICAgICAgICB0aGlzLmluaXQoY2ZnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkYXRhICYmIChpc0RhdGFDaGFuZ2VkIHx8ICF1dGlsXzEuaXNFcXVhbChkYXRhLCB0aGlzLmRhdGEpKSkge1xuICAgICAgICAgICAgLy8g5pWw5o2u5Y+R55Sf5Y+Y5YyWXG4gICAgICAgICAgICB0aGlzLnNldENmZyhjZmcpO1xuICAgICAgICAgICAgdGhpcy5wcm9jZXNzRGF0YShkYXRhKTsgLy8g5pWw5o2u5Yqg5bel77ya5YiG57uEIC0+IOaVsOWtl+WMliAtPiBhZGp1c3RcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOacieWPr+iDvSBjb29yZGluYXRlIOWPmOWMllxuICAgICAgICAgICAgdGhpcy5zZXRDZmcoY2ZnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyDosIPmlbQgc2NhbGVcbiAgICAgICAgdGhpcy5hZGp1c3RTY2FsZSgpO1xuICAgICAgICB0aGlzLmlzQ29vcmRpbmF0ZUNoYW5nZWQgPSBpc0Nvb3JkaW5hdGVDaGFuZ2VkO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5bCG5Y6f5aeL5pWw5o2u5pig5bCE6Iez5Zu+5b2i56m66Ze077yM5ZCM5pe25Yib5bu65Zu+5b2i5a+56LGh44CCXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLnBhaW50ID0gZnVuY3Rpb24gKGlzVXBkYXRlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmIChpc1VwZGF0ZSA9PT0gdm9pZCAwKSB7IGlzVXBkYXRlID0gZmFsc2U7IH1cbiAgICAgICAgaWYgKHRoaXMuYW5pbWF0ZU9wdGlvbikge1xuICAgICAgICAgICAgdGhpcy5hbmltYXRlT3B0aW9uID0gdXRpbF8xLmRlZXBNaXgoe30sIGFuaW1hdGVfMS5nZXREZWZhdWx0QW5pbWF0ZUNmZyh0aGlzLnR5cGUsIHRoaXMuY29vcmRpbmF0ZSksIHRoaXMuYW5pbWF0ZU9wdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWZhdWx0U2l6ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5lbGVtZW50cyA9IFtdO1xuICAgICAgICB0aGlzLmVsZW1lbnRzTWFwID0ge307XG4gICAgICAgIHZhciBvZmZzY3JlZW5Hcm91cCA9IHRoaXMuZ2V0T2Zmc2NyZWVuR3JvdXAoKTtcbiAgICAgICAgb2Zmc2NyZWVuR3JvdXAuY2xlYXIoKTtcbiAgICAgICAgdmFyIGJlZm9yZU1hcHBpbmdEYXRhID0gdGhpcy5iZWZvcmVNYXBwaW5nRGF0YTtcbiAgICAgICAgdmFyIGRhdGFBcnJheSA9IHRoaXMuYmVmb3JlTWFwcGluZyhiZWZvcmVNYXBwaW5nRGF0YSk7XG4gICAgICAgIHZhciBtYXBwaW5nQXJyYXkgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwLCBsZW5ndGhfMSA9IGRhdGFBcnJheS5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoXzE7IGluZGV4KyspIHtcbiAgICAgICAgICAgIHZhciBlYWNoR3JvdXAgPSBkYXRhQXJyYXlbaW5kZXhdO1xuICAgICAgICAgICAgdmFyIG1hcHBpbmdEYXRhID0gdGhpcy5tYXBwaW5nKGVhY2hHcm91cCk7XG4gICAgICAgICAgICBtYXBwaW5nQXJyYXkucHVzaChtYXBwaW5nRGF0YSk7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUVsZW1lbnRzKG1hcHBpbmdEYXRhLCBpbmRleCwgaXNVcGRhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNhbkRvR3JvdXBBbmltYXRpb24oaXNVcGRhdGUpKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpznlKjmiLfmsqHmnInphY3nva4gYXBwZWFyLmFuaW1hdGlvbu+8jOWwsem7mOiupOi1sOaVtOS9k+WKqOeUu1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICAgICAgdmFyIHR5cGUgPSB0aGlzLnR5cGU7XG4gICAgICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuY29vcmRpbmF0ZTtcbiAgICAgICAgICAgIHZhciBhbmltYXRlQ2ZnID0gdXRpbF8xLmdldCh0aGlzLmFuaW1hdGVPcHRpb24sICdhcHBlYXInKTtcbiAgICAgICAgICAgIHZhciB5U2NhbGUgPSB0aGlzLmdldFlTY2FsZSgpO1xuICAgICAgICAgICAgdmFyIHlNaW5Qb2ludCA9IGNvb3JkaW5hdGUuY29udmVydCh7XG4gICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICB5OiB5U2NhbGUuc2NhbGUodGhpcy5nZXRZTWluVmFsdWUoKSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFuaW1hdGVfMS5kb0dyb3VwQXBwZWFyQW5pbWF0ZShjb250YWluZXIsIGFuaW1hdGVDZmcsIHR5cGUsIGNvb3JkaW5hdGUsIHlNaW5Qb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5re75YqgIGxhYmVsXG4gICAgICAgIGlmICh0aGlzLmxhYmVsT3B0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckxhYmVscyh1dGlsXzEuZmxhdHRlbihtYXBwaW5nQXJyYXkpLCBpc1VwZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXRhQXJyYXkgPSBtYXBwaW5nQXJyYXk7XG4gICAgICAgIC8vIOmUgOavgeiiq+WIoOmZpOeahCBlbGVtZW50c1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmxhc3RFbGVtZW50c01hcCwgZnVuY3Rpb24gKGRlbGV0ZWRFbGVtZW50KSB7XG4gICAgICAgICAgICAvLyDmm7TmlrDliqjnlLvphY3nva7vvIznlKjmiLfmnInlj6/og73lnKjmm7TmlrDkuYvliY3mnInlr7nliqjnlLvov5vooYzphY3nva7mk43kvZxcbiAgICAgICAgICAgIGRlbGV0ZWRFbGVtZW50LmFuaW1hdGUgPSBfdGhpcy5hbmltYXRlT3B0aW9uO1xuICAgICAgICAgICAgZGVsZXRlZEVsZW1lbnQuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sYXN0RWxlbWVudHNNYXAgPSB0aGlzLmVsZW1lbnRzTWFwO1xuICAgICAgICAvLyDnvJPlrZjvvIznlKjkuo7mm7TmlrBcbiAgICAgICAgdGhpcy5sYXN0QXR0cmlidXRlT3B0aW9uID0gdHNsaWJfMS5fX2Fzc2lnbih7fSwgdGhpcy5hdHRyaWJ1dGVPcHRpb24pO1xuICAgICAgICBpZiAodGhpcy52aXNpYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgLy8g55So5oi35Zyo5Yid5aeL5YyW55qE5pe25YCZ5aOw5piOIHZpc2libGU6IGZhbHNlXG4gICAgICAgICAgICB0aGlzLmNoYW5nZVZpc2libGUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuIXnqbrlvZPliY0gR2VvbWV0cnnvvIzphY3nva7pobnku43kv53nlZnvvIzkvYbmmK/lhoXpg6jliJvlu7rnmoTlr7nosaHlhajpg6jmuIXnqbrjgIJcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIGNvbnRhaW5lciA9IF9hLmNvbnRhaW5lciwgZ2VvbWV0cnlMYWJlbCA9IF9hLmdlb21ldHJ5TGFiZWwsIG9mZnNjcmVlbkdyb3VwID0gX2Eub2Zmc2NyZWVuR3JvdXA7XG4gICAgICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChnZW9tZXRyeUxhYmVsKSB7XG4gICAgICAgICAgICBnZW9tZXRyeUxhYmVsLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9mZnNjcmVlbkdyb3VwKSB7XG4gICAgICAgICAgICBvZmZzY3JlZW5Hcm91cC5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWxnuaAp+aBouWkjeiHs+WHuuWOgueKtuaAgVxuICAgICAgICB0aGlzLnNjYWxlRGVmcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVzID0ge307XG4gICAgICAgIHRoaXMuc2NhbGVzID0ge307XG4gICAgICAgIHRoaXMuZWxlbWVudHNNYXAgPSB7fTtcbiAgICAgICAgdGhpcy5sYXN0RWxlbWVudHNNYXAgPSB7fTtcbiAgICAgICAgdGhpcy5lbGVtZW50cyA9IFtdO1xuICAgICAgICB0aGlzLmFkanVzdHMgPSB7fTtcbiAgICAgICAgdGhpcy5kYXRhQXJyYXkgPSBudWxsO1xuICAgICAgICB0aGlzLmJlZm9yZU1hcHBpbmdEYXRhID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0QXR0cmlidXRlT3B0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmRlZmF1bHRTaXplID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmlkRmllbGRzID0gW107XG4gICAgICAgIHRoaXMuZ3JvdXBTY2FsZXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuaGFzU29ydGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNDb29yZGluYXRlQ2hhbmdlZCA9IGZhbHNlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZSA5q+BIEdlb21ldHJ5IOWunuS+i+OAglxuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lcjtcbiAgICAgICAgY29udGFpbmVyLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMub2Zmc2NyZWVuR3JvdXApIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2NyZWVuR3JvdXAucmVtb3ZlKHRydWUpO1xuICAgICAgICAgICAgdGhpcy5vZmZzY3JlZW5Hcm91cCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZ2VvbWV0cnlMYWJlbCkge1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeUxhYmVsLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuZ2VvbWV0cnlMYWJlbCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aGVtZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zaGFwZUZhY3RvcnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5Yaz5a6a5YiG57uE55qE5Zu+5b2i5bGe5oCn5a+55bqU55qEIHNjYWxlIOWunuS+i+OAglxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldEdyb3VwU2NhbGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cFNjYWxlcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOagueaNruWQjeWtl+iOt+WPluWbvuW9ouWxnuaAp+WunuS+i+OAglxuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW25hbWVdO1xuICAgIH07XG4gICAgLyoqIOiOt+WPliB4IOi9tOWvueW6lOeahCBzY2FsZSDlrp7kvovjgIIgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0WFNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoJ3Bvc2l0aW9uJykuc2NhbGVzWzBdO1xuICAgIH07XG4gICAgLyoqIOiOt+WPliB5IOi9tOWvueW6lOeahCBzY2FsZSDlrp7kvovjgIIgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0WVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoJ3Bvc2l0aW9uJykuc2NhbGVzWzFdO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5Yaz5a6a5YiG57uE55qE5Zu+5b2i5bGe5oCn5a6e5L6L44CCXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldEdyb3VwQXR0cmlidXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmF0dHJpYnV0ZXMsIGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICAgICAgICBpZiAoY29uc3RhbnRfMS5HUk9VUF9BVFRSUy5pbmNsdWRlcyhhdHRyLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcnN0LnB1c2goYXR0cik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgLyoqIOiOt+WPluWbvuW9ouWxnuaAp+m7mOiupOeahOaYoOWwhOWAvOOAgiAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5nZXREZWZhdWx0VmFsdWUgPSBmdW5jdGlvbiAoYXR0ck5hbWUpIHtcbiAgICAgICAgdmFyIHZhbHVlO1xuICAgICAgICB2YXIgYXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKTtcbiAgICAgICAgaWYgKGF0dHIgJiYgdXRpbF8xLmlzRW1wdHkoYXR0ci5zY2FsZXMpKSB7XG4gICAgICAgICAgICAvLyDojrflj5bmmKDlsIToh7PluLjph4/nmoTlgLxcbiAgICAgICAgICAgIHZhbHVlID0gYXR0ci52YWx1ZXNbMF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W6K+l5pWw5o2u5Y+R55Sf5Zu+5b2i5pig5bCE5ZCO5a+55bqU55qEIEF0dHJpYnV0ZSDlm77lvaLnqbrpl7TmlbDmja7jgIJcbiAgICAgKiBAcGFyYW0gYXR0ciBBdHRyaWJ1dGUg5Zu+5b2i5bGe5oCn5a6e5L6L44CCXG4gICAgICogQHBhcmFtIG9iaiDpnIDopoHov5vooYzmmKDlsITnmoTljp/lp4vmlbDmja7jgIJcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRBdHRyaWJ1dGVWYWx1ZXMgPSBmdW5jdGlvbiAoYXR0ciwgb2JqKSB7XG4gICAgICAgIHZhciBwYXJhbXMgPSBbXTtcbiAgICAgICAgdmFyIHNjYWxlcyA9IGF0dHIuc2NhbGVzO1xuICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aF8yID0gc2NhbGVzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGhfMjsgaW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIHNjYWxlID0gc2NhbGVzW2luZGV4XTtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IHNjYWxlLmZpZWxkO1xuICAgICAgICAgICAgaWYgKHNjYWxlLmlzSWRlbnRpdHkpIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMucHVzaChzY2FsZS52YWx1ZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zLnB1c2gob2JqW2ZpZWxkXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF0dHIubWFwcGluZy5hcHBseShhdHRyLCBwYXJhbXMpO1xuICAgIH07XG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldEFkanVzdCA9IGZ1bmN0aW9uIChhZGp1c3RUeXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkanVzdHNbYWRqdXN0VHlwZV07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5Ygc2hhcGUg5a+55bqU55qEIG1hcmtlciDmoLflvI/jgIJcbiAgICAgKiBAcGFyYW0gc2hhcGVOYW1lIHNoYXBlIOWFt+S9k+WQjeWtl1xuICAgICAqIEBwYXJhbSBjZmcgbWFya2VyIOS/oeaBr1xuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldFNoYXBlTWFya2VyID0gZnVuY3Rpb24gKHNoYXBlTmFtZSwgY2ZnKSB7XG4gICAgICAgIHZhciBzaGFwZUZhY3RvcnkgPSB0aGlzLmdldFNoYXBlRmFjdG9yeSgpO1xuICAgICAgICByZXR1cm4gc2hhcGVGYWN0b3J5LmdldE1hcmtlcihzaGFwZU5hbWUsIGNmZyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmoLnmja7kuIDlrprnmoTop4TliJnmn6Xmib4gR2VvbWV0cnkg55qEIEVsZW1lbnRz44CCXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogZ2V0RWxlbWVudHNCeSgoZWxlbWVudCkgPT4ge1xuICAgICAqICAgY29uc3QgZGF0YSA9IGVsZW1lbnQuZ2V0RGF0YSgpO1xuICAgICAqXG4gICAgICogICByZXR1cm4gZGF0YS5hID09PSAnYSc7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29uZGl0aW9uIOWumuS5ieafpeaJvuinhOWImeeahOWbnuiwg+WHveaVsOOAglxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldEVsZW1lbnRzQnkgPSBmdW5jdGlvbiAoY29uZGl0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbmRpdGlvbihlbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmlbDmja7lr7nlupTnmoTllK/kuIAgaWTjgIJcbiAgICAgKiBAcGFyYW0gZGF0YSBFbGVtZW50IOWvueW6lOeahOe7mOWItuaVsOaNrlxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldEVsZW1lbnRJZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIGRhdGEgPSB1dGlsXzEuaXNBcnJheShkYXRhKSA/IGRhdGFbMF0gOiBkYXRhO1xuICAgICAgICB2YXIgb3JpZ2luRGF0YSA9IGRhdGFbY29uc3RhbnRfMS5GSUVMRF9PUklHSU5dO1xuICAgICAgICAvLyDlpoLmnpznlKjmiLflo7DmmI7kuobkvb/nlKjlk6rkupvlrZfmrrXkvZzkuLogaWQg5YC8XG4gICAgICAgIGlmICh0aGlzLmlkRmllbGRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRJZCA9IG9yaWdpbkRhdGFbdGhpcy5pZEZpZWxkc1swXV07XG4gICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDE7IGluZGV4IDwgdGhpcy5pZEZpZWxkcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50SWQgKz0gJy0nICsgb3JpZ2luRGF0YVt0aGlzLmlkRmllbGRzW2luZGV4XV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudElkO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlO1xuICAgICAgICB2YXIgeFNjYWxlID0gdGhpcy5nZXRYU2NhbGUoKTtcbiAgICAgICAgdmFyIHlTY2FsZSA9IHRoaXMuZ2V0WVNjYWxlKCk7XG4gICAgICAgIHZhciB4RmllbGQgPSB4U2NhbGUuZmllbGQgfHwgJ3gnO1xuICAgICAgICB2YXIgeUZpZWxkID0geVNjYWxlLmZpZWxkIHx8ICd5JztcbiAgICAgICAgdmFyIHlWYWwgPSBvcmlnaW5EYXRhW3lGaWVsZF07XG4gICAgICAgIHZhciB4VmFsO1xuICAgICAgICBpZiAoeFNjYWxlLnR5cGUgPT09ICdpZGVudGl0eScpIHtcbiAgICAgICAgICAgIHhWYWwgPSB4U2NhbGUudmFsdWVzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgeFZhbCA9IG9yaWdpbkRhdGFbeEZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaWQ7XG4gICAgICAgIGlmICh0eXBlID09PSAnaW50ZXJ2YWwnIHx8IHR5cGUgPT09ICdzY2hlbWEnKSB7XG4gICAgICAgICAgICBpZCA9IHhWYWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2xpbmUnIHx8IHR5cGUgPT09ICdhcmVhJyB8fCB0eXBlID09PSAncGF0aCcpIHtcbiAgICAgICAgICAgIGlkID0gdHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlkID0geFZhbCArIFwiLVwiICsgeVZhbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZ3JvdXBTY2FsZXMgPSB0aGlzLmdyb3VwU2NhbGVzO1xuICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aF8zID0gZ3JvdXBTY2FsZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aF8zOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgZ3JvdXBTY2FsZSA9IGdyb3VwU2NhbGVzW2luZGV4XTtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IGdyb3VwU2NhbGUuZmllbGQ7XG4gICAgICAgICAgICBpZCA9IGlkICsgXCItXCIgKyBvcmlnaW5EYXRhW2ZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICAvLyDnlKjmiLflnKjov5vooYwgZG9kZ2Ug57G75Z6L55qEIGFkanVzdCDosIPmlbTnmoTml7blgJnorr7nva7kuoYgZG9kZ2VCeSDlsZ7mgKdcbiAgICAgICAgdmFyIGRvZGdlQWRqdXN0ID0gdGhpcy5nZXRBZGp1c3QoJ2RvZGdlJyk7XG4gICAgICAgIGlmIChkb2RnZUFkanVzdCkge1xuICAgICAgICAgICAgdmFyIGRvZGdlQnkgPSBkb2RnZUFkanVzdC5kb2RnZUJ5O1xuICAgICAgICAgICAgaWYgKGRvZGdlQnkpIHtcbiAgICAgICAgICAgICAgICBpZCA9IGlkICsgXCItXCIgKyBvcmlnaW5EYXRhW2RvZGdlQnldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmdldEFkanVzdCgnaml0dGVyJykpIHtcbiAgICAgICAgICAgIGlkID0gaWQgKyBcIi1cIiArIGRhdGEueCArIFwiLVwiICsgZGF0YS55O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluaJgOaciemcgOimgeWIm+W7uiBzY2FsZSDnmoTlrZfmrrXlkI3np7DjgIJcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0U2NhbGVGaWVsZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmaWVsZHMgPSBbXTtcbiAgICAgICAgdmFyIHRtcE1hcCA9IHt9O1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBhdHRyaWJ1dGVPcHRpb24gPSBfYS5hdHRyaWJ1dGVPcHRpb24sIGxhYmVsT3B0aW9uID0gX2EubGFiZWxPcHRpb24sIHRvb2x0aXBPcHRpb24gPSBfYS50b29sdGlwT3B0aW9uO1xuICAgICAgICAvLyDojrflj5blm77lvaLlsZ7mgKfkuIrnmoQgZmllbGRzXG4gICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZVR5cGUgaW4gYXR0cmlidXRlT3B0aW9uKSB7XG4gICAgICAgICAgICBpZiAoYXR0cmlidXRlT3B0aW9uLmhhc093blByb3BlcnR5KGF0dHJpYnV0ZVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVhY2hPcHQgPSBhdHRyaWJ1dGVPcHRpb25bYXR0cmlidXRlVHlwZV07XG4gICAgICAgICAgICAgICAgaWYgKGVhY2hPcHQuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlbHBlcl8xLnVuaXEoZWFjaE9wdC5maWVsZHMsIGZpZWxkcywgdG1wTWFwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZWFjaE9wdC52YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g6ICD6JmRIHNpemUoMTApLCBzaGFwZSgnY2lyY2xlJykg562J5Zy65pmvXG4gICAgICAgICAgICAgICAgICAgIGhlbHBlcl8xLnVuaXEoZWFjaE9wdC52YWx1ZXMsIGZpZWxkcywgdG1wTWFwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8g6I635Y+WIGxhYmVsIOS4iueahOWtl+autVxuICAgICAgICBpZiAobGFiZWxPcHRpb24gJiYgbGFiZWxPcHRpb24uZmllbGRzKSB7XG4gICAgICAgICAgICBoZWxwZXJfMS51bmlxKGxhYmVsT3B0aW9uLmZpZWxkcywgZmllbGRzLCB0bXBNYXApO1xuICAgICAgICB9XG4gICAgICAgIC8vIOiOt+WPliB0b29sdGlwIOS4iueahOWtl+autVxuICAgICAgICBpZiAodXRpbF8xLmlzT2JqZWN0KHRvb2x0aXBPcHRpb24pICYmIHRvb2x0aXBPcHRpb24uZmllbGRzKSB7XG4gICAgICAgICAgICBoZWxwZXJfMS51bmlxKHRvb2x0aXBPcHRpb24uZmllbGRzLCBmaWVsZHMsIHRtcE1hcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYvuekuuaIluiAhemakOiXjyBnZW9tZXRyeeOAglxuICAgICAqIEBwYXJhbSB2aXNpYmxlXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmNoYW5nZVZpc2libGUgPSBmdW5jdGlvbiAodmlzaWJsZSkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNoYW5nZVZpc2libGUuY2FsbCh0aGlzLCB2aXNpYmxlKTtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50cztcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwLCBsZW5ndGhfNCA9IGVsZW1lbnRzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGhfNDsgaW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBlbGVtZW50c1tpbmRleF07XG4gICAgICAgICAgICBlbGVtZW50LmNoYW5nZVZpc2libGUodmlzaWJsZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnNob3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmxhYmVsc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMubGFiZWxzQ29udGFpbmVyLnNob3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmxhYmVsc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMubGFiZWxzQ29udGFpbmVyLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5b2T5YmN6YWN572u5Lit55qE5omA5pyJ5YiG57uEICYg5YiG57G755qE5a2X5q6144CCXG4gICAgICogQHJldHVybiBmaWVsZHMgc3RyaW5nW11cbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0R3JvdXBGaWVsZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cEZpZWxkcyA9IFtdO1xuICAgICAgICB2YXIgdG1wTWFwID0ge307IC8vIOeUqOS6juWOu+mHjei/h+a7pFxuICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aF81ID0gY29uc3RhbnRfMS5HUk9VUF9BVFRSUy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoXzU7IGluZGV4KyspIHtcbiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVOYW1lID0gY29uc3RhbnRfMS5HUk9VUF9BVFRSU1tpbmRleF07XG4gICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5hdHRyaWJ1dGVPcHRpb25bYXR0cmlidXRlTmFtZV07XG4gICAgICAgICAgICBpZiAoY2ZnICYmIGNmZy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICBoZWxwZXJfMS51bmlxKGNmZy5maWVsZHMsIGdyb3VwRmllbGRzLCB0bXBNYXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBncm91cEZpZWxkcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+W+l+WbvuW9oueahCB4IHkg5a2X5q6144CCXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldFhZRmllbGRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmF0dHJpYnV0ZU9wdGlvbi5wb3NpdGlvbi5maWVsZHMsIHggPSBfYVswXSwgeSA9IF9hWzFdO1xuICAgICAgICByZXR1cm4gW3gsIHldO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W6K+lIEdlb21ldHJ5IOS4i+aJgOacieeUn+aIkOeahCBzaGFwZXPjgIJcbiAgICAgKiBAcmV0dXJucyBzaGFwZXNcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0U2hhcGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50cy5tYXAoZnVuY3Rpb24gKGVsZW1lbnQpIHsgcmV0dXJuIGVsZW1lbnQuc2hhcGU7IH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W6Jma5oufIEdyb3Vw44CCXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0T2Zmc2NyZWVuR3JvdXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5vZmZzY3JlZW5Hcm91cCkge1xuICAgICAgICAgICAgdmFyIEdyb3VwQ3RvciA9IHRoaXMuY29udGFpbmVyLmdldEdyb3VwQmFzZSgpOyAvLyDojrflj5bliIbnu4TnmoTmnoTpgKDlh73mlbBcbiAgICAgICAgICAgIHRoaXMub2Zmc2NyZWVuR3JvdXAgPSBuZXcgR3JvdXBDdG9yKHt9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5vZmZzY3JlZW5Hcm91cDtcbiAgICB9O1xuICAgIC8vIOWvueaVsOaNrui/m+ihjOaOkuW6j1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5zb3J0ID0gZnVuY3Rpb24gKG1hcHBpbmdBcnJheSkge1xuICAgICAgICBpZiAoIXRoaXMuaGFzU29ydGVkKSB7XG4gICAgICAgICAgICAvLyDmnKrlj5HnlJ/ov4fmjpLluo9cbiAgICAgICAgICAgIHZhciB4U2NhbGVfMSA9IHRoaXMuZ2V0WFNjYWxlKCk7XG4gICAgICAgICAgICB2YXIgeEZpZWxkXzEgPSB4U2NhbGVfMS5maWVsZDtcbiAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBtYXBwaW5nQXJyYXkubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW1BcnIgPSBtYXBwaW5nQXJyYXlbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGl0ZW1BcnIuc29ydChmdW5jdGlvbiAob2JqMSwgb2JqMikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geFNjYWxlXzEudHJhbnNsYXRlKG9iajFbY29uc3RhbnRfMS5GSUVMRF9PUklHSU5dW3hGaWVsZF8xXSkgLSB4U2NhbGVfMS50cmFuc2xhdGUob2JqMltjb25zdGFudF8xLkZJRUxEX09SSUdJTl1beEZpZWxkXzFdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhhc1NvcnRlZCA9IHRydWU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDosIPmlbTluqbph4/ojIPlm7TjgILkuLvopoHpkojlr7nlj5HnlJ/lsYLlj6Dku6Xlj4rkuIDkupvnibnmrorpnIDmsYLnmoQgR2VvbWV0cnnvvIzmr5TlpoIgSW50ZXJ2YWwg5LiL55qE5p+x54q25Zu+IFkg6L206buY6K6k5LuOIDAg5byA5aeL44CCXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmFkanVzdFNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeVNjYWxlID0gdGhpcy5nZXRZU2NhbGUoKTtcbiAgICAgICAgLy8g5aaC5p6c5pWw5o2u5Y+R55Sf6L+HIHN0YWNrIGFkanVzdO+8jOmcgOimgeiwg+aVtOS4iyB5U2NhbGUg55qE5pWw5o2u6IyD5Zu0XG4gICAgICAgIGlmICh5U2NhbGUgJiYgdGhpcy5nZXRBZGp1c3QoJ3N0YWNrJykpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlU3RhY2tSYW5nZSh5U2NhbGUsIHRoaXMuYmVmb3JlTWFwcGluZ0RhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blvZPliY0gR2VvbWV0cnkg5a+55bqU55qEIFNoYXBlIOW3peWOguWunuS+i+OAglxuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRTaGFwZUZhY3RvcnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzaGFwZVR5cGUgPSB0aGlzLnNoYXBlVHlwZTtcbiAgICAgICAgaWYgKCFiYXNlXzIuZ2V0U2hhcGVGYWN0b3J5KHNoYXBlVHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuc2hhcGVGYWN0b3J5KSB7XG4gICAgICAgICAgICB0aGlzLnNoYXBlRmFjdG9yeSA9IHV0aWxfMS5jbG9uZShiYXNlXzIuZ2V0U2hhcGVGYWN0b3J5KHNoYXBlVHlwZSkpOyAvLyDpmLLmraLlpJrkuKogdmlldyDlhbHkuqvkuIDkuKogc2hhcGVGYWN0b3J5IOWunuS+i++8jOWvvOiHtCBjb29yZGluYXRlIOiiq+evoeaUuVxuICAgICAgICB9XG4gICAgICAgIC8vIOWboOS4uui/memHjOe8k+WtmOS6hiBzaGFwZUZhY3RvcnnvvIzkvYbmmK/lpJbpg6jlj6/og73kvJrlj5jmm7QgY29vcmRpbmF0Ze+8jOWvvOiHtOaXoOazlemHjeaWsOiuvue9ruWIsCBzaGFwZUZhY3Rvcnkg5LitXG4gICAgICAgIHRoaXMuc2hhcGVGYWN0b3J5LmNvb3JkaW5hdGUgPSB0aGlzLmNvb3JkaW5hdGU7XG4gICAgICAgIC8vIHRoZW1lIOWOn+WboOWQjOS4ilxuICAgICAgICB0aGlzLnNoYXBlRmFjdG9yeS50aGVtZSA9IHRoaXMudGhlbWUuZ2VvbWV0cmllc1tzaGFwZVR5cGVdIHx8IHt9O1xuICAgICAgICByZXR1cm4gdGhpcy5zaGFwZUZhY3Rvcnk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmr4/kuKogU2hhcGUg5a+55bqU55qE5YWz6ZSu54K55pWw5o2u44CCXG4gICAgICogQHBhcmFtIG9iaiDnu4/ov4fliIbnu4QgLT4g5pWw5a2X5YyWIC0+IGFkanVzdCDosIPmlbTlkI7nmoTmlbDmja7orrDlvZVcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5jcmVhdGVTaGFwZVBvaW50c0NmZyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgdmFyIHhTY2FsZSA9IHRoaXMuZ2V0WFNjYWxlKCk7XG4gICAgICAgIHZhciB5U2NhbGUgPSB0aGlzLmdldFlTY2FsZSgpO1xuICAgICAgICB2YXIgeCA9IHRoaXMubm9ybWFsaXplVmFsdWVzKG9ialt4U2NhbGUuZmllbGRdLCB4U2NhbGUpO1xuICAgICAgICB2YXIgeTsgLy8g5a2Y5Zyo5rKh5pyJIHkg55qE5oOF5Ya1XG4gICAgICAgIGlmICh5U2NhbGUpIHtcbiAgICAgICAgICAgIHkgPSB0aGlzLm5vcm1hbGl6ZVZhbHVlcyhvYmpbeVNjYWxlLmZpZWxkXSwgeVNjYWxlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHkgPSBvYmoueSA/IG9iai55IDogMC4xO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgIHkwOiB5U2NhbGUgPyB5U2NhbGUuc2NhbGUodGhpcy5nZXRZTWluVmFsdWUoKSkgOiB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDliJvlu7ogRWxlbWVudCDlrp7kvovjgIJcbiAgICAgKiBAcGFyYW0gbWFwcGluZ0RhdHVtIEVsZW1lbnQg5a+55bqU55qE57uY5Yi25pWw5o2uXG4gICAgICogQHBhcmFtIFtpc1VwZGF0ZV0g5piv5ZCm5aSE5LqO5pu05paw6Zi25q61XG4gICAgICogQHJldHVybnMgZWxlbWVudCDov5Tlm57liJvlu7rnmoQgRWxlbWVudCDlrp7kvotcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uIChtYXBwaW5nRGF0dW0sIGlzVXBkYXRlKSB7XG4gICAgICAgIGlmIChpc1VwZGF0ZSA9PT0gdm9pZCAwKSB7IGlzVXBkYXRlID0gZmFsc2U7IH1cbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICB2YXIgc2hhcGVDZmcgPSB0aGlzLmdldERyYXdDZmcobWFwcGluZ0RhdHVtKTsgLy8g6I635Y+W57uY5Yi25Zu+5b2i55qE6YWN572u5L+h5oGvXG4gICAgICAgIHZhciBzaGFwZUZhY3RvcnkgPSB0aGlzLmdldFNoYXBlRmFjdG9yeSgpO1xuICAgICAgICB2YXIgZWxlbWVudCA9IG5ldyBlbGVtZW50XzEuZGVmYXVsdCh7XG4gICAgICAgICAgICBzaGFwZUZhY3Rvcnk6IHNoYXBlRmFjdG9yeSxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxuICAgICAgICAgICAgb2Zmc2NyZWVuR3JvdXA6IHRoaXMuZ2V0T2Zmc2NyZWVuR3JvdXAoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGVsZW1lbnQuYW5pbWF0ZSA9IHRoaXMuYW5pbWF0ZU9wdGlvbjtcbiAgICAgICAgZWxlbWVudC5nZW9tZXRyeSA9IHRoaXM7XG4gICAgICAgIGVsZW1lbnQuZHJhdyhzaGFwZUNmZywgaXNVcGRhdGUpOyAvLyDnu5jliLZcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmr4/mnaHmlbDmja7lr7nlupTnmoTlm77lvaLnu5jliLbmlbDmja7jgIJcbiAgICAgKiBAcGFyYW0gbWFwcGluZ0RhdHVtIOaYoOWwhOWQjueahOaVsOaNrlxuICAgICAqIEByZXR1cm5zIGRyYXcgY2ZnXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldERyYXdDZmcgPSBmdW5jdGlvbiAobWFwcGluZ0RhdHVtKSB7XG4gICAgICAgIHZhciBvcmlnaW5EYXRhID0gbWFwcGluZ0RhdHVtW2NvbnN0YW50XzEuRklFTERfT1JJR0lOXTsgLy8g5Y6f5aeL5pWw5o2uXG4gICAgICAgIHZhciBjZmcgPSB7XG4gICAgICAgICAgICBtYXBwaW5nRGF0YTogbWFwcGluZ0RhdHVtLFxuICAgICAgICAgICAgZGF0YTogb3JpZ2luRGF0YSxcbiAgICAgICAgICAgIHg6IG1hcHBpbmdEYXR1bS54LFxuICAgICAgICAgICAgeTogbWFwcGluZ0RhdHVtLnksXG4gICAgICAgICAgICBjb2xvcjogbWFwcGluZ0RhdHVtLmNvbG9yLFxuICAgICAgICAgICAgc2l6ZTogbWFwcGluZ0RhdHVtLnNpemUsXG4gICAgICAgICAgICBpc0luQ2lyY2xlOiB0aGlzLmNvb3JkaW5hdGUuaXNQb2xhcixcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHNoYXBlTmFtZSA9IG1hcHBpbmdEYXR1bS5zaGFwZTtcbiAgICAgICAgaWYgKCFzaGFwZU5hbWUgJiYgdGhpcy5nZXRTaGFwZUZhY3RvcnkoKSkge1xuICAgICAgICAgICAgc2hhcGVOYW1lID0gdGhpcy5nZXRTaGFwZUZhY3RvcnkoKS5kZWZhdWx0U2hhcGVUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGNmZy5zaGFwZSA9IHNoYXBlTmFtZTtcbiAgICAgICAgLy8g6I635Y+W6buY6K6k5qC35byPXG4gICAgICAgIHZhciB0aGVtZSA9IHRoaXMudGhlbWUuZ2VvbWV0cmllc1t0aGlzLnNoYXBlVHlwZV07XG4gICAgICAgIGNmZy5kZWZhdWx0U3R5bGUgPSB1dGlsXzEuZ2V0KHRoZW1lLCBbc2hhcGVOYW1lLCAnZGVmYXVsdCddLCB7fSkuc3R5bGU7XG4gICAgICAgIHZhciBzdHlsZU9wdGlvbiA9IHRoaXMuc3R5bGVPcHRpb247XG4gICAgICAgIGlmIChzdHlsZU9wdGlvbikge1xuICAgICAgICAgICAgY2ZnLnN0eWxlID0gdGhpcy5nZXRTdHlsZUNmZyhzdHlsZU9wdGlvbiwgb3JpZ2luRGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZ2VuZXJhdGVQb2ludHMpIHtcbiAgICAgICAgICAgIGNmZy5wb2ludHMgPSBtYXBwaW5nRGF0dW0ucG9pbnRzO1xuICAgICAgICAgICAgY2ZnLm5leHRQb2ludHMgPSBtYXBwaW5nRGF0dW0ubmV4dFBvaW50cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2ZnO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5Yib5bu65omA5pyJ55qEIEVsZW1lbnRz44CCXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhXG4gICAgICogQHBhcmFtIFtpc1VwZGF0ZV1cbiAgICAgKiBAcmV0dXJucyBlbGVtZW50c1xuICAgICAqL1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50cyA9IGZ1bmN0aW9uIChtYXBwaW5nRGF0YSwgaW5kZXgsIGlzVXBkYXRlKSB7XG4gICAgICAgIGlmIChpc1VwZGF0ZSA9PT0gdm9pZCAwKSB7IGlzVXBkYXRlID0gZmFsc2U7IH1cbiAgICAgICAgdmFyIF9hID0gdGhpcywgbGFzdEVsZW1lbnRzTWFwID0gX2EubGFzdEVsZW1lbnRzTWFwLCBlbGVtZW50c01hcCA9IF9hLmVsZW1lbnRzTWFwLCBlbGVtZW50cyA9IF9hLmVsZW1lbnRzO1xuICAgICAgICBmb3IgKHZhciBzdWJJbmRleCA9IDAsIGxlbmd0aF82ID0gbWFwcGluZ0RhdGEubGVuZ3RoOyBzdWJJbmRleCA8IGxlbmd0aF82OyBzdWJJbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgbWFwcGluZ0RhdHVtID0gbWFwcGluZ0RhdGFbc3ViSW5kZXhdO1xuICAgICAgICAgICAgdmFyIGlkID0gdGhpcy5nZXRFbGVtZW50SWQobWFwcGluZ0RhdHVtKTtcbiAgICAgICAgICAgIGlmIChlbGVtZW50c01hcFtpZF0pIHtcbiAgICAgICAgICAgICAgICAvLyDlrZjlnKjph43lpI3mlbDmja7vvIzliJnmoLnmja7lho3moLnmja4gaW5kZXgg6L+b6KGM5Yy65YiGXG4gICAgICAgICAgICAgICAgaWQgPSBpZCArIFwiLVwiICsgaW5kZXggKyBcIi1cIiArIHN1YkluZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGxhc3RFbGVtZW50c01hcFtpZF07XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIC8vIOWIm+W7uuaWsOeahCBlbGVtZW50XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5jcmVhdGVFbGVtZW50KG1hcHBpbmdEYXR1bSwgaXNVcGRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZWxlbWVudCDlt7Lnu4/liJvlu7pcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNoYXBlQ2ZnID0gdGhpcy5nZXREcmF3Q2ZnKG1hcHBpbmdEYXR1bSk7XG4gICAgICAgICAgICAgICAgdmFyIHByZVNoYXBlQ2ZnID0gcmVzdWx0LmdldE1vZGVsKCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNDb29yZGluYXRlQ2hhbmdlZCB8fCBpc19tb2RlbF9jaGFuZ2VfMS5pc01vZGVsQ2hhbmdlKGN1cnJlbnRTaGFwZUNmZywgcHJlU2hhcGVDZmcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hbmltYXRlID0gdGhpcy5hbmltYXRlT3B0aW9uO1xuICAgICAgICAgICAgICAgICAgICAvLyDpgJrov4fnu5jliLbmlbDmja7nmoTlj5jmm7TmnaXliKTmlq3mmK/lkKbpnIDopoHmm7TmlrDvvIzlm6DkuLrnlKjmiLfmnInlj6/og73kvJrkv67mlLnlm77lvaLlsZ7mgKfmmKDlsIRcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnVwZGF0ZShjdXJyZW50U2hhcGVDZmcpOyAvLyDmm7TmlrDlr7nlupTnmoQgZWxlbWVudFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgbGFzdEVsZW1lbnRzTWFwW2lkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgICAgIGVsZW1lbnRzTWFwW2lkXSA9IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWxlbWVudHM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmuLLmn5PnmoQgbGFiZWwg57G75Z6L44CCXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldExhYmVsVHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcywgbGFiZWxPcHRpb24gPSBfYS5sYWJlbE9wdGlvbiwgY29vcmRpbmF0ZSA9IF9hLmNvb3JkaW5hdGUsIHR5cGUgPSBfYS50eXBlO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZVR5cGUgPSBjb29yZGluYXRlLnR5cGU7XG4gICAgICAgIHZhciBsYWJlbFR5cGUgPSB1dGlsXzEuZ2V0KGxhYmVsT3B0aW9uLCBbJ2NmZycsICd0eXBlJ10pO1xuICAgICAgICBpZiAoIWxhYmVsVHlwZSkge1xuICAgICAgICAgICAgLy8g55So5oi35pyq5a6a5LmJ77yM5YiZ6L+b6KGM6buY6K6k55qE6YC76L6RXG4gICAgICAgICAgICBpZiAoY29vcmRpbmF0ZVR5cGUgPT09ICdwb2xhcicpIHtcbiAgICAgICAgICAgICAgICAvLyDmnoHlnZDmoIfkuIvkvb/nlKjpgJrnlKjnmoTmnoHlnZDmoIfmlofmnKxcbiAgICAgICAgICAgICAgICBsYWJlbFR5cGUgPSAncG9sYXInO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29vcmRpbmF0ZVR5cGUgPT09ICd0aGV0YScpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGV0YSDlnZDmoIfns7vkuIvkvb/nlKjppbzlm77mlofmnKxcbiAgICAgICAgICAgICAgICBsYWJlbFR5cGUgPSAncGllJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlcnZhbCcgfHwgdHlwZSA9PT0gJ3BvbHlnb24nKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxUeXBlID0gJ2ludGVydmFsJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxhYmVsVHlwZSA9ICdiYXNlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbGFiZWxUeXBlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+WIFkg6L205LiK55qE5pyA5bCP5YC844CCXG4gICAgICovXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldFlNaW5WYWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHlTY2FsZSA9IHRoaXMuZ2V0WVNjYWxlKCk7XG4gICAgICAgIHZhciBtaW4gPSB5U2NhbGUubWluLCBtYXggPSB5U2NhbGUubWF4O1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIGlmIChtaW4gPj0gMCkge1xuICAgICAgICAgICAgdmFsdWUgPSBtaW47XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobWF4IDw9IDApIHtcbiAgICAgICAgICAgIC8vIOW9k+WAvOWFqOS9jeS6jui0n+WMuumXtOaXtu+8jOmcgOimgeS/neivgSB5bWluIOWcqOWMuuWfn+WGhe+8jOS4jeWPr+S4uiAwXG4gICAgICAgICAgICB2YWx1ZSA9IG1heDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgICAvLyDliJvlu7rlm77lvaLlsZ7mgKfnm7jlhbPnmoTphY3nva7poblcbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuY3JlYXRlQXR0ck9wdGlvbiA9IGZ1bmN0aW9uIChhdHRyTmFtZSwgZmllbGQsIGNmZykge1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKGZpZWxkKSB8fCB1dGlsXzEuaXNPYmplY3QoZmllbGQpKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzT2JqZWN0KGZpZWxkKSAmJiB1dGlsXzEuaXNFcXVhbChPYmplY3Qua2V5cyhmaWVsZCksIFsndmFsdWVzJ10pKSB7XG4gICAgICAgICAgICAgICAgLy8gc2hhcGUoeyB2YWx1ZXM6IFsgJ2Z1bm5lbCcgXSB9KVxuICAgICAgICAgICAgICAgIHV0aWxfMS5zZXQodGhpcy5hdHRyaWJ1dGVPcHRpb24sIGF0dHJOYW1lLCB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkczogZmllbGQudmFsdWVzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLnNldCh0aGlzLmF0dHJpYnV0ZU9wdGlvbiwgYXR0ck5hbWUsIGZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBhdHRyQ2ZnID0ge307XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKGZpZWxkKSkge1xuICAgICAgICAgICAgICAgIC8vIHNpemUoMylcbiAgICAgICAgICAgICAgICBhdHRyQ2ZnLnZhbHVlcyA9IFtmaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhdHRyQ2ZnLmZpZWxkcyA9IHBhcnNlX2ZpZWxkc18xLnBhcnNlRmllbGRzKGZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjZmcpIHtcbiAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24oY2ZnKSkge1xuICAgICAgICAgICAgICAgICAgICBhdHRyQ2ZnLmNhbGxiYWNrID0gY2ZnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0ckNmZy52YWx1ZXMgPSBjZmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXRpbF8xLnNldCh0aGlzLmF0dHJpYnV0ZU9wdGlvbiwgYXR0ck5hbWUsIGF0dHJDZmcpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuaW5pdEF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIGF0dHJpYnV0ZXMgPSBfYS5hdHRyaWJ1dGVzLCBhdHRyaWJ1dGVPcHRpb24gPSBfYS5hdHRyaWJ1dGVPcHRpb24sIHRoZW1lID0gX2EudGhlbWUsIHNoYXBlVHlwZSA9IF9hLnNoYXBlVHlwZTtcbiAgICAgICAgdGhpcy5ncm91cFNjYWxlcyA9IFtdO1xuICAgICAgICB2YXIgdG1wTWFwID0ge307XG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKGF0dHJUeXBlKSB7XG4gICAgICAgICAgICBpZiAoYXR0cmlidXRlT3B0aW9uLmhhc093blByb3BlcnR5KGF0dHJUeXBlKSkge1xuICAgICAgICAgICAgICAgIHZhciBvcHRpb24gPSBhdHRyaWJ1dGVPcHRpb25bYXR0clR5cGVdO1xuICAgICAgICAgICAgICAgIGlmICghb3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiB2b2lkIDAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGF0dHJDZmcgPSB0c2xpYl8xLl9fYXNzaWduKHt9LCBvcHRpb24pO1xuICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IGF0dHJDZmcuY2FsbGJhY2ssIHZhbHVlcyA9IGF0dHJDZmcudmFsdWVzLCBfYSA9IGF0dHJDZmcuZmllbGRzLCBmaWVsZHMgPSBfYSA9PT0gdm9pZCAwID8gW10gOiBfYTtcbiAgICAgICAgICAgICAgICAvLyDojrflj5bmr4/kuIDkuKrlrZfmrrXlr7nlupTnmoQgc2NhbGVcbiAgICAgICAgICAgICAgICB2YXIgc2NhbGVzID0gZmllbGRzLm1hcChmdW5jdGlvbiAoZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjYWxlID0gX3RoaXMuc2NhbGVzW2ZpZWxkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNjYWxlLmlzQ2F0ZWdvcnkgJiYgIXRtcE1hcFtmaWVsZF0gJiYgY29uc3RhbnRfMS5HUk9VUF9BVFRSUy5pbmNsdWRlcyhhdHRyVHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmdyb3VwU2NhbGVzLnB1c2goc2NhbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdG1wTWFwW2ZpZWxkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNjYWxlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGF0dHJDZmcuc2NhbGVzID0gc2NhbGVzO1xuICAgICAgICAgICAgICAgIGlmIChhdHRyVHlwZSAhPT0gJ3Bvc2l0aW9uJyAmJiBzY2FsZXMubGVuZ3RoID09PSAxICYmIHNjYWxlc1swXS50eXBlID09PSAnaWRlbnRpdHknKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOeUqOaIt+WcqOWbvuW9oumAmumBk+S4iuWjsOaYjuS6huW4uOmHj+Wtl+autSBjb2xvcigncmVkJyksIHNpemUoNSlcbiAgICAgICAgICAgICAgICAgICAgYXR0ckNmZy52YWx1ZXMgPSBzY2FsZXNbMF0udmFsdWVzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICghY2FsbGJhY2sgJiYgIXZhbHVlcykge1xuICAgICAgICAgICAgICAgICAgICAvLyDnlKjmiLfmsqHmnInmjIflrprku7vkvZXop4TliJnvvIzliJnkvb/nlKjpu5jorqTnmoTmmKDlsITop4TliJlcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJUeXBlID09PSAnc2l6ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJDZmcudmFsdWVzID0gdGhlbWUuc2l6ZXM7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXR0clR5cGUgPT09ICdzaGFwZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJDZmcudmFsdWVzID0gdGhlbWUuc2hhcGVzW3NoYXBlVHlwZV0gfHwgW107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXR0clR5cGUgPT09ICdjb2xvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2FsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g5qC55o2u5pWw5YC85Liq5pWw5L2/55So5a+55bqU55qE6Imy5p2/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckNmZy52YWx1ZXMgPSBzY2FsZXNbMF0udmFsdWVzLmxlbmd0aCA8PSAxMCA/IHRoZW1lLmNvbG9yczEwIDogdGhlbWUuY29sb3JzMjA7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyQ2ZnLnZhbHVlcyA9IHRoZW1lLmNvbG9yczEwO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBBdHRyaWJ1dGVDdG9yID0gYXR0cl8xLmdldEF0dHJpYnV0ZShhdHRyVHlwZSk7XG4gICAgICAgICAgICAgICAgYXR0cmlidXRlc1thdHRyVHlwZV0gPSBuZXcgQXR0cmlidXRlQ3RvcihhdHRyQ2ZnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgLy8g6YGN5Y6G5q+P5LiA5LiqIGF0dHJPcHRpb27vvIzlkIToh6rliJvlu7ogQXR0cmlidXRlIOWunuS+i1xuICAgICAgICBmb3IgKHZhciBhdHRyVHlwZSBpbiBhdHRyaWJ1dGVPcHRpb24pIHtcbiAgICAgICAgICAgIHZhciBzdGF0ZV8xID0gX2xvb3BfMShhdHRyVHlwZSk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0YXRlXzEgPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlXzEudmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOWkhOeQhuaVsOaNru+8muWIhue7hCAtPiDmlbDlrZfljJYgLT4gYWRqdXN0IOiwg+aVtFxuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHRoaXMuaGFzU29ydGVkID0gZmFsc2U7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKS5zY2FsZXM7XG4gICAgICAgIHZhciBjYXRlZ29yeVNjYWxlcyA9IHNjYWxlcy5maWx0ZXIoZnVuY3Rpb24gKHNjYWxlKSB7IHJldHVybiBzY2FsZS5pc0NhdGVnb3J5OyB9KTtcbiAgICAgICAgdmFyIGdyb3VwZWRBcnJheSA9IHRoaXMuZ3JvdXBEYXRhKGRhdGEpOyAvLyDmlbDmja7liIbnu4RcbiAgICAgICAgdmFyIGJlZm9yZUFkanVzdCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gZ3JvdXBlZEFycmF5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgc3ViRGF0YSA9IGdyb3VwZWRBcnJheVtpXTtcbiAgICAgICAgICAgIHZhciBhcnIgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBzdWJMZW4gPSBzdWJEYXRhLmxlbmd0aDsgaiA8IHN1YkxlbjsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9yaWdpbkRhdGEgPSBzdWJEYXRhW2pdO1xuICAgICAgICAgICAgICAgIHZhciBpdGVtID0ge307XG4gICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBmb3JpblxuICAgICAgICAgICAgICAgIGZvciAodmFyIGsgaW4gb3JpZ2luRGF0YSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtW2tdID0gb3JpZ2luRGF0YVtrXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaXRlbVtjb25zdGFudF8xLkZJRUxEX09SSUdJTl0gPSBvcmlnaW5EYXRhO1xuICAgICAgICAgICAgICAgIC8vIOWwhuWIhuexu+aVsOaNrue/u+ivkeaIkOaVsOaNriwg5LuF5a+55L2N572u55u45YWz55qE5bqm6YeP6L+b6KGM5pWw5a2X5YyW5aSE55CGXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBjYXRlZ29yeVNjYWxlc18xID0gY2F0ZWdvcnlTY2FsZXM7IF9pIDwgY2F0ZWdvcnlTY2FsZXNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjYWxlID0gY2F0ZWdvcnlTY2FsZXNfMVtfaV07XG4gICAgICAgICAgICAgICAgICAgIHZhciBmaWVsZCA9IHNjYWxlLmZpZWxkO1xuICAgICAgICAgICAgICAgICAgICBpdGVtW2ZpZWxkXSA9IHNjYWxlLnRyYW5zbGF0ZShpdGVtW2ZpZWxkXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFyci5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYmVmb3JlQWRqdXN0LnB1c2goYXJyKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF0YUFycmF5ID0gdGhpcy5hZGp1c3REYXRhKGJlZm9yZUFkanVzdCk7IC8vIOi/m+ihjCBhZGp1c3Qg5pWw5o2u6LCD5pW0XG4gICAgICAgIHRoaXMuYmVmb3JlTWFwcGluZ0RhdGEgPSBkYXRhQXJyYXk7XG4gICAgICAgIHJldHVybiBkYXRhQXJyYXk7XG4gICAgfTtcbiAgICAvLyDosIPmlbTmlbDmja5cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuYWRqdXN0RGF0YSA9IGZ1bmN0aW9uIChkYXRhQXJyYXkpIHtcbiAgICAgICAgdmFyIGFkanVzdE9wdGlvbiA9IHRoaXMuYWRqdXN0T3B0aW9uO1xuICAgICAgICB2YXIgcmVzdWx0ID0gZGF0YUFycmF5O1xuICAgICAgICBpZiAoYWRqdXN0T3B0aW9uKSB7XG4gICAgICAgICAgICB2YXIgeFNjYWxlID0gdGhpcy5nZXRYU2NhbGUoKTtcbiAgICAgICAgICAgIHZhciB5U2NhbGUgPSB0aGlzLmdldFlTY2FsZSgpO1xuICAgICAgICAgICAgdmFyIHhGaWVsZCA9IHhTY2FsZS5maWVsZDtcbiAgICAgICAgICAgIHZhciB5RmllbGQgPSB5U2NhbGUgPyB5U2NhbGUuZmllbGQgOiBudWxsO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFkanVzdE9wdGlvbi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBhZGp1c3QgPSBhZGp1c3RPcHRpb25baV07XG4gICAgICAgICAgICAgICAgdmFyIGFkanVzdENmZyA9IHRzbGliXzEuX19hc3NpZ24oeyB4RmllbGQ6IHhGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgeUZpZWxkOiB5RmllbGQgfSwgYWRqdXN0KTtcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IGFkanVzdC50eXBlO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnZG9kZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhZGp1c3ROYW1lcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoeFNjYWxlLmlzQ2F0ZWdvcnkgfHwgeFNjYWxlLnR5cGUgPT09ICdpZGVudGl0eScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkanVzdE5hbWVzLnB1c2goJ3gnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgheVNjYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3ROYW1lcy5wdXNoKCd5Jyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RvZGdlIGlzIG5vdCBzdXBwb3J0IGxpbmVhciBhdHRyaWJ1dGUsIHBsZWFzZSB1c2UgY2F0ZWdvcnkgYXR0cmlidXRlIScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFkanVzdENmZy5hZGp1c3ROYW1lcyA9IGFkanVzdE5hbWVzO1xuICAgICAgICAgICAgICAgICAgICAvLyDmr4/kuKrliIbnu4TlhoXmr4/mnaHmn7HlrZDnmoTlrr3luqbljaDmr5TvvIznlKjmiLfkuI3lj6/mjIflrprvvIznlKjmiLfpnIDopoHpgJrov4cgY29sdW1uV2lkdGhSYXRpbyDmjIflrppcbiAgICAgICAgICAgICAgICAgICAgYWRqdXN0Q2ZnLmRvZGdlUmF0aW8gPSB0aGlzLnRoZW1lLmNvbHVtbldpZHRoUmF0aW87XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdzdGFjaycpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmNvb3JkaW5hdGU7XG4gICAgICAgICAgICAgICAgICAgIGlmICgheVNjYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDkuIDnu7TnmoTmg4XlhrXkuIvojrflj5bpq5jluqblkozpu5jorqRzaXplXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3RDZmcuaGVpZ2h0ID0gY29vcmRpbmF0ZS5nZXRIZWlnaHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaXplID0gdGhpcy5nZXREZWZhdWx0VmFsdWUoJ3NpemUnKSB8fCAzO1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRqdXN0Q2ZnLnNpemUgPSBzaXplO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIOS4jei/m+ihjCB0cmFuc3Bvc2Ug5pe277yM55So5oi35Y+I5rKh5pyJ6K6+572u6L+Z5Liq5Y+C5pWw5pe277yM6buY6K6k5LuO5LiK5ZCR5LiLXG4gICAgICAgICAgICAgICAgICAgIGlmICghY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQgJiYgdXRpbF8xLmlzTmlsKGFkanVzdENmZy5yZXZlcnNlT3JkZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3RDZmcucmV2ZXJzZU9yZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgYWRqdXN0Q3RvciA9IGFkanVzdF8xLmdldEFkanVzdCh0eXBlKTtcbiAgICAgICAgICAgICAgICB2YXIgYWRqdXN0SW5zdGFuY2UgPSBuZXcgYWRqdXN0Q3RvcihhZGp1c3RDZmcpO1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFkanVzdEluc3RhbmNlLnByb2Nlc3MocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmFkanVzdHNbdHlwZV0gPSBhZGp1c3RJbnN0YW5jZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgLy8g5a+55pWw5o2u6L+b6KGM5YiG57uEXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdyb3VwRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBncm91cFNjYWxlcyA9IHRoaXMuZ2V0R3JvdXBTY2FsZXMoKTtcbiAgICAgICAgdmFyIHNjYWxlRGVmcyA9IHRoaXMuc2NhbGVEZWZzO1xuICAgICAgICB2YXIgYXBwZW5kQ29uZGl0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgZ3JvdXBGaWVsZHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGdyb3VwU2NhbGVzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIHNjYWxlID0gZ3JvdXBTY2FsZXNbaW5kZXhdO1xuICAgICAgICAgICAgdmFyIGZpZWxkID0gc2NhbGUuZmllbGQ7XG4gICAgICAgICAgICBncm91cEZpZWxkcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuZ2V0KHNjYWxlRGVmcywgW2ZpZWxkLCAndmFsdWVzJ10pKSB7XG4gICAgICAgICAgICAgICAgLy8g55So5oi36YCa6L+HIHZpZXcuc2NhbGUoKSDmjqXlj6PmjIflrprkuoYgdmFsdWVzIOWxnuaAp1xuICAgICAgICAgICAgICAgIGFwcGVuZENvbmRpdGlvbnNbZmllbGRdID0gc2NhbGVEZWZzW2ZpZWxkXS52YWx1ZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdyb3VwX2RhdGFfMS5ncm91cChkYXRhLCBncm91cEZpZWxkcywgYXBwZW5kQ29uZGl0aW9ucyk7XG4gICAgfTtcbiAgICAvLyDmm7TmlrDlj5HnlJ/lsYLlj6DlkI7nmoTmlbDmja7lr7nlupTnmoTluqbph4/ojIPlm7RcbiAgICBHZW9tZXRyeS5wcm90b3R5cGUudXBkYXRlU3RhY2tSYW5nZSA9IGZ1bmN0aW9uIChzY2FsZSwgZGF0YUFycmF5KSB7XG4gICAgICAgIHZhciBtZXJnZUFycmF5ID0gdXRpbF8xLmZsYXR0ZW4oZGF0YUFycmF5KTtcbiAgICAgICAgdmFyIGZpZWxkID0gc2NhbGUuZmllbGQ7XG4gICAgICAgIHZhciBtaW4gPSBzY2FsZS5taW47XG4gICAgICAgIHZhciBtYXggPSBzY2FsZS5tYXg7XG4gICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBtZXJnZUFycmF5Lmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIG9iaiA9IG1lcmdlQXJyYXlbaW5kZXhdO1xuICAgICAgICAgICAgdmFyIHRtcE1pbiA9IE1hdGgubWluLmFwcGx5KG51bGwsIG9ialtmaWVsZF0pO1xuICAgICAgICAgICAgdmFyIHRtcE1heCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIG9ialtmaWVsZF0pO1xuICAgICAgICAgICAgaWYgKHRtcE1pbiA8IG1pbikge1xuICAgICAgICAgICAgICAgIG1pbiA9IHRtcE1pbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0bXBNYXggPiBtYXgpIHtcbiAgICAgICAgICAgICAgICBtYXggPSB0bXBNYXg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNjYWxlRGVmcyA9IHRoaXMuc2NhbGVEZWZzO1xuICAgICAgICB2YXIgY2ZnID0ge307XG4gICAgICAgIGlmIChtaW4gPCBzY2FsZS5taW4gJiYgIXV0aWxfMS5nZXQoc2NhbGVEZWZzLCBbZmllbGQsICdtaW4nXSkpIHtcbiAgICAgICAgICAgIC8vIOeUqOaIt+WmguaenOWcqOWIl+WumuS5ieS4reWumuS5ieS6hiBtaW7vvIzliJnku6XnlKjmiLflrprkuYnnmoTkuLrlh4ZcbiAgICAgICAgICAgIGNmZy5taW4gPSBtaW47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heCA+IHNjYWxlLm1heCAmJiAhdXRpbF8xLmdldChzY2FsZURlZnMsIFtmaWVsZCwgJ21heCddKSkge1xuICAgICAgICAgICAgLy8g55So5oi35aaC5p6c5Zyo5YiX5a6a5LmJ5Lit5a6a5LmJ5LqGIG1heFxuICAgICAgICAgICAgY2ZnLm1heCA9IG1heDtcbiAgICAgICAgfVxuICAgICAgICBzY2FsZS5jaGFuZ2UoY2ZnKTtcbiAgICB9O1xuICAgIC8vIOWwhuaVsOaNruaYoOWwhOiHs+WbvuW9ouepuumXtOWJjeeahOaTjeS9nO+8muaOkuW6j+S7peWPiuWFs+mUrueCueeahOeUn+aIkFxuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5iZWZvcmVNYXBwaW5nID0gZnVuY3Rpb24gKGJlZm9yZU1hcHBpbmdEYXRhKSB7XG4gICAgICAgIC8vIOW9k+WIneWKoCBjbG9uZSDmmK/lm6DkuLogcG9pbnRzIOeahOW8leeUqOWFs+ezu++8jOWvvOiHtOabtOaWsOWksei0pe+8jOWPr+aYr+eOsOWcqOiyjOS8vOWkjeeOsOS4jeWHuuadpeS6hu+8jOaJgOS7peaaguaXtuS4jei/m+ihjCBjbG9uZVxuICAgICAgICAvLyBjb25zdCBzb3VyY2UgPSBjbG9uZShiZWZvcmVNYXBwaW5nRGF0YSk7XG4gICAgICAgIHZhciBzb3VyY2UgPSBiZWZvcmVNYXBwaW5nRGF0YTtcbiAgICAgICAgaWYgKHRoaXMuc29ydGFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuc29ydChzb3VyY2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmdlbmVyYXRlUG9pbnRzKSB7XG4gICAgICAgICAgICAvLyDpnIDopoHnlJ/miJDlhbPplK7ngrlcbiAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMCwgbGVuZ3RoXzcgPSBzb3VyY2UubGVuZ3RoOyBpbmRleCA8IGxlbmd0aF83OyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnREYXRhID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYXRlU2hhcGVQb2ludHMoY3VycmVudERhdGEpO1xuICAgICAgICAgICAgICAgIHZhciBuZXh0RGF0YSA9IHNvdXJjZVtpbmRleCArIDFdO1xuICAgICAgICAgICAgICAgIGlmIChuZXh0RGF0YSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYXRlU2hhcGVQb2ludHMobmV4dERhdGEpO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50RGF0YVswXS5uZXh0UG9pbnRzID0gbmV4dERhdGFbMF0ucG9pbnRzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc291cmNlO1xuICAgIH07XG4gICAgLy8g55Sf5oiQIHNoYXBlIOeahOWFs+mUrueCuVxuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5nZW5lcmF0ZVNoYXBlUG9pbnRzID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIHNoYXBlRmFjdG9yeSA9IHRoaXMuZ2V0U2hhcGVGYWN0b3J5KCk7XG4gICAgICAgIHZhciBzaGFwZUF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnc2hhcGUnKTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGRhdGEubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgb2JqID0gZGF0YVtpbmRleF07XG4gICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jcmVhdGVTaGFwZVBvaW50c0NmZyhvYmopO1xuICAgICAgICAgICAgdmFyIHNoYXBlID0gc2hhcGVBdHRyID8gdGhpcy5nZXRBdHRyaWJ1dGVWYWx1ZXMoc2hhcGVBdHRyLCBvYmopIDogbnVsbDtcbiAgICAgICAgICAgIHZhciBwb2ludHMgPSBzaGFwZUZhY3RvcnkuZ2V0U2hhcGVQb2ludHMoc2hhcGUsIGNmZyk7XG4gICAgICAgICAgICBvYmoucG9pbnRzID0gcG9pbnRzO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDlsIbmlbDmja7lvZLkuIDljJZcbiAgICBHZW9tZXRyeS5wcm90b3R5cGUubm9ybWFsaXplVmFsdWVzID0gZnVuY3Rpb24gKHZhbHVlcywgc2NhbGUpIHtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkodmFsdWVzKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHZhbHVlcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICAgICAgICAgIHJzdC5wdXNoKHNjYWxlLnNjYWxlKHZhbHVlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByc3QgPSBzY2FsZS5zY2FsZSh2YWx1ZXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByc3Q7XG4gICAgfTtcbiAgICAvLyDlsIbmlbDmja7mmKDlsIToh7Plm77lvaLnqbrpl7RcbiAgICBHZW9tZXRyeS5wcm90b3R5cGUubWFwcGluZyA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBhdHRyaWJ1dGVzID0gdGhpcy5hdHRyaWJ1dGVzO1xuICAgICAgICB2YXIgbWFwcGluZ0RhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGRhdGEubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgcmVjb3JkID0gZGF0YVtpbmRleF07XG4gICAgICAgICAgICB2YXIgbmV3UmVjb3JkID0ge1xuICAgICAgICAgICAgICAgIF9vcmlnaW46IHJlY29yZFtjb25zdGFudF8xLkZJRUxEX09SSUdJTl0sXG4gICAgICAgICAgICAgICAgcG9pbnRzOiByZWNvcmQucG9pbnRzLFxuICAgICAgICAgICAgICAgIG5leHRQb2ludHM6IHJlY29yZC5uZXh0UG9pbnRzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAodmFyIGsgaW4gYXR0cmlidXRlcykge1xuICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhdHRyID0gYXR0cmlidXRlc1trXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWVzID0gYXR0ci5uYW1lcztcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IHRoaXMuZ2V0QXR0cmlidXRlVmFsdWVzKGF0dHIsIHJlY29yZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwb3NpdGlvbiDkuYvnsbvnmoTnlJ/miJDlpJrkuKrlrZfmrrXnmoTlsZ7mgKdcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsdWVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbCA9IHZhbHVlc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZV8xID0gbmFtZXNbal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UmVjb3JkW25hbWVfMV0gPSB1dGlsXzEuaXNBcnJheSh2YWwpICYmIHZhbC5sZW5ndGggPT09IDEgPyB2YWxbMF0gOiB2YWw7IC8vIOWPquacieS4gOS4quWAvOaXtui/lOWbnuesrOS4gOS4quWxnuaAp+WAvFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzLmxlbmd0aCA9PT0gMSDnmoTliKTmlq3mmK/ku6XkuIvmg4XlhrXvvIzojrflj5bnlKjmiLforr7nva7nmoTlm77lvaLlsZ7mgKflgLxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNoYXBlKCdhJywgWydkb3QnLCAnZGFzaCddKSwgY29sb3IoJ2EnLCBbJ3JlZCcsICd5ZWxsb3cnXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1JlY29yZFtuYW1lc1swXV0gPSB2YWx1ZXMubGVuZ3RoID09PSAxID8gdmFsdWVzWzBdIDogdmFsdWVzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jb252ZXJ0UG9pbnQobmV3UmVjb3JkKTsgLy8g5bCGIHjjgIF5IOi9rOaNouaIkOeUu+W4g+WdkOagh1xuICAgICAgICAgICAgbWFwcGluZ0RhdGEucHVzaChuZXdSZWNvcmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXBwaW5nRGF0YTtcbiAgICB9O1xuICAgIC8vIOWwhuW9kuS4gOWMlueahOWdkOagh+WAvOi9rOaNouaIkOeUu+W4g+WdkOagh1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5jb252ZXJ0UG9pbnQgPSBmdW5jdGlvbiAobWFwcGluZ1JlY29yZCkge1xuICAgICAgICB2YXIgeCA9IG1hcHBpbmdSZWNvcmQueCwgeSA9IG1hcHBpbmdSZWNvcmQueTtcbiAgICAgICAgdmFyIHJzdFg7XG4gICAgICAgIHZhciByc3RZO1xuICAgICAgICB2YXIgb2JqO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuY29vcmRpbmF0ZTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KHgpICYmIHV0aWxfMS5pc0FycmF5KHkpKSB7XG4gICAgICAgICAgICByc3RYID0gW107XG4gICAgICAgICAgICByc3RZID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaiA9IDAsIHhMZW4gPSB4Lmxlbmd0aCwgeUxlbiA9IHkubGVuZ3RoOyBpIDwgeExlbiAmJiBqIDwgeUxlbjsgaSArPSAxLCBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICBvYmogPSBjb29yZGluYXRlLmNvbnZlcnQoe1xuICAgICAgICAgICAgICAgICAgICB4OiB4W2ldLFxuICAgICAgICAgICAgICAgICAgICB5OiB5W2pdLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJzdFgucHVzaChvYmoueCk7XG4gICAgICAgICAgICAgICAgcnN0WS5wdXNoKG9iai55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNBcnJheSh5KSkge1xuICAgICAgICAgICAgcnN0WSA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHkubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHlWYWwgPSB5W2luZGV4XTtcbiAgICAgICAgICAgICAgICBvYmogPSBjb29yZGluYXRlLmNvbnZlcnQoe1xuICAgICAgICAgICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgICAgICAgICB5OiB5VmFsLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChyc3RYICYmIHJzdFggIT09IG9iai54KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdXRpbF8xLmlzQXJyYXkocnN0WCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJzdFggPSBbcnN0WF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcnN0WC5wdXNoKG9iai54KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJzdFggPSBvYmoueDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcnN0WS5wdXNoKG9iai55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNBcnJheSh4KSkge1xuICAgICAgICAgICAgcnN0WCA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHgubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHhWYWwgPSB4W2luZGV4XTtcbiAgICAgICAgICAgICAgICBvYmogPSBjb29yZGluYXRlLmNvbnZlcnQoe1xuICAgICAgICAgICAgICAgICAgICB4OiB4VmFsLFxuICAgICAgICAgICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChyc3RZICYmIHJzdFkgIT09IG9iai55KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdXRpbF8xLmlzQXJyYXkocnN0WSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJzdFkgPSBbcnN0WV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcnN0WS5wdXNoKG9iai55KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJzdFkgPSBvYmoueTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcnN0WC5wdXNoKG9iai54KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwb2ludCA9IGNvb3JkaW5hdGUuY29udmVydCh7XG4gICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByc3RYID0gcG9pbnQueDtcbiAgICAgICAgICAgIHJzdFkgPSBwb2ludC55O1xuICAgICAgICB9XG4gICAgICAgIG1hcHBpbmdSZWNvcmQueCA9IHJzdFg7XG4gICAgICAgIG1hcHBpbmdSZWNvcmQueSA9IHJzdFk7XG4gICAgfTtcbiAgICAvLyDojrflj5Ygc3R5bGUg6YWN572uXG4gICAgR2VvbWV0cnkucHJvdG90eXBlLmdldFN0eWxlQ2ZnID0gZnVuY3Rpb24gKHN0eWxlT3B0aW9uLCBvcmlnaW5EYXRhKSB7XG4gICAgICAgIHZhciBfYSA9IHN0eWxlT3B0aW9uLmZpZWxkcywgZmllbGRzID0gX2EgPT09IHZvaWQgMCA/IFtdIDogX2EsIGNhbGxiYWNrID0gc3R5bGVPcHRpb24uY2FsbGJhY2ssIGNmZyA9IHN0eWxlT3B0aW9uLmNmZztcbiAgICAgICAgaWYgKGNmZykge1xuICAgICAgICAgICAgLy8g55So5oi355u05o6l6YWN572u5qC35byP5bGe5oCnXG4gICAgICAgICAgICByZXR1cm4gY2ZnO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwYXJhbXMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uIChmaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbkRhdGFbZmllbGRdO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHZvaWQgMCwgcGFyYW1zKTtcbiAgICB9O1xuICAgIEdlb21ldHJ5LnByb3RvdHlwZS5zZXRDZmcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gY2ZnLmNvb3JkaW5hdGUsIGRhdGEgPSBjZmcuZGF0YSwgdGhlbWUgPSBjZmcudGhlbWUsIHNjYWxlRGVmcyA9IGNmZy5zY2FsZURlZnM7XG4gICAgICAgIGlmIChjb29yZGluYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmNvb3JkaW5hdGUgPSBjb29yZGluYXRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzY2FsZURlZnMpIHtcbiAgICAgICAgICAgIHRoaXMuc2NhbGVEZWZzID0gc2NhbGVEZWZzO1xuICAgICAgICAgICAgdGhpcy5pZEZpZWxkcyA9IFtdO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goc2NhbGVEZWZzLCBmdW5jdGlvbiAoc2NhbGVEZWYsIGZpZWxkKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNjYWxlRGVmICYmIHNjYWxlRGVmLmtleSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5pZEZpZWxkcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhlbWUpIHtcbiAgICAgICAgICAgIHRoaXMudGhlbWUgPSB0aGlzLnVzZXJUaGVtZSA/IHV0aWxfMS5kZWVwTWl4KHt9LCB0aGVtZSwgdGhpcy51c2VyVGhlbWUpIDogdGhlbWU7IC8vIOaUr+aMgSBnZW9tZXRyeSDlsYLnuqfnmoTkuLvpopjorr7nva5cbiAgICAgICAgfVxuICAgIH07XG4gICAgR2VvbWV0cnkucHJvdG90eXBlLnJlbmRlckxhYmVscyA9IGZ1bmN0aW9uIChtYXBwaW5nQXJyYXksIGlzVXBkYXRlKSB7XG4gICAgICAgIGlmIChpc1VwZGF0ZSA9PT0gdm9pZCAwKSB7IGlzVXBkYXRlID0gZmFsc2U7IH1cbiAgICAgICAgdmFyIGdlb21ldHJ5TGFiZWwgPSB0aGlzLmdlb21ldHJ5TGFiZWw7XG4gICAgICAgIGlmICghZ2VvbWV0cnlMYWJlbCkge1xuICAgICAgICAgICAgLy8g5Yid5qyh5Yib5bu6XG4gICAgICAgICAgICB2YXIgbGFiZWxUeXBlID0gdGhpcy5nZXRMYWJlbFR5cGUoKTtcbiAgICAgICAgICAgIHZhciBHZW9tZXRyeUxhYmVsc0N0b3IgPSBsYWJlbF8xLmdldEdlb21ldHJ5TGFiZWwobGFiZWxUeXBlKTtcbiAgICAgICAgICAgIGdlb21ldHJ5TGFiZWwgPSBuZXcgR2VvbWV0cnlMYWJlbHNDdG9yKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeUxhYmVsID0gZ2VvbWV0cnlMYWJlbDtcbiAgICAgICAgfVxuICAgICAgICBnZW9tZXRyeUxhYmVsLnJlbmRlcihtYXBwaW5nQXJyYXksIGlzVXBkYXRlKTtcbiAgICAgICAgLy8g5bCGIGxhYmVsIOWQjCBlbGVtZW50IOi/m+ihjOWFs+iBlFxuICAgICAgICB2YXIgbGFiZWxzTWFwID0gZ2VvbWV0cnlMYWJlbC5sYWJlbHNSZW5kZXJlci5zaGFwZXNNYXA7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZWxlbWVudHNNYXAsIGZ1bmN0aW9uIChlbGVtZW50LCBpZCkge1xuICAgICAgICAgICAgdmFyIGxhYmVscyA9IGZpbHRlckxhYmVsc0J5SWQoaWQsIGxhYmVsc01hcCk7IC8vIGVsZW1lbnQg5a6e5L6L5ZCMIGxhYmVsIOi/m+ihjOe7keWumlxuICAgICAgICAgICAgaWYgKGxhYmVscy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmxhYmVsU2hhcGUgPSBsYWJlbHM7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsYWJlbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gbGFiZWxzW2ldO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxDaGlsZHJlbiA9IGxhYmVsLmdldENoaWxkcmVuKCk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGFiZWxDaGlsZHJlbi5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gbGFiZWxDaGlsZHJlbltqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmNmZy5uYW1lID0gWydlbGVtZW50JywgJ2xhYmVsJ107XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5jZmcuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm6ZyA6KaB6L+b6KGM576k57uE5YWl5Zy65Yqo55S7XG4gICAgICog6KeE5YiZ77yaXG4gICAgICogMS4g5aaC5p6c5Y+R55Sf5pu05paw77yM5YiZ5LiN6L+b6KGMXG4gICAgICogMi4g5aaC5p6c55So5oi35YWz6ZetIGdlb21ldHJ5IOWKqOeUu++8jOWImeS4jei/m+ihjFxuICAgICAqIDMuIOWmguaenOeUqOaIt+WFs+mXreS6hiBhcHBlYXIg5Yqo55S777yM5YiZ5LiN6L+b6KGMXG4gICAgICogNC4g5aaC5p6c55So5oi36YWN572u5LqGIGFwcGVhci5hbmltYXRpb27vvIzliJnkuI3ov5vooYxcbiAgICAgKi9cbiAgICBHZW9tZXRyeS5wcm90b3R5cGUuY2FuRG9Hcm91cEFuaW1hdGlvbiA9IGZ1bmN0aW9uIChpc1VwZGF0ZSkge1xuICAgICAgICByZXR1cm4gKCFpc1VwZGF0ZSAmJlxuICAgICAgICAgICAgdGhpcy5hbmltYXRlT3B0aW9uICYmXG4gICAgICAgICAgICAodXRpbF8xLmdldCh0aGlzLmFuaW1hdGVPcHRpb24sICdhcHBlYXInKSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgICAgKHV0aWxfMS5nZXQodGhpcy5hbmltYXRlT3B0aW9uLCAnYXBwZWFyJykgJiYgdXRpbF8xLmdldCh0aGlzLmFuaW1hdGVPcHRpb24sIFsnYXBwZWFyJywgJ2FuaW1hdGlvbiddKSA9PT0gdW5kZWZpbmVkKSkpO1xuICAgIH07XG4gICAgcmV0dXJuIEdlb21ldHJ5O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR2VvbWV0cnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG5yZXF1aXJlKFwiLi9zaGFwZS9lZGdlXCIpO1xuLyoqXG4gKiBFZGdlIOWHoOS9leagh+iusO+8jOeUqOS6jue7mOWItuWFs+ezu+WbvuS4reeahCoq6L65Kirlm77lvaLvvIzlpoLvvJpcbiAqIDEuIOa1geeoi+WbvlxuICogMi4g5qCRXG4gKiAzLiDlvKfplb/ov57mjqXlm75cbiAqIDQuIOWSjOW8puWbvlxuICogNS4g5qGR5Z+65Zu+XG4gKi9cbnZhciBFZGdlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEVkZ2UsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWRnZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnZWRnZSc7XG4gICAgICAgIF90aGlzLnNoYXBlVHlwZSA9ICdlZGdlJztcbiAgICAgICAgX3RoaXMuZ2VuZXJhdGVQb2ludHMgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIHJldHVybiBFZGdlO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRWRnZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVkZ2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBhbmltYXRlXzEgPSByZXF1aXJlKFwiLi4vLi4vYW5pbWF0ZVwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZVwiKSk7XG52YXIgZ3JhcGhpY3NfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2dyYXBoaWNzXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiQGFudHYvY29tcG9uZW50L2xpYi91dGlsL2V2ZW50XCIpO1xuLyoqXG4gKiBFbGVtZW50IOWbvuW9ouWFg+e0oOOAglxuICog5a6a5LmJ77ya5ZyoIEcyIOS4re+8jOaIkeS7rOS8muWwhuaVsOaNrumAmui/h+WbvuW9ouivreazleaYoOWwhOaIkOS4jeWQjOeahOWbvuW9ou+8jOavlOWmgueCueWbvu+8jOaVsOaNrumbhuS4reeahOavj+adoeaVsOaNruS8muWvueW6lOS4gOS4queCue+8jOafseeKtuWbvuavj+adoeaVsOaNruWvueW6lOS4gOS4quafseWtkO+8jOe6v+WbvuWImeaYr+S4gOe7hOaVsOaNruWvueW6lOS4gOadoeaKmOe6v++8jEVsZW1lbnQg5Y2z5LiA5p2hL+S4gOe7hOaVsOaNruWvueW6lOeahOWbvuW9ouWFg+e0oO+8jOWug+S7o+ihqOS4gOadoeaVsOaNruaIluiAheS4gOS4quaVsOaNrumbhu+8jOWcqOWbvuW9ouWxgumdou+8jOWug+WPr+S7peaYr+WNleS4qiBTaGFwZSDkuZ/lj6/ku6XmmK/lpJrkuKogU2hhcGXvvIzmiJHku6znp7DkuYvkuLrlm77lvaLlhYPntKDjgIJcbiAqL1xudmFyIEVsZW1lbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBFbGVtZW50KGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjZmcpIHx8IHRoaXM7XG4gICAgICAgIC8vIOWtmOWCqOW9k+WJjeW8gOWQr+eahOeKtuaAgVxuICAgICAgICBfdGhpcy5zdGF0ZXMgPSBbXTtcbiAgICAgICAgdmFyIHNoYXBlRmFjdG9yeSA9IGNmZy5zaGFwZUZhY3RvcnksIGNvbnRhaW5lciA9IGNmZy5jb250YWluZXIsIG9mZnNjcmVlbkdyb3VwID0gY2ZnLm9mZnNjcmVlbkdyb3VwLCBfYSA9IGNmZy52aXNpYmxlLCB2aXNpYmxlID0gX2EgPT09IHZvaWQgMCA/IHRydWUgOiBfYTtcbiAgICAgICAgX3RoaXMuc2hhcGVGYWN0b3J5ID0gc2hhcGVGYWN0b3J5O1xuICAgICAgICBfdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICAgIF90aGlzLm9mZnNjcmVlbkdyb3VwID0gb2Zmc2NyZWVuR3JvdXA7XG4gICAgICAgIF90aGlzLnZpc2libGUgPSB2aXNpYmxlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOe7mOWItuWbvuW9ouOAglxuICAgICAqIEBwYXJhbSBtb2RlbCDnu5jliLbmlbDmja7jgIJcbiAgICAgKiBAcGFyYW0gaXNVcGRhdGUg5Y+v6YCJ77yM5piv5ZCm5piv5pu05paw5Y+R55Sf5ZCO55qE57uY5Yi244CCXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uIChtb2RlbCwgaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKGlzVXBkYXRlID09PSB2b2lkIDApIHsgaXNVcGRhdGUgPSBmYWxzZTsgfVxuICAgICAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gICAgICAgIHRoaXMuZGF0YSA9IG1vZGVsLmRhdGE7IC8vIOWtmOWCqOWOn+Wni+aVsOaNrlxuICAgICAgICB0aGlzLnNoYXBlVHlwZSA9IHRoaXMuZ2V0U2hhcGVUeXBlKG1vZGVsKTtcbiAgICAgICAgLy8g57uY5Yi25Zu+5b2iXG4gICAgICAgIHRoaXMuZHJhd1NoYXBlKG1vZGVsLCBpc1VwZGF0ZSk7XG4gICAgICAgIGlmICh0aGlzLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAvLyDnlKjmiLflnKjliJ3lp4vljJbnmoTml7blgJnlo7DmmI4gdmlzaWJsZTogZmFsc2VcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlVmlzaWJsZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOabtOaWsOWbvuW9ouOAglxuICAgICAqIEBwYXJhbSBtb2RlbCDmm7TmlrDnmoTnu5jliLbmlbDmja7jgIJcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcywgc2hhcGVGYWN0b3J5ID0gX2Euc2hhcGVGYWN0b3J5LCBzaGFwZSA9IF9hLnNoYXBlO1xuICAgICAgICBpZiAoIXNoYXBlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8g5pu05paw5pWw5o2uXG4gICAgICAgIHRoaXMubW9kZWwgPSBtb2RlbDtcbiAgICAgICAgdGhpcy5kYXRhID0gbW9kZWwuZGF0YTtcbiAgICAgICAgdGhpcy5zaGFwZVR5cGUgPSB0aGlzLmdldFNoYXBlVHlwZShtb2RlbCk7XG4gICAgICAgIC8vIHN0ZXAgMTog5pu05pawIHNoYXBlIOaQuuW4pueahOS/oeaBr1xuICAgICAgICB0aGlzLnNldFNoYXBlSW5mbyhzaGFwZSwgbW9kZWwpO1xuICAgICAgICAvLyBzdGVwIDI6IOS9v+eUqOiZmuaLnyBHcm91cCDph43mlrDnu5jliLYgc2hhcGXvvIznhLblkI7mm7TmlrDlvZPliY0gc2hhcGVcbiAgICAgICAgdmFyIG9mZnNjcmVlbkdyb3VwID0gdGhpcy5nZXRPZmZzY3JlZW5Hcm91cCgpO1xuICAgICAgICB2YXIgbmV3U2hhcGUgPSBzaGFwZUZhY3RvcnkuZHJhd1NoYXBlKHRoaXMuc2hhcGVUeXBlLCBtb2RlbCwgb2Zmc2NyZWVuR3JvdXApO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIG5ld1NoYXBlLmNmZy5kYXRhID0gdGhpcy5kYXRhO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIG5ld1NoYXBlLmNmZy5vcmlnaW4gPSBtb2RlbDtcbiAgICAgICAgLy8gc3RlcCAzOiDlkIzmraUgc2hhcGUg5qC35byPXG4gICAgICAgIHRoaXMuc3luY1NoYXBlU3R5bGUoc2hhcGUsIG5ld1NoYXBlLCAnJywgdGhpcy5nZXRBbmltYXRlQ2ZnKCd1cGRhdGUnKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDplIDmr4EgZWxlbWVudCDlrp7kvovjgIJcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBzaGFwZUZhY3RvcnkgPSBfYS5zaGFwZUZhY3RvcnksIHNoYXBlID0gX2Euc2hhcGU7XG4gICAgICAgIGlmIChzaGFwZSkge1xuICAgICAgICAgICAgdmFyIGFuaW1hdGVDZmcgPSB0aGlzLmdldEFuaW1hdGVDZmcoJ2xlYXZlJyk7XG4gICAgICAgICAgICBpZiAoYW5pbWF0ZUNmZykge1xuICAgICAgICAgICAgICAgIC8vIOaMh+WumuS6huWKqOeUu+mFjee9ruWImeaJp+ihjOmUgOavgeWKqOeUu1xuICAgICAgICAgICAgICAgIGFuaW1hdGVfMS5kb0FuaW1hdGUoc2hhcGUsIGFuaW1hdGVDZmcsIHtcbiAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZTogc2hhcGVGYWN0b3J5LmNvb3JkaW5hdGUsXG4gICAgICAgICAgICAgICAgICAgIHRvQXR0cnM6IHRzbGliXzEuX19hc3NpZ24oe30sIHNoYXBlLmF0dHIoKSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyDlkKbliJnnm7TmjqXplIDmr4FcbiAgICAgICAgICAgICAgICBzaGFwZS5yZW1vdmUodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVzZXRcbiAgICAgICAgdGhpcy5zdGF0ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5zaGFwZUZhY3RvcnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnNoYXBlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmFuaW1hdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuZ2VvbWV0cnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMubGFiZWxTaGFwZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5tb2RlbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5kYXRhID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLm9mZnNjcmVlbkdyb3VwID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnN0YXRlc1N0eWxlID0gdW5kZWZpbmVkO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYvuekuuaIluiAhemakOiXjyBlbGVtZW5044CCXG4gICAgICogQHBhcmFtIHZpc2libGUg5piv5ZCm5Y+v6KeB44CCXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuY2hhbmdlVmlzaWJsZSA9IGZ1bmN0aW9uICh2aXNpYmxlKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY2hhbmdlVmlzaWJsZS5jYWxsKHRoaXMsIHZpc2libGUpO1xuICAgICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2hhcGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNoYXBlLnNob3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmxhYmVsU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVsU2hhcGUuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuc2hvdygpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2hhcGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNoYXBlLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmxhYmVsU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVsU2hhcGUuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuaGlkZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva4gRWxlbWVudCDnmoTnirbmgIHjgIJcbiAgICAgKlxuICAgICAqIOebruWJjSBFbGVtZW50IOW8gOaUvuS4ieenjeeKtuaAge+8mlxuICAgICAqIDEuIGFjdGl2ZVxuICAgICAqIDIuIHNlbGVjdGVkXG4gICAgICogMy4gaW5hY3RpdmVcbiAgICAgKlxuICAgICAqIOi/meS4ieenjeeKtuaAgeebuOS6kueLrOeri++8jOWPr+S7pei/m+ihjOWPoOWKoOOAglxuICAgICAqXG4gICAgICog6L+Z5LiJ56eN54q25oCB55qE5qC35byP5Y+v5ZyoIFtbVGhlbWVdXSDkuLvpopjkuK3miJbogIXpgJrov4cgYGdlb21ldHJ5LnN0YXRlKClgIOaOpeWPo+i/m+ihjOmFjee9ruOAglxuICAgICAqXG4gICAgICogYGBgdHNcbiAgICAgKiAvLyDmv4DmtLsgYWN0aXZlIOeKtuaAgVxuICAgICAqIHNldFN0YXRlKCdhY3RpdmUnLCB0cnVlKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSBzdGF0ZU5hbWUg54q25oCB5ZCNXG4gICAgICogQHBhcmFtIHN0YXRlU3RhdHVzIOaYr+WQpuW8gOWQr+eKtuaAgVxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlTmFtZSwgc3RhdGVTdGF0dXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcywgc3RhdGVzID0gX2Euc3RhdGVzLCBzaGFwZUZhY3RvcnkgPSBfYS5zaGFwZUZhY3RvcnksIG1vZGVsID0gX2EubW9kZWwsIHNoYXBlID0gX2Euc2hhcGUsIHNoYXBlVHlwZSA9IF9hLnNoYXBlVHlwZTtcbiAgICAgICAgdmFyIGluZGV4ID0gc3RhdGVzLmluZGV4T2Yoc3RhdGVOYW1lKTtcbiAgICAgICAgaWYgKHN0YXRlU3RhdHVzKSB7XG4gICAgICAgICAgICAvLyDlvIDlkK/nirbmgIFcbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8g6K+l54q25oCB5bey57uP5byA5ZCv77yM5YiZ6L+U5ZueXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhdGVzLnB1c2goc3RhdGVOYW1lKTtcbiAgICAgICAgICAgIGlmIChzdGF0ZU5hbWUgPT09ICdhY3RpdmUnIHx8IHN0YXRlTmFtZSA9PT0gJ3NlbGVjdGVkJykge1xuICAgICAgICAgICAgICAgIHNoYXBlLnRvRnJvbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyDlhbPpl63nirbmgIHvvIzkvYbmmK/nirbmgIHmnKrorr7nva7ov4dcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGF0ZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGlmIChzdGF0ZU5hbWUgPT09ICdhY3RpdmUnIHx8IHN0YXRlTmFtZSA9PT0gJ3NlbGVjdGVkJykge1xuICAgICAgICAgICAgICAgIHNoYXBlLnRvQmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOS9v+eUqOiZmuaLnyBncm91cCDph43mlrDnu5jliLYgc2hhcGXvvIznhLblkI7lr7nov5nkuKogc2hhcGUg5bqU55So54q25oCB5qC35byP5ZCO77yM5pu05paw5b2T5YmNIHNoYXBl44CCXG4gICAgICAgIHZhciBvZmZzY3JlZW5TaGFwZSA9IHNoYXBlRmFjdG9yeS5kcmF3U2hhcGUoc2hhcGVUeXBlLCBtb2RlbCwgdGhpcy5nZXRPZmZzY3JlZW5Hcm91cCgpKTtcbiAgICAgICAgaWYgKHN0YXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIOW6lOeUqOW9k+WJjeeKtuaAgVxuICAgICAgICAgICAgc3RhdGVzLmZvckVhY2goZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc3luY1NoYXBlU3R5bGUoc2hhcGUsIG9mZnNjcmVlblNoYXBlLCBzdGF0ZSwgbnVsbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOWmguaenOayoeacieeKtuaAge+8jOWImemcgOimgeaBouWkjeiHs+WOn+Wni+eKtuaAgVxuICAgICAgICAgICAgdGhpcy5zeW5jU2hhcGVTdHlsZShzaGFwZSwgb2Zmc2NyZWVuU2hhcGUsICdyZXNldCcsIG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIG9mZnNjcmVlblNoYXBlLnJlbW92ZSh0cnVlKTsgLy8g6ZSA5q+B77yM5YeP5bCR5YaF5a2Y5Y2g55SoXG4gICAgICAgIHZhciBldmVudE9iamVjdCA9IHtcbiAgICAgICAgICAgIHN0YXRlOiBzdGF0ZU5hbWUsXG4gICAgICAgICAgICBzdGF0ZVN0YXR1czogc3RhdGVTdGF0dXMsXG4gICAgICAgICAgICBlbGVtZW50OiB0aGlzLFxuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmNvbnRhaW5lcixcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuZW1pdCgnc3RhdGVjaGFuZ2UnLCBldmVudE9iamVjdCk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgZXZlbnRfMS5wcm9wYWdhdGlvbkRlbGVnYXRlKHRoaXMuc2hhcGUsICdzdGF0ZWNoYW5nZScsIGV2ZW50T2JqZWN0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOa4heepuueKtumHj+aAge+8jOaBouWkjeiHs+WIneWni+eKtuaAgeOAglxuICAgICAqL1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmNsZWFyU3RhdGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc3RhdGVzID0gdGhpcy5zdGF0ZXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHN0YXRlcywgZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZShzdGF0ZSwgZmFsc2UpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdGF0ZXMgPSBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOafpeivouW9k+WJjSBFbGVtZW50IOS4iuaYr+WQpuW3suiuvue9riBgc3RhdGVOYW1lYCDlr7nlupTnmoTnirbmgIHjgIJcbiAgICAgKiBAcGFyYW0gc3RhdGVOYW1lIOeKtuaAgeWQjeensOOAglxuICAgICAqIEByZXR1cm5zIHRydWUg6KGo56S65a2Y5Zyo77yMZmFsc2Ug6KGo56S65LiN5a2Y5Zyo44CCXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuaGFzU3RhdGUgPSBmdW5jdGlvbiAoc3RhdGVOYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlcy5pbmNsdWRlcyhzdGF0ZU5hbWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5b2T5YmNIEVsZW1lbnQg5LiK5omA5pyJ55qE54q25oCB44CCXG4gICAgICogQHJldHVybnMg5b2T5YmNIEVsZW1lbnQg5LiK5omA5pyJ55qE54q25oCB5pWw57uE44CCXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0U3RhdGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZXM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5YgRWxlbWVudCDlr7nlupTnmoTljp/lp4vmlbDmja7jgIJcbiAgICAgKiBAcmV0dXJucyDljp/lp4vmlbDmja7jgIJcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5nZXREYXRhID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+WIEVsZW1lbnQg5a+55bqU55qE5Zu+5b2i57uY5Yi25pWw5o2u44CCXG4gICAgICogQHJldHVybnMg5Zu+5b2i57uY5Yi25pWw5o2u44CCXG4gICAgICovXG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0TW9kZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6L+U5ZueIEVsZW1lbnQg5YWD57Sg5pW05L2T55qEIGJib3jvvIzljIXlkKvmlofmnKzlj4rmlofmnKzov57nur/vvIjmnInnmoTor53vvInjgIJcbiAgICAgKiBAcmV0dXJucyDmlbTkvZPljIXlm7Tnm5LjgIJcbiAgICAgKi9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBzaGFwZSA9IF9hLnNoYXBlLCBsYWJlbFNoYXBlID0gX2EubGFiZWxTaGFwZTtcbiAgICAgICAgdmFyIGJib3ggPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgIG1pblg6IDAsXG4gICAgICAgICAgICBtaW5ZOiAwLFxuICAgICAgICAgICAgbWF4WDogMCxcbiAgICAgICAgICAgIG1heFk6IDAsXG4gICAgICAgICAgICB3aWR0aDogMCxcbiAgICAgICAgICAgIGhlaWdodDogMCxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHNoYXBlKSB7XG4gICAgICAgICAgICBiYm94ID0gc2hhcGUuZ2V0Q2FudmFzQkJveCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsYWJlbFNoYXBlKSB7XG4gICAgICAgICAgICBsYWJlbFNoYXBlLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGxhYmVsQkJveCA9IGxhYmVsLmdldENhbnZhc0JCb3goKTtcbiAgICAgICAgICAgICAgICBiYm94LnggPSBNYXRoLm1pbihsYWJlbEJCb3gueCwgYmJveC54KTtcbiAgICAgICAgICAgICAgICBiYm94LnkgPSBNYXRoLm1pbihsYWJlbEJCb3gueSwgYmJveC55KTtcbiAgICAgICAgICAgICAgICBiYm94Lm1pblggPSBNYXRoLm1pbihsYWJlbEJCb3gubWluWCwgYmJveC5taW5YKTtcbiAgICAgICAgICAgICAgICBiYm94Lm1pblkgPSBNYXRoLm1pbihsYWJlbEJCb3gubWluWSwgYmJveC5taW5ZKTtcbiAgICAgICAgICAgICAgICBiYm94Lm1heFggPSBNYXRoLm1heChsYWJlbEJCb3gubWF4WCwgYmJveC5tYXhYKTtcbiAgICAgICAgICAgICAgICBiYm94Lm1heFkgPSBNYXRoLm1heChsYWJlbEJCb3gubWF4WSwgYmJveC5tYXhZKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJib3gud2lkdGggPSBiYm94Lm1heFggLSBiYm94Lm1pblg7XG4gICAgICAgIGJib3guaGVpZ2h0ID0gYmJveC5tYXhZIC0gYmJveC5taW5ZO1xuICAgICAgICByZXR1cm4gYmJveDtcbiAgICB9O1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmdldFN0YXRlc1N0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGVzU3R5bGUpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IHRoaXMsIHNoYXBlVHlwZSA9IF9hLnNoYXBlVHlwZSwgZ2VvbWV0cnkgPSBfYS5nZW9tZXRyeSwgc2hhcGVGYWN0b3J5ID0gX2Euc2hhcGVGYWN0b3J5O1xuICAgICAgICAgICAgdmFyIHN0YXRlT3B0aW9uID0gZ2VvbWV0cnkuc3RhdGVPcHRpb247XG4gICAgICAgICAgICB2YXIgZGVmYXVsdFNoYXBlVHlwZSA9IHNoYXBlRmFjdG9yeS5kZWZhdWx0U2hhcGVUeXBlO1xuICAgICAgICAgICAgdmFyIHN0YXRlVGhlbWUgPSBzaGFwZUZhY3RvcnkudGhlbWVbc2hhcGVUeXBlXSB8fCBzaGFwZUZhY3RvcnkudGhlbWVbZGVmYXVsdFNoYXBlVHlwZV07XG4gICAgICAgICAgICB0aGlzLnN0YXRlc1N0eWxlID0gdXRpbF8xLmRlZXBNaXgoe30sIHN0YXRlVGhlbWUsIHN0YXRlT3B0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZXNTdHlsZTtcbiAgICB9O1xuICAgIC8vIOS7juS4u+mimOS4reiOt+WPluWvueW6lOeKtuaAgemHj+eahOagt+W8j1xuICAgIEVsZW1lbnQucHJvdG90eXBlLmdldFN0YXRlU3R5bGUgPSBmdW5jdGlvbiAoc3RhdGVOYW1lLCBzaGFwZUtleSkge1xuICAgICAgICB2YXIgc3RhdGVzU3R5bGUgPSB0aGlzLmdldFN0YXRlc1N0eWxlKCk7XG4gICAgICAgIHZhciBzdGF0ZUNmZyA9IHV0aWxfMS5nZXQoc3RhdGVzU3R5bGUsIFtzdGF0ZU5hbWUsICdzdHlsZSddLCB7fSk7XG4gICAgICAgIHZhciBzaGFwZVN0eWxlID0gc3RhdGVDZmdbc2hhcGVLZXldIHx8IHN0YXRlQ2ZnO1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24oc2hhcGVTdHlsZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBzaGFwZVN0eWxlKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaGFwZVN0eWxlO1xuICAgIH07XG4gICAgLy8g6I635Y+W5Yqo55S76YWN572uXG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0QW5pbWF0ZUNmZyA9IGZ1bmN0aW9uIChhbmltYXRlVHlwZSkge1xuICAgICAgICB2YXIgYW5pbWF0ZSA9IHRoaXMuYW5pbWF0ZTtcbiAgICAgICAgaWYgKGFuaW1hdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBhbmltYXRlW2FuaW1hdGVUeXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIC8vIOe7mOWItuWbvuW9olxuICAgIEVsZW1lbnQucHJvdG90eXBlLmRyYXdTaGFwZSA9IGZ1bmN0aW9uIChtb2RlbCwgaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKGlzVXBkYXRlID09PSB2b2lkIDApIHsgaXNVcGRhdGUgPSBmYWxzZTsgfVxuICAgICAgICB2YXIgX2EgPSB0aGlzLCBzaGFwZUZhY3RvcnkgPSBfYS5zaGFwZUZhY3RvcnksIGNvbnRhaW5lciA9IF9hLmNvbnRhaW5lciwgc2hhcGVUeXBlID0gX2Euc2hhcGVUeXBlO1xuICAgICAgICAvLyDoh6rlrprkuYkgc2hhcGUg5pyJ5Y+v6IO96L+U5Zue56m6IHNoYXBlXG4gICAgICAgIHRoaXMuc2hhcGUgPSBzaGFwZUZhY3RvcnkuZHJhd1NoYXBlKHNoYXBlVHlwZSwgbW9kZWwsIGNvbnRhaW5lcik7XG4gICAgICAgIGlmICh0aGlzLnNoYXBlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFNoYXBlSW5mbyh0aGlzLnNoYXBlLCBtb2RlbCk7IC8vIOWtmOWCqOe7mOWbvuaVsOaNrlxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgdmFyIG5hbWVfMSA9IHRoaXMuc2hhcGUuY2ZnLm5hbWU7XG4gICAgICAgICAgICAvLyDpmYTliqAgZWxlbWVudCDnmoQgbmFtZSwgbmFtZSDnjrDlnKjmlK/mjIHmlbDnu4TkuobvvIzlvojlpb3nlKjkuoZcbiAgICAgICAgICAgIGlmICghbmFtZV8xKSB7XG4gICAgICAgICAgICAgICAgLy8g6L+Z5Liq5Zyw5pa55aaC5p6c55So5oi35re75Yqg5LqGIG5hbWUsIOWImemZhOWKoCBuYW1lIO+8jOWQpuWImeWwsea3u+WKoOiHquW3seeahCBuYW1lXG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIHRoaXMuc2hhcGUuY2ZnLm5hbWUgPSBbJ2VsZW1lbnQnLCB0aGlzLnNoYXBlRmFjdG9yeS5nZW9tZXRyeVR5cGVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzU3RyaW5nKG5hbWVfMSkpIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgdGhpcy5zaGFwZS5jZmcubmFtZSA9IFsnZWxlbWVudCcsIG5hbWVfMV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDmiafooYzlhaXlnLrliqjnlLtcbiAgICAgICAgICAgIHZhciBhbmltYXRlVHlwZSA9IGlzVXBkYXRlID8gJ2VudGVyJyA6ICdhcHBlYXInO1xuICAgICAgICAgICAgdmFyIGFuaW1hdGVDZmcgPSB0aGlzLmdldEFuaW1hdGVDZmcoYW5pbWF0ZVR5cGUpO1xuICAgICAgICAgICAgaWYgKGFuaW1hdGVDZmcpIHtcbiAgICAgICAgICAgICAgICBhbmltYXRlXzEuZG9BbmltYXRlKHRoaXMuc2hhcGUsIGFuaW1hdGVDZmcsIHtcbiAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZTogc2hhcGVGYWN0b3J5LmNvb3JkaW5hdGUsXG4gICAgICAgICAgICAgICAgICAgIHRvQXR0cnM6IHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMuc2hhcGUuYXR0cigpKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g6I635Y+W6Jma5oufIEdyb3VwXG4gICAgRWxlbWVudC5wcm90b3R5cGUuZ2V0T2Zmc2NyZWVuR3JvdXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5vZmZzY3JlZW5Hcm91cCkge1xuICAgICAgICAgICAgdmFyIEdyb3VwQ3RvciA9IHRoaXMuY29udGFpbmVyLmdldEdyb3VwQmFzZSgpOyAvLyDojrflj5bliIbnu4TnmoTmnoTpgKDlh73mlbBcbiAgICAgICAgICAgIHRoaXMub2Zmc2NyZWVuR3JvdXAgPSBuZXcgR3JvdXBDdG9yKHt9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5vZmZzY3JlZW5Hcm91cDtcbiAgICB9O1xuICAgIC8vIOiuvue9riBzaGFwZSDkuIrpnIDopoHmkLrluKbnmoTkv6Hmga9cbiAgICBFbGVtZW50LnByb3RvdHlwZS5zZXRTaGFwZUluZm8gPSBmdW5jdGlvbiAoc2hhcGUsIGRhdGEpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBzaGFwZS5jZmcub3JpZ2luID0gZGF0YTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBzaGFwZS5jZmcuZWxlbWVudCA9IHRoaXM7XG4gICAgICAgIGlmIChzaGFwZS5pc0dyb3VwKCkpIHtcbiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHNoYXBlLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0U2hhcGVJbmZvKGNoaWxkLCBkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmm7TmlrDlvZPliY0gc2hhcGUg55qE5qC35byPXG4gICAgRWxlbWVudC5wcm90b3R5cGUuc3luY1NoYXBlU3R5bGUgPSBmdW5jdGlvbiAoc291cmNlU2hhcGUsIHRhcmdldFNoYXBlLCBzdGF0ZSwgYW5pbWF0ZUNmZywgaW5kZXgpIHtcbiAgICAgICAgaWYgKHN0YXRlID09PSB2b2lkIDApIHsgc3RhdGUgPSAnJzsgfVxuICAgICAgICBpZiAoaW5kZXggPT09IHZvaWQgMCkgeyBpbmRleCA9IDA7IH1cbiAgICAgICAgaWYgKHNvdXJjZVNoYXBlLmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gc291cmNlU2hhcGUuZ2V0KCdjaGlsZHJlbicpO1xuICAgICAgICAgICAgdmFyIG5ld0NoaWxkcmVuID0gdGFyZ2V0U2hhcGUuZ2V0KCdjaGlsZHJlbicpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3luY1NoYXBlU3R5bGUoY2hpbGRyZW5baV0sIG5ld0NoaWxkcmVuW2ldLCBzdGF0ZSwgYW5pbWF0ZUNmZywgaW5kZXggKyBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChzdGF0ZSAmJiBzdGF0ZSAhPT0gJ3Jlc2V0Jykge1xuICAgICAgICAgICAgICAgIHZhciBuYW1lXzIgPSBzb3VyY2VTaGFwZS5nZXQoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkobmFtZV8yKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDkvJrpmYTliqAgZWxlbWVudCDnmoQgbmFtZVxuICAgICAgICAgICAgICAgICAgICBuYW1lXzIgPSBuYW1lXzJbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBzdHlsZSA9IHRoaXMuZ2V0U3RhdGVTdHlsZShzdGF0ZSwgbmFtZV8yIHx8IGluZGV4KTsgLy8g5aaC5p6c55So5oi35rKh5pyJ6K6+572uIG5hbWXvvIzliJnpu5jorqTmoLnmja7ntKLlvJXlgLxcbiAgICAgICAgICAgICAgICB0YXJnZXRTaGFwZS5hdHRyKHN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBuZXdBdHRycyA9IGdyYXBoaWNzXzEuZ2V0UmVwbGFjZUF0dHJzKHNvdXJjZVNoYXBlLCB0YXJnZXRTaGFwZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5hbmltYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFuaW1hdGVDZmcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g6ZyA6KaB6L+b6KGM5Yqo55S7XG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGVfMS5kb0FuaW1hdGUoc291cmNlU2hhcGUsIGFuaW1hdGVDZmcsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGU6IHRoaXMuc2hhcGVGYWN0b3J5LmNvb3JkaW5hdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b0F0dHJzOiBuZXdBdHRycyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlTW9kZWw6IHRoaXMubW9kZWwsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2VTaGFwZS5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2VTaGFwZS5hbmltYXRlKG5ld0F0dHJzLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogMzAwLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZVNoYXBlLmF0dHIobmV3QXR0cnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvdXJjZVNoYXBlLmF0dHIobmV3QXR0cnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBFbGVtZW50LnByb3RvdHlwZS5nZXRTaGFwZVR5cGUgPSBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIHNoYXBlID0gdXRpbF8xLmdldChtb2RlbCwgJ3NoYXBlJyk7XG4gICAgICAgIHJldHVybiB1dGlsXzEuaXNBcnJheShzaGFwZSkgPyBzaGFwZVswXSA6IHNoYXBlO1xuICAgIH07XG4gICAgcmV0dXJuIEVsZW1lbnQ7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGVtZW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBjb2xvcl91dGlsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiQGFudHYvY29sb3ItdXRpbFwiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbi8qKlxuICog55So5LqO57uY5Yi254Ot5Yqb5Zu+44CCXG4gKi9cbnZhciBIZWF0bWFwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEhlYXRtYXAsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gSGVhdG1hcCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnaGVhdG1hcCc7XG4gICAgICAgIF90aGlzLnBhbGV0dGVDYWNoZSA9IHt9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEhlYXRtYXAucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnRzID0gZnVuY3Rpb24gKG1hcHBpbmdEYXRhLCBpbmRleCwgaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKGlzVXBkYXRlID09PSB2b2lkIDApIHsgaXNVcGRhdGUgPSBmYWxzZTsgfVxuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLnByZXBhcmVSYW5nZShtYXBwaW5nRGF0YSk7XG4gICAgICAgIHZhciByYWRpdXMgPSB0aGlzLnByZXBhcmVTaXplKCk7XG4gICAgICAgIHZhciBibHVyID0gdXRpbF8xLmdldCh0aGlzLnN0eWxlT3B0aW9uLCBbJ3N0eWxlJywgJ3NoYWRvd0JsdXInXSk7XG4gICAgICAgIGlmICghdXRpbF8xLmlzTnVtYmVyKGJsdXIpKSB7XG4gICAgICAgICAgICBibHVyID0gcmFkaXVzIC8gMjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByZXBhcmVHcmV5U2NhbGVCbHVycmVkQ2lyY2xlKHJhZGl1cywgYmx1cik7XG4gICAgICAgIHRoaXMuZHJhd1dpdGhSYW5nZShtYXBwaW5nRGF0YSwgcmFuZ2UsIHJhZGl1cywgYmx1cik7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogY2xlYXJcbiAgICAgKi9cbiAgICBIZWF0bWFwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jbGVhci5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLmNsZWFyU2hhZG93Q2FudmFzQ3R4KCk7XG4gICAgICAgIHRoaXMucGFsZXR0ZUNhY2hlID0ge307XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5wcmVwYXJlUmFuZ2UgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgY29sb3JBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2NvbG9yJyk7XG4gICAgICAgIHZhciBjb2xvckZpZWxkID0gY29sb3JBdHRyLmdldEZpZWxkcygpWzBdO1xuICAgICAgICB2YXIgbWluID0gSW5maW5pdHk7XG4gICAgICAgIHZhciBtYXggPSAtSW5maW5pdHk7XG4gICAgICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAocm93KSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSByb3dbY29uc3RhbnRfMS5GSUVMRF9PUklHSU5dW2NvbG9yRmllbGRdO1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gbWF4KSB7XG4gICAgICAgICAgICAgICAgbWF4ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUgPCBtaW4pIHtcbiAgICAgICAgICAgICAgICBtaW4gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChtaW4gPT09IG1heCkge1xuICAgICAgICAgICAgbWluID0gbWF4IC0gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW21pbiwgbWF4XTtcbiAgICB9O1xuICAgIEhlYXRtYXAucHJvdG90eXBlLnByZXBhcmVTaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmFkaXVzID0gdGhpcy5nZXREZWZhdWx0VmFsdWUoJ3NpemUnKTtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOdW1iZXIocmFkaXVzKSkge1xuICAgICAgICAgICAgcmFkaXVzID0gdGhpcy5nZXREZWZhdWx0U2l6ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByYWRpdXM7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5wcmVwYXJlR3JleVNjYWxlQmx1cnJlZENpcmNsZSA9IGZ1bmN0aW9uIChyYWRpdXMsIGJsdXIpIHtcbiAgICAgICAgdmFyIGdyYXlTY2FsZUJsdXJyZWRDYW52YXMgPSB0aGlzLmdldEdyYXlTY2FsZUJsdXJyZWRDYW52YXMoKTtcbiAgICAgICAgdmFyIHIyID0gcmFkaXVzICsgYmx1cjtcbiAgICAgICAgdmFyIGN0eCA9IGdyYXlTY2FsZUJsdXJyZWRDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgZ3JheVNjYWxlQmx1cnJlZENhbnZhcy53aWR0aCA9IGdyYXlTY2FsZUJsdXJyZWRDYW52YXMuaGVpZ2h0ID0gcjIgKiAyO1xuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGdyYXlTY2FsZUJsdXJyZWRDYW52YXMud2lkdGgsIGdyYXlTY2FsZUJsdXJyZWRDYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjdHguc2hhZG93T2Zmc2V0WSA9IHIyICogMjtcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBibHVyO1xuICAgICAgICBjdHguc2hhZG93Q29sb3IgPSAnYmxhY2snO1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5hcmMoLXIyLCAtcjIsIHJhZGl1cywgMCwgTWF0aC5QSSAqIDIsIHRydWUpO1xuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgIGN0eC5maWxsKCk7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5kcmF3V2l0aFJhbmdlID0gZnVuY3Rpb24gKGRhdGEsIHJhbmdlLCByYWRpdXMsIGJsdXIpIHtcbiAgICAgICAgLy8gY2FudmFzIHNpemVcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb29yZGluYXRlLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgIHZhciB3aWR0aCA9IHRoaXMuY29vcmRpbmF0ZS5nZXRXaWR0aCgpO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gdGhpcy5jb29yZGluYXRlLmdldEhlaWdodCgpO1xuICAgICAgICAvLyB2YWx1ZSwgcmFuZ2UsIGV0Y1xuICAgICAgICB2YXIgY29sb3JBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2NvbG9yJyk7XG4gICAgICAgIHZhciB2YWx1ZUZpZWxkID0gY29sb3JBdHRyLmdldEZpZWxkcygpWzBdO1xuICAgICAgICAvLyBwcmVwYXJlIHNoYWRvdyBjYW52YXMgY29udGV4dFxuICAgICAgICB0aGlzLmNsZWFyU2hhZG93Q2FudmFzQ3R4KCk7XG4gICAgICAgIHZhciBjdHggPSB0aGlzLmdldFNoYWRvd0NhbnZhc0N0eCgpO1xuICAgICAgICAvLyBmaWx0ZXIgZGF0YVxuICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgIGRhdGEgPSBkYXRhLmZpbHRlcihmdW5jdGlvbiAocm93KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJvd1tjb25zdGFudF8xLkZJRUxEX09SSUdJTl1bdmFsdWVGaWVsZF0gPD0gcmFuZ2VbMV0gJiYgcm93W2NvbnN0YW50XzEuRklFTERfT1JJR0lOXVt2YWx1ZUZpZWxkXSA+PSByYW5nZVswXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIHN0ZXAxLiBkcmF3IHBvaW50cyB3aXRoIHNoYWRvd1xuICAgICAgICB2YXIgc2NhbGUgPSB0aGlzLnNjYWxlc1t2YWx1ZUZpZWxkXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBkYXRhXzEgPSBkYXRhOyBfaSA8IGRhdGFfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBvYmogPSBkYXRhXzFbX2ldO1xuICAgICAgICAgICAgdmFyIF9iID0gdGhpcy5nZXREcmF3Q2ZnKG9iaiksIHggPSBfYi54LCB5ID0gX2IueTtcbiAgICAgICAgICAgIHZhciBhbHBoYSA9IHNjYWxlLnNjYWxlKG9ialtjb25zdGFudF8xLkZJRUxEX09SSUdJTl1bdmFsdWVGaWVsZF0pO1xuICAgICAgICAgICAgdGhpcy5kcmF3R3JheVNjYWxlQmx1cnJlZENpcmNsZSh4IC0gc3RhcnQueCwgeSAtIGVuZC55LCByYWRpdXMgKyBibHVyLCBhbHBoYSwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzdGVwMi4gY29udmVydCBwaXhlbHNcbiAgICAgICAgdmFyIGNvbG9yZWQgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICB0aGlzLmNsZWFyU2hhZG93Q2FudmFzQ3R4KCk7XG4gICAgICAgIHRoaXMuY29sb3JpemUoY29sb3JlZCk7XG4gICAgICAgIGN0eC5wdXRJbWFnZURhdGEoY29sb3JlZCwgMCwgMCk7XG4gICAgICAgIHZhciBpbWFnZVNoYXBlID0gdGhpcy5nZXRJbWFnZVNoYXBlKCk7XG4gICAgICAgIGltYWdlU2hhcGUuYXR0cigneCcsIHN0YXJ0LngpO1xuICAgICAgICBpbWFnZVNoYXBlLmF0dHIoJ3knLCBlbmQueSk7XG4gICAgICAgIGltYWdlU2hhcGUuYXR0cignd2lkdGgnLCB3aWR0aCk7XG4gICAgICAgIGltYWdlU2hhcGUuYXR0cignaGVpZ2h0JywgaGVpZ2h0KTtcbiAgICAgICAgaW1hZ2VTaGFwZS5hdHRyKCdpbWcnLCBjdHguY2FudmFzKTtcbiAgICAgICAgaW1hZ2VTaGFwZS5zZXQoJ29yaWdpbicsIHRoaXMuZ2V0U2hhcGVJbmZvKGRhdGEpKTsgLy8g5a2Y5YKo57uY5Zu+5L+h5oGv5pWw5o2uXG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5nZXREZWZhdWx0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3Bvc2l0aW9uJyk7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5jb29yZGluYXRlO1xuICAgICAgICByZXR1cm4gTWF0aC5taW4oY29vcmRpbmF0ZS5nZXRXaWR0aCgpIC8gKHBvc2l0aW9uLnNjYWxlc1swXS50aWNrcy5sZW5ndGggKiA0KSwgY29vcmRpbmF0ZS5nZXRIZWlnaHQoKSAvIChwb3NpdGlvbi5zY2FsZXNbMV0udGlja3MubGVuZ3RoICogNCkpO1xuICAgIH07XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuY2xlYXJTaGFkb3dDYW52YXNDdHggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjdHggPSB0aGlzLmdldFNoYWRvd0NhbnZhc0N0eCgpO1xuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGN0eC5jYW52YXMud2lkdGgsIGN0eC5jYW52YXMuaGVpZ2h0KTtcbiAgICB9O1xuICAgIEhlYXRtYXAucHJvdG90eXBlLmdldFNoYWRvd0NhbnZhc0N0eCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IHRoaXMuc2hhZG93Q2FudmFzO1xuICAgICAgICBpZiAoIWNhbnZhcykge1xuICAgICAgICAgICAgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgICAgICB0aGlzLnNoYWRvd0NhbnZhcyA9IGNhbnZhcztcbiAgICAgICAgfVxuICAgICAgICBjYW52YXMud2lkdGggPSB0aGlzLmNvb3JkaW5hdGUuZ2V0V2lkdGgoKTtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IHRoaXMuY29vcmRpbmF0ZS5nZXRIZWlnaHQoKTtcbiAgICAgICAgcmV0dXJuIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIH07XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuZ2V0R3JheVNjYWxlQmx1cnJlZENhbnZhcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmdyYXlTY2FsZUJsdXJyZWRDYW52YXMpIHtcbiAgICAgICAgICAgIHRoaXMuZ3JheVNjYWxlQmx1cnJlZENhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdyYXlTY2FsZUJsdXJyZWRDYW52YXM7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5kcmF3R3JheVNjYWxlQmx1cnJlZENpcmNsZSA9IGZ1bmN0aW9uICh4LCB5LCByLCBhbHBoYSwgY3R4KSB7XG4gICAgICAgIHZhciBncmF5U2NhbGVCbHVycmVkQ2FudmFzID0gdGhpcy5nZXRHcmF5U2NhbGVCbHVycmVkQ2FudmFzKCk7XG4gICAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IGFscGhhO1xuICAgICAgICBjdHguZHJhd0ltYWdlKGdyYXlTY2FsZUJsdXJyZWRDYW52YXMsIHggLSByLCB5IC0gcik7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5jb2xvcml6ZSA9IGZ1bmN0aW9uIChpbWcpIHtcbiAgICAgICAgdmFyIGNvbG9yQXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCdjb2xvcicpO1xuICAgICAgICB2YXIgcGl4ZWxzID0gaW1nLmRhdGE7XG4gICAgICAgIHZhciBwYWxldHRlQ2FjaGUgPSB0aGlzLnBhbGV0dGVDYWNoZTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDM7IGkgPCBwaXhlbHMubGVuZ3RoOyBpICs9IDQpIHtcbiAgICAgICAgICAgIHZhciBhbHBoYSA9IHBpeGVsc1tpXTsgLy8gZ2V0IGdyYWRpZW50IGNvbG9yIGZyb20gb3BhY2l0eSB2YWx1ZVxuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc051bWJlcihhbHBoYSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGFsZXR0ZSA9IHBhbGV0dGVDYWNoZVthbHBoYV0gPyBwYWxldHRlQ2FjaGVbYWxwaGFdIDogY29sb3JfdXRpbF8xLmRlZmF1bHQucmdiMmFycihjb2xvckF0dHIuZ3JhZGllbnQoYWxwaGEgLyAyNTYpKTtcbiAgICAgICAgICAgICAgICBwaXhlbHNbaSAtIDNdID0gcGFsZXR0ZVswXTtcbiAgICAgICAgICAgICAgICBwaXhlbHNbaSAtIDJdID0gcGFsZXR0ZVsxXTtcbiAgICAgICAgICAgICAgICBwaXhlbHNbaSAtIDFdID0gcGFsZXR0ZVsyXTtcbiAgICAgICAgICAgICAgICBwaXhlbHNbaV0gPSBhbHBoYTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuZ2V0SW1hZ2VTaGFwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGltYWdlU2hhcGUgPSB0aGlzLmltYWdlU2hhcGU7XG4gICAgICAgIGlmIChpbWFnZVNoYXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gaW1hZ2VTaGFwZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XG4gICAgICAgIGltYWdlU2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoe1xuICAgICAgICAgICAgdHlwZTogJ2ltYWdlJyxcbiAgICAgICAgICAgIGF0dHJzOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW1hZ2VTaGFwZSA9IGltYWdlU2hhcGU7XG4gICAgICAgIHJldHVybiBpbWFnZVNoYXBlO1xuICAgIH07XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuZ2V0U2hhcGVJbmZvID0gZnVuY3Rpb24gKG1hcHBpbmdEYXRhKSB7XG4gICAgICAgIHZhciBzaGFwZUNmZyA9IHRoaXMuZ2V0RHJhd0NmZyhtYXBwaW5nRGF0YVswXSk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHNoYXBlQ2ZnKSwgeyBtYXBwaW5nRGF0YTogbWFwcGluZ0RhdGEsIGRhdGE6IHRoaXMuZ2V0RGF0YShtYXBwaW5nRGF0YSkgfSk7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5nZXREYXRhID0gZnVuY3Rpb24gKG1hcHBpbmdEYXRhKSB7XG4gICAgICAgIHJldHVybiBtYXBwaW5nRGF0YS5tYXAoZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIG9ialtjb25zdGFudF8xLkZJRUxEX09SSUdJTl07XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEhlYXRtYXA7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIZWF0bWFwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aGVhdG1hcC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvb3JkaW5hdGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2Nvb3JkaW5hdGVcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG4vKiog5byV5YWl5a+55bqU55qEIFNoYXBlRmFjdG9yeSAqL1xucmVxdWlyZShcIi4vc2hhcGUvaW50ZXJ2YWxcIik7XG52YXIgc2hhcGVfc2l6ZV8xID0gcmVxdWlyZShcIi4vdXRpbC9zaGFwZS1zaXplXCIpO1xuLyoqXG4gKiBJbnRlcnZhbCDlh6DkvZXmoIforrDjgIJcbiAqIOeUqOS6jue7mOWItuafseeKtuWbvuOAgemlvOWbvuOAgeadoeW9ouWbvuOAgeeOq+eRsOWbvuetieOAglxuICovXG52YXIgSW50ZXJ2YWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSW50ZXJ2YWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gSW50ZXJ2YWwoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2ludGVydmFsJztcbiAgICAgICAgX3RoaXMuc2hhcGVUeXBlID0gJ2ludGVydmFsJztcbiAgICAgICAgX3RoaXMuZ2VuZXJhdGVQb2ludHMgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOiOt+WPluavj+adoeaVsOaNrueahCBTaGFwZSDnu5jliLbkv6Hmga9cbiAgICAgKiBAcGFyYW0gb2JqIOe7j+i/h+WIhue7hCAtPiDmlbDlrZfljJYgLT4gYWRqdXN0IOiwg+aVtOWQjueahOaVsOaNruiusOW9lVxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgSW50ZXJ2YWwucHJvdG90eXBlLmNyZWF0ZVNoYXBlUG9pbnRzQ2ZnID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVTaGFwZVBvaW50c0NmZy5jYWxsKHRoaXMsIG9iaik7XG4gICAgICAgIC8vIOiuoeeul+avj+S4qiBzaGFwZSDnmoQgc2l6ZVxuICAgICAgICB2YXIgc2l6ZTtcbiAgICAgICAgdmFyIHNpemVBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3NpemUnKTtcbiAgICAgICAgaWYgKHNpemVBdHRyKSB7XG4gICAgICAgICAgICBzaXplID0gdGhpcy5nZXRBdHRyaWJ1dGVWYWx1ZXMoc2l6ZUF0dHIsIG9iailbMF07XG4gICAgICAgICAgICAvLyDlvZLkuIDljJZcbiAgICAgICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5jb29yZGluYXRlO1xuICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVXaWR0aCA9IGNvb3JkaW5hdGVfMS5nZXRYRGltZW5zaW9uTGVuZ3RoKGNvb3JkaW5hdGUpO1xuICAgICAgICAgICAgc2l6ZSA9IHNpemUgLyBjb29yZGluYXRlV2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGVmYXVsdFNpemUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRTaXplID0gc2hhcGVfc2l6ZV8xLmdldERlZmF1bHRTaXplKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2l6ZSA9IHRoaXMuZGVmYXVsdFNpemU7XG4gICAgICAgIH1cbiAgICAgICAgY2ZnLnNpemUgPSBzaXplO1xuICAgICAgICByZXR1cm4gY2ZnO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6LCD5pW0IHkg6L2055qEIHNjYWxlIOiMg+WbtOOAglxuICAgICAqIOWvueS6jiBZIOi9tOS4uuaVsOWAvOi9tOafseeKtuWbvu+8jOm7mOiupOS7jiAwIOW8gOWniyDnlJ/plb/jgIJcbiAgICAgKi9cbiAgICBJbnRlcnZhbC5wcm90b3R5cGUuYWRqdXN0U2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWRqdXN0U2NhbGUuY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIHlTY2FsZSA9IHRoaXMuZ2V0WVNjYWxlKCk7XG4gICAgICAgIC8vIOeJueauiumAu+i+ke+8mumlvOWbvumcgOimgeWhq+WFhea7oeaVtOS4quepuumXtFxuICAgICAgICBpZiAodGhpcy5jb29yZGluYXRlLnR5cGUgPT09ICd0aGV0YScpIHtcbiAgICAgICAgICAgIHlTY2FsZS5jaGFuZ2Uoe1xuICAgICAgICAgICAgICAgIG5pY2U6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgICAvLyDlj5HnlJ/ov4cgc3RhY2sg6LCD5pW077yMeVNjYWxlIOeahCBtYXgg6KKr6LCD5pW06L+H77yMdGhpcy51cGRhdGVTdGFja1JhbmdlKClcbiAgICAgICAgICAgICAgICBtYXg6IE1hdGgubWF4KE1hdGgubWF4LmFwcGx5KG51bGwsIHlTY2FsZS52YWx1ZXMpLCB5U2NhbGUubWF4KSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5p+x54q25Zu+5pWw5YC86L206buY6K6k5LuOIDAg5byA5aeLXG4gICAgICAgICAgICB2YXIgc2NhbGVEZWZzID0gdGhpcy5zY2FsZURlZnM7XG4gICAgICAgICAgICB2YXIgZmllbGQgPSB5U2NhbGUuZmllbGQsIG1pbiA9IHlTY2FsZS5taW4sIG1heCA9IHlTY2FsZS5tYXgsIHR5cGUgPSB5U2NhbGUudHlwZTtcbiAgICAgICAgICAgIGlmICh0eXBlICE9PSAndGltZScpIHtcbiAgICAgICAgICAgICAgICAvLyB0aW1lIOexu+Wei+S4jeWBmuiwg+aVtFxuICAgICAgICAgICAgICAgIC8vIOafseeKtuWbvueahCBZIOi9tOimgeS7jiAwIOW8gOWni+eUn+mVv++8jOS9huaYr+WmguaenOeUqOaIt+iuvue9ruS6huWImeS7peeUqOaIt+eahOS4uuWHhlxuICAgICAgICAgICAgICAgIGlmIChtaW4gPiAwICYmICF1dGlsXzEuZ2V0KHNjYWxlRGVmcywgW2ZpZWxkLCAnbWluJ10pKSB7XG4gICAgICAgICAgICAgICAgICAgIHlTY2FsZS5jaGFuZ2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g5p+x5b2T5p+x54q25Zu+5YWo5Li66LSf5YC85pe25Lmf6ZyA6KaB5LuOIDAg5byA5aeL55Sf6ZW/77yM5L2G5piv5aaC5p6c55So5oi36K6+572u5LqG5YiZ5Lul55So5oi355qE5Li65YeGXG4gICAgICAgICAgICAgICAgaWYgKG1heCA8PSAwICYmICF1dGlsXzEuZ2V0KHNjYWxlRGVmcywgW2ZpZWxkLCAnbWF4J10pKSB7XG4gICAgICAgICAgICAgICAgICAgIHlTY2FsZS5jaGFuZ2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBJbnRlcnZhbDtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEludGVydmFsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJ2YWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uLy4uL2NvbnN0YW50XCIpO1xudmFyIGFuaW1hdGVfMSA9IHJlcXVpcmUoXCIuLi8uLi9hbmltYXRlXCIpO1xudmFyIGdyYXBoaWNzXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ncmFwaGljc1wiKTtcbnZhciBsYWJlbHNfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnQvbGFiZWxzXCIpKTtcbmZ1bmN0aW9uIGF2ZyhhcnIpIHtcbiAgICB2YXIgc3VtID0gMDtcbiAgICB1dGlsXzEuZWFjaChhcnIsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBzdW0gKz0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHN1bSAvIGFyci5sZW5ndGg7XG59XG4vKipcbiAqIEdlb21ldHJ5IExhYmVsIOWfuuexu++8jOeUqOS6jueUn+aIkCBHZW9tZXRyeSDkuIvmiYDmnIkgbGFiZWwg55qE6YWN572u6aG55L+h5oGvXG4gKi9cbnZhciBHZW9tZXRyeUxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdlb21ldHJ5TGFiZWwoZ2VvbWV0cnkpIHtcbiAgICAgICAgdGhpcy5nZW9tZXRyeSA9IGdlb21ldHJ5O1xuICAgIH1cbiAgICBHZW9tZXRyeUxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbEl0ZW1zID0gZnVuY3Rpb24gKG1hcHBwaW5nQXJyYXkpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGl0ZW1zID0gW107XG4gICAgICAgIHZhciBsYWJlbENmZ3MgPSB0aGlzLmdldExhYmVsQ2ZncyhtYXBwcGluZ0FycmF5KTtcbiAgICAgICAgLy8g6I635Y+WIGxhYmVsIOebuOWFs+eahCB477yMeSDnmoTlgLzvvIzojrflj5blhbfkvZPnmoQgeCwgee+8jOmYsuatouWtmOWcqOaVsOe7hFxuICAgICAgICB1dGlsXzEuZWFjaChtYXBwcGluZ0FycmF5LCBmdW5jdGlvbiAobWFwcGluZ0RhdGEsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgbGFiZWxDZmcgPSBsYWJlbENmZ3NbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKCFsYWJlbENmZyB8fCB1dGlsXzEuaXNOaWwobWFwcGluZ0RhdGEueCkgfHwgdXRpbF8xLmlzTmlsKG1hcHBpbmdEYXRhLnkpKSB7XG4gICAgICAgICAgICAgICAgaXRlbXMucHVzaChudWxsKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbGFiZWxDb250ZW50ID0gIXV0aWxfMS5pc0FycmF5KGxhYmVsQ2ZnLmNvbnRlbnQpID8gW2xhYmVsQ2ZnLmNvbnRlbnRdIDogbGFiZWxDZmcuY29udGVudDtcbiAgICAgICAgICAgIGxhYmVsQ2ZnLmNvbnRlbnQgPSBsYWJlbENvbnRlbnQ7XG4gICAgICAgICAgICB2YXIgdG90YWwgPSBsYWJlbENvbnRlbnQubGVuZ3RoO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxDb250ZW50LCBmdW5jdGlvbiAoY29udGVudCwgc3ViSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzTmlsKGNvbnRlbnQpIHx8IGNvbnRlbnQgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2gobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGxhYmVsQ2ZnKSwgX3RoaXMuZ2V0TGFiZWxQb2ludChsYWJlbENmZywgbWFwcGluZ0RhdGEsIHN1YkluZGV4KSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtLnRleHRBbGlnbikge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLnRleHRBbGlnbiA9IF90aGlzLmdldExhYmVsQWxpZ24oaXRlbSwgc3ViSW5kZXgsIHRvdGFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0ub2Zmc2V0IDw9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5sYWJlbExpbmUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfTtcbiAgICBHZW9tZXRyeUxhYmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAobWFwcHBpbmdBcnJheSwgaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKGlzVXBkYXRlID09PSB2b2lkIDApIHsgaXNVcGRhdGUgPSBmYWxzZTsgfVxuICAgICAgICB2YXIgbGFiZWxJdGVtcyA9IHRoaXMuZ2V0TGFiZWxJdGVtcyhtYXBwcGluZ0FycmF5KTtcbiAgICAgICAgdmFyIGxhYmVsc1JlbmRlcmVyID0gdGhpcy5nZXRMYWJlbHNSZW5kZXJlcigpO1xuICAgICAgICB2YXIgc2hhcGVzID0gdGhpcy5nZXRHZW9tZXRyeVNoYXBlcygpO1xuICAgICAgICAvLyDmuLLmn5PmlofmnKxcbiAgICAgICAgbGFiZWxzUmVuZGVyZXIucmVuZGVyKGxhYmVsSXRlbXMsIHNoYXBlcywgaXNVcGRhdGUpO1xuICAgIH07XG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYWJlbHNSZW5kZXJlciA9IHRoaXMubGFiZWxzUmVuZGVyZXI7XG4gICAgICAgIGlmIChsYWJlbHNSZW5kZXJlcikge1xuICAgICAgICAgICAgbGFiZWxzUmVuZGVyZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxhYmVsc1JlbmRlcmVyID0gdGhpcy5sYWJlbHNSZW5kZXJlcjtcbiAgICAgICAgaWYgKGxhYmVsc1JlbmRlcmVyKSB7XG4gICAgICAgICAgICBsYWJlbHNSZW5kZXJlci5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sYWJlbHNSZW5kZXJlciA9IG51bGw7XG4gICAgfTtcbiAgICAvLyBnZW9tZXRyeSDmm7TmlrDkuYvlkI7vvIzlr7nlupTnmoQgQ29vcmRpbmF0ZSDkuZ/kvJrmm7TmlrDvvIzkuLrkuobojrflj5bliLDmnIDmlrDpspznmoQgQ29vcmRpbmF0Ze+8jOaVheS9v+eUqOaWueazleiOt+WPllxuICAgIEdlb21ldHJ5TGFiZWwucHJvdG90eXBlLmdldENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdlb21ldHJ5LmNvb3JkaW5hdGU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5YgbGFiZWwg55qE6buY6K6k6YWN572uXG4gICAgICovXG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdExhYmVsQ2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldCh0aGlzLmdlb21ldHJ5LnRoZW1lLCAnbGFiZWxzJywge30pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572uIGxhYmVsIOS9jee9rlxuICAgICAqIEBwYXJhbSBsYWJlbFBvaW50Q2ZnXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhXG4gICAgICogQHBhcmFtIGluZGV4XG4gICAgICogQHBhcmFtIHBvc2l0aW9uXG4gICAgICovXG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuc2V0TGFiZWxQb3NpdGlvbiA9IGZ1bmN0aW9uIChsYWJlbFBvaW50Q2ZnLCBtYXBwaW5nRGF0YSwgaW5kZXgsIHBvc2l0aW9uKSB7IH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5paH5pys6buY6K6k5YGP56e76YePXG4gICAgICogQHBhcmFtIG9mZnNldFxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHZlY3RvciA9IHRoaXMuZ2V0T2Zmc2V0VmVjdG9yKG9mZnNldCk7XG4gICAgICAgIHJldHVybiBjb29yZGluYXRlLmlzVHJhbnNwb3NlZCA/IHZlY3RvclswXSA6IHZlY3RvclsxXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluavj+S4qiBsYWJlbCDnmoTlgY/np7vph49cbiAgICAgKiBAcGFyYW0gbGFiZWxDZmdcbiAgICAgKiBAcGFyYW0gaW5kZXhcbiAgICAgKiBAcGFyYW0gdG90YWxcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIEdlb21ldHJ5TGFiZWwucHJvdG90eXBlLmdldExhYmVsT2Zmc2V0ID0gZnVuY3Rpb24gKGxhYmVsQ2ZnLCBpbmRleCwgdG90YWwpIHtcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMuZ2V0RGVmYXVsdE9mZnNldChsYWJlbENmZy5vZmZzZXQpO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgdHJhbnNwb3NlZCA9IGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkO1xuICAgICAgICB2YXIgZGltID0gdHJhbnNwb3NlZCA/ICd4JyA6ICd5JztcbiAgICAgICAgdmFyIGZhY3RvciA9IHRyYW5zcG9zZWQgPyAxIDogLTE7IC8vIHkg5pa55ZCR5LiK6LaK5aSn77yM5YOP57Sg55qE5Z2Q5qCH6LaK5bCP77yM5omA5LuldHJhbnNwb3NlZOaXtuWwhuezu+aVsOWPmOaIkFxuICAgICAgICB2YXIgb2Zmc2V0UG9pbnQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluZGV4ID4gMCB8fCB0b3RhbCA9PT0gMSkge1xuICAgICAgICAgICAgLy8g5Yik5pat5piv5ZCm5bCP5LqOMFxuICAgICAgICAgICAgb2Zmc2V0UG9pbnRbZGltXSA9IG9mZnNldCAqIGZhY3RvcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9mZnNldFBvaW50W2RpbV0gPSBvZmZzZXQgKiBmYWN0b3IgKiAtMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2Zmc2V0UG9pbnQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmr4/kuKogbGFiZWwg55qE5L2N572uXG4gICAgICogQHBhcmFtIGxhYmVsQ2ZnXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhXG4gICAgICogQHBhcmFtIGluZGV4XG4gICAgICogQHJldHVybnMgbGFiZWwgcG9pbnRcbiAgICAgKi9cbiAgICBHZW9tZXRyeUxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbFBvaW50ID0gZnVuY3Rpb24gKGxhYmVsQ2ZnLCBtYXBwaW5nRGF0YSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHRvdGFsID0gbGFiZWxDZmcuY29udGVudC5sZW5ndGg7XG4gICAgICAgIGZ1bmN0aW9uIGdldERpbVZhbHVlKHZhbHVlLCBpZHgpIHtcbiAgICAgICAgICAgIHZhciB2ID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkodikpIHtcbiAgICAgICAgICAgICAgICBpZiAobGFiZWxDZmcuY29udGVudC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5LuF5LiA5LiqIGxhYmVs77yM5aSa5LiqIHksIOWPluacgOWQjuS4gOS4qiB5XG4gICAgICAgICAgICAgICAgICAgIGlmICh2Lmxlbmd0aCA8PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ID0gdlt2YWx1ZS5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHYgPSBhdmcodik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHYgPSB2W2lkeF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGxhYmVsID0ge1xuICAgICAgICAgICAgY29udGVudDogbGFiZWxDZmcuY29udGVudFtpbmRleF0sXG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgIHN0YXJ0OiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgICAgIGNvbG9yOiAnI2ZmZicsXG4gICAgICAgIH07XG4gICAgICAgIC8vIOWkmui+ueW9ouWcuuaZr++8jOWkmueUqOS6juWcsOWbvlxuICAgICAgICBpZiAobWFwcGluZ0RhdGEgJiYgdGhpcy5nZW9tZXRyeS50eXBlID09PSAncG9seWdvbicpIHtcbiAgICAgICAgICAgIHZhciBjZW50cm9pZCA9IGdyYXBoaWNzXzEuZ2V0UG9seWdvbkNlbnRyb2lkKG1hcHBpbmdEYXRhLngsIG1hcHBpbmdEYXRhLnkpO1xuICAgICAgICAgICAgbGFiZWwueCA9IGNlbnRyb2lkWzBdO1xuICAgICAgICAgICAgbGFiZWwueSA9IGNlbnRyb2lkWzFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGFiZWwueCA9IGdldERpbVZhbHVlKG1hcHBpbmdEYXRhLngsIGluZGV4KTtcbiAgICAgICAgICAgIGxhYmVsLnkgPSBnZXREaW1WYWx1ZShtYXBwaW5nRGF0YS55LCBpbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5aSE55CG5ryP5paX5Zu+5paH5pys5L2N572uXG4gICAgICAgIHZhciBzaGFwZSA9IHV0aWxfMS5pc0FycmF5KG1hcHBpbmdEYXRhLnNoYXBlKSA/IG1hcHBpbmdEYXRhLnNoYXBlWzBdIDogbWFwcGluZ0RhdGEuc2hhcGU7XG4gICAgICAgIGlmIChzaGFwZSA9PT0gJ2Z1bm5lbCcgfHwgc2hhcGUgPT09ICdweXJhbWlkJykge1xuICAgICAgICAgICAgdmFyIG5leHRQb2ludHMgPSB1dGlsXzEuZ2V0KG1hcHBpbmdEYXRhLCAnbmV4dFBvaW50cycpO1xuICAgICAgICAgICAgdmFyIHBvaW50cyA9IHV0aWxfMS5nZXQobWFwcGluZ0RhdGEsICdwb2ludHMnKTtcbiAgICAgICAgICAgIGlmIChuZXh0UG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgLy8g6Z2e5ryP5paX5Zu+5bqV6YOoXG4gICAgICAgICAgICAgICAgdmFyIHBvaW50MSA9IGNvb3JkaW5hdGUuY29udmVydChwb2ludHNbMV0pO1xuICAgICAgICAgICAgICAgIHZhciBwb2ludDIgPSBjb29yZGluYXRlLmNvbnZlcnQobmV4dFBvaW50c1sxXSk7XG4gICAgICAgICAgICAgICAgbGFiZWwueCA9IChwb2ludDEueCArIHBvaW50Mi54KSAvIDI7XG4gICAgICAgICAgICAgICAgbGFiZWwueSA9IChwb2ludDEueSArIHBvaW50Mi55KSAvIDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChzaGFwZSA9PT0gJ3B5cmFtaWQnKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBvaW50MSA9IGNvb3JkaW5hdGUuY29udmVydChwb2ludHNbMV0pO1xuICAgICAgICAgICAgICAgIHZhciBwb2ludDIgPSBjb29yZGluYXRlLmNvbnZlcnQocG9pbnRzWzJdKTtcbiAgICAgICAgICAgICAgICBsYWJlbC54ID0gKHBvaW50MS54ICsgcG9pbnQyLngpIC8gMjtcbiAgICAgICAgICAgICAgICBsYWJlbC55ID0gKHBvaW50MS55ICsgcG9pbnQyLnkpIC8gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobGFiZWxDZmcucG9zaXRpb24pIHtcbiAgICAgICAgICAgIC8vIOWmguaenCBsYWJlbCDmlK/mjIEgcG9zaXRpb24g5bGe5oCnXG4gICAgICAgICAgICB0aGlzLnNldExhYmVsUG9zaXRpb24obGFiZWwsIG1hcHBpbmdEYXRhLCBpbmRleCwgbGFiZWxDZmcucG9zaXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvZmZzZXRQb2ludCA9IHRoaXMuZ2V0TGFiZWxPZmZzZXQobGFiZWxDZmcsIGluZGV4LCB0b3RhbCk7XG4gICAgICAgIGxhYmVsLnN0YXJ0ID0geyB4OiBsYWJlbC54LCB5OiBsYWJlbC55IH07XG4gICAgICAgIGxhYmVsLnggKz0gb2Zmc2V0UG9pbnQueDtcbiAgICAgICAgbGFiZWwueSArPSBvZmZzZXRQb2ludC55O1xuICAgICAgICBsYWJlbC5jb2xvciA9IG1hcHBpbmdEYXRhLmNvbG9yO1xuICAgICAgICByZXR1cm4gbGFiZWw7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmlofmnKznmoTlr7npvZDmlrnlvI9cbiAgICAgKiBAcGFyYW0gaXRlbVxuICAgICAqIEBwYXJhbSBpbmRleFxuICAgICAqIEBwYXJhbSB0b3RhbFxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuZ2V0TGFiZWxBbGlnbiA9IGZ1bmN0aW9uIChpdGVtLCBpbmRleCwgdG90YWwpIHtcbiAgICAgICAgdmFyIGFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIGlmIChjb29yZGluYXRlLmlzVHJhbnNwb3NlZCkge1xuICAgICAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMuZ2V0RGVmYXVsdE9mZnNldChpdGVtLm9mZnNldCk7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgICAgIGFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG9mZnNldCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0b3RhbCA+IDEgJiYgaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICBpZiAoYWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAnbGVmdCc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAncmlnaHQnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWxpZ247XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5bmr4/kuIDkuKogbGFiZWwg55qE5ZSv5LiAIGlkXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhIGxhYmVsIOWvueW6lOeahOWbvuW9oueahOe7mOWItuaVsOaNrlxuICAgICAqL1xuICAgIEdlb21ldHJ5TGFiZWwucHJvdG90eXBlLmdldExhYmVsSWQgPSBmdW5jdGlvbiAobWFwcGluZ0RhdGEpIHtcbiAgICAgICAgdmFyIGdlb21ldHJ5ID0gdGhpcy5nZW9tZXRyeTtcbiAgICAgICAgdmFyIHR5cGUgPSBnZW9tZXRyeS50eXBlO1xuICAgICAgICB2YXIgeFNjYWxlID0gZ2VvbWV0cnkuZ2V0WFNjYWxlKCk7XG4gICAgICAgIHZhciB5U2NhbGUgPSBnZW9tZXRyeS5nZXRZU2NhbGUoKTtcbiAgICAgICAgdmFyIG9yaWdpbiA9IG1hcHBpbmdEYXRhW2NvbnN0YW50XzEuRklFTERfT1JJR0lOXTsgLy8g5Y6f5aeL5pWw5o2uXG4gICAgICAgIHZhciBsYWJlbElkID0gZ2VvbWV0cnkuZ2V0RWxlbWVudElkKG1hcHBpbmdEYXRhKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdsaW5lJyB8fCB0eXBlID09PSAnYXJlYScpIHtcbiAgICAgICAgICAgIC8vIOaKmOe6v+WbvuS7peWPiuWMuuWfn+Wbvu+8jOS4gOadoee6v+S8muWvueW6lOS4gOe7hOaVsOaNru+8jOWNs+WkmuS4qiBsYWJlbHPvvIzkuLrkuobljLrliIbov5nkupsgbGFiZWxz77yM6ZyA6KaB5ZyoIGxpbmUgaWQg55qE5YmN5o+Q5LiL5Yqg5LiKIHgg5a2X5q615YC8XG4gICAgICAgICAgICBsYWJlbElkICs9IFwiIFwiICsgb3JpZ2luW3hTY2FsZS5maWVsZF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ3BhdGgnKSB7XG4gICAgICAgICAgICAvLyBwYXRoIOi3r+W+hOWbvu+8jOaXoOW6j++8jOacieWPr+iDveWtmOWcqOebuOWQjCB4IOS4jeWQjCB5IOeahOaDheWGte+8jOmcgOimgemAmui/hyB4IHkg5p2l56Gu5a6a5ZSv5LiAIGlkXG4gICAgICAgICAgICBsYWJlbElkICs9IFwiIFwiICsgb3JpZ2luW3hTY2FsZS5maWVsZF0gKyBcIi1cIiArIG9yaWdpblt5U2NhbGUuZmllbGRdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYWJlbElkO1xuICAgIH07XG4gICAgLy8g6I635Y+WIGxhYmVscyDnu4Tku7ZcbiAgICBHZW9tZXRyeUxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbHNSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZW9tZXRyeSwgbGFiZWxzQ29udGFpbmVyID0gX2EubGFiZWxzQ29udGFpbmVyLCBsYWJlbE9wdGlvbiA9IF9hLmxhYmVsT3B0aW9uLCBjYW52YXNSZWdpb24gPSBfYS5jYW52YXNSZWdpb24sIGFuaW1hdGVPcHRpb24gPSBfYS5hbmltYXRlT3B0aW9uO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2VvbWV0cnkuY29vcmRpbmF0ZTtcbiAgICAgICAgdmFyIGxhYmVsc1JlbmRlcmVyID0gdGhpcy5sYWJlbHNSZW5kZXJlcjtcbiAgICAgICAgaWYgKCFsYWJlbHNSZW5kZXJlcikge1xuICAgICAgICAgICAgbGFiZWxzUmVuZGVyZXIgPSBuZXcgbGFiZWxzXzEuZGVmYXVsdCh7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiBsYWJlbHNDb250YWluZXIsXG4gICAgICAgICAgICAgICAgbGF5b3V0OiB1dGlsXzEuZ2V0KGxhYmVsT3B0aW9uLCBbJ2NmZycsICdsYXlvdXQnXSwge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLmRlZmF1bHRMYXlvdXQsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubGFiZWxzUmVuZGVyZXIgPSBsYWJlbHNSZW5kZXJlcjtcbiAgICAgICAgfVxuICAgICAgICBsYWJlbHNSZW5kZXJlci5yZWdpb24gPSBjYW52YXNSZWdpb247XG4gICAgICAgIC8vIOiuvue9ruWKqOeUu+mFjee9ru+8jOWmguaenCBnZW9tZXRyeSDnmoTliqjnlLvlhbPpl63kuobvvIzpgqPkuYggbGFiZWwg55qE5Yqo55S75Lmf5Lya5YWz6ZetXG4gICAgICAgIGxhYmVsc1JlbmRlcmVyLmFuaW1hdGUgPSBhbmltYXRlT3B0aW9uID8gYW5pbWF0ZV8xLmdldERlZmF1bHRBbmltYXRlQ2ZnKCdsYWJlbCcsIGNvb3JkaW5hdGUpIDogZmFsc2U7XG4gICAgICAgIHJldHVybiBsYWJlbHNSZW5kZXJlcjtcbiAgICB9O1xuICAgIEdlb21ldHJ5TGFiZWwucHJvdG90eXBlLmdldExhYmVsQ2ZncyA9IGZ1bmN0aW9uIChtYXBwcGluZ0FycmF5KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBnZW9tZXRyeSA9IHRoaXMuZ2VvbWV0cnk7XG4gICAgICAgIHZhciBkZWZhdWx0TGFiZWxDZmcgPSB0aGlzLmdldERlZmF1bHRMYWJlbENmZygpO1xuICAgICAgICB2YXIgdHlwZSA9IGdlb21ldHJ5LnR5cGUsIHRoZW1lID0gZ2VvbWV0cnkudGhlbWUsIGxhYmVsT3B0aW9uID0gZ2VvbWV0cnkubGFiZWxPcHRpb24sIHNjYWxlcyA9IGdlb21ldHJ5LnNjYWxlcywgY29vcmRpbmF0ZSA9IGdlb21ldHJ5LmNvb3JkaW5hdGU7XG4gICAgICAgIHZhciBfYSA9IGxhYmVsT3B0aW9uLCBmaWVsZHMgPSBfYS5maWVsZHMsIGNhbGxiYWNrID0gX2EuY2FsbGJhY2ssIGNmZyA9IF9hLmNmZztcbiAgICAgICAgdmFyIGxhYmVsU2NhbGVzID0gZmllbGRzLm1hcChmdW5jdGlvbiAoZmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FsZXNbZmllbGRdO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGxhYmVsQ2ZncyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChtYXBwcGluZ0FycmF5LCBmdW5jdGlvbiAobWFwcGluZ0RhdGEsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgb3JpZ2luID0gbWFwcGluZ0RhdGFbY29uc3RhbnRfMS5GSUVMRF9PUklHSU5dOyAvLyDljp/lp4vmlbDmja5cbiAgICAgICAgICAgIHZhciBvcmlnaW5UZXh0ID0gX3RoaXMuZ2V0TGFiZWxUZXh0KG9yaWdpbiwgbGFiZWxTY2FsZXMpO1xuICAgICAgICAgICAgdmFyIGNhbGxiYWNrQ2ZnO1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgLy8g5b2T5ZCM5pe26YWN572u5LqGIGNhbGxiYWNrIOWSjCBjZmcg5pe277yM5LulIGNhbGxiYWNrIOS4uuWHhlxuICAgICAgICAgICAgICAgIHZhciBvcmlnaW5WYWx1ZXMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uIChmaWVsZCkgeyByZXR1cm4gb3JpZ2luW2ZpZWxkXTsgfSk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2tDZmcgPSBjYWxsYmFjay5hcHBseSh2b2lkIDAsIG9yaWdpblZhbHVlcyk7XG4gICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc05pbChjYWxsYmFja0NmZykpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxDZmdzLnB1c2gobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbGFiZWxDZmcgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyBpZDogX3RoaXMuZ2V0TGFiZWxJZChtYXBwaW5nRGF0YSksIGRhdGE6IG9yaWdpbiwgLy8g5a2Y5YKo5Y6f5aeL5pWw5o2uXG4gICAgICAgICAgICAgICAgbWFwcGluZ0RhdGE6IG1hcHBpbmdEYXRhLFxuICAgICAgICAgICAgICAgIGNvb3JkaW5hdGU6IGNvb3JkaW5hdGUgfSwgY2ZnKSwgY2FsbGJhY2tDZmcpO1xuICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSBsYWJlbENmZy5jb250ZW50O1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGNvbnRlbnQpKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxDZmcuY29udGVudCA9IGNvbnRlbnQob3JpZ2luLCBtYXBwaW5nRGF0YSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzVW5kZWZpbmVkKGNvbnRlbnQpKSB7XG4gICAgICAgICAgICAgICAgLy8g55So5oi35pyq6YWN572uIGNvbnRlbnTvvIzliJnpu5jorqTkuLrmmKDlsITnmoTnrKzkuIDkuKrlrZfmrrXnmoTlgLxcbiAgICAgICAgICAgICAgICBsYWJlbENmZy5jb250ZW50ID0gb3JpZ2luVGV4dFswXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihsYWJlbENmZy5wb3NpdGlvbikpIHtcbiAgICAgICAgICAgICAgICBsYWJlbENmZy5wb3NpdGlvbiA9IGxhYmVsQ2ZnLnBvc2l0aW9uKG9yaWdpbiwgbWFwcGluZ0RhdGEsIGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAncG9seWdvbicgfHwgKGxhYmVsQ2ZnLm9mZnNldCA8IDAgJiYgIVsnbGluZScsICdwb2ludCcsICdwYXRoJ10uaW5jbHVkZXModHlwZSkpKSB7XG4gICAgICAgICAgICAgICAgLy8gcG9seWdvbiDmiJbogIUgb2Zmc2V0IOWwj+S6jiAwIOaXtu+8jOaWh+acrOWxleekuuWcqOWbvuW9ouWGhemDqO+8jOWwhuWFtuminOiJsuiuvue9ruS4uiDnmb3oibJcbiAgICAgICAgICAgICAgICBsYWJlbENmZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBkZWZhdWx0TGFiZWxDZmcsIHRoZW1lLmlubmVyTGFiZWxzLCBsYWJlbENmZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsYWJlbENmZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBkZWZhdWx0TGFiZWxDZmcsIHRoZW1lLmxhYmVscywgbGFiZWxDZmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFiZWxDZmdzLnB1c2gobGFiZWxDZmcpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGxhYmVsQ2ZncztcbiAgICB9O1xuICAgIEdlb21ldHJ5TGFiZWwucHJvdG90eXBlLmdldExhYmVsVGV4dCA9IGZ1bmN0aW9uIChvcmlnaW4sIHNjYWxlcykge1xuICAgICAgICB2YXIgbGFiZWxUZXh0cyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChzY2FsZXMsIGZ1bmN0aW9uIChzY2FsZSkge1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gb3JpZ2luW3NjYWxlLmZpZWxkXTtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLm1hcChmdW5jdGlvbiAoc3ViVmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2FsZS5nZXRUZXh0KHN1YlZhbCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHNjYWxlLmdldFRleHQodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc05pbCh2YWx1ZSkgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxUZXh0cy5wdXNoKG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGFiZWxUZXh0cy5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBsYWJlbFRleHRzO1xuICAgIH07XG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuZ2V0T2Zmc2V0VmVjdG9yID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICAgICAgICBpZiAob2Zmc2V0ID09PSB2b2lkIDApIHsgb2Zmc2V0ID0gMDsgfVxuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICAvLyDlpoLmnpwgeCx5IOe/u+i9rO+8jOWImeWBj+enuyB477yM5ZCm5YiZ5YGP56e7IHlcbiAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkID8gY29vcmRpbmF0ZS5hcHBseU1hdHJpeChvZmZzZXQsIDApIDogY29vcmRpbmF0ZS5hcHBseU1hdHJpeCgwLCBvZmZzZXQpO1xuICAgIH07XG4gICAgR2VvbWV0cnlMYWJlbC5wcm90b3R5cGUuZ2V0R2VvbWV0cnlTaGFwZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBnZW9tZXRyeSA9IHRoaXMuZ2VvbWV0cnk7XG4gICAgICAgIHZhciBzaGFwZXMgPSB7fTtcbiAgICAgICAgdXRpbF8xLmVhY2goZ2VvbWV0cnkuZWxlbWVudHNNYXAsIGZ1bmN0aW9uIChlbGVtZW50LCBpZCkge1xuICAgICAgICAgICAgc2hhcGVzW2lkXSA9IGVsZW1lbnQuc2hhcGU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDlm6DkuLrmnInlj6/og70gc2hhcGUg6L+Y5Zyo6L+b6KGM5Yqo55S777yM5a+86Ie0IHNoYXBlLmdldEJCb3goKSDojrflj5bliLDnmoTlgLzkuI3mmK/mnIDnu4jmgIHvvIzmiYDku6XpnIDopoHku44gb2Zmc2NyZWVuR3JvdXAg6I635Y+WXG4gICAgICAgIHV0aWxfMS5lYWNoKGdlb21ldHJ5LmdldE9mZnNjcmVlbkdyb3VwKCkuZ2V0Q2hpbGRyZW4oKSwgZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICB2YXIgaWQgPSBnZW9tZXRyeS5nZXRFbGVtZW50SWQoY2hpbGQuZ2V0KCdvcmlnaW4nKS5tYXBwaW5nRGF0YSk7XG4gICAgICAgICAgICBzaGFwZXNbaWRdID0gY2hpbGQ7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2hhcGVzO1xuICAgIH07XG4gICAgcmV0dXJuIEdlb21ldHJ5TGFiZWw7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR2VvbWV0cnlMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyR2VvbWV0cnlMYWJlbExheW91dCA9IGV4cG9ydHMuZ2V0R2VvbWV0cnlMYWJlbExheW91dCA9IGV4cG9ydHMucmVnaXN0ZXJHZW9tZXRyeUxhYmVsID0gZXhwb3J0cy5nZXRHZW9tZXRyeUxhYmVsID0gdm9pZCAwO1xudmFyIEdFT01FVFJZX0xBQkVMU19NQVAgPSB7fTtcbnZhciBHRU9NRVRSWV9MQUJFTFNfTEFZT1VUX01BUCA9IHt9O1xuLyoqXG4gKiDojrflj5YgYHR5cGVgIOWvueW6lOeahCBbW0dlb21ldHJ5TGFiZWxdXSDnsbtcbiAqIEBwYXJhbSB0eXBlXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBnZXRHZW9tZXRyeUxhYmVsKHR5cGUpIHtcbiAgICByZXR1cm4gR0VPTUVUUllfTEFCRUxTX01BUFt0eXBlLnRvTG93ZXJDYXNlKCldO1xufVxuZXhwb3J0cy5nZXRHZW9tZXRyeUxhYmVsID0gZ2V0R2VvbWV0cnlMYWJlbDtcbi8qKlxuICog5rOo5YaM5a6a5LmJ55qEIEdlb21ldHJ5TGFiZWwg57G7XG4gKiBAcGFyYW0gdHlwZSBHZW9tZXRyeUxhYmVsIOexu+Wei+WQjeensFxuICogQHBhcmFtIGN0b3IgR2VvbWV0cnlMYWJlbCDnsbtcbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJHZW9tZXRyeUxhYmVsKHR5cGUsIGN0b3IpIHtcbiAgICBHRU9NRVRSWV9MQUJFTFNfTUFQW3R5cGUudG9Mb3dlckNhc2UoKV0gPSBjdG9yO1xufVxuZXhwb3J0cy5yZWdpc3Rlckdlb21ldHJ5TGFiZWwgPSByZWdpc3Rlckdlb21ldHJ5TGFiZWw7XG4vKipcbiAqIOiOt+WPliBgdHlwZWAg5a+55bqU55qEIFtbR2VvbWV0cnlMYWJlbHNMYXlvdXRGbl1dIGxhYmVsIOW4g+WxgOWHveaVsFxuICogQHBhcmFtIHR5cGUg5biD5bGA5Ye95pWw5ZCN56ewXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBnZXRHZW9tZXRyeUxhYmVsTGF5b3V0KHR5cGUpIHtcbiAgICByZXR1cm4gR0VPTUVUUllfTEFCRUxTX0xBWU9VVF9NQVBbdHlwZS50b0xvd2VyQ2FzZSgpXTtcbn1cbmV4cG9ydHMuZ2V0R2VvbWV0cnlMYWJlbExheW91dCA9IGdldEdlb21ldHJ5TGFiZWxMYXlvdXQ7XG4vKipcbiAqIOazqOWGjOWumuS5ieeahCBsYWJlbCDluIPlsYDlh73mlbBcbiAqIEBwYXJhbSB0eXBlIGxhYmVsIOW4g+WxgOWHveaVsOWQjeensFxuICogQHBhcmFtIGxheW91dEZuIGxhYmVsIOW4g+WxgOWHveaVsFxuICovXG5mdW5jdGlvbiByZWdpc3Rlckdlb21ldHJ5TGFiZWxMYXlvdXQodHlwZSwgbGF5b3V0Rm4pIHtcbiAgICBHRU9NRVRSWV9MQUJFTFNfTEFZT1VUX01BUFt0eXBlLnRvTG93ZXJDYXNlKCldID0gbGF5b3V0Rm47XG59XG5leHBvcnRzLnJlZ2lzdGVyR2VvbWV0cnlMYWJlbExheW91dCA9IHJlZ2lzdGVyR2VvbWV0cnlMYWJlbExheW91dDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG4vKipcbiAqIOafseeKtuWbviBsYWJlbFxuICovXG52YXIgSW50ZXJ2YWxMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhJbnRlcnZhbExhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEludGVydmFsTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgSW50ZXJ2YWxMYWJlbC5wcm90b3R5cGUuc2V0TGFiZWxQb3NpdGlvbiA9IGZ1bmN0aW9uIChsYWJlbFBvaW50Q2ZnLCBtYXBwaW5nRGF0YSwgaW5kZXgsIHBvc2l0aW9uKSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciB0cmFuc3Bvc2VkID0gY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQ7XG4gICAgICAgIHZhciBzaGFwZVBvaW50cyA9IG1hcHBpbmdEYXRhLnBvaW50cztcbiAgICAgICAgdmFyIHBvaW50MCA9IGNvb3JkaW5hdGUuY29udmVydChzaGFwZVBvaW50c1swXSk7XG4gICAgICAgIHZhciBwb2ludDEgPSBjb29yZGluYXRlLmNvbnZlcnQoc2hhcGVQb2ludHNbMl0pO1xuICAgICAgICB2YXIgZmxhZyA9IHRyYW5zcG9zZWQgPyAtMSA6IDE7XG4gICAgICAgIHZhciB3aWR0aCA9ICgocG9pbnQwLnggLSBwb2ludDEueCkgLyAyKSAqIGZsYWc7XG4gICAgICAgIHZhciBoZWlnaHQgPSAoKHBvaW50MC55IC0gcG9pbnQxLnkpIC8gMikgKiBmbGFnO1xuICAgICAgICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgaWYgKCF0cmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsUG9pbnRDZmcueCAtPSB3aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy55ICs9IGhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy50ZXh0QWxpZ24gPSB1dGlsXzEuZ2V0KGxhYmVsUG9pbnRDZmcsICd0ZXh0QWxpZ24nLCAnbGVmdCcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy54IC09IHdpZHRoICogMjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsUG9pbnRDZmcueCArPSB3aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy55ICs9IGhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy50ZXh0QWxpZ24gPSB1dGlsXzEuZ2V0KGxhYmVsUG9pbnRDZmcsICd0ZXh0QWxpZ24nLCAncmlnaHQnKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy54IC09IHdpZHRoO1xuICAgICAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnkgLT0gaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy55ICs9IGhlaWdodCAqIDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxhYmVsUG9pbnRDZmcudGV4dEFsaWduID0gdXRpbF8xLmdldChsYWJlbFBvaW50Q2ZnLCAndGV4dEFsaWduJywgJ2NlbnRlcicpO1xuICAgICAgICAgICAgICAgIGxhYmVsUG9pbnRDZmcudGV4dEJhc2VsaW5lID0gdXRpbF8xLmdldChsYWJlbFBvaW50Q2ZnLCAndGV4dEJhc2VsaW5lJywgJ3RvcCcpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWlkZGxlJzpcbiAgICAgICAgICAgICAgICBpZiAodHJhbnNwb3NlZCkge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnggLT0gd2lkdGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnkgKz0gaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnRleHRBbGlnbiA9IHV0aWxfMS5nZXQobGFiZWxQb2ludENmZywgJ3RleHRBbGlnbicsICdjZW50ZXInKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxQb2ludENmZy54IC09IHdpZHRoO1xuICAgICAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnkgKz0gaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnRleHRBbGlnbiA9IHV0aWxfMS5nZXQobGFiZWxQb2ludENmZywgJ3RleHRBbGlnbicsICdjZW50ZXInKTtcbiAgICAgICAgICAgICAgICBsYWJlbFBvaW50Q2ZnLnRleHRCYXNlbGluZSA9IHV0aWxfMS5nZXQobGFiZWxQb2ludENmZywgJ3RleHRCYXNlbGluZScsICdib3R0b20nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBJbnRlcnZhbExhYmVsO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSW50ZXJ2YWxMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludGVydmFsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5saW1pdEluQ2FudmFzID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHRyYW5zZm9ybV8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvdHJhbnNmb3JtXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDlsIYgbGFiZWwg6ZmQ5Yi25Zyo55S75biD6IyD5Zu05YaF77yM566A5Y2V5b6X5bCG6LaF5Ye655S75biD55qEIGxhYmVsIOW+gOeUu+W4g+WGheiwg+aVtFxuICogQHBhcmFtIGxhYmVsc1xuICogQHBhcmFtIGNmZ1xuICovXG5mdW5jdGlvbiBsaW1pdEluQ2FudmFzKGl0ZW1zLCBsYWJlbHMsIHNoYXBlcywgcmVnaW9uKSB7XG4gICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgdmFyIHJlZ2lvbk1pblggPSByZWdpb24ubWluWCwgcmVnaW9uTWluWSA9IHJlZ2lvbi5taW5ZLCByZWdpb25NYXhYID0gcmVnaW9uLm1heFgsIHJlZ2lvbk1heFkgPSByZWdpb24ubWF4WTtcbiAgICAgICAgdmFyIF9hID0gbGFiZWwuZ2V0Q2FudmFzQkJveCgpLCBtaW5YID0gX2EubWluWCwgbWluWSA9IF9hLm1pblksIG1heFggPSBfYS5tYXhYLCBtYXhZID0gX2EubWF4WSwgeCA9IF9hLngsIHkgPSBfYS55LCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgIHZhciBmaW5hbFggPSB4O1xuICAgICAgICB2YXIgZmluYWxZID0geTtcbiAgICAgICAgaWYgKG1pblggPCByZWdpb25NaW5YIHx8IG1heFggPCByZWdpb25NaW5YKSB7XG4gICAgICAgICAgICAvLyDotoXlh7rlt6bkvqdcbiAgICAgICAgICAgIGZpbmFsWCA9IHJlZ2lvbk1pblg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1pblkgPCByZWdpb25NaW5ZIHx8IG1heFkgPCByZWdpb25NaW5ZKSB7XG4gICAgICAgICAgICAvLyDotoXlh7rpobbpg6hcbiAgICAgICAgICAgIGZpbmFsWSA9IHJlZ2lvbk1pblk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1pblggPiByZWdpb25NYXhYKSB7XG4gICAgICAgICAgICAvLyDmlbTkvZPotoXlh7rlj7PkvqdcbiAgICAgICAgICAgIGZpbmFsWCA9IHJlZ2lvbk1heFggLSB3aWR0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtYXhYID4gcmVnaW9uTWF4WCkge1xuICAgICAgICAgICAgLy8g6LaF5Ye65Y+z5L6nXG4gICAgICAgICAgICBmaW5hbFggPSBmaW5hbFggLSAobWF4WCAtIHJlZ2lvbk1heFgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaW5ZID4gcmVnaW9uTWF4WSkge1xuICAgICAgICAgICAgLy8g5pW05L2T6LaF5Ye66aG26YOoXG4gICAgICAgICAgICBmaW5hbFkgPSByZWdpb25NYXhZIC0gaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1heFkgPiByZWdpb25NYXhZKSB7XG4gICAgICAgICAgICAvLyDotoXlh7rlupXpg6hcbiAgICAgICAgICAgIGZpbmFsWSA9IGZpbmFsWSAtIChtYXhZIC0gcmVnaW9uTWF4WSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbmFsWCAhPT0geCB8fCBmaW5hbFkgIT09IHkpIHtcbiAgICAgICAgICAgIHRyYW5zZm9ybV8xLnRyYW5zbGF0ZShsYWJlbCwgZmluYWxYIC0geCwgZmluYWxZIC0geSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydHMubGltaXRJbkNhbnZhcyA9IGxpbWl0SW5DYW52YXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW1pdC1pbi1jYW52YXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmxpbWl0SW5TaGFwZSA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog5qC55o2u5Zu+5b2i5YWD57Sg5Lul5Y+KIGxhYmVsIOeahCBiYm94IOi/m+ihjOiwg+aVtO+8jOWmguaenCBsYWJlbCDotoXlh7rkuoYgc2hhcGUg55qEIGJib3gg5YiZ5LiN5bGV56S6XG4gKi9cbmZ1bmN0aW9uIGxpbWl0SW5TaGFwZShpdGVtcywgbGFiZWxzLCBzaGFwZXMsIHJlZ2lvbikge1xuICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsLCBpbmRleCkge1xuICAgICAgICB2YXIgbGFiZWxCQm94ID0gbGFiZWwuZ2V0Q2FudmFzQkJveCgpOyAvLyDmlofmnKzmnInlj6/og73lj5HnlJ/ml4vovaxcbiAgICAgICAgdmFyIHNoYXBlQkJveCA9IHNoYXBlc1tpbmRleF0uZ2V0QkJveCgpO1xuICAgICAgICBpZiAobGFiZWxCQm94Lm1pblggPCBzaGFwZUJCb3gubWluWCB8fFxuICAgICAgICAgICAgbGFiZWxCQm94Lm1pblkgPCBzaGFwZUJCb3gubWluWSB8fFxuICAgICAgICAgICAgbGFiZWxCQm94Lm1heFggPiBzaGFwZUJCb3gubWF4WCB8fFxuICAgICAgICAgICAgbGFiZWxCQm94Lm1heFkgPiBzaGFwZUJCb3gubWF4WSkge1xuICAgICAgICAgICAgbGFiZWwucmVtb3ZlKHRydWUpOyAvLyDotoXlh7rliJnkuI3lsZXnpLpcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5saW1pdEluU2hhcGUgPSBsaW1pdEluU2hhcGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW1pdC1pbi1zaGFwZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub3ZlcmxhcCA9IGV4cG9ydHMuZml4ZWRPdmVybGFwID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIE1BWF9USU1FUyA9IDEwMDtcbi8qKlxuICogQGlnbm9yZVxuICogR3JlZWR5IOi0quWpqueul+azlVxuICovXG52YXIgR3JlZWR5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdyZWVkeShjZmcpIHtcbiAgICAgICAgaWYgKGNmZyA9PT0gdm9pZCAwKSB7IGNmZyA9IHt9OyB9XG4gICAgICAgIHRoaXMuYml0bWFwID0ge307XG4gICAgICAgIHZhciBfYSA9IGNmZy54R2FwLCB4R2FwID0gX2EgPT09IHZvaWQgMCA/IDEgOiBfYSwgX2IgPSBjZmcueUdhcCwgeUdhcCA9IF9iID09PSB2b2lkIDAgPyA4IDogX2I7XG4gICAgICAgIHRoaXMueEdhcCA9IHhHYXA7XG4gICAgICAgIHRoaXMueUdhcCA9IHlHYXA7XG4gICAgfVxuICAgIEdyZWVkeS5wcm90b3R5cGUuaGFzR2FwID0gZnVuY3Rpb24gKGJib3gpIHtcbiAgICAgICAgdmFyIGhhc0dhcCA9IHRydWU7XG4gICAgICAgIHZhciBiaXRtYXAgPSB0aGlzLmJpdG1hcDtcbiAgICAgICAgdmFyIG1pblggPSBNYXRoLnJvdW5kKGJib3gubWluWCk7XG4gICAgICAgIHZhciBtYXhYID0gTWF0aC5yb3VuZChiYm94Lm1heFgpO1xuICAgICAgICB2YXIgbWluWSA9IE1hdGgucm91bmQoYmJveC5taW5ZKTtcbiAgICAgICAgdmFyIG1heFkgPSBNYXRoLnJvdW5kKGJib3gubWF4WSk7XG4gICAgICAgIGZvciAodmFyIGkgPSBtaW5YOyBpIDw9IG1heFg7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKCFiaXRtYXBbaV0pIHtcbiAgICAgICAgICAgICAgICBiaXRtYXBbaV0gPSB7fTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpID09PSBtaW5YIHx8IGkgPT09IG1heFgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gbWluWTsgaiA8PSBtYXhZOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJpdG1hcFtpXVtqXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFzR2FwID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChiaXRtYXBbaV1bbWluWV0gfHwgYml0bWFwW2ldW21heFldKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhc0dhcCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc0dhcDtcbiAgICB9O1xuICAgIEdyZWVkeS5wcm90b3R5cGUuZmlsbEdhcCA9IGZ1bmN0aW9uIChiYm94KSB7XG4gICAgICAgIHZhciBiaXRtYXAgPSB0aGlzLmJpdG1hcDtcbiAgICAgICAgdmFyIG1pblggPSBNYXRoLnJvdW5kKGJib3gubWluWCk7XG4gICAgICAgIHZhciBtYXhYID0gTWF0aC5yb3VuZChiYm94Lm1heFgpO1xuICAgICAgICB2YXIgbWluWSA9IE1hdGgucm91bmQoYmJveC5taW5ZKTtcbiAgICAgICAgdmFyIG1heFkgPSBNYXRoLnJvdW5kKGJib3gubWF4WSk7XG4gICAgICAgIC8vIGZpbGxpbmcgZ3JpZFxuICAgICAgICBmb3IgKHZhciBpID0gbWluWDsgaSA8PSBtYXhYOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmICghYml0bWFwW2ldKSB7XG4gICAgICAgICAgICAgICAgYml0bWFwW2ldID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IG1pblg7IGkgPD0gbWF4WDsgaSArPSB0aGlzLnhHYXApIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSBtaW5ZOyBqIDw9IG1heFk7IGogKz0gdGhpcy55R2FwKSB7XG4gICAgICAgICAgICAgICAgYml0bWFwW2ldW2pdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJpdG1hcFtpXVttYXhZXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZmlsbGluZyB5IGVkZ2VzXG4gICAgICAgIGlmICh0aGlzLnlHYXAgIT09IDEpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBtaW5ZOyBpIDw9IG1heFk7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGJpdG1hcFttaW5YXVtpXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgYml0bWFwW21heFhdW2ldID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBmaWxsaW5nIHggZWRnZXNcbiAgICAgICAgaWYgKHRoaXMueEdhcCAhPT0gMSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IG1pblg7IGkgPD0gbWF4WDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgYml0bWFwW2ldW21pblldID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBiaXRtYXBbaV1bbWF4WV0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBHcmVlZHkucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYml0bWFwID0ge307XG4gICAgfTtcbiAgICByZXR1cm4gR3JlZWR5O1xufSgpKTtcbmZ1bmN0aW9uIHNwaXJhbEZpbGwobGFiZWwsIGdyZWVkeSwgbWF4VGltZXMpIHtcbiAgICBpZiAobWF4VGltZXMgPT09IHZvaWQgMCkgeyBtYXhUaW1lcyA9IE1BWF9USU1FUzsgfVxuICAgIHZhciBkdCA9IC0xO1xuICAgIHZhciBfYSA9IGxhYmVsLmF0dHIoKSwgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgIHZhciBiYm94ID0gbGFiZWwuZ2V0Q2FudmFzQkJveCgpO1xuICAgIHZhciBtYXhEZWx0YSA9IE1hdGguc3FydChiYm94LndpZHRoICogYmJveC53aWR0aCArIGJib3guaGVpZ2h0ICogYmJveC5oZWlnaHQpO1xuICAgIHZhciBkeGR5O1xuICAgIHZhciB0ID0gLWR0O1xuICAgIHZhciBkeCA9IDA7XG4gICAgdmFyIGR5ID0gMDtcbiAgICB2YXIgZiA9IGZ1bmN0aW9uIChwYXJhbSkge1xuICAgICAgICB2YXIgbnQgPSBwYXJhbSAqIDAuMTtcbiAgICAgICAgcmV0dXJuIFtudCAqIE1hdGguY29zKG50KSwgbnQgKiBNYXRoLnNpbihudCldO1xuICAgIH07XG4gICAgaWYgKGdyZWVkeS5oYXNHYXAoYmJveCkpIHtcbiAgICAgICAgZ3JlZWR5LmZpbGxHYXAoYmJveCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB2YXIgY2FuRmlsbCA9IGZhbHNlO1xuICAgIHZhciB0aW1lcyA9IDA7XG4gICAgdmFyIGFjY2Vzc2VkQ2FjaGUgPSB7fTtcbiAgICB3aGlsZSAoTWF0aC5taW4oTWF0aC5hYnMoZHgpLCBNYXRoLmFicyhkeSkpIDwgbWF4RGVsdGEgJiYgdGltZXMgPCBtYXhUaW1lcykge1xuICAgICAgICBkeGR5ID0gZigodCArPSBkdCkpO1xuICAgICAgICBkeCA9IH5+ZHhkeVswXTtcbiAgICAgICAgZHkgPSB+fmR4ZHlbMV07XG4gICAgICAgIGlmICgoIWR4ICYmICFkeSkgfHwgYWNjZXNzZWRDYWNoZVtkeCArIFwiLVwiICsgZHldKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsYWJlbC5hdHRyKHsgeDogeCArIGR4LCB5OiB5ICsgZHkgfSk7XG4gICAgICAgIGlmIChkeCArIGR5IDwgMCkge1xuICAgICAgICAgICAgbGFiZWwuYXR0cigndGV4dEFsaWduJywgJ3JpZ2h0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgdGltZXMrKztcbiAgICAgICAgaWYgKGdyZWVkeS5oYXNHYXAobGFiZWwuZ2V0Q2FudmFzQkJveCgpKSkge1xuICAgICAgICAgICAgZ3JlZWR5LmZpbGxHYXAobGFiZWwuZ2V0Q2FudmFzQkJveCgpKTtcbiAgICAgICAgICAgIGNhbkZpbGwgPSB0cnVlO1xuICAgICAgICAgICAgYWNjZXNzZWRDYWNoZVtkeCArIFwiLVwiICsgZHldID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjYW5GaWxsO1xufVxuLypcbiAqICDmoLnmja7lpoLkuIvop4TliJnlsJ3or5XmlL7nva5sYWJlbFxuICogICAgICAgICAgICAgICAgNVxuICogICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLVxuICogICAgICAgIHwgICAgMSAgIHwgICAwICAgfFxuICogICAgOCAgIOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlDTigJTigJTigJTigJTigJTigJTigJTigJQgICA3XG4gKiAgICAgICAgfCAgICAyICAgfCAgIDMgICB8XG4gKiAgICAgICAg4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCU4oCUXG4gKiAgICAgICAgICAgICAgICAgNlxuICovXG5mdW5jdGlvbiBhZGp1c3RMYWJlbFBvc2l0aW9uKGxhYmVsLCB4LCB5LCBpbmRleCkge1xuICAgIHZhciBfYSA9IGxhYmVsLmdldENhbnZhc0JCb3goKSwgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICB9O1xuICAgIHN3aXRjaCAoaW5kZXgpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgYXR0cnMueSAtPSBoZWlnaHQgKyAxO1xuICAgICAgICAgICAgYXR0cnMueCArPSAxO1xuICAgICAgICAgICAgYXR0cnMudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIGF0dHJzLnkgLT0gaGVpZ2h0ICsgMTtcbiAgICAgICAgICAgIGF0dHJzLnggLT0gMTtcbiAgICAgICAgICAgIGF0dHJzLnRleHRBbGlnbiA9ICdyaWdodCc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgYXR0cnMueSArPSBoZWlnaHQgKyAxO1xuICAgICAgICAgICAgYXR0cnMueCAtPSAxO1xuICAgICAgICAgICAgYXR0cnMudGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICBhdHRycy55ICs9IGhlaWdodCArIDE7XG4gICAgICAgICAgICBhdHRycy54ICs9IDE7XG4gICAgICAgICAgICBhdHRycy50ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgYXR0cnMueSAtPSBoZWlnaHQgKiAyICsgMjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICBhdHRycy55ICs9IGhlaWdodCAqIDIgKyAyO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgIGF0dHJzLnggKz0gd2lkdGggKyAxO1xuICAgICAgICAgICAgYXR0cnMudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgIGF0dHJzLnggLT0gd2lkdGggKyAxO1xuICAgICAgICAgICAgYXR0cnMudGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGxhYmVsLmF0dHIoYXR0cnMpO1xuICAgIHJldHVybiBsYWJlbC5nZXRDYW52YXNCQm94KCk7XG59XG4vKipcbiAqIEBpZ25vcmVcbiAqIGxhYmVsIOmYsumBruaMoeW4g+WxgO+8muWcqOS4jeaUueWPmCBsYWJlbCDkvY3nva7nmoTmg4XlhrXkuIvlr7nnm7jkupLph43lj6DnmoQgbGFiZWwg6L+b6KGM6LCD5pW044CCXG4gKiDkuI3lkIzkuo4gJ292ZXJsYXAnIOexu+Wei+eahOW4g+WxgO+8jOivpeW4g+WxgOS4jeS8muWvuSBsYWJlbCDnmoTkvY3nva7ov5vooYzlgY/np7vosIPmlbTjgIJcbiAqIEBwYXJhbSBsYWJlbHMg5Y+C5LiO5biD5bGA6LCD5pW055qEIGxhYmVsIOaVsOe7hOmbhuWQiFxuICovXG5mdW5jdGlvbiBmaXhlZE92ZXJsYXAoaXRlbXMsIGxhYmVscywgc2hhcGVzLCByZWdpb24pIHtcbiAgICB2YXIgZ3JlZWR5ID0gbmV3IEdyZWVkeSgpO1xuICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgIHZhciBsYWJlbFNoYXBlID0gbGFiZWwuZmluZChmdW5jdGlvbiAoc2hhcGUpIHsgcmV0dXJuIHNoYXBlLmdldCgndHlwZScpID09PSAndGV4dCc7IH0pO1xuICAgICAgICBpZiAoIXNwaXJhbEZpbGwobGFiZWxTaGFwZSwgZ3JlZWR5KSkge1xuICAgICAgICAgICAgbGFiZWwucmVtb3ZlKHRydWUpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgZ3JlZWR5LmRlc3Ryb3koKTtcbn1cbmV4cG9ydHMuZml4ZWRPdmVybGFwID0gZml4ZWRPdmVybGFwO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBsYWJlbCDpmLLpga7mjKHluIPlsYDvvJrkuLrkuobpmLLmraIgbGFiZWwg5LmL6Ze055u45LqS6KaG55uW5ZCM5pe25L+d6K+B5bC95Y+v6IO95aSaIOeahCBsYWJlbCDlsZXnpLrvvIzpgJrov4flsJ3or5XlsIYgbGFiZWwg5ZCRKirlm5vlkajlgY/np7sqKuadpeWJlOmZpOaUvuS4jeS4i+eahCBsYWJlbFxuICogQHBhcmFtIGxhYmVscyDlj4LkuI7luIPlsYDosIPmlbTnmoQgbGFiZWwg5pWw57uE6ZuG5ZCIXG4gKi9cbmZ1bmN0aW9uIG92ZXJsYXAoaXRlbXMsIGxhYmVscywgc2hhcGVzLCByZWdpb24pIHtcbiAgICB2YXIgZ3JlZWR5ID0gbmV3IEdyZWVkeSgpO1xuICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgIHZhciBsYWJlbFNoYXBlID0gbGFiZWwuZmluZChmdW5jdGlvbiAoc2hhcGUpIHsgcmV0dXJuIHNoYXBlLmdldCgndHlwZScpID09PSAndGV4dCc7IH0pO1xuICAgICAgICB2YXIgX2EgPSBsYWJlbFNoYXBlLmF0dHIoKSwgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgICAgICB2YXIgY2FuRmlsbCA9IGZhbHNlO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSA4OyBpKyspIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gYWRqdXN0TGFiZWxQb3NpdGlvbihsYWJlbFNoYXBlLCB4LCB5LCBpKTtcbiAgICAgICAgICAgIGlmIChncmVlZHkuaGFzR2FwKGJib3gpKSB7XG4gICAgICAgICAgICAgICAgZ3JlZWR5LmZpbGxHYXAoYmJveCk7XG4gICAgICAgICAgICAgICAgY2FuRmlsbCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjYW5GaWxsKSB7XG4gICAgICAgICAgICBsYWJlbC5yZW1vdmUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBncmVlZHkuZGVzdHJveSgpO1xufVxuZXhwb3J0cy5vdmVybGFwID0gb3ZlcmxhcDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW92ZXJsYXAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRpc3RyaWJ1dGUgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ3JhcGhpY3NfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi91dGlsL2dyYXBoaWNzXCIpO1xuLyoqIGxhYmVsIHRleHTlkoxsaW5l6Led56a7IDRweCAqL1xudmFyIE1BUkdJTiA9IDQ7XG5mdW5jdGlvbiBhbnRpQ29sbGlzaW9uKGxhYmVsU2hhcGVzLCBsYWJlbHMsIGxpbmVIZWlnaHQsIHBsb3RSYW5nZSwgY2VudGVyLCBpc1JpZ2h0KSB7XG4gICAgLy8gYWRqdXN0IHkgcG9zaXRpb24gb2YgbGFiZWxzIHRvIGF2b2lkIG92ZXJsYXBwaW5nXG4gICAgdmFyIG92ZXJsYXBwaW5nID0gdHJ1ZTtcbiAgICB2YXIgc3RhcnQgPSBwbG90UmFuZ2Uuc3RhcnQ7XG4gICAgdmFyIGVuZCA9IHBsb3RSYW5nZS5lbmQ7XG4gICAgdmFyIHN0YXJ0WSA9IE1hdGgubWluKHN0YXJ0LnksIGVuZC55KTtcbiAgICB2YXIgdG90YWxIZWlnaHQgPSBNYXRoLmFicyhzdGFydC55IC0gZW5kLnkpO1xuICAgIHZhciBpO1xuICAgIHZhciBtYXhZID0gMDtcbiAgICB2YXIgbWluWSA9IE51bWJlci5NSU5fVkFMVUU7XG4gICAgdmFyIGJveGVzID0gbGFiZWxzLm1hcChmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgaWYgKGxhYmVsLnkgPiBtYXhZKSB7XG4gICAgICAgICAgICBtYXhZID0gbGFiZWwueTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFiZWwueSA8IG1pblkpIHtcbiAgICAgICAgICAgIG1pblkgPSBsYWJlbC55O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzaXplOiBsaW5lSGVpZ2h0LFxuICAgICAgICAgICAgdGFyZ2V0czogW2xhYmVsLnkgLSBzdGFydFldLFxuICAgICAgICB9O1xuICAgIH0pO1xuICAgIG1pblkgLT0gc3RhcnRZO1xuICAgIGlmIChtYXhZIC0gc3RhcnRZID4gdG90YWxIZWlnaHQpIHtcbiAgICAgICAgdG90YWxIZWlnaHQgPSBtYXhZIC0gc3RhcnRZO1xuICAgIH1cbiAgICB3aGlsZSAob3ZlcmxhcHBpbmcpIHtcbiAgICAgICAgLyogZXNsaW50IG5vLWxvb3AtZnVuYzogMCAqL1xuICAgICAgICBib3hlcy5mb3JFYWNoKGZ1bmN0aW9uIChib3gpIHtcbiAgICAgICAgICAgIHZhciB0YXJnZXQgPSAoTWF0aC5taW4uYXBwbHkobWluWSwgYm94LnRhcmdldHMpICsgTWF0aC5tYXguYXBwbHkobWluWSwgYm94LnRhcmdldHMpKSAvIDI7XG4gICAgICAgICAgICBib3gucG9zID0gTWF0aC5taW4oTWF0aC5tYXgobWluWSwgdGFyZ2V0IC0gYm94LnNpemUgLyAyKSwgdG90YWxIZWlnaHQgLSBib3guc2l6ZSk7XG4gICAgICAgICAgICAvLyBib3gucG9zID0gTWF0aC5tYXgoMCwgdGFyZ2V0IC0gYm94LnNpemUgLyAyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGRldGVjdCBvdmVybGFwcGluZyBhbmQgam9pbiBib3hlc1xuICAgICAgICBvdmVybGFwcGluZyA9IGZhbHNlO1xuICAgICAgICBpID0gYm94ZXMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXNCb3ggPSBib3hlc1tpIC0gMV07XG4gICAgICAgICAgICAgICAgdmFyIGJveCA9IGJveGVzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c0JveC5wb3MgKyBwcmV2aW91c0JveC5zaXplID4gYm94LnBvcykge1xuICAgICAgICAgICAgICAgICAgICAvLyBvdmVybGFwcGluZ1xuICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5zaXplICs9IGJveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC50YXJnZXRzID0gcHJldmlvdXNCb3gudGFyZ2V0cy5jb25jYXQoYm94LnRhcmdldHMpO1xuICAgICAgICAgICAgICAgICAgICAvLyBvdmVyZmxvdywgc2hpZnQgdXBcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzQm94LnBvcyArIHByZXZpb3VzQm94LnNpemUgPiB0b3RhbEhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNCb3gucG9zID0gdG90YWxIZWlnaHQgLSBwcmV2aW91c0JveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJveGVzLnNwbGljZShpLCAxKTsgLy8gcmVtb3ZpbmcgYm94XG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXBwaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaSA9IDA7XG4gICAgLy8gc3RlcCA0OiBub3JtYWxpemUgeSBhbmQgYWRqdXN0IHhcbiAgICBib3hlcy5mb3JFYWNoKGZ1bmN0aW9uIChiKSB7XG4gICAgICAgIHZhciBwb3NJbkNvbXBvc2l0ZUJveCA9IHN0YXJ0WSArIGxpbmVIZWlnaHQgLyAyOyAvLyBtaWRkbGUgb2YgdGhlIGxhYmVsXG4gICAgICAgIGIudGFyZ2V0cy5mb3JFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxhYmVsc1tpXS55ID0gYi5wb3MgKyBwb3NJbkNvbXBvc2l0ZUJveDtcbiAgICAgICAgICAgIHBvc0luQ29tcG9zaXRlQm94ICs9IGxpbmVIZWlnaHQ7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIHZhciBsYWJlbHNNYXAgPSB7fTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIGxhYmVsU2hhcGVzXzEgPSBsYWJlbFNoYXBlczsgX2kgPCBsYWJlbFNoYXBlc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgbGFiZWxTaGFwZSA9IGxhYmVsU2hhcGVzXzFbX2ldO1xuICAgICAgICBsYWJlbHNNYXBbbGFiZWxTaGFwZS5nZXQoJ2lkJyldID0gbGFiZWxTaGFwZTtcbiAgICB9XG4gICAgLy8gKHggLSBjeCleMiArICh5IC0gY3kpXjIgPSB0b3RhbFJeMlxuICAgIGxhYmVscy5mb3JFYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICB2YXIgclBvdzIgPSBsYWJlbC5yICogbGFiZWwucjtcbiAgICAgICAgdmFyIGR5UG93MiA9IE1hdGgucG93KE1hdGguYWJzKGxhYmVsLnkgLSBjZW50ZXIueSksIDIpO1xuICAgICAgICBpZiAoclBvdzIgPCBkeVBvdzIpIHtcbiAgICAgICAgICAgIGxhYmVsLnggPSBjZW50ZXIueDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBkeCA9IE1hdGguc3FydChyUG93MiAtIGR5UG93Mik7XG4gICAgICAgICAgICBpZiAoIWlzUmlnaHQpIHtcbiAgICAgICAgICAgICAgICAvLyBsZWZ0XG4gICAgICAgICAgICAgICAgbGFiZWwueCA9IGNlbnRlci54IC0gZHg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyByaWdodFxuICAgICAgICAgICAgICAgIGxhYmVsLnggPSBjZW50ZXIueCArIGR4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGFkanVzdCBsYWJlbFNoYXBlXG4gICAgICAgIHZhciBsYWJlbFNoYXBlID0gbGFiZWxzTWFwW2xhYmVsLmlkXTtcbiAgICAgICAgbGFiZWxTaGFwZS5hdHRyKCd4JywgbGFiZWwueCk7XG4gICAgICAgIGxhYmVsU2hhcGUuYXR0cigneScsIGxhYmVsLnkpO1xuICAgICAgICAvLyBiZWNhdXNlIGdyb3VwIGNvdWxkIG5vdCBlZmZlY3QgdGV4dC1zaGFwZSwgc2hvdWxkIHNldCB0ZXh0LXNoYXBlIHBvc2l0aW9uIG1hbnVhbGx5XG4gICAgICAgIHZhciB0ZXh0U2hhcGUgPSB1dGlsXzEuZmluZChsYWJlbFNoYXBlLmdldENoaWxkcmVuKCksIGZ1bmN0aW9uIChlbGUpIHsgcmV0dXJuIGVsZS5nZXQoJ3R5cGUnKSA9PT0gJ3RleHQnOyB9KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBpZiAodGV4dFNoYXBlKSB7XG4gICAgICAgICAgICB0ZXh0U2hhcGUuYXR0cigneScsIGxhYmVsLnkpO1xuICAgICAgICAgICAgdGV4dFNoYXBlLmF0dHIoJ3gnLCBsYWJlbC54KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gZGlzdHJpYnV0ZShpdGVtcywgbGFiZWxzLCBzaGFwZXMsIHJlZ2lvbikge1xuICAgIHZhciBvZmZzZXQgPSBpdGVtc1swXSA/IGl0ZW1zWzBdLm9mZnNldCA6IDA7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBsYWJlbHNbMF0uZ2V0KCdjb29yZGluYXRlJyk7XG4gICAgdmFyIHJhZGl1cyA9IGNvb3JkaW5hdGUuZ2V0UmFkaXVzKCk7XG4gICAgdmFyIGNlbnRlciA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgLy8gY29uc3QgbGluZUhlaWdodCA9IGdldCh0aGlzLmdlb21ldHJ5LnRoZW1lLCBbJ3BpZUxhYmVscycsICdsYWJlbEhlaWdodCddLCAxNCk7XG4gICAgICAgIHZhciBsaW5lSGVpZ2h0XzEgPSAxNDsgLy8gVE9ET1xuICAgICAgICB2YXIgdG90YWxSID0gcmFkaXVzICsgb2Zmc2V0O1xuICAgICAgICB2YXIgdG90YWxIZWlnaHRfMSA9IHRvdGFsUiAqIDIgKyBsaW5lSGVpZ2h0XzEgKiAyO1xuICAgICAgICB2YXIgcGxvdFJhbmdlXzEgPSB7XG4gICAgICAgICAgICBzdGFydDogY29vcmRpbmF0ZS5zdGFydCxcbiAgICAgICAgICAgIGVuZDogY29vcmRpbmF0ZS5lbmQsXG4gICAgICAgIH07XG4gICAgICAgIC8vIHN0ZXAgMTogc2VwYXJhdGUgbGFiZWxzXG4gICAgICAgIHZhciBoYWx2ZXNfMSA9IFtcbiAgICAgICAgICAgIFtdLFxuICAgICAgICAgICAgW10sXG4gICAgICAgIF07XG4gICAgICAgIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsSXRlbSkge1xuICAgICAgICAgICAgaWYgKCFsYWJlbEl0ZW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFiZWxJdGVtLnRleHRBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgICAgIC8vIGxlZnRcbiAgICAgICAgICAgICAgICBoYWx2ZXNfMVswXS5wdXNoKGxhYmVsSXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyByaWdodCBvciBjZW50ZXIgd2lsbCBiZSBwdXQgb24gdGhlIHJpZ2h0IHNpZGVcbiAgICAgICAgICAgICAgICBoYWx2ZXNfMVsxXS5wdXNoKGxhYmVsSXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBoYWx2ZXNfMS5mb3JFYWNoKGZ1bmN0aW9uIChoYWxmLCBpbmRleCkge1xuICAgICAgICAgICAgLy8gc3RlcCAyOiByZWR1Y2UgbGFiZWxzXG4gICAgICAgICAgICB2YXIgbWF4TGFiZWxzQ291bnRGb3JPbmVTaWRlID0gdG90YWxIZWlnaHRfMSAvIGxpbmVIZWlnaHRfMTtcbiAgICAgICAgICAgIGlmIChoYWxmLmxlbmd0aCA+IG1heExhYmVsc0NvdW50Rm9yT25lU2lkZSkge1xuICAgICAgICAgICAgICAgIGhhbGYuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICAvLyBzb3J0IGJ5IHBlcmNlbnRhZ2UgREVTQ1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYlsnLi5wZXJjZW50J10gLSBhWycuLnBlcmNlbnQnXTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBoYWxmLnNwbGljZShtYXhMYWJlbHNDb3VudEZvck9uZVNpZGUsIGhhbGYubGVuZ3RoIC0gbWF4TGFiZWxzQ291bnRGb3JPbmVTaWRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHN0ZXAgMzogZGlzdHJpYnV0ZSBwb3NpdGlvbiAoeCBhbmQgeSlcbiAgICAgICAgICAgIGhhbGYuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgIC8vIHNvcnQgYnkgeSBBU0NcbiAgICAgICAgICAgICAgICByZXR1cm4gYS55IC0gYi55O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhbnRpQ29sbGlzaW9uKGxhYmVscywgaGFsZiwgbGluZUhlaWdodF8xLCBwbG90UmFuZ2VfMSwgY2VudGVyLCBpbmRleCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyDphY3nva4gbGFiZWxMaW5lXG4gICAgdXRpbF8xLmVhY2goaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIGlmIChpdGVtICYmIGl0ZW0ubGFiZWxMaW5lKSB7XG4gICAgICAgICAgICB2YXIgZGlzdGFuY2UgPSBpdGVtLm9mZnNldDtcbiAgICAgICAgICAgIHZhciBhbmdsZSA9IGl0ZW0uYW5nbGU7XG4gICAgICAgICAgICAvLyDotLTov5HlnIblkahcbiAgICAgICAgICAgIHZhciBzdGFydFBvaW50ID0gZ3JhcGhpY3NfMS5wb2xhclRvQ2FydGVzaWFuKGNlbnRlci54LCBjZW50ZXIueSwgcmFkaXVzLCBhbmdsZSk7XG4gICAgICAgICAgICB2YXIgaW5uZXJQb2ludCA9IGdyYXBoaWNzXzEucG9sYXJUb0NhcnRlc2lhbihjZW50ZXIueCwgY2VudGVyLnksIHJhZGl1cyArIGRpc3RhbmNlIC8gMiwgYW5nbGUpO1xuICAgICAgICAgICAgdmFyIGl0ZW1YID0gaXRlbS54ICsgdXRpbF8xLmdldChpdGVtLCAnb2Zmc2V0WCcsIDApO1xuICAgICAgICAgICAgdmFyIGl0ZW1ZID0gaXRlbS55ICsgdXRpbF8xLmdldChpdGVtLCAnb2Zmc2V0WScsIDApO1xuICAgICAgICAgICAgdmFyIGVuZFBvaW50ID0ge1xuICAgICAgICAgICAgICAgIHg6IGl0ZW1YIC0gTWF0aC5jb3MoYW5nbGUpICogTUFSR0lOLFxuICAgICAgICAgICAgICAgIHk6IGl0ZW1ZIC0gTWF0aC5zaW4oYW5nbGUpICogTUFSR0lOLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmlzT2JqZWN0KGl0ZW0ubGFiZWxMaW5lKSkge1xuICAgICAgICAgICAgICAgIC8vIGxhYmVsTGluZTogdHJ1ZVxuICAgICAgICAgICAgICAgIGl0ZW0ubGFiZWxMaW5lID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpdGVtLmxhYmVsTGluZS5wYXRoID0gW1xuICAgICAgICAgICAgICAgIFwiTSBcIiArIHN0YXJ0UG9pbnQueCxcbiAgICAgICAgICAgICAgICBzdGFydFBvaW50LnkgKyBcIiBRXCIgKyBpbm5lclBvaW50LngsXG4gICAgICAgICAgICAgICAgaW5uZXJQb2ludC55ICsgXCIgXCIgKyBlbmRQb2ludC54LFxuICAgICAgICAgICAgICAgIGVuZFBvaW50LnksXG4gICAgICAgICAgICBdLmpvaW4oJywnKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5kaXN0cmlidXRlID0gZGlzdHJpYnV0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc3RyaWJ1dGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnBpZU91dGVyTGFiZWxMYXlvdXQgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ3JhcGhpY3NfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi91dGlsL2dyYXBoaWNzXCIpO1xuLyoqIGxhYmVsIHRleHTlkoxsaW5l6Led56a7IDRweCAqL1xudmFyIE1BUkdJTiA9IDQ7XG5mdW5jdGlvbiBhbnRpQ29sbGlzaW9uKGxhYmVsU2hhcGVzLCBsYWJlbHMsIGxhYmVsSGVpZ2h0LCBwbG90UmFuZ2UsIGNlbnRlciwgcmFkaXVzLCBpc1JpZ2h0KSB7XG4gICAgLy8gc29ydGVkIGJ5IHksIG11dGFibGVcbiAgICBsYWJlbHMuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYS55IC0gYi55OyB9KTtcbiAgICAvLyBhZGp1c3QgeSBwb3NpdGlvbiBvZiBsYWJlbHMgdG8gYXZvaWQgb3ZlcmxhcHBpbmdcbiAgICB2YXIgc3RhcnQgPSBwbG90UmFuZ2Uuc3RhcnQ7XG4gICAgdmFyIGVuZCA9IHBsb3RSYW5nZS5lbmQ7XG4gICAgdmFyIHN0YXJ0WSA9IE1hdGgubWluKHN0YXJ0LnksIGVuZC55KTtcbiAgICB2YXIgZW5kWSA9IE1hdGgubWF4KHN0YXJ0LnksIGVuZC55KTtcbiAgICB2YXIgaTtcbiAgICB2YXIgYm94ZXMgPSBsYWJlbHMubWFwKGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogbGFiZWwuY29udGVudCxcbiAgICAgICAgICAgIHNpemU6IGxhYmVsSGVpZ2h0LFxuICAgICAgICAgICAgcG9zOiBsYWJlbC55LFxuICAgICAgICAgICAgdGFyZ2V0czogW2xhYmVsLnldLFxuICAgICAgICB9O1xuICAgIH0pO1xuICAgIHZhciBtYXhQb3MgPSBNYXRoLm1heC5hcHBseShNYXRoLCBib3hlcy5tYXAoZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGIucG9zOyB9KSk7XG4gICAgdmFyIG1pblBvcyA9IE1hdGgubWluLmFwcGx5KE1hdGgsIGJveGVzLm1hcChmdW5jdGlvbiAoYikgeyByZXR1cm4gYi5wb3M7IH0pKTtcbiAgICAvKipcbiAgICAgKiB3aGVuIGluIHJpZ2h0LCBzaGlmdCBmcm9tIHVwIHRvIGRvd25cbiAgICAgKi9cbiAgICBpZiAoaXNSaWdodCkge1xuICAgICAgICB2YXIgbWluWSA9IE1hdGgubWluKG1pblBvcywgZW5kWSAtIChib3hlcy5sZW5ndGggLSAxKSAqIGxhYmVsSGVpZ2h0KTtcbiAgICAgICAgdmFyIG1heFkgPSBNYXRoLm1heChtaW5ZICsgYm94ZXMubGVuZ3RoICogbGFiZWxIZWlnaHQsIG1heFBvcyArIGxhYmVsSGVpZ2h0KTtcbiAgICAgICAgdmFyIG92ZXJsYXBwaW5nID0gdHJ1ZTtcbiAgICAgICAgd2hpbGUgKG92ZXJsYXBwaW5nKSB7XG4gICAgICAgICAgICAvLyBkZXRlY3Qgb3ZlcmxhcHBpbmcgYW5kIGpvaW4gYm94ZXNcbiAgICAgICAgICAgIG92ZXJsYXBwaW5nID0gZmFsc2U7XG4gICAgICAgICAgICBpID0gYm94ZXMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXNCb3ggPSBib3hlc1tpIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIHZhciBib3ggPSBib3hlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gb3ZlcmxhcFxuICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNCb3gucG9zICsgcHJldmlvdXNCb3guc2l6ZSA+IGJveC5wb3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChib3gucG9zICsgaSAqIGxhYmVsSGVpZ2h0IDwgbWF4WSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGpvaW4gYm94ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5zaXplICs9IGJveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzQm94LnRhcmdldHMgPSBwcmV2aW91c0JveC50YXJnZXRzLmNvbmNhdChib3gudGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZpbmcgYm94XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94ZXMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNCb3gucG9zID0gYm94LnBvcyAtIHByZXZpb3VzQm94LnNpemU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBvdmVybGFwcGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBtYXhZID0gTWF0aC5tYXgoc3RhcnRZICsgKGJveGVzLmxlbmd0aCAtIDEpICogbGFiZWxIZWlnaHQsIG1heFBvcyk7XG4gICAgICAgIHZhciBtaW5ZID0gTWF0aC5taW4obWluUG9zLCBtYXhZIC0gKGJveGVzLmxlbmd0aCAtIDEpICogbGFiZWxIZWlnaHQpO1xuICAgICAgICB2YXIgb3ZlcmxhcHBpbmcgPSB0cnVlO1xuICAgICAgICB3aGlsZSAob3ZlcmxhcHBpbmcpIHtcbiAgICAgICAgICAgIC8vIGRldGVjdCBvdmVybGFwcGluZyBhbmQgam9pbiBib3hlc1xuICAgICAgICAgICAgb3ZlcmxhcHBpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIGkgPSBib3hlcy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c0JveCA9IGJveGVzW2kgLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveCA9IGJveGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICAvLyBvdmVybGFwXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c0JveC5wb3MgKyBwcmV2aW91c0JveC5zaXplID4gYm94LnBvcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzQm94LnBvcyAtIG1pblkgPiBpICogbGFiZWxIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5wb3MgLT0gcHJldmlvdXNCb3guc2l6ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGpvaW4gYm94ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5zaXplICs9IGJveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzQm94LnRhcmdldHMgPSBwcmV2aW91c0JveC50YXJnZXRzLmNvbmNhdChib3gudGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZpbmcgYm94XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94ZXMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxhcHBpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHN0ZXAgNDogbm9ybWFsaXplIHkgYW5kIGFkanVzdCB4XG4gICAgaSA9IDA7XG4gICAgYm94ZXMuZm9yRWFjaChmdW5jdGlvbiAoYikge1xuICAgICAgICB2YXIgcG9zSW5Db21wb3NpdGVCb3ggPSBiLnBvcztcbiAgICAgICAgYi50YXJnZXRzLmZvckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGFiZWxzW2ldLnkgPSBwb3NJbkNvbXBvc2l0ZUJveDtcbiAgICAgICAgICAgIHBvc0luQ29tcG9zaXRlQm94ICs9IGxhYmVsSGVpZ2h0O1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICB2YXIgbGFiZWxzTWFwID0ge307XG4gICAgZm9yICh2YXIgX2kgPSAwLCBsYWJlbFNoYXBlc18xID0gbGFiZWxTaGFwZXM7IF9pIDwgbGFiZWxTaGFwZXNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIGxhYmVsU2hhcGUgPSBsYWJlbFNoYXBlc18xW19pXTtcbiAgICAgICAgbGFiZWxzTWFwW2xhYmVsU2hhcGUuZ2V0KCdpZCcpXSA9IGxhYmVsU2hhcGU7XG4gICAgfVxuICAgIC8vICh4IC0gY3gpXjIgKyAoeSAtIGN5KV4yID0gdG90YWxSXjJcbiAgICB2YXIgdG90YWxSID0gKE1hdGgubWF4LmFwcGx5KE1hdGgsIGxhYmVscy5tYXAoZnVuY3Rpb24gKGwpIHsgcmV0dXJuIGwueTsgfSkpIC0gTWF0aC5taW4uYXBwbHkoTWF0aCwgbGFiZWxzLm1hcChmdW5jdGlvbiAobCkgeyByZXR1cm4gbC55OyB9KSkpIC8gMjtcbiAgICB0b3RhbFIgPSBNYXRoLm1heCh0b3RhbFIsIHJhZGl1cyk7XG4gICAgbGFiZWxzLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgIHZhciBsYWJlbFNoYXBlID0gbGFiZWxzTWFwW2xhYmVsLmlkXTtcbiAgICAgICAgLy8gYmVjYXVzZSBncm91cCBjb3VsZCBub3QgZWZmZWN0IHRleHQtc2hhcGUsIHNob3VsZCBzZXQgdGV4dC1zaGFwZSBwb3NpdGlvbiBtYW51YWxseVxuICAgICAgICB2YXIgdGV4dFNoYXBlID0gbGFiZWxTaGFwZS5maW5kKGZ1bmN0aW9uIChjaGlsZCkgeyByZXR1cm4gY2hpbGQuZ2V0KCd0eXBlJykgPT09ICd0ZXh0JzsgfSk7XG4gICAgICAgIC8vIHRleHRTaGFwZSDlj5HnlJ/ov4fosIPmlbRcbiAgICAgICAgaWYgKHRleHRTaGFwZSAmJiB0ZXh0U2hhcGUuYXR0cigneScpICE9PSBsYWJlbC55KSB7XG4gICAgICAgICAgICB2YXIgclBvdzIgPSB0b3RhbFIgKiB0b3RhbFI7XG4gICAgICAgICAgICB2YXIgZHlQb3cyID0gTWF0aC5wb3coTWF0aC5hYnMobGFiZWwueSAtIGNlbnRlci55KSwgMik7XG4gICAgICAgICAgICBpZiAoclBvdzIgPCBkeVBvdzIpIHtcbiAgICAgICAgICAgICAgICBsYWJlbC54ID0gY2VudGVyLng7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgZHggPSBNYXRoLnNxcnQoclBvdzIgLSBkeVBvdzIpO1xuICAgICAgICAgICAgICAgIGlmICghaXNSaWdodCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBsZWZ0XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLnggPSBjZW50ZXIueCAtIGR4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmlnaHRcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwueCA9IGNlbnRlci54ICsgZHg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGFkanVzdCBsYWJlbFNoYXBlXG4gICAgICAgIGxhYmVsU2hhcGUuYXR0cigneCcsIGxhYmVsLngpO1xuICAgICAgICBsYWJlbFNoYXBlLmF0dHIoJ3knLCBsYWJlbC55KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBpZiAodGV4dFNoYXBlKSB7XG4gICAgICAgICAgICB0ZXh0U2hhcGUuYXR0cigneScsIGxhYmVsLnkpO1xuICAgICAgICAgICAgdGV4dFNoYXBlLmF0dHIoJ3gnLCBsYWJlbC54KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gcGllT3V0ZXJMYWJlbExheW91dChpdGVtcywgbGFiZWxzLCBzaGFwZXMsIHJlZ2lvbikge1xuICAgIHZhciBvZmZzZXQgPSBpdGVtc1swXSA/IGl0ZW1zWzBdLm9mZnNldCA6IDA7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBsYWJlbHNbMF0uZ2V0KCdjb29yZGluYXRlJyk7XG4gICAgdmFyIHJhZGl1cyA9IGNvb3JkaW5hdGUuZ2V0UmFkaXVzKCk7XG4gICAgdmFyIGNlbnRlciA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgLy8gbm90ZSBsYWJlbEhlaWdodCDlj6/ku6XmjqfliLYgbGFiZWwg55qE6KGM6auYXG4gICAgICAgIHZhciBsaW5lSGVpZ2h0XzEgPSB1dGlsXzEuZ2V0KGl0ZW1zWzBdLCAnbGFiZWxIZWlnaHQnLCAxNCk7XG4gICAgICAgIHZhciB0b3RhbFJfMSA9IHJhZGl1cyArIG9mZnNldDtcbiAgICAgICAgdmFyIHRvdGFsSGVpZ2h0XzEgPSB0b3RhbFJfMSAqIDIgKyBsaW5lSGVpZ2h0XzEgKiAyO1xuICAgICAgICB2YXIgcGxvdFJhbmdlXzEgPSB7XG4gICAgICAgICAgICBzdGFydDogY29vcmRpbmF0ZS5zdGFydCxcbiAgICAgICAgICAgIGVuZDogY29vcmRpbmF0ZS5lbmQsXG4gICAgICAgIH07XG4gICAgICAgIC8vIHN0ZXAgMTogc2VwYXJhdGUgbGFiZWxzXG4gICAgICAgIHZhciBoYWx2ZXNfMSA9IFtcbiAgICAgICAgICAgIFtdLFxuICAgICAgICAgICAgW10sXG4gICAgICAgIF07XG4gICAgICAgIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsSXRlbSkge1xuICAgICAgICAgICAgaWYgKCFsYWJlbEl0ZW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFiZWxJdGVtLnggPCBjZW50ZXIueCkge1xuICAgICAgICAgICAgICAgIC8vIGxlZnRcbiAgICAgICAgICAgICAgICBoYWx2ZXNfMVswXS5wdXNoKGxhYmVsSXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyByaWdodCBvciBjZW50ZXIgd2lsbCBiZSBwdXQgb24gdGhlIHJpZ2h0IHNpZGVcbiAgICAgICAgICAgICAgICBoYWx2ZXNfMVsxXS5wdXNoKGxhYmVsSXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBoYWx2ZXNfMS5mb3JFYWNoKGZ1bmN0aW9uIChoYWxmLCBpbmRleCkge1xuICAgICAgICAgICAgLy8gc3RlcCAyOiByZWR1Y2UgbGFiZWxzXG4gICAgICAgICAgICB2YXIgbWF4TGFiZWxzQ291bnRGb3JPbmVTaWRlID0gdG90YWxIZWlnaHRfMSAvIGxpbmVIZWlnaHRfMTtcbiAgICAgICAgICAgIGlmIChoYWxmLmxlbmd0aCA+IG1heExhYmVsc0NvdW50Rm9yT25lU2lkZSkge1xuICAgICAgICAgICAgICAgIGhhbGYuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICAvLyBzb3J0IGJ5IHBlcmNlbnRhZ2UgREVTQ1xuICAgICAgICAgICAgICAgICAgICAvLyBmaXhtZS14aW5taW5nIOebruWJjei/mOiOt+WPluS4jeWIsO+8jOmcgOimgeS9v+eUqCBzY2FsZSDljrvojrflj5YgcGVyY2VudFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYlsnZGF0YS5wZXJjZW50J10gLSBhWydkYXRhLnBlcmNlbnQnXTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2YXIgaGlkZGVuID0gaGFsZi5zcGxpY2UobWF4TGFiZWxzQ291bnRGb3JPbmVTaWRlLCBoYWxmLmxlbmd0aCAtIG1heExhYmVsc0NvdW50Rm9yT25lU2lkZSArIDEpO1xuICAgICAgICAgICAgICAgIGhpZGRlbi5mb3JFYWNoKGZ1bmN0aW9uIChsKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBsYWJlbHMuZmluZEluZGV4KGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtLmdldCgnaWQnKSA9PT0gbC5pZDsgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsYWJlbHNbaWR4XSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzW2lkeF0ucmVtb3ZlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5ZCM5pe256e76ZmkXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFudGlDb2xsaXNpb24obGFiZWxzLCBoYWxmLCBsaW5lSGVpZ2h0XzEsIHBsb3RSYW5nZV8xLCBjZW50ZXIsIHRvdGFsUl8xLCBpbmRleCA9PT0gMSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyDphY3nva4gbGFiZWxMaW5lXG4gICAgdXRpbF8xLmVhY2goaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIGlmIChpdGVtICYmIGl0ZW0ubGFiZWxMaW5lKSB7XG4gICAgICAgICAgICB2YXIgYW5nbGUgPSBpdGVtLmFuZ2xlO1xuICAgICAgICAgICAgLy8g6LS06L+R5ZyG5ZGoXG4gICAgICAgICAgICB2YXIgc3RhcnRQb2ludCA9IGdyYXBoaWNzXzEucG9sYXJUb0NhcnRlc2lhbihjZW50ZXIueCwgY2VudGVyLnksIHJhZGl1cywgYW5nbGUpO1xuICAgICAgICAgICAgdmFyIGl0ZW1YID0gaXRlbS54ICsgdXRpbF8xLmdldChpdGVtLCAnb2Zmc2V0WCcsIDApICogKE1hdGguY29zKGFuZ2xlKSA+IDAgPyAxIDogLTEpO1xuICAgICAgICAgICAgdmFyIGl0ZW1ZID0gaXRlbS55ICsgdXRpbF8xLmdldChpdGVtLCAnb2Zmc2V0WScsIDApICogKE1hdGguc2luKGFuZ2xlKSA+IDAgPyAxIDogLTEpO1xuICAgICAgICAgICAgdmFyIGVuZFBvaW50ID0ge1xuICAgICAgICAgICAgICAgIHg6IGl0ZW1YIC0gTWF0aC5jb3MoYW5nbGUpICogTUFSR0lOLFxuICAgICAgICAgICAgICAgIHk6IGl0ZW1ZIC0gTWF0aC5zaW4oYW5nbGUpICogTUFSR0lOLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhciBzbW9vdGhDb25uZWN0b3IgPSBpdGVtLmxhYmVsTGluZS5zbW9vdGg7XG4gICAgICAgICAgICB2YXIgcGF0aCA9IFtdO1xuICAgICAgICAgICAgdmFyIGR4ID0gZW5kUG9pbnQueCAtIGNlbnRlci54O1xuICAgICAgICAgICAgdmFyIGR5ID0gZW5kUG9pbnQueSAtIGNlbnRlci55O1xuICAgICAgICAgICAgdmFyIGVuZEFuZ2xlID0gTWF0aC5hdGFuKGR5IC8gZHgpO1xuICAgICAgICAgICAgLy8g56ys5LiJ6LGh6ZmQICYg56ys5Zub6LGh6ZmQXG4gICAgICAgICAgICBpZiAoZHggPCAwKSB7XG4gICAgICAgICAgICAgICAgZW5kQW5nbGUgKz0gTWF0aC5QSTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIOm7mOiupCBzbW9vdGgsIHVuZGVmaW5lZCDkuZ/kuLogc21vb3RoXG4gICAgICAgICAgICBpZiAoc21vb3RoQ29ubmVjdG9yID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGlmICghdXRpbF8xLmlzT2JqZWN0KGl0ZW0ubGFiZWxMaW5lKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBsYWJlbExpbmU6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5sYWJlbExpbmUgPSB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g6KGo56S65byn57q/55qE5pa55ZCR77yMMCDooajnpLrku47otbfngrnliLDnu4jngrnmsr/pgIbml7bpkojnlLvlvKcsIDEg6KGo56S66aG65pe26ZKIXG4gICAgICAgICAgICAgICAgdmFyIHN3ZWVwRmxhZyA9IDA7XG4gICAgICAgICAgICAgICAgLy8g56ys5LiA6LGh6ZmQXG4gICAgICAgICAgICAgICAgaWYgKChhbmdsZSA8IDAgJiYgYW5nbGUgPiAtTWF0aC5QSSAvIDIpIHx8IGFuZ2xlID4gTWF0aC5QSSAqIDEuNSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZW5kUG9pbnQueSA+IHN0YXJ0UG9pbnQueSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dlZXBGbGFnID0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyDnrKzkuozosaHpmZBcbiAgICAgICAgICAgICAgICBpZiAoYW5nbGUgPj0gMCAmJiBhbmdsZSA8IE1hdGguUEkgLyAyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbmRQb2ludC55ID4gc3RhcnRQb2ludC55KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2VlcEZsYWcgPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOesrOS4ieixoemZkFxuICAgICAgICAgICAgICAgIGlmIChhbmdsZSA+PSBNYXRoLlBJIC8gMiAmJiBhbmdsZSA8IE1hdGguUEkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0UG9pbnQueSA+IGVuZFBvaW50LnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3ZWVwRmxhZyA9IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g56ys5Zub6LGh6ZmQXG4gICAgICAgICAgICAgICAgaWYgKGFuZ2xlIDwgLU1hdGguUEkgLyAyIHx8IChhbmdsZSA+PSBNYXRoLlBJICYmIGFuZ2xlIDwgTWF0aC5QSSAqIDEuNSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0UG9pbnQueSA+IGVuZFBvaW50LnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3ZWVwRmxhZyA9IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGRpc3RhbmNlID0gb2Zmc2V0IC8gMiA+IDQgPyA0IDogTWF0aC5tYXgob2Zmc2V0IC8gMiAtIDEsIDApO1xuICAgICAgICAgICAgICAgIHZhciBicmVha1BvaW50ID0gZ3JhcGhpY3NfMS5wb2xhclRvQ2FydGVzaWFuKGNlbnRlci54LCBjZW50ZXIueSwgcmFkaXVzICsgZGlzdGFuY2UsIGFuZ2xlKTtcbiAgICAgICAgICAgICAgICAvLyDlnIblvKfnmoTnu5PmnZ/ngrlcbiAgICAgICAgICAgICAgICB2YXIgYnJlYWtQb2ludDMgPSBncmFwaGljc18xLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyLngsIGNlbnRlci55LCByYWRpdXMgKyBvZmZzZXQgLyAyLCBlbmRBbmdsZSk7XG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICAgICAgICAgKiBNIDEwMCAxMDAgTDEwMCA5MCBBIDUwIDUwIDAgMCAwIDE1MCA1MFxuICAgICAgICAgICAgICAgICAqIOenu+WKqOiHsyAoMTAwLCAxMDApLCDov57mjqXliLAgKDEwMCwgOTApLCDku6UgKDUwLCA1MCkg5Li65ZyG5b+D77yM57uY5Yi25ZyG5byn6IezICgxNTAsIDUwKTtcbiAgICAgICAgICAgICAgICAgKiBBIOWRveS7pOeahOesrCA0IOS4quWPguaVsCBsYXJnZS1hcmMtZmxhZywg5Yaz5a6a5byn57q/5piv5aSn5LqO6L+Y5piv5bCP5LqOIDE4MCDluqY6IDAg6KGo56S65bCP6KeS5bqm5byn77yMMSDooajnpLrlpKfop5JcbiAgICAgICAgICAgICAgICAgKiDnrKwgNSDkuKrlj4LmlbA6IOaYr+WQpumhuuaXtumSiOe7mOWItlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIC8vIOm7mOiupOWwj+W8p1xuICAgICAgICAgICAgICAgIHZhciBsYXJnZUFyY0ZsYWcgPSAwO1xuICAgICAgICAgICAgICAgIC8vIHN0ZXAxOiDnp7vliqjoh7PotbfngrlcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goXCJNIFwiICsgc3RhcnRQb2ludC54ICsgXCIgXCIgKyBzdGFydFBvaW50LnkpO1xuICAgICAgICAgICAgICAgIC8vIHN0ZXAyOiDov57mjqXmi5DngrlcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goXCJMIFwiICsgYnJlYWtQb2ludC54ICsgXCIgXCIgKyBicmVha1BvaW50LnkpO1xuICAgICAgICAgICAgICAgIC8vIHN0ZXAzOiDnu5jliLblnIblvKcg6IezIOe7k+adn+eCuVxuICAgICAgICAgICAgICAgIHBhdGgucHVzaChcIkEgXCIgKyBjZW50ZXIueCArIFwiIFwiICsgY2VudGVyLnkgKyBcIiAwIFwiICsgbGFyZ2VBcmNGbGFnICsgXCIgXCIgKyBzd2VlcEZsYWcgKyBcIiBcIiArIGJyZWFrUG9pbnQzLnggKyBcIiBcIiArIGJyZWFrUG9pbnQzLnkpO1xuICAgICAgICAgICAgICAgIC8vIHN0ZXA0OiDov57mjqXnu5PmnZ/ngrlcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goXCJMIFwiICsgZW5kUG9pbnQueCArIFwiIFwiICsgZW5kUG9pbnQueSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgYnJlYWtQb2ludCA9IGdyYXBoaWNzXzEucG9sYXJUb0NhcnRlc2lhbihjZW50ZXIueCwgY2VudGVyLnksIHJhZGl1cyArIChvZmZzZXQgLyAyID4gNCA/IDQgOiBNYXRoLm1heChvZmZzZXQgLyAyIC0gMSwgMCkpLCBhbmdsZSk7XG4gICAgICAgICAgICAgICAgLy8gRzIg5pen55qE5ouJ57q/XG4gICAgICAgICAgICAgICAgLy8gcGF0aC5wdXNoKCdRJywgYCR7YnJlYWtQb2ludC54fWAsIGAke2JyZWFrUG9pbnQueX1gLCBgJHtlbmRQb2ludC54fWAsIGAke2VuZFBvaW50Lnl9YCk7XG4gICAgICAgICAgICAgICAgdmFyIHhTaWduID0gc3RhcnRQb2ludC54IDwgY2VudGVyLnggPyAxIDogLTE7XG4gICAgICAgICAgICAgICAgLy8gc3RlcDE6IOi/nuaOpee7k+adn+eCuVxuICAgICAgICAgICAgICAgIHBhdGgucHVzaChcIk0gXCIgKyBlbmRQb2ludC54ICsgXCIgXCIgKyBlbmRQb2ludC55KTtcbiAgICAgICAgICAgICAgICB2YXIgc2xvcGUxID0gKHN0YXJ0UG9pbnQueSAtIGNlbnRlci55KSAvIChzdGFydFBvaW50LnggLSBjZW50ZXIueCk7XG4gICAgICAgICAgICAgICAgdmFyIHNsb3BlMiA9IChlbmRQb2ludC55IC0gY2VudGVyLnkpIC8gKGVuZFBvaW50LnggLSBjZW50ZXIueCk7XG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKHNsb3BlMSAtIHNsb3BlMikgPiBNYXRoLnBvdyhNYXRoLkUsIC0xNikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RlcDI6IOe7mOWItiBjdXJ2ZSBsaW5lICjotbfngrkgJiDnu5PlkIjngrnkuI7lnIblv4PnmoTmlpznjofkuI3nrYnml7YsIOeUseS6juWtmOWcqOivr+W3riwg5L2/55So6L+R5Ly85aSE55CGKVxuICAgICAgICAgICAgICAgICAgICBwYXRoLnB1c2guYXBwbHkocGF0aCwgW1xuICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZW5kUG9pbnQueCArIHhTaWduICogNCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZFBvaW50LnksXG4gICAgICAgICAgICAgICAgICAgICAgICAyICogYnJlYWtQb2ludC54IC0gc3RhcnRQb2ludC54LFxuICAgICAgICAgICAgICAgICAgICAgICAgMiAqIGJyZWFrUG9pbnQueSAtIHN0YXJ0UG9pbnQueSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UG9pbnQueCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UG9pbnQueSxcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIHN0ZXAzOiDov57mjqXoh7PotbfngrlcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goXCJMIFwiICsgc3RhcnRQb2ludC54ICsgXCIgXCIgKyBzdGFydFBvaW50LnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXRlbS5sYWJlbExpbmUucGF0aCA9IHBhdGguam9pbignICcpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnRzLnBpZU91dGVyTGFiZWxMYXlvdXQgPSBwaWVPdXRlckxhYmVsTGF5b3V0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3V0ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb29yZGluYXRlXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9jb29yZGluYXRlXCIpO1xudmFyIGdyYXBoaWNzXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ncmFwaGljc1wiKTtcbnZhciBwb2xhcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcG9sYXJcIikpO1xuLyoqXG4gKiDppbzlm74gbGFiZWxcbiAqL1xudmFyIFBpZUxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBpZUxhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBpZUxhYmVsKGdlb21ldHJ5KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGdlb21ldHJ5KSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5kZWZhdWx0TGF5b3V0ID0gJ2Rpc3RyaWJ1dGUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFBpZUxhYmVsLnByb3RvdHlwZS5nZXREZWZhdWx0TGFiZWxDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZ2V0KHRoaXMuZ2VvbWV0cnkudGhlbWUsICdwaWVMYWJlbHMnLCB7fSk7XG4gICAgfTtcbiAgICBQaWVMYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIG9mZnNldCB8fCAwO1xuICAgIH07XG4gICAgUGllTGFiZWwucHJvdG90eXBlLmdldExhYmVsUm90YXRlID0gZnVuY3Rpb24gKGFuZ2xlLCBvZmZzZXQsIGlzTGFiZWxMaW1pdCkge1xuICAgICAgICB2YXIgcm90YXRlO1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgcm90YXRlID0gYW5nbGU7XG4gICAgICAgICAgICBpZiAocm90YXRlID4gTWF0aC5QSSAvIDIpIHtcbiAgICAgICAgICAgICAgICByb3RhdGUgPSByb3RhdGUgLSBNYXRoLlBJO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJvdGF0ZSA8IC1NYXRoLlBJIC8gMikge1xuICAgICAgICAgICAgICAgIHJvdGF0ZSA9IHJvdGF0ZSArIE1hdGguUEk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJvdGF0ZTtcbiAgICB9O1xuICAgIFBpZUxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbEFsaWduID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlLmdldENlbnRlcigpO1xuICAgICAgICB2YXIgYWxpZ247XG4gICAgICAgIGlmIChwb2ludC5hbmdsZSA8PSBNYXRoLlBJIC8gMiAmJiBwb2ludC54ID49IGNlbnRlci54KSB7XG4gICAgICAgICAgICBhbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgfVxuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KHBvaW50Lm9mZnNldCk7XG4gICAgICAgIGlmIChvZmZzZXQgPD0gMCkge1xuICAgICAgICAgICAgaWYgKGFsaWduID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICAgICAgYWxpZ24gPSAnbGVmdCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbGlnbiA9ICdyaWdodCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFsaWduO1xuICAgIH07XG4gICAgUGllTGFiZWwucHJvdG90eXBlLmdldEFyY1BvaW50ID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHJldHVybiBwb2ludDtcbiAgICB9O1xuICAgIFBpZUxhYmVsLnByb3RvdHlwZS5nZXRQb2ludEFuZ2xlID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBzdGFydFBvaW50ID0ge1xuICAgICAgICAgICAgeDogdXRpbF8xLmlzQXJyYXkocG9pbnQueCkgPyBwb2ludC54WzBdIDogcG9pbnQueCxcbiAgICAgICAgICAgIHk6IHBvaW50LnlbMF0sXG4gICAgICAgIH07XG4gICAgICAgIHZhciBlbmRQb2ludCA9IHtcbiAgICAgICAgICAgIHg6IHV0aWxfMS5pc0FycmF5KHBvaW50LngpID8gcG9pbnQueFsxXSA6IHBvaW50LngsXG4gICAgICAgICAgICB5OiBwb2ludC55WzFdLFxuICAgICAgICB9O1xuICAgICAgICB2YXIgYW5nbGU7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gY29vcmRpbmF0ZV8xLmdldEFuZ2xlQnlQb2ludChjb29yZGluYXRlLCBzdGFydFBvaW50KTtcbiAgICAgICAgaWYgKHBvaW50LnBvaW50cyAmJiBwb2ludC5wb2ludHNbMF0ueSA9PT0gcG9pbnQucG9pbnRzWzFdLnkpIHtcbiAgICAgICAgICAgIGFuZ2xlID0gc3RhcnRBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBlbmRBbmdsZSA9IGNvb3JkaW5hdGVfMS5nZXRBbmdsZUJ5UG9pbnQoY29vcmRpbmF0ZSwgZW5kUG9pbnQpO1xuICAgICAgICAgICAgaWYgKHN0YXJ0QW5nbGUgPj0gZW5kQW5nbGUpIHtcbiAgICAgICAgICAgICAgICAvLyAxMDAlIHBpZSBzbGljZVxuICAgICAgICAgICAgICAgIGVuZEFuZ2xlID0gZW5kQW5nbGUgKyBNYXRoLlBJICogMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFuZ2xlID0gc3RhcnRBbmdsZSArIChlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpIC8gMjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYW5nbGU7XG4gICAgfTtcbiAgICBQaWVMYWJlbC5wcm90b3R5cGUuZ2V0Q2lyY2xlUG9pbnQgPSBmdW5jdGlvbiAoYW5nbGUsIG9mZnNldCwgcCkge1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgY2VudGVyID0gY29vcmRpbmF0ZS5nZXRDZW50ZXIoKTtcbiAgICAgICAgdmFyIHIgPSBjb29yZGluYXRlLmdldFJhZGl1cygpICsgb2Zmc2V0O1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBncmFwaGljc18xLnBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyLngsIGNlbnRlci55LCByLCBhbmdsZSkpLCB7IGFuZ2xlOiBhbmdsZSxcbiAgICAgICAgICAgIHI6IHIgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gUGllTGFiZWw7XG59KHBvbGFyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUGllTGFiZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1waWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb29yZGluYXRlXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9jb29yZGluYXRlXCIpO1xudmFyIGNvb3JkaW5hdGVfMiA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2Nvb3JkaW5hdGVcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG52YXIgSEFMRl9QSSA9IE1hdGguUEkgLyAyO1xuLyoqXG4gKiDmnoHlnZDmoIfkuIvnmoTlm77lvaIgbGFiZWxcbiAqL1xudmFyIFBvbGFyTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUG9sYXJMYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQb2xhckxhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqIOiOt+WPluaWh+acrOeahOWvuem9kOaWueW8j1xuICAgICAqIEBwYXJhbSBwb2ludFxuICAgICAqL1xuICAgIFBvbGFyTGFiZWwucHJvdG90eXBlLmdldExhYmVsQWxpZ24gPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIGFsaWduO1xuICAgICAgICBpZiAocG9pbnQubGFiZWxFbWl0KSB7XG4gICAgICAgICAgICBhbGlnbiA9IHBvaW50LmFuZ2xlIDw9IE1hdGguUEkgLyAyICYmIHBvaW50LmFuZ2xlID49IC1NYXRoLlBJIC8gMiA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICBhbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGNlbnRlciA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KHBvaW50Lm9mZnNldCk7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMocG9pbnQueCAtIGNlbnRlci54KSA8IDEpIHtcbiAgICAgICAgICAgICAgICBhbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocG9pbnQuYW5nbGUgPiBNYXRoLlBJIHx8IHBvaW50LmFuZ2xlIDw9IDApIHtcbiAgICAgICAgICAgICAgICBhbGlnbiA9IG9mZnNldCA+IDAgPyAnbGVmdCcgOiAncmlnaHQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYWxpZ24gPSBvZmZzZXQgPiAwID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWxpZ247XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKiDojrflj5YgbGFiZWwg55qE5L2N572uXG4gICAgICogQHBhcmFtIGxhYmVsQ2ZnXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhXG4gICAgICogQHBhcmFtIGluZGV4XG4gICAgICovXG4gICAgUG9sYXJMYWJlbC5wcm90b3R5cGUuZ2V0TGFiZWxQb2ludCA9IGZ1bmN0aW9uIChsYWJlbENmZywgbWFwcGluZ0RhdGEsIGluZGV4KSB7XG4gICAgICAgIHZhciBmYWN0b3IgPSAxO1xuICAgICAgICB2YXIgYXJjUG9pbnQ7XG4gICAgICAgIHZhciBjb250ZW50ID0gbGFiZWxDZmcuY29udGVudFtpbmRleF07XG4gICAgICAgIGlmICh0aGlzLmlzVG9NaWRkbGUobWFwcGluZ0RhdGEpKSB7XG4gICAgICAgICAgICBhcmNQb2ludCA9IHRoaXMuZ2V0TWlkZGxlUG9pbnQobWFwcGluZ0RhdGEucG9pbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChsYWJlbENmZy5jb250ZW50Lmxlbmd0aCA9PT0gMSAmJiBpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZmFjdG9yID0gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhcmNQb2ludCA9IHRoaXMuZ2V0QXJjUG9pbnQobWFwcGluZ0RhdGEsIGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KGxhYmVsQ2ZnLm9mZnNldCkgKiBmYWN0b3I7XG4gICAgICAgIHZhciBtaWRkbGVBbmdsZSA9IHRoaXMuZ2V0UG9pbnRBbmdsZShhcmNQb2ludCk7XG4gICAgICAgIHZhciBpc0xhYmVsRW1pdCA9IGxhYmVsQ2ZnLmxhYmVsRW1pdDtcbiAgICAgICAgdmFyIGxhYmVsUG9zaXRpb25DZmcgPSB0aGlzLmdldENpcmNsZVBvaW50KG1pZGRsZUFuZ2xlLCBvZmZzZXQsIGFyY1BvaW50LCBpc0xhYmVsRW1pdCk7XG4gICAgICAgIGlmIChsYWJlbFBvc2l0aW9uQ2ZnLnIgPT09IDApIHtcbiAgICAgICAgICAgIC8vIOWmguaenOaWh+acrOS9jee9ruS9jeS6juWchuW/g++8jOWImeS4jeWxleekulxuICAgICAgICAgICAgbGFiZWxQb3NpdGlvbkNmZy5jb250ZW50ID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsYWJlbFBvc2l0aW9uQ2ZnLmNvbnRlbnQgPSBjb250ZW50O1xuICAgICAgICAgICAgbGFiZWxQb3NpdGlvbkNmZy5hbmdsZSA9IG1pZGRsZUFuZ2xlO1xuICAgICAgICAgICAgbGFiZWxQb3NpdGlvbkNmZy5jb2xvciA9IG1hcHBpbmdEYXRhLmNvbG9yO1xuICAgICAgICB9XG4gICAgICAgIGxhYmVsUG9zaXRpb25DZmcucm90YXRlID0gbGFiZWxDZmcuYXV0b1JvdGF0ZVxuICAgICAgICAgICAgPyB0aGlzLmdldExhYmVsUm90YXRlKG1pZGRsZUFuZ2xlLCBvZmZzZXQsIGlzTGFiZWxFbWl0KVxuICAgICAgICAgICAgOiBsYWJlbENmZy5yb3RhdGU7XG4gICAgICAgIGxhYmVsUG9zaXRpb25DZmcuc3RhcnQgPSB7XG4gICAgICAgICAgICB4OiBhcmNQb2ludC54LFxuICAgICAgICAgICAgeTogYXJjUG9pbnQueSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGxhYmVsUG9zaXRpb25DZmc7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blnIblvKfnmoTkvY3nva5cbiAgICAgKi9cbiAgICBQb2xhckxhYmVsLnByb3RvdHlwZS5nZXRBcmNQb2ludCA9IGZ1bmN0aW9uIChtYXBwaW5nRGF0YSwgaW5kZXgpIHtcbiAgICAgICAgaWYgKGluZGV4ID09PSB2b2lkIDApIHsgaW5kZXggPSAwOyB9XG4gICAgICAgIGlmICghdXRpbF8xLmlzQXJyYXkobWFwcGluZ0RhdGEueCkgJiYgIXV0aWxfMS5pc0FycmF5KG1hcHBpbmdEYXRhLnkpKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IG1hcHBpbmdEYXRhLngsXG4gICAgICAgICAgICAgICAgeTogbWFwcGluZ0RhdGEueSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHV0aWxfMS5pc0FycmF5KG1hcHBpbmdEYXRhLngpID8gbWFwcGluZ0RhdGEueFtpbmRleF0gOiBtYXBwaW5nRGF0YS54LFxuICAgICAgICAgICAgeTogdXRpbF8xLmlzQXJyYXkobWFwcGluZ0RhdGEueSkgPyBtYXBwaW5nRGF0YS55W2luZGV4XSA6IG1hcHBpbmdEYXRhLnksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorqHnrpflnZDmoIfnur/ngrnlnKjmnoHlnZDmoIfns7vkuIvop5LluqZcbiAgICAgKiBAcGFyYW0gcG9pbnRcbiAgICAgKi9cbiAgICBQb2xhckxhYmVsLnByb3RvdHlwZS5nZXRQb2ludEFuZ2xlID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHJldHVybiBjb29yZGluYXRlXzIuZ2V0QW5nbGVCeVBvaW50KHRoaXMuZ2V0Q29vcmRpbmF0ZSgpLCBwb2ludCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blnZDmoIfngrnkuI7lnIblv4PlvaLmiJDnmoTlnIbnmoTkvY3nva7kv6Hmga9cbiAgICAgKiBAcGFyYW0gYW5nbGVcbiAgICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAgICogQHBhcmFtIHBvaW50XG4gICAgICogQHBhcmFtIGlzTGFiZWxFbWl0XG4gICAgICovXG4gICAgUG9sYXJMYWJlbC5wcm90b3R5cGUuZ2V0Q2lyY2xlUG9pbnQgPSBmdW5jdGlvbiAoYW5nbGUsIG9mZnNldCwgcG9pbnQsIGlzTGFiZWxFbWl0KSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlLmdldENlbnRlcigpO1xuICAgICAgICB2YXIgciA9IGNvb3JkaW5hdGVfMS5nZXREaXN0YW5jZVRvQ2VudGVyKGNvb3JkaW5hdGUsIHBvaW50KTtcbiAgICAgICAgaWYgKHIgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNlbnRlciksIHsgcjogciB9KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFiZWxBbmdsZSA9IGFuZ2xlO1xuICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQgJiYgciA+IG9mZnNldCAmJiAhaXNMYWJlbEVtaXQpIHtcbiAgICAgICAgICAgIHZhciBhcHBlbmRBbmdsZSA9IE1hdGguYXNpbihvZmZzZXQgLyAoMiAqIHIpKTtcbiAgICAgICAgICAgIGxhYmVsQW5nbGUgPSBhbmdsZSArIGFwcGVuZEFuZ2xlICogMjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHIgPSByICsgb2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBjZW50ZXIueCArIHIgKiBNYXRoLmNvcyhsYWJlbEFuZ2xlKSxcbiAgICAgICAgICAgIHk6IGNlbnRlci55ICsgciAqIE1hdGguc2luKGxhYmVsQW5nbGUpLFxuICAgICAgICAgICAgcjogcixcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPliBsYWJlbCDnmoTml4vovazop5LluqZcbiAgICAgKiBAcGFyYW0gYW5nbGVcbiAgICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAgICogQHBhcmFtIGlzTGFiZWxFbWl0XG4gICAgICovXG4gICAgUG9sYXJMYWJlbC5wcm90b3R5cGUuZ2V0TGFiZWxSb3RhdGUgPSBmdW5jdGlvbiAoYW5nbGUsIG9mZnNldCwgaXNMYWJlbEVtaXQpIHtcbiAgICAgICAgdmFyIHJvdGF0ZSA9IGFuZ2xlICsgSEFMRl9QSTtcbiAgICAgICAgaWYgKGlzTGFiZWxFbWl0KSB7XG4gICAgICAgICAgICByb3RhdGUgLT0gSEFMRl9QSTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm90YXRlKSB7XG4gICAgICAgICAgICBpZiAocm90YXRlID4gSEFMRl9QSSkge1xuICAgICAgICAgICAgICAgIHJvdGF0ZSA9IHJvdGF0ZSAtIE1hdGguUEk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyb3RhdGUgPCAtSEFMRl9QSSkge1xuICAgICAgICAgICAgICAgIHJvdGF0ZSA9IHJvdGF0ZSArIE1hdGguUEk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJvdGF0ZTtcbiAgICB9O1xuICAgIC8vIOiOt+WPluS4reW/g+eahOS9jee9rlxuICAgIFBvbGFyTGFiZWwucHJvdG90eXBlLmdldE1pZGRsZVBvaW50ID0gZnVuY3Rpb24gKHBvaW50cykge1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICAgICAgICB2YXIgbWlkZGxlUG9pbnQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgdXRpbF8xLmVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgICAgIG1pZGRsZVBvaW50LnggKz0gcG9pbnQueDtcbiAgICAgICAgICAgIG1pZGRsZVBvaW50LnkgKz0gcG9pbnQueTtcbiAgICAgICAgfSk7XG4gICAgICAgIG1pZGRsZVBvaW50LnggLz0gY291bnQ7XG4gICAgICAgIG1pZGRsZVBvaW50LnkgLz0gY291bnQ7XG4gICAgICAgIG1pZGRsZVBvaW50ID0gY29vcmRpbmF0ZS5jb252ZXJ0KG1pZGRsZVBvaW50KTtcbiAgICAgICAgcmV0dXJuIG1pZGRsZVBvaW50O1xuICAgIH07XG4gICAgLy8g5piv5ZCm5bGF5LitXG4gICAgUG9sYXJMYWJlbC5wcm90b3R5cGUuaXNUb01pZGRsZSA9IGZ1bmN0aW9uIChtYXBwaW5nRGF0YSkge1xuICAgICAgICByZXR1cm4gbWFwcGluZ0RhdGEueC5sZW5ndGggPiAyO1xuICAgIH07XG4gICAgcmV0dXJuIFBvbGFyTGFiZWw7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQb2xhckxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cG9sYXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBwYXRoXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9wYXRoXCIpKTtcbi8qKiDlvJXlhaUgUGF0aCDlr7nlupTnmoQgU2hhcGVGYWN0b3J5ICovXG5yZXF1aXJlKFwiLi9zaGFwZS9saW5lXCIpO1xuLyoqXG4gKiBMaW5lIOWHoOS9leagh+iusOOAglxuICog5bi455So5LqO5oqY57q/5Zu+55qE57uY5Yi244CCXG4gKi9cbnZhciBMaW5lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZShjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2xpbmUnO1xuICAgICAgICB2YXIgX2EgPSBjZmcuc29ydGFibGUsIHNvcnRhYmxlID0gX2EgPT09IHZvaWQgMCA/IHRydWUgOiBfYTsgLy8gTGluZSDpu5jorqTkvJrlr7nmlbDmja7mjInnhacgeCDovbTlrZfmrrXov5vooYzmjpLluo9cbiAgICAgICAgX3RoaXMuc29ydGFibGUgPSBzb3J0YWJsZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICByZXR1cm4gTGluZTtcbn0ocGF0aF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbnZhciBlbGVtZW50XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9lbGVtZW50XCIpKTtcbi8qKiDlvJXlhaXlr7nlupTnmoQgU2hhcGVGYWN0b3J5ICovXG5yZXF1aXJlKFwiLi9zaGFwZS9saW5lXCIpO1xudmFyIGlzX21vZGVsX2NoYW5nZV8xID0gcmVxdWlyZShcIi4vdXRpbC9pcy1tb2RlbC1jaGFuZ2VcIik7XG4vKipcbiAqIFBhdGgg5Yeg5L2V5qCH6K6w44CCXG4gKiDnlKjkuo7nu5jliLbot6/lvoTlm77nrYnjgIJcbiAqL1xudmFyIFBhdGggPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGF0aCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQYXRoKGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjZmcpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAncGF0aCc7XG4gICAgICAgIF90aGlzLnNoYXBlVHlwZSA9ICdsaW5lJztcbiAgICAgICAgdmFyIF9hID0gY2ZnLmNvbm5lY3ROdWxscywgY29ubmVjdE51bGxzID0gX2EgPT09IHZvaWQgMCA/IGZhbHNlIDogX2EsIF9iID0gY2ZnLnNob3dTaW5nbGVQb2ludCwgc2hvd1NpbmdsZVBvaW50ID0gX2IgPT09IHZvaWQgMCA/IHRydWUgOiBfYjtcbiAgICAgICAgX3RoaXMuY29ubmVjdE51bGxzID0gY29ubmVjdE51bGxzO1xuICAgICAgICBfdGhpcy5zaG93U2luZ2xlUG9pbnQgPSBzaG93U2luZ2xlUG9pbnQ7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5Yib5bu65omA5pyJ55qEIEVsZW1lbnQg5a6e5L6L77yM5a+55LqOIFBhdGjjgIFMaW5l44CBQXJlYe+8jOS4gOe7hOaVsOaNruWvueW6lOS4gOS4qiBFbGVtZW5044CCXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhXG4gICAgICogQHBhcmFtIFtpc1VwZGF0ZV1cbiAgICAgKiBAcmV0dXJucyBlbGVtZW50c1xuICAgICAqL1xuICAgIFBhdGgucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnRzID0gZnVuY3Rpb24gKG1hcHBpbmdEYXRhLCBpbmRleCwgaXNVcGRhdGUpIHtcbiAgICAgICAgaWYgKGlzVXBkYXRlID09PSB2b2lkIDApIHsgaXNVcGRhdGUgPSBmYWxzZTsgfVxuICAgICAgICAvLyBQYXRoIOeahOavj+S4qiBlbGVtZW50IOWvueW6lOS4gOe7hOaVsOaNrlxuICAgICAgICB2YXIgX2EgPSB0aGlzLCBsYXN0RWxlbWVudHNNYXAgPSBfYS5sYXN0RWxlbWVudHNNYXAsIGVsZW1lbnRzTWFwID0gX2EuZWxlbWVudHNNYXAsIGVsZW1lbnRzID0gX2EuZWxlbWVudHMsIGNvbnRhaW5lciA9IF9hLmNvbnRhaW5lcjtcbiAgICAgICAgdmFyIGVsZW1lbnRJZCA9IHRoaXMuZ2V0RWxlbWVudElkKG1hcHBpbmdEYXRhKTtcbiAgICAgICAgdmFyIHNoYXBlQ2ZnID0gdGhpcy5nZXRTaGFwZUluZm8obWFwcGluZ0RhdGEpO1xuICAgICAgICB2YXIgcmVzdWx0ID0gbGFzdEVsZW1lbnRzTWFwW2VsZW1lbnRJZF07XG4gICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICB2YXIgc2hhcGVGYWN0b3J5ID0gdGhpcy5nZXRTaGFwZUZhY3RvcnkoKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBlbGVtZW50XzEuZGVmYXVsdCh7XG4gICAgICAgICAgICAgICAgc2hhcGVGYWN0b3J5OiBzaGFwZUZhY3RvcnksXG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiBjb250YWluZXIsXG4gICAgICAgICAgICAgICAgb2Zmc2NyZWVuR3JvdXA6IHRoaXMuZ2V0T2Zmc2NyZWVuR3JvdXAoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzdWx0Lmdlb21ldHJ5ID0gdGhpcztcbiAgICAgICAgICAgIHJlc3VsdC5hbmltYXRlID0gdGhpcy5hbmltYXRlT3B0aW9uO1xuICAgICAgICAgICAgcmVzdWx0LmRyYXcoc2hhcGVDZmcsIGlzVXBkYXRlKTsgLy8g57uY5Yi2IHNoYXBlXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBlbGVtZW50IOW3sue7j+WIm+W7ulxuICAgICAgICAgICAgdmFyIHByZVNoYXBlQ2ZnID0gcmVzdWx0LmdldE1vZGVsKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0Nvb3JkaW5hdGVDaGFuZ2VkIHx8IGlzX21vZGVsX2NoYW5nZV8xLmlzTW9kZWxDaGFuZ2UocHJlU2hhcGVDZmcsIHNoYXBlQ2ZnKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5hbmltYXRlID0gdGhpcy5hbmltYXRlT3B0aW9uO1xuICAgICAgICAgICAgICAgIC8vIOmAmui/h+e7mOWItuaVsOaNrueahOWPmOabtOadpeWIpOaWreaYr+WQpumcgOimgeabtOaWsO+8jOWboOS4uueUqOaIt+acieWPr+iDveS8muS/ruaUueWbvuW9ouWxnuaAp+aYoOWwhFxuICAgICAgICAgICAgICAgIHJlc3VsdC51cGRhdGUoc2hhcGVDZmcpOyAvLyDmm7TmlrDlr7nlupTnmoQgZWxlbWVudFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGxhc3RFbGVtZW50c01hcFtlbGVtZW50SWRdO1xuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnRzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgZWxlbWVudHNNYXBbZWxlbWVudElkXSA9IHJlc3VsdDtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnRzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W57uE5oiQ5LiA5p2h57q/77yI5LiA57uE5pWw5o2u77yJ55qE5omA5pyJ54K55Lul5Y+K5pWw5o2uXG4gICAgICogQHBhcmFtIG1hcHBpbmdEYXRhIOaYoOWwhOWQjueahOaVsOe7hFxuICAgICAqL1xuICAgIFBhdGgucHJvdG90eXBlLmdldFBvaW50c0FuZERhdGEgPSBmdW5jdGlvbiAobWFwcGluZ0RhdGEpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IFtdO1xuICAgICAgICB2YXIgZGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbWFwcGluZ0RhdGEubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBvYmogPSBtYXBwaW5nRGF0YVtpXTtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB4OiBvYmoueCxcbiAgICAgICAgICAgICAgICB5OiBvYmoueSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGF0YS5wdXNoKG9ialtjb25zdGFudF8xLkZJRUxEX09SSUdJTl0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb2ludHM6IHBvaW50cyxcbiAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBQYXRoLnByb3RvdHlwZS5nZXRTaGFwZUluZm8gPSBmdW5jdGlvbiAobWFwcGluZ0RhdGEpIHtcbiAgICAgICAgdmFyIHNoYXBlQ2ZnID0gdGhpcy5nZXREcmF3Q2ZnKG1hcHBpbmdEYXRhWzBdKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRQb2ludHNBbmREYXRhKG1hcHBpbmdEYXRhKSwgcG9pbnRzID0gX2EucG9pbnRzLCBkYXRhID0gX2EuZGF0YTtcbiAgICAgICAgc2hhcGVDZmcubWFwcGluZ0RhdGEgPSBtYXBwaW5nRGF0YTtcbiAgICAgICAgc2hhcGVDZmcuZGF0YSA9IGRhdGE7XG4gICAgICAgIHNoYXBlQ2ZnLmlzU3RhY2sgPSAhIXRoaXMuZ2V0QWRqdXN0KCdzdGFjaycpO1xuICAgICAgICBzaGFwZUNmZy5wb2ludHMgPSBwb2ludHM7XG4gICAgICAgIHNoYXBlQ2ZnLmNvbm5lY3ROdWxscyA9IHRoaXMuY29ubmVjdE51bGxzO1xuICAgICAgICBzaGFwZUNmZy5zaG93U2luZ2xlUG9pbnQgPSB0aGlzLnNob3dTaW5nbGVQb2ludDtcbiAgICAgICAgcmV0dXJuIHNoYXBlQ2ZnO1xuICAgIH07XG4gICAgcmV0dXJuIFBhdGg7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2Jhc2VcIikpO1xuLyoqIOW8leWFpSBQb2ludCDlr7nlupTnmoQgU2hhcGVGYWN0b3J5ICovXG5yZXF1aXJlKFwiLi9zaGFwZS9wb2ludFwiKTtcbi8qKlxuICogUG9pbnQg5Yeg5L2V5qCH6K6w44CCXG4gKiDluLjnlKjkuo7nu5jliLbngrnlm77jgIJcbiAqL1xudmFyIFBvaW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBvaW50LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBvaW50KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdwb2ludCc7XG4gICAgICAgIF90aGlzLnNoYXBlVHlwZSA9ICdwb2ludCc7XG4gICAgICAgIF90aGlzLmdlbmVyYXRlUG9pbnRzID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDojrflj5bkuIDkuKrngrnnmoTnu5jliLbkv6Hmga/jgIJcbiAgICAgKiBAcGFyYW0gbWFwcGluZ0RhdHVtXG4gICAgICogQHJldHVybnMgZHJhdyBjZmdcbiAgICAgKi9cbiAgICBQb2ludC5wcm90b3R5cGUuZ2V0RHJhd0NmZyA9IGZ1bmN0aW9uIChtYXBwaW5nRGF0dW0pIHtcbiAgICAgICAgdmFyIHNoYXBlQ2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXREcmF3Q2ZnLmNhbGwodGhpcywgbWFwcGluZ0RhdHVtKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcGVDZmcpLCB7IGlzU3RhY2s6ICEhdGhpcy5nZXRBZGp1c3QoJ3N0YWNrJykgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gUG9pbnQ7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQb2ludDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvaW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG4vKiog5byV5YWlIFBhdGgg5a+55bqU55qEIFNoYXBlRmFjdG9yeSAqL1xucmVxdWlyZShcIi4vc2hhcGUvcG9seWdvblwiKTtcbi8qKlxuICogUG9seWdvbiDlh6DkvZXmoIforrDjgIJcbiAqIOW4uOeUqOS6jue7mOWItuiJsuWdl+WbvuOAgeaXpeWOhuWbvuetieOAglxuICovXG52YXIgUG9seWdvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQb2x5Z29uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBvbHlnb24oKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3BvbHlnb24nO1xuICAgICAgICBfdGhpcy5zaGFwZVR5cGUgPSAncG9seWdvbic7XG4gICAgICAgIF90aGlzLmdlbmVyYXRlUG9pbnRzID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDojrflj5YgU2hhcGUg55qE5YWz6ZSu54K55pWw5o2u44CCXG4gICAgICogQHBhcmFtIG9ialxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgUG9seWdvbi5wcm90b3R5cGUuY3JlYXRlU2hhcGVQb2ludHNDZmcgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZVNoYXBlUG9pbnRzQ2ZnLmNhbGwodGhpcywgb2JqKTtcbiAgICAgICAgdmFyIHggPSBjZmcueDtcbiAgICAgICAgdmFyIHkgPSBjZmcueTtcbiAgICAgICAgdmFyIHRlbXA7XG4gICAgICAgIC8vIHggeSDpg73mmK/mlbDnu4Tml7bvvIzkuI3lgZrlpITnkIZcbiAgICAgICAgaWYgKCEodXRpbF8xLmlzQXJyYXkoeCkgJiYgdXRpbF8xLmlzQXJyYXkoeSkpKSB7XG4gICAgICAgICAgICB2YXIgeFNjYWxlID0gdGhpcy5nZXRYU2NhbGUoKTtcbiAgICAgICAgICAgIHZhciB5U2NhbGUgPSB0aGlzLmdldFlTY2FsZSgpO1xuICAgICAgICAgICAgdmFyIHhDb3VudCA9IHhTY2FsZS52YWx1ZXMubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIHlDb3VudCA9IHlTY2FsZS52YWx1ZXMubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIHhPZmZzZXQgPSAoMC41ICogMSkgLyB4Q291bnQ7XG4gICAgICAgICAgICB2YXIgeU9mZnNldCA9ICgwLjUgKiAxKSAvIHlDb3VudDtcbiAgICAgICAgICAgIGlmICh4U2NhbGUuaXNDYXRlZ29yeSAmJiB5U2NhbGUuaXNDYXRlZ29yeSkge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenHgseemDveaYr+WIhuexu1xuICAgICAgICAgICAgICAgIHggPSBbeCAtIHhPZmZzZXQsIHggLSB4T2Zmc2V0LCB4ICsgeE9mZnNldCwgeCArIHhPZmZzZXRdO1xuICAgICAgICAgICAgICAgIHkgPSBbeSAtIHlPZmZzZXQsIHkgKyB5T2Zmc2V0LCB5ICsgeU9mZnNldCwgeSAtIHlPZmZzZXRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzQXJyYXkoeCkpIHtcbiAgICAgICAgICAgICAgICAvLyB4IOaYr+aVsOe7hFxuICAgICAgICAgICAgICAgIHRlbXAgPSB4O1xuICAgICAgICAgICAgICAgIHggPSBbdGVtcFswXSwgdGVtcFswXSwgdGVtcFsxXSwgdGVtcFsxXV07XG4gICAgICAgICAgICAgICAgeSA9IFt5IC0geU9mZnNldCAvIDIsIHkgKyB5T2Zmc2V0IC8gMiwgeSArIHlPZmZzZXQgLyAyLCB5IC0geU9mZnNldCAvIDJdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzQXJyYXkoeSkpIHtcbiAgICAgICAgICAgICAgICAvLyB5IOaYr+aVsOe7hFxuICAgICAgICAgICAgICAgIHRlbXAgPSB5O1xuICAgICAgICAgICAgICAgIHkgPSBbdGVtcFswXSwgdGVtcFsxXSwgdGVtcFsxXSwgdGVtcFswXV07XG4gICAgICAgICAgICAgICAgeCA9IFt4IC0geE9mZnNldCAvIDIsIHggLSB4T2Zmc2V0IC8gMiwgeCArIHhPZmZzZXQgLyAyLCB4ICsgeE9mZnNldCAvIDJdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2ZnLnggPSB4O1xuICAgICAgICAgICAgY2ZnLnkgPSB5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjZmc7XG4gICAgfTtcbiAgICByZXR1cm4gUG9seWdvbjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBvbHlnb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2x5Z29uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY29vcmRpbmF0ZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvY29vcmRpbmF0ZVwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbi8qKiDlvJXlhaXlr7nlupTnmoQgU2hhcGVGYWN0b3J5ICovXG5yZXF1aXJlKFwiLi9zaGFwZS9zY2hlbWFcIik7XG52YXIgc2hhcGVfc2l6ZV8xID0gcmVxdWlyZShcIi4vdXRpbC9zaGFwZS1zaXplXCIpO1xuLyoqXG4gKiBTY2hlbWEg5Yeg5L2V5qCH6K6w77yM55So5LqO5LiA5Lqb6Ieq5a6a5LmJ5Zu+5b2i55qE57uY5Yi277yM5q+U5aaC566x5Z6L5Zu+44CB6IKh56Wo5Zu+562J44CCXG4gKi9cbnZhciBTY2hlbWEgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2NoZW1hLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNjaGVtYSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnc2NoZW1hJztcbiAgICAgICAgX3RoaXMuc2hhcGVUeXBlID0gJ3NjaGVtYSc7XG4gICAgICAgIF90aGlzLmdlbmVyYXRlUG9pbnRzID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDojrflj5YgU2hhcGUg55qE5YWz6ZSu54K55pWw5o2u44CCXG4gICAgICogQHBhcmFtIHJlY29yZFxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgU2NoZW1hLnByb3RvdHlwZS5jcmVhdGVTaGFwZVBvaW50c0NmZyA9IGZ1bmN0aW9uIChyZWNvcmQpIHtcbiAgICAgICAgdmFyIGNmZyA9IF9zdXBlci5wcm90b3R5cGUuY3JlYXRlU2hhcGVQb2ludHNDZmcuY2FsbCh0aGlzLCByZWNvcmQpO1xuICAgICAgICAvLyDorqHnrpfmr4/kuKogc2hhcGUg55qEIHNpemVcbiAgICAgICAgdmFyIHNpemU7XG4gICAgICAgIHZhciBzaXplQXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCdzaXplJyk7XG4gICAgICAgIGlmIChzaXplQXR0cikge1xuICAgICAgICAgICAgc2l6ZSA9IHRoaXMuZ2V0QXR0cmlidXRlVmFsdWVzKHNpemVBdHRyLCByZWNvcmQpWzBdO1xuICAgICAgICAgICAgLy8g5b2S5LiA5YyWXG4gICAgICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuY29vcmRpbmF0ZTtcbiAgICAgICAgICAgIHZhciBjb29yZGluYXRlV2lkdGggPSBjb29yZGluYXRlXzEuZ2V0WERpbWVuc2lvbkxlbmd0aChjb29yZGluYXRlKTtcbiAgICAgICAgICAgIHNpemUgPSBzaXplIC8gY29vcmRpbmF0ZVdpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRlZmF1bHRTaXplKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0U2l6ZSA9IHNoYXBlX3NpemVfMS5nZXREZWZhdWx0U2l6ZSh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNpemUgPSB0aGlzLmRlZmF1bHRTaXplO1xuICAgICAgICB9XG4gICAgICAgIGNmZy5zaXplID0gc2l6ZTtcbiAgICAgICAgcmV0dXJuIGNmZztcbiAgICB9O1xuICAgIHJldHVybiBTY2hlbWE7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTY2hlbWE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zY2hlbWEuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbnZhciBBcmVhU2hhcGVGYWN0b3J5ID0gYmFzZV8xLnJlZ2lzdGVyU2hhcGVGYWN0b3J5KCdhcmVhJywge1xuICAgIGRlZmF1bHRTaGFwZVR5cGU6ICdhcmVhJyxcbiAgICBnZXREZWZhdWx0UG9pbnRzOiBmdW5jdGlvbiAocG9pbnRJbmZvKSB7XG4gICAgICAgIC8vIGFyZWEg5Z+65pys5qCH6K6w55qE57uY5Yi26ZyA6KaB6I635Y+W5LiK5LiL5Lik6L6555qE6aG254K5XG4gICAgICAgIHZhciB4ID0gcG9pbnRJbmZvLngsIHkwID0gcG9pbnRJbmZvLnkwO1xuICAgICAgICB2YXIgeSA9IHV0aWxfMS5pc0FycmF5KHBvaW50SW5mby55KSA/IHBvaW50SW5mby55IDogW3kwLCBwb2ludEluZm8ueV07XG4gICAgICAgIHJldHVybiB5Lm1hcChmdW5jdGlvbiAoeUl0ZW0pIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICB5OiB5SXRlbSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH0sXG59KTtcbi8vIEFyZWEg5Yeg5L2V5qCH6K6w6buY6K6k55qEIHNoYXBl77ya5aGr5YWF55qE5Yy65Z+f5Zu+XG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnYXJlYScsICdhcmVhJywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgYXR0cnMgPSB1dGlsXzIuZ2V0U2hhcGVBdHRycyhjZmcsIGZhbHNlLCBmYWxzZSwgdGhpcyk7XG4gICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSh7XG4gICAgICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgICAgICBhdHRyczogYXR0cnMsXG4gICAgICAgICAgICBuYW1lOiAnYXJlYScsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfSxcbiAgICBnZXRNYXJrZXI6IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gbWFya2VyQ2ZnLmNvbG9yO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3ltYm9sOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICAgICAgICAgIGlmIChyID09PSB2b2lkIDApIHsgciA9IDUuNTsgfVxuICAgICAgICAgICAgICAgIHJldHVybiBbWydNJywgeCAtIHIsIHkgLSA0XSwgWydMJywgeCArIHIsIHkgLSA0XSwgWydMJywgeCArIHIsIHkgKyA0XSwgWydMJywgeCAtIHIsIHkgKyA0XSwgWydaJ11dO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgcjogNSxcbiAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJlYVNoYXBlRmFjdG9yeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vKipcbiAqIOaPj+i+ueS9huS4jeWhq+WFheeahOWMuuWfn+WbvlxuICovXG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnYXJlYScsICdsaW5lJywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgYXR0cnMgPSB1dGlsXzEuZ2V0U2hhcGVBdHRycyhjZmcsIHRydWUsIGZhbHNlLCB0aGlzKTtcbiAgICAgICAgdmFyIHNoYXBlID0gY29udGFpbmVyLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgIG5hbWU6ICdhcmVhJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgICAgICAgICAgaWYgKHIgPT09IHZvaWQgMCkgeyByID0gNS41OyB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSAtIDRdLCBbJ0wnLCB4ICsgciwgeSAtIDRdLCBbJ0wnLCB4ICsgciwgeSArIDRdLCBbJ0wnLCB4IC0gciwgeSArIDRdLCBbJ1onXV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA1LFxuICAgICAgICAgICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgICAgICAgICAgZmlsbDogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGluZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vYmFzZVwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuLyoqIOaPj+i+ueeahOW5s+a7keabsumdouWbviAqL1xuYmFzZV8xLnJlZ2lzdGVyU2hhcGUoJ2FyZWEnLCAnc21vb3RoLWxpbmUnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5jb29yZGluYXRlO1xuICAgICAgICB2YXIgYXR0cnMgPSB1dGlsXzEuZ2V0U2hhcGVBdHRycyhjZmcsIHRydWUsIHRydWUsIHRoaXMsIHV0aWxfMS5nZXRDb25zdHJhaW50KGNvb3JkaW5hdGUpKTtcbiAgICAgICAgdmFyIHNoYXBlID0gY29udGFpbmVyLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgIG5hbWU6ICdhcmVhJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgICAgICAgICAgaWYgKHIgPT09IHZvaWQgMCkgeyByID0gNS41OyB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSAtIDRdLCBbJ0wnLCB4ICsgciwgeSAtIDRdLCBbJ0wnLCB4ICsgciwgeSArIDRdLCBbJ0wnLCB4IC0gciwgeSArIDRdLCBbJ1onXV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA1LFxuICAgICAgICAgICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgICAgICAgICAgZmlsbDogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c21vb3RoLWxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbi8qKlxuICog5aGr5YWF55qE5bmz5ruR5puy6Z2i5Zu+XG4gKi9cbmJhc2VfMS5yZWdpc3RlclNoYXBlKCdhcmVhJywgJ3Ntb290aCcsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmNvb3JkaW5hdGU7XG4gICAgICAgIHZhciBhdHRycyA9IHV0aWxfMS5nZXRTaGFwZUF0dHJzKGNmZywgZmFsc2UsIHRydWUsIHRoaXMsIHV0aWxfMS5nZXRDb25zdHJhaW50KGNvb3JkaW5hdGUpKTtcbiAgICAgICAgdmFyIHNoYXBlID0gY29udGFpbmVyLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgIG5hbWU6ICdhcmVhJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgICAgICAgICAgaWYgKHIgPT09IHZvaWQgMCkgeyByID0gNS41OyB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSAtIDRdLCBbJ0wnLCB4ICsgciwgeSAtIDRdLCBbJ0wnLCB4ICsgciwgeSArIDRdLCBbJ0wnLCB4IC0gciwgeSArIDRdLCBbJ1onXV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA1LFxuICAgICAgICAgICAgICAgIGZpbGw6IGNvbG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zbW9vdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldENvbnN0cmFpbnQgPSBleHBvcnRzLmdldFNoYXBlQXR0cnMgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2V0X3BhdGhfcG9pbnRzXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtcGF0aC1wb2ludHNcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtc3R5bGVcIik7XG52YXIgcGF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvcGF0aFwiKTtcbmZ1bmN0aW9uIGdldFBhdGgocG9pbnRzLCBpc0luQ2lyY2xlLCBzbW9vdGgsIHJlZ2lzdGVyZWRTaGFwZSwgY29uc3RyYWludCkge1xuICAgIHZhciBwYXRoID0gW107XG4gICAgaWYgKHBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIHRvcExpbmVQb2ludHNfMSA9IFtdOyAvLyBhcmVhIOWMuuWfn+S4iumDqOWIhlxuICAgICAgICB2YXIgYm90dG9tTGluZVBvaW50c18xID0gW107IC8vIGFyZWEg5Yy65Z+f5LiL6YOo5YiGXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIHRvcExpbmVQb2ludHNfMS5wdXNoKHBvaW50WzFdKTtcbiAgICAgICAgICAgIGJvdHRvbUxpbmVQb2ludHNfMS5wdXNoKHBvaW50WzBdKTtcbiAgICAgICAgfVxuICAgICAgICBib3R0b21MaW5lUG9pbnRzXzEgPSBib3R0b21MaW5lUG9pbnRzXzEucmV2ZXJzZSgpO1xuICAgICAgICB1dGlsXzEuZWFjaChbdG9wTGluZVBvaW50c18xLCBib3R0b21MaW5lUG9pbnRzXzFdLCBmdW5jdGlvbiAocG9pbnRzRGF0YSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBzdWJQYXRoID0gW107XG4gICAgICAgICAgICB2YXIgcGFyc2VkUG9pbnRzID0gcmVnaXN0ZXJlZFNoYXBlLnBhcnNlUG9pbnRzKHBvaW50c0RhdGEpO1xuICAgICAgICAgICAgdmFyIHAxID0gcGFyc2VkUG9pbnRzWzBdO1xuICAgICAgICAgICAgaWYgKHRvcExpbmVQb2ludHNfMS5sZW5ndGggPT09IDEgJiYgYm90dG9tTGluZVBvaW50c18xLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIC8vIOmDveWPquacieS4gOS4queCue+8jOe7mOWItuS4gOadoeerlue6v1xuICAgICAgICAgICAgICAgIHN1YlBhdGggPVxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9PT0gMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWydNJywgcDEueCAtIDAuNSwgcDEueV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWydMJywgcDEueCArIDAuNSwgcDEueV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwMS54ICsgMC41LCBwMS55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwMS54IC0gMC41LCBwMS55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNJbkNpcmNsZSkge1xuICAgICAgICAgICAgICAgICAgICBwYXJzZWRQb2ludHMucHVzaCh7IHg6IHAxLngsIHk6IHAxLnkgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzbW9vdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc3ViUGF0aCA9IHBhdGhfMS5nZXRTcGxpbmVQYXRoKHBhcnNlZFBvaW50cywgZmFsc2UsIGNvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3ViUGF0aCA9IHBhdGhfMS5nZXRMaW5lUGF0aChwYXJzZWRQb2ludHMsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBzdWJQYXRoWzBdWzBdID0gJ0wnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhdGggPSBwYXRoLmNvbmNhdChzdWJQYXRoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHBhdGgucHVzaChbJ1onXSk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoO1xufVxuLyoqXG4gKiBAaWdub3JlXG4gKiBHZXRzIHNoYXBlIGF0dHJzXG4gKiBAcGFyYW0gY2ZnXG4gKiBAcGFyYW0gaXNTdHJva2VcbiAqIEBwYXJhbSBzbW9vdGhcbiAqIEBwYXJhbSByZWdpc3RlcmVkU2hhcGVcbiAqIEBwYXJhbSBbY29uc3RyYWludF1cbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldFNoYXBlQXR0cnMoY2ZnLCBpc1N0cm9rZSwgc21vb3RoLCByZWdpc3RlcmVkU2hhcGUsIGNvbnN0cmFpbnQpIHtcbiAgICB2YXIgYXR0cnMgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIGlzU3Ryb2tlLCAhaXNTdHJva2UsICdsaW5lV2lkdGgnKTtcbiAgICB2YXIgY29ubmVjdE51bGxzID0gY2ZnLmNvbm5lY3ROdWxscywgaXNJbkNpcmNsZSA9IGNmZy5pc0luQ2lyY2xlLCBwb2ludHMgPSBjZmcucG9pbnRzLCBzaG93U2luZ2xlUG9pbnQgPSBjZmcuc2hvd1NpbmdsZVBvaW50O1xuICAgIHZhciBwYXRoUG9pbnRzID0gZ2V0X3BhdGhfcG9pbnRzXzEuZ2V0UGF0aFBvaW50cyhwb2ludHMsIGNvbm5lY3ROdWxscywgc2hvd1NpbmdsZVBvaW50KTsgLy8g5qC55o2uIGNvbm5lY3ROdWxscyDphY3nva7ojrflj5blm77lvaLlhbPplK7ngrlcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYXRoUG9pbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBlYWNoUG9pbnRzID0gcGF0aFBvaW50c1tpXTtcbiAgICAgICAgcGF0aCA9IHBhdGguY29uY2F0KGdldFBhdGgoZWFjaFBvaW50cywgaXNJbkNpcmNsZSwgc21vb3RoLCByZWdpc3RlcmVkU2hhcGUsIGNvbnN0cmFpbnQpKTtcbiAgICB9XG4gICAgYXR0cnMucGF0aCA9IHBhdGg7XG4gICAgcmV0dXJuIGF0dHJzO1xufVxuZXhwb3J0cy5nZXRTaGFwZUF0dHJzID0gZ2V0U2hhcGVBdHRycztcbi8qKlxuICogQGlnbm9yZVxuICogR2V0cyBjb25zdHJhaW50XG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHJldHVybnMgY29uc3RyYWludFxuICovXG5mdW5jdGlvbiBnZXRDb25zdHJhaW50KGNvb3JkaW5hdGUpIHtcbiAgICB2YXIgc3RhcnQgPSBjb29yZGluYXRlLnN0YXJ0LCBlbmQgPSBjb29yZGluYXRlLmVuZDtcbiAgICByZXR1cm4gW1xuICAgICAgICBbc3RhcnQueCwgZW5kLnldLFxuICAgICAgICBbZW5kLngsIHN0YXJ0LnldLFxuICAgIF07XG59XG5leHBvcnRzLmdldENvbnN0cmFpbnQgPSBnZXRDb25zdHJhaW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dXRpbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0U2hhcGVGYWN0b3J5ID0gZXhwb3J0cy5yZWdpc3RlclNoYXBlID0gZXhwb3J0cy5yZWdpc3RlclNoYXBlRmFjdG9yeSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHBhdGhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3BhdGgtdXRpbFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwYXRoXzEgPSByZXF1aXJlKFwiLi91dGlsL3BhdGhcIik7XG4vKiogU2hhcGVGYWN0b3J5IOWfuuexuyAqL1xudmFyIFNoYXBlRmFjdG9yeUJhc2UgPSB7XG4gICAgLyoqIOWdkOagh+ezu+WvueixoSAqL1xuICAgIGNvb3JkaW5hdGU6IG51bGwsXG4gICAgLyoqIOm7mOiupOe7mOWItueahCBTaGFwZSDnsbvlnosgKi9cbiAgICBkZWZhdWx0U2hhcGVUeXBlOiBudWxsLFxuICAgIC8qKiDkuLvpopjmoLflvI8gKi9cbiAgICB0aGVtZTogbnVsbCxcbiAgICAvKipcbiAgICAgKiDojrflj5Ygc2hhcGUg57uY5Yi26ZyA6KaB55qE5YWz6ZSu54K5XG4gICAgICogQHBhcmFtIHNoYXBlVHlwZSBzaGFwZSDnsbvlnotcbiAgICAgKiBAcGFyYW0gc2hhcGVQb2ludCDmr4/mnaHmlbDmja7mmKDlsITlkI7nmoTlnZDmoIfngrnku6Xlj4ogc2l6ZSDmlbDlgLxcbiAgICAgKiBAcmV0dXJucyDlm77lvaLlhbPplK7ngrnkv6Hmga9cbiAgICAgKi9cbiAgICBnZXRTaGFwZVBvaW50czogZnVuY3Rpb24gKHNoYXBlVHlwZSwgc2hhcGVQb2ludCkge1xuICAgICAgICB2YXIgc2hhcGUgPSB0aGlzLmdldFNoYXBlKHNoYXBlVHlwZSk7XG4gICAgICAgIGlmIChzaGFwZS5nZXRQb2ludHMpIHtcbiAgICAgICAgICAgIHJldHVybiBzaGFwZS5nZXRQb2ludHMoc2hhcGVQb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RGVmYXVsdFBvaW50cyhzaGFwZVBvaW50KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOagueaNriBzaGFwZSDnsbvlnovojrflj5blhbfkvZPnmoQgc2hhcGUg5a6e5L6LXG4gICAgICogQHBhcmFtIHNoYXBlVHlwZSBzdHJpbmcgc2hhcGUg55qE57G75Z6LXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBnZXRTaGFwZTogZnVuY3Rpb24gKHNoYXBlVHlwZSkge1xuICAgICAgICB2YXIgc2hhcGUgPSB0aGlzW3NoYXBlVHlwZV0gfHwgdGhpc1t0aGlzLmRlZmF1bHRTaGFwZVR5cGVdO1xuICAgICAgICBzaGFwZS5jb29yZGluYXRlID0gdGhpcy5jb29yZGluYXRlO1xuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDojrflj5Ygc2hhcGUg55qE6buY6K6k5YWz6ZSu54K5XG4gICAgICogQG92ZXJyaWRlXG4gICAgICovXG4gICAgZ2V0RGVmYXVsdFBvaW50czogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDojrflj5Ygc2hhcGUg5a+55bqU55qE57yp55Wl5Zu+6YWN572u5L+h5oGv44CCXG4gICAgICogQHBhcmFtIHNoYXBlVHlwZSBzaGFwZSDnsbvlnotcbiAgICAgKiBAcGFyYW0gY29sb3Ig6aKc6ImyXG4gICAgICogQHBhcmFtIGlzSW5Qb2xhciDmmK/lkKblnKjmnoHlnZDmoIfns7vkuItcbiAgICAgKiBAcmV0dXJucyDov5Tlm57nvKnnlaXlm74gbWFya2VyIOmFjee9ruOAglxuICAgICAqL1xuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKHNoYXBlVHlwZSwgbWFya2VyQ2ZnKSB7XG4gICAgICAgIHZhciBzaGFwZSA9IHRoaXMuZ2V0U2hhcGUoc2hhcGVUeXBlKTtcbiAgICAgICAgaWYgKCFzaGFwZS5nZXRNYXJrZXIpIHtcbiAgICAgICAgICAgIHZhciBkZWZhdWx0U2hhcGVUeXBlID0gdGhpcy5kZWZhdWx0U2hhcGVUeXBlO1xuICAgICAgICAgICAgc2hhcGUgPSB0aGlzLmdldFNoYXBlKGRlZmF1bHRTaGFwZVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aGVtZSA9IHRoaXMudGhlbWU7XG4gICAgICAgIHZhciBzaGFwZVN0eWxlID0gdXRpbF8xLmdldCh0aGVtZSwgW3NoYXBlVHlwZSwgJ2RlZmF1bHQnXSwge30pO1xuICAgICAgICB2YXIgbWFya2VyU3R5bGUgPSBzaGFwZS5nZXRNYXJrZXIobWFya2VyQ2ZnKTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBzaGFwZVN0eWxlLCBtYXJrZXJTdHlsZSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDnu5jliLYgc2hhcGVcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKiBAcGFyYW0gc2hhcGVUeXBlIOe7mOWItueahCBzaGFwZSDnsbvlnotcbiAgICAgKiBAcGFyYW0gY2ZnIOe7mOWItiBzaGFwZSDpnIDopoHnmoTkv6Hmga9cbiAgICAgKiBAcGFyYW0gZWxlbWVudCBFbGVtZW50IOWunuS+i1xuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgZHJhd1NoYXBlOiBmdW5jdGlvbiAoc2hhcGVUeXBlLCBjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc2hhcGUgPSB0aGlzLmdldFNoYXBlKHNoYXBlVHlwZSk7XG4gICAgICAgIHJldHVybiBzaGFwZS5kcmF3KGNmZywgY29udGFpbmVyKTtcbiAgICB9LFxufTtcbi8qKiBTaGFwZSDln7rnsbsgKi9cbnZhciBTaGFwZUJhc2UgPSB7XG4gICAgLyoqIOWdkOagh+ezu+WvueixoSAqL1xuICAgIGNvb3JkaW5hdGU6IG51bGwsXG4gICAgLyoqXG4gICAgICog5bCG5b2S5LiA5YyW55qEIHBhdGgg6L2s5o2i5oiQ5Z2Q5qCH57O75LiL55qEIHBhdGhcbiAgICAgKiBAcGFyYW0gcGF0aCDlvZLkuIDljJbnmoTot6/lvoRcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIHBhcnNlUGF0aDogZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmNvb3JkaW5hdGU7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aF91dGlsXzEucGFyc2VQYXRoU3RyaW5nKHBhdGgpO1xuICAgICAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgICAgICBwYXJzZWRQYXRoID0gcGF0aF8xLmNvbnZlcnRQb2xhclBhdGgoY29vcmRpbmF0ZSwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwYXJzZWRQYXRoID0gcGF0aF8xLmNvbnZlcnROb3JtYWxQYXRoKGNvb3JkaW5hdGUsIHBhcnNlZFBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZWRQYXRoO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5bCG5b2S5LiA5YyW55qE5Z2Q5qCH6L2s5o2i5oiQ55S75biD5Z2Q5qCHXG4gICAgICogQHBhcmFtIHBvaW50IOW9kuS4gOWMlueahOWdkOagh+eCueaVsOaNrlxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgcGFyc2VQb2ludDogZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5jb29yZGluYXRlO1xuICAgICAgICByZXR1cm4gY29vcmRpbmF0ZS5jb252ZXJ0KHBvaW50KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIDDvvZ4xIHBvaW50cyDovawg55S75biDIHBvaW50c1xuICAgICAqIEBwYXJhbSBwb2ludHMg6IqC54K56ZuG5ZCIXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBwYXJzZVBvaW50czogZnVuY3Rpb24gKHBvaW50cykge1xuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuY29vcmRpbmF0ZTtcbiAgICAgICAgcmV0dXJuIHBvaW50cy5tYXAoZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gY29vcmRpbmF0ZS5jb252ZXJ0KHBvaW50KTtcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDnu5jliLYgc2hhcGVcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKi9cbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHsgfSxcbn07XG52YXIgU2hhcGVGYWN0b3J5TWFwID0ge307XG4vKipcbiAqIOazqOWGjCBTaGFwZUZhY3RvcnnjgIJcbiAqIEBwYXJhbSBmYWN0b3J5TmFtZSAgU2hhcGVGYWN0b3J5IOWQjeensO+8jOWvueW6lCBHZW9tZXRyeSDlh6DkvZXmoIforrDlkI3np7DjgIJcbiAqIEBwYXJhbSBjZmcg5rOo5YaMIFNoYXBlRmFjdG9yeSDpnIDopoHopoblhpnlrprkuYnnmoTlsZ7mgKfjgIJcbiAqIEByZXR1cm5zIOi/lOWbniBTaGFwZUZhY3Rvcnkg5a+56LGh44CCXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyU2hhcGVGYWN0b3J5KGZhY3RvcnlOYW1lLCBjZmcpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gdXRpbF8xLnVwcGVyRmlyc3QoZmFjdG9yeU5hbWUpO1xuICAgIHZhciBnZW9tT2JqID0gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIFNoYXBlRmFjdG9yeUJhc2UpLCBjZmcpLCB7IGdlb21ldHJ5VHlwZTogZmFjdG9yeU5hbWUgfSk7XG4gICAgU2hhcGVGYWN0b3J5TWFwW2NsYXNzTmFtZV0gPSBnZW9tT2JqO1xuICAgIHJldHVybiBnZW9tT2JqO1xufVxuZXhwb3J0cy5yZWdpc3RlclNoYXBlRmFjdG9yeSA9IHJlZ2lzdGVyU2hhcGVGYWN0b3J5O1xuLyoqXG4gKiDms6jlhowgU2hhcGXjgIJcbiAqIEBwYXJhbSBmYWN0b3J5TmFtZSDlr7nlupTnmoQgU2hhcGVGYWN0b3J5IOWQjeensOOAglxuICogQHBhcmFtIHNoYXBlVHlwZSDms6jlhoznmoQgc2hhcGUg5ZCN56ew44CCXG4gKiBAcGFyYW0gY2ZnIOazqOWGjCBTaGFwZSDpnIDopoHopoblhpnlrprkuYnnmoTlsZ7mgKfjgIJcbiAqIEByZXR1cm5zIHNoYXBlIOi/lOWbnuazqOWGjOeahCBzaGFwZSDlr7nosaHjgIJcbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJTaGFwZShmYWN0b3J5TmFtZSwgc2hhcGVUeXBlLCBjZmcpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gdXRpbF8xLnVwcGVyRmlyc3QoZmFjdG9yeU5hbWUpO1xuICAgIHZhciBmYWN0b3J5ID0gU2hhcGVGYWN0b3J5TWFwW2NsYXNzTmFtZV07XG4gICAgdmFyIHNoYXBlT2JqID0gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBTaGFwZUJhc2UpLCBjZmcpO1xuICAgIGZhY3Rvcnlbc2hhcGVUeXBlXSA9IHNoYXBlT2JqO1xuICAgIHJldHVybiBzaGFwZU9iajtcbn1cbmV4cG9ydHMucmVnaXN0ZXJTaGFwZSA9IHJlZ2lzdGVyU2hhcGU7XG4vKipcbiAqIOiOt+WPliBmYWN0b3J5TmFtZSDlr7nlupTnmoQgc2hhcGVGYWN0b3J5XG4gKiBAcGFyYW0gZmFjdG9yeU5hbWVcbiAqIEByZXR1cm5zIHNoYXBlIGZhY3RvcnlcbiAqL1xuZnVuY3Rpb24gZ2V0U2hhcGVGYWN0b3J5KGZhY3RvcnlOYW1lKSB7XG4gICAgdmFyIGNsYXNzTmFtZSA9IHV0aWxfMS51cHBlckZpcnN0KGZhY3RvcnlOYW1lKTtcbiAgICByZXR1cm4gU2hhcGVGYWN0b3J5TWFwW2NsYXNzTmFtZV07XG59XG5leHBvcnRzLmdldFNoYXBlRmFjdG9yeSA9IGdldFNoYXBlRmFjdG9yeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBncmFwaGljc18xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvZ3JhcGhpY3NcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtc3R5bGVcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGdldEFyY1NoYXBlUGF0aChmcm9tLCB0bywgY2VudGVyKSB7XG4gICAgdmFyIHN1YiA9IHV0aWxfMS5nZXRRUGF0aCh0bywgY2VudGVyKTtcbiAgICB2YXIgcGF0aCA9IFtbJ00nLCBmcm9tLngsIGZyb20ueV1dO1xuICAgIHBhdGgucHVzaChzdWIpO1xuICAgIHJldHVybiBwYXRoO1xufVxuZnVuY3Rpb24gZ2V0QXJjU2hhcGVXZWlnaHRQYXRoKHBvaW50cywgY2VudGVyKSB7XG4gICAgdmFyIGFyYzEgPSB1dGlsXzEuZ2V0UVBhdGgocG9pbnRzWzFdLCBjZW50ZXIpO1xuICAgIHZhciBhcmMyID0gdXRpbF8xLmdldFFQYXRoKHBvaW50c1szXSwgY2VudGVyKTtcbiAgICB2YXIgcGF0aCA9IFtbJ00nLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldXTtcbiAgICBwYXRoLnB1c2goYXJjMik7XG4gICAgcGF0aC5wdXNoKFsnTCcsIHBvaW50c1szXS54LCBwb2ludHNbM10ueV0pO1xuICAgIHBhdGgucHVzaChbJ0wnLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldKTtcbiAgICBwYXRoLnB1c2goYXJjMSk7XG4gICAgcGF0aC5wdXNoKFsnTCcsIHBvaW50c1sxXS54LCBwb2ludHNbMV0ueV0pO1xuICAgIHBhdGgucHVzaChbJ0wnLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldKTtcbiAgICBwYXRoLnB1c2goWydaJ10pO1xuICAgIHJldHVybiBwYXRoO1xufVxuLy8g5byn57q/5YyF5ous56yb5Y2h5bCU5Z2Q5qCH57O75LiL55qE5Y2K5ZyG5byn57q/44CB5p6B5Z2Q5qCH57O75LiL5Lul5ZyG5b+D5Li65o6n5Yi254K555qE5LqM6Zi25puy57q/44CB56yb5Y2h5bCU5Z2Q5qCH57O75LiL5bim5p2D6YeN55qE5LiJ6Zi25puy57q/44CB5p6B5Z2Q5qCH57O75LiL5bim5p2D6YeN55qE5Lul5ZyG5b+D5Li65o6n5Yi254K555qE5LqM6Zi25puy57q/XG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnZWRnZScsICdhcmMnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IGdldF9zdHlsZV8xLmdldFN0eWxlKGNmZywgdHJ1ZSwgZmFsc2UsICdsaW5lV2lkdGgnKTtcbiAgICAgICAgdmFyIHBvaW50cyA9IGNmZy5wb2ludHM7XG4gICAgICAgIHZhciB0eXBlID0gcG9pbnRzLmxlbmd0aCA+IDIgPyAnd2VpZ2h0JyA6ICdub3JtYWwnO1xuICAgICAgICB2YXIgcGF0aDtcbiAgICAgICAgaWYgKGNmZy5pc0luQ2lyY2xlKSB7XG4gICAgICAgICAgICB2YXIgY2VudGVyID0geyB4OiAwLCB5OiAxIH07XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ25vcm1hbCcpIHtcbiAgICAgICAgICAgICAgICBwYXRoID0gZ2V0QXJjU2hhcGVQYXRoKHBvaW50c1swXSwgcG9pbnRzWzFdLCBjZW50ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3R5bGUuZmlsbCA9IHN0eWxlLnN0cm9rZTtcbiAgICAgICAgICAgICAgICBwYXRoID0gZ2V0QXJjU2hhcGVXZWlnaHRQYXRoKHBvaW50cywgY2VudGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhdGggPSB0aGlzLnBhcnNlUGF0aChwYXRoKTtcbiAgICAgICAgICAgIHJldHVybiBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnbm9ybWFsJykge1xuICAgICAgICAgICAgICAgIHBvaW50cyA9IHRoaXMucGFyc2VQb2ludHMocG9pbnRzKTtcbiAgICAgICAgICAgICAgICBwYXRoID0gZ3JhcGhpY3NfMS5nZXRBcmNQYXRoKChwb2ludHNbMV0ueCArIHBvaW50c1swXS54KSAvIDIsIHBvaW50c1swXS55LCBNYXRoLmFicyhwb2ludHNbMV0ueCAtIHBvaW50c1swXS54KSAvIDIsIE1hdGguUEksIE1hdGguUEkgKiAyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgcGF0aDogcGF0aCB9KSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBjMSA9IHV0aWxfMS5nZXRDUGF0aChwb2ludHNbMV0sIHBvaW50c1szXSk7XG4gICAgICAgICAgICAgICAgdmFyIGMyID0gdXRpbF8xLmdldENQYXRoKHBvaW50c1syXSwgcG9pbnRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYXRoID0gW1xuICAgICAgICAgICAgICAgICAgICBbJ00nLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbMV0ueCwgcG9pbnRzWzFdLnldLFxuICAgICAgICAgICAgICAgICAgICBjMSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzNdLngsIHBvaW50c1szXS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzJdLngsIHBvaW50c1syXS55XSxcbiAgICAgICAgICAgICAgICAgICAgYzIsXG4gICAgICAgICAgICAgICAgICAgIFsnWiddLFxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgcGF0aCA9IHRoaXMucGFyc2VQYXRoKHBhdGgpO1xuICAgICAgICAgICAgICAgIHN0eWxlLmZpbGwgPSBzdHlsZS5zdHJva2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3ltYm9sOiAnY2lyY2xlJyxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgcjogNC41LFxuICAgICAgICAgICAgICAgIGZpbGw6IG1hcmtlckNmZy5jb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXJjLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtc3R5bGVcIik7XG52YXIgcGF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvcGF0aFwiKTtcbnZhciBzcGxpdF9wb2ludHNfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3NwbGl0LXBvaW50c1wiKTtcbnZhciBFZGdlU2hhcGVGYWN0b3J5ID0gYmFzZV8xLnJlZ2lzdGVyU2hhcGVGYWN0b3J5KCdlZGdlJywge1xuICAgIGRlZmF1bHRTaGFwZVR5cGU6ICdsaW5lJyxcbiAgICBnZXREZWZhdWx0UG9pbnRzOiBmdW5jdGlvbiAocG9pbnRJbmZvKSB7XG4gICAgICAgIHJldHVybiBzcGxpdF9wb2ludHNfMS5zcGxpdFBvaW50cyhwb2ludEluZm8pO1xuICAgIH0sXG59KTtcbmJhc2VfMS5yZWdpc3RlclNoYXBlKCdlZGdlJywgJ2xpbmUnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IGdldF9zdHlsZV8xLmdldFN0eWxlKGNmZywgdHJ1ZSwgZmFsc2UsICdsaW5lV2lkdGgnKTtcbiAgICAgICAgdmFyIHBhdGggPSBwYXRoXzEuZ2V0TGluZVBhdGgodGhpcy5wYXJzZVBvaW50cyhjZmcucG9pbnRzKSwgdGhpcy5jb29yZGluYXRlLmlzUG9sYXIpO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA0LjUsXG4gICAgICAgICAgICAgICAgZmlsbDogbWFya2VyQ2ZnLmNvbG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9LFxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFZGdlU2hhcGVGYWN0b3J5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vYmFzZVwiKTtcbnZhciBnZXRfc3R5bGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2dldC1zdHlsZVwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuZnVuY3Rpb24gZ2V0U21vb3RoUGF0aChmcm9tLCB0bykge1xuICAgIHZhciBzdWIgPSB1dGlsXzEuZ2V0Q1BhdGgoZnJvbSwgdG8pO1xuICAgIHZhciBwYXRoID0gW1snTScsIGZyb20ueCwgZnJvbS55XV07XG4gICAgcGF0aC5wdXNoKHN1Yik7XG4gICAgcmV0dXJuIHBhdGg7XG59XG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnZWRnZScsICdzbW9vdGgnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IGdldF9zdHlsZV8xLmdldFN0eWxlKGNmZywgdHJ1ZSwgZmFsc2UsICdsaW5lV2lkdGgnKTtcbiAgICAgICAgdmFyIHBvaW50cyA9IGNmZy5wb2ludHM7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5wYXJzZVBhdGgoZ2V0U21vb3RoUGF0aChwb2ludHNbMF0sIHBvaW50c1sxXSkpO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA0LjUsXG4gICAgICAgICAgICAgICAgZmlsbDogbWFya2VyQ2ZnLmNvbG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zbW9vdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFFQYXRoID0gZXhwb3J0cy5nZXRDUGF0aCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICogR2V0cyBjcGF0aFxuICogQHBhcmFtIGZyb21cbiAqIEBwYXJhbSB0b1xuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0Q1BhdGgoZnJvbSwgdG8pIHtcbiAgICB2YXIgcG9pbnRzID0gW107XG4gICAgcG9pbnRzLnB1c2goe1xuICAgICAgICB4OiBmcm9tLngsXG4gICAgICAgIHk6IChmcm9tLnkgKiAxKSAvIDIgKyAodG8ueSAqIDEpIC8gMixcbiAgICB9KTtcbiAgICBwb2ludHMucHVzaCh7XG4gICAgICAgIHg6IHRvLngsXG4gICAgICAgIHk6IChmcm9tLnkgKiAxKSAvIDIgKyAodG8ueSAqIDEpIC8gMixcbiAgICB9KTtcbiAgICBwb2ludHMucHVzaCh0byk7XG4gICAgdmFyIHN1YiA9IFsnQyddO1xuICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHN1Yi5wdXNoKHBvaW50LngsIHBvaW50LnkpO1xuICAgIH0pO1xuICAgIHJldHVybiBzdWI7XG59XG5leHBvcnRzLmdldENQYXRoID0gZ2V0Q1BhdGg7XG4vKipcbiAqIEBpZ25vcmVcbiAqIEdldHMgcXBhdGhcbiAqIEBwYXJhbSB0b1xuICogQHBhcmFtIGNlbnRlclxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0UVBhdGgodG8sIGNlbnRlcikge1xuICAgIHZhciBwb2ludHMgPSBbXTtcbiAgICBwb2ludHMucHVzaCh7XG4gICAgICAgIHg6IGNlbnRlci54LFxuICAgICAgICB5OiBjZW50ZXIueSxcbiAgICB9KTtcbiAgICBwb2ludHMucHVzaCh0byk7XG4gICAgdmFyIHN1YiA9IFsnUSddO1xuICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHN1Yi5wdXNoKHBvaW50LngsIHBvaW50LnkpO1xuICAgIH0pO1xuICAgIHJldHVybiBzdWI7XG59XG5leHBvcnRzLmdldFFQYXRoID0gZ2V0UVBhdGg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11dGlsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtc3R5bGVcIik7XG52YXIgQ09STkVSX1BFUkNFTlQgPSAxIC8gMztcbmZ1bmN0aW9uIGdldFZIVlBhdGgoZnJvbSwgdG8pIHtcbiAgICB2YXIgcG9pbnRzID0gW107XG4gICAgcG9pbnRzLnB1c2goe1xuICAgICAgICB4OiBmcm9tLngsXG4gICAgICAgIHk6IGZyb20ueSAqICgxIC0gQ09STkVSX1BFUkNFTlQpICsgdG8ueSAqIENPUk5FUl9QRVJDRU5ULFxuICAgIH0pO1xuICAgIHBvaW50cy5wdXNoKHtcbiAgICAgICAgeDogdG8ueCxcbiAgICAgICAgeTogZnJvbS55ICogKDEgLSBDT1JORVJfUEVSQ0VOVCkgKyB0by55ICogQ09STkVSX1BFUkNFTlQsXG4gICAgfSk7XG4gICAgcG9pbnRzLnB1c2godG8pO1xuICAgIHZhciBwYXRoID0gW1snTScsIGZyb20ueCwgZnJvbS55XV07XG4gICAgdXRpbF8xLmVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgcGF0aC5wdXNoKFsnTCcsIHBvaW50LngsIHBvaW50LnldKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcGF0aDtcbn1cbmJhc2VfMS5yZWdpc3RlclNoYXBlKCdlZGdlJywgJ3ZodicsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gZ2V0X3N0eWxlXzEuZ2V0U3R5bGUoY2ZnLCB0cnVlLCBmYWxzZSwgJ2xpbmVXaWR0aCcpO1xuICAgICAgICB2YXIgcG9pbnRzID0gY2ZnLnBvaW50cztcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLnBhcnNlUGF0aChnZXRWSFZQYXRoKHBvaW50c1swXSwgcG9pbnRzWzFdKSk7XG4gICAgICAgIHJldHVybiBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgcGF0aDogcGF0aCB9KSxcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBnZXRNYXJrZXI6IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDQuNSxcbiAgICAgICAgICAgICAgICBmaWxsOiBtYXJrZXJDZmcuY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZodi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vKiog5ryP5paX5Zu+ICovXG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnaW50ZXJ2YWwnLCAnZnVubmVsJywge1xuICAgIGdldFBvaW50czogZnVuY3Rpb24gKHNoYXBlUG9pbnQpIHtcbiAgICAgICAgc2hhcGVQb2ludC5zaXplID0gc2hhcGVQb2ludC5zaXplICogMjsgLy8g5ryP5paX5Zu+55qEIHNpemUg5piv5p+x54q25Zu+55qE5Lik5YCNXG4gICAgICAgIHJldHVybiB1dGlsXzEuZ2V0UmVjdFBvaW50cyhzaGFwZVBvaW50KTtcbiAgICB9LFxuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLnBhcnNlUGF0aCh1dGlsXzEuZ2V0RnVubmVsUGF0aChjZmcucG9pbnRzLCBjZmcubmV4dFBvaW50cywgZmFsc2UpKTtcbiAgICAgICAgdmFyIHNoYXBlID0gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgICAgICBuYW1lOiAnaW50ZXJ2YWwnLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvcjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogJ3NxdWFyZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZ1bm5lbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vKiog5o+P6L655p+x54q25Zu+ICovXG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnaW50ZXJ2YWwnLCAnaG9sbG93LXJlY3QnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IGdldF9zdHlsZV8xLmdldFN0eWxlKGNmZywgdHJ1ZSwgZmFsc2UpO1xuICAgICAgICB2YXIgcGF0aCA9IHRoaXMucGFyc2VQYXRoKHV0aWxfMS5nZXRSZWN0UGF0aChjZmcucG9pbnRzKSk7XG4gICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHN0eWxlKSwgeyBwYXRoOiBwYXRoIH0pLFxuICAgICAgICAgICAgbmFtZTogJ2ludGVydmFsJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3IsIGlzSW5Qb2xhciA9IG1hcmtlckNmZy5pc0luUG9sYXI7XG4gICAgICAgIGlmIChpc0luUG9sYXIpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3ltYm9sOiAnY2lyY2xlJyxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICByOiA0LjUsXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IG51bGwsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogJ3NxdWFyZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBjb2xvcixcbiAgICAgICAgICAgICAgICBmaWxsOiBudWxsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ob2xsb3ctcmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vKiogSW50ZXJ2YWwg55qEIHNoYXBlIOW3peWOgiAqL1xudmFyIEludGVydmFsU2hhcGVGYWN0b3J5ID0gYmFzZV8xLnJlZ2lzdGVyU2hhcGVGYWN0b3J5KCdpbnRlcnZhbCcsIHtcbiAgICBkZWZhdWx0U2hhcGVUeXBlOiAncmVjdCcsXG4gICAgZ2V0RGVmYXVsdFBvaW50czogZnVuY3Rpb24gKHBvaW50SW5mbykge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldFJlY3RQb2ludHMocG9pbnRJbmZvKTtcbiAgICB9LFxufSk7XG4vKiogSW5lcnZhbCDpu5jorqQgc2hhcGXvvIzloavlhYXnmoTnn6nlvaIgKi9cbmJhc2VfMS5yZWdpc3RlclNoYXBlKCdpbnRlcnZhbCcsICdyZWN0Jywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLnBhcnNlUGF0aCh1dGlsXzEuZ2V0UmVjdFBhdGgoY2ZnLnBvaW50cykpO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgcGF0aDogcGF0aCB9KSxcbiAgICAgICAgICAgIG5hbWU6ICdpbnRlcnZhbCcsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfSxcbiAgICBnZXRNYXJrZXI6IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gbWFya2VyQ2ZnLmNvbG9yLCBpc0luUG9sYXIgPSBtYXJrZXJDZmcuaXNJblBvbGFyO1xuICAgICAgICBpZiAoaXNJblBvbGFyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgcjogNC41LFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3ltYm9sOiAnc3F1YXJlJyxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gSW50ZXJ2YWxTaGFwZUZhY3Rvcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vLyDmoLnmja7mlbDmja7ngrnnlJ/miJAgTGluZSDnmoTkuKTkuKrlhbPplK7ngrlcbmZ1bmN0aW9uIGdldExpbmVQb2ludHMocG9pbnRJbmZvKSB7XG4gICAgdmFyIHggPSBwb2ludEluZm8ueCwgeSA9IHBvaW50SW5mby55LCB5MCA9IHBvaW50SW5mby55MDtcbiAgICBpZiAodXRpbF8xLmlzQXJyYXkoeSkpIHtcbiAgICAgICAgcmV0dXJuIHkubWFwKGZ1bmN0aW9uICh5SXRlbSwgaWR4KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IHV0aWxfMS5pc0FycmF5KHgpID8geFtpZHhdIDogeCxcbiAgICAgICAgICAgICAgICB5OiB5SXRlbSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyDotbflp4vngrnku44geTAg5byA5aeLXG4gICAgcmV0dXJuIFtcbiAgICAgICAgeyB4OiB4LCB5OiB5MCB9LFxuICAgICAgICB7IHg6IHgsIHk6IHkgfSxcbiAgICBdO1xufVxuYmFzZV8xLnJlZ2lzdGVyU2hhcGUoJ2ludGVydmFsJywgJ2xpbmUnLCB7XG4gICAgZ2V0UG9pbnRzOiBmdW5jdGlvbiAoc2hhcGVQb2ludCkge1xuICAgICAgICByZXR1cm4gZ2V0TGluZVBvaW50cyhzaGFwZVBvaW50KTtcbiAgICB9LFxuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIHRydWUsIGZhbHNlLCAnbGluZVdpZHRoJyk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5wYXJzZVBhdGgodXRpbF8yLmdldFJlY3RQYXRoKGNmZy5wb2ludHMsIGZhbHNlKSk7XG4gICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHN0eWxlKSwgeyBwYXRoOiBwYXRoIH0pLFxuICAgICAgICAgICAgbmFtZTogJ2ludGVydmFsJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICAgICAgWydNJywgeCwgeSAtIHJdLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCB4LCB5ICsgcl0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDUsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBjb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGluZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG4vKiog6YeR5a2X5aGU5Zu+77yM5bCW5bqV5ryP5paX5Zu+ICovXG5iYXNlXzEucmVnaXN0ZXJTaGFwZSgnaW50ZXJ2YWwnLCAncHlyYW1pZCcsIHtcbiAgICBnZXRQb2ludHM6IGZ1bmN0aW9uIChzaGFwZVBvaW50KSB7XG4gICAgICAgIHNoYXBlUG9pbnQuc2l6ZSA9IHNoYXBlUG9pbnQuc2l6ZSAqIDI7IC8vIOa8j+aWl+WbvueahCBzaXplIOaYr+afseeKtuWbvueahOS4pOWAjVxuICAgICAgICByZXR1cm4gdXRpbF8xLmdldFJlY3RQb2ludHMoc2hhcGVQb2ludCwgdHJ1ZSk7XG4gICAgfSxcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gZ2V0X3N0eWxlXzEuZ2V0U3R5bGUoY2ZnLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5wYXJzZVBhdGgodXRpbF8xLmdldEZ1bm5lbFBhdGgoY2ZnLnBvaW50cywgY2ZnLm5leHRQb2ludHMsIHRydWUpKTtcbiAgICAgICAgdmFyIHNoYXBlID0gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgICAgICBuYW1lOiAnaW50ZXJ2YWwnLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvcjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogJ3NxdWFyZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXB5cmFtaWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vYmFzZVwiKTtcbnZhciBnZXRfc3R5bGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2dldC1zdHlsZVwiKTtcbi8vIOagueaNruaVsOaNrueCueeUn+aIkCB0aWNrIHNoYXBlIOeahCA2IOS4quWFs+mUrueCuVxuZnVuY3Rpb24gZ2V0VGlja1BvaW50cyhwb2ludEluZm8pIHtcbiAgICB2YXIgeCA9IHBvaW50SW5mby54LCB5ID0gcG9pbnRJbmZvLnksIHkwID0gcG9pbnRJbmZvLnkwLCBzaXplID0gcG9pbnRJbmZvLnNpemU7XG4gICAgdmFyIHlNaW47XG4gICAgdmFyIHlNYXg7XG4gICAgaWYgKHV0aWxfMS5pc0FycmF5KHkpKSB7XG4gICAgICAgIHlNaW4gPSB5WzBdLCB5TWF4ID0geVsxXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHlNaW4gPSB5MDtcbiAgICAgICAgeU1heCA9IHk7XG4gICAgfVxuICAgIHZhciB4TWF4ID0geCArIHNpemUgLyAyO1xuICAgIHZhciB4TWluID0geCAtIHNpemUgLyAyO1xuICAgIC8vIHRpY2sg5YWz6ZSu54K56aG65bqPXG4gICAgLy8gNCAtIDEgLSA1XG4gICAgLy8gICAgIHxcbiAgICAvLyAyIC0gMCAtIDNcbiAgICByZXR1cm4gW1xuICAgICAgICB7IHg6IHgsIHk6IHlNaW4gfSxcbiAgICAgICAgeyB4OiB4LCB5OiB5TWF4IH0sXG4gICAgICAgIHsgeDogeE1pbiwgeTogeU1pbiB9LFxuICAgICAgICB7IHg6IHhNYXgsIHk6IHlNaW4gfSxcbiAgICAgICAgeyB4OiB4TWluLCB5OiB5TWF4IH0sXG4gICAgICAgIHsgeDogeE1heCwgeTogeU1heCB9LFxuICAgIF07XG59XG4vLyDmoLnmja4gdGljayDlhbPplK7ngrnnu5jliLYgcGF0aFxuZnVuY3Rpb24gZ2V0VGlja1BhdGgocG9pbnRzKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgWydNJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzFdLngsIHBvaW50c1sxXS55XSxcbiAgICAgICAgWydNJywgcG9pbnRzWzJdLngsIHBvaW50c1syXS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzNdLngsIHBvaW50c1szXS55XSxcbiAgICAgICAgWydNJywgcG9pbnRzWzRdLngsIHBvaW50c1s0XS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzVdLngsIHBvaW50c1s1XS55XSxcbiAgICBdO1xufVxuLyoqIEkg5b2i54q25p+x54q25Zu+77yM5bi455So5LqOIGVycm9yIGJhciBjaGFydCAqL1xuYmFzZV8xLnJlZ2lzdGVyU2hhcGUoJ2ludGVydmFsJywgJ3RpY2snLCB7XG4gICAgZ2V0UG9pbnRzOiBmdW5jdGlvbiAoc2hhcGVQb2ludCkge1xuICAgICAgICByZXR1cm4gZ2V0VGlja1BvaW50cyhzaGFwZVBvaW50KTtcbiAgICB9LFxuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIHRydWUsIGZhbHNlKTtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLnBhcnNlUGF0aChnZXRUaWNrUGF0aChjZmcucG9pbnRzKSk7XG4gICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHN0eWxlKSwgeyBwYXRoOiBwYXRoIH0pLFxuICAgICAgICAgICAgbmFtZTogJ2ludGVydmFsJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICAgICAgWydNJywgeCAtIHIgLyAyLCB5IC0gcl0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIHggKyByIC8gMiwgeSAtIHJdLFxuICAgICAgICAgICAgICAgICAgICBbJ00nLCB4LCB5IC0gcl0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIHgsIHkgKyByXSxcbiAgICAgICAgICAgICAgICAgICAgWydNJywgeCAtIHIgLyAyLCB5ICsgcl0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIHggKyByIC8gMiwgeSArIHJdLFxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA1LFxuICAgICAgICAgICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRpY2suanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldEZ1bm5lbFBhdGggPSBleHBvcnRzLmdldFJlY3RQYXRoID0gZXhwb3J0cy5nZXRSZWN0UG9pbnRzID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmoLnmja7mlbDmja7ngrnnlJ/miJDnn6nlvaLnmoTlm5vkuKrlhbPplK7ngrlcbiAqIEBwYXJhbSBwb2ludEluZm8g5pWw5o2u54K55L+h5oGvXG4gKiBAcGFyYW0gW2lzUHlyYW1pZF0g5piv5ZCm5Li65bCW5bqV5ryP5paX5Zu+XG4gKiBAcmV0dXJucyByZWN0IHBvaW50cyDov5Tlm57nn6nlvaLlm5vkuKrpobbngrnkv6Hmga9cbiAqL1xuZnVuY3Rpb24gZ2V0UmVjdFBvaW50cyhwb2ludEluZm8sIGlzUHlyYW1pZCkge1xuICAgIGlmIChpc1B5cmFtaWQgPT09IHZvaWQgMCkgeyBpc1B5cmFtaWQgPSBmYWxzZTsgfVxuICAgIHZhciB4ID0gcG9pbnRJbmZvLngsIHkgPSBwb2ludEluZm8ueSwgeTAgPSBwb2ludEluZm8ueTAsIHNpemUgPSBwb2ludEluZm8uc2l6ZTtcbiAgICAvLyDmnIkgNCDnp43mg4XlhrXvvIxcbiAgICAvLyAxLiB4LCB5IOmDveS4jeaYr+aVsOe7hFxuICAgIC8vIDIuIHnmmK/mlbDnu4TvvIx45LiN5pivXG4gICAgLy8gMy4geOaYr+aVsOe7hO+8jHnkuI3mmK9cbiAgICAvLyA0LiB4LCB5IOmDveaYr+aVsOe7hFxuICAgIHZhciB5TWluO1xuICAgIHZhciB5TWF4O1xuICAgIGlmICh1dGlsXzEuaXNBcnJheSh5KSkge1xuICAgICAgICB5TWluID0geVswXSwgeU1heCA9IHlbMV07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB5TWluID0geTA7XG4gICAgICAgIHlNYXggPSB5O1xuICAgIH1cbiAgICB2YXIgeE1pbjtcbiAgICB2YXIgeE1heDtcbiAgICBpZiAodXRpbF8xLmlzQXJyYXkoeCkpIHtcbiAgICAgICAgeE1pbiA9IHhbMF0sIHhNYXggPSB4WzFdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgeE1pbiA9IHggLSBzaXplIC8gMjtcbiAgICAgICAgeE1heCA9IHggKyBzaXplIC8gMjtcbiAgICB9XG4gICAgdmFyIHBvaW50cyA9IFtcbiAgICAgICAgeyB4OiB4TWluLCB5OiB5TWluIH0sXG4gICAgICAgIHsgeDogeE1pbiwgeTogeU1heCB9LFxuICAgIF07XG4gICAgaWYgKGlzUHlyYW1pZCkge1xuICAgICAgICAvLyDnu5jliLblsJblupXmvI/mlpflm75cbiAgICAgICAgLy8g6YeR5a2X5aGU5ryP5paX5Zu+55qE5YWz6ZSu54K5XG4gICAgICAgIC8vIDFcbiAgICAgICAgLy8gfCAgIDJcbiAgICAgICAgLy8gMFxuICAgICAgICBwb2ludHMucHVzaCh7XG4gICAgICAgICAgICB4OiB4TWF4LFxuICAgICAgICAgICAgeTogKHlNYXggKyB5TWluKSAvIDIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g55+p5b2i55qE5Zub5Liq5YWz6ZSu54K577yM57uT5p6E5aaC5LiL77yI5bem5LiL6KeS6aG65pe26ZKI6L+e5o6l77yJXG4gICAgICAgIC8vIDEgLS0tLSAyXG4gICAgICAgIC8vIHwgICAgICB8XG4gICAgICAgIC8vIDAgLS0tLSAzXG4gICAgICAgIHBvaW50cy5wdXNoKHsgeDogeE1heCwgeTogeU1heCB9LCB7IHg6IHhNYXgsIHk6IHlNaW4gfSk7XG4gICAgfVxuICAgIHJldHVybiBwb2ludHM7XG59XG5leHBvcnRzLmdldFJlY3RQb2ludHMgPSBnZXRSZWN0UG9pbnRzO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmoLnmja7nn6nlvaLlhbPplK7ngrnnu5jliLYgcGF0aFxuICogQHBhcmFtIHBvaW50cyDlhbPplK7ngrnmlbDnu4RcbiAqIEBwYXJhbSBpc0Nsb3NlZCBwYXRoIOaYr+WQpumcgOimgemXreWQiFxuICogQHJldHVybnMg6L+U5Zue55+p5b2i55qEIHBhdGhcbiAqL1xuZnVuY3Rpb24gZ2V0UmVjdFBhdGgocG9pbnRzLCBpc0Nsb3NlZCkge1xuICAgIGlmIChpc0Nsb3NlZCA9PT0gdm9pZCAwKSB7IGlzQ2xvc2VkID0gdHJ1ZTsgfVxuICAgIHZhciBwYXRoID0gW107XG4gICAgdmFyIGZpcnN0UG9pbnQgPSBwb2ludHNbMF07XG4gICAgcGF0aC5wdXNoKFsnTScsIGZpcnN0UG9pbnQueCwgZmlyc3RQb2ludC55XSk7XG4gICAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBwYXRoLnB1c2goWydMJywgcG9pbnRzW2ldLngsIHBvaW50c1tpXS55XSk7XG4gICAgfVxuICAgIC8vIOWvueS6jiBzaGFwZT1cImxpbmVcIiBwYXRoIOS4jeW6lOivpemXreWQiO+8jOWQpuWImeS8mumAoOaIkCBsaW5lQ2FwIOe7mOWbvuWxnuaAp+WkseaViFxuICAgIGlmIChpc0Nsb3NlZCkge1xuICAgICAgICBwYXRoLnB1c2goWydMJywgZmlyc3RQb2ludC54LCBmaXJzdFBvaW50LnldKTsgLy8g6ZyA6KaB6Zet5ZCIXG4gICAgICAgIHBhdGgucHVzaChbJ3onXSk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoO1xufVxuZXhwb3J0cy5nZXRSZWN0UGF0aCA9IGdldFJlY3RQYXRoO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmoLnmja4gZnVubmVsIOWFs+mUrueCuee7mOWItua8j+aWl+WbvueahCBwYXRoXG4gKiBAcGFyYW0gcG9pbnRzIOWbvuW9ouWFs+mUrueCueS/oeaBr1xuICogQHBhcmFtIG5leHRQb2ludHMg5LiL5LiA5Liq5pWw5o2u55qE5Zu+5b2i5YWz6ZSu54K55L+h5oGvXG4gKiBAcGFyYW0gaXNQeXJhbWlkIOaYr+WQpuS4uuWwluW6lea8j+aWl+WbvlxuICogQHJldHVybnMg6L+U5Zue5ryP5paX5Zu+55qE5Zu+5b2iIHBhdGhcbiAqL1xuZnVuY3Rpb24gZ2V0RnVubmVsUGF0aChwb2ludHMsIG5leHRQb2ludHMsIGlzUHlyYW1pZCkge1xuICAgIHZhciBwYXRoID0gW107XG4gICAgaWYgKCF1dGlsXzEuaXNOaWwobmV4dFBvaW50cykpIHtcbiAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50c1swXS54LCBwb2ludHNbMF0ueV0sIFsnTCcsIHBvaW50c1sxXS54LCBwb2ludHNbMV0ueV0sIFsnTCcsIG5leHRQb2ludHNbMV0ueCwgbmV4dFBvaW50c1sxXS55XSwgWydMJywgbmV4dFBvaW50c1swXS54LCBuZXh0UG9pbnRzWzBdLnldLCBbJ1onXSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzUHlyYW1pZCkge1xuICAgICAgICAvLyDph5HlrZfloZTmnIDlupXpg6hcbiAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50c1swXS54LCBwb2ludHNbMF0ueV0sIFsnTCcsIHBvaW50c1sxXS54LCBwb2ludHNbMV0ueV0sIFsnTCcsIHBvaW50c1syXS54LCBwb2ludHNbMl0ueV0sIFsnTCcsIHBvaW50c1syXS54LCBwb2ludHNbMl0ueV0sIFsnWiddKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIOa8j+aWl+WbvuacgOW6lemDqFxuICAgICAgICBwYXRoLnB1c2goWydNJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSwgWydMJywgcG9pbnRzWzFdLngsIHBvaW50c1sxXS55XSwgWydMJywgcG9pbnRzWzJdLngsIHBvaW50c1syXS55XSwgWydMJywgcG9pbnRzWzNdLngsIHBvaW50c1szXS55XSwgWydaJ10pO1xuICAgIH1cbiAgICByZXR1cm4gcGF0aDtcbn1cbmV4cG9ydHMuZ2V0RnVubmVsUGF0aCA9IGdldEZ1bm5lbFBhdGg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11dGlsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9wYXRoX3BvaW50c18xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXBhdGgtcG9pbnRzXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xudmFyIHBhdGhfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3BhdGhcIik7XG52YXIgc3BsaXRfcG9pbnRzXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9zcGxpdC1wb2ludHNcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbmZ1bmN0aW9uIGdldFNoYXBlQXR0cnMoY2ZnLCBzbW9vdGgsIGNvbnN0cmFpbnQpIHtcbiAgICB2YXIgaXNTdGFjayA9IGNmZy5pc1N0YWNrLCBjb25uZWN0TnVsbHMgPSBjZmcuY29ubmVjdE51bGxzLCBpc0luQ2lyY2xlID0gY2ZnLmlzSW5DaXJjbGUsIHNob3dTaW5nbGVQb2ludCA9IGNmZy5zaG93U2luZ2xlUG9pbnQ7XG4gICAgdmFyIHNoYXBlQXR0cnMgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIHRydWUsIGZhbHNlLCAnbGluZVdpZHRoJyk7XG4gICAgdmFyIHBvaW50cyA9IGdldF9wYXRoX3BvaW50c18xLmdldFBhdGhQb2ludHMoY2ZnLnBvaW50cywgY29ubmVjdE51bGxzLCBzaG93U2luZ2xlUG9pbnQpOyAvLyDmoLnmja4gY29ubmVjdE51bGxzIOWAvOWkhOeQhiBwb2ludHNcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGVhY2hMaW5lUG9pbnRzID0gcG9pbnRzW2ldO1xuICAgICAgICBwYXRoID0gcGF0aC5jb25jYXQoZ2V0UGF0aChlYWNoTGluZVBvaW50cywgaXNJbkNpcmNsZSwgaXNTdGFjaywgc21vb3RoLCBjb25zdHJhaW50LCBzaGFwZUF0dHJzKSk7XG4gICAgfVxuICAgIHNoYXBlQXR0cnMucGF0aCA9IHBhdGg7XG4gICAgcmV0dXJuIHNoYXBlQXR0cnM7XG59XG4vLyDljZXmnaEgcGF0aFxuZnVuY3Rpb24gZ2V0U2luZ2xlUGF0aChwb2ludHMsIGlzSW5DaXJjbGUsIHNtb290aCwgY29uc3RyYWludCwgc3R5bGUpIHtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAvLyDlj6rmnInkuIDkuKrngrnml7ZcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHBvaW50c1swXS54LCBwb2ludHNbMF0ueSAtIHN0eWxlLmxpbmVXaWR0aCAvIDJdLFxuICAgICAgICAgICAgWydMJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSxcbiAgICAgICAgICAgIFsnTCcsIHBvaW50c1swXS54LCBwb2ludHNbMF0ueSArIHN0eWxlLmxpbmVXaWR0aCAvIDJdLFxuICAgICAgICBdO1xuICAgIH1cbiAgICB2YXIgcGF0aDtcbiAgICBpZiAoIXNtb290aCkge1xuICAgICAgICBwYXRoID0gcGF0aF8xLmdldExpbmVQYXRoKHBvaW50cywgZmFsc2UpO1xuICAgICAgICBpZiAoaXNJbkNpcmNsZSkge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnWiddKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g55u06KeS5Z2Q5qCH57O75LiL57uY5Yi25puy57q/5pe26ZmQ5Yi25pyA5aSn5YC844CB5pyA5bCP5YC8XG4gICAgICAgIGlmIChpc0luQ2lyY2xlICYmIHBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeDogcG9pbnRzWzBdLngsIHk6IHBvaW50c1swXS55IH0pO1xuICAgICAgICB9XG4gICAgICAgIHBhdGggPSBwYXRoXzEuZ2V0U3BsaW5lUGF0aChwb2ludHMsIGZhbHNlLCBjb25zdHJhaW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGg7XG59XG5mdW5jdGlvbiBnZXRSYW5nZVBhdGgocG9pbnRzLCBpc0luQ2lyY2xlLCBpc1N0YWNrLCBzbW9vdGgsIGNvbnN0cmFpbnQsIHN0eWxlKSB7XG4gICAgdmFyIHRvcFBvaW50cyA9IFtdO1xuICAgIHZhciBib3R0b21Qb2ludHMgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gc3BsaXRfcG9pbnRzXzEuc3BsaXRQb2ludHMocG9pbnQpO1xuICAgICAgICB0b3BQb2ludHMucHVzaChyZXN1bHRbMV0pOyAvLyDkuIrovrlcbiAgICAgICAgYm90dG9tUG9pbnRzLnB1c2gocmVzdWx0WzBdKTsgLy8g5bqV6L65XG4gICAgfSk7XG4gICAgdmFyIHRvcFBhdGggPSBnZXRTaW5nbGVQYXRoKHRvcFBvaW50cywgaXNJbkNpcmNsZSwgc21vb3RoLCBjb25zdHJhaW50LCBzdHlsZSk7XG4gICAgdmFyIGJvdHRvbVBhdGggPSBnZXRTaW5nbGVQYXRoKGJvdHRvbVBvaW50cywgaXNJbkNpcmNsZSwgc21vb3RoLCBjb25zdHJhaW50LCBzdHlsZSk7XG4gICAgaWYgKGlzU3RhY2spIHtcbiAgICAgICAgcmV0dXJuIHRvcFBhdGg7XG4gICAgfVxuICAgIHJldHVybiB0b3BQYXRoLmNvbmNhdChib3R0b21QYXRoKTtcbn1cbmZ1bmN0aW9uIGdldFBhdGgocG9pbnRzLCBpc0luQ2lyY2xlLCBpc1N0YWNrLCBzbW9vdGgsIGNvbnN0cmFpbnQsIHN0eWxlKSB7XG4gICAgaWYgKHBvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGZpcnN0ID0gcG9pbnRzWzBdO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmlzQXJyYXkoZmlyc3QueSlcbiAgICAgICAgICAgID8gZ2V0UmFuZ2VQYXRoKHBvaW50cywgaXNJbkNpcmNsZSwgaXNTdGFjaywgc21vb3RoLCBjb25zdHJhaW50LCBzdHlsZSlcbiAgICAgICAgICAgIDogZ2V0U2luZ2xlUGF0aChwb2ludHMsIGlzSW5DaXJjbGUsIHNtb290aCwgY29uc3RyYWludCwgc3R5bGUpO1xuICAgIH1cbiAgICByZXR1cm4gW107XG59XG52YXIgTGluZVNoYXBlRmFjdG9yeSA9IGJhc2VfMS5yZWdpc3RlclNoYXBlRmFjdG9yeSgnbGluZScsIHtcbiAgICBkZWZhdWx0U2hhcGVUeXBlOiAnbGluZScsXG59KTtcbi8vIOi/memHjOWboOS4uuS7o+eggeWFrOeUqO+8jOaJgOS7peebtOaOpeWFqOmDqOazqOWGjFxuLy8gJ2xpbmUnIOm7mOiupOaKmOe6v++8mydkb3QnIOeCuee6vyDCt8K3wrfvvJsnZGFzaCcg5pat57q/IC0gLSAtXG51dGlsXzEuZWFjaChbJ2xpbmUnLCAnZG90JywgJ2Rhc2gnLCAnc21vb3RoJ10sIGZ1bmN0aW9uIChzaGFwZVR5cGUpIHtcbiAgICBiYXNlXzEucmVnaXN0ZXJTaGFwZSgnbGluZScsIHNoYXBlVHlwZSwge1xuICAgICAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgICAgIHZhciBzbW9vdGggPSBzaGFwZVR5cGUgPT09ICdzbW9vdGgnO1xuICAgICAgICAgICAgdmFyIGNvbnN0cmFpbnQ7XG4gICAgICAgICAgICBpZiAoc21vb3RoKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hID0gdGhpcy5jb29yZGluYXRlLCBzdGFydCA9IF9hLnN0YXJ0LCBlbmQgPSBfYS5lbmQ7XG4gICAgICAgICAgICAgICAgY29uc3RyYWludCA9IFtcbiAgICAgICAgICAgICAgICAgICAgW3N0YXJ0LngsIGVuZC55XSxcbiAgICAgICAgICAgICAgICAgICAgW2VuZC54LCBzdGFydC55XSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGF0dHJzID0gZ2V0U2hhcGVBdHRycyhjZmcsIHNtb290aCwgY29uc3RyYWludCk7XG4gICAgICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgICAgICBhdHRyczogYXR0cnMsXG4gICAgICAgICAgICAgICAgbmFtZTogJ2xpbmUnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICAgICAgcmV0dXJuIHV0aWxfMi5nZXRMaW5lTWFya2VyKG1hcmtlckNmZywgc2hhcGVUeXBlKTtcbiAgICAgICAgfSxcbiAgICB9KTtcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGluZVNoYXBlRmFjdG9yeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgZ2V0X3BhdGhfcG9pbnRzXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtcGF0aC1wb2ludHNcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtc3R5bGVcIik7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbnZhciBpbnRlcnBvbGF0ZUNhbGxiYWNrID0gZnVuY3Rpb24gKHBvaW50LCBuZXh0UG9pbnQsIHNoYXBlVHlwZSkge1xuICAgIHZhciB4ID0gcG9pbnQueDtcbiAgICB2YXIgeSA9IHBvaW50Lnk7XG4gICAgdmFyIG5leHRYID0gbmV4dFBvaW50Lng7XG4gICAgdmFyIG5leHRZID0gbmV4dFBvaW50Lnk7XG4gICAgdmFyIHJlc3VsdDtcbiAgICBzd2l0Y2ggKHNoYXBlVHlwZSkge1xuICAgICAgICBjYXNlICdodic6XG4gICAgICAgICAgICByZXN1bHQgPSBbeyB4OiBuZXh0WCwgeTogeSB9XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd2aCc6XG4gICAgICAgICAgICByZXN1bHQgPSBbeyB4OiB4LCB5OiBuZXh0WSB9XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdodmgnOlxuICAgICAgICAgICAgdmFyIG1pZGRsZVggPSAobmV4dFggKyB4KSAvIDI7XG4gICAgICAgICAgICByZXN1bHQgPSBbXG4gICAgICAgICAgICAgICAgeyB4OiBtaWRkbGVYLCB5OiB5IH0sXG4gICAgICAgICAgICAgICAgeyB4OiBtaWRkbGVYLCB5OiBuZXh0WSB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd2aHYnOlxuICAgICAgICAgICAgdmFyIG1pZGRsZVkgPSAoeSArIG5leHRZKSAvIDI7XG4gICAgICAgICAgICByZXN1bHQgPSBbXG4gICAgICAgICAgICAgICAgeyB4OiB4LCB5OiBtaWRkbGVZIH0sXG4gICAgICAgICAgICAgICAgeyB4OiBuZXh0WCwgeTogbWlkZGxlWSB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuZnVuY3Rpb24gZ2V0SW50ZXJwb2xhdGVQb2ludHMocG9pbnRzLCBzaGFwZVR5cGUpIHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgdXRpbF8xLmVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQsIGluZGV4KSB7XG4gICAgICAgIHZhciBuZXh0UG9pbnQgPSBwb2ludHNbaW5kZXggKyAxXTtcbiAgICAgICAgcmVzdWx0LnB1c2gocG9pbnQpO1xuICAgICAgICBpZiAobmV4dFBvaW50KSB7XG4gICAgICAgICAgICB2YXIgaW50ZXJwb2xhdGVQb2ludCA9IGludGVycG9sYXRlQ2FsbGJhY2socG9pbnQsIG5leHRQb2ludCwgc2hhcGVUeXBlKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQoaW50ZXJwb2xhdGVQb2ludCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLy8g5o+S5YC855qE5Zu+5b2icGF0aO+8jOS4jeiAg+iZkW51bGxcbmZ1bmN0aW9uIGdldEludGVycG9sYXRlUGF0aChwb2ludHMpIHtcbiAgICByZXR1cm4gcG9pbnRzLm1hcChmdW5jdGlvbiAocG9pbnQsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBpbmRleCA9PT0gMCA/IFsnTScsIHBvaW50LngsIHBvaW50LnldIDogWydMJywgcG9pbnQueCwgcG9pbnQueV07XG4gICAgfSk7XG59XG4vLyDmj5LlgLznmoTlm77lvaJcbmZ1bmN0aW9uIGdldEludGVycG9sYXRlU2hhcGVBdHRycyhjZmcsIHNoYXBlVHlwZSkge1xuICAgIHZhciBwb2ludHMgPSBnZXRfcGF0aF9wb2ludHNfMS5nZXRQYXRoUG9pbnRzKGNmZy5wb2ludHMsIGNmZy5jb25uZWN0TnVsbHMsIGNmZy5zaG93U2luZ2xlUG9pbnQpOyAvLyDmoLnmja4gY29ubmVjdE51bGxzIOWAvOWkhOeQhiBwb2ludHNcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKGVhY2hMaW5lUG9pbnRzKSB7XG4gICAgICAgIHZhciBpbnRlcnBvbGF0ZVBvaW50cyA9IGdldEludGVycG9sYXRlUG9pbnRzKGVhY2hMaW5lUG9pbnRzLCBzaGFwZVR5cGUpO1xuICAgICAgICBwYXRoID0gcGF0aC5jb25jYXQoZ2V0SW50ZXJwb2xhdGVQYXRoKGludGVycG9sYXRlUG9pbnRzKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgZ2V0X3N0eWxlXzEuZ2V0U3R5bGUoY2ZnLCB0cnVlLCBmYWxzZSwgJ2xpbmVXaWR0aCcpKSwgeyBwYXRoOiBwYXRoIH0pO1xufVxuLy8gc3RlcCBsaW5lXG51dGlsXzEuZWFjaChbJ2h2JywgJ3ZoJywgJ2h2aCcsICd2aHYnXSwgZnVuY3Rpb24gKHNoYXBlVHlwZSkge1xuICAgIGJhc2VfMS5yZWdpc3RlclNoYXBlKCdsaW5lJywgc2hhcGVUeXBlLCB7XG4gICAgICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICAgICAgdmFyIGF0dHJzID0gZ2V0SW50ZXJwb2xhdGVTaGFwZUF0dHJzKGNmZywgc2hhcGVUeXBlKTtcbiAgICAgICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnbGluZScsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBzaGFwZTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8yLmdldExpbmVNYXJrZXIobWFya2VyQ2ZnLCBzaGFwZVR5cGUpO1xuICAgICAgICB9LFxuICAgIH0pO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVwLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRMaW5lTWFya2VyID0gdm9pZCAwO1xudmFyIExpbmVTeW1ib2xzID0ge1xuICAgIGxpbmU6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCB4IC0gciwgeV0sXG4gICAgICAgICAgICBbJ0wnLCB4ICsgciwgeV0sXG4gICAgICAgIF07XG4gICAgfSxcbiAgICBkb3Q6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCB4IC0gciwgeV0sXG4gICAgICAgICAgICBbJ0wnLCB4ICsgciwgeV0sXG4gICAgICAgIF07XG4gICAgfSxcbiAgICBkYXNoOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgWydNJywgeCAtIHIsIHldLFxuICAgICAgICAgICAgWydMJywgeCArIHIsIHldLFxuICAgICAgICBdO1xuICAgIH0sXG4gICAgc21vb3RoOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgWydNJywgeCAtIHIsIHldLFxuICAgICAgICAgICAgWydBJywgciAvIDIsIHIgLyAyLCAwLCAxLCAxLCB4LCB5XSxcbiAgICAgICAgICAgIFsnQScsIHIgLyAyLCByIC8gMiwgMCwgMSwgMCwgeCArIHIsIHldLFxuICAgICAgICBdO1xuICAgIH0sXG4gICAgaHY6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCB4IC0gciAtIDEsIHkgLSAyLjVdLFxuICAgICAgICAgICAgWydMJywgeCwgeSAtIDIuNV0sXG4gICAgICAgICAgICBbJ0wnLCB4LCB5ICsgMi41XSxcbiAgICAgICAgICAgIFsnTCcsIHggKyByICsgMSwgeSArIDIuNV0sXG4gICAgICAgIF07XG4gICAgfSxcbiAgICB2aDogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHggLSByIC0gMSwgeSArIDIuNV0sXG4gICAgICAgICAgICBbJ0wnLCB4LCB5ICsgMi41XSxcbiAgICAgICAgICAgIFsnTCcsIHgsIHkgLSAyLjVdLFxuICAgICAgICAgICAgWydMJywgeCArIHIgKyAxLCB5IC0gMi41XSxcbiAgICAgICAgXTtcbiAgICB9LFxuICAgIGh2aDogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHggLSAociArIDEpLCB5ICsgMi41XSxcbiAgICAgICAgICAgIFsnTCcsIHggLSByIC8gMiwgeSArIDIuNV0sXG4gICAgICAgICAgICBbJ0wnLCB4IC0gciAvIDIsIHkgLSAyLjVdLFxuICAgICAgICAgICAgWydMJywgeCArIHIgLyAyLCB5IC0gMi41XSxcbiAgICAgICAgICAgIFsnTCcsIHggKyByIC8gMiwgeSArIDIuNV0sXG4gICAgICAgICAgICBbJ0wnLCB4ICsgciArIDEsIHkgKyAyLjVdLFxuICAgICAgICBdO1xuICAgIH0sXG4gICAgdmh2OiBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICAvLyDlrr0gMTNweO+8jOmrmCA4cHhcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHggLSA1LCB5ICsgMi41XSxcbiAgICAgICAgICAgIFsnTCcsIHggLSA1LCB5XSxcbiAgICAgICAgICAgIFsnTCcsIHgsIHldLFxuICAgICAgICAgICAgWydMJywgeCwgeSAtIDNdLFxuICAgICAgICAgICAgWydMJywgeCwgeSArIDNdLFxuICAgICAgICAgICAgWydMJywgeCArIDYuNSwgeSArIDNdLFxuICAgICAgICBdO1xuICAgIH0sXG59O1xuLyoqXG4gKiBHZXRzIGxpbmUgbWFya2VyXG4gKiBAaWdub3JlXG4gKiBAcGFyYW0gbWFya2VyQ2ZnXG4gKiBAcGFyYW0gc2hhcGVUeXBlXG4gKiBAcmV0dXJucyDov5Tlm54gTGluZSDnmoQgbWFya2VyIOmFjee9rlxuICovXG5mdW5jdGlvbiBnZXRMaW5lTWFya2VyKG1hcmtlckNmZywgc2hhcGVUeXBlKSB7XG4gICAgdmFyIGNvbG9yID0gbWFya2VyQ2ZnLmNvbG9yO1xuICAgIHJldHVybiB7XG4gICAgICAgIHN5bWJvbDogTGluZVN5bWJvbHNbc2hhcGVUeXBlXSxcbiAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgIHI6IDYsXG4gICAgICAgICAgICBzdHJva2U6IGNvbG9yLFxuICAgICAgICB9LFxuICAgIH07XG59XG5leHBvcnRzLmdldExpbmVNYXJrZXIgPSBnZXRMaW5lTWFya2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dXRpbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBtYXJrZXJfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL21hcmtlclwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vYmFzZVwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuLy8g5re75YqgIGhvbGxvd1NoYXBlXG51dGlsXzEuZWFjaCh1dGlsXzIuSE9MTE9XX1NIQVBFUywgZnVuY3Rpb24gKHNoYXBlTmFtZSkge1xuICAgIGJhc2VfMS5yZWdpc3RlclNoYXBlKCdwb2ludCcsIHNoYXBlTmFtZSwge1xuICAgICAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlsXzIuZHJhd1BvaW50cyh0aGlzLCBjZmcsIGNvbnRhaW5lciwgc2hhcGVOYW1lLCB0cnVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN5bWJvbDogbWFya2VyXzEuTWFya2VyU3ltYm9sc1tzaGFwZU5hbWVdLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHI6IDQuNSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogbnVsbCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICB9KTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aG9sbG93LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xuYmFzZV8xLnJlZ2lzdGVyU2hhcGUoJ3BvaW50JywgJ2ltYWdlJywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc2l6ZSA9IGdldF9zdHlsZV8xLmdldFN0eWxlKGNmZywgZmFsc2UsIGZhbHNlLCAncicpLnI7XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLnBhcnNlUG9pbnRzKGNmZy5wb2ludHMpO1xuICAgICAgICB2YXIgcG9pbnRQb3NpdGlvbiA9IHBvaW50c1swXTtcbiAgICAgICAgaWYgKGNmZy5pc1N0YWNrKSB7XG4gICAgICAgICAgICBwb2ludFBvc2l0aW9uID0gcG9pbnRzWzFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB2YXIgZ3JvdXAgPSBjb250YWluZXIuYWRkR3JvdXAoKTtcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgcG9pbnRzXzEgPSBwb2ludHM7IF9pIDwgcG9pbnRzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBvaW50ID0gcG9pbnRzXzFbX2ldO1xuICAgICAgICAgICAgICAgIGdyb3VwLmFkZFNoYXBlKCdpbWFnZScsIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IHBvaW50LnggLSBzaXplIC8gMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IHBvaW50LnkgLSBzaXplLFxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWc6IGNmZy5zaGFwZVsxXSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBncm91cDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29udGFpbmVyLmFkZFNoYXBlKCdpbWFnZScsIHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogcG9pbnRQb3NpdGlvbi54IC0gc2l6ZSAvIDIsXG4gICAgICAgICAgICAgICAgeTogcG9pbnRQb3NpdGlvbi55IC0gc2l6ZSxcbiAgICAgICAgICAgICAgICB3aWR0aDogc2l6ZSxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHNpemUsXG4gICAgICAgICAgICAgICAgaW1nOiBjZmcuc2hhcGVbMV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA0LjUsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWltYWdlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIG1hcmtlcl8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvbWFya2VyXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIHNwbGl0X3BvaW50c18xID0gcmVxdWlyZShcIi4uL3V0aWwvc3BsaXQtcG9pbnRzXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG52YXIgUG9pbnRTaGFwZUZhY3RvcnkgPSBiYXNlXzEucmVnaXN0ZXJTaGFwZUZhY3RvcnkoJ3BvaW50Jywge1xuICAgIGRlZmF1bHRTaGFwZVR5cGU6ICdob2xsb3ctY2lyY2xlJyxcbiAgICBnZXREZWZhdWx0UG9pbnRzOiBmdW5jdGlvbiAocG9pbnRJbmZvKSB7XG4gICAgICAgIHJldHVybiBzcGxpdF9wb2ludHNfMS5zcGxpdFBvaW50cyhwb2ludEluZm8pO1xuICAgIH0sXG59KTtcbnV0aWxfMS5lYWNoKHV0aWxfMi5TSEFQRVMsIGZ1bmN0aW9uIChzaGFwZU5hbWUpIHtcbiAgICAvLyDmt7vliqDor6Ugc2hhcGUg5a+55bqU55qEIGhvbGxvdy1zaGFwZVxuICAgIGJhc2VfMS5yZWdpc3RlclNoYXBlKCdwb2ludCcsIFwiaG9sbG93LVwiICsgc2hhcGVOYW1lLCB7XG4gICAgICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICAgICAgcmV0dXJuIHV0aWxfMi5kcmF3UG9pbnRzKHRoaXMsIGNmZywgY29udGFpbmVyLCBzaGFwZU5hbWUsIHRydWUpO1xuICAgICAgICB9LFxuICAgICAgICBnZXRNYXJrZXI6IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvcjtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3ltYm9sOiBtYXJrZXJfMS5NYXJrZXJTeW1ib2xzW3NoYXBlTmFtZV0gfHwgc2hhcGVOYW1lLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHI6IDQuNSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogbnVsbCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICB9KTtcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG9pbnRTaGFwZUZhY3Rvcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBtYXJrZXJfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL21hcmtlclwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vYmFzZVwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuLy8g5omA5pyJ55qEIFNIQVBFUyDpg73ms6jlhozkuIDkuItcbnV0aWxfMS5lYWNoKHV0aWxfMi5TSEFQRVMsIGZ1bmN0aW9uIChzaGFwZU5hbWUpIHtcbiAgICBiYXNlXzEucmVnaXN0ZXJTaGFwZSgncG9pbnQnLCBzaGFwZU5hbWUsIHtcbiAgICAgICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8yLmRyYXdQb2ludHModGhpcywgY2ZnLCBjb250YWluZXIsIHNoYXBlTmFtZSwgZmFsc2UpO1xuICAgICAgICB9LFxuICAgICAgICBnZXRNYXJrZXI6IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvcjtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3ltYm9sOiBtYXJrZXJfMS5NYXJrZXJTeW1ib2xzW3NoYXBlTmFtZV0gfHwgc2hhcGVOYW1lLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHI6IDQuNSxcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgfSk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNvbGlkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kcmF3UG9pbnRzID0gZXhwb3J0cy5IT0xMT1dfU0hBUEVTID0gZXhwb3J0cy5TSEFQRVMgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBtYXJrZXJfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL21hcmtlclwiKTtcbnZhciBnZXRfc3R5bGVfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2dldC1zdHlsZVwiKTtcbmV4cG9ydHMuU0hBUEVTID0gWydjaXJjbGUnLCAnc3F1YXJlJywgJ2Jvd3RpZScsICdkaWFtb25kJywgJ2hleGFnb24nLCAndHJpYW5nbGUnLCAndHJpYW5nbGUtZG93biddO1xuZXhwb3J0cy5IT0xMT1dfU0hBUEVTID0gWydjcm9zcycsICd0aWNrJywgJ3BsdXMnLCAnaHlwaGVuJywgJ2xpbmUnXTtcbi8qKlxuICogQGlnbm9yZVxuICogRHJhd3MgcG9pbnRzXG4gKiBAcGFyYW0gc2hhcGVcbiAqIEBwYXJhbSBjZmdcbiAqIEBwYXJhbSBjb250YWluZXJcbiAqIEBwYXJhbSBzaGFwZU5hbWVcbiAqIEBwYXJhbSBpc1N0cm9rZVxuICogQHJldHVybnMgcG9pbnRzXG4gKi9cbmZ1bmN0aW9uIGRyYXdQb2ludHMoc2hhcGUsIGNmZywgY29udGFpbmVyLCBzaGFwZU5hbWUsIGlzU3Ryb2tlKSB7XG4gICAgdmFyIHN0eWxlID0gZ2V0X3N0eWxlXzEuZ2V0U3R5bGUoY2ZnLCBpc1N0cm9rZSwgIWlzU3Ryb2tlLCAncicpO1xuICAgIHZhciBwb2ludHMgPSBzaGFwZS5wYXJzZVBvaW50cyhjZmcucG9pbnRzKTtcbiAgICB2YXIgcG9pbnRQb3NpdGlvbiA9IHBvaW50c1swXTtcbiAgICBpZiAoY2ZnLmlzU3RhY2spIHtcbiAgICAgICAgcG9pbnRQb3NpdGlvbiA9IHBvaW50c1sxXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdmFyIGdyb3VwID0gY29udGFpbmVyLmFkZEdyb3VwKCk7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgcG9pbnRzXzEgPSBwb2ludHM7IF9pIDwgcG9pbnRzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNfMVtfaV07XG4gICAgICAgICAgICBncm91cC5hZGRTaGFwZSh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ21hcmtlcicsXG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgc3ltYm9sOiBtYXJrZXJfMS5NYXJrZXJTeW1ib2xzW3NoYXBlTmFtZV0gfHwgc2hhcGVOYW1lIH0pLCBwb2ludCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfVxuICAgIHJldHVybiBjb250YWluZXIuYWRkU2hhcGUoe1xuICAgICAgICB0eXBlOiAnbWFya2VyJyxcbiAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgc3ltYm9sOiBtYXJrZXJfMS5NYXJrZXJTeW1ib2xzW3NoYXBlTmFtZV0gfHwgc2hhcGVOYW1lIH0pLCBwb2ludFBvc2l0aW9uKSxcbiAgICB9KTtcbn1cbmV4cG9ydHMuZHJhd1BvaW50cyA9IGRyYXdQb2ludHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11dGlsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9nZXQtc3R5bGVcIik7XG5mdW5jdGlvbiBnZXRQYXRoKHBvaW50cykge1xuICAgIHZhciBmbGFnID0gcG9pbnRzWzBdO1xuICAgIHZhciBpID0gMTtcbiAgICB2YXIgcGF0aCA9IFtbJ00nLCBmbGFnLngsIGZsYWcueV1dO1xuICAgIHdoaWxlIChpIDwgcG9pbnRzLmxlbmd0aCkge1xuICAgICAgICB2YXIgYyA9IHBvaW50c1tpXTtcbiAgICAgICAgaWYgKGMueCAhPT0gcG9pbnRzW2kgLSAxXS54IHx8IGMueSAhPT0gcG9pbnRzW2kgLSAxXS55KSB7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgYy54LCBjLnldKTtcbiAgICAgICAgICAgIGlmIChjLnggPT09IGZsYWcueCAmJiBjLnkgPT09IGZsYWcueSAmJiBpIDwgcG9pbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBmbGFnID0gcG9pbnRzW2kgKyAxXTtcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goWydaJ10pO1xuICAgICAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCBmbGFnLngsIGZsYWcueV0pO1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpKys7XG4gICAgfVxuICAgIGlmICghdXRpbF8xLmlzRXF1YWwodXRpbF8xLmxhc3QocGF0aCksIGZsYWcpKSB7XG4gICAgICAgIHBhdGgucHVzaChbJ0wnLCBmbGFnLngsIGZsYWcueV0pO1xuICAgIH1cbiAgICBwYXRoLnB1c2goWydaJ10pO1xuICAgIHJldHVybiBwYXRoO1xufVxudmFyIFBvbHlnb25TaGFwZUZhY3RvcnkgPSBiYXNlXzEucmVnaXN0ZXJTaGFwZUZhY3RvcnkoJ3BvbHlnb24nLCB7XG4gICAgZGVmYXVsdFNoYXBlVHlwZTogJ3BvbHlnb24nLFxuICAgIGdldERlZmF1bHRQb2ludHM6IGZ1bmN0aW9uIChwb2ludEluZm8pIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChwb2ludEluZm8ueCwgZnVuY3Rpb24gKHN1YlgsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc3ViWSA9IHBvaW50SW5mby55W2luZGV4XTtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB4OiBzdWJYLFxuICAgICAgICAgICAgICAgIHk6IHN1YlksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwb2ludHM7XG4gICAgfSxcbn0pO1xuYmFzZV8xLnJlZ2lzdGVyU2hhcGUoJ3BvbHlnb24nLCAncG9seWdvbicsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNFbXB0eShjZmcucG9pbnRzKSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlQXR0cnMgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIHRydWUsIHRydWUpO1xuICAgICAgICAgICAgdmFyIHBhdGggPSB0aGlzLnBhcnNlUGF0aChnZXRQYXRoKGNmZy5wb2ludHMpKTtcbiAgICAgICAgICAgIHJldHVybiBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcGVBdHRycyksIHsgcGF0aDogcGF0aCB9KSxcbiAgICAgICAgICAgICAgICBuYW1lOiAncG9seWdvbicsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvcjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogJ3NxdWFyZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBvbHlnb25TaGFwZUZhY3Rvcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xuZnVuY3Rpb24gZ2V0UmVjdEF0dHJzKHBvaW50cywgc2l6ZSkge1xuICAgIHZhciB3aWR0aCA9IE1hdGguYWJzKHBvaW50c1swXS54IC0gcG9pbnRzWzJdLngpO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLmFicyhwb2ludHNbMF0ueSAtIHBvaW50c1syXS55KTtcbiAgICB2YXIgbGVuID0gTWF0aC5taW4od2lkdGgsIGhlaWdodCk7XG4gICAgaWYgKHNpemUpIHtcbiAgICAgICAgbGVuID0gdXRpbF8xLmNsYW1wKHNpemUsIDAsIE1hdGgubWluKHdpZHRoLCBoZWlnaHQpKTtcbiAgICB9XG4gICAgbGVuID0gbGVuIC8gMjtcbiAgICB2YXIgY2VudGVyWCA9IChwb2ludHNbMF0ueCArIHBvaW50c1syXS54KSAvIDI7XG4gICAgdmFyIGNlbnRlclkgPSAocG9pbnRzWzBdLnkgKyBwb2ludHNbMl0ueSkgLyAyO1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IGNlbnRlclggLSBsZW4sXG4gICAgICAgIHk6IGNlbnRlclkgLSBsZW4sXG4gICAgICAgIHdpZHRoOiBsZW4gKiAyLFxuICAgICAgICBoZWlnaHQ6IGxlbiAqIDIsXG4gICAgfTtcbn1cbmJhc2VfMS5yZWdpc3RlclNoYXBlKCdwb2x5Z29uJywgJ3NxdWFyZScsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNFbXB0eShjZmcucG9pbnRzKSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlQXR0cnMgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIHRydWUsIHRydWUpO1xuICAgICAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMucGFyc2VQb2ludHMoY2ZnLnBvaW50cyk7IC8vIOi9rOaNouS4uueUu+W4g+WdkOagh1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5lci5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzaGFwZUF0dHJzKSwgZ2V0UmVjdEF0dHJzKHBvaW50cywgY2ZnLnNpemUpKSxcbiAgICAgICAgICAgICAgICBuYW1lOiAncG9seWdvbicsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvcjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogJ3NxdWFyZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNxdWFyZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xuZnVuY3Rpb24gcGFyc2VWYWx1ZSh2YWx1ZSkge1xuICAgIHZhciBhcnJheSA9ICF1dGlsXzEuaXNBcnJheSh2YWx1ZSkgPyBbdmFsdWVdIDogdmFsdWU7XG4gICAgdmFyIG1pbiA9IGFycmF5WzBdOyAvLyDmnIDlsI/lgLxcbiAgICB2YXIgbWF4ID0gYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV07IC8vIOacgOWkp+WAvFxuICAgIHZhciBtaW4xID0gYXJyYXkubGVuZ3RoID4gMSA/IGFycmF5WzFdIDogbWluO1xuICAgIHZhciBtYXgxID0gYXJyYXkubGVuZ3RoID4gMyA/IGFycmF5WzNdIDogbWF4O1xuICAgIHZhciBtZWRpYW4gPSBhcnJheS5sZW5ndGggPiAyID8gYXJyYXlbMl0gOiBtaW4xO1xuICAgIHJldHVybiB7XG4gICAgICAgIG1pbjogbWluLFxuICAgICAgICBtYXg6IG1heCxcbiAgICAgICAgbWluMTogbWluMSxcbiAgICAgICAgbWF4MTogbWF4MSxcbiAgICAgICAgbWVkaWFuOiBtZWRpYW4sXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGdldEJveFBvaW50cyh4LCB5LCBzaXplKSB7XG4gICAgdmFyIGhhbGZTaXplID0gc2l6ZSAvIDI7XG4gICAgdmFyIHBvaW50c0FycmF5O1xuICAgIGlmICh1dGlsXzEuaXNBcnJheSh5KSkge1xuICAgICAgICAvLyAy57u0XG4gICAgICAgIHZhciBfYSA9IHBhcnNlVmFsdWUoeSksIG1pbiA9IF9hLm1pbiwgbWF4ID0gX2EubWF4LCBtZWRpYW4gPSBfYS5tZWRpYW4sIG1pbjEgPSBfYS5taW4xLCBtYXgxID0gX2EubWF4MTtcbiAgICAgICAgdmFyIG1pblggPSB4IC0gaGFsZlNpemU7XG4gICAgICAgIHZhciBtYXhYID0geCArIGhhbGZTaXplO1xuICAgICAgICBwb2ludHNBcnJheSA9IFtcbiAgICAgICAgICAgIFttaW5YLCBtYXhdLFxuICAgICAgICAgICAgW21heFgsIG1heF0sXG4gICAgICAgICAgICBbeCwgbWF4XSxcbiAgICAgICAgICAgIFt4LCBtYXgxXSxcbiAgICAgICAgICAgIFttaW5YLCBtaW4xXSxcbiAgICAgICAgICAgIFttaW5YLCBtYXgxXSxcbiAgICAgICAgICAgIFttYXhYLCBtYXgxXSxcbiAgICAgICAgICAgIFttYXhYLCBtaW4xXSxcbiAgICAgICAgICAgIFt4LCBtaW4xXSxcbiAgICAgICAgICAgIFt4LCBtaW5dLFxuICAgICAgICAgICAgW21pblgsIG1pbl0sXG4gICAgICAgICAgICBbbWF4WCwgbWluXSxcbiAgICAgICAgICAgIFttaW5YLCBtZWRpYW5dLFxuICAgICAgICAgICAgW21heFgsIG1lZGlhbl0sXG4gICAgICAgIF07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyDlj6rmnInkuIDkuKrnu7TluqZcbiAgICAgICAgeSA9IHV0aWxfMS5pc05pbCh5KSA/IDAuNSA6IHk7XG4gICAgICAgIHZhciBfYiA9IHBhcnNlVmFsdWUoeCksIG1pbiA9IF9iLm1pbiwgbWF4ID0gX2IubWF4LCBtZWRpYW4gPSBfYi5tZWRpYW4sIG1pbjEgPSBfYi5taW4xLCBtYXgxID0gX2IubWF4MTtcbiAgICAgICAgdmFyIG1pblkgPSB5IC0gaGFsZlNpemU7XG4gICAgICAgIHZhciBtYXhZID0geSArIGhhbGZTaXplO1xuICAgICAgICBwb2ludHNBcnJheSA9IFtcbiAgICAgICAgICAgIFttaW4sIG1pblldLFxuICAgICAgICAgICAgW21pbiwgbWF4WV0sXG4gICAgICAgICAgICBbbWluLCB5XSxcbiAgICAgICAgICAgIFttaW4xLCB5XSxcbiAgICAgICAgICAgIFttaW4xLCBtaW5ZXSxcbiAgICAgICAgICAgIFttaW4xLCBtYXhZXSxcbiAgICAgICAgICAgIFttYXgxLCBtYXhZXSxcbiAgICAgICAgICAgIFttYXgxLCBtaW5ZXSxcbiAgICAgICAgICAgIFttYXgxLCB5XSxcbiAgICAgICAgICAgIFttYXgsIHldLFxuICAgICAgICAgICAgW21heCwgbWluWV0sXG4gICAgICAgICAgICBbbWF4LCBtYXhZXSxcbiAgICAgICAgICAgIFttZWRpYW4sIG1pblldLFxuICAgICAgICAgICAgW21lZGlhbiwgbWF4WV0sXG4gICAgICAgIF07XG4gICAgfVxuICAgIHJldHVybiBwb2ludHNBcnJheS5tYXAoZnVuY3Rpb24gKGFycikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogYXJyWzBdLFxuICAgICAgICAgICAgeTogYXJyWzFdLFxuICAgICAgICB9O1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZ2V0Qm94UGF0aChwb2ludHMpIHtcbiAgICByZXR1cm4gW1xuICAgICAgICBbJ00nLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbMV0ueCwgcG9pbnRzWzFdLnldLFxuICAgICAgICBbJ00nLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbM10ueCwgcG9pbnRzWzNdLnldLFxuICAgICAgICBbJ00nLCBwb2ludHNbNF0ueCwgcG9pbnRzWzRdLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbNV0ueCwgcG9pbnRzWzVdLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbNl0ueCwgcG9pbnRzWzZdLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbN10ueCwgcG9pbnRzWzddLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbNF0ueCwgcG9pbnRzWzRdLnldLFxuICAgICAgICBbJ1onXSxcbiAgICAgICAgWydNJywgcG9pbnRzWzhdLngsIHBvaW50c1s4XS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzldLngsIHBvaW50c1s5XS55XSxcbiAgICAgICAgWydNJywgcG9pbnRzWzEwXS54LCBwb2ludHNbMTBdLnldLFxuICAgICAgICBbJ0wnLCBwb2ludHNbMTFdLngsIHBvaW50c1sxMV0ueV0sXG4gICAgICAgIFsnTScsIHBvaW50c1sxMl0ueCwgcG9pbnRzWzEyXS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzEzXS54LCBwb2ludHNbMTNdLnldLFxuICAgIF07XG59XG4vLyBib3ggc2hhcGVcbmJhc2VfMS5yZWdpc3RlclNoYXBlKCdzY2hlbWEnLCAnYm94Jywge1xuICAgIGdldFBvaW50czogZnVuY3Rpb24gKHNoYXBlUG9pbnQpIHtcbiAgICAgICAgdmFyIHggPSBzaGFwZVBvaW50LngsIHkgPSBzaGFwZVBvaW50LnksIHNpemUgPSBzaGFwZVBvaW50LnNpemU7XG4gICAgICAgIHJldHVybiBnZXRCb3hQb2ludHMoeCwgeSwgc2l6ZSk7XG4gICAgfSxcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gZ2V0X3N0eWxlXzEuZ2V0U3R5bGUoY2ZnLCB0cnVlLCBmYWxzZSk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5wYXJzZVBhdGgoZ2V0Qm94UGF0aChjZmcucG9pbnRzKSk7XG4gICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHN0eWxlKSwgeyBwYXRoOiBwYXRoLCBuYW1lOiAnc2NoZW1hJyB9KSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgICAgICAgICAgdmFyIHlWYWx1ZXMgPSBbeSAtIDYsIHkgLSAzLCB5LCB5ICsgMywgeSArIDZdO1xuICAgICAgICAgICAgICAgIHZhciBwb2ludHMgPSBnZXRCb3hQb2ludHMoeCwgeVZhbHVlcywgcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICAgICAgWydNJywgcG9pbnRzWzBdLnggKyAxLCBwb2ludHNbMF0ueV0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIHBvaW50c1sxXS54IC0gMSwgcG9pbnRzWzFdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ00nLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbM10ueCwgcG9pbnRzWzNdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ00nLCBwb2ludHNbNF0ueCwgcG9pbnRzWzRdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbNV0ueCwgcG9pbnRzWzVdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbNl0ueCwgcG9pbnRzWzZdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbN10ueCwgcG9pbnRzWzddLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbNF0ueCwgcG9pbnRzWzRdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ1onXSxcbiAgICAgICAgICAgICAgICAgICAgWydNJywgcG9pbnRzWzhdLngsIHBvaW50c1s4XS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzldLngsIHBvaW50c1s5XS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydNJywgcG9pbnRzWzEwXS54ICsgMSwgcG9pbnRzWzEwXS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzExXS54IC0gMSwgcG9pbnRzWzExXS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydNJywgcG9pbnRzWzEyXS54LCBwb2ludHNbMTJdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbMTNdLngsIHBvaW50c1sxM10ueV0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IDYsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJveC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGhlbHBlcl8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvaGVscGVyXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvZ2V0LXN0eWxlXCIpO1xuZnVuY3Rpb24gZ2V0Q2FuZGxlWVZhbHVlcyh2YWx1ZSkge1xuICAgIHZhciBhcnJheSA9ICF1dGlsXzEuaXNBcnJheSh2YWx1ZSkgPyBbdmFsdWVdIDogdmFsdWU7XG4gICAgLy8g5LuO5aSn5Yiw5bCP5o6S5bqPXG4gICAgdmFyIHNvcnRlZCA9IGFycmF5LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGIgLSBhOyB9KTtcbiAgICByZXR1cm4gaGVscGVyXzEucGFkRW5kKHNvcnRlZCwgNCwgc29ydGVkW3NvcnRlZC5sZW5ndGggLSAxXSk7XG59XG4vLyBnZXQgY2FuZGxlIHNoYXBlJ3Mga2V5IHBvaW50c1xuZnVuY3Rpb24gZ2V0Q2FuZGxlUG9pbnRzKHgsIHksIHNpemUpIHtcbiAgICB2YXIgeVZhbHVlcyA9IGdldENhbmRsZVlWYWx1ZXMoeSk7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgeyB4OiB4LCB5OiB5VmFsdWVzWzBdIH0sXG4gICAgICAgIHsgeDogeCwgeTogeVZhbHVlc1sxXSB9LFxuICAgICAgICB7IHg6IHggLSBzaXplIC8gMiwgeTogeVZhbHVlc1syXSB9LFxuICAgICAgICB7IHg6IHggLSBzaXplIC8gMiwgeTogeVZhbHVlc1sxXSB9LFxuICAgICAgICB7IHg6IHggKyBzaXplIC8gMiwgeTogeVZhbHVlc1sxXSB9LFxuICAgICAgICB7IHg6IHggKyBzaXplIC8gMiwgeTogeVZhbHVlc1syXSB9LFxuICAgICAgICB7IHg6IHgsIHk6IHlWYWx1ZXNbMl0gfSxcbiAgICAgICAgeyB4OiB4LCB5OiB5VmFsdWVzWzNdIH0sXG4gICAgXTtcbn1cbmZ1bmN0aW9uIGdldENhbmRsZVBhdGgocG9pbnRzKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgWydNJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzFdLngsIHBvaW50c1sxXS55XSxcbiAgICAgICAgWydNJywgcG9pbnRzWzJdLngsIHBvaW50c1syXS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzNdLngsIHBvaW50c1szXS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzRdLngsIHBvaW50c1s0XS55XSxcbiAgICAgICAgWydMJywgcG9pbnRzWzVdLngsIHBvaW50c1s1XS55XSxcbiAgICAgICAgWydaJ10sXG4gICAgICAgIFsnTScsIHBvaW50c1s2XS54LCBwb2ludHNbNl0ueV0sXG4gICAgICAgIFsnTCcsIHBvaW50c1s3XS54LCBwb2ludHNbN10ueV0sXG4gICAgXTtcbn1cbi8vIGsgbGluZSBzaGFwZVxuYmFzZV8xLnJlZ2lzdGVyU2hhcGUoJ3NjaGVtYScsICdjYW5kbGUnLCB7XG4gICAgZ2V0UG9pbnRzOiBmdW5jdGlvbiAoc2hhcGVQb2ludCkge1xuICAgICAgICB2YXIgeCA9IHNoYXBlUG9pbnQueCwgeSA9IHNoYXBlUG9pbnQueSwgc2l6ZSA9IHNoYXBlUG9pbnQuc2l6ZTtcbiAgICAgICAgcmV0dXJuIGdldENhbmRsZVBvaW50cyh4LCB5LCBzaXplKTtcbiAgICB9LFxuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIHRydWUsIHRydWUpO1xuICAgICAgICB2YXIgcGF0aCA9IHRoaXMucGFyc2VQYXRoKGdldENhbmRsZVBhdGgoY2ZnLnBvaW50cykpO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgcGF0aDogcGF0aCwgbmFtZTogJ3NjaGVtYScgfSksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfSxcbiAgICBnZXRNYXJrZXI6IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgdmFyIGNvbG9yID0gbWFya2VyQ2ZnLmNvbG9yO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3ltYm9sOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuICAgICAgICAgICAgICAgIHZhciB5VmFsdWVzID0gW3kgKyA3LjUsIHkgKyAzLCB5IC0gMywgeSAtIDcuNV07XG4gICAgICAgICAgICAgICAgdmFyIHBvaW50cyA9IGdldENhbmRsZVBvaW50cyh4LCB5VmFsdWVzLCByKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgICAgICBbJ00nLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbMV0ueCwgcG9pbnRzWzFdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ00nLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbM10ueCwgcG9pbnRzWzNdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbNF0ueCwgcG9pbnRzWzRdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbNV0ueCwgcG9pbnRzWzVdLnldLFxuICAgICAgICAgICAgICAgICAgICBbJ1onXSxcbiAgICAgICAgICAgICAgICAgICAgWydNJywgcG9pbnRzWzZdLngsIHBvaW50c1s2XS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzddLngsIHBvaW50c1s3XS55XSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICAgICAgcjogNixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2FuZGxlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi9iYXNlXCIpO1xudmFyIFNjaGVtYVNoYXBlRmFjdG9yeSA9IGJhc2VfMS5yZWdpc3RlclNoYXBlRmFjdG9yeSgnc2NoZW1hJywge1xuICAgIGRlZmF1bHRTaGFwZVR5cGU6ICcnLFxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTY2hlbWFTaGFwZUZhY3Rvcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0UGF0aFBvaW50cyA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbmZ1bmN0aW9uIGlzVmFsdWVFbXB0eSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IGlzTmFOKHZhbHVlKTtcbn1cbmZ1bmN0aW9uIGlzWU5pbChwb2ludCkge1xuICAgIGlmICh1dGlsXzEuaXNBcnJheShwb2ludCkpIHtcbiAgICAgICAgLy8g54m55q6K5aSE55CGIGFyZWEg55qE5YWz6ZSu54K55pWw5o2u77yM5YW25YWz6ZSu54K557uT5p6E5Li6IFt7eDogMCwgeTogMX0sIHt4OiAwLCB5OiAyfV1cbiAgICAgICAgcmV0dXJuIGlzVmFsdWVFbXB0eShwb2ludFsxXS55KTtcbiAgICB9XG4gICAgdmFyIHZhbHVlID0gcG9pbnQueTtcbiAgICByZXR1cm4gdXRpbF8xLmlzQXJyYXkodmFsdWUpID8gaXNWYWx1ZUVtcHR5KHZhbHVlWzBdKSA6IGlzVmFsdWVFbXB0eSh2YWx1ZSk7XG59XG4vKipcbiAqIEBpZ25vcmVcbiAqIOWIhuWJsuaVsOaNru+8jOeUqOS6juWkhOeQhuWcqOS4gOe7hOeCueaVsOaNruS4re+8jHkg5a+55bqU55qE5pWw5YC85a2Y5ZyoIG51bGwvdW5kZWZpbmVkL05hTiDnmoTmg4XlhrVcbiAqIOW6lOeUqOS6juaKmOe6v+WbvuOAgeWMuuWfn+WbvuS7peWPiui3r+W+hOWbvlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHJldHVybiBbW3t4OiAxLCB5OiAyfSwge3g6IDMsIHk6IDN9XV1cbiAqIGdldFBhdGhQb2ludHMoW3t4OiAxLCB5OiAyfSwge3g6IDIsIHk6IG51bGx9LCB7eDogMywgeTogM31dLCB0cnVlKTtcbiAqIC8vIHJldHVybiBbW3t4OiAxLCB5OiAyfV0sIFt7eDogMywgeTogM31dXVxuICogZ2V0UGF0aFBvaW50cyhbe3g6IDEsIHk6IDJ9LCB7eDogMiwgeTogbnVsbH0sIHt4OiAzLCB5OiAzfV0sIGZhbHNlKTtcbiAqIC8vIHJldHVybiBbW1t7IHg6IDEsIHk6IDEwIH0sIHsgeDogMiwgeTogMiB9XSwgW3sgeDogOSwgeTogMzQgfSwgeyB4OiAxLCB5OiAxIH1dXV1cbiAqIGdldFBhdGhQb2ludHMoW1xuICogICBbeyB4OiAxLCB5OiAxMCB9LCB7IHg6IDIsIHk6IDIgfV0sXG4gKiAgIFt7IHg6IDQsIHk6IDIgfSwgeyB4OiA4LCB5OiBOYU4gfV0sXG4gKiAgIFt7IHg6IDksIHk6IDM0IH0sIHsgeDogMSwgeTogMSB9XSxcbiAqIF0sIHRydWUpO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHBvaW50cyDopoHov5vooYzlpITnkIbngrnpm4blkIhcbiAqIEBwYXJhbSBjb25uZWN0TnVsbHMg5piv5ZCm6L+e5o6l56m65YC85pWw5o2uXG4gKiBAcGFyYW0gc2hvd1NpbmdsZVBvaW50IOaYr+WQpuWxleekuuWtpOeri+eCuVxuICogQHJldHVybnMg6L+U5Zue5aSE55CG5ZCO55qE54K56ZuG5ZCIXG4gKi9cbmZ1bmN0aW9uIGdldFBhdGhQb2ludHMocG9pbnRzLCBjb25uZWN0TnVsbHMsIHNob3dTaW5nbGVQb2ludCkge1xuICAgIGlmIChjb25uZWN0TnVsbHMgPT09IHZvaWQgMCkgeyBjb25uZWN0TnVsbHMgPSBmYWxzZTsgfVxuICAgIGlmIChzaG93U2luZ2xlUG9pbnQgPT09IHZvaWQgMCkgeyBzaG93U2luZ2xlUG9pbnQgPSB0cnVlOyB9XG4gICAgaWYgKCFwb2ludHMubGVuZ3RoIHx8IChwb2ludHMubGVuZ3RoID09PSAxICYmICFzaG93U2luZ2xlUG9pbnQpKSB7XG4gICAgICAgIC8vIOepuuaIluiAheWPquacieS4gOS4queCueW5tumFjee9ruS4jeWxleekuuaXtlxuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGlmIChjb25uZWN0TnVsbHMpIHtcbiAgICAgICAgLy8g5Y2zIHkg5YC85Li656m655qE5Zy65pmvXG4gICAgICAgIHZhciBmaWx0ZXJlZCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgICAgICBpZiAoIWlzWU5pbChwb2ludCkpIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJlZC5wdXNoKHBvaW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2ZpbHRlcmVkXTtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHZhciB0bXAgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgaWYgKGlzWU5pbChwb2ludCkpIHtcbiAgICAgICAgICAgIGlmICh0bXAubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEodG1wLmxlbmd0aCA9PT0gMSAmJiAhc2hvd1NpbmdsZVBvaW50KSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzliY3mrrXmlbDmja7lj6rmnInkuIDkuKrlrZfmrrXlubbkuJTkuI3pnIDopoHlsZXnpLrml7bliJnkuI3liqDlhaVcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2godG1wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdG1wID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0bXAucHVzaChwb2ludCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRtcC5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0LnB1c2godG1wKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydHMuZ2V0UGF0aFBvaW50cyA9IGdldFBhdGhQb2ludHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtcGF0aC1wb2ludHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFN0eWxlID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOiOt+WPliBTaGFwZSDnmoTlm77lvaLlsZ7mgKdcbiAqIEBwYXJhbSBjZmdcbiAqIEBwYXJhbSBpc1N0cm9rZSDmmK/lkKbpnIDopoHmj4/ovrlcbiAqIEBwYXJhbSBpc0ZpbGwg5piv5ZCm6ZyA6KaB5aGr5YWFXG4gKiBAcGFyYW0gW3NpemVOYW1lXSDlj6/pgInvvIzooajnpLrlm77lvaLlpKflsI/nmoTlsZ7mgKfvvIxsaW5lV2lkdGgg5oiW6ICFIHJcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldFN0eWxlKGNmZywgaXNTdHJva2UsIGlzRmlsbCwgc2l6ZU5hbWUpIHtcbiAgICBpZiAoc2l6ZU5hbWUgPT09IHZvaWQgMCkgeyBzaXplTmFtZSA9ICcnOyB9XG4gICAgdmFyIF9hID0gY2ZnLnN0eWxlLCBzdHlsZSA9IF9hID09PSB2b2lkIDAgPyB7fSA6IF9hLCBkZWZhdWx0U3R5bGUgPSBjZmcuZGVmYXVsdFN0eWxlLCBjb2xvciA9IGNmZy5jb2xvciwgc2l6ZSA9IGNmZy5zaXplO1xuICAgIHZhciBhdHRycyA9IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgZGVmYXVsdFN0eWxlKSwgc3R5bGUpO1xuICAgIGlmIChjb2xvcikge1xuICAgICAgICBpZiAoaXNTdHJva2UpIHtcbiAgICAgICAgICAgIGlmICghc3R5bGUuc3Ryb2tlKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c55So5oi35ZyoIHN0eWxlKCkg5Lit6YWN572u5LqGIHN0cm9rZe+8jOWImeS7peeUqOaIt+mFjee9rueahOS4uuWHhlxuICAgICAgICAgICAgICAgIGF0dHJzLnN0cm9rZSA9IGNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0ZpbGwpIHtcbiAgICAgICAgICAgIGlmICghc3R5bGUuZmlsbCkge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOeUqOaIt+WcqCBzdHlsZSgpIOS4remFjee9ruS6hiBmaWxsXG4gICAgICAgICAgICAgICAgYXR0cnMuZmlsbCA9IGNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChzaXplTmFtZSAmJiB1dGlsXzEuaXNOaWwoc3R5bGVbc2l6ZU5hbWVdKSAmJiAhdXRpbF8xLmlzTmlsKHNpemUpKSB7XG4gICAgICAgIC8vIOWmguaenOeUqOaIt+WcqCBzdHlsZSgpIOS4remFjee9ruS6hiBsaW5lV2lkdGgg5oiW6ICFIHIg5bGe5oCnXG4gICAgICAgIGF0dHJzW3NpemVOYW1lXSA9IHNpemU7XG4gICAgfVxuICAgIHJldHVybiBhdHRycztcbn1cbmV4cG9ydHMuZ2V0U3R5bGUgPSBnZXRTdHlsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1zdHlsZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuY29udmVydFBvbGFyUGF0aCA9IGV4cG9ydHMuY29udmVydE5vcm1hbFBhdGggPSBleHBvcnRzLmdldFNwbGluZVBhdGggPSBleHBvcnRzLmdldExpbmVQYXRoID0gZXhwb3J0cy5jYXRtdWxsUm9tMmJlemllciA9IGV4cG9ydHMuc21vb3RoQmV6aWVyID0gdm9pZCAwO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29vcmRpbmF0ZV8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvY29vcmRpbmF0ZVwiKTtcbmZ1bmN0aW9uIF9wb2ludHMycGF0aChwb2ludHMsIGlzSW5DaXJjbGUpIHtcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIGlmIChwb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIHBhdGgucHVzaChbJ00nLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDEsIGxlbmd0aF8xID0gcG9pbnRzLmxlbmd0aDsgaSA8IGxlbmd0aF8xOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTCcsIGl0ZW0ueCwgaXRlbS55XSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzSW5DaXJjbGUpIHtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ1onXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBhdGg7XG59XG5mdW5jdGlvbiBfY29udmVydEFycihhcnIsIGNvb3JkKSB7XG4gICAgdmFyIHRtcCA9IFthcnJbMF1dO1xuICAgIGZvciAodmFyIGkgPSAxLCBsZW4gPSBhcnIubGVuZ3RoOyBpIDwgbGVuOyBpID0gaSArIDIpIHtcbiAgICAgICAgdmFyIHBvaW50ID0gY29vcmQuY29udmVydCh7XG4gICAgICAgICAgICB4OiBhcnJbaV0sXG4gICAgICAgICAgICB5OiBhcnJbaSArIDFdLFxuICAgICAgICB9KTtcbiAgICAgICAgdG1wLnB1c2gocG9pbnQueCwgcG9pbnQueSk7XG4gICAgfVxuICAgIHJldHVybiB0bXA7XG59XG5mdW5jdGlvbiBfY29udmVydFBvbGFyUGF0aChwcmUsIGN1ciwgY29vcmQpIHtcbiAgICB2YXIgaXNUcmFuc3Bvc2VkID0gY29vcmQuaXNUcmFuc3Bvc2VkLCBzdGFydEFuZ2xlID0gY29vcmQuc3RhcnRBbmdsZSwgZW5kQW5nbGUgPSBjb29yZC5lbmRBbmdsZTtcbiAgICB2YXIgcHJlUG9pbnQgPSB7XG4gICAgICAgIHg6IHByZVsxXSxcbiAgICAgICAgeTogcHJlWzJdLFxuICAgIH07XG4gICAgdmFyIGN1clBvaW50ID0ge1xuICAgICAgICB4OiBjdXJbMV0sXG4gICAgICAgIHk6IGN1clsyXSxcbiAgICB9O1xuICAgIHZhciByc3QgPSBbXTtcbiAgICB2YXIgeERpbSA9IGlzVHJhbnNwb3NlZCA/ICd5JyA6ICd4JztcbiAgICB2YXIgYW5nbGVSYW5nZSA9IE1hdGguYWJzKGN1clBvaW50W3hEaW1dIC0gcHJlUG9pbnRbeERpbV0pICogKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSk7XG4gICAgdmFyIGRpcmVjdGlvbiA9IGN1clBvaW50W3hEaW1dID49IHByZVBvaW50W3hEaW1dID8gMSA6IDA7IC8vIOWchuW8p+eahOaWueWQkVxuICAgIHZhciBmbGFnID0gYW5nbGVSYW5nZSA+IE1hdGguUEkgPyAxIDogMDsgLy8g5aSn5byn6L+Y5piv5bCP5byn5qCH5b+X5L2NXG4gICAgdmFyIGNvbnZlcnRQb2ludCA9IGNvb3JkLmNvbnZlcnQoY3VyUG9pbnQpO1xuICAgIHZhciByID0gY29vcmRpbmF0ZV8xLmdldERpc3RhbmNlVG9DZW50ZXIoY29vcmQsIGNvbnZlcnRQb2ludCk7XG4gICAgaWYgKHIgPj0gMC41KSB7XG4gICAgICAgIC8vIOWwj+S6jjHlg4/ntKDnmoTlnIblnKjlm77lg4/kuIrml6Dms5Xor4bliKtcbiAgICAgICAgaWYgKGFuZ2xlUmFuZ2UgPT09IE1hdGguUEkgKiAyKSB7XG4gICAgICAgICAgICB2YXIgbWlkZGxlUG9pbnQgPSB7XG4gICAgICAgICAgICAgICAgeDogKGN1clBvaW50LnggKyBwcmVQb2ludC54KSAvIDIsXG4gICAgICAgICAgICAgICAgeTogKGN1clBvaW50LnkgKyBwcmVQb2ludC55KSAvIDIsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIG1pZGRsZUNvbnZlcnRQb2ludCA9IGNvb3JkLmNvbnZlcnQobWlkZGxlUG9pbnQpO1xuICAgICAgICAgICAgcnN0LnB1c2goWydBJywgciwgciwgMCwgZmxhZywgZGlyZWN0aW9uLCBtaWRkbGVDb252ZXJ0UG9pbnQueCwgbWlkZGxlQ29udmVydFBvaW50LnldKTtcbiAgICAgICAgICAgIHJzdC5wdXNoKFsnQScsIHIsIHIsIDAsIGZsYWcsIGRpcmVjdGlvbiwgY29udmVydFBvaW50LngsIGNvbnZlcnRQb2ludC55XSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByc3QucHVzaChbJ0EnLCByLCByLCAwLCBmbGFnLCBkaXJlY3Rpb24sIGNvbnZlcnRQb2ludC54LCBjb252ZXJ0UG9pbnQueV0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByc3Q7XG59XG4vLyDlvZPlrZjlnKjmlbTkvZPnmoTlnIbml7bvvIzljrvpmaTlnIbliY3pnaLlkozlkI7pnaLnmoTnur/vvIzpmLLmraLlh7rnjrDnm7Tnur/nqb/ov4fmlbTkuKrlnIbnmoTmg4XlvaJcbmZ1bmN0aW9uIF9maWx0ZXJGdWxsQ2lybGVMaW5lKHBhdGgpIHtcbiAgICB1dGlsXzEuZWFjaChwYXRoLCBmdW5jdGlvbiAoc3ViUGF0aCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGN1ciA9IHN1YlBhdGg7XG4gICAgICAgIGlmIChjdXJbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ2EnKSB7XG4gICAgICAgICAgICB2YXIgcHJlID0gcGF0aFtpbmRleCAtIDFdO1xuICAgICAgICAgICAgdmFyIG5leHQgPSBwYXRoW2luZGV4ICsgMV07XG4gICAgICAgICAgICBpZiAobmV4dCAmJiBuZXh0WzBdLnRvTG93ZXJDYXNlKCkgPT09ICdhJykge1xuICAgICAgICAgICAgICAgIGlmIChwcmUgJiYgcHJlWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdsJykge1xuICAgICAgICAgICAgICAgICAgICBwcmVbMF0gPSAnTSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocHJlICYmIHByZVswXS50b0xvd2VyQ2FzZSgpID09PSAnYScpIHtcbiAgICAgICAgICAgICAgICBpZiAobmV4dCAmJiBuZXh0WzBdLnRvTG93ZXJDYXNlKCkgPT09ICdsJykge1xuICAgICAgICAgICAgICAgICAgICBuZXh0WzBdID0gJ00nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBAaWdub3JlXG4gKiDorqHnrpflhYnmu5HnmoTotJ3loZ7lsJTmm7Lnur9cbiAqL1xuZXhwb3J0cy5zbW9vdGhCZXppZXIgPSBmdW5jdGlvbiAocG9pbnRzLCBzbW9vdGgsIGlzTG9vcCwgY29uc3RyYWludCkge1xuICAgIHZhciBjcHMgPSBbXTtcbiAgICB2YXIgcHJldlBvaW50O1xuICAgIHZhciBuZXh0UG9pbnQ7XG4gICAgdmFyIGhhc0NvbnN0cmFpbnQgPSAhIWNvbnN0cmFpbnQ7XG4gICAgdmFyIG1pbjtcbiAgICB2YXIgbWF4O1xuICAgIGlmIChoYXNDb25zdHJhaW50KSB7XG4gICAgICAgIG1pbiA9IFtJbmZpbml0eSwgSW5maW5pdHldO1xuICAgICAgICBtYXggPSBbLUluZmluaXR5LCAtSW5maW5pdHldO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHBvaW50cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIG1pbiA9IG1hdHJpeF91dGlsXzEudmVjMi5taW4oWzAsIDBdLCBtaW4sIHBvaW50KTtcbiAgICAgICAgICAgIG1heCA9IG1hdHJpeF91dGlsXzEudmVjMi5tYXgoWzAsIDBdLCBtYXgsIHBvaW50KTtcbiAgICAgICAgfVxuICAgICAgICBtaW4gPSBtYXRyaXhfdXRpbF8xLnZlYzIubWluKFswLCAwXSwgbWluLCBjb25zdHJhaW50WzBdKTtcbiAgICAgICAgbWF4ID0gbWF0cml4X3V0aWxfMS52ZWMyLm1heChbMCwgMF0sIG1heCwgY29uc3RyYWludFsxXSk7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgICBpZiAoaXNMb29wKSB7XG4gICAgICAgICAgICBwcmV2UG9pbnQgPSBwb2ludHNbaSA/IGkgLSAxIDogbGVuIC0gMV07XG4gICAgICAgICAgICBuZXh0UG9pbnQgPSBwb2ludHNbKGkgKyAxKSAlIGxlbl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoaSA9PT0gMCB8fCBpID09PSBsZW4gLSAxKSB7XG4gICAgICAgICAgICAgICAgY3BzLnB1c2gocG9pbnQpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcHJldlBvaW50ID0gcG9pbnRzW2kgLSAxXTtcbiAgICAgICAgICAgICAgICBuZXh0UG9pbnQgPSBwb2ludHNbaSArIDFdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciB2ID0gWzAsIDBdO1xuICAgICAgICB2ID0gbWF0cml4X3V0aWxfMS52ZWMyLnN1Yih2LCBuZXh0UG9pbnQsIHByZXZQb2ludCk7XG4gICAgICAgIHYgPSBtYXRyaXhfdXRpbF8xLnZlYzIuc2NhbGUodiwgdiwgc21vb3RoKTtcbiAgICAgICAgdmFyIGQwID0gbWF0cml4X3V0aWxfMS52ZWMyLmRpc3RhbmNlKHBvaW50LCBwcmV2UG9pbnQpO1xuICAgICAgICB2YXIgZDEgPSBtYXRyaXhfdXRpbF8xLnZlYzIuZGlzdGFuY2UocG9pbnQsIG5leHRQb2ludCk7XG4gICAgICAgIHZhciBzdW0gPSBkMCArIGQxO1xuICAgICAgICBpZiAoc3VtICE9PSAwKSB7XG4gICAgICAgICAgICBkMCAvPSBzdW07XG4gICAgICAgICAgICBkMSAvPSBzdW07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHYxID0gbWF0cml4X3V0aWxfMS52ZWMyLnNjYWxlKFswLCAwXSwgdiwgLWQwKTtcbiAgICAgICAgdmFyIHYyID0gbWF0cml4X3V0aWxfMS52ZWMyLnNjYWxlKFswLCAwXSwgdiwgZDEpO1xuICAgICAgICB2YXIgY3AwID0gbWF0cml4X3V0aWxfMS52ZWMyLmFkZChbMCwgMF0sIHBvaW50LCB2MSk7XG4gICAgICAgIHZhciBjcDEgPSBtYXRyaXhfdXRpbF8xLnZlYzIuYWRkKFswLCAwXSwgcG9pbnQsIHYyKTtcbiAgICAgICAgaWYgKGhhc0NvbnN0cmFpbnQpIHtcbiAgICAgICAgICAgIGNwMCA9IG1hdHJpeF91dGlsXzEudmVjMi5tYXgoWzAsIDBdLCBjcDAsIG1pbik7XG4gICAgICAgICAgICBjcDAgPSBtYXRyaXhfdXRpbF8xLnZlYzIubWluKFswLCAwXSwgY3AwLCBtYXgpO1xuICAgICAgICAgICAgY3AxID0gbWF0cml4X3V0aWxfMS52ZWMyLm1heChbMCwgMF0sIGNwMSwgbWluKTtcbiAgICAgICAgICAgIGNwMSA9IG1hdHJpeF91dGlsXzEudmVjMi5taW4oWzAsIDBdLCBjcDEsIG1heCk7XG4gICAgICAgIH1cbiAgICAgICAgY3BzLnB1c2goY3AwKTtcbiAgICAgICAgY3BzLnB1c2goY3AxKTtcbiAgICB9XG4gICAgaWYgKGlzTG9vcCkge1xuICAgICAgICBjcHMucHVzaChjcHMuc2hpZnQoKSk7XG4gICAgfVxuICAgIHJldHVybiBjcHM7XG59O1xuLyoqXG4gKiBAaWdub3JlXG4gKiDotJ3loZ7lsJTmm7Lnur9cbiAqL1xuZnVuY3Rpb24gY2F0bXVsbFJvbTJiZXppZXIoY3JwLCB6LCBjb25zdHJhaW50KSB7XG4gICAgdmFyIGlzTG9vcCA9ICEhejtcbiAgICB2YXIgcG9pbnRMaXN0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjcnAubGVuZ3RoOyBpIDwgbDsgaSArPSAyKSB7XG4gICAgICAgIHBvaW50TGlzdC5wdXNoKFtjcnBbaV0sIGNycFtpICsgMV1dKTtcbiAgICB9XG4gICAgdmFyIGNvbnRyb2xQb2ludExpc3QgPSBleHBvcnRzLnNtb290aEJlemllcihwb2ludExpc3QsIDAuNCwgaXNMb29wLCBjb25zdHJhaW50KTtcbiAgICB2YXIgbGVuID0gcG9pbnRMaXN0Lmxlbmd0aDtcbiAgICB2YXIgZDEgPSBbXTtcbiAgICB2YXIgY3AxO1xuICAgIHZhciBjcDI7XG4gICAgdmFyIHA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICAgICAgY3AxID0gY29udHJvbFBvaW50TGlzdFtpICogMl07XG4gICAgICAgIGNwMiA9IGNvbnRyb2xQb2ludExpc3RbaSAqIDIgKyAxXTtcbiAgICAgICAgcCA9IHBvaW50TGlzdFtpICsgMV07XG4gICAgICAgIGQxLnB1c2goWydDJywgY3AxWzBdLCBjcDFbMV0sIGNwMlswXSwgY3AyWzFdLCBwWzBdLCBwWzFdXSk7XG4gICAgfVxuICAgIGlmIChpc0xvb3ApIHtcbiAgICAgICAgY3AxID0gY29udHJvbFBvaW50TGlzdFtsZW5dO1xuICAgICAgICBjcDIgPSBjb250cm9sUG9pbnRMaXN0W2xlbiArIDFdO1xuICAgICAgICBwID0gcG9pbnRMaXN0WzBdO1xuICAgICAgICBkMS5wdXNoKFsnQycsIGNwMVswXSwgY3AxWzFdLCBjcDJbMF0sIGNwMlsxXSwgcFswXSwgcFsxXV0pO1xuICAgIH1cbiAgICByZXR1cm4gZDE7XG59XG5leHBvcnRzLmNhdG11bGxSb20yYmV6aWVyID0gY2F0bXVsbFJvbTJiZXppZXI7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOWwhueCuei/nuaOpeaIkOi3r+W+hCBwYXRoXG4gKi9cbmZ1bmN0aW9uIGdldExpbmVQYXRoKHBvaW50cywgaXNJbkNpcmNsZSkge1xuICAgIHJldHVybiBfcG9pbnRzMnBhdGgocG9pbnRzLCBpc0luQ2lyY2xlKTtcbn1cbmV4cG9ydHMuZ2V0TGluZVBhdGggPSBnZXRMaW5lUGF0aDtcbi8qKlxuICogQGlnbm9yZVxuICog5qC55o2u5YWz6ZSu54K56I635Y+W6ZmQ5a6a5LqG6IyD5Zu055qE5bmz5ruR57q/XG4gKi9cbmZ1bmN0aW9uIGdldFNwbGluZVBhdGgocG9pbnRzLCBpc0luQ2lyY2xlLCBjb25zdGFpbnQpIHtcbiAgICB2YXIgZGF0YSA9IFtdO1xuICAgIHZhciBmaXJzdCA9IHBvaW50c1swXTtcbiAgICB2YXIgcHJlUG9pbnQgPSBudWxsO1xuICAgIGlmIChwb2ludHMubGVuZ3RoIDw9IDIpIHtcbiAgICAgICAgLy8g5Lik54K55Lul5YaF55u05o6l57uY5Yi25oiQ6Lev5b6EXG4gICAgICAgIHJldHVybiBnZXRMaW5lUGF0aChwb2ludHMsIGlzSW5DaXJjbGUpO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgaWYgKCFwcmVQb2ludCB8fCAhKHByZVBvaW50LnggPT09IHBvaW50LnggJiYgcHJlUG9pbnQueSA9PT0gcG9pbnQueSkpIHtcbiAgICAgICAgICAgIGRhdGEucHVzaChwb2ludC54KTtcbiAgICAgICAgICAgIGRhdGEucHVzaChwb2ludC55KTtcbiAgICAgICAgICAgIHByZVBvaW50ID0gcG9pbnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIGNvbnN0cmFpbnQgPSBjb25zdGFpbnQgfHwgW1xuICAgICAgICAvLyDojIPlm7RcbiAgICAgICAgWzAsIDBdLFxuICAgICAgICBbMSwgMV0sXG4gICAgXTtcbiAgICB2YXIgc3BsaW5lUGF0aCA9IGNhdG11bGxSb20yYmV6aWVyKGRhdGEsIGlzSW5DaXJjbGUsIGNvbnN0cmFpbnQpO1xuICAgIHNwbGluZVBhdGgudW5zaGlmdChbJ00nLCBmaXJzdC54LCBmaXJzdC55XSk7XG4gICAgcmV0dXJuIHNwbGluZVBhdGg7XG59XG5leHBvcnRzLmdldFNwbGluZVBhdGggPSBnZXRTcGxpbmVQYXRoO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDlsIblvZLkuIDljJblkI7nmoTot6/lvoTmlbDmja7ovazmjaLmiJDlnZDmoIdcbiAqL1xuZnVuY3Rpb24gY29udmVydE5vcm1hbFBhdGgoY29vcmQsIHBhdGgpIHtcbiAgICB2YXIgdG1wID0gW107XG4gICAgdXRpbF8xLmVhY2gocGF0aCwgZnVuY3Rpb24gKHN1YlBhdGgpIHtcbiAgICAgICAgdmFyIGFjdGlvbiA9IHN1YlBhdGhbMF07XG4gICAgICAgIHN3aXRjaCAoYWN0aW9uLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgJ20nOlxuICAgICAgICAgICAgY2FzZSAnbCc6XG4gICAgICAgICAgICBjYXNlICdjJzpcbiAgICAgICAgICAgICAgICB0bXAucHVzaChfY29udmVydEFycihzdWJQYXRoLCBjb29yZCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAneic6XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRtcC5wdXNoKHN1YlBhdGgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRtcDtcbn1cbmV4cG9ydHMuY29udmVydE5vcm1hbFBhdGggPSBjb252ZXJ0Tm9ybWFsUGF0aDtcbi8qKlxuICogQGlnbm9yZVxuICog5bCG6Lev5b6E6L2s5o2i5Li65p6B5Z2Q5qCH5LiL55qE55yf5a6e6Lev5b6EXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRQb2xhclBhdGgoY29vcmQsIHBhdGgpIHtcbiAgICB2YXIgdG1wID0gW107XG4gICAgdmFyIHByZTtcbiAgICB2YXIgY3VyO1xuICAgIHZhciB0cmFuc3Bvc2VkO1xuICAgIHZhciBlcXVhbHM7XG4gICAgdXRpbF8xLmVhY2gocGF0aCwgZnVuY3Rpb24gKHN1YlBhdGgsIGluZGV4KSB7XG4gICAgICAgIHZhciBhY3Rpb24gPSBzdWJQYXRoWzBdO1xuICAgICAgICBzd2l0Y2ggKGFjdGlvbi50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlICdtJzpcbiAgICAgICAgICAgIGNhc2UgJ2MnOlxuICAgICAgICAgICAgY2FzZSAncSc6XG4gICAgICAgICAgICAgICAgdG1wLnB1c2goX2NvbnZlcnRBcnIoc3ViUGF0aCwgY29vcmQpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2wnOlxuICAgICAgICAgICAgICAgIHByZSA9IHBhdGhbaW5kZXggLSAxXTtcbiAgICAgICAgICAgICAgICBjdXIgPSBzdWJQYXRoO1xuICAgICAgICAgICAgICAgIHRyYW5zcG9zZWQgPSBjb29yZC5pc1RyYW5zcG9zZWQ7XG4gICAgICAgICAgICAgICAgLy8g5piv5ZCm5Y2K5b6E55u45ZCM77yM6L2s5o2i5oiQ5ZyG5bynXG4gICAgICAgICAgICAgICAgZXF1YWxzID0gdHJhbnNwb3NlZCA/IHByZVtwcmUubGVuZ3RoIC0gMl0gPT09IGN1clsxXSA6IHByZVtwcmUubGVuZ3RoIC0gMV0gPT09IGN1clsyXTtcbiAgICAgICAgICAgICAgICBpZiAoZXF1YWxzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRtcCA9IHRtcC5jb25jYXQoX2NvbnZlcnRQb2xhclBhdGgocHJlLCBjdXIsIGNvb3JkKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyB5IOS4jeebuOetie+8jOaJgOS7peebtOaOpei9rOaNolxuICAgICAgICAgICAgICAgICAgICB0bXAucHVzaChfY29udmVydEFycihzdWJQYXRoLCBjb29yZCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3onOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0bXAucHVzaChzdWJQYXRoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIF9maWx0ZXJGdWxsQ2lybGVMaW5lKHRtcCk7IC8vIOi/h+a7pOWkmuS9meeahOebtOe6v1xuICAgIHJldHVybiB0bXA7XG59XG5leHBvcnRzLmNvbnZlcnRQb2xhclBhdGggPSBjb252ZXJ0UG9sYXJQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuc3BsaXRQb2ludHMgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOaLhuWIhueCueaVsOaNrlxuICogQGV4YW1wbGVcbiAqIC8vIHJlc3VsdDogW3t4OiAyMCwgeTogMjB9LCB7eDogMjAsIHk6IDMwfV1cbiAqIHNwbGl0UG9pbnRzKHt4OiAyMCx5OiBbMjAsIDMwXX0pO1xuICogQGV4YW1wbGVcbiAqIC8vIHJlc3VsdDogW3t4OiAyMCwgeTogMjB9LCB7eDogMzAsIHk6IDMwfV1cbiAqIHNwbGl0UG9pbnRzKHt4OiBbMjAsIDMwXSx5OiBbMjAsIDMwXX0pO1xuICogQHBhcmFtIG9ialxuICovXG5mdW5jdGlvbiBzcGxpdFBvaW50cyhvYmopIHtcbiAgICAvLyB5IOacieWPr+iDveaYr+aVsOe7hO+8jOWvueW6lOWOn+Wni+aVsOaNruS4rSB5IOS4uuS4gOS4quWMuumXtOaVsOaNru+8jOWmgiBbMTksIDMwXe+8jOS4uuS6hue7n+S4gOS5n+WwhiB4IOi9rOaNouS4uuaVsOe7hFxuICAgIHZhciB4ID0gb2JqLng7XG4gICAgdmFyIHkgPSB1dGlsXzEuaXNBcnJheShvYmoueSkgPyBvYmoueSA6IFtvYmoueV07XG4gICAgcmV0dXJuIHkubWFwKGZ1bmN0aW9uIChlYWNoWSwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHV0aWxfMS5pc0FycmF5KHgpID8geFtpbmRleF0gOiB4LFxuICAgICAgICAgICAgeTogZWFjaFksXG4gICAgICAgIH07XG4gICAgfSk7XG59XG5leHBvcnRzLnNwbGl0UG9pbnRzID0gc3BsaXRQb2ludHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zcGxpdC1wb2ludHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdyb3VwID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqIEBpZ25vcmUgKi9cbmZ1bmN0aW9uIGdyb3VwKGRhdGEsIGZpZWxkcywgYXBwZW5kQ29uZGl0aW9ucykge1xuICAgIGlmIChhcHBlbmRDb25kaXRpb25zID09PSB2b2lkIDApIHsgYXBwZW5kQ29uZGl0aW9ucyA9IHt9OyB9XG4gICAgaWYgKCFmaWVsZHMpIHtcbiAgICAgICAgcmV0dXJuIFtkYXRhXTtcbiAgICB9XG4gICAgdmFyIGdyb3VwcyA9IHV0aWxfMS5ncm91cFRvTWFwKGRhdGEsIGZpZWxkcyk7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgaWYgKGZpZWxkcy5sZW5ndGggPT09IDEgJiYgYXBwZW5kQ29uZGl0aW9uc1tmaWVsZHNbMF1dKSB7XG4gICAgICAgIHZhciB2YWx1ZXMgPSBhcHBlbmRDb25kaXRpb25zW2ZpZWxkc1swXV07XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgdmFsdWVzXzEgPSB2YWx1ZXM7IF9pIDwgdmFsdWVzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNfMVtfaV07XG4gICAgICAgICAgICB2YXIgYXJyID0gZ3JvdXBzW1wiX1wiICsgdmFsdWVdO1xuICAgICAgICAgICAgaWYgKGFycikge1xuICAgICAgICAgICAgICAgIC8vIOWPr+iDveWtmOWcqOeUqOaIt+iuvue9riB2YWx1ZXMg77yM5L2G5piv5pWw5o2u5Lit5rKh5pyJ5a+55bqU55qE5a2X5q6177yM5YiZ6L+Z5pe25YCZIGFyciDlsLHkuLogbnVsbFxuICAgICAgICAgICAgICAgIGFycmF5LnB1c2goYXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgayBpbiBncm91cHMpIHtcbiAgICAgICAgICAgIGlmIChncm91cHMuaGFzT3duUHJvcGVydHkoaykpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWFjaEdyb3VwID0gZ3JvdXBzW2tdO1xuICAgICAgICAgICAgICAgIGFycmF5LnB1c2goZWFjaEdyb3VwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG59XG5leHBvcnRzLmdyb3VwID0gZ3JvdXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncm91cC1kYXRhLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pc01vZGVsQ2hhbmdlID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgbW9kZWwgaXMgY2hhbmdlXG4gKiBAcGFyYW0gY3VycmVudE1vZGVsXG4gKiBAcGFyYW0gcHJlTW9kZWxcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGlzTW9kZWxDaGFuZ2UoY3VycmVudE1vZGVsLCBwcmVNb2RlbCkge1xuICAgIHJldHVybiB1dGlsXzEuc29tZShbJ2NvbG9yJywgJ3NoYXBlJywgJ3NpemUnLCAneCcsICd5JywgJ2lzSW5DaXJjbGUnLCAnZGF0YScsICdzdHlsZScsICdkZWZhdWx0U3R5bGUnLCAncG9pbnRzJywgJ21hcHBpbmdEYXRhJ10sIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuICF1dGlsXzEuaXNFcXVhbChjdXJyZW50TW9kZWxba2V5XSwgcHJlTW9kZWxba2V5XSk7XG4gICAgfSk7XG59XG5leHBvcnRzLmlzTW9kZWxDaGFuZ2UgPSBpc01vZGVsQ2hhbmdlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbW9kZWwtY2hhbmdlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5wYXJzZUZpZWxkcyA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKiBAaWdub3JlICovXG5mdW5jdGlvbiBwYXJzZUZpZWxkcyhmaWVsZCkge1xuICAgIGlmICh1dGlsXzEuaXNBcnJheShmaWVsZCkpIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkO1xuICAgIH1cbiAgICByZXR1cm4gZmllbGQuc3BsaXQoJyonKTtcbn1cbmV4cG9ydHMucGFyc2VGaWVsZHMgPSBwYXJzZUZpZWxkcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhcnNlLWZpZWxkcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0RGVmYXVsdFNpemUgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29vcmRpbmF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvY29vcmRpbmF0ZVwiKTtcbi8vIOW3sue7j+aOkuW6j+WQjueahOaVsOaNruafpeaJvui3neemu+acgOWwj+eahFxuZnVuY3Rpb24gZmluZE1pbkRpc3RhbmNlKGFyciwgc2NhbGUpIHtcbiAgICB2YXIgY291bnQgPSBhcnIubGVuZ3RoO1xuICAgIHZhciBzb3VyY2VBcnIgPSBhcnI7XG4gICAgaWYgKHV0aWxfMS5pc1N0cmluZyhzb3VyY2VBcnJbMF0pKSB7XG4gICAgICAgIC8vIOaXpeacn+exu+Wei+eahCB2YWx1ZXMg57uP5bi45LiK5paH5pys57G75Z6L77yM5omA5Lul6ZyA6KaB6L2s5o2i5LiA5LiLXG4gICAgICAgIHNvdXJjZUFyciA9IGFyci5tYXAoZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FsZS50cmFuc2xhdGUodik7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgZGlzdGFuY2UgPSBzb3VyY2VBcnJbMV0gLSBzb3VyY2VBcnJbMF07XG4gICAgZm9yICh2YXIgaSA9IDI7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgIHZhciB0bXAgPSBzb3VyY2VBcnJbaV0gLSBzb3VyY2VBcnJbaSAtIDFdO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPiB0bXApIHtcbiAgICAgICAgICAgIGRpc3RhbmNlID0gdG1wO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkaXN0YW5jZTtcbn1cbmZ1bmN0aW9uIGdldERvZGdlQ291bnQoZGF0YUFycmF5LCBkb2RnZUJ5KSB7XG4gICAgaWYgKGRvZGdlQnkpIHtcbiAgICAgICAgdmFyIG1lcmdlRGF0YSA9IHV0aWxfMS5mbGF0dGVuKGRhdGFBcnJheSk7XG4gICAgICAgIHZhciB2YWx1ZXMgPSB1dGlsXzEudmFsdWVzT2ZLZXkobWVyZ2VEYXRhLCBkb2RnZUJ5KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBkYXRhQXJyYXkubGVuZ3RoO1xufVxuLyoqIEBpZ25vcmUgKi9cbmZ1bmN0aW9uIGdldERlZmF1bHRTaXplKGdlb21ldHJ5KSB7XG4gICAgdmFyIHRoZW1lID0gZ2VvbWV0cnkudGhlbWU7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBnZW9tZXRyeS5jb29yZGluYXRlO1xuICAgIHZhciB4U2NhbGUgPSBnZW9tZXRyeS5nZXRYU2NhbGUoKTtcbiAgICB2YXIgeFZhbHVlcyA9IHhTY2FsZS52YWx1ZXM7XG4gICAgdmFyIGRhdGFBcnJheSA9IGdlb21ldHJ5LmJlZm9yZU1hcHBpbmdEYXRhO1xuICAgIHZhciBjb3VudCA9IHhWYWx1ZXMubGVuZ3RoO1xuICAgIGlmICh4U2NhbGUuaXNMaW5lYXIgJiYgeFZhbHVlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIExpbmVhciDnsbvlnovnlKjmiLfmnInlj6/og73orr7nva7kuoYgbWluLCBtYXgg6IyD5Zu05omA5Lul6ZyA6KaB5qC55o2u5pWw5o2u5pyA5bCP5Yy66Ze06K6h566XIGNvdW50XG4gICAgICAgIHhWYWx1ZXMuc29ydCgpO1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSBmaW5kTWluRGlzdGFuY2UoeFZhbHVlcywgeFNjYWxlKTtcbiAgICAgICAgY291bnQgPSAoeFNjYWxlLm1heCAtIHhTY2FsZS5taW4pIC8gaW50ZXJ2YWw7XG4gICAgICAgIGlmICh4VmFsdWVzLmxlbmd0aCA+IGNvdW50KSB7XG4gICAgICAgICAgICBjb3VudCA9IHhWYWx1ZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciByYW5nZSA9IHhTY2FsZS5yYW5nZTtcbiAgICB2YXIgbm9ybWFsaXplZFNpemUgPSAxIC8gY291bnQ7XG4gICAgdmFyIHdyID0gMTtcbiAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgIGlmIChjb29yZGluYXRlLmlzVHJhbnNwb3NlZCAmJiBjb3VudCA+IDEpIHtcbiAgICAgICAgICAgIC8vIOaegeWdkOagh+S4i+WkmuWxgueOr+WbvlxuICAgICAgICAgICAgd3IgPSB0aGVtZS5tdWx0aXBsZVBpZVdpZHRoUmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3ciA9IHRoZW1lLnJvc2VXaWR0aFJhdGlvO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAoeFNjYWxlLmlzTGluZWFyKSB7XG4gICAgICAgICAgICBub3JtYWxpemVkU2l6ZSAqPSByYW5nZVsxXSAtIHJhbmdlWzBdO1xuICAgICAgICB9XG4gICAgICAgIHdyID0gdGhlbWUuY29sdW1uV2lkdGhSYXRpbztcbiAgICB9XG4gICAgbm9ybWFsaXplZFNpemUgKj0gd3I7XG4gICAgaWYgKGdlb21ldHJ5LmdldEFkanVzdCgnZG9kZ2UnKSkge1xuICAgICAgICB2YXIgZG9kZ2VBZGp1c3QgPSBnZW9tZXRyeS5nZXRBZGp1c3QoJ2RvZGdlJyk7XG4gICAgICAgIHZhciBkb2RnZUJ5ID0gZG9kZ2VBZGp1c3QuZG9kZ2VCeTtcbiAgICAgICAgdmFyIGRvZGdlQ291bnQgPSBnZXREb2RnZUNvdW50KGRhdGFBcnJheSwgZG9kZ2VCeSk7XG4gICAgICAgIG5vcm1hbGl6ZWRTaXplID0gbm9ybWFsaXplZFNpemUgLyBkb2RnZUNvdW50O1xuICAgIH1cbiAgICAvLyDmnIDlpKflkozmnIDlsI/pmZDliLZcbiAgICB2YXIgbWF4Q29sdW1uV2lkdGggPSB0aGVtZS5tYXhDb2x1bW5XaWR0aCwgbWluQ29sdW1uV2lkdGggPSB0aGVtZS5taW5Db2x1bW5XaWR0aDtcbiAgICB2YXIgeERpbWVuc2lvbkxlbmd0aCA9IGNvb3JkaW5hdGVfMS5nZXRYRGltZW5zaW9uTGVuZ3RoKGdlb21ldHJ5LmNvb3JkaW5hdGUpO1xuICAgIGlmIChtYXhDb2x1bW5XaWR0aCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZE1heENvbHVtbldpZHRoID0gbWF4Q29sdW1uV2lkdGggLyB4RGltZW5zaW9uTGVuZ3RoO1xuICAgICAgICBpZiAobm9ybWFsaXplZFNpemUgPiBub3JtYWxpemVkTWF4Q29sdW1uV2lkdGgpIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRTaXplID0gbm9ybWFsaXplZE1heENvbHVtbldpZHRoO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChtaW5Db2x1bW5XaWR0aCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZE1pbkNvbHVtbldpZHRoID0gbWluQ29sdW1uV2lkdGggLyB4RGltZW5zaW9uTGVuZ3RoO1xuICAgICAgICBpZiAobm9ybWFsaXplZFNpemUgPCBub3JtYWxpemVkTWluQ29sdW1uV2lkdGgpIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRTaXplID0gbm9ybWFsaXplZE1pbkNvbHVtbldpZHRoO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBub3JtYWxpemVkU2l6ZTtcbn1cbmV4cG9ydHMuZ2V0RGVmYXVsdFNpemUgPSBnZXREZWZhdWx0U2l6ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYXBlLXNpemUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlV0aWwgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8vIOazqOWGjOm7keaal+S4u+mimFxudmFyIGNvcmVfMSA9IHJlcXVpcmUoXCIuL2NvcmVcIik7XG52YXIgZGFya18xID0gcmVxdWlyZShcIi4vdGhlbWUvc3R5bGUtc2hlZXQvZGFya1wiKTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4vdXRpbC90aGVtZVwiKTtcbmNvcmVfMS5yZWdpc3RlclRoZW1lKCdkYXJrJywgdGhlbWVfMS5jcmVhdGVUaGVtZUJ5U3R5bGVzaGVldChkYXJrXzEuYW50dkRhcmspKTtcbi8vIOazqOWGjCBHIOa4suafk+W8leaTjlxudmFyIENhbnZhc0VuZ2luZSA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJAYW50di9nLWNhbnZhc1wiKSk7XG52YXIgU1ZHRW5naW5lID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIkBhbnR2L2ctc3ZnXCIpKTtcbnZhciBjb3JlXzIgPSByZXF1aXJlKFwiLi9jb3JlXCIpO1xuY29yZV8yLnJlZ2lzdGVyRW5naW5lKCdjYW52YXMnLCBDYW52YXNFbmdpbmUpO1xuY29yZV8yLnJlZ2lzdGVyRW5naW5lKCdzdmcnLCBTVkdFbmdpbmUpO1xuLy8g5rOo5YaMIEcyIOWGhee9rueahCBnZW9tZXRyeVxudmFyIGNvcmVfMyA9IHJlcXVpcmUoXCIuL2NvcmVcIik7XG52YXIgYXJlYV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZ2VvbWV0cnkvYXJlYVwiKSk7XG52YXIgZWRnZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZ2VvbWV0cnkvZWRnZVwiKSk7XG52YXIgaGVhdG1hcF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZ2VvbWV0cnkvaGVhdG1hcFwiKSk7XG52YXIgaW50ZXJ2YWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2dlb21ldHJ5L2ludGVydmFsXCIpKTtcbnZhciBsaW5lXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9nZW9tZXRyeS9saW5lXCIpKTtcbnZhciBwYXRoXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9nZW9tZXRyeS9wYXRoXCIpKTtcbnZhciBwb2ludF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZ2VvbWV0cnkvcG9pbnRcIikpO1xudmFyIHBvbHlnb25fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2dlb21ldHJ5L3BvbHlnb25cIikpO1xudmFyIHNjaGVtYV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZ2VvbWV0cnkvc2NoZW1hXCIpKTtcbmNvcmVfMy5yZWdpc3Rlckdlb21ldHJ5KCdQb2x5Z29uJywgcG9seWdvbl8xLmRlZmF1bHQpO1xuY29yZV8zLnJlZ2lzdGVyR2VvbWV0cnkoJ0ludGVydmFsJywgaW50ZXJ2YWxfMS5kZWZhdWx0KTtcbmNvcmVfMy5yZWdpc3Rlckdlb21ldHJ5KCdTY2hlbWEnLCBzY2hlbWFfMS5kZWZhdWx0KTtcbmNvcmVfMy5yZWdpc3Rlckdlb21ldHJ5KCdQYXRoJywgcGF0aF8xLmRlZmF1bHQpO1xuY29yZV8zLnJlZ2lzdGVyR2VvbWV0cnkoJ1BvaW50JywgcG9pbnRfMS5kZWZhdWx0KTtcbmNvcmVfMy5yZWdpc3Rlckdlb21ldHJ5KCdMaW5lJywgbGluZV8xLmRlZmF1bHQpO1xuY29yZV8zLnJlZ2lzdGVyR2VvbWV0cnkoJ0FyZWEnLCBhcmVhXzEuZGVmYXVsdCk7XG5jb3JlXzMucmVnaXN0ZXJHZW9tZXRyeSgnRWRnZScsIGVkZ2VfMS5kZWZhdWx0KTtcbmNvcmVfMy5yZWdpc3Rlckdlb21ldHJ5KCdIZWF0bWFwJywgaGVhdG1hcF8xLmRlZmF1bHQpO1xuLy8g5byV5YWl5omA5pyJ5YaF572u55qEIHNoYXBlc1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvYXJlYS9saW5lXCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvYXJlYS9zbW9vdGhcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9hcmVhL3Ntb290aC1saW5lXCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvZWRnZS9hcmNcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9lZGdlL3Ntb290aFwiKTtcbnJlcXVpcmUoXCIuL2dlb21ldHJ5L3NoYXBlL2VkZ2Uvdmh2XCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvZnVubmVsXCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvaG9sbG93LXJlY3RcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9pbnRlcnZhbC9saW5lXCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvaW50ZXJ2YWwvcHlyYW1pZFwiKTtcbnJlcXVpcmUoXCIuL2dlb21ldHJ5L3NoYXBlL2ludGVydmFsL3RpY2tcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9saW5lL3N0ZXBcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9wb2ludC9ob2xsb3dcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9wb2ludC9pbWFnZVwiKTtcbnJlcXVpcmUoXCIuL2dlb21ldHJ5L3NoYXBlL3BvaW50L3NvbGlkXCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvc2NoZW1hL2JveFwiKTtcbnJlcXVpcmUoXCIuL2dlb21ldHJ5L3NoYXBlL3NjaGVtYS9jYW5kbGVcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9wb2x5Z29uL3NxdWFyZVwiKTtcbi8vIOazqOWGjCBHZW9tZXRyeSDlhoXnva7nmoQgbGFiZWxcbnZhciBjb3JlXzQgPSByZXF1aXJlKFwiLi9jb3JlXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2dlb21ldHJ5L2xhYmVsL2Jhc2VcIikpO1xudmFyIGludGVydmFsXzIgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9nZW9tZXRyeS9sYWJlbC9pbnRlcnZhbFwiKSk7XG52YXIgcGllXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9nZW9tZXRyeS9sYWJlbC9waWVcIikpO1xudmFyIHBvbGFyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9nZW9tZXRyeS9sYWJlbC9wb2xhclwiKSk7XG5jb3JlXzQucmVnaXN0ZXJHZW9tZXRyeUxhYmVsKCdiYXNlJywgYmFzZV8xLmRlZmF1bHQpO1xuY29yZV80LnJlZ2lzdGVyR2VvbWV0cnlMYWJlbCgnaW50ZXJ2YWwnLCBpbnRlcnZhbF8yLmRlZmF1bHQpO1xuY29yZV80LnJlZ2lzdGVyR2VvbWV0cnlMYWJlbCgncGllJywgcGllXzEuZGVmYXVsdCk7XG5jb3JlXzQucmVnaXN0ZXJHZW9tZXRyeUxhYmVsKCdwb2xhcicsIHBvbGFyXzEuZGVmYXVsdCk7XG4vLyDms6jlhowgR2VvbWV0cnkgbGFiZWwg5YaF572u55qE5biD5bGA5Ye95pWwXG52YXIgY29yZV81ID0gcmVxdWlyZShcIi4vY29yZVwiKTtcbnZhciBkaXN0cmlidXRlXzEgPSByZXF1aXJlKFwiLi9nZW9tZXRyeS9sYWJlbC9sYXlvdXQvcGllL2Rpc3RyaWJ1dGVcIik7XG52YXIgb3V0ZXJfMSA9IHJlcXVpcmUoXCIuL2dlb21ldHJ5L2xhYmVsL2xheW91dC9waWUvb3V0ZXJcIik7XG52YXIgbGltaXRfaW5fY2FudmFzXzEgPSByZXF1aXJlKFwiLi9nZW9tZXRyeS9sYWJlbC9sYXlvdXQvbGltaXQtaW4tY2FudmFzXCIpO1xudmFyIGxpbWl0X2luX3NoYXBlXzEgPSByZXF1aXJlKFwiLi9nZW9tZXRyeS9sYWJlbC9sYXlvdXQvbGltaXQtaW4tc2hhcGVcIik7XG52YXIgb3ZlcmxhcF8xID0gcmVxdWlyZShcIi4vZ2VvbWV0cnkvbGFiZWwvbGF5b3V0L292ZXJsYXBcIik7XG5jb3JlXzUucmVnaXN0ZXJHZW9tZXRyeUxhYmVsTGF5b3V0KCdvdmVybGFwJywgb3ZlcmxhcF8xLm92ZXJsYXApO1xuY29yZV81LnJlZ2lzdGVyR2VvbWV0cnlMYWJlbExheW91dCgnZGlzdHJpYnV0ZScsIGRpc3RyaWJ1dGVfMS5kaXN0cmlidXRlKTtcbmNvcmVfNS5yZWdpc3Rlckdlb21ldHJ5TGFiZWxMYXlvdXQoJ2ZpeGVkLW92ZXJsYXAnLCBvdmVybGFwXzEuZml4ZWRPdmVybGFwKTtcbmNvcmVfNS5yZWdpc3Rlckdlb21ldHJ5TGFiZWxMYXlvdXQoJ2xpbWl0LWluLXNoYXBlJywgbGltaXRfaW5fc2hhcGVfMS5saW1pdEluU2hhcGUpO1xuY29yZV81LnJlZ2lzdGVyR2VvbWV0cnlMYWJlbExheW91dCgnbGltaXQtaW4tY2FudmFzJywgbGltaXRfaW5fY2FudmFzXzEubGltaXRJbkNhbnZhcyk7XG5jb3JlXzUucmVnaXN0ZXJHZW9tZXRyeUxhYmVsTGF5b3V0KCdwaWUtb3V0ZXInLCBvdXRlcl8xLnBpZU91dGVyTGFiZWxMYXlvdXQpO1xuLy8g5rOo5YaM6ZyA6KaB55qE5Yqo55S75omn6KGM5Ye95pWwXG52YXIgZmFkZV8xID0gcmVxdWlyZShcIi4vYW5pbWF0ZS9hbmltYXRpb24vZmFkZVwiKTtcbnZhciBncm93X2luXzEgPSByZXF1aXJlKFwiLi9hbmltYXRlL2FuaW1hdGlvbi9ncm93LWluXCIpO1xudmFyIHBhdGhfaW5fMSA9IHJlcXVpcmUoXCIuL2FuaW1hdGUvYW5pbWF0aW9uL3BhdGgtaW5cIik7XG52YXIgcG9zaXRpb25fdXBkYXRlXzEgPSByZXF1aXJlKFwiLi9hbmltYXRlL2FuaW1hdGlvbi9wb3NpdGlvbi11cGRhdGVcIik7XG52YXIgc2NhbGVfaW5fMSA9IHJlcXVpcmUoXCIuL2FuaW1hdGUvYW5pbWF0aW9uL3NjYWxlLWluXCIpO1xudmFyIHNlY3Rvcl9wYXRoX3VwZGF0ZV8xID0gcmVxdWlyZShcIi4vYW5pbWF0ZS9hbmltYXRpb24vc2VjdG9yLXBhdGgtdXBkYXRlXCIpO1xudmFyIHdhdmVfaW5fMSA9IHJlcXVpcmUoXCIuL2FuaW1hdGUvYW5pbWF0aW9uL3dhdmUtaW5cIik7XG52YXIgem9vbV8xID0gcmVxdWlyZShcIi4vYW5pbWF0ZS9hbmltYXRpb24vem9vbVwiKTtcbnZhciBjb3JlXzYgPSByZXF1aXJlKFwiLi9jb3JlXCIpO1xuY29yZV82LnJlZ2lzdGVyQW5pbWF0aW9uKCdmYWRlLWluJywgZmFkZV8xLmZhZGVJbik7XG5jb3JlXzYucmVnaXN0ZXJBbmltYXRpb24oJ2ZhZGUtb3V0JywgZmFkZV8xLmZhZGVPdXQpO1xuY29yZV82LnJlZ2lzdGVyQW5pbWF0aW9uKCdncm93LWluLXgnLCBncm93X2luXzEuZ3Jvd0luWCk7XG5jb3JlXzYucmVnaXN0ZXJBbmltYXRpb24oJ2dyb3ctaW4teHknLCBncm93X2luXzEuZ3Jvd0luWFkpO1xuY29yZV82LnJlZ2lzdGVyQW5pbWF0aW9uKCdncm93LWluLXknLCBncm93X2luXzEuZ3Jvd0luWSk7XG5jb3JlXzYucmVnaXN0ZXJBbmltYXRpb24oJ3NjYWxlLWluLXgnLCBzY2FsZV9pbl8xLnNjYWxlSW5YKTtcbmNvcmVfNi5yZWdpc3RlckFuaW1hdGlvbignc2NhbGUtaW4teScsIHNjYWxlX2luXzEuc2NhbGVJblkpO1xuY29yZV82LnJlZ2lzdGVyQW5pbWF0aW9uKCd3YXZlLWluJywgd2F2ZV9pbl8xLndhdmVJbik7XG5jb3JlXzYucmVnaXN0ZXJBbmltYXRpb24oJ3pvb20taW4nLCB6b29tXzEuem9vbUluKTtcbmNvcmVfNi5yZWdpc3RlckFuaW1hdGlvbignem9vbS1vdXQnLCB6b29tXzEuem9vbU91dCk7XG5jb3JlXzYucmVnaXN0ZXJBbmltYXRpb24oJ3Bvc2l0aW9uLXVwZGF0ZScsIHBvc2l0aW9uX3VwZGF0ZV8xLnBvc2l0aW9uVXBkYXRlKTtcbmNvcmVfNi5yZWdpc3RlckFuaW1hdGlvbignc2VjdG9yLXBhdGgtdXBkYXRlJywgc2VjdG9yX3BhdGhfdXBkYXRlXzEuc2VjdG9yUGF0aFVwZGF0ZSk7XG5jb3JlXzYucmVnaXN0ZXJBbmltYXRpb24oJ3BhdGgtaW4nLCBwYXRoX2luXzEucGF0aEluKTtcbi8vIOazqOWGjOWGhee9rueahCBGYWNldFxudmFyIGNvcmVfNyA9IHJlcXVpcmUoXCIuL2NvcmVcIik7XG52YXIgY2lyY2xlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9mYWNldC9jaXJjbGVcIikpO1xudmFyIGxpc3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ZhY2V0L2xpc3RcIikpO1xudmFyIG1hdHJpeF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZmFjZXQvbWF0cml4XCIpKTtcbnZhciBtaXJyb3JfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ZhY2V0L21pcnJvclwiKSk7XG52YXIgcmVjdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZmFjZXQvcmVjdFwiKSk7XG52YXIgdHJlZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZmFjZXQvdHJlZVwiKSk7XG5jb3JlXzcucmVnaXN0ZXJGYWNldCgncmVjdCcsIHJlY3RfMS5kZWZhdWx0KTtcbmNvcmVfNy5yZWdpc3RlckZhY2V0KCdtaXJyb3InLCBtaXJyb3JfMS5kZWZhdWx0KTtcbmNvcmVfNy5yZWdpc3RlckZhY2V0KCdsaXN0JywgbGlzdF8xLmRlZmF1bHQpO1xuY29yZV83LnJlZ2lzdGVyRmFjZXQoJ21hdHJpeCcsIG1hdHJpeF8xLmRlZmF1bHQpO1xuY29yZV83LnJlZ2lzdGVyRmFjZXQoJ2NpcmNsZScsIGNpcmNsZV8xLmRlZmF1bHQpO1xuY29yZV83LnJlZ2lzdGVyRmFjZXQoJ3RyZWUnLCB0cmVlXzEuZGVmYXVsdCk7XG4vLyDms6jlhozlhoXnva7nmoQgQ29tcG9uZW50XG52YXIgY29yZV84ID0gcmVxdWlyZShcIi4vY29yZVwiKTtcbnZhciBhbm5vdGF0aW9uXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jaGFydC9jb250cm9sbGVyL2Fubm90YXRpb25cIikpO1xudmFyIGF4aXNfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NoYXJ0L2NvbnRyb2xsZXIvYXhpc1wiKSk7XG52YXIgbGVnZW5kXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jaGFydC9jb250cm9sbGVyL2xlZ2VuZFwiKSk7XG52YXIgc2xpZGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jaGFydC9jb250cm9sbGVyL3NsaWRlclwiKSk7XG52YXIgdG9vbHRpcF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY2hhcnQvY29udHJvbGxlci90b29sdGlwXCIpKTtcbi8vIHJlZ2lzdGVyIGJ1aWxkLWluIGNvbXBvbmVudHNcbmNvcmVfOC5yZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXIoJ2F4aXMnLCBheGlzXzEuZGVmYXVsdCk7XG5jb3JlXzgucmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyKCdsZWdlbmQnLCBsZWdlbmRfMS5kZWZhdWx0KTtcbmNvcmVfOC5yZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXIoJ3Rvb2x0aXAnLCB0b29sdGlwXzEuZGVmYXVsdCk7XG5jb3JlXzgucmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyKCdhbm5vdGF0aW9uJywgYW5ub3RhdGlvbl8xLmRlZmF1bHQpO1xuY29yZV84LnJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlcignc2xpZGVyJywgc2xpZGVyXzEuZGVmYXVsdCk7XG4vLyDms6jlhowgSW50ZXJhY3Rpb24gQWN0aW9uXG52YXIgY29yZV85ID0gcmVxdWlyZShcIi4vY29yZVwiKTtcbnZhciBhY3RpdmVfcmVnaW9uXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vYWN0aXZlLXJlZ2lvblwiKSk7XG52YXIgc2libGluZ18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2NvbXBvbmVudC90b29sdGlwL3NpYmxpbmdcIikpO1xudmFyIGdlb21ldHJ5XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vY29tcG9uZW50L3Rvb2x0aXAvZ2VvbWV0cnlcIikpO1xudmFyIGVsbGlwc2lzX3RleHRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvdG9vbHRpcC9lbGxpcHNpcy10ZXh0XCIpKTtcbnZhciBhY3RpdmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L2FjdGl2ZVwiKSk7XG52YXIgbGlua19ieV9jb2xvcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvbGluay1ieS1jb2xvclwiKSk7XG52YXIgcmFuZ2VfYWN0aXZlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9yYW5nZS1hY3RpdmVcIikpO1xudmFyIHNpbmdsZV9hY3RpdmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3NpbmdsZS1hY3RpdmVcIikpO1xudmFyIGhpZ2hsaWdodF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvaGlnaGxpZ2h0XCIpKTtcbnZhciBoaWdobGlnaHRfYnlfY29sb3JfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L2hpZ2hsaWdodC1ieS1jb2xvclwiKSk7XG52YXIgaGlnaGxpZ2h0X2J5X3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L2hpZ2hsaWdodC1ieS14XCIpKTtcbnZhciByYW5nZV9oaWdobGlnaHRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3JhbmdlLWhpZ2hsaWdodFwiKSk7XG52YXIgc2luZ2xlX2hpZ2hsaWdodF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvc2luZ2xlLWhpZ2hsaWdodFwiKSk7XG52YXIgcmFuZ2Vfc2VsZWN0ZWRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9lbGVtZW50L3JhbmdlLXNlbGVjdGVkXCIpKTtcbnZhciBzZWxlY3RlZF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvc2VsZWN0ZWRcIikpO1xudmFyIHNpbmdsZV9zZWxlY3RlZF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2VsZW1lbnQvc2luZ2xlLXNlbGVjdGVkXCIpKTtcbnZhciBsaXN0X2FjdGl2ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL2NvbXBvbmVudC9saXN0LWFjdGl2ZVwiKSk7XG52YXIgbGlzdF9oaWdobGlnaHRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvbGlzdC1oaWdobGlnaHRcIikpO1xudmFyIGxpc3Rfc2VsZWN0ZWRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvbGlzdC1zZWxlY3RlZFwiKSk7XG52YXIgbGlzdF91bmNoZWNrZWRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9jb21wb25lbnQvbGlzdC11bmNoZWNrZWRcIikpO1xudmFyIGNpcmNsZV8yID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL21hc2svY2lyY2xlXCIpKTtcbnZhciBkaW1fcmVjdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL21hc2svZGltLXJlY3RcIikpO1xudmFyIHBhdGhfMiA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9tYXNrL3BhdGhcIikpO1xudmFyIHJlY3RfMiA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9tYXNrL3JlY3RcIikpO1xudmFyIHNtb290aF9wYXRoXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vbWFzay9zbW9vdGgtcGF0aFwiKSk7XG52YXIgY3Vyc29yXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vY3Vyc29yXCIpKTtcbnZhciBmaWx0ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi9kYXRhL2ZpbHRlclwiKSk7XG52YXIgcmFuZ2VfZmlsdGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vZGF0YS9yYW5nZS1maWx0ZXJcIikpO1xudmFyIHNpYmxpbmdfZmlsdGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vZGF0YS9zaWJsaW5nLWZpbHRlclwiKSk7XG52YXIgZmlsdGVyXzIgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9maWx0ZXJcIikpO1xudmFyIHNpYmxpbmdfZmlsdGVyXzIgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vZWxlbWVudC9zaWJsaW5nLWZpbHRlclwiKSk7XG52YXIgYnV0dG9uXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vdmlldy9idXR0b25cIikpO1xudmFyIGRyYWdfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi92aWV3L2RyYWdcIikpO1xudmFyIG1vdmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uL2FjdGlvbi92aWV3L21vdmVcIikpO1xudmFyIHNjYWxlX3RyYW5zbGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJhY3Rpb24vYWN0aW9uL3ZpZXcvc2NhbGUtdHJhbnNsYXRlXCIpKTtcbnZhciBzY2FsZV96b29tXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9hY3Rpb24vdmlldy9zY2FsZS16b29tXCIpKTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbigndG9vbHRpcCcsIGdlb21ldHJ5XzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ3NpYmxpbmctdG9vbHRpcCcsIHNpYmxpbmdfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignZWxsaXBzaXMtdGV4dCcsIGVsbGlwc2lzX3RleHRfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignZWxlbWVudC1hY3RpdmUnLCBhY3RpdmVfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignZWxlbWVudC1zaW5nbGUtYWN0aXZlJywgc2luZ2xlX2FjdGl2ZV8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LXJhbmdlLWFjdGl2ZScsIHJhbmdlX2FjdGl2ZV8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LWhpZ2hsaWdodCcsIGhpZ2hsaWdodF8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LWhpZ2hsaWdodC1ieS14JywgaGlnaGxpZ2h0X2J5X3hfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignZWxlbWVudC1oaWdobGlnaHQtYnktY29sb3InLCBoaWdobGlnaHRfYnlfY29sb3JfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignZWxlbWVudC1zaW5nbGUtaGlnaGxpZ2h0Jywgc2luZ2xlX2hpZ2hsaWdodF8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LXJhbmdlLWhpZ2hsaWdodCcsIHJhbmdlX2hpZ2hsaWdodF8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LXNpYmxpbmctaGlnaGxpZ2h0JywgcmFuZ2VfaGlnaGxpZ2h0XzEuZGVmYXVsdCwge1xuICAgIGVmZmVjdFNpYmxpbmdzOiB0cnVlLFxuICAgIGVmZmVjdEJ5UmVjb3JkOiB0cnVlLFxufSk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2VsZW1lbnQtc2VsZWN0ZWQnLCBzZWxlY3RlZF8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LXNpbmdsZS1zZWxlY3RlZCcsIHNpbmdsZV9zZWxlY3RlZF8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LXJhbmdlLXNlbGVjdGVkJywgcmFuZ2Vfc2VsZWN0ZWRfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignZWxlbWVudC1saW5rLWJ5LWNvbG9yJywgbGlua19ieV9jb2xvcl8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdhY3RpdmUtcmVnaW9uJywgYWN0aXZlX3JlZ2lvbl8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdsaXN0LWFjdGl2ZScsIGxpc3RfYWN0aXZlXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2xpc3Qtc2VsZWN0ZWQnLCBsaXN0X3NlbGVjdGVkXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2xpc3QtaGlnaGxpZ2h0JywgbGlzdF9oaWdobGlnaHRfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignbGlzdC11bmNoZWNrZWQnLCBsaXN0X3VuY2hlY2tlZF8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdsZWdlbmQtaXRlbS1oaWdobGlnaHQnLCBsaXN0X2hpZ2hsaWdodF8xLmRlZmF1bHQsIHtcbiAgICBjb21wb25lbnROYW1lczogWydsZWdlbmQnXSxcbn0pO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdheGlzLWxhYmVsLWhpZ2hsaWdodCcsIGxpc3RfaGlnaGxpZ2h0XzEuZGVmYXVsdCwge1xuICAgIGNvbXBvbmVudE5hbWVzOiBbJ2F4aXMnXSxcbn0pO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdyZWN0LW1hc2snLCByZWN0XzIuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ3gtcmVjdC1tYXNrJywgZGltX3JlY3RfMS5kZWZhdWx0LCB7IGRpbTogJ3gnIH0pO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCd5LXJlY3QtbWFzaycsIGRpbV9yZWN0XzEuZGVmYXVsdCwgeyBkaW06ICd5JyB9KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignY2lyY2xlLW1hc2snLCBjaXJjbGVfMi5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbigncGF0aC1tYXNrJywgcGF0aF8yLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdzbW9vdGgtcGF0aC1tYXNrJywgc21vb3RoX3BhdGhfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignY3Vyc29yJywgY3Vyc29yXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2RhdGEtZmlsdGVyJywgZmlsdGVyXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2JydXNoJywgcmFuZ2VfZmlsdGVyXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2JydXNoLXgnLCByYW5nZV9maWx0ZXJfMS5kZWZhdWx0LCB7IGRpbXM6IFsneCddIH0pO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdicnVzaC15JywgcmFuZ2VfZmlsdGVyXzEuZGVmYXVsdCwgeyBkaW1zOiBbJ3knXSB9KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignc2libGluZy1maWx0ZXInLCBzaWJsaW5nX2ZpbHRlcl8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdzaWJsaW5nLXgtZmlsdGVyJywgc2libGluZ19maWx0ZXJfMS5kZWZhdWx0KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbignc2libGluZy15LWZpbHRlcicsIHNpYmxpbmdfZmlsdGVyXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2VsZW1lbnQtZmlsdGVyJywgZmlsdGVyXzIuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ2VsZW1lbnQtc2libGluZy1maWx0ZXInLCBzaWJsaW5nX2ZpbHRlcl8yLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdlbGVtZW50LXNpYmxpbmctZmlsdGVyLXJlY29yZCcsIHNpYmxpbmdfZmlsdGVyXzIuZGVmYXVsdCwgeyBieVJlY29yZDogdHJ1ZSB9KTtcbmNvcmVfOS5yZWdpc3RlckFjdGlvbigndmlldy1kcmFnJywgZHJhZ18xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCd2aWV3LW1vdmUnLCBtb3ZlXzEuZGVmYXVsdCk7XG5jb3JlXzkucmVnaXN0ZXJBY3Rpb24oJ3NjYWxlLXRyYW5zbGF0ZScsIHNjYWxlX3RyYW5zbGF0ZV8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdzY2FsZS16b29tJywgc2NhbGVfem9vbV8xLmRlZmF1bHQpO1xuY29yZV85LnJlZ2lzdGVyQWN0aW9uKCdyZXNldC1idXR0b24nLCBidXR0b25fMS5kZWZhdWx0LCB7XG4gICAgbmFtZTogJ3Jlc2V0LWJ1dHRvbicsXG4gICAgdGV4dDogJ3Jlc2V0Jyxcbn0pO1xuLy8g5rOo5YaM6buY6K6k55qEIEludGVyYWN0aW9uIOS6pOS6kuihjOS4ulxudmFyIGNvcmVfMTAgPSByZXF1aXJlKFwiLi9jb3JlXCIpO1xuZnVuY3Rpb24gaXNQb2ludEluVmlldyhjb250ZXh0KSB7XG4gICAgcmV0dXJuIGNvbnRleHQuaXNJblBsb3QoKTtcbn1cbi8vIOazqOWGjCB0b29sdGlwIOeahCBpbnRlcmFjdGlvblxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCd0b29sdGlwJywge1xuICAgIHN0YXJ0OiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6bW91c2Vtb3ZlJywgYWN0aW9uOiAndG9vbHRpcDpzaG93JywgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9IH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6dG91Y2htb3ZlJywgYWN0aW9uOiAndG9vbHRpcDpzaG93JywgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9IH0sXG4gICAgXSxcbiAgICBlbmQ6IFtcbiAgICAgICAgeyB0cmlnZ2VyOiAncGxvdDptb3VzZWxlYXZlJywgYWN0aW9uOiAndG9vbHRpcDpoaWRlJyB9LFxuICAgICAgICB7IHRyaWdnZXI6ICdwbG90OmxlYXZlJywgYWN0aW9uOiAndG9vbHRpcDpoaWRlJyB9LFxuICAgICAgICB7IHRyaWdnZXI6ICdwbG90OnRvdWNoZW5kJywgYWN0aW9uOiAndG9vbHRpcDpoaWRlJyB9LFxuICAgIF0sXG59KTtcbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignZWxsaXBzaXMtdGV4dCcsIHtcbiAgICBzdGFydDogW1xuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW0tbmFtZTptb3VzZW1vdmUnLFxuICAgICAgICAgICAgYWN0aW9uOiAnZWxsaXBzaXMtdGV4dDpzaG93JyxcbiAgICAgICAgICAgIHRocm90dGxlOiB7IHdhaXQ6IDUwLCBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2UgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ2xlZ2VuZC1pdGVtLW5hbWU6dG91Y2hzdGFydCcsXG4gICAgICAgICAgICBhY3Rpb246ICdlbGxpcHNpcy10ZXh0OnNob3cnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAnYXhpcy1sYWJlbDptb3VzZW1vdmUnLFxuICAgICAgICAgICAgYWN0aW9uOiAnZWxsaXBzaXMtdGV4dDpzaG93JyxcbiAgICAgICAgICAgIHRocm90dGxlOiB7IHdhaXQ6IDUwLCBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2UgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ2F4aXMtbGFiZWw6dG91Y2hzdGFydCcsXG4gICAgICAgICAgICBhY3Rpb246ICdlbGxpcHNpcy10ZXh0OnNob3cnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9LFxuICAgICAgICB9LFxuICAgIF0sXG4gICAgZW5kOiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ2xlZ2VuZC1pdGVtLW5hbWU6bW91c2VsZWF2ZScsIGFjdGlvbjogJ2VsbGlwc2lzLXRleHQ6aGlkZScgfSxcbiAgICAgICAgeyB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW0tbmFtZTp0b3VjaGVuZCcsIGFjdGlvbjogJ2VsbGlwc2lzLXRleHQ6aGlkZScgfSxcbiAgICAgICAgeyB0cmlnZ2VyOiAnYXhpcy1sYWJlbDptb3VzZWxlYXZlJywgYWN0aW9uOiAnZWxsaXBzaXMtdGV4dDpoaWRlJyB9LFxuICAgICAgICB7IHRyaWdnZXI6ICdheGlzLWxhYmVsOnRvdWNoZW5kJywgYWN0aW9uOiAnZWxsaXBzaXMtdGV4dDpoaWRlJyB9LFxuICAgIF0sXG59KTtcbi8vIOenu+WKqOWIsCBlbG1lbnQg5LiKIGFjdGl2ZVxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdlbGVtZW50LWFjdGl2ZScsIHtcbiAgICBzdGFydDogW3sgdHJpZ2dlcjogJ2VsZW1lbnQ6bW91c2VlbnRlcicsIGFjdGlvbjogJ2VsZW1lbnQtYWN0aXZlOmFjdGl2ZScgfV0sXG4gICAgZW5kOiBbeyB0cmlnZ2VyOiAnZWxlbWVudDptb3VzZWxlYXZlJywgYWN0aW9uOiAnZWxlbWVudC1hY3RpdmU6cmVzZXQnIH1dLFxufSk7XG4vLyDngrnlh7vpgInkuK3vvIzlhYHorrjlj5bmtohcbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignZWxlbWVudC1zZWxlY3RlZCcsIHtcbiAgICBzdGFydDogW3sgdHJpZ2dlcjogJ2VsZW1lbnQ6Y2xpY2snLCBhY3Rpb246ICdlbGVtZW50LXNlbGVjdGVkOnRvZ2dsZScgfV0sXG59KTtcbi8vIGhvdmVyIGhpZ2hsaWdodO+8jOWFgeiuuOWPlua2iFxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdlbGVtZW50LWhpZ2hsaWdodCcsIHtcbiAgICBzdGFydDogW3sgdHJpZ2dlcjogJ2VsZW1lbnQ6bW91c2VlbnRlcicsIGFjdGlvbjogJ2VsZW1lbnQtaGlnaGxpZ2h0OmhpZ2hsaWdodCcgfV0sXG4gICAgZW5kOiBbeyB0cmlnZ2VyOiAnZWxlbWVudDptb3VzZWxlYXZlJywgYWN0aW9uOiAnZWxlbWVudC1oaWdobGlnaHQ6cmVzZXQnIH1dLFxufSk7XG4vLyBob3ZlciBoaWdobGlnaHQgYnkgeO+8jOWFgeiuuOWPlua2iFxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdlbGVtZW50LWhpZ2hsaWdodC1ieS14Jywge1xuICAgIHN0YXJ0OiBbeyB0cmlnZ2VyOiAnZWxlbWVudDptb3VzZWVudGVyJywgYWN0aW9uOiAnZWxlbWVudC1oaWdobGlnaHQtYnkteDpoaWdobGlnaHQnIH1dLFxuICAgIGVuZDogW3sgdHJpZ2dlcjogJ2VsZW1lbnQ6bW91c2VsZWF2ZScsIGFjdGlvbjogJ2VsZW1lbnQtaGlnaGxpZ2h0LWJ5LXg6cmVzZXQnIH1dLFxufSk7XG4vLyBob3ZlciBoaWdobGlnaHQgYnkgee+8jOWFgeiuuOWPlua2iFxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdlbGVtZW50LWhpZ2hsaWdodC1ieS1jb2xvcicsIHtcbiAgICBzdGFydDogW3sgdHJpZ2dlcjogJ2VsZW1lbnQ6bW91c2VlbnRlcicsIGFjdGlvbjogJ2VsZW1lbnQtaGlnaGxpZ2h0LWJ5LWNvbG9yOmhpZ2hsaWdodCcgfV0sXG4gICAgZW5kOiBbeyB0cmlnZ2VyOiAnZWxlbWVudDptb3VzZWxlYXZlJywgYWN0aW9uOiAnZWxlbWVudC1oaWdobGlnaHQtYnktY29sb3I6cmVzZXQnIH1dLFxufSk7XG4vLyBsZWdlbmQgaG92ZXLvvIxlbGVtZW50IGFjdGl2ZVxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdsZWdlbmQtYWN0aXZlJywge1xuICAgIHN0YXJ0OiBbeyB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW06bW91c2VlbnRlcicsIGFjdGlvbjogWydsaXN0LWFjdGl2ZTphY3RpdmUnLCAnZWxlbWVudC1hY3RpdmU6YWN0aXZlJ10gfV0sXG4gICAgZW5kOiBbeyB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW06bW91c2VsZWF2ZScsIGFjdGlvbjogWydsaXN0LWFjdGl2ZTpyZXNldCcsICdlbGVtZW50LWFjdGl2ZTpyZXNldCddIH1dLFxufSk7XG4vLyBsZWdlbmQgaG92ZXLvvIxlbGVtZW50IGFjdGl2ZVxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdsZWdlbmQtaGlnaGxpZ2h0Jywge1xuICAgIHN0YXJ0OiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ2xlZ2VuZC1pdGVtOm1vdXNlZW50ZXInLCBhY3Rpb246IFsnbGVnZW5kLWl0ZW0taGlnaGxpZ2h0OmhpZ2hsaWdodCcsICdlbGVtZW50LWhpZ2hsaWdodDpoaWdobGlnaHQnXSB9LFxuICAgIF0sXG4gICAgZW5kOiBbeyB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW06bW91c2VsZWF2ZScsIGFjdGlvbjogWydsZWdlbmQtaXRlbS1oaWdobGlnaHQ6cmVzZXQnLCAnZWxlbWVudC1oaWdobGlnaHQ6cmVzZXQnXSB9XSxcbn0pO1xuLy8gbGVnZW5kIGhvdmVy77yMZWxlbWVudCBhY3RpdmVcbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignYXhpcy1sYWJlbC1oaWdobGlnaHQnLCB7XG4gICAgc3RhcnQ6IFtcbiAgICAgICAgeyB0cmlnZ2VyOiAnYXhpcy1sYWJlbDptb3VzZWVudGVyJywgYWN0aW9uOiBbJ2F4aXMtbGFiZWwtaGlnaGxpZ2h0OmhpZ2hsaWdodCcsICdlbGVtZW50LWhpZ2hsaWdodDpoaWdobGlnaHQnXSB9LFxuICAgIF0sXG4gICAgZW5kOiBbeyB0cmlnZ2VyOiAnYXhpcy1sYWJlbDptb3VzZWxlYXZlJywgYWN0aW9uOiBbJ2F4aXMtbGFiZWwtaGlnaGxpZ2h0OnJlc2V0JywgJ2VsZW1lbnQtaGlnaGxpZ2h0OnJlc2V0J10gfV0sXG59KTtcbi8vIGxlZ2VuZCBob3Zlcu+8jGVsZW1lbnQgYWN0aXZlXG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ2VsZW1lbnQtbGlzdC1oaWdobGlnaHQnLCB7XG4gICAgc3RhcnQ6IFt7IHRyaWdnZXI6ICdlbGVtZW50Om1vdXNlZW50ZXInLCBhY3Rpb246IFsnbGlzdC1oaWdobGlnaHQ6aGlnaGxpZ2h0JywgJ2VsZW1lbnQtaGlnaGxpZ2h0OmhpZ2hsaWdodCddIH1dLFxuICAgIGVuZDogW3sgdHJpZ2dlcjogJ2VsZW1lbnQ6bW91c2VsZWF2ZScsIGFjdGlvbjogWydsaXN0LWhpZ2hsaWdodDpyZXNldCcsICdlbGVtZW50LWhpZ2hsaWdodDpyZXNldCddIH1dLFxufSk7XG4vLyDmoYbpgIlcbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignZWxlbWVudC1yYW5nZS1oaWdobGlnaHQnLCB7XG4gICAgc2hvd0VuYWJsZTogW1xuICAgICAgICB7IHRyaWdnZXI6ICdwbG90Om1vdXNlZW50ZXInLCBhY3Rpb246ICdjdXJzb3I6Y3Jvc3NoYWlyJyB9LFxuICAgICAgICB7IHRyaWdnZXI6ICdtYXNrOm1vdXNlZW50ZXInLCBhY3Rpb246ICdjdXJzb3I6bW92ZScgfSxcbiAgICAgICAgeyB0cmlnZ2VyOiAncGxvdDptb3VzZWxlYXZlJywgYWN0aW9uOiAnY3Vyc29yOmRlZmF1bHQnIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ21hc2s6bW91c2VsZWF2ZScsIGFjdGlvbjogJ2N1cnNvcjpjcm9zc2hhaXInIH0sXG4gICAgXSxcbiAgICBzdGFydDogW1xuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAncGxvdDptb3VzZWRvd24nLFxuICAgICAgICAgICAgaXNFbmFibGU6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8g5LiN6KaB54K55Ye75ZyoIG1hc2sg5LiK6YeN5paw5byA5aeLXG4gICAgICAgICAgICAgICAgcmV0dXJuICFjb250ZXh0LmlzSW5TaGFwZSgnbWFzaycpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdGlvbjogWydyZWN0LW1hc2s6c3RhcnQnLCAncmVjdC1tYXNrOnNob3cnXSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ21hc2s6ZHJhZ3N0YXJ0JyxcbiAgICAgICAgICAgIGFjdGlvbjogWydyZWN0LW1hc2s6bW92ZVN0YXJ0J10sXG4gICAgICAgIH0sXG4gICAgXSxcbiAgICBwcm9jZXNzaW5nOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyaWdnZXI6ICdwbG90Om1vdXNlbW92ZScsXG4gICAgICAgICAgICBhY3Rpb246IFsncmVjdC1tYXNrOnJlc2l6ZSddLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAnbWFzazpkcmFnJyxcbiAgICAgICAgICAgIGFjdGlvbjogWydyZWN0LW1hc2s6bW92ZSddLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAnbWFzazpjaGFuZ2UnLFxuICAgICAgICAgICAgYWN0aW9uOiBbJ2VsZW1lbnQtcmFuZ2UtaGlnaGxpZ2h0OmhpZ2hsaWdodCddLFxuICAgICAgICB9LFxuICAgIF0sXG4gICAgZW5kOiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6bW91c2V1cCcsIGFjdGlvbjogWydyZWN0LW1hc2s6ZW5kJ10gfSxcbiAgICAgICAgeyB0cmlnZ2VyOiAnbWFzazpkcmFnZW5kJywgYWN0aW9uOiBbJ3JlY3QtbWFzazptb3ZlRW5kJ10gfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ2RvY3VtZW50Om1vdXNldXAnLFxuICAgICAgICAgICAgaXNFbmFibGU6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICFjb250ZXh0LmlzSW5QbG90KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0aW9uOiBbJ2VsZW1lbnQtcmFuZ2UtaGlnaGxpZ2h0OmNsZWFyJywgJ3JlY3QtbWFzazplbmQnLCAncmVjdC1tYXNrOmhpZGUnXSxcbiAgICAgICAgfSxcbiAgICBdLFxuICAgIHJvbGxiYWNrOiBbeyB0cmlnZ2VyOiAnZGJsY2xpY2snLCBhY3Rpb246IFsnZWxlbWVudC1yYW5nZS1oaWdobGlnaHQ6Y2xlYXInLCAncmVjdC1tYXNrOmhpZGUnXSB9XSxcbn0pO1xuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdicnVzaCcsIHtcbiAgICBzaG93RW5hYmxlOiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6bW91c2VlbnRlcicsIGFjdGlvbjogJ2N1cnNvcjpjcm9zc2hhaXInIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6bW91c2VsZWF2ZScsIGFjdGlvbjogJ2N1cnNvcjpkZWZhdWx0JyB9LFxuICAgIF0sXG4gICAgc3RhcnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ21vdXNlZG93bicsXG4gICAgICAgICAgICBpc0VuYWJsZTogaXNQb2ludEluVmlldyxcbiAgICAgICAgICAgIGFjdGlvbjogWydicnVzaDpzdGFydCcsICdyZWN0LW1hc2s6c3RhcnQnLCAncmVjdC1tYXNrOnNob3cnXSxcbiAgICAgICAgfSxcbiAgICBdLFxuICAgIHByb2Nlc3Npbmc6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ21vdXNlbW92ZScsXG4gICAgICAgICAgICBpc0VuYWJsZTogaXNQb2ludEluVmlldyxcbiAgICAgICAgICAgIGFjdGlvbjogWydyZWN0LW1hc2s6cmVzaXplJ10sXG4gICAgICAgIH0sXG4gICAgXSxcbiAgICBlbmQ6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ21vdXNldXAnLFxuICAgICAgICAgICAgaXNFbmFibGU6IGlzUG9pbnRJblZpZXcsXG4gICAgICAgICAgICBhY3Rpb246IFsnYnJ1c2g6ZmlsdGVyJywgJ2JydXNoOmVuZCcsICdyZWN0LW1hc2s6ZW5kJywgJ3JlY3QtbWFzazpoaWRlJywgJ3Jlc2V0LWJ1dHRvbjpzaG93J10sXG4gICAgICAgIH0sXG4gICAgXSxcbiAgICByb2xsYmFjazogW3sgdHJpZ2dlcjogJ3Jlc2V0LWJ1dHRvbjpjbGljaycsIGFjdGlvbjogWydicnVzaDpyZXNldCcsICdyZXNldC1idXR0b246aGlkZScsICdjdXJzb3I6Y3Jvc3NoYWlyJ10gfV0sXG59KTtcbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignYnJ1c2gtdmlzaWJsZScsIHtcbiAgICBzaG93RW5hYmxlOiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6bW91c2VlbnRlcicsIGFjdGlvbjogJ2N1cnNvcjpjcm9zc2hhaXInIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ3Bsb3Q6bW91c2VsZWF2ZScsIGFjdGlvbjogJ2N1cnNvcjpkZWZhdWx0JyB9LFxuICAgIF0sXG4gICAgc3RhcnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ3Bsb3Q6bW91c2Vkb3duJyxcbiAgICAgICAgICAgIGFjdGlvbjogWydyZWN0LW1hc2s6c3RhcnQnLCAncmVjdC1tYXNrOnNob3cnXSxcbiAgICAgICAgfSxcbiAgICBdLFxuICAgIHByb2Nlc3Npbmc6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ3Bsb3Q6bW91c2Vtb3ZlJyxcbiAgICAgICAgICAgIGFjdGlvbjogWydyZWN0LW1hc2s6cmVzaXplJ10sXG4gICAgICAgIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ21hc2s6Y2hhbmdlJywgYWN0aW9uOiBbJ2VsZW1lbnQtcmFuZ2UtaGlnaGxpZ2h0OmhpZ2hsaWdodCddIH0sXG4gICAgXSxcbiAgICBlbmQ6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ3Bsb3Q6bW91c2V1cCcsXG4gICAgICAgICAgICBhY3Rpb246IFsncmVjdC1tYXNrOmVuZCcsICdyZWN0LW1hc2s6aGlkZScsICdlbGVtZW50LWZpbHRlcjpmaWx0ZXInLCAnZWxlbWVudC1yYW5nZS1oaWdobGlnaHQ6Y2xlYXInXSxcbiAgICAgICAgfSxcbiAgICBdLFxuICAgIHJvbGxiYWNrOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyaWdnZXI6ICdkYmxjbGljaycsXG4gICAgICAgICAgICBhY3Rpb246IFsnZWxlbWVudC1maWx0ZXI6Y2xlYXInXSxcbiAgICAgICAgfSxcbiAgICBdLFxufSk7XG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ2JydXNoLXgnLCB7XG4gICAgc2hvd0VuYWJsZTogW1xuICAgICAgICB7IHRyaWdnZXI6ICdwbG90Om1vdXNlZW50ZXInLCBhY3Rpb246ICdjdXJzb3I6Y3Jvc3NoYWlyJyB9LFxuICAgICAgICB7IHRyaWdnZXI6ICdwbG90Om1vdXNlbGVhdmUnLCBhY3Rpb246ICdjdXJzb3I6ZGVmYXVsdCcgfSxcbiAgICBdLFxuICAgIHN0YXJ0OiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyaWdnZXI6ICdtb3VzZWRvd24nLFxuICAgICAgICAgICAgaXNFbmFibGU6IGlzUG9pbnRJblZpZXcsXG4gICAgICAgICAgICBhY3Rpb246IFsnYnJ1c2gteDpzdGFydCcsICd4LXJlY3QtbWFzazpzdGFydCcsICd4LXJlY3QtbWFzazpzaG93J10sXG4gICAgICAgIH0sXG4gICAgXSxcbiAgICBwcm9jZXNzaW5nOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyaWdnZXI6ICdtb3VzZW1vdmUnLFxuICAgICAgICAgICAgaXNFbmFibGU6IGlzUG9pbnRJblZpZXcsXG4gICAgICAgICAgICBhY3Rpb246IFsneC1yZWN0LW1hc2s6cmVzaXplJ10sXG4gICAgICAgIH0sXG4gICAgXSxcbiAgICBlbmQ6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ21vdXNldXAnLFxuICAgICAgICAgICAgaXNFbmFibGU6IGlzUG9pbnRJblZpZXcsXG4gICAgICAgICAgICBhY3Rpb246IFsnYnJ1c2gteDpmaWx0ZXInLCAnYnJ1c2gteDplbmQnLCAneC1yZWN0LW1hc2s6ZW5kJywgJ3gtcmVjdC1tYXNrOmhpZGUnXSxcbiAgICAgICAgfSxcbiAgICBdLFxuICAgIHJvbGxiYWNrOiBbeyB0cmlnZ2VyOiAnZGJsY2xpY2snLCBhY3Rpb246IFsnYnJ1c2gteDpyZXNldCddIH1dLFxufSk7XG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ2VsZW1lbnQtcGF0aC1oaWdobGlnaHQnLCB7XG4gICAgc2hvd0VuYWJsZTogW1xuICAgICAgICB7IHRyaWdnZXI6ICdwbG90Om1vdXNlZW50ZXInLCBhY3Rpb246ICdjdXJzb3I6Y3Jvc3NoYWlyJyB9LFxuICAgICAgICB7IHRyaWdnZXI6ICdwbG90Om1vdXNlbGVhdmUnLCBhY3Rpb246ICdjdXJzb3I6ZGVmYXVsdCcgfSxcbiAgICBdLFxuICAgIHN0YXJ0OiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ21vdXNlZG93bicsIGlzRW5hYmxlOiBpc1BvaW50SW5WaWV3LCBhY3Rpb246ICdwYXRoLW1hc2s6c3RhcnQnIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ21vdXNlZG93bicsIGlzRW5hYmxlOiBpc1BvaW50SW5WaWV3LCBhY3Rpb246ICdwYXRoLW1hc2s6c2hvdycgfSxcbiAgICBdLFxuICAgIHByb2Nlc3Npbmc6IFt7IHRyaWdnZXI6ICdtb3VzZW1vdmUnLCBhY3Rpb246ICdwYXRoLW1hc2s6YWRkUG9pbnQnIH1dLFxuICAgIGVuZDogW3sgdHJpZ2dlcjogJ21vdXNldXAnLCBhY3Rpb246ICdwYXRoLW1hc2s6ZW5kJyB9XSxcbiAgICByb2xsYmFjazogW3sgdHJpZ2dlcjogJ2RibGNsaWNrJywgYWN0aW9uOiAncGF0aC1tYXNrOmhpZGUnIH1dLFxufSk7XG4vLyDngrnlh7vpgInkuK3vvIzlhYHorrjlj5bmtohcbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignZWxlbWVudC1zaW5nbGUtc2VsZWN0ZWQnLCB7XG4gICAgc3RhcnQ6IFt7IHRyaWdnZXI6ICdlbGVtZW50OmNsaWNrJywgYWN0aW9uOiAnZWxlbWVudC1zaW5nbGUtc2VsZWN0ZWQ6dG9nZ2xlJyB9XSxcbn0pO1xuLy8g562b6YCJ5pWw5o2uXG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ2xlZ2VuZC1maWx0ZXInLCB7XG4gICAgc2hvd0VuYWJsZTogW1xuICAgICAgICB7IHRyaWdnZXI6ICdsZWdlbmQtaXRlbTptb3VzZWVudGVyJywgYWN0aW9uOiAnY3Vyc29yOnBvaW50ZXInIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogJ2xlZ2VuZC1pdGVtOm1vdXNlbGVhdmUnLCBhY3Rpb246ICdjdXJzb3I6ZGVmYXVsdCcgfSxcbiAgICBdLFxuICAgIHN0YXJ0OiBbeyB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW06Y2xpY2snLCBhY3Rpb246IFsnbGlzdC11bmNoZWNrZWQ6dG9nZ2xlJywgJ2RhdGEtZmlsdGVyOmZpbHRlciddIH1dLFxufSk7XG4vLyDnrZvpgInmlbDmja5cbmNvcmVfMTAucmVnaXN0ZXJJbnRlcmFjdGlvbignY29udGludW91cy1maWx0ZXInLCB7XG4gICAgc3RhcnQ6IFt7IHRyaWdnZXI6ICdsZWdlbmQ6dmFsdWVjaGFuZ2VkJywgYWN0aW9uOiAnZGF0YS1maWx0ZXI6ZmlsdGVyJyB9XSxcbn0pO1xuLy8g562b6YCJ5pWw5o2uXG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ2NvbnRpbnVvdXMtdmlzaWJsZS1maWx0ZXInLCB7XG4gICAgc3RhcnQ6IFt7IHRyaWdnZXI6ICdsZWdlbmQ6dmFsdWVjaGFuZ2VkJywgYWN0aW9uOiAnZWxlbWVudC1maWx0ZXI6ZmlsdGVyJyB9XSxcbn0pO1xuLy8g562b6YCJ5Zu+5b2iXG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ2xlZ2VuZC12aXNpYmxlLWZpbHRlcicsIHtcbiAgICBzaG93RW5hYmxlOiBbXG4gICAgICAgIHsgdHJpZ2dlcjogJ2xlZ2VuZC1pdGVtOm1vdXNlZW50ZXInLCBhY3Rpb246ICdjdXJzb3I6cG9pbnRlcicgfSxcbiAgICAgICAgeyB0cmlnZ2VyOiAnbGVnZW5kLWl0ZW06bW91c2VsZWF2ZScsIGFjdGlvbjogJ2N1cnNvcjpkZWZhdWx0JyB9LFxuICAgIF0sXG4gICAgc3RhcnQ6IFt7IHRyaWdnZXI6ICdsZWdlbmQtaXRlbTpjbGljaycsIGFjdGlvbjogWydsaXN0LXVuY2hlY2tlZDp0b2dnbGUnLCAnZWxlbWVudC1maWx0ZXI6ZmlsdGVyJ10gfV0sXG59KTtcbi8vIOWHuueOsOiDjOaZr+ahhlxuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdhY3RpdmUtcmVnaW9uJywge1xuICAgIHN0YXJ0OiBbeyB0cmlnZ2VyOiAncGxvdDptb3VzZW1vdmUnLCBhY3Rpb246ICdhY3RpdmUtcmVnaW9uOnNob3cnIH1dLFxuICAgIGVuZDogW3sgdHJpZ2dlcjogJ3Bsb3Q6bW91c2VsZWF2ZScsIGFjdGlvbjogJ2FjdGl2ZS1yZWdpb246aGlkZScgfV0sXG59KTtcbmZ1bmN0aW9uIGlzV2hlZWxEb3duKGV2ZW50KSB7XG4gICAgZXZlbnQuZ0V2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgcmV0dXJuIGV2ZW50LmdFdmVudC5vcmlnaW5hbEV2ZW50LmRlbHRhWSA+IDA7XG59XG5jb3JlXzEwLnJlZ2lzdGVySW50ZXJhY3Rpb24oJ3ZpZXctem9vbScsIHtcbiAgICBzdGFydDogW1xuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAncGxvdDptb3VzZXdoZWVsJyxcbiAgICAgICAgICAgIGlzRW5hYmxlOiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1doZWVsRG93bihjb250ZXh0LmV2ZW50KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3Rpb246ICdzY2FsZS16b29tOnpvb21PdXQnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogMTAwLCBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2UgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ3Bsb3Q6bW91c2V3aGVlbCcsXG4gICAgICAgICAgICBpc0VuYWJsZTogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIWlzV2hlZWxEb3duKGNvbnRleHQuZXZlbnQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdGlvbjogJ3NjYWxlLXpvb206em9vbUluJyxcbiAgICAgICAgICAgIHRocm90dGxlOiB7IHdhaXQ6IDEwMCwgbGVhZGluZzogdHJ1ZSwgdHJhaWxpbmc6IGZhbHNlIH0sXG4gICAgICAgIH0sXG4gICAgXSxcbn0pO1xuY29yZV8xMC5yZWdpc3RlckludGVyYWN0aW9uKCdzaWJsaW5nLXRvb2x0aXAnLCB7XG4gICAgc3RhcnQ6IFt7IHRyaWdnZXI6ICdwbG90Om1vdXNlbW92ZScsIGFjdGlvbjogJ3NpYmxpbmctdG9vbHRpcDpzaG93JyB9XSxcbiAgICBlbmQ6IFt7IHRyaWdnZXI6ICdwbG90Om1vdXNlbGVhdmUnLCBhY3Rpb246ICdzaWJsaW5nLXRvb2x0aXA6aGlkZScgfV0sXG59KTtcbnRzbGliXzEuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvcmVcIiksIGV4cG9ydHMpO1xuLy8g5LiA5Lqb5bel5YW35pa55rOV5a+85Ye6XG52YXIgZ3JhcGhpY3NfMSA9IHJlcXVpcmUoXCIuL3V0aWwvZ3JhcGhpY3NcIik7XG52YXIgdHJhbnNmb3JtXzEgPSByZXF1aXJlKFwiLi91dGlsL3RyYW5zZm9ybVwiKTtcbmV4cG9ydHMuVXRpbCA9IHtcbiAgICB0cmFuc2xhdGU6IHRyYW5zZm9ybV8xLnRyYW5zbGF0ZSxcbiAgICByb3RhdGU6IHRyYW5zZm9ybV8xLnJvdGF0ZSxcbiAgICB6b29tOiB0cmFuc2Zvcm1fMS56b29tLFxuICAgIHRyYW5zZm9ybTogdHJhbnNmb3JtXzEudHJhbnNmb3JtLFxuICAgIGdldEFuZ2xlOiBncmFwaGljc18xLmdldEFuZ2xlLFxuICAgIHBvbGFyVG9DYXJ0ZXNpYW46IGdyYXBoaWNzXzEucG9sYXJUb0NhcnRlc2lhbixcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdyYXBoaWNzXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ncmFwaGljc1wiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbi8qKlxuICog6IOM5pmv5qGG55qEIEFjdGlvblxuICogQGlnbm9yZVxuICovXG52YXIgQWN0aXZlUmVnaW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEFjdGl2ZVJlZ2lvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBY3RpdmVSZWdpb24oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5pi+56S6XG4gICAgICovXG4gICAgQWN0aXZlUmVnaW9uLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgZXYgPSB0aGlzLmNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHZhciB0b29sdGlwSXRlbXMgPSB2aWV3LmdldFRvb2x0aXBJdGVtcyh7XG4gICAgICAgICAgICB4OiBldi54LFxuICAgICAgICAgICAgeTogZXYueSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh1dGlsXzEuaXNFcXVhbCh0b29sdGlwSXRlbXMsIHRoaXMuaXRlbXMpKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzmi77lj5bmlbDmja7lkIzkuIrmrKHnm7jlkIzvvIzliJnkuI3ph43lpI3nu5jliLZcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLml0ZW1zID0gdG9vbHRpcEl0ZW1zO1xuICAgICAgICBpZiAodG9vbHRpcEl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIHhGaWVsZF8xID0gdmlldy5nZXRYU2NhbGUoKS5maWVsZDtcbiAgICAgICAgICAgIHZhciB4VmFsdWVfMSA9IHRvb2x0aXBJdGVtc1swXS5kYXRhW3hGaWVsZF8xXTtcbiAgICAgICAgICAgIC8vIOagueaNriB4IOWvueW6lOeahOWAvOafpeaJviBlbGVtZW50c1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRzXzEgPSBbXTtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyaWVzID0gdmlldy5nZW9tZXRyaWVzO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgICAgICAgICAgICAgaWYgKGdlb21ldHJ5LnR5cGUgPT09ICdpbnRlcnZhbCcgfHwgZ2VvbWV0cnkudHlwZSA9PT0gJ3NjaGVtYScpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGdlb21ldHJ5LmdldEVsZW1lbnRzQnkoZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZURhdGEgPSBlbGUuZ2V0RGF0YSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZURhdGFbeEZpZWxkXzFdID09PSB4VmFsdWVfMTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzXzEgPSBlbGVtZW50c18xLmNvbmNhdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8g5qC55o2uIGJib3gg6K6h566X6IOM5pmv5qGG55qE6Z2i56ev5Yy65Z+fXG4gICAgICAgICAgICBpZiAoZWxlbWVudHNfMS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZV8xID0gdmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgICAgICAgICAgdmFyIGZpcnN0QkJveF8xID0gZWxlbWVudHNfMVswXS5zaGFwZS5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgICAgICAgICAgdmFyIGxhc3RCQm94XzEgPSBlbGVtZW50c18xWzBdLnNoYXBlLmdldENhbnZhc0JCb3goKTtcbiAgICAgICAgICAgICAgICB2YXIgZ3JvdXBCQm94XzEgPSBmaXJzdEJCb3hfMTtcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50c18xLCBmdW5jdGlvbiAoZWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBiYm94ID0gZWxlLnNoYXBlLmdldENhbnZhc0JCb3goKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVfMS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYm94Lm1pblkgPCBmaXJzdEJCb3hfMS5taW5ZKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RCQm94XzEgPSBiYm94O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJib3gubWF4WSA+IGxhc3RCQm94XzEubWF4WSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RCQm94XzEgPSBiYm94O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJib3gubWluWCA8IGZpcnN0QkJveF8xLm1pblgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdEJCb3hfMSA9IGJib3g7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmJveC5tYXhYID4gbGFzdEJCb3hfMS5tYXhYKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEJCb3hfMSA9IGJib3g7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBCQm94XzEueCA9IE1hdGgubWluKGJib3gubWluWCwgZ3JvdXBCQm94XzEubWluWCk7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwQkJveF8xLnkgPSBNYXRoLm1pbihiYm94Lm1pblksIGdyb3VwQkJveF8xLm1pblkpO1xuICAgICAgICAgICAgICAgICAgICBncm91cEJCb3hfMS53aWR0aCA9IE1hdGgubWF4KGJib3gubWF4WCwgZ3JvdXBCQm94XzEubWF4WCkgLSBncm91cEJCb3hfMS54O1xuICAgICAgICAgICAgICAgICAgICBncm91cEJCb3hfMS5oZWlnaHQgPSBNYXRoLm1heChiYm94Lm1heFksIGdyb3VwQkJveF8xLm1heFkpIC0gZ3JvdXBCQm94XzEueTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2YXIgYmFja2dyb3VuZEdyb3VwID0gdmlldy5iYWNrZ3JvdW5kR3JvdXAsIGNvb3JkaW5hdGVCQm94ID0gdmlldy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aCA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZV8xLmlzUmVjdCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgeFNjYWxlID0gdmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGVuZFJhdGlvID0geFNjYWxlLmlzTGluZWFyID8gMCA6IDAuMjU7IC8vIOWmguaenCB4IOi9tOaYr+aVsOWAvOexu+Wei++8jOWmguebtOaWueWbvu+8jOS4jemcgOimgeWutumineWklueahOWuveW6plxuICAgICAgICAgICAgICAgICAgICB2YXIgbWluWCA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1pblkgPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aCA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodCA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVfMS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pblggPSBjb29yZGluYXRlQkJveC5taW5YO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWSA9IE1hdGgubWluKGxhc3RCQm94XzEubWluWSwgZmlyc3RCQm94XzEubWluWSkgLSBhcHBlbmRSYXRpbyAqIGxhc3RCQm94XzEuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBjb29yZGluYXRlQkJveC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IGdyb3VwQkJveF8xLmhlaWdodCArIGFwcGVuZFJhdGlvICogMiAqIGxhc3RCQm94XzEuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWCA9IE1hdGgubWluKGZpcnN0QkJveF8xLm1pblgsIGxhc3RCQm94XzEubWluWCkgLSBhcHBlbmRSYXRpbyAqIGZpcnN0QkJveF8xLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWSA9IE1hdGgubWluKGNvb3JkaW5hdGVCQm94Lm1pblksIGZpcnN0QkJveF8xLm1pblkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBncm91cEJCb3hfMS53aWR0aCArIGFwcGVuZFJhdGlvICogMiAqIGZpcnN0QkJveF8xLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gY29vcmRpbmF0ZUJCb3guaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHBhdGggPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCBtaW5YLCBtaW5ZXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIG1pblggKyB3aWR0aCwgbWluWV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBtaW5YICsgd2lkdGgsIG1pblkgKyBoZWlnaHRdLFxuICAgICAgICAgICAgICAgICAgICAgICAgWydMJywgbWluWCwgbWluWSArIGhlaWdodF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ1onXSxcbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmaXJzdEVsZW1lbnQgPSB1dGlsXzEuaGVhZChlbGVtZW50c18xKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RFbGVtZW50ID0gdXRpbF8xLmxhc3QoZWxlbWVudHNfMSk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGFydEFuZ2xlID0gZ3JhcGhpY3NfMS5nZXRBbmdsZShmaXJzdEVsZW1lbnQuZ2V0TW9kZWwoKSwgY29vcmRpbmF0ZV8xKS5zdGFydEFuZ2xlO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZW5kQW5nbGUgPSBncmFwaGljc18xLmdldEFuZ2xlKGxhc3RFbGVtZW50LmdldE1vZGVsKCksIGNvb3JkaW5hdGVfMSkuZW5kQW5nbGU7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlXzEuZ2V0Q2VudGVyKCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciByYWRpdXMgPSBjb29yZGluYXRlXzEuZ2V0UmFkaXVzKCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbm50ZXJSYWRpdXMgPSBjb29yZGluYXRlXzEuaW5uZXJSYWRpdXMgKiByYWRpdXM7XG4gICAgICAgICAgICAgICAgICAgIHBhdGggPSBncmFwaGljc18xLmdldFNlY3RvclBhdGgoY2VudGVyLngsIGNlbnRlci55LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBpbm50ZXJSYWRpdXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZWdpb25QYXRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVnaW9uUGF0aC5hdHRyKCdwYXRoJywgcGF0aCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVnaW9uUGF0aC5zaG93KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZ2lvblBhdGggPSBiYWNrZ3JvdW5kR3JvdXAuYWRkU2hhcGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2FjdGl2ZS1yZWdpb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogJyNDQ0Q2RUMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuMyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZqQ6JePXG4gICAgICovXG4gICAgQWN0aXZlUmVnaW9uLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5yZWdpb25QYXRoKSB7XG4gICAgICAgICAgICB0aGlzLnJlZ2lvblBhdGguaGlkZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoaXMucmVnaW9uUGF0aCA9IG51bGw7XG4gICAgICAgIHRoaXMuaXRlbXMgPSBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZSA5q+BXG4gICAgICovXG4gICAgQWN0aXZlUmVnaW9uLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgaWYgKHRoaXMucmVnaW9uUGF0aCkge1xuICAgICAgICAgICAgdGhpcy5yZWdpb25QYXRoLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIHJldHVybiBBY3RpdmVSZWdpb247XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBY3RpdmVSZWdpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hY3RpdmUtcmVnaW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBBY3Rpb24g55qE5Z+657G7XG4gKi9cbnZhciBBY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQWN0aW9uKGNvbnRleHQsIGNmZykge1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0aGlzLmNmZyA9IGNmZztcbiAgICAgICAgY29udGV4dC5hZGRBY3Rpb24odGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOiuvue9rumFjee9rumhueS8oOWFpeeahOWAvFxuICAgICAqIEBwYXJhbSBjZmdcbiAgICAgKi9cbiAgICBBY3Rpb24ucHJvdG90eXBlLmFwcGx5Q2ZnID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB1dGlsXzEuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBJbml0cyBhY3Rpb27vvIzmj5Dkvpvnu5nlrZDnsbvnlKjkuo7nu6fmib9cbiAgICAgKi9cbiAgICBBY3Rpb24ucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYXBwbHlDZmcodGhpcy5jZmcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogRGVzdHJveXMgYWN0aW9uXG4gICAgICovXG4gICAgQWN0aW9uLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDnp7vpmaQgYWN0aW9uXG4gICAgICAgIHRoaXMuY29udGV4dC5yZW1vdmVBY3Rpb24odGhpcyk7XG4gICAgICAgIC8vIOa4heepulxuICAgICAgICB0aGlzLmNvbnRleHQgPSBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIEFjdGlvbjtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBY3Rpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG4vKiog5Zue6LCD5Ye95pWw5p6E5bu655qEIEFjdGlvbiAqL1xudmFyIENhbGxiYWNrQWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENhbGxiYWNrQWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENhbGxiYWNrQWN0aW9uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOaJp+ihjFxuICAgICAqL1xuICAgIENhbGxiYWNrQWN0aW9uLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jYWxsYmFjaykge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aGlzLmNvbnRleHQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDplIDmr4FcbiAgICAgKi9cbiAgICBDYWxsYmFja0FjdGlvbi5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIENhbGxiYWNrQWN0aW9uO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2FsbGJhY2tBY3Rpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jYWxsYmFjay5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGxpc3Rfc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xpc3Qtc3RhdGVcIikpO1xuLyoqXG4gKiDliJfooajpobnvvIjlm77kvovpobnjgIHlnZDmoIfovbTmlofmnKzvvInmv4DmtLvnmoQgQWN0aW9uXG4gKiBAY2xhc3NcbiAqIEBpZ25vcmVcbiAqL1xudmFyIExpc3RBY3RpdmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTGlzdEFjdGl2ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaXN0QWN0aXZlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc3RhdGVOYW1lID0gJ2FjdGl2ZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5r+A5rS76YCJ6aG5XG4gICAgICovXG4gICAgTGlzdEFjdGl2ZS5wcm90b3R5cGUuYWN0aXZlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKCk7XG4gICAgfTtcbiAgICByZXR1cm4gTGlzdEFjdGl2ZTtcbn0obGlzdF9zdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpc3RBY3RpdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saXN0LWFjdGl2ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuY2xlYXJMaXN0ID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIFNUQVRVU19VTkFDVElWRSA9ICdpbmFjdGl2ZSc7XG52YXIgU1RBVFVTX0FDVElWRSA9ICdhY3RpdmUnO1xuLyoqXG4gKiDmuIXnkIblm77kvovnmoQgSGlnaGxpZ2h0IOaViOaenFxuICogQHBhcmFtIGxpc3Qg5YiX6KGo57uE5Lu277yM5Zu+5L6L5oiW6ICF5Z2Q5qCH6L20XG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGNsZWFyTGlzdChsaXN0KSB7XG4gICAgdmFyIGl0ZW1zID0gbGlzdC5nZXRJdGVtcygpO1xuICAgIHV0aWxfMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICBpZiAobGlzdC5oYXNTdGF0ZShpdGVtLCBTVEFUVVNfQUNUSVZFKSkge1xuICAgICAgICAgICAgbGlzdC5zZXRJdGVtU3RhdGUoaXRlbSwgU1RBVFVTX0FDVElWRSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaXN0Lmhhc1N0YXRlKGl0ZW0sIFNUQVRVU19VTkFDVElWRSkpIHtcbiAgICAgICAgICAgIGxpc3Quc2V0SXRlbVN0YXRlKGl0ZW0sIFNUQVRVU19VTkFDVElWRSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnRzLmNsZWFyTGlzdCA9IGNsZWFyTGlzdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpc3QtaGlnaGxpZ2h0LXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBsaXN0X2hpZ2hsaWdodF91dGlsXzEgPSByZXF1aXJlKFwiLi9saXN0LWhpZ2hsaWdodC11dGlsXCIpO1xudmFyIGxpc3Rfc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xpc3Qtc3RhdGVcIikpO1xudmFyIFNUQVRVU19VTkFDVElWRSA9ICdpbmFjdGl2ZSc7XG52YXIgU1RBVFVTX0FDVElWRSA9ICdhY3RpdmUnO1xuLyoqXG4gKiBoaWdobGlnaHQgQWN0aW9uIOeahOaViOaenOaYryBhY3RpdmUg5ZKMIGluYWN0aXZlIOS4pOS4queKtuaAgeeahOe7hOWQiFxuICogQGNsYXNzXG4gKiBAaWdub3JlXG4gKi9cbnZhciBMaXN0SGlnaGxpZ2h0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpc3RIaWdobGlnaHQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGlzdEhpZ2hsaWdodCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnN0YXRlTmFtZSA9IFNUQVRVU19BQ1RJVkU7XG4gICAgICAgIF90aGlzLmlnbm9yZUl0ZW1TdGF0ZXMgPSBbJ3VuY2hlY2tlZCddOyAvLyDlvZPlrZjlnKggdW5jaGVja2VkIOeKtuaAgeaXtuS4jeinpuWPkVxuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8vIOWmguaenCBpdGVtLm5hbWUg5Yy56YWN77yM5YiZ6K6+572uIGhpZ2hsaWdodCDku6Xlj4rlj5bmtohcbiAgICBMaXN0SGlnaGxpZ2h0LnByb3RvdHlwZS5zZXRJdGVtc1N0YXRlID0gZnVuY3Rpb24gKGxpc3QsIG5hbWUsIGVuYWJsZSkge1xuICAgICAgICB0aGlzLnNldEhpZ2hsaWdodEJ5KGxpc3QsIGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtLm5hbWUgPT09IG5hbWU7IH0sIGVuYWJsZSk7XG4gICAgfTtcbiAgICAvLyDljZXkuKogaXRlbSDorr7nva7nirbmgIFcbiAgICBMaXN0SGlnaGxpZ2h0LnByb3RvdHlwZS5zZXRJdGVtU3RhdGUgPSBmdW5jdGlvbiAobGlzdCwgaXRlbSwgZW5hYmxlKSB7XG4gICAgICAgIHZhciBpdGVtcyA9IGxpc3QuZ2V0SXRlbXMoKTtcbiAgICAgICAgdGhpcy5zZXRIaWdobGlnaHRCeShsaXN0LCBmdW5jdGlvbiAoZWwpIHsgcmV0dXJuIGVsID09PSBpdGVtOyB9LCBlbmFibGUpO1xuICAgIH07XG4gICAgLy8g5qC55o2u5p2h5Lu26K6+572uIGhpZ2hsaWdodFxuICAgIExpc3RIaWdobGlnaHQucHJvdG90eXBlLnNldEhpZ2hsaWdodEJ5ID0gZnVuY3Rpb24gKGxpc3QsIGNhbGxiYWNrLCBlbmFibGUpIHtcbiAgICAgICAgdmFyIGl0ZW1zID0gbGlzdC5nZXRJdGVtcygpO1xuICAgICAgICBpZiAoZW5hYmxlKSB7XG4gICAgICAgICAgICAvLyDorr7nva4gaGlnaGxpZ2h0IOaXtu+8jOS/neeVmeS5i+WJjeW3sue7jyBIaWdobGlnaHQg55qE6aG5XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChpdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2soaXRlbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3QuaGFzU3RhdGUoaXRlbSwgU1RBVFVTX1VOQUNUSVZFKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5zZXRJdGVtU3RhdGUoaXRlbSwgU1RBVFVTX1VOQUNUSVZFLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGlzdC5zZXRJdGVtU3RhdGUoaXRlbSwgU1RBVFVTX0FDVElWRSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFsaXN0Lmhhc1N0YXRlKGl0ZW0sIFNUQVRVU19BQ1RJVkUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3Quc2V0SXRlbVN0YXRlKGl0ZW0sIFNUQVRVU19VTkFDVElWRSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgYWN0aXZlSXRlbXMgPSBsaXN0LmdldEl0ZW1zQnlTdGF0ZShTVEFUVVNfQUNUSVZFKTtcbiAgICAgICAgICAgIHZhciBhbGxDYW5jZWxfMSA9IHRydWU7XG4gICAgICAgICAgICAvLyDmo4DmtYsgYWN0aXZlSXRlbXMg5piv5ZCm6KaB5YWo6YOo5Y+W5raIXG4gICAgICAgICAgICB1dGlsXzEuZWFjaChhY3RpdmVJdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNhbGxiYWNrKGl0ZW0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsbENhbmNlbF8xID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChhbGxDYW5jZWxfMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOS4jeaYr+mDveimgeWPlua2iCBoaWdobGlnaHQsIOWImeiuvue9ruWMuemFjeeahCBlbGVtZW50IOeahOeKtuaAgeS4uiB1bmFjdGl2ZVxuICAgICAgICAgICAgICAgIC8vIOWFtuS7liBlbGVtZW50IOeKtuaAgeS4jeWPmFxuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2soaXRlbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0Lmhhc1N0YXRlKGl0ZW0sIFNUQVRVU19BQ1RJVkUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5zZXRJdGVtU3RhdGUoaXRlbSwgU1RBVFVTX0FDVElWRSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5zZXRJdGVtU3RhdGUoaXRlbSwgU1RBVFVTX1VOQUNUSVZFLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBoaWdobGlnaHQg5Zu+5L6L6aG577yI5Z2Q5qCH6L205paH5pys77yJXG4gICAgICovXG4gICAgTGlzdEhpZ2hsaWdodC5wcm90b3R5cGUuaGlnaGxpZ2h0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKCk7XG4gICAgfTtcbiAgICAvLyDpnIDopoHlhajpg6jmuIXnkIYgYWN0aXZlIOWSjCB1bmFjdGl2ZVxuICAgIExpc3RIaWdobGlnaHQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdHJpZ2dlckluZm8gPSB0aGlzLmdldFRyaWdnZXJMaXN0SW5mbygpO1xuICAgICAgICBpZiAodHJpZ2dlckluZm8pIHtcbiAgICAgICAgICAgIGxpc3RfaGlnaGxpZ2h0X3V0aWxfMS5jbGVhckxpc3QodHJpZ2dlckluZm8ubGlzdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzkuI3mmK8gY29tcG9uZW50IOeahOS6i+S7tuinpuWPke+8jOWImeaJgOaciea7oei2s+inpuWPkeadoeS7tueahOe7hOS7tumDvea4hemZpOivpeeKtuaAgVxuICAgICAgICAgICAgdmFyIGNvbXBvbmVudHMgPSB0aGlzLmdldEFsbG93Q29tcG9uZW50cygpO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goY29tcG9uZW50cywgZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5jbGVhckl0ZW1zU3RhdGUoU1RBVFVTX0FDVElWRSk7XG4gICAgICAgICAgICAgICAgY29tcG9uZW50LmNsZWFySXRlbXNTdGF0ZShTVEFUVVNfVU5BQ1RJVkUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBMaXN0SGlnaGxpZ2h0O1xufShsaXN0X3N0YXRlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGlzdEhpZ2hsaWdodDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpc3QtaGlnaGxpZ2h0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbGlzdF9zdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGlzdC1zdGF0ZVwiKSk7XG4vKipcbiAqIOWbvuS+i+mhueWSjOWdkOagh+i9tOaWh+acrOmAieS4reeahCBBY3Rpb25cbiAqIEBpZ25vcmVcbiAqL1xudmFyIExpc3RTZWxlY3RlZCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaXN0U2VsZWN0ZWQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGlzdFNlbGVjdGVkKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc3RhdGVOYW1lID0gJ3NlbGVjdGVkJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBMaXN0U2VsZWN0ZWQucHJvdG90eXBlLnNlbGVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKCk7XG4gICAgfTtcbiAgICByZXR1cm4gTGlzdFNlbGVjdGVkO1xufShsaXN0X3N0YXRlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGlzdFNlbGVjdGVkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGlzdC1zZWxlY3RlZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbnZhciB1dGlsXzMgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbi8qKlxuICog5YiX6KGo6aG554q25oCBIEFjdGlvbiDnmoTln7rnoYDnsbtcbiAqIEBjbGFzc1xuICogQGlnbm9yZVxuICovXG52YXIgTGlzdFN0YXRlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpc3RTdGF0ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaXN0U3RhdGUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGF0ZU5hbWUgPSAnJztcbiAgICAgICAgX3RoaXMuaWdub3JlSXRlbVN0YXRlcyA9IFtdO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKiDojrflj5bop6blj5HnmoTliJfooajnu4Tku7YgKi9cbiAgICBMaXN0U3RhdGUucHJvdG90eXBlLmdldFRyaWdnZXJMaXN0SW5mbyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRlbGVnYXRlT2JqZWN0ID0gdXRpbF8zLmdldERlbGVnYXRpb25PYmplY3QodGhpcy5jb250ZXh0KTtcbiAgICAgICAgdmFyIGluZm8gPSBudWxsO1xuICAgICAgICBpZiAodXRpbF8zLmlzTGlzdChkZWxlZ2F0ZU9iamVjdCkpIHtcbiAgICAgICAgICAgIGluZm8gPSB7XG4gICAgICAgICAgICAgICAgaXRlbTogZGVsZWdhdGVPYmplY3QuaXRlbSxcbiAgICAgICAgICAgICAgICBsaXN0OiBkZWxlZ2F0ZU9iamVjdC5jb21wb25lbnQsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbmZvO1xuICAgIH07XG4gICAgLy8g6I635Y+W5omA5pyJ5YWB6K645omn6KGMIEFjdGlvbiDnmoTnu4Tku7ZcbiAgICBMaXN0U3RhdGUucHJvdG90eXBlLmdldEFsbG93Q29tcG9uZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGNvbXBvbmVudHMgPSB1dGlsXzIuZ2V0Q29tcG9uZW50cyh2aWV3KTtcbiAgICAgICAgdmFyIHJzdCA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChjb21wb25lbnRzLCBmdW5jdGlvbiAoY29tcG9uZW50KSB7XG4gICAgICAgICAgICBpZiAoY29tcG9uZW50LmlzTGlzdCgpICYmIF90aGlzLmFsbG93U2V0U3RhdGVCeUVsZW1lbnQoY29tcG9uZW50KSkge1xuICAgICAgICAgICAgICAgIHJzdC5wdXNoKGNvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH07XG4gICAgLyoqIOaYr+WQpuWtmOWcqOaMh+WumueahOeKtuaAgSAqL1xuICAgIExpc3RTdGF0ZS5wcm90b3R5cGUuaGFzU3RhdGUgPSBmdW5jdGlvbiAobGlzdCwgaXRlbSkge1xuICAgICAgICByZXR1cm4gbGlzdC5oYXNTdGF0ZShpdGVtLCB0aGlzLnN0YXRlTmFtZSk7XG4gICAgfTtcbiAgICAvKiog5riF55CG57uE5Lu255qE54q25oCBICovXG4gICAgTGlzdFN0YXRlLnByb3RvdHlwZS5jbGVhckFsbENvbXBvbmVudHNTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNvbXBvbmVudHMgPSB0aGlzLmdldEFsbG93Q29tcG9uZW50cygpO1xuICAgICAgICB1dGlsXzEuZWFjaChjb21wb25lbnRzLCBmdW5jdGlvbiAoY29tcG9uZW50KSB7XG4gICAgICAgICAgICBjb21wb25lbnQuY2xlYXJJdGVtc1N0YXRlKF90aGlzLnN0YXRlTmFtZSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g5LiN5piv5omA5pyJ55qEIGNvbXBvbmVudCDpg73og73ov5vooYwgYWN0aXZl77yM55uu5YmN5LuF5pSv5oyB5YiG57G7IHNjYWxlIOWvueW6lOeahOe7hOS7tlxuICAgIExpc3RTdGF0ZS5wcm90b3R5cGUuYWxsb3dTZXRTdGF0ZUJ5RWxlbWVudCA9IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICAgICAgdmFyIGZpZWxkID0gY29tcG9uZW50LmdldCgnZmllbGQnKTtcbiAgICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNmZyAmJiB0aGlzLmNmZy5jb21wb25lbnROYW1lcykge1xuICAgICAgICAgICAgdmFyIG5hbWVfMSA9IGNvbXBvbmVudC5nZXQoJ25hbWUnKTtcbiAgICAgICAgICAgIC8vIOWmguaenOmFjee9ruS6humZkOWItueahCBjb21wb25lbnQgbmFtZe+8jOWImeimgei/m+ihjOajgOa1i1xuICAgICAgICAgICAgaWYgKHRoaXMuY2ZnLmNvbXBvbmVudE5hbWVzLmluZGV4T2YobmFtZV8xKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIHNjYWxlID0gdXRpbF8zLmdldFNjYWxlQnlGaWVsZCh2aWV3LCBmaWVsZCk7XG4gICAgICAgIHJldHVybiBzY2FsZSAmJiBzY2FsZS5pc0NhdGVnb3J5O1xuICAgIH07XG4gICAgLy8g5qOA5rWL5piv5ZCm5YWB6K646Kem5Y+R5a+55bqU55qE54q25oCB5pS55Y+Y5LqL5Lu2XG4gICAgTGlzdFN0YXRlLnByb3RvdHlwZS5hbGxvd1NldFN0YXRlQnlJdGVtID0gZnVuY3Rpb24gKGl0ZW0sIGxpc3QpIHtcbiAgICAgICAgdmFyIGlnbm9yZVN0YXRlcyA9IHRoaXMuaWdub3JlSXRlbVN0YXRlcztcbiAgICAgICAgaWYgKGlnbm9yZVN0YXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBmaWx0ZXJTdGF0ZXMgPSBpZ25vcmVTdGF0ZXMuZmlsdGVyKGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsaXN0Lmhhc1N0YXRlKGl0ZW0sIHN0YXRlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGZpbHRlclN0YXRlcy5sZW5ndGggPT09IDA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7IC8vIOayoeacieWumuS5ieW/veeVpeeahOeKtuaAgeaXtu+8jOWFgeiuuFxuICAgIH07XG4gICAgLy8g6K6+572u57uE5Lu255qEIGl0ZW0gYWN0aXZlXG4gICAgTGlzdFN0YXRlLnByb3RvdHlwZS5zZXRTdGF0ZUJ5RWxlbWVudCA9IGZ1bmN0aW9uIChjb21wb25lbnQsIGVsZW1lbnQsIGVuYWJsZSkge1xuICAgICAgICB2YXIgZmllbGQgPSBjb21wb25lbnQuZ2V0KCdmaWVsZCcpO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgc2NhbGUgPSB1dGlsXzMuZ2V0U2NhbGVCeUZpZWxkKHZpZXcsIGZpZWxkKTtcbiAgICAgICAgdmFyIHZhbHVlID0gdXRpbF8zLmdldEVsZW1lbnRWYWx1ZShlbGVtZW50LCBmaWVsZCk7XG4gICAgICAgIHZhciB0ZXh0ID0gc2NhbGUuZ2V0VGV4dCh2YWx1ZSk7XG4gICAgICAgIHRoaXMuc2V0SXRlbXNTdGF0ZShjb21wb25lbnQsIHRleHQsIGVuYWJsZSk7XG4gICAgfTtcbiAgICAvLyDorr7nva7nirbmgIFcbiAgICBMaXN0U3RhdGUucHJvdG90eXBlLnNldFN0YXRlRW5hYmxlID0gZnVuY3Rpb24gKGVuYWJsZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZWxlbWVudCA9IHV0aWxfMy5nZXRDdXJyZW50RWxlbWVudCh0aGlzLmNvbnRleHQpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgLy8gdHJpZ2dlciBieSBlbGVtZW50XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50cyA9IHRoaXMuZ2V0QWxsb3dDb21wb25lbnRzKCk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChjb21wb25lbnRzLCBmdW5jdGlvbiAoY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGVCeUVsZW1lbnQoY29tcG9uZW50LCBlbGVtZW50LCBlbmFibGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyDooqvnu4Tku7bop6blj5FcbiAgICAgICAgICAgIHZhciBkZWxlZ2F0ZU9iamVjdCA9IHV0aWxfMy5nZXREZWxlZ2F0aW9uT2JqZWN0KHRoaXMuY29udGV4dCk7XG4gICAgICAgICAgICBpZiAodXRpbF8zLmlzTGlzdChkZWxlZ2F0ZU9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGRlbGVnYXRlT2JqZWN0Lml0ZW0sIGNvbXBvbmVudCA9IGRlbGVnYXRlT2JqZWN0LmNvbXBvbmVudDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5hbGxvd1NldFN0YXRlQnlFbGVtZW50KGNvbXBvbmVudCkgJiYgdGhpcy5hbGxvd1NldFN0YXRlQnlJdGVtKGl0ZW0sIGNvbXBvbmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRJdGVtU3RhdGUoY29tcG9uZW50LCBpdGVtLCBlbmFibGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8g5aSa5LiqIGl0ZW0g6K6+572u54q25oCBXG4gICAgTGlzdFN0YXRlLnByb3RvdHlwZS5zZXRJdGVtc1N0YXRlID0gZnVuY3Rpb24gKGxpc3QsIG5hbWUsIGVuYWJsZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXRlbXMgPSBsaXN0LmdldEl0ZW1zKCk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgaWYgKGl0ZW0ubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgICAgICAgIF90aGlzLnNldEl0ZW1TdGF0ZShsaXN0LCBpdGVtLCBlbmFibGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOWNleS4qiBpdGVtIOiuvue9rueKtuaAgVxuICAgIExpc3RTdGF0ZS5wcm90b3R5cGUuc2V0SXRlbVN0YXRlID0gZnVuY3Rpb24gKGxpc3QsIGl0ZW0sIGVuYWJsZSkge1xuICAgICAgICBsaXN0LnNldEl0ZW1TdGF0ZShpdGVtLCB0aGlzLnN0YXRlTmFtZSwgZW5hYmxlKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiuvue9rueKtuaAgVxuICAgICAqL1xuICAgIExpc3RTdGF0ZS5wcm90b3R5cGUuc2V0U3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGVFbmFibGUodHJ1ZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlj5bmtojnirbmgIFcbiAgICAgKi9cbiAgICBMaXN0U3RhdGUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlRW5hYmxlKGZhbHNlKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWIh+aNoueKtuaAgVxuICAgICAqL1xuICAgIExpc3RTdGF0ZS5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdHJpZ2dlckluZm8gPSB0aGlzLmdldFRyaWdnZXJMaXN0SW5mbygpO1xuICAgICAgICBpZiAodHJpZ2dlckluZm8gJiYgdHJpZ2dlckluZm8uaXRlbSkge1xuICAgICAgICAgICAgdmFyIGxpc3QgPSB0cmlnZ2VySW5mby5saXN0LCBpdGVtID0gdHJpZ2dlckluZm8uaXRlbTtcbiAgICAgICAgICAgIHZhciBlbmFibGUgPSB0aGlzLmhhc1N0YXRlKGxpc3QsIGl0ZW0pO1xuICAgICAgICAgICAgdGhpcy5zZXRJdGVtU3RhdGUobGlzdCwgaXRlbSwgIWVuYWJsZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWPlua2iOeKtuaAgVxuICAgICAqL1xuICAgIExpc3RTdGF0ZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0cmlnZ2VySW5mbyA9IHRoaXMuZ2V0VHJpZ2dlckxpc3RJbmZvKCk7XG4gICAgICAgIGlmICh0cmlnZ2VySW5mbykge1xuICAgICAgICAgICAgdHJpZ2dlckluZm8ubGlzdC5jbGVhckl0ZW1zU3RhdGUodGhpcy5zdGF0ZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jbGVhckFsbENvbXBvbmVudHNTdGF0ZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gTGlzdFN0YXRlO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGlzdFN0YXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGlzdC1zdGF0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGxpc3Rfc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xpc3Qtc3RhdGVcIikpO1xuLyoqXG4gKiDlm77kvovpobnlj5bmtojli77pgInnmoQgQWN0aW9uXG4gKiBAaWdub3JlXG4gKi9cbnZhciBMaXN0VW5jaGVja2VkID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpc3RVbmNoZWNrZWQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGlzdFVuY2hlY2tlZCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnN0YXRlTmFtZSA9ICd1bmNoZWNrZWQnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOWPlua2iOWLvumAiVxuICAgICAqL1xuICAgIExpc3RVbmNoZWNrZWQucHJvdG90eXBlLnVuY2hlY2tlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgpO1xuICAgIH07XG4gICAgcmV0dXJuIExpc3RVbmNoZWNrZWQ7XG59KGxpc3Rfc3RhdGVfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMaXN0VW5jaGVja2VkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGlzdC11bmNoZWNrZWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZVwiKSk7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG4vKipcbiAqIOeUqOS6jue7hOS7tuaWh+acrOecgeeVpeWQjumcgOimgeWxleekuuWujOaVtOS/oeaBr+eahCBUb29sdGlwIEFjdGlvblxuICogQGlnbm9yZVxuICovXG52YXIgRWxsaXBzaXNUZXh0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEVsbGlwc2lzVGV4dCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBFbGxpcHNpc1RleHQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50aW1lU3RhbXAgPSAwO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEVsbGlwc2lzVGV4dC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMudG9vbHRpcCAmJiB0aGlzLnRvb2x0aXAuZGVzdHJveSgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5pi+56S6IFRvb2x0aXBcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIEVsbGlwc2lzVGV4dC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIHZhciBldiA9IGNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHZhciBsYXN0VGltZVN0YW1wID0gdGhpcy50aW1lU3RhbXA7XG4gICAgICAgIHZhciB0aW1lU3RhbXAgPSArbmV3IERhdGUoKTtcbiAgICAgICAgaWYgKHRpbWVTdGFtcCAtIGxhc3RUaW1lU3RhbXAgPiAxNikge1xuICAgICAgICAgICAgdmFyIHByZUxvYyA9IHRoaXMubG9jYXRpb247XG4gICAgICAgICAgICB2YXIgY3VyTG9jID0geyB4OiBldi54LCB5OiBldi55IH07XG4gICAgICAgICAgICBpZiAoIXByZUxvYyB8fCAhdXRpbF8xLmlzRXF1YWwocHJlTG9jLCBjdXJMb2MpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93VG9vbHRpcChjdXJMb2MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy50aW1lU3RhbXAgPSB0aW1lU3RhbXA7XG4gICAgICAgICAgICB0aGlzLmxvY2F0aW9uID0gY3VyTG9jO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpmpDol48gVG9vbHRpcOOAglxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgRWxsaXBzaXNUZXh0LnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gICAgICAgIHRoaXMubG9jYXRpb24gPSBudWxsO1xuICAgIH07XG4gICAgRWxsaXBzaXNUZXh0LnByb3RvdHlwZS5zaG93VG9vbHRpcCA9IGZ1bmN0aW9uIChjdXJMb2MpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIHZhciBldiA9IGNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHZhciB0YXJnZXQgPSBldi50YXJnZXQ7XG4gICAgICAgIGlmICh0YXJnZXQgJiYgdGFyZ2V0LmdldCgndGlwJykpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy50b29sdGlwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJUb29sdGlwKCk7IC8vIOW7tui/n+eUn+aIkFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHRpcENvbnRlbnQgPSB0YXJnZXQuZ2V0KCd0aXAnKTtcbiAgICAgICAgICAgIC8vIOWxleekuiB0b29sdGlwXG4gICAgICAgICAgICB0aGlzLnRvb2x0aXAudXBkYXRlKHRzbGliXzEuX19hc3NpZ24oeyB0aXRsZTogdGlwQ29udGVudCB9LCBjdXJMb2MpKTtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcC5zaG93KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEVsbGlwc2lzVGV4dC5wcm90b3R5cGUuaGlkZVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMudG9vbHRpcCAmJiB0aGlzLnRvb2x0aXAuaGlkZSgpO1xuICAgIH07XG4gICAgRWxsaXBzaXNUZXh0LnByb3RvdHlwZS5yZW5kZXJUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgY2FudmFzID0gdmlldy5jYW52YXM7XG4gICAgICAgIHZhciByZWdpb24gPSB7XG4gICAgICAgICAgICBzdGFydDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgICAgICBlbmQ6IHsgeDogY2FudmFzLmdldCgnd2lkdGgnKSwgeTogY2FudmFzLmdldCgnaGVpZ2h0JykgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHRoZW1lID0gdmlldy5nZXRUaGVtZSgpO1xuICAgICAgICB2YXIgdG9vbHRpcFN0eWxlcyA9IHV0aWxfMS5nZXQodGhlbWUsIFsnY29tcG9uZW50cycsICd0b29sdGlwJywgJ2RvbVN0eWxlcyddLCB7fSk7IC8vIOiOt+WPliB0b29sdGlwIOagt+W8j1xuICAgICAgICB2YXIgdG9vbHRpcCA9IG5ldyBkZXBlbmRlbnRzXzEuSHRtbFRvb2x0aXAoe1xuICAgICAgICAgICAgcGFyZW50OiBjYW52YXMuZ2V0KCdlbCcpLnBhcmVudE5vZGUsXG4gICAgICAgICAgICByZWdpb246IHJlZ2lvbixcbiAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgY3Jvc3NoYWlyczogbnVsbCxcbiAgICAgICAgICAgIGRvbVN0eWxlczogdG9vbHRpcFN0eWxlcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRvb2x0aXAuaW5pdCgpO1xuICAgICAgICB0b29sdGlwLnNldENhcHR1cmUoZmFsc2UpOyAvLyDkuI3lhYHorrjmjZXojrfkuovku7ZcbiAgICAgICAgdGhpcy50b29sdGlwID0gdG9vbHRpcDtcbiAgICB9O1xuICAgIHJldHVybiBFbGxpcHNpc1RleHQ7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGxpcHNpc1RleHQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbGxpcHNpcy10ZXh0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2VcIikpO1xuLyoqXG4gKiBUb29sdGlwIOWxleekuumakOiXj+eahCBBY3Rpb25cbiAqIEBpZ25vcmVcbiAqL1xudmFyIFRvb2x0aXBBY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVG9vbHRpcEFjdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUb29sdGlwQWN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudGltZVN0YW1wID0gMDtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDmmL7npLogVG9vbHRpcFxuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgVG9vbHRpcEFjdGlvbi5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIHZhciBldiA9IGNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHZhciB2aWV3ID0gY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgaXNUb29sdGlwTG9ja2VkID0gdmlldy5pc1Rvb2x0aXBMb2NrZWQoKTtcbiAgICAgICAgaWYgKGlzVG9vbHRpcExvY2tlZCkge1xuICAgICAgICAgICAgLy8g6ZSB5a6a5pe25LiN56e75YqoIHRvb2x0aXBcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFzdFRpbWVTdGFtcCA9IHRoaXMudGltZVN0YW1wO1xuICAgICAgICB2YXIgdGltZVN0YW1wID0gK25ldyBEYXRlKCk7XG4gICAgICAgIGlmICh0aW1lU3RhbXAgLSBsYXN0VGltZVN0YW1wID4gMTYpIHtcbiAgICAgICAgICAgIHZhciBwcmVMb2MgPSB0aGlzLmxvY2F0aW9uO1xuICAgICAgICAgICAgdmFyIGN1ckxvYyA9IHsgeDogZXYueCwgeTogZXYueSB9O1xuICAgICAgICAgICAgaWYgKCFwcmVMb2MgfHwgIXV0aWxfMS5pc0VxdWFsKHByZUxvYywgY3VyTG9jKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd1Rvb2x0aXAodmlldywgY3VyTG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudGltZVN0YW1wID0gdGltZVN0YW1wO1xuICAgICAgICAgICAgdGhpcy5sb2NhdGlvbiA9IGN1ckxvYztcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZqQ6JePIFRvb2x0aXDjgIJcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIFRvb2x0aXBBY3Rpb24ucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZhciBpc1Rvb2x0aXBMb2NrZWQgPSB2aWV3LmlzVG9vbHRpcExvY2tlZCgpO1xuICAgICAgICBpZiAoaXNUb29sdGlwTG9ja2VkKSB7XG4gICAgICAgICAgICAvLyDplIHlrpogdG9vbHRpcCDml7bkuI3pmpDol49cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhpZGVUb29sdGlwKHZpZXcpO1xuICAgICAgICB0aGlzLmxvY2F0aW9uID0gbnVsbDtcbiAgICB9O1xuICAgIFRvb2x0aXBBY3Rpb24ucHJvdG90eXBlLnNob3dUb29sdGlwID0gZnVuY3Rpb24gKHZpZXcsIHBvaW50KSB7XG4gICAgICAgIC8vIOebuOWQjOS9jee9ruS4jemHjeWkjeWxleekulxuICAgICAgICB2aWV3LnNob3dUb29sdGlwKHBvaW50KTtcbiAgICB9O1xuICAgIFRvb2x0aXBBY3Rpb24ucHJvdG90eXBlLmhpZGVUb29sdGlwID0gZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgdmlldy5oaWRlVG9vbHRpcCgpO1xuICAgIH07XG4gICAgcmV0dXJuIFRvb2x0aXBBY3Rpb247XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUb29sdGlwQWN0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2VvbWV0cnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vLi4vdXRpbFwiKTtcbnZhciBnZW9tZXRyeV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZ2VvbWV0cnlcIikpO1xuLyoqXG4gKiDlrZjlnKjlpJrkuKogdmlldyDml7bvvIzmjqfliLblhbbku5YgdmlldyDkuIrnmoQgdG9vbHRpcCDmmL7npLpcbiAqIEBpZ25vcmVcbiAqL1xudmFyIFNpYmxpbmdUb29sdGlwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFNpYmxpbmdUb29sdGlwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNpYmxpbmdUb29sdGlwKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOaJgOacieWQjOS4gOWxgue6p+eahCB0b29sdGlwIOaYvuekulxuICAgICAqIEBwYXJhbSB2aWV3XG4gICAgICogQHBhcmFtIHBvaW50XG4gICAgICovXG4gICAgU2libGluZ1Rvb2x0aXAucHJvdG90eXBlLnNob3dUb29sdGlwID0gZnVuY3Rpb24gKHZpZXcsIHBvaW50KSB7XG4gICAgICAgIHZhciBzaWJsaW5ncyA9IHV0aWxfMi5nZXRTaWxiaW5ncyh2aWV3KTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2libGluZ3MsIGZ1bmN0aW9uIChzaWJsaW5nKSB7XG4gICAgICAgICAgICB2YXIgc2libGluZ1BvaW50ID0gdXRpbF8yLmdldFNpYmxpbmdQb2ludCh2aWV3LCBzaWJsaW5nLCBwb2ludCk7XG4gICAgICAgICAgICBzaWJsaW5nLnNob3dUb29sdGlwKHNpYmxpbmdQb2ludCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZqQ6JeP5ZCM5LiA5bGC57qn55qEIHRvb2x0aXBcbiAgICAgKiBAcGFyYW0gdmlld1xuICAgICAqL1xuICAgIFNpYmxpbmdUb29sdGlwLnByb3RvdHlwZS5oaWRlVG9vbHRpcCA9IGZ1bmN0aW9uICh2aWV3KSB7XG4gICAgICAgIHZhciBzaWJsaW5ncyA9IHV0aWxfMi5nZXRTaWxiaW5ncyh2aWV3KTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2libGluZ3MsIGZ1bmN0aW9uIChzaWJsaW5nKSB7XG4gICAgICAgICAgICBzaWJsaW5nLmhpZGVUb29sdGlwKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIFNpYmxpbmdUb29sdGlwO1xufShnZW9tZXRyeV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNpYmxpbmdUb29sdGlwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2libGluZy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOiuvue9rueUu+W4g+eahOeureWktO+8jOWPgueci++8mmh0dHBzOi8vd3d3Lnczc2Nob29sLmNvbS5jbi9qc3JlZi9wcm9wX3N0eWxlX2N1cnNvci5hc3BcbiAqIEBhdXRob3IgZHhxNjEzXG4gKi9cbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbi8qKlxuICog6byg5qCH5b2i54q255qEIEFjdGlvblxuICogQGlnbm9yZVxuICovXG52YXIgQ3Vyc29yQWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEN1cnNvckFjdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDdXJzb3JBY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5zZXRDdXJzb3IgPSBmdW5jdGlvbiAoY3Vyc29yKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZpZXcuZ2V0Q2FudmFzKCkuc2V0Q3Vyc29yKGN1cnNvcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpu5jorqTlhYnmoIfvvIjpgJrluLjmmK/kuIDkuKrnrq3lpLTvvIlcbiAgICAgKi9cbiAgICBDdXJzb3JBY3Rpb24ucHJvdG90eXBlLmRlZmF1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0Q3Vyc29yKCdkZWZhdWx0Jyk7XG4gICAgfTtcbiAgICAvKiog5YWJ5qCH5ZGI546w5Li65oyH56S66ZO+5o6l55qE5oyH6ZKI77yI5LiA5Y+q5omL77yJICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5wb2ludGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldEN1cnNvcigncG9pbnRlcicpO1xuICAgIH07XG4gICAgLyoqIOatpOWFieagh+aMh+ekuuafkOWvueixoeWPr+iiq+enu+WKqOOAgiAqL1xuICAgIEN1cnNvckFjdGlvbi5wcm90b3R5cGUubW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ21vdmUnKTtcbiAgICB9O1xuICAgIC8qKiDlhYnmoIflkYjnjrDkuLrljYHlrZfnur/jgIIgKi9cbiAgICBDdXJzb3JBY3Rpb24ucHJvdG90eXBlLmNyb3NzaGFpciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ2Nyb3NzaGFpcicpO1xuICAgIH07XG4gICAgLyoqIOatpOWFieagh+aMh+ekuueoi+W6j+ato+W/me+8iOmAmuW4uOaYr+S4gOWPquihqOaIluaymea8j++8ieOAgiAqL1xuICAgIEN1cnNvckFjdGlvbi5wcm90b3R5cGUud2FpdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ3dhaXQnKTtcbiAgICB9O1xuICAgIC8qKiDmraTlhYnmoIfmjIfnpLrlj6/nlKjnmoTluK7liqnvvIjpgJrluLjmmK/kuIDkuKrpl67lj7fmiJbkuIDkuKrmsJTnkIPvvInjgIIgKi9cbiAgICBDdXJzb3JBY3Rpb24ucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0Q3Vyc29yKCdoZWxwJyk7XG4gICAgfTtcbiAgICAvKiog5q2k5YWJ5qCH5oyH56S65paH5pys44CCICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS50ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldEN1cnNvcigndGV4dCcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5q2k5YWJ5qCH5oyH56S655+p5b2i5qGG55qE6L6557yY5Y+v6KKr5ZCR5Y+z77yI5Lic77yJ56e75Yqo44CCXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5lUmVzaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldEN1cnNvcignZS1yZXNpemUnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOatpOWFieagh+aMh+ekuuefqeW9ouahhueahOi+uee8mOWPr+iiq+WQkeW3pu+8iOilv++8ieenu+WKqOOAglxuICAgICAqL1xuICAgIEN1cnNvckFjdGlvbi5wcm90b3R5cGUud1Jlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ3ctcmVzaXplJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmraTlhYnmoIfmjIfnpLrnn6nlvaLmoYbnmoTovrnnvJjlj6/ooqvlkJHkuIrvvIjljJfvvInnp7vliqjjgIJcbiAgICAgKi9cbiAgICBDdXJzb3JBY3Rpb24ucHJvdG90eXBlLm5SZXNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0Q3Vyc29yKCduLXJlc2l6ZScpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5q2k5YWJ5qCH5oyH56S655+p5b2i5qGG55qE6L6557yY5Y+v6KKr5ZCR5LiL77yI5Y2X77yJ56e75Yqo44CCXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5zUmVzaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldEN1cnNvcigncy1yZXNpemUnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWFieagh+aMh+ekuuWPr+enu+WKqOeahOaWueWQkSDlj7PkuIrmlrnvvIjkuJzljJfvvIlcbiAgICAgKi9cbiAgICBDdXJzb3JBY3Rpb24ucHJvdG90eXBlLm5lUmVzaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldEN1cnNvcignbmUtcmVzaXplJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlhYnmoIfmjIfnpLrlj6/np7vliqjnmoTmlrnlkJEg5bem5LiK5pa577yI6KW/5YyX77yJXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5ud1Jlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ253LXJlc2l6ZScpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5YWJ5qCH5oyH56S65Y+v56e75Yqo55qE5pa55ZCR5Y+z5LiL5pa577yI5Lic5Y2X77yJXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5zZVJlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ3NlLXJlc2l6ZScpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5YWJ5qCH5oyH56S65Y+v56e75Yqo55qE5pa55ZCR5bem5LiL5pa577yI6KW/5Y2X77yJXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5zd1Jlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ3N3LXJlc2l6ZScpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5YWJ5qCH5oyH56S65Y+v5Lul5Zyo5LiK5LiL5pa55ZCR56e75YqoXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5uc1Jlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ25zLXJlc2l6ZScpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5YWJ5qCH5oyH56S65Y+v5Lul5Zyo5bem5Y+z5pa55ZCR56e75YqoXG4gICAgICovXG4gICAgQ3Vyc29yQWN0aW9uLnByb3RvdHlwZS5ld1Jlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDdXJzb3IoJ2V3LXJlc2l6ZScpO1xuICAgIH07XG4gICAgcmV0dXJuIEN1cnNvckFjdGlvbjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEN1cnNvckFjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWN1cnNvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbi8qKlxuICog5pWw5o2u6L+H5ruk44CCXG4gKiBAaWdub3JlXG4gKi9cbnZhciBEYXRhRmlsdGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERhdGFGaWx0ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRGF0YUZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBEYXRhRmlsdGVyLnByb3RvdHlwZS5maWx0ZXJWaWV3ID0gZnVuY3Rpb24gKHZpZXcsIGZpZWxkLCBmaWx0ZXIpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgLy8g5Y+q5pyJ5a2Y5Zyo6L+Z5LiqIHNjYWxlIOaXtuaJjeeUn+aViFxuICAgICAgICBpZiAodmlldy5nZXRTY2FsZUJ5RmllbGQoZmllbGQpKSB7XG4gICAgICAgICAgICB2aWV3LmZpbHRlcihmaWVsZCwgZmlsdGVyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy52aWV3cyAmJiB2aWV3LnZpZXdzLmxlbmd0aCkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2godmlldy52aWV3cywgZnVuY3Rpb24gKHN1YlZpZXcpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5maWx0ZXJWaWV3KHN1YlZpZXcsIGZpZWxkLCBmaWx0ZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOi/h+a7pOaVsOaNrlxuICAgICAqL1xuICAgIERhdGFGaWx0ZXIucHJvdG90eXBlLmZpbHRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRlbGVnYXRlT2JqZWN0ID0gdXRpbF8yLmdldERlbGVnYXRpb25PYmplY3QodGhpcy5jb250ZXh0KTtcbiAgICAgICAgaWYgKGRlbGVnYXRlT2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICAgICAgdmFyIGNvbXBvbmVudCA9IGRlbGVnYXRlT2JqZWN0LmNvbXBvbmVudDtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IGNvbXBvbmVudC5nZXQoJ2ZpZWxkJyk7XG4gICAgICAgICAgICAvLyDliJfooajnsbvnmoTnu4Tku7bog73lpJ/op6blj5FcbiAgICAgICAgICAgIGlmICh1dGlsXzIuaXNMaXN0KGRlbGVnYXRlT2JqZWN0KSkge1xuICAgICAgICAgICAgICAgIGlmIChmaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdW5DaGVja2VkSXRlbXMgPSBjb21wb25lbnQuZ2V0SXRlbXNCeVN0YXRlKCd1bmNoZWNrZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjYWxlXzEgPSB1dGlsXzIuZ2V0U2NhbGVCeUZpZWxkKHZpZXcsIGZpZWxkKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWVzXzEgPSB1bkNoZWNrZWRJdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHsgcmV0dXJuIGl0ZW0ubmFtZTsgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc18xLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJWaWV3KHZpZXcsIGZpZWxkLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IHNjYWxlXzEuZ2V0VGV4dCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFuYW1lc18xLmluY2x1ZGVzKHRleHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclZpZXcodmlldywgZmllbGQsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZpZXcucmVuZGVyKHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHV0aWxfMi5pc1NsaWRlcihkZWxlZ2F0ZU9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSBjb21wb25lbnQuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgICAgICB2YXIgbWluXzEgPSByYW5nZVswXSwgbWF4XzEgPSByYW5nZVsxXTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclZpZXcodmlldywgZmllbGQsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgPj0gbWluXzEgJiYgdmFsdWUgPD0gbWF4XzE7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdmlldy5yZW5kZXIodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBEYXRhRmlsdGVyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRGF0YUZpbHRlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbHRlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbi8vIOiOt+WPluWvueW6lOeahCBzY2FsZVxuZnVuY3Rpb24gZ2V0RmlsdGVyKHNjYWxlLCBkaW0sIHBvaW50MSwgcG9pbnQyKSB7XG4gICAgdmFyIG1pbiA9IE1hdGgubWluKHBvaW50MVtkaW1dLCBwb2ludDJbZGltXSk7XG4gICAgdmFyIG1heCA9IE1hdGgubWF4KHBvaW50MVtkaW1dLCBwb2ludDJbZGltXSk7XG4gICAgdmFyIF9hID0gc2NhbGUucmFuZ2UsIHJhbmdlTWluID0gX2FbMF0sIHJhbmdlTWF4ID0gX2FbMV07XG4gICAgLy8g57qm5p2f5YC85ZyoIHNjYWxlIOeahCByYW5nZSDkuYvpl7RcbiAgICBpZiAobWluIDwgcmFuZ2VNaW4pIHtcbiAgICAgICAgbWluID0gcmFuZ2VNaW47XG4gICAgfVxuICAgIGlmIChtYXggPiByYW5nZU1heCkge1xuICAgICAgICBtYXggPSByYW5nZU1heDtcbiAgICB9XG4gICAgLy8g6IyD5Zu05aSn5LqO5pW05LiqIHZpZXcg55qE6IyD5Zu077yM5YiZ6L+U5ZueIG51bGxcbiAgICBpZiAobWluID09PSByYW5nZU1heCAmJiBtYXggPT09IHJhbmdlTWF4KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbWluVmFsdWUgPSBzY2FsZS5pbnZlcnQobWluKTtcbiAgICB2YXIgbWF4VmFsdWUgPSBzY2FsZS5pbnZlcnQobWF4KTtcbiAgICBpZiAoc2NhbGUuaXNDYXRlZ29yeSkge1xuICAgICAgICB2YXIgbWluSW5kZXggPSBzY2FsZS52YWx1ZXMuaW5kZXhPZihtaW5WYWx1ZSk7XG4gICAgICAgIHZhciBtYXhJbmRleCA9IHNjYWxlLnZhbHVlcy5pbmRleE9mKG1heFZhbHVlKTtcbiAgICAgICAgdmFyIGFycl8xID0gc2NhbGUudmFsdWVzLnNsaWNlKG1pbkluZGV4LCBtYXhJbmRleCArIDEpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyXzEuaW5jbHVkZXModmFsdWUpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID49IG1pblZhbHVlICYmIHZhbHVlIDw9IG1heFZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cbn1cbi8qKlxuICog6IyD5Zu06L+H5ruk55qEIEFjdGlvblxuICogQGlnbm9yZVxuICovXG52YXIgUmFuZ2VGaWx0ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUmFuZ2VGaWx0ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmFuZ2VGaWx0ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICAvKipcbiAgICAgICAgICog6IyD5Zu06L+H5ruk55Sf5pWI55qE5a2X5q61L+e7tOW6pu+8jOWPr+S7peaYryB4LCB5XG4gICAgICAgICAqL1xuICAgICAgICBfdGhpcy5kaW1zID0gWyd4JywgJ3knXTtcbiAgICAgICAgLyoqIOi1t+Wni+eCuSAqL1xuICAgICAgICBfdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcbiAgICAgICAgX3RoaXMuaXNTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLy8geCx5IOaYr+WQpueUn+aViFxuICAgIFJhbmdlRmlsdGVyLnByb3RvdHlwZS5oYXNEaW0gPSBmdW5jdGlvbiAoZGltKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpbXMuaW5jbHVkZXMoZGltKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOW8gOWni+iMg+WbtOi/h+a7pO+8jOiusOW9leiMg+WbtOi/h+a7pOeahOi1t+eCuVxuICAgICAqL1xuICAgIFJhbmdlRmlsdGVyLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIHRoaXMuaXNTdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gY29udGV4dC5nZXRDdXJyZW50UG9pbnQoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOi/h+a7pO+8jOS7peW8gOWni+eahOeCueWSjOW9k+WJjeeCueWvueaVsOaNrui/m+ihjOi/h+a7pFxuICAgICAqL1xuICAgIFJhbmdlRmlsdGVyLnByb3RvdHlwZS5maWx0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFydFBvaW50O1xuICAgICAgICB2YXIgY3VycmVudFBvaW50O1xuICAgICAgICBpZiAodXRpbF8xLmlzTWFzayh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICB2YXIgbWFza1NoYXBlID0gdGhpcy5jb250ZXh0LmV2ZW50LnRhcmdldDtcbiAgICAgICAgICAgIHZhciBiYm94ID0gbWFza1NoYXBlLmdldENhbnZhc0JCb3goKTtcbiAgICAgICAgICAgIHN0YXJ0UG9pbnQgPSB7IHg6IGJib3gueCwgeTogYmJveC55IH07XG4gICAgICAgICAgICBjdXJyZW50UG9pbnQgPSB7IHg6IGJib3gubWF4WCwgeTogYmJveC5tYXhZIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTdGFydGVkKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5rKh5pyJ5byA5aeL77yM5YiZ5LiN5omn6KGM6L+H5rukXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhcnRQb2ludCA9IHRoaXMuc3RhcnRQb2ludDtcbiAgICAgICAgICAgIGN1cnJlbnRQb2ludCA9IHRoaXMuY29udGV4dC5nZXRDdXJyZW50UG9pbnQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTWF0aC5hYnMoc3RhcnRQb2ludC54IC0gY3VycmVudFBvaW50LngpIDwgNSB8fCBNYXRoLmFicyhzdGFydFBvaW50LnggLSBjdXJyZW50UG9pbnQueSkgPCA1KSB7XG4gICAgICAgICAgICAvLyDot53nprvov4flsI/kuZ/kuI3nlJ/mlYhcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgY29vcmQgPSB2aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIG5vcm1hbEN1cnJlbnQgPSBjb29yZC5pbnZlcnQoY3VycmVudFBvaW50KTtcbiAgICAgICAgdmFyIG5vcm1hbFN0YXJ0ID0gY29vcmQuaW52ZXJ0KHN0YXJ0UG9pbnQpO1xuICAgICAgICAvLyDorr7nva4geCDmlrnlkJHnmoQgZmlsdGVyXG4gICAgICAgIGlmICh0aGlzLmhhc0RpbSgneCcpKSB7XG4gICAgICAgICAgICB2YXIgeFNjYWxlID0gdmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgICAgIHZhciBmaWx0ZXIgPSBnZXRGaWx0ZXIoeFNjYWxlLCAneCcsIG5vcm1hbEN1cnJlbnQsIG5vcm1hbFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyVmlldyh2aWV3LCB4U2NhbGUuZmllbGQsIGZpbHRlcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6K6+572uIHkg5pa55ZCR55qEIGZpbHRlclxuICAgICAgICBpZiAodGhpcy5oYXNEaW0oJ3knKSkge1xuICAgICAgICAgICAgdmFyIHlTY2FsZSA9IHZpZXcuZ2V0WVNjYWxlcygpWzBdO1xuICAgICAgICAgICAgdmFyIGZpbHRlciA9IGdldEZpbHRlcih5U2NhbGUsICd5Jywgbm9ybWFsQ3VycmVudCwgbm9ybWFsU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJWaWV3KHZpZXcsIHlTY2FsZS5maWVsZCwgZmlsdGVyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlUmVuZGVyKHZpZXcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog57uT5p2fXG4gICAgICovXG4gICAgUmFuZ2VGaWx0ZXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pc1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWPlua2iOWQjOW9k+WJjSBBY3Rpb24g55u45YWz55qE6L+H5ruk77yM5oyH5a6a55qEIHgseVxuICAgICAqL1xuICAgIFJhbmdlRmlsdGVyLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdGhpcy5pc1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuaGFzRGltKCd4JykpIHtcbiAgICAgICAgICAgIHZhciB4U2NhbGUgPSB2aWV3LmdldFhTY2FsZSgpO1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJWaWV3KHZpZXcsIHhTY2FsZS5maWVsZCwgbnVsbCk7IC8vIOWPlua2iOi/h+a7pFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmhhc0RpbSgneScpKSB7XG4gICAgICAgICAgICAvLyB5IOi9tOi/h+a7pOS7heWPluesrOS4gOS4qiB5U2NhbGVcbiAgICAgICAgICAgIHZhciB5U2NhbGUgPSB2aWV3LmdldFlTY2FsZXMoKVswXTtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyVmlldyh2aWV3LCB5U2NhbGUuZmllbGQsIG51bGwpOyAvLyDlj5bmtojov4fmu6RcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlUmVuZGVyKHZpZXcpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5a+5IHZpZXcg6L+b6KGM6L+H5rukXG4gICAgICovXG4gICAgUmFuZ2VGaWx0ZXIucHJvdG90eXBlLmZpbHRlclZpZXcgPSBmdW5jdGlvbiAodmlldywgZmllbGQsIGZpbHRlcikge1xuICAgICAgICB2aWV3LmZpbHRlcihmaWVsZCwgZmlsdGVyKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOmHjeaWsOa4suafk1xuICAgICAqIEBwYXJhbSB2aWV3XG4gICAgICovXG4gICAgUmFuZ2VGaWx0ZXIucHJvdG90eXBlLnJlUmVuZGVyID0gZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgdmlldy5yZW5kZXIodHJ1ZSk7XG4gICAgfTtcbiAgICByZXR1cm4gUmFuZ2VGaWx0ZXI7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSYW5nZUZpbHRlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJhbmdlLWZpbHRlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHJhbmdlX2ZpbHRlcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcmFuZ2UtZmlsdGVyXCIpKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbi8qKlxuICog5pWw5o2u6IyD5Zu06L+H5ruk77yM5L2G5LiN5Zyo5b2T5YmN55qEIHZpZXcg5LiK55Sf5pWI77yM6ICM5Zyo5b2T5YmN55qEIHZpZXcg5ZCM5LiA5bGC57qn55qE5YW25LuWIHZpZXdzIOS4iueUn+aViO+8jOeUqOS6juWunueOsOiBlOWKqOi/h+a7pOOAglxuICogQGlnbm9yZVxuICovXG52YXIgU2libGluZ0ZpbHRlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTaWJsaW5nRmlsdGVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNpYmxpbmdGaWx0ZXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5a+5IHZpZXcg6L+b6KGM6L+H5rukXG4gICAgICogQHBhcmFtIHZpZXdcbiAgICAgKiBAcGFyYW0gZmllbGRcbiAgICAgKiBAcGFyYW0gZmlsdGVyXG4gICAgICovXG4gICAgU2libGluZ0ZpbHRlci5wcm90b3R5cGUuZmlsdGVyVmlldyA9IGZ1bmN0aW9uICh2aWV3LCBmaWVsZCwgZmlsdGVyKSB7XG4gICAgICAgIHZhciBzaWJsaW5ncyA9IHV0aWxfMi5nZXRTaWxiaW5ncyh2aWV3KTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2libGluZ3MsIGZ1bmN0aW9uIChzaWJsaW5nKSB7XG4gICAgICAgICAgICBzaWJsaW5nLmZpbHRlcihmaWVsZCwgZmlsdGVyKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDph43mlrDmuLLmn5NcbiAgICAgKiBAcGFyYW0gdmlld1xuICAgICAqL1xuICAgIFNpYmxpbmdGaWx0ZXIucHJvdG90eXBlLnJlUmVuZGVyID0gZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgdmFyIHNpYmxpbmdzID0gdXRpbF8yLmdldFNpbGJpbmdzKHZpZXcpO1xuICAgICAgICB1dGlsXzEuZWFjaChzaWJsaW5ncywgZnVuY3Rpb24gKHNpYmxpbmcpIHtcbiAgICAgICAgICAgIHNpYmxpbmcucmVuZGVyKHRydWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTaWJsaW5nRmlsdGVyO1xufShyYW5nZV9maWx0ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTaWJsaW5nRmlsdGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2libGluZy1maWx0ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBzdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vc3RhdGVcIikpO1xuLyoqXG4gKiDlhYPntKAgYWN0aXZlIOeahCBBY3Rpb27vvIzlhYHorrjlpJrkuKrlhYPntKDlkIzml7YgYWN0aXZlXG4gKiBAY2xhc3NcbiAqIEBpZ25vcmVcbiAqL1xudmFyIEVsZW1lbnRBY3RpdmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudEFjdGl2ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBFbGVtZW50QWN0aXZlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc3RhdGVOYW1lID0gJ2FjdGl2ZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWN0aXZlIEVsZW1lbnRcbiAgICAgKi9cbiAgICBFbGVtZW50QWN0aXZlLnByb3RvdHlwZS5hY3RpdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50QWN0aXZlO1xufShzdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRBY3RpdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hY3RpdmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWxcIik7XG4vKipcbiAqIOWFg+e0oOi/h+a7pOeahCBBY3Rpb27vvIzmjqfliLblhYPntKDnmoTmmL7npLrpmpDol49cbiAqIEBpZ25vcmVcbiAqL1xudmFyIEVsZW1lbnRGaWx0ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudEZpbHRlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBFbGVtZW50RmlsdGVyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOi/h+a7pFxuICAgICAqL1xuICAgIEVsZW1lbnRGaWx0ZXIucHJvdG90eXBlLmZpbHRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRlbGVnYXRlT2JqZWN0ID0gdXRpbF8yLmdldERlbGVnYXRpb25PYmplY3QodGhpcy5jb250ZXh0KTtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdXRpbF8yLmdldEVsZW1lbnRzKHZpZXcpO1xuICAgICAgICBpZiAodXRpbF8yLmlzTWFzayh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICB2YXIgbWFza0VsZW1lbnRzXzEgPSB1dGlsXzIuZ2V0TWFza2VkRWxlbWVudHModGhpcy5jb250ZXh0LCAxMCk7XG4gICAgICAgICAgICBpZiAobWFza0VsZW1lbnRzXzEpIHtcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXNrRWxlbWVudHNfMS5pbmNsdWRlcyhlbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnNob3coKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRlbGVnYXRlT2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gZGVsZWdhdGVPYmplY3QuY29tcG9uZW50O1xuICAgICAgICAgICAgdmFyIGZpZWxkXzEgPSBjb21wb25lbnQuZ2V0KCdmaWVsZCcpO1xuICAgICAgICAgICAgLy8g5YiX6KGo57G755qE57uE5Lu26IO95aSf6Kem5Y+RXG4gICAgICAgICAgICBpZiAodXRpbF8yLmlzTGlzdChkZWxlZ2F0ZU9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmllbGRfMSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdW5DaGVja2VkSXRlbXMgPSBjb21wb25lbnQuZ2V0SXRlbXNCeVN0YXRlKCd1bmNoZWNrZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjYWxlXzEgPSB1dGlsXzIuZ2V0U2NhbGVCeUZpZWxkKHZpZXcsIGZpZWxkXzEpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZXNfMSA9IHVuQ2hlY2tlZEl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbS5uYW1lOyB9KTtcbiAgICAgICAgICAgICAgICAgICAgLy8g55u05o6l5o6n5Yi25pi+56S644CB6ZqQ6JePXG4gICAgICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHV0aWxfMi5nZXRFbGVtZW50VmFsdWUoZWwsIGZpZWxkXzEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSBzY2FsZV8xLmdldFRleHQodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzXzEuaW5kZXhPZih0ZXh0KSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuc2hvdygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzIuaXNTbGlkZXIoZGVsZWdhdGVPYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9uZW50LmdldFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgdmFyIG1pbl8xID0gcmFuZ2VbMF0sIG1heF8xID0gcmFuZ2VbMV07XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2goZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB1dGlsXzIuZ2V0RWxlbWVudFZhbHVlKGVsLCBmaWVsZF8xKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID49IG1pbl8xICYmIHZhbHVlIDw9IG1heF8xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF6Zmk6L+H5rukXG4gICAgICovXG4gICAgRWxlbWVudEZpbHRlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHV0aWxfMi5nZXRFbGVtZW50cyh0aGlzLmNvbnRleHQudmlldyk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgIGVsLnNob3coKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmgaLlpI3lj5HnlJ/nmoTov4fmu6TvvIzkv53mjIHlkIwgZGF0YS1maWx0ZXIg5ZG95ZCN55qE5LiA6Ie0XG4gICAgICovXG4gICAgRWxlbWVudEZpbHRlci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50RmlsdGVyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRWxlbWVudEZpbHRlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbHRlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIGhpZ2hsaWdodF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaGlnaGxpZ2h0XCIpKTtcbi8qKlxuICogSGlnaGxpZ2h0IGNvbG9yXG4gKiBAaWdub3JlXG4gKi9cbnZhciBIaWdobGlnaHRDb2xvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhIaWdobGlnaHRDb2xvciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIaWdobGlnaHRDb2xvcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBIaWdobGlnaHRDb2xvci5wcm90b3R5cGUuc2V0U3RhdGVCeUVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgZW5hYmxlKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZhciBjb2xvckF0dHIgPSBlbGVtZW50Lmdlb21ldHJ5LmdldEF0dHJpYnV0ZSgnY29sb3InKTtcbiAgICAgICAgaWYgKCFjb2xvckF0dHIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2NhbGUgPSB2aWV3LmdldFNjYWxlQnlGaWVsZChjb2xvckF0dHIuZ2V0RmllbGRzKClbMF0pO1xuICAgICAgICB2YXIgdmFsdWUgPSB1dGlsXzEuZ2V0RWxlbWVudFZhbHVlKGVsZW1lbnQsIHNjYWxlLmZpZWxkKTtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdXRpbF8xLmdldEVsZW1lbnRzKHZpZXcpO1xuICAgICAgICB2YXIgaGlnaGxpZ2h0RWxlbWVudHMgPSBlbGVtZW50cy5maWx0ZXIoZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8xLmdldEVsZW1lbnRWYWx1ZShlbCwgc2NhbGUuZmllbGQpID09PSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0SGlnaGxpZ2h0QnkoZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkgeyByZXR1cm4gaGlnaGxpZ2h0RWxlbWVudHMuaW5jbHVkZXMoZWwpOyB9LCBlbmFibGUpO1xuICAgIH07XG4gICAgcmV0dXJuIEhpZ2hsaWdodENvbG9yO1xufShoaWdobGlnaHRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIaWdobGlnaHRDb2xvcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhpZ2hsaWdodC1ieS1jb2xvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIGhpZ2hsaWdodF8xID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vaGlnaGxpZ2h0XCIpKTtcbi8qKlxuICogSGlnaGxpZ2h0IHhcbiAqIEBpZ25vcmVcbiAqL1xudmFyIEhpZ2hsaWdodFggPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoSGlnaGxpZ2h0WCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIaWdobGlnaHRYKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8vIOS4jeWFgeiuuOWkmumAiVxuICAgIEhpZ2hsaWdodFgucHJvdG90eXBlLnNldEVsZW1lbnRIaWdobGlnaHQgPSBmdW5jdGlvbiAoZWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChjYWxsYmFjayhlbCkpIHtcbiAgICAgICAgICAgIGlmIChlbC5oYXNTdGF0ZShoaWdobGlnaHRfMS5TVEFUVVNfVU5BQ1RJVkUpKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0U3RhdGUoaGlnaGxpZ2h0XzEuU1RBVFVTX1VOQUNUSVZFLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbC5zZXRTdGF0ZShoaWdobGlnaHRfMS5TVEFUVVNfQUNUSVZFLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVsLnNldFN0YXRlKGhpZ2hsaWdodF8xLlNUQVRVU19VTkFDVElWRSwgdHJ1ZSk7XG4gICAgICAgICAgICBpZiAoZWwuaGFzU3RhdGUoaGlnaGxpZ2h0XzEuU1RBVFVTX0FDVElWRSkpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRTdGF0ZShoaWdobGlnaHRfMS5TVEFUVVNfQUNUSVZFLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEhpZ2hsaWdodFgucHJvdG90eXBlLnNldFN0YXRlQnlFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQsIGVuYWJsZSkge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgc2NhbGUgPSB2aWV3LmdldFhTY2FsZSgpO1xuICAgICAgICB2YXIgdmFsdWUgPSB1dGlsXzEuZ2V0RWxlbWVudFZhbHVlKGVsZW1lbnQsIHNjYWxlLmZpZWxkKTtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdXRpbF8xLmdldEVsZW1lbnRzKHZpZXcpO1xuICAgICAgICB2YXIgaGlnaGxpZ2h0RWxlbWVudHMgPSBlbGVtZW50cy5maWx0ZXIoZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8xLmdldEVsZW1lbnRWYWx1ZShlbCwgc2NhbGUuZmllbGQpID09PSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0SGlnaGxpZ2h0QnkoZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkgeyByZXR1cm4gaGlnaGxpZ2h0RWxlbWVudHMuaW5jbHVkZXMoZWwpOyB9LCBlbmFibGUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5YiH5o2i54q25oCBXG4gICAgICovXG4gICAgSGlnaGxpZ2h0WC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHV0aWxfMS5nZXRDdXJyZW50RWxlbWVudCh0aGlzLmNvbnRleHQpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgdmFyIGhhc1N0YXRlID0gZWxlbWVudC5oYXNTdGF0ZSh0aGlzLnN0YXRlTmFtZSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlQnlFbGVtZW50KGVsZW1lbnQsICFoYXNTdGF0ZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBIaWdobGlnaHRYO1xufShoaWdobGlnaHRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIaWdobGlnaHRYO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aGlnaGxpZ2h0LWJ5LXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnNldEhpZ2hsaWdodEJ5ID0gZXhwb3J0cy5jbGVhckhpZ2hsaWdodCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbnZhciBTVEFUVVNfVU5BQ1RJVkUgPSAnaW5hY3RpdmUnO1xudmFyIFNUQVRVU19BQ1RJVkUgPSAnYWN0aXZlJztcbi8qKlxuICogQGlnbm9yZVxuICog5riF55CGIGhpZ2hsaWdodCDmlYjmnpxcbiAqIEBwYXJhbSB2aWV3IFZpZXcg5oiW6ICFIENoYXJ0XG4gKi9cbmZ1bmN0aW9uIGNsZWFySGlnaGxpZ2h0KHZpZXcpIHtcbiAgICB2YXIgZWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHModmlldyk7XG4gICAgdXRpbF8xLmVhY2goZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICBpZiAoZWwuaGFzU3RhdGUoU1RBVFVTX0FDVElWRSkpIHtcbiAgICAgICAgICAgIGVsLnNldFN0YXRlKFNUQVRVU19BQ1RJVkUsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWwuaGFzU3RhdGUoU1RBVFVTX1VOQUNUSVZFKSkge1xuICAgICAgICAgICAgZWwuc2V0U3RhdGUoU1RBVFVTX1VOQUNUSVZFLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydHMuY2xlYXJIaWdobGlnaHQgPSBjbGVhckhpZ2hsaWdodDtcbi8qKlxuICogQGlnbm9yZVxuICog6K6+572u5aSa5Liq5YWD57Sg55qEIGhpZ2hsaWdodFxuICogQHBhcmFtIGVsZW1lbnRzIOWFg+e0oOmbhuWQiFxuICogQHBhcmFtIGNhbGxiYWNrIOiuvue9ruWbnuiwg+WHveaVsFxuICogQHBhcmFtIGVuYWJsZSDorr7nva7miJbogIXlj5bmtohcbiAqL1xuZnVuY3Rpb24gc2V0SGlnaGxpZ2h0QnkoZWxlbWVudHMsIGNhbGxiYWNrLCBlbmFibGUpIHtcbiAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIC8vIOmcgOimgeWkhOeQhiBhY3RpdmUg5ZKMIHVuYWN0aXZlIOeahOS6kuaWpVxuICAgICAgICBpZiAoY2FsbGJhY2soZWwpKSB7XG4gICAgICAgICAgICBpZiAoZWwuaGFzU3RhdGUoU1RBVFVTX1VOQUNUSVZFKSkge1xuICAgICAgICAgICAgICAgIGVsLnNldFN0YXRlKFNUQVRVU19VTkFDVElWRSwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWwuc2V0U3RhdGUoU1RBVFVTX0FDVElWRSwgZW5hYmxlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChlbC5oYXNTdGF0ZShTVEFUVVNfQUNUSVZFKSkge1xuICAgICAgICAgICAgICAgIGVsLnNldFN0YXRlKFNUQVRVU19BQ1RJVkUsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsLnNldFN0YXRlKFNUQVRVU19VTkFDVElWRSwgZW5hYmxlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5zZXRIaWdobGlnaHRCeSA9IHNldEhpZ2hsaWdodEJ5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aGlnaGxpZ2h0LXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlNUQVRVU19BQ1RJVkUgPSBleHBvcnRzLlNUQVRVU19VTkFDVElWRSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIGhpZ2hsaWdodF91dGlsXzEgPSByZXF1aXJlKFwiLi9oaWdobGlnaHQtdXRpbFwiKTtcbnZhciBzdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vc3RhdGVcIikpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vY29uc3RhbnRcIik7XG5leHBvcnRzLlNUQVRVU19VTkFDVElWRSA9IGNvbnN0YW50XzEuRUxFTUVOVF9TVEFURS5JTkFDVElWRTtcbmV4cG9ydHMuU1RBVFVTX0FDVElWRSA9IGNvbnN0YW50XzEuRUxFTUVOVF9TVEFURS5BQ1RJVkU7XG4vKipcbiAqIEBpZ25vcmVcbiAqIGhpZ2hsaWdodO+8jOaMh+WumuWbvuW9oumrmOS6ru+8jOWFtuS7luWbvuW9ouWPmOaal1xuICovXG52YXIgRWxlbWVudEhpZ2hsaWdodCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGVtZW50SGlnaGxpZ2h0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEVsZW1lbnRIaWdobGlnaHQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGF0ZU5hbWUgPSBleHBvcnRzLlNUQVRVU19BQ1RJVkU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLy8g5aSa5Liq5YWD57Sg6K6+572u44CB5Y+W5raIIGhpZ2hsaWdodFxuICAgIEVsZW1lbnRIaWdobGlnaHQucHJvdG90eXBlLnNldEVsZW1lbnRzU3RhdGVCeUl0ZW0gPSBmdW5jdGlvbiAoZWxlbWVudHMsIGZpZWxkLCBpdGVtLCBlbmFibGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKGVsKSB7IHJldHVybiBfdGhpcy5pc01hdGhJdGVtKGVsLCBmaWVsZCwgaXRlbSk7IH07XG4gICAgICAgIHRoaXMuc2V0SGlnaGxpZ2h0QnkoZWxlbWVudHMsIGNhbGxiYWNrLCBlbmFibGUpO1xuICAgIH07XG4gICAgLy8g6K6+572u5YWD57Sg55qEIGhpZ2hsaWdodFxuICAgIEVsZW1lbnRIaWdobGlnaHQucHJvdG90eXBlLnNldEVsZW1lbnRIaWdobGlnaHQgPSBmdW5jdGlvbiAoZWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChjYWxsYmFjayhlbCkpIHtcbiAgICAgICAgICAgIGlmIChlbC5oYXNTdGF0ZShleHBvcnRzLlNUQVRVU19VTkFDVElWRSkpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRTdGF0ZShleHBvcnRzLlNUQVRVU19VTkFDVElWRSwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWwuc2V0U3RhdGUoZXhwb3J0cy5TVEFUVVNfQUNUSVZFLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghZWwuaGFzU3RhdGUoZXhwb3J0cy5TVEFUVVNfQUNUSVZFKSkge1xuICAgICAgICAgICAgZWwuc2V0U3RhdGUoZXhwb3J0cy5TVEFUVVNfVU5BQ1RJVkUsIHRydWUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBFbGVtZW50SGlnaGxpZ2h0LnByb3RvdHlwZS5zZXRIaWdobGlnaHRCeSA9IGZ1bmN0aW9uIChlbGVtZW50cywgY2FsbGJhY2ssIGVuYWJsZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICBpZiAoZW5hYmxlKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzmmK/orr7nva4gaGlnaGxpZ2h0IO+8jOWImeWwhuWMuemFjeeahCBlbGVtZW50IOiuvue9ruaIkCBhY3RpdmXvvIxcbiAgICAgICAgICAgIC8vIOWFtuS7luWmguaenOS4jeaYryBhY3RpdmXvvIzliJnorr7nva7miJAgdW5hY3RpdmVcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRFbGVtZW50SGlnaGxpZ2h0KGVsLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOWmguaenOWPlua2iCBoaWdobGlnaHTvvIzliJnopoHmo4DmtYvmmK/lkKblhajpg6jlj5bmtoggaGlnaGxpZ2h0XG4gICAgICAgICAgICB2YXIgYWN0aXZlRWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHNCeVN0YXRlKHRoaXMuY29udGV4dC52aWV3LCBleHBvcnRzLlNUQVRVU19BQ1RJVkUpO1xuICAgICAgICAgICAgdmFyIGFsbENhbmNlbF8xID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIOajgOa1i+aJgOaciSBhY3RpdmVFbGVtZW50cyDpg73opoHlj5bmtoggaGlnaGxpZ2h0XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChhY3RpdmVFbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjYWxsYmFjayhlbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxsQ2FuY2VsXzEgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGFsbENhbmNlbF8xKSB7XG4gICAgICAgICAgICAgICAgLy8g6YO96KaB5Y+W5raI77yM5YiZ5Y+W5raI5omA5pyJ55qEIGFjdGl2Ze+8jHVuYWN0aXZlIOeKtuaAgVxuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOS4jeaYr+mDveimgeWPlua2iCBoaWdobGlnaHQsIOWImeiuvue9ruWMuemFjeeahCBlbGVtZW50IOeahOeKtuaAgeS4uiB1bmFjdGl2ZVxuICAgICAgICAgICAgICAgIC8vIOWFtuS7liBlbGVtZW50IOeKtuaAgeS4jeWPmFxuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKGVsKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsLmhhc1N0YXRlKGV4cG9ydHMuU1RBVFVTX0FDVElWRSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5zZXRTdGF0ZShleHBvcnRzLlNUQVRVU19BQ1RJVkUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnNldFN0YXRlKGV4cG9ydHMuU1RBVFVTX1VOQUNUSVZFLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDljZXkuKrlhYPntKDorr7nva7lkozlj5bmtoggaGlnaGxpZ2h0XG4gICAgRWxlbWVudEhpZ2hsaWdodC5wcm90b3R5cGUuc2V0RWxlbWVudFN0YXRlID0gZnVuY3Rpb24gKGVsZW1lbnQsIGVuYWJsZSkge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgZWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHModmlldyk7XG4gICAgICAgIHRoaXMuc2V0SGlnaGxpZ2h0QnkoZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkgeyByZXR1cm4gZWxlbWVudCA9PT0gZWw7IH0sIGVuYWJsZSk7XG4gICAgfTtcbiAgICBFbGVtZW50SGlnaGxpZ2h0LnByb3RvdHlwZS5oaWdobGlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKTtcbiAgICB9O1xuICAgIC8vIOa4heeQhuaOieaJgOacieeahCBhY3RpdmXvvIwgdW5hY3RpdmUg54q25oCBXG4gICAgRWxlbWVudEhpZ2hsaWdodC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIGhpZ2hsaWdodF91dGlsXzEuY2xlYXJIaWdobGlnaHQodmlldyk7XG4gICAgfTtcbiAgICByZXR1cm4gRWxlbWVudEhpZ2hsaWdodDtcbn0oc3RhdGVfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGVtZW50SGlnaGxpZ2h0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aGlnaGxpZ2h0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2Jhc2VcIikpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBMaW5rIEVsZW1lbnRzIGJ5IGNvbG9yXG4gKiBAaWdub3JlXG4gKi9cbnZhciBMaW5rQnlDb2xvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaW5rQnlDb2xvciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaW5rQnlDb2xvcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmNhY2hlID0ge307XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLy8g6I635Y+W6aKc6Imy5a+55bqU55qEIHNjYWxlXG4gICAgTGlua0J5Q29sb3IucHJvdG90eXBlLmdldENvbG9yU2NhbGUgPSBmdW5jdGlvbiAodmlldywgZWxlbWVudCkge1xuICAgICAgICB2YXIgY29sb3JBdHRyID0gZWxlbWVudC5nZW9tZXRyeS5nZXRBdHRyaWJ1dGUoJ2NvbG9yJyk7XG4gICAgICAgIGlmICghY29sb3JBdHRyKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2NhbGUgPSB2aWV3LmdldFNjYWxlQnlGaWVsZChjb2xvckF0dHIuZ2V0RmllbGRzKClbMF0pO1xuICAgICAgICByZXR1cm4gc2NhbGU7XG4gICAgfTtcbiAgICAvLyDojrflj5bov57mjqXnmoQgcGF0aFxuICAgIExpbmtCeUNvbG9yLnByb3RvdHlwZS5nZXRMaW5rUGF0aCA9IGZ1bmN0aW9uIChlbGVtZW50LCBuZXh0RWxlbWVudCkge1xuICAgICAgICB2YXIgYmJveCA9IGVsZW1lbnQuc2hhcGUuZ2V0Q2FudmFzQkJveCgpO1xuICAgICAgICB2YXIgbmV4dEJCb3ggPSBuZXh0RWxlbWVudC5zaGFwZS5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgIHZhciBwYXRoID0gW1xuICAgICAgICAgICAgWydNJywgYmJveC5tYXhYLCBiYm94Lm1pblldLFxuICAgICAgICAgICAgWydMJywgbmV4dEJCb3gubWluWCwgbmV4dEJCb3gubWluWV0sXG4gICAgICAgICAgICBbJ0wnLCBuZXh0QkJveC5taW5YLCBuZXh0QkJveC5tYXhZXSxcbiAgICAgICAgICAgIFsnTCcsIGJib3gubWF4WCwgYmJveC5tYXhZXSxcbiAgICAgICAgICAgIFsnWiddLFxuICAgICAgICBdO1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIC8vIOa3u+WKoOi/nuaOpeeahOWbvuW9olxuICAgIExpbmtCeUNvbG9yLnByb3RvdHlwZS5hZGRMaW5rU2hhcGUgPSBmdW5jdGlvbiAoZ3JvdXAsIGVsZW1lbnQsIG5leHRFbGVtZW50KSB7XG4gICAgICAgIGdyb3VwLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIHR5cGU6ICdwYXRoJyxcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC40LFxuICAgICAgICAgICAgICAgIGZpbGw6IGVsZW1lbnQuc2hhcGUuYXR0cignZmlsbCcpLFxuICAgICAgICAgICAgICAgIHBhdGg6IHRoaXMuZ2V0TGlua1BhdGgoZWxlbWVudCwgbmV4dEVsZW1lbnQpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDkvb/nlKjlm77lvaLov57mjqVcbiAgICBMaW5rQnlDb2xvci5wcm90b3R5cGUubGlua0J5RWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZhciBzY2FsZSA9IHRoaXMuZ2V0Q29sb3JTY2FsZSh2aWV3LCBlbGVtZW50KTtcbiAgICAgICAgaWYgKCFzY2FsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2YWx1ZSA9IHV0aWxfMS5nZXRFbGVtZW50VmFsdWUoZWxlbWVudCwgc2NhbGUuZmllbGQpO1xuICAgICAgICBpZiAoIXRoaXMuY2FjaGVbdmFsdWVdKSB7XG4gICAgICAgICAgICB2YXIgZWxlbWVudHNfMSA9IHV0aWxfMS5nZXRFbGVtZW50c0J5RmllbGQodmlldywgc2NhbGUuZmllbGQsIHZhbHVlKTtcbiAgICAgICAgICAgIHZhciBsaW5rR3JvdXAgPSB0aGlzLmxpbmtHcm91cDtcbiAgICAgICAgICAgIHZhciBncm91cF8xID0gbGlua0dyb3VwLmFkZEdyb3VwKCk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlW3ZhbHVlXSA9IGdyb3VwXzE7IC8vIOe8k+WtmFxuICAgICAgICAgICAgdmFyIGNvdW50XzEgPSBlbGVtZW50c18xLmxlbmd0aDtcbiAgICAgICAgICAgIHV0aWxfMi5lYWNoKGVsZW1lbnRzXzEsIGZ1bmN0aW9uIChlbCwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCBjb3VudF8xIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dEVsID0gZWxlbWVudHNfMVtpbmRleCArIDFdO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5hZGRMaW5rU2hhcGUoZ3JvdXBfMSwgZWwsIG5leHRFbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOenu+mZpOi/nuaOpVxuICAgIExpbmtCeUNvbG9yLnByb3RvdHlwZS5yZW1vdmVMaW5rID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHNjYWxlID0gdGhpcy5nZXRDb2xvclNjYWxlKHRoaXMuY29udGV4dC52aWV3LCBlbGVtZW50KTtcbiAgICAgICAgaWYgKCFzY2FsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2YWx1ZSA9IHV0aWxfMS5nZXRFbGVtZW50VmFsdWUoZWxlbWVudCwgc2NhbGUuZmllbGQpO1xuICAgICAgICBpZiAodGhpcy5jYWNoZVt2YWx1ZV0pIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVbdmFsdWVdLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZVt2YWx1ZV0gPSBudWxsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDov57mjqUgZWxlbWVudHNcbiAgICAgKi9cbiAgICBMaW5rQnlDb2xvci5wcm90b3R5cGUubGluayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGlmICghdGhpcy5saW5rR3JvdXApIHtcbiAgICAgICAgICAgIC8vIOS4jeWFgeiuuOiiq+aLvuWPllxuICAgICAgICAgICAgdGhpcy5saW5rR3JvdXAgPSBjb250ZXh0LnZpZXcuZm9yZWdyb3VuZEdyb3VwLmFkZEdyb3VwKHtcbiAgICAgICAgICAgICAgICBjYXB0dXJlOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbGVtZW50ID0gdXRpbF8xLmdldEN1cnJlbnRFbGVtZW50KGNvbnRleHQpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5saW5rQnlFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlj5bmtojov57mjqUgZWxlbWVudHNcbiAgICAgKi9cbiAgICBMaW5rQnlDb2xvci5wcm90b3R5cGUudW5saW5rID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHV0aWxfMS5nZXRDdXJyZW50RWxlbWVudCh0aGlzLmNvbnRleHQpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVMaW5rKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuIXpmaTmiYDmnInov57mjqVcbiAgICAgKi9cbiAgICBMaW5rQnlDb2xvci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmxpbmtHcm91cCkge1xuICAgICAgICAgICAgdGhpcy5saW5rR3JvdXAuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZSA5q+BXG4gICAgICovXG4gICAgTGlua0J5Q29sb3IucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5saW5rR3JvdXApIHtcbiAgICAgICAgICAgIHRoaXMubGlua0dyb3VwLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gTGlua0J5Q29sb3I7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMaW5rQnlDb2xvcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmstYnktY29sb3IuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciByYW5nZV9zdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcmFuZ2Utc3RhdGVcIikpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDlm77ooajlhYPntKDljLrln58gQWN0aXZlIOeahCBBY3Rpb25cbiAqL1xudmFyIEVsZW1lbnRSYW5nZUFjdGl2ZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGVtZW50UmFuZ2VBY3RpdmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudFJhbmdlQWN0aXZlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc3RhdGVOYW1lID0gJ2FjdGl2ZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5Zu+6KGo5YWD57SgIEFjdGl2ZVxuICAgICAqL1xuICAgIEVsZW1lbnRSYW5nZUFjdGl2ZS5wcm90b3R5cGUuYWN0aXZlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRWxlbWVudFJhbmdlQWN0aXZlO1xufShyYW5nZV9zdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRSYW5nZUFjdGl2ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJhbmdlLWFjdGl2ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGhpZ2hsaWdodF91dGlsXzEgPSByZXF1aXJlKFwiLi9oaWdobGlnaHQtdXRpbFwiKTtcbnZhciByYW5nZV9zdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcmFuZ2Utc3RhdGVcIikpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDljLrln58gaGlnaGxpZ2h0IOeahCBBY3Rpb25cbiAqL1xudmFyIEVsZW1lbnRSYW5nZUhpZ2hsaWdodCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGVtZW50UmFuZ2VIaWdobGlnaHQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudFJhbmdlSGlnaGxpZ2h0KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc3RhdGVOYW1lID0gJ2FjdGl2ZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLy8g5riF55CG5o6J5omA5pyJ55qEIGFjdGl2Ze+8jCB1bmFjdGl2ZSDnirbmgIFcbiAgICBFbGVtZW50UmFuZ2VIaWdobGlnaHQucHJvdG90eXBlLmNsZWFyVmlld1N0YXRlID0gZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgaGlnaGxpZ2h0X3V0aWxfMS5jbGVhckhpZ2hsaWdodCh2aWV3KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiuvue9riBoaWdobGlnaHRcbiAgICAgKi9cbiAgICBFbGVtZW50UmFuZ2VIaWdobGlnaHQucHJvdG90eXBlLmhpZ2hsaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgpO1xuICAgIH07XG4gICAgRWxlbWVudFJhbmdlSGlnaGxpZ2h0LnByb3RvdHlwZS5zZXRFbGVtZW50c1N0YXRlID0gZnVuY3Rpb24gKGVsZW1lbnRzLCBlbmFibGUsIGFsbEVsZW1lbnRzKSB7XG4gICAgICAgIGhpZ2hsaWdodF91dGlsXzEuc2V0SGlnaGxpZ2h0QnkoYWxsRWxlbWVudHMsIGZ1bmN0aW9uIChlbCkgeyByZXR1cm4gZWxlbWVudHMuaW5kZXhPZihlbCkgPj0gMDsgfSwgZW5hYmxlKTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50UmFuZ2VIaWdobGlnaHQ7XG59KHJhbmdlX3N0YXRlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRWxlbWVudFJhbmdlSGlnaGxpZ2h0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmFuZ2UtaGlnaGxpZ2h0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgcmFuZ2Vfc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3JhbmdlLXN0YXRlXCIpKTtcbi8qKlxuICogQGlnbm9yZVxuICog5Yy65Z+f6YCJ5Lit55qEIEFjdGlvblxuICovXG52YXIgRWxlbWVudFJhbmdlU2VsZWN0ZWQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudFJhbmdlU2VsZWN0ZWQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudFJhbmdlU2VsZWN0ZWQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGF0ZU5hbWUgPSAnc2VsZWN0ZWQnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOmAieS4rVxuICAgICAqL1xuICAgIEVsZW1lbnRSYW5nZVNlbGVjdGVkLnByb3RvdHlwZS5zZWxlY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgpO1xuICAgIH07XG4gICAgcmV0dXJuIEVsZW1lbnRSYW5nZVNlbGVjdGVkO1xufShyYW5nZV9zdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRSYW5nZVNlbGVjdGVkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmFuZ2Utc2VsZWN0ZWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbnZhciBzdGF0ZV9iYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9zdGF0ZS1iYXNlXCIpKTtcbi8qKlxuICogQGlnbm9yZVxuICog5Yy65Z+f6K6+572u54q25oCB55qE5Z+656GAIEFjdGlvblxuICovXG52YXIgRWxlbWVudFJhbmdlU3RhdGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudFJhbmdlU3RhdGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudFJhbmdlU3RhdGUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcbiAgICAgICAgX3RoaXMuZW5kUG9pbnQgPSBudWxsO1xuICAgICAgICBfdGhpcy5pc1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOaYr+WQpuS9nOeUqOS6juW9k+WJjSB2aWV3IOeahCBzaWJsaW5nc++8jOm7mOiupOaYryBmYWxzZSDku4XkvZznlKjkuo7oh6rlt7FcbiAgICAgICAgICovXG4gICAgICAgIF90aGlzLmVmZmVjdFNpYmxpbmdzID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDmmK/lkKblj5cgZWxlbWVudCDnmoTmlbDmja7lvbHlk43vvIzov5jmmK/lj5fljIXlm7Tnm5LnmoTlvbHlk41cbiAgICAgICAgICovXG4gICAgICAgIF90aGlzLmVmZmVjdEJ5UmVjb3JkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLy8g6I635Y+W5b2T5YmN55qE5L2N572uXG4gICAgRWxlbWVudFJhbmdlU3RhdGUucHJvdG90eXBlLmdldEN1cnJlbnRQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5jb250ZXh0LmV2ZW50O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICAgIHk6IGV2ZW50LnksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlvIDlp4vvvIzorrDlvZXlvIDlp4vpgInkuK3nmoTkvY3nva5cbiAgICAgKi9cbiAgICBFbGVtZW50UmFuZ2VTdGF0ZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTsgLy8g5byA5aeL55qE5pe25YCZ5riF55CG5LmL5YmN55qE54q25oCBXG4gICAgICAgIHRoaXMuc3RhcnRQb2ludCA9IHRoaXMuZ2V0Q3VycmVudFBvaW50KCk7XG4gICAgICAgIHRoaXMuaXNTdGFydGVkID0gdHJ1ZTtcbiAgICB9O1xuICAgIEVsZW1lbnRSYW5nZVN0YXRlLnByb3RvdHlwZS5nZXRJbnRlcnNlY3RFbGVtZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gbnVsbDtcbiAgICAgICAgaWYgKHV0aWxfMi5pc01hc2sodGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgZWxlbWVudHMgPSB1dGlsXzIuZ2V0TWFza2VkRWxlbWVudHModGhpcy5jb250ZXh0LCAxMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRQb2ludCA9IHRoaXMuc3RhcnRQb2ludDtcbiAgICAgICAgICAgIHZhciBlbmRQb2ludCA9IHRoaXMuaXNTdGFydGVkID8gdGhpcy5nZXRDdXJyZW50UG9pbnQoKSA6IHRoaXMuZW5kUG9pbnQ7XG4gICAgICAgICAgICAvLyDlpoLmnpzmsqHmnInlvIDlp4vvvIzliJnkuI3lhYHorrjojIPlm7Torr7nva7nirbmgIHvvIzkv53miqTmgKfotKhcbiAgICAgICAgICAgIGlmICghc3RhcnRQb2ludCB8fCAhZW5kUG9pbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDorqHnrpfmoYbpgInljLrln59cbiAgICAgICAgICAgIHZhciBib3ggPSB7XG4gICAgICAgICAgICAgICAgbWluWDogTWF0aC5taW4oc3RhcnRQb2ludC54LCBlbmRQb2ludC54KSxcbiAgICAgICAgICAgICAgICBtaW5ZOiBNYXRoLm1pbihzdGFydFBvaW50LnksIGVuZFBvaW50LnkpLFxuICAgICAgICAgICAgICAgIG1heFg6IE1hdGgubWF4KHN0YXJ0UG9pbnQueCwgZW5kUG9pbnQueCksXG4gICAgICAgICAgICAgICAgbWF4WTogTWF0aC5tYXgoc3RhcnRQb2ludC55LCBlbmRQb2ludC55KSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyB0aGlzLmNsZWFyKCk7IC8vIOS4jeWFqOmDqOa4heeQhu+8jOS8muWvvOiHtOmXqueDgVxuICAgICAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgICAgIGVsZW1lbnRzID0gdXRpbF8yLmdldEludGVyc2VjdEVsZW1lbnRzKHZpZXcsIGJveCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVsZW1lbnRzO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6YCJ5LitXG4gICAgICovXG4gICAgRWxlbWVudFJhbmdlU3RhdGUucHJvdG90eXBlLnNldFN0YXRlRW5hYmxlID0gZnVuY3Rpb24gKGVuYWJsZSkge1xuICAgICAgICBpZiAodGhpcy5lZmZlY3RTaWJsaW5ncyAmJiAhdGhpcy5lZmZlY3RCeVJlY29yZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTaWJsaW5nc1N0YXRlKGVuYWJsZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgYWxsRWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHModGhpcy5jb250ZXh0LnZpZXcpO1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy5nZXRJbnRlcnNlY3RFbGVtZW50cygpO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnRzICYmIGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmVmZmVjdEJ5UmVjb3JkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2libGluZ3NTdGF0ZUJ5UmVjb3JkKGVsZW1lbnRzLCBlbmFibGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50c1N0YXRlKGVsZW1lbnRzLCBlbmFibGUsIGFsbEVsZW1lbnRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIOagueaNrumAieS4reeahCBlbGVtZW50IOeahOaVsOaNrui/m+ihjOiuvue9rueKtuaAgVxuICAgIEVsZW1lbnRSYW5nZVN0YXRlLnByb3RvdHlwZS5zZXRTaWJsaW5nc1N0YXRlQnlSZWNvcmQgPSBmdW5jdGlvbiAoZWxlbWVudHMsIGVuYWJsZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgc2libGluZ3MgPSB1dGlsXzIuZ2V0U2lsYmluZ3Modmlldyk7XG4gICAgICAgIHZhciByZWNvcmRzID0gZWxlbWVudHMubWFwKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgcmV0dXJuIGVsLmdldE1vZGVsKCkuZGF0YTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB4RmlsZWQgPSB2aWV3LmdldFhTY2FsZSgpLmZpZWxkO1xuICAgICAgICB2YXIgeUZpZWxkID0gdmlldy5nZXRZU2NhbGVzKClbMF0uZmllbGQ7XG4gICAgICAgIHV0aWxfMS5lYWNoKHNpYmxpbmdzLCBmdW5jdGlvbiAoc2libGluZykge1xuICAgICAgICAgICAgdmFyIGFsbEVsZW1lbnRzID0gdXRpbF8yLmdldEVsZW1lbnRzKHNpYmxpbmcpO1xuICAgICAgICAgICAgdmFyIGVmZmVjdEVsZW1lbnRzID0gYWxsRWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHZhciByZWNvcmQgPSBlbC5nZXRNb2RlbCgpLmRhdGE7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHV0aWxfMi5pc0luUmVjb3JkcyhyZWNvcmRzLCByZWNvcmQsIHhGaWxlZCwgeUZpZWxkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX3RoaXMuc2V0RWxlbWVudHNTdGF0ZShlZmZlY3RFbGVtZW50cywgZW5hYmxlLCBhbGxFbGVtZW50cyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g6K6+572u5YWE5byfIHZpZXcg55qE54q25oCBXG4gICAgRWxlbWVudFJhbmdlU3RhdGUucHJvdG90eXBlLnNldFNpYmxpbmdzU3RhdGUgPSBmdW5jdGlvbiAoZW5hYmxlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZhciBzaWJsaW5ncyA9IHV0aWxfMi5nZXRTaWxiaW5ncyh2aWV3KTtcbiAgICAgICAgaWYgKHV0aWxfMi5pc01hc2sodGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgLy8g5Y+XIG1hc2sg5b2x5ZONXG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzaWJsaW5ncywgZnVuY3Rpb24gKHNpYmxpbmcpIHtcbiAgICAgICAgICAgICAgICB2YXIgYWxsRWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHMoc2libGluZyk7XG4gICAgICAgICAgICAgICAgdmFyIGVmZmVjdEVsZW1lbnRzID0gdXRpbF8yLmdldFNpYmxpbmdNYXNrRWxlbWVudHMoX3RoaXMuY29udGV4dCwgc2libGluZywgMTApO1xuICAgICAgICAgICAgICAgIGlmIChlZmZlY3RFbGVtZW50cyAmJiBlZmZlY3RFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0RWxlbWVudHNTdGF0ZShlZmZlY3RFbGVtZW50cywgZW5hYmxlLCBhbGxFbGVtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5jbGVhclZpZXdTdGF0ZShzaWJsaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRWxlbWVudFJhbmdlU3RhdGUucHJvdG90eXBlLnNldEVsZW1lbnRzU3RhdGUgPSBmdW5jdGlvbiAoZWxlbWVudHMsIGVuYWJsZSwgYWxsRWxlbWVudHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2goYWxsRWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgaWYgKCFlbGVtZW50cy5pbmNsdWRlcyhlbCkpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRFbGVtZW50U3RhdGUoZWwsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIF90aGlzLnNldEVsZW1lbnRTdGF0ZShlbCwgZW5hYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnu5PmnZ9cbiAgICAgKi9cbiAgICBFbGVtZW50UmFuZ2VTdGF0ZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlzU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVuZFBvaW50ID0gdGhpcy5nZXRDdXJyZW50UG9pbnQoKTtcbiAgICB9O1xuICAgIC8vIOWkjeWGmSBjbGVhclxuICAgIEVsZW1lbnRSYW5nZVN0YXRlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgLy8g5Yik5pat5piv5ZCm5b2x5ZONIHNpYmxpbmdzXG4gICAgICAgIGlmICh0aGlzLmVmZmVjdFNpYmxpbmdzKSB7XG4gICAgICAgICAgICB2YXIgc2libGluZ3MgPSB1dGlsXzIuZ2V0U2lsYmluZ3Modmlldyk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzaWJsaW5ncywgZnVuY3Rpb24gKHNpYmxpbmcpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5jbGVhclZpZXdTdGF0ZShzaWJsaW5nKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jbGVhclZpZXdTdGF0ZSh2aWV3KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIEVsZW1lbnRSYW5nZVN0YXRlO1xufShzdGF0ZV9iYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRWxlbWVudFJhbmdlU3RhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yYW5nZS1zdGF0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHN0YXRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9zdGF0ZVwiKSk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOWFgeiuuOWkmumAieeahCBBY3Rpb25cbiAqIEBjbGFzc1xuICovXG52YXIgRWxlbWVudE11bHRpcGxlU2VsZWN0ZWQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudE11bHRpcGxlU2VsZWN0ZWQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudE11bHRpcGxlU2VsZWN0ZWQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGF0ZU5hbWUgPSAnc2VsZWN0ZWQnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOmAieS4reiKgueCue+8jOWFgeiuuOWkmumAiVxuICAgICAqL1xuICAgIEVsZW1lbnRNdWx0aXBsZVNlbGVjdGVkLnByb3RvdHlwZS5zZWxlY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgpO1xuICAgIH07XG4gICAgcmV0dXJuIEVsZW1lbnRNdWx0aXBsZVNlbGVjdGVkO1xufShzdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRNdWx0aXBsZVNlbGVjdGVkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0ZWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWxcIik7XG4vKipcbiAqIFNpYmxpbmcgZmlsdGVyXG4gKiBAaWdub3JlXG4gKi9cbnZhciBTaWJsaW5nRmlsdGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFNpYmxpbmdGaWx0ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2libGluZ0ZpbHRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmJ5UmVjb3JkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog6L+H5ruk6ZqQ6JeP5Zu+5b2iXG4gICAgICovXG4gICAgU2libGluZ0ZpbHRlci5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDku4XogIPomZEgbWFzayDlr7zoh7TnmoTov4fmu6RcbiAgICAgICAgaWYgKHV0aWxfMi5pc01hc2sodGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuYnlSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlckJ5UmVjb3JkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlckJ5QkJveCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmoLnmja7moYbpgInnmoTorrDlvZXmnaXlgZrov4fmu6RcbiAgICBTaWJsaW5nRmlsdGVyLnByb3RvdHlwZS5maWx0ZXJCeVJlY29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIG1hc2tFbGVtZW50cyA9IHV0aWxfMi5nZXRNYXNrZWRFbGVtZW50cyh0aGlzLmNvbnRleHQsIDEwKTtcbiAgICAgICAgaWYgKCFtYXNrRWxlbWVudHMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgeEZpbGVkID0gdmlldy5nZXRYU2NhbGUoKS5maWVsZDtcbiAgICAgICAgdmFyIHlGaWVsZCA9IHZpZXcuZ2V0WVNjYWxlcygpWzBdLmZpZWxkO1xuICAgICAgICB2YXIgcmVjb3JkcyA9IG1hc2tFbGVtZW50cy5tYXAoZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICByZXR1cm4gZWwuZ2V0TW9kZWwoKS5kYXRhO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHNpYmxpbmdzID0gdXRpbF8yLmdldFNpbGJpbmdzKHZpZXcpO1xuICAgICAgICB1dGlsXzEuZWFjaChzaWJsaW5ncywgZnVuY3Rpb24gKHNpYmxpbmcpIHtcbiAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IHV0aWxfMi5nZXRFbGVtZW50cyhzaWJsaW5nKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVjb3JkID0gZWwuZ2V0TW9kZWwoKS5kYXRhO1xuICAgICAgICAgICAgICAgIC8vIHJlY29yZHMuaW5jbHVkZXMocmVjb3JkKSDkuI3nlJ/mlYjvvIzlupTor6XmmK/mlbDmja7nmoTlvJXnlKjooqvmlLnkuoZcbiAgICAgICAgICAgICAgICBpZiAodXRpbF8yLmlzSW5SZWNvcmRzKHJlY29yZHMsIHJlY29yZCwgeEZpbGVkLCB5RmllbGQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsLnNob3coKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVsLmhpZGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDmoLnmja7ooqvmoYbpgInnmoTljIXlm7Tnm5LlgZrov4fmu6RcbiAgICBTaWJsaW5nRmlsdGVyLnByb3RvdHlwZS5maWx0ZXJCeUJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZhciBzaWJsaW5ncyA9IHV0aWxfMi5nZXRTaWxiaW5ncyh2aWV3KTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2libGluZ3MsIGZ1bmN0aW9uIChzaWJsaW5nKSB7XG4gICAgICAgICAgICB2YXIgbWFza0VsZW1lbnRzID0gdXRpbF8yLmdldFNpYmxpbmdNYXNrRWxlbWVudHMoX3RoaXMuY29udGV4dCwgc2libGluZywgMTApO1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRzID0gdXRpbF8yLmdldEVsZW1lbnRzKHNpYmxpbmcpO1xuICAgICAgICAgICAgaWYgKG1hc2tFbGVtZW50cykge1xuICAgICAgICAgICAgICAgIC8vIG1hc2sg6L+H5bCP5pe26L+U5Zue5Li6IG51bGzvvIzkuI3og73mmK/nqbrmlbDnu4TvvIzlkKbliJnlkIzmnKrmoYbpgInliLDmt7fmt4ZcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXNrRWxlbWVudHMuaW5jbHVkZXMoZWwpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuIXnkIbmiYDmnInpmpDol4/nmoTlm77lvaJcbiAgICAgKi9cbiAgICBTaWJsaW5nRmlsdGVyLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNpYmxpbmdzID0gdXRpbF8yLmdldFNpbGJpbmdzKHRoaXMuY29udGV4dC52aWV3KTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2libGluZ3MsIGZ1bmN0aW9uIChzaWJsaW5nKSB7XG4gICAgICAgICAgICB2YXIgZWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHMoc2libGluZyk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgZWwuc2hvdygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIFNpYmxpbmdGaWx0ZXI7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTaWJsaW5nRmlsdGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2libGluZy1maWx0ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBzaW5nbGVfc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3NpbmdsZS1zdGF0ZVwiKSk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOS7heWFgeiuuOWNleS4qiBFbGVtZW50IEFjdGl2ZSDnmoQgQWN0aW9uXG4gKi9cbnZhciBFbGVtZW50U2luZ2xlQWN0aXZlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEVsZW1lbnRTaW5nbGVBY3RpdmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudFNpbmdsZUFjdGl2ZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnN0YXRlTmFtZSA9ICdhY3RpdmUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOW9k+WJjeS6i+S7tuebuOWFs+eahCBFbGVtZW50IEFjdGl2ZVxuICAgICAqL1xuICAgIEVsZW1lbnRTaW5nbGVBY3RpdmUucHJvdG90eXBlLmFjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgpO1xuICAgIH07XG4gICAgcmV0dXJuIEVsZW1lbnRTaW5nbGVBY3RpdmU7XG59KHNpbmdsZV9zdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRTaW5nbGVBY3RpdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zaW5nbGUtYWN0aXZlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWxcIik7XG52YXIgaGlnaGxpZ2h0X3V0aWxfMSA9IHJlcXVpcmUoXCIuL2hpZ2hsaWdodC11dGlsXCIpO1xudmFyIHNpbmdsZV9zdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vc2luZ2xlLXN0YXRlXCIpKTtcbi8qKlxuICogQGlnbm9yZVxuICog5Y2V5LiqIEVsZW1lbnQgSGlnaGxpZ2h0IOeahCBBY3Rpb25cbiAqL1xudmFyIEVsZW1lbnRTaW5nbGVIaWdobGlnaHQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudFNpbmdsZUhpZ2hsaWdodCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBFbGVtZW50U2luZ2xlSGlnaGxpZ2h0KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc3RhdGVOYW1lID0gJ2FjdGl2ZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRWxlbWVudCBIaWdobGlnaHRcbiAgICAgKi9cbiAgICBFbGVtZW50U2luZ2xlSGlnaGxpZ2h0LnByb3RvdHlwZS5oaWdobGlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKTtcbiAgICB9O1xuICAgIEVsZW1lbnRTaW5nbGVIaWdobGlnaHQucHJvdG90eXBlLnNldEVsZW1lbnRTdGF0ZSA9IGZ1bmN0aW9uIChlbGVtZW50LCBlbmFibGUpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdXRpbF8xLmdldEVsZW1lbnRzKHZpZXcpO1xuICAgICAgICBoaWdobGlnaHRfdXRpbF8xLnNldEhpZ2hsaWdodEJ5KGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHsgcmV0dXJuIGVsZW1lbnQgPT09IGVsOyB9LCBlbmFibGUpO1xuICAgIH07XG4gICAgLy8g5riF55CG5o6J5omA5pyJ55qEIGFjdGl2Ze+8jCB1bmFjdGl2ZSDnirbmgIFcbiAgICBFbGVtZW50U2luZ2xlSGlnaGxpZ2h0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgaGlnaGxpZ2h0X3V0aWxfMS5jbGVhckhpZ2hsaWdodCh2aWV3KTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50U2luZ2xlSGlnaGxpZ2h0O1xufShzaW5nbGVfc3RhdGVfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGVtZW50U2luZ2xlSGlnaGxpZ2h0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2luZ2xlLWhpZ2hsaWdodC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHNpbmdsZV9zdGF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vc2luZ2xlLXN0YXRlXCIpKTtcbi8qKlxuICogQGlnbm9yZVxuICog5Y2V6YCJ55qEIEFjdGlvblxuICovXG52YXIgRWxlbWVudFNpbmdsZVNlbGVjdGVkID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEVsZW1lbnRTaW5nbGVTZWxlY3RlZCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBFbGVtZW50U2luZ2xlU2VsZWN0ZWQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGF0ZU5hbWUgPSAnc2VsZWN0ZWQnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOmAieS4rVxuICAgICAqL1xuICAgIEVsZW1lbnRTaW5nbGVTZWxlY3RlZC5wcm90b3R5cGUuc2VsZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50U2luZ2xlU2VsZWN0ZWQ7XG59KHNpbmdsZV9zdGF0ZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRTaW5nbGVTZWxlY3RlZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNpbmdsZS1zZWxlY3RlZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIHN0YXRlX2Jhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3N0YXRlLWJhc2VcIikpO1xuLyoqXG4gKiDljZXnirbmgIHph4/nmoQgQWN0aW9uIOWfuuexu1xuICogQGNsYXNzXG4gKiBAaWdub3JlXG4gKi9cbnZhciBFbGVtZW50U2luZ2xlU3RhdGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRWxlbWVudFNpbmdsZVN0YXRlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEVsZW1lbnRTaW5nbGVTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBFbGVtZW50U2luZ2xlU3RhdGUucHJvdG90eXBlLnNldFN0YXRlRW5hYmxlID0gZnVuY3Rpb24gKGVuYWJsZSkge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHV0aWxfMS5nZXRDdXJyZW50RWxlbWVudCh0aGlzLmNvbnRleHQpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgLy8g5Zyo5ZCM5LiA5LiqIGVsZW1lbnQg5YaF6YOo56e75Yqo77yM5b+96KeGIGxhYmVsIOWSjCBzaGFwZSDkuYvpl7RcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmlzRWxlbWVudENoYW5nZSh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5LuF5pSv5oyB5Y2V5Liq54q25oCB6YeP55qE5YWD57Sg77yM5Y+q6IO955SxIGVsZW1lbnQg6Kem5Y+RXG4gICAgICAgICAgICBpZiAoZW5hYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudFN0YXRlKGVsZW1lbnQsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5oYXNTdGF0ZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudFN0YXRlKGVsZW1lbnQsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5YiH5o2i6YCJ5Lit77yM5Y+q5YWB6K646YCJ5Lit5LiA5LiqXG4gICAgICovXG4gICAgRWxlbWVudFNpbmdsZVN0YXRlLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50ID0gdXRpbF8xLmdldEN1cnJlbnRFbGVtZW50KHRoaXMuY29udGV4dCk7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICB2YXIgaGFzU3RhdGUgPSB0aGlzLmhhc1N0YXRlKGVsZW1lbnQpOyAvLyDmj5DliY3ojrflj5bnirbmgIFcbiAgICAgICAgICAgIGlmICghaGFzU3RhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldEVsZW1lbnRTdGF0ZShlbGVtZW50LCAhaGFzU3RhdGUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlj5bmtojlvZPliY3ml7bpl7TlvbHlk43nmoTnirbmgIFcbiAgICAgKi9cbiAgICBFbGVtZW50U2luZ2xlU3RhdGUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlRW5hYmxlKGZhbHNlKTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50U2luZ2xlU3RhdGU7XG59KHN0YXRlX2Jhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGVtZW50U2luZ2xlU3RhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zaW5nbGUtc3RhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4uL3V0aWxcIik7XG4vKipcbiAqIOeKtuaAgemHjyBBY3Rpb24g55qE5Z+657G7XG4gKiBAYWJzdHJhY3RcbiAqIEBjbGFzc1xuICogQGlnbm9yZVxuICovXG52YXIgU3RhdGVCYXNlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YXRlQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGF0ZUJhc2UoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICAvKipcbiAgICAgICAgICog54q25oCB5ZCN56ewXG4gICAgICAgICAqL1xuICAgICAgICBfdGhpcy5zdGF0ZU5hbWUgPSAnJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDmmK/lkKblhbfmnInmn5DkuKrnirbmgIFcbiAgICAgKiBAcGFyYW0gZWxlbWVudCDlm77ooaggRWxlbWVudCDlhYPntKBcbiAgICAgKi9cbiAgICBTdGF0ZUJhc2UucHJvdG90eXBlLmhhc1N0YXRlID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQuaGFzU3RhdGUodGhpcy5zdGF0ZU5hbWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6K6+572u54q25oCB5r+A5rS7XG4gICAgICogQHBhcmFtIGVuYWJsZSDnirbmgIHlgLxcbiAgICAgKi9cbiAgICBTdGF0ZUJhc2UucHJvdG90eXBlLnNldEVsZW1lbnRTdGF0ZSA9IGZ1bmN0aW9uIChlbGVtZW50LCBlbmFibGUpIHtcbiAgICAgICAgLy8g6Ziy5q2i6Zeq54OBXG4gICAgICAgIGVsZW1lbnQuc2V0U3RhdGUodGhpcy5zdGF0ZU5hbWUsIGVuYWJsZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDorr7nva7nirbmgIFcbiAgICAgKi9cbiAgICBTdGF0ZUJhc2UucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlRW5hYmxlKHRydWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5riF6Zmk5omA5pyJIEVsZW1lbnQg55qE54q25oCBXG4gICAgICovXG4gICAgU3RhdGVCYXNlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdGhpcy5jbGVhclZpZXdTdGF0ZSh2aWV3KTtcbiAgICB9O1xuICAgIFN0YXRlQmFzZS5wcm90b3R5cGUuY2xlYXJWaWV3U3RhdGUgPSBmdW5jdGlvbiAodmlldykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZWxlbWVudHMgPSB1dGlsXzIuZ2V0RWxlbWVudHNCeVN0YXRlKHZpZXcsIHRoaXMuc3RhdGVOYW1lKTtcbiAgICAgICAgdXRpbF8xLmVhY2goZWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgX3RoaXMuc2V0RWxlbWVudFN0YXRlKGVsLCBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIFN0YXRlQmFzZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YXRlQmFzZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRlLWJhc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbnZhciBzdGF0ZV9iYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9zdGF0ZS1iYXNlXCIpKTtcbmZ1bmN0aW9uIGdldEl0ZW0oc2hhcGUpIHtcbiAgICByZXR1cm4gdXRpbF8xLmdldChzaGFwZS5nZXQoJ2RlbGVnYXRlT2JqZWN0JyksICdpdGVtJyk7XG59XG4vKipcbiAqIOeKtuaAgemHjyBBY3Rpb24g55qE5Z+657G777yM5YWB6K645aSa5LiqIEVsZW1lbnQg5ZCM5pe25oul5pyJ5p+Q5Liq54q25oCBXG4gKiBAY2xhc3NcbiAqIEBpZ25vcmVcbiAqL1xudmFyIEVsZW1lbnRTdGF0ZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhFbGVtZW50U3RhdGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRWxlbWVudFN0YXRlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuaWdub3JlTGlzdEl0ZW1TdGF0ZXMgPSBbJ3VuY2hlY2tlZCddO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8vIOaYr+WQpuW/veeVpeinpuWPkeeahOWIl+ihqOmhuVxuICAgIEVsZW1lbnRTdGF0ZS5wcm90b3R5cGUuaXNJdGVtSWdub3JlID0gZnVuY3Rpb24gKGl0ZW0sIGxpc3QpIHtcbiAgICAgICAgdmFyIHN0YXRlcyA9IHRoaXMuaWdub3JlTGlzdEl0ZW1TdGF0ZXM7XG4gICAgICAgIHZhciBmaWx0ZXJlZCA9IHN0YXRlcy5maWx0ZXIoZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdC5oYXNTdGF0ZShpdGVtLCBzdGF0ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gISFmaWx0ZXJlZC5sZW5ndGg7XG4gICAgfTtcbiAgICAvLyDorr7nva7nlLHnu4Tku7bpgInpobnlr7zoh7TnmoTnirbmgIHlj5jljJZcbiAgICBFbGVtZW50U3RhdGUucHJvdG90eXBlLnNldFN0YXRlQnlDb21wb25lbnQgPSBmdW5jdGlvbiAoY29tcG9uZW50LCBpdGVtLCBlbmFibGUpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGZpZWxkID0gY29tcG9uZW50LmdldCgnZmllbGQnKTtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdXRpbF8yLmdldEVsZW1lbnRzKHZpZXcpO1xuICAgICAgICB0aGlzLnNldEVsZW1lbnRzU3RhdGVCeUl0ZW0oZWxlbWVudHMsIGZpZWxkLCBpdGVtLCBlbmFibGUpO1xuICAgIH07XG4gICAgLy8g5aSE55CG6Kem5Y+R5rqQ55SxIGVsZW1lbnQg5a+86Ie055qE54q25oCB5Y+Y5YyWXG4gICAgRWxlbWVudFN0YXRlLnByb3RvdHlwZS5zZXRTdGF0ZUJ5RWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50LCBlbmFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRFbGVtZW50U3RhdGUoZWxlbWVudCwgZW5hYmxlKTtcbiAgICB9O1xuICAgIC8qKiDnu4Tku7bnmoTpgInpobnmmK/lkKblkIwgZWxlbWVudCDljLnphY0gKi9cbiAgICBFbGVtZW50U3RhdGUucHJvdG90eXBlLmlzTWF0aEl0ZW0gPSBmdW5jdGlvbiAoZWxlbWVudCwgZmllbGQsIGl0ZW0pIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIHNjYWxlID0gdXRpbF8yLmdldFNjYWxlQnlGaWVsZCh2aWV3LCBmaWVsZCk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHV0aWxfMi5nZXRFbGVtZW50VmFsdWUoZWxlbWVudCwgZmllbGQpO1xuICAgICAgICByZXR1cm4gIXV0aWxfMS5pc05pbCh2YWx1ZSkgJiYgaXRlbS5uYW1lID09PSBzY2FsZS5nZXRUZXh0KHZhbHVlKTtcbiAgICB9O1xuICAgIEVsZW1lbnRTdGF0ZS5wcm90b3R5cGUuc2V0RWxlbWVudHNTdGF0ZUJ5SXRlbSA9IGZ1bmN0aW9uIChlbGVtZW50cywgZmllbGQsIGl0ZW0sIGVuYWJsZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMuaXNNYXRoSXRlbShlbCwgZmllbGQsIGl0ZW0pKSB7XG4gICAgICAgICAgICAgICAgZWwuc2V0U3RhdGUoX3RoaXMuc3RhdGVOYW1lLCBlbmFibGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDorr7nva7nirbmgIHmmK/lkKbmv4DmtLsgKi9cbiAgICBFbGVtZW50U3RhdGUucHJvdG90eXBlLnNldFN0YXRlRW5hYmxlID0gZnVuY3Rpb24gKGVuYWJsZSkge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHV0aWxfMi5nZXRDdXJyZW50RWxlbWVudCh0aGlzLmNvbnRleHQpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgLy8g6Kem5Y+R5rqQ55Sx5LqOIGVsZW1lbnQg5a+86Ie0XG4gICAgICAgICAgICBpZiAodXRpbF8yLmlzRWxlbWVudENoYW5nZSh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZUJ5RWxlbWVudChlbGVtZW50LCBlbmFibGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g6Kem5Y+R5rqQ55Sx57uE5Lu25a+86Ie0XG4gICAgICAgICAgICB2YXIgZGVsZWdhdGVPYmplY3QgPSB1dGlsXzIuZ2V0RGVsZWdhdGlvbk9iamVjdCh0aGlzLmNvbnRleHQpO1xuICAgICAgICAgICAgLy8g5aaC5p6c6Kem5Y+R5rqQ5pe25YiX6KGo77yM5Zu+5L6L44CB5Z2Q5qCH6L20XG4gICAgICAgICAgICBpZiAodXRpbF8yLmlzTGlzdChkZWxlZ2F0ZU9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGRlbGVnYXRlT2JqZWN0Lml0ZW0sIGNvbXBvbmVudCA9IGRlbGVnYXRlT2JqZWN0LmNvbXBvbmVudDtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbSAmJiBjb21wb25lbnQgJiYgIXRoaXMuaXNJdGVtSWdub3JlKGl0ZW0sIGNvbXBvbmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50XzEgPSB0aGlzLmNvbnRleHQuZXZlbnQuZ0V2ZW50O1xuICAgICAgICAgICAgICAgICAgICAvLyDpmLLmraLpl6rng4FcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50XzEgJiYgZXZlbnRfMS5mcm9tU2hhcGUgJiYgZXZlbnRfMS50b1NoYXBlICYmIGdldEl0ZW0oZXZlbnRfMS5mcm9tU2hhcGUpID09PSBnZXRJdGVtKGV2ZW50XzEudG9TaGFwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlQnlDb21wb25lbnQoY29tcG9uZW50LCBpdGVtLCBlbmFibGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5YiH5o2i54q25oCBXG4gICAgICovXG4gICAgRWxlbWVudFN0YXRlLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50ID0gdXRpbF8yLmdldEN1cnJlbnRFbGVtZW50KHRoaXMuY29udGV4dCk7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICB2YXIgaGFzU3RhdGUgPSBlbGVtZW50Lmhhc1N0YXRlKHRoaXMuc3RhdGVOYW1lKTtcbiAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudFN0YXRlKGVsZW1lbnQsICFoYXNTdGF0ZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWPlua2iOW9k+WJjeaXtumXtOW9seWTjeeahOeKtuaAgVxuICAgICAqL1xuICAgIEVsZW1lbnRTdGF0ZS5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGVFbmFibGUoZmFsc2UpO1xuICAgIH07XG4gICAgcmV0dXJuIEVsZW1lbnRTdGF0ZTtcbn0oc3RhdGVfYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEVsZW1lbnRTdGF0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7IC8vIOWvvOWHuiBBY3Rpb24g5Z+657G7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBY3Rpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJhc2VfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHJlZ2lzdGVyXzEgPSByZXF1aXJlKFwiLi9yZWdpc3RlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImNyZWF0ZUFjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVnaXN0ZXJfMS5jcmVhdGVBY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckFjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVnaXN0ZXJfMS5yZWdpc3RlckFjdGlvbjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldEFjdGlvbkNsYXNzXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiByZWdpc3Rlcl8xLmdldEFjdGlvbkNsYXNzOyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOi+heWKqeahhiBBY3Rpb24g55qE5Z+657G7XG4gKi9cbnZhciBNYXNrQmFzZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhNYXNrQmFzZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBNYXNrQmFzZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIC8vIG1hc2sg5Zu+5b2iXG4gICAgICAgIF90aGlzLm1hc2tTaGFwZSA9IG51bGw7XG4gICAgICAgIC8vIOe7hOaIkCBtYXNrIOeahOWQhOS4queCuVxuICAgICAgICBfdGhpcy5wb2ludHMgPSBbXTtcbiAgICAgICAgLy8g5byA5aeLIG1hc2sg55qE5qCH6K6wXG4gICAgICAgIF90aGlzLnN0YXJ0aW5nID0gZmFsc2U7XG4gICAgICAgIC8vIOW8gOWni+enu+WKqOeahOagh+iusFxuICAgICAgICBfdGhpcy5tb3ZpbmcgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMucHJlTW92ZVBvaW50ID0gbnVsbDtcbiAgICAgICAgX3RoaXMuc2hhcGVUeXBlID0gJ3BhdGgnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8vIOiOt+WPluW9k+WJjeeahOS9jee9rlxuICAgIE1hc2tCYXNlLnByb3RvdHlwZS5nZXRDdXJyZW50UG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBldmVudCA9IHRoaXMuY29udGV4dC5ldmVudDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGV2ZW50LngsXG4gICAgICAgICAgICB5OiBldmVudC55LFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLy8g6Kem5Y+RIG1hc2sg55qE5LqL5Lu2XG4gICAgTWFza0Jhc2UucHJvdG90eXBlLmVtaXRFdmVudCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIHZhciBldmVudE5hbWUgPSBcIm1hc2s6XCIgKyB0eXBlO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICB2YXIgZXZlbnQgPSB0aGlzLmNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHZpZXcuZW1pdChldmVudE5hbWUsIHtcbiAgICAgICAgICAgIHRhcmdldDogdGhpcy5tYXNrU2hhcGUsXG4gICAgICAgICAgICBzaGFwZTogdGhpcy5tYXNrU2hhcGUsXG4gICAgICAgICAgICBwb2ludHM6IHRoaXMucG9pbnRzLFxuICAgICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICAgIHk6IGV2ZW50LnksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8g5Yib5bu6IG1hc2tcbiAgICBNYXNrQmFzZS5wcm90b3R5cGUuY3JlYXRlTWFzayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIG1hc2tBdHRycyA9IHRoaXMuZ2V0TWFza0F0dHJzKCk7XG4gICAgICAgIHZhciBtYXNrU2hhcGUgPSB2aWV3LmZvcmVncm91bmRHcm91cC5hZGRTaGFwZSh7XG4gICAgICAgICAgICB0eXBlOiB0aGlzLnNoYXBlVHlwZSxcbiAgICAgICAgICAgIG5hbWU6ICdtYXNrJyxcbiAgICAgICAgICAgIGRyYWdnYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgZmlsbDogJyNDNUQ0RUInLCBvcGFjaXR5OiAwLjMgfSwgbWFza0F0dHJzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtYXNrU2hhcGU7XG4gICAgfTtcbiAgICAvLyDnlJ/miJAgbWFzayDnmoTot6/lvoRcbiAgICBNYXNrQmFzZS5wcm90b3R5cGUuZ2V0TWFza1BhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYvuekulxuICAgICAqL1xuICAgIE1hc2tCYXNlLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5tYXNrU2hhcGUpIHtcbiAgICAgICAgICAgIHRoaXMubWFza1NoYXBlLnNob3coKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzaG93Jyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOW8gOWni1xuICAgICAqL1xuICAgIE1hc2tCYXNlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zdGFydGluZyA9IHRydWU7XG4gICAgICAgIC8vIOW8gOWni+aXtu+8jOS/neivgeenu+WKqOe7k+adn1xuICAgICAgICB0aGlzLm1vdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBvaW50cyA9IFt0aGlzLmdldEN1cnJlbnRQb2ludCgpXTtcbiAgICAgICAgaWYgKCF0aGlzLm1hc2tTaGFwZSkge1xuICAgICAgICAgICAgdGhpcy5tYXNrU2hhcGUgPSB0aGlzLmNyZWF0ZU1hc2soKTtcbiAgICAgICAgICAgIC8vIOW8gOWni+aXtuiuvue9riBjYXB0dXJlOiBmYWxzZe+8jOWPr+S7pemBv+WFjeWIm+W7uuOAgXJlc2l6ZSDml7bop6blj5Hkuovku7ZcbiAgICAgICAgICAgIHRoaXMubWFza1NoYXBlLnNldCgnY2FwdHVyZScsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZU1hc2soKTtcbiAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0YXJ0Jyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlvIDlp4vnp7vliqhcbiAgICAgKi9cbiAgICBNYXNrQmFzZS5wcm90b3R5cGUubW92ZVN0YXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm1vdmluZyA9IHRydWU7XG4gICAgICAgIHRoaXMucHJlTW92ZVBvaW50ID0gdGhpcy5nZXRDdXJyZW50UG9pbnQoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOenu+WKqCBtYXNrXG4gICAgICovXG4gICAgTWFza0Jhc2UucHJvdG90eXBlLm1vdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5tb3ZpbmcgfHwgIXRoaXMubWFza1NoYXBlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGN1cnJlbnRQb2ludCA9IHRoaXMuZ2V0Q3VycmVudFBvaW50KCk7XG4gICAgICAgIHZhciBwcmVNb3ZlUG9pbnQgPSB0aGlzLnByZU1vdmVQb2ludDtcbiAgICAgICAgdmFyIGR4ID0gY3VycmVudFBvaW50LnggLSBwcmVNb3ZlUG9pbnQueDtcbiAgICAgICAgdmFyIGR5ID0gY3VycmVudFBvaW50LnkgLSBwcmVNb3ZlUG9pbnQueTtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMucG9pbnRzO1xuICAgICAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICAgICAgcG9pbnQueCArPSBkeDtcbiAgICAgICAgICAgIHBvaW50LnkgKz0gZHk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwZGF0ZU1hc2soKTtcbiAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2NoYW5nZScpO1xuICAgICAgICB0aGlzLnByZU1vdmVQb2ludCA9IGN1cnJlbnRQb2ludDtcbiAgICB9O1xuICAgIE1hc2tCYXNlLnByb3RvdHlwZS51cGRhdGVNYXNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmdldE1hc2tBdHRycygpO1xuICAgICAgICB0aGlzLm1hc2tTaGFwZS5hdHRyKGF0dHJzKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe7k+adn+enu+WKqFxuICAgICAqL1xuICAgIE1hc2tCYXNlLnByb3RvdHlwZS5tb3ZlRW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm1vdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnByZU1vdmVQb2ludCA9IG51bGw7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnu5PmnZ9cbiAgICAgKi9cbiAgICBNYXNrQmFzZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnN0YXJ0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZW1pdEV2ZW50KCdlbmQnKTtcbiAgICAgICAgaWYgKHRoaXMubWFza1NoYXBlKSB7XG4gICAgICAgICAgICB0aGlzLm1hc2tTaGFwZS5zZXQoJ2NhcHR1cmUnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZqQ6JePXG4gICAgICovXG4gICAgTWFza0Jhc2UucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm1hc2tTaGFwZSkge1xuICAgICAgICAgICAgdGhpcy5tYXNrU2hhcGUuaGlkZSgpO1xuICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2hpZGUnKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5aSn5bCP5Y+Y5YyWXG4gICAgICovXG4gICAgTWFza0Jhc2UucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g5Y+q5pyJ6L+b6KGM5Lit77yM5omN5Lya5YWB6K645aSn5bCP5Y+Y5YyWXG4gICAgICAgIGlmICh0aGlzLnN0YXJ0aW5nICYmIHRoaXMubWFza1NoYXBlKSB7XG4gICAgICAgICAgICB0aGlzLnBvaW50cy5wdXNoKHRoaXMuZ2V0Q3VycmVudFBvaW50KCkpO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVNYXNrKCk7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnY2hhbmdlJyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOmUgOavgVxuICAgICAqL1xuICAgIE1hc2tCYXNlLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnBvaW50cyA9IFtdO1xuICAgICAgICBpZiAodGhpcy5tYXNrU2hhcGUpIHtcbiAgICAgICAgICAgIHRoaXMubWFza1NoYXBlLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWFza1NoYXBlID0gbnVsbDtcbiAgICAgICAgdGhpcy5wcmVNb3ZlUG9pbnQgPSBudWxsO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIHJldHVybiBNYXNrQmFzZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1hc2tCYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2Jhc2VcIikpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDlnIblvaLovoXliqnmoYYgQWN0aW9uXG4gKi9cbnZhciBDaXJjbGVNYXNrID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENpcmNsZU1hc2ssIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ2lyY2xlTWFzaygpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnNoYXBlVHlwZSA9ICdjaXJjbGUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIENpcmNsZU1hc2sucHJvdG90eXBlLmdldE1hc2tBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMucG9pbnRzO1xuICAgICAgICB2YXIgY3VycmVudFBvaW50ID0gdXRpbF8xLmxhc3QodGhpcy5wb2ludHMpO1xuICAgICAgICB2YXIgciA9IDA7XG4gICAgICAgIHZhciB4ID0gMDtcbiAgICAgICAgdmFyIHkgPSAwO1xuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIGZpcnN0ID0gcG9pbnRzWzBdO1xuICAgICAgICAgICAgciA9IHV0aWxfMi5kaXN0YW5jZShmaXJzdCwgY3VycmVudFBvaW50KSAvIDI7XG4gICAgICAgICAgICB4ID0gKGN1cnJlbnRQb2ludC54ICsgZmlyc3QueCkgLyAyO1xuICAgICAgICAgICAgeSA9IChjdXJyZW50UG9pbnQueSArIGZpcnN0LnkpIC8gMjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICByOiByLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIENpcmNsZU1hc2s7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDaXJjbGVNYXNrO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2lyY2xlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcmVjdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcmVjdFwiKSk7XG5mdW5jdGlvbiBjbGFtcFBvaW50KHBvaW50KSB7XG4gICAgcG9pbnQueCA9IHV0aWxfMS5jbGFtcChwb2ludC54LCAwLCAxKTtcbiAgICBwb2ludC55ID0gdXRpbF8xLmNsYW1wKHBvaW50LnksIDAsIDEpO1xufVxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbnZhciBEaW1SZWN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERpbVJlY3QsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRGltUmVjdCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmRpbSA9ICd4JztcbiAgICAgICAgX3RoaXMuaW5QbG90ID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBEaW1SZWN0LnByb3RvdHlwZS5nZXRSZWdpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFydCA9IG51bGw7XG4gICAgICAgIHZhciBlbmQgPSBudWxsO1xuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5wb2ludHM7XG4gICAgICAgIHZhciBkaW0gPSB0aGlzLmRpbTtcbiAgICAgICAgdmFyIGNvb3JkID0gdGhpcy5jb250ZXh0LnZpZXcuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgbm9ybWFsU3RhcnQgPSBjb29yZC5pbnZlcnQodXRpbF8xLmhlYWQocG9pbnRzKSk7XG4gICAgICAgIHZhciBub3JtYWxFbmQgPSBjb29yZC5pbnZlcnQodXRpbF8xLmxhc3QocG9pbnRzKSk7XG4gICAgICAgIGlmICh0aGlzLmluUGxvdCkge1xuICAgICAgICAgICAgLy8g57qm5p2f5YiwIDAgLSAxIOiMg+WbtOWGhVxuICAgICAgICAgICAgY2xhbXBQb2ludChub3JtYWxTdGFydCk7XG4gICAgICAgICAgICBjbGFtcFBvaW50KG5vcm1hbEVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRpbSA9PT0gJ3gnKSB7XG4gICAgICAgICAgICAvLyB4IOi9tOaWueWQkeaJqeWxlSwgeSDovbTmlrnlkJHljaDmu6Hlhajpg6hcbiAgICAgICAgICAgIHN0YXJ0ID0gY29vcmQuY29udmVydCh7XG4gICAgICAgICAgICAgICAgeDogbm9ybWFsU3RhcnQueCxcbiAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBlbmQgPSBjb29yZC5jb252ZXJ0KHtcbiAgICAgICAgICAgICAgICB4OiBub3JtYWxFbmQueCxcbiAgICAgICAgICAgICAgICB5OiAxLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyB5IOi9tOaWueWQkeaJqeWxlSwgeCDovbTmlrnlkJHljaDmu6Hlhajpg6hcbiAgICAgICAgICAgIHN0YXJ0ID0gY29vcmQuY29udmVydCh7XG4gICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICB5OiBub3JtYWxTdGFydC55LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBlbmQgPSBjb29yZC5jb252ZXJ0KHtcbiAgICAgICAgICAgICAgICB4OiAxLFxuICAgICAgICAgICAgICAgIHk6IG5vcm1hbEVuZC55LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogZW5kLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIERpbVJlY3Q7XG59KHJlY3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEaW1SZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGltLXJlY3QuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbi8qKlxuICogQGlnbm9yZVxuICog5aSa5Liq54K55p6E5oiQ55qEIFBhdGgg6L6F5Yqp5qGGIEFjdGlvblxuICovXG52YXIgUGF0aE1hc2sgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGF0aE1hc2ssIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUGF0aE1hc2soKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLy8g55Sf5oiQIG1hc2sg55qE6Lev5b6EXG4gICAgUGF0aE1hc2sucHJvdG90eXBlLmdldE1hc2tQYXRoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5wb2ludHM7XG4gICAgICAgIHZhciBwYXRoID0gW107XG4gICAgICAgIGlmIChwb2ludHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50LngsIHBvaW50LnldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHBhdGgucHVzaChbJ0wnLCBwb2ludC54LCBwb2ludC55XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydMJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfTtcbiAgICBQYXRoTWFzay5wcm90b3R5cGUuZ2V0TWFza0F0dHJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGF0aDogdGhpcy5nZXRNYXNrUGF0aCgpLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5re75Yqg5LiA5Liq54K5XG4gICAgICovXG4gICAgUGF0aE1hc2sucHJvdG90eXBlLmFkZFBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlc2l6ZSgpO1xuICAgIH07XG4gICAgcmV0dXJuIFBhdGhNYXNrO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUGF0aE1hc2s7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXRoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOefqeW9oueahOi+heWKqeahhiBBY3Rpb25cbiAqL1xudmFyIFJlY3RNYXNrID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJlY3RNYXNrLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJlY3RNYXNrKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuc2hhcGVUeXBlID0gJ3JlY3QnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFJlY3RNYXNrLnByb3RvdHlwZS5nZXRSZWdpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLnBvaW50cztcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiB1dGlsXzEuaGVhZChwb2ludHMpLFxuICAgICAgICAgICAgZW5kOiB1dGlsXzEubGFzdChwb2ludHMpLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLy8g5re75Yqg5Zu+5b2iXG4gICAgUmVjdE1hc2sucHJvdG90eXBlLmdldE1hc2tBdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRSZWdpb24oKSwgc3RhcnQgPSBfYS5zdGFydCwgZW5kID0gX2EuZW5kO1xuICAgICAgICB2YXIgeCA9IE1hdGgubWluKHN0YXJ0LngsIGVuZC54KTtcbiAgICAgICAgdmFyIHkgPSBNYXRoLm1pbihzdGFydC55LCBlbmQueSk7XG4gICAgICAgIHZhciB3aWR0aCA9IE1hdGguYWJzKGVuZC54IC0gc3RhcnQueCk7XG4gICAgICAgIHZhciBoZWlnaHQgPSBNYXRoLmFicyhlbmQueSAtIHN0YXJ0LnkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBSZWN0TWFzaztcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFJlY3RNYXNrO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIHBhdGhfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3BhdGhcIikpO1xuLyoqXG4gKiBTbW9vdGggcGF0aCBtYXNrXG4gKiBAaWdub3JlXG4gKi9cbnZhciBTbW9vdGhQYXRoTWFzayA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTbW9vdGhQYXRoTWFzaywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTbW9vdGhQYXRoTWFzaygpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvLyDnlJ/miJAgbWFzayDnmoTot6/lvoRcbiAgICBTbW9vdGhQYXRoTWFzay5wcm90b3R5cGUuZ2V0TWFza1BhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSB0aGlzLnBvaW50cztcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5nZXRTcGxpbmUocG9pbnRzLCB0cnVlKTtcbiAgICB9O1xuICAgIHJldHVybiBTbW9vdGhQYXRoTWFzaztcbn0ocGF0aF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNtb290aFBhdGhNYXNrO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c21vb3RoLXBhdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNyZWF0ZUNhbGxiYWNrQWN0aW9uID0gZXhwb3J0cy51bnJlZ2lzdGVyQWN0aW9uID0gZXhwb3J0cy5yZWdpc3RlckFjdGlvbiA9IGV4cG9ydHMuZ2V0QWN0aW9uQ2xhc3MgPSBleHBvcnRzLmNyZWF0ZUFjdGlvbiA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGNhbGxiYWNrXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jYWxsYmFja1wiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vLyBBY3Rpb24g57G755qE57yT5a2YXG52YXIgQWN0aW9uQ2FjaGUgPSB7fTtcbi8qKlxuICog5qC55o2u5ZCN56ew6I635Y+WIEFjdGlvbiDlrp7kvotcbiAqIEBwYXJhbSBhY3Rpb25OYW1lIC0gYWN0aW9uIOeahOWQjeensFxuICogQHBhcmFtIGNvbnRleHQg5LiK5LiL5paHXG4gKiBAcmV0dXJucyBBY3Rpb24g5a6e5L6LXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUFjdGlvbihhY3Rpb25OYW1lLCBjb250ZXh0KSB7XG4gICAgdmFyIGFjdGlvbk9wdGlvbiA9IEFjdGlvbkNhY2hlW2FjdGlvbk5hbWVdO1xuICAgIHZhciBhY3Rpb24gPSBudWxsO1xuICAgIGlmIChhY3Rpb25PcHRpb24pIHtcbiAgICAgICAgdmFyIEFjdGlvbkNsYXNzID0gYWN0aW9uT3B0aW9uLkFjdGlvbkNsYXNzLCBjZmcgPSBhY3Rpb25PcHRpb24uY2ZnO1xuICAgICAgICBhY3Rpb24gPSBuZXcgQWN0aW9uQ2xhc3MoY29udGV4dCwgY2ZnKTtcbiAgICAgICAgYWN0aW9uLm5hbWUgPSBhY3Rpb25OYW1lO1xuICAgICAgICBhY3Rpb24uaW5pdCgpO1xuICAgIH1cbiAgICByZXR1cm4gYWN0aW9uO1xufVxuZXhwb3J0cy5jcmVhdGVBY3Rpb24gPSBjcmVhdGVBY3Rpb247XG4vKipcbiAqIOagueaNriBhY3Rpb24g55qEIG5hbWUg6I635Y+W5a6a5LmJ55qE57G7XG4gKiBAcGFyYW0gYWN0aW9uTmFtZSBhY3Rpb24g55qEIG5hbWVcbiAqL1xuZnVuY3Rpb24gZ2V0QWN0aW9uQ2xhc3MoYWN0aW9uTmFtZSkge1xuICAgIHZhciBhY3Rpb25PcHRpb24gPSBBY3Rpb25DYWNoZVthY3Rpb25OYW1lXTtcbiAgICByZXR1cm4gdXRpbF8xLmdldChhY3Rpb25PcHRpb24sICdBY3Rpb25DbGFzcycpO1xufVxuZXhwb3J0cy5nZXRBY3Rpb25DbGFzcyA9IGdldEFjdGlvbkNsYXNzO1xuLyoqXG4gKiDms6jlhowgQWN0aW9uXG4gKiBAcGFyYW0gYWN0aW9uTmFtZSAtIGFjdGlvbiDnmoTlkI3np7BcbiAqIEBwYXJhbSBBY3Rpb25DbGFzcyAtIOe7p+aJv+iHqiBhY3Rpb24g55qE57G7XG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyQWN0aW9uKGFjdGlvbk5hbWUsIEFjdGlvbkNsYXNzLCBjZmcpIHtcbiAgICBBY3Rpb25DYWNoZVthY3Rpb25OYW1lXSA9IHtcbiAgICAgICAgQWN0aW9uQ2xhc3M6IEFjdGlvbkNsYXNzLFxuICAgICAgICBjZmc6IGNmZyxcbiAgICB9O1xufVxuZXhwb3J0cy5yZWdpc3RlckFjdGlvbiA9IHJlZ2lzdGVyQWN0aW9uO1xuLyoqXG4gKiDlj5bmtojms6jlhowgQWN0aW9uXG4gKiBAcGFyYW0gYWN0aW9uTmFtZSBhY3Rpb24g5ZCN56ewXG4gKi9cbmZ1bmN0aW9uIHVucmVnaXN0ZXJBY3Rpb24oYWN0aW9uTmFtZSkge1xuICAgIGRlbGV0ZSBBY3Rpb25DYWNoZVthY3Rpb25OYW1lXTtcbn1cbmV4cG9ydHMudW5yZWdpc3RlckFjdGlvbiA9IHVucmVnaXN0ZXJBY3Rpb247XG4vKipcbiAqIOagueaNruWbnuiwg+WHveaVsOiOt+WPliBBY3Rpb24g5a6e5L6LXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBhY3Rpb24g55qE5Zue6LCD5Ye95pWwXG4gKiBAcGFyYW0gY29udGV4dCDkuIrkuIvmlodcbiAqIEByZXR1cm5zIEFjdGlvbiDlrp7kvotcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FsbGJhY2tBY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgYWN0aW9uID0gbmV3IGNhbGxiYWNrXzEuZGVmYXVsdChjb250ZXh0KTtcbiAgICBhY3Rpb24uY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICBhY3Rpb24ubmFtZSA9ICdjYWxsYmFjayc7XG4gICAgcmV0dXJuIGFjdGlvbjtcbn1cbmV4cG9ydHMuY3JlYXRlQ2FsbGJhY2tBY3Rpb24gPSBjcmVhdGVDYWxsYmFja0FjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlZ2lzdGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRTY2FsZUJ5RmllbGQgPSBleHBvcnRzLmlzSW5SZWNvcmRzID0gZXhwb3J0cy5nZXRTaWJsaW5nUG9pbnQgPSBleHBvcnRzLmdldFNpbGJpbmdzID0gZXhwb3J0cy5pc0luQm94ID0gZXhwb3J0cy5nZXRTcGxpbmUgPSBleHBvcnRzLmRpc3RhbmNlID0gZXhwb3J0cy5nZXRDb21wb25lbnRzID0gZXhwb3J0cy5nZXRFbGVtZW50c0J5UGF0aCA9IGV4cG9ydHMuZ2V0SW50ZXJzZWN0RWxlbWVudHMgPSBleHBvcnRzLmludGVyc2VjdFJlY3QgPSBleHBvcnRzLmdldEVsZW1lbnRWYWx1ZSA9IGV4cG9ydHMuZ2V0RWxlbWVudHNCeVN0YXRlID0gZXhwb3J0cy5nZXRFbGVtZW50c0J5RmllbGQgPSBleHBvcnRzLmdldEVsZW1lbnRzID0gZXhwb3J0cy5nZXRTaWJsaW5nTWFza0VsZW1lbnRzID0gZXhwb3J0cy5nZXRNYXNrZWRFbGVtZW50cyA9IGV4cG9ydHMuaXNNYXNrID0gZXhwb3J0cy5pc1NsaWRlciA9IGV4cG9ydHMuaXNMaXN0ID0gZXhwb3J0cy5pc0VsZW1lbnRDaGFuZ2UgPSBleHBvcnRzLmdldERlbGVnYXRpb25PYmplY3QgPSBleHBvcnRzLmdldEN1cnJlbnRFbGVtZW50ID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGF0aF8xID0gcmVxdWlyZShcIi4uLy4uL2dlb21ldHJ5L3NoYXBlL3V0aWwvcGF0aFwiKTtcbnZhciBiYm94XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9iYm94XCIpO1xudmFyIGlzX3BvbHlnb25zX2ludGVyc2VjdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIkBhbnR2L3BhdGgtdXRpbC9saWIvaXMtcG9seWdvbnMtaW50ZXJzZWN0XCIpKTtcbmZ1bmN0aW9uIGdldE1hc2tCQm94KGNvbnRleHQsIHRvbGVyYW5jZSkge1xuICAgIHZhciBldmVudCA9IGNvbnRleHQuZXZlbnQ7XG4gICAgdmFyIG1hc2tTaGFwZSA9IGV2ZW50LnRhcmdldDtcbiAgICB2YXIgbWFza0JCb3ggPSBtYXNrU2hhcGUuZ2V0Q2FudmFzQkJveCgpO1xuICAgIC8vIOWmguaenCBiYm94IOi/h+Wwj+WImeS4jei/lOWbnlxuICAgIGlmICghKG1hc2tCQm94LndpZHRoID49IHRvbGVyYW5jZSB8fCBtYXNrQkJveC5oZWlnaHQgPj0gdG9sZXJhbmNlKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG1hc2tCQm94O1xufVxuZnVuY3Rpb24gZ2V0TWFza1BhdGgoY29udGV4dCwgdG9sZXJhbmNlKSB7XG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5ldmVudDtcbiAgICB2YXIgbWFza1NoYXBlID0gZXZlbnQudGFyZ2V0O1xuICAgIHZhciBtYXNrQkJveCA9IG1hc2tTaGFwZS5nZXRDYW52YXNCQm94KCk7XG4gICAgLy8g5aaC5p6cIGJib3gg6L+H5bCP5YiZ5LiN6L+U5ZueXG4gICAgaWYgKCEobWFza0JCb3gud2lkdGggPj0gdG9sZXJhbmNlIHx8IG1hc2tCQm94LmhlaWdodCA+PSB0b2xlcmFuY2UpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbWFza1NoYXBlLmF0dHIoJ3BhdGgnKTtcbn1cbi8qKlxuICog6I635Y+W5b2T5YmN5LqL5Lu255u45YWz55qE5Zu+6KGo5YWD57SgXG4gKiBAcGFyYW0gY29udGV4dCDkuqTkupLnmoTkuIrkuIvmlodcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gZ2V0Q3VycmVudEVsZW1lbnQoY29udGV4dCkge1xuICAgIHZhciBldmVudCA9IGNvbnRleHQuZXZlbnQ7XG4gICAgdmFyIGVsZW1lbnQ7XG4gICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGVsZW1lbnQgPSB0YXJnZXQuZ2V0KCdlbGVtZW50Jyk7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50O1xufVxuZXhwb3J0cy5nZXRDdXJyZW50RWxlbWVudCA9IGdldEN1cnJlbnRFbGVtZW50O1xuLyoqXG4gKiDojrflj5blp5TmiZjlr7nosaFcbiAqIEBwYXJhbSBjb250ZXh0IOS4iuS4i+aWh1xuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBnZXREZWxlZ2F0aW9uT2JqZWN0KGNvbnRleHQpIHtcbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmV2ZW50O1xuICAgIHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgdmFyIGRlbGVnYXRlT2JqZWN0O1xuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgZGVsZWdhdGVPYmplY3QgPSB0YXJnZXQuZ2V0KCdkZWxlZ2F0ZU9iamVjdCcpO1xuICAgIH1cbiAgICByZXR1cm4gZGVsZWdhdGVPYmplY3Q7XG59XG5leHBvcnRzLmdldERlbGVnYXRpb25PYmplY3QgPSBnZXREZWxlZ2F0aW9uT2JqZWN0O1xuZnVuY3Rpb24gaXNFbGVtZW50Q2hhbmdlKGNvbnRleHQpIHtcbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmV2ZW50LmdFdmVudDtcbiAgICAvLyDlnKjlkIzkuIDkuKogZWxlbWVudCDlhoXpg6jnp7vliqjvvIxsYWJlbCDlkowgc2hhcGUg5LmL6Ze0XG4gICAgaWYgKGV2ZW50ICYmIGV2ZW50LmZyb21TaGFwZSAmJiBldmVudC50b1NoYXBlICYmIGV2ZW50LmZyb21TaGFwZS5nZXQoJ2VsZW1lbnQnKSA9PT0gZXZlbnQudG9TaGFwZS5nZXQoJ2VsZW1lbnQnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZXhwb3J0cy5pc0VsZW1lbnRDaGFuZ2UgPSBpc0VsZW1lbnRDaGFuZ2U7XG4vKipcbiAqIOaYr+WQpuaYr+WIl+ihqOe7hOS7tlxuICogQHBhcmFtIGRlbGVnYXRlT2JqZWN0IOWnlOaJmOWvueixoVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBpc0xpc3QoZGVsZWdhdGVPYmplY3QpIHtcbiAgICByZXR1cm4gZGVsZWdhdGVPYmplY3QgJiYgZGVsZWdhdGVPYmplY3QuY29tcG9uZW50ICYmIGRlbGVnYXRlT2JqZWN0LmNvbXBvbmVudC5pc0xpc3QoKTtcbn1cbmV4cG9ydHMuaXNMaXN0ID0gaXNMaXN0O1xuLyoqXG4gKiDmmK/lkKbmmK/mu5HlnZfnu4Tku7ZcbiAqIEBwYXJhbSBkZWxlZ2F0ZU9iamVjdCDlp5TmiZjlr7nosaFcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gaXNTbGlkZXIoZGVsZWdhdGVPYmplY3QpIHtcbiAgICByZXR1cm4gZGVsZWdhdGVPYmplY3QgJiYgZGVsZWdhdGVPYmplY3QuY29tcG9uZW50ICYmIGRlbGVnYXRlT2JqZWN0LmNvbXBvbmVudC5pc1NsaWRlcigpO1xufVxuZXhwb3J0cy5pc1NsaWRlciA9IGlzU2xpZGVyO1xuLyoqXG4gKiDmmK/lkKbnlLEgbWFzayDop6blj5FcbiAqIEBwYXJhbSBjb250ZXh0IOS4iuS4i+aWh1xuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBpc01hc2soY29udGV4dCkge1xuICAgIHZhciBldmVudCA9IGNvbnRleHQuZXZlbnQ7XG4gICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICByZXR1cm4gdGFyZ2V0ICYmIHRhcmdldC5nZXQoJ25hbWUnKSA9PT0gJ21hc2snO1xufVxuZXhwb3J0cy5pc01hc2sgPSBpc01hc2s7XG4vKipcbiAqIOiOt+WPluiiq+mBruaMoeeahCBlbGVtZW50c1xuICogQHBhcmFtIGNvbnRleHQg5LiK5LiL5paHXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGdldE1hc2tlZEVsZW1lbnRzKGNvbnRleHQsIHRvbGVyYW5jZSkge1xuICAgIHZhciB0YXJnZXQgPSBjb250ZXh0LmV2ZW50LnRhcmdldDtcbiAgICBpZiAodGFyZ2V0LmdldCgndHlwZScpID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIG1hc2tQYXRoID0gZ2V0TWFza1BhdGgoY29udGV4dCwgdG9sZXJhbmNlKTtcbiAgICAgICAgaWYgKCFtYXNrUGF0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXRFbGVtZW50c0J5UGF0aChjb250ZXh0LnZpZXcsIG1hc2tQYXRoKTtcbiAgICB9XG4gICAgdmFyIG1hc2tCQm94ID0gZ2V0TWFza0JCb3goY29udGV4dCwgdG9sZXJhbmNlKTtcbiAgICAvLyDlpoLmnpwgYmJveCDov4flsI/liJnkuI3ov5Tlm55cbiAgICBpZiAoIW1hc2tCQm94KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gZ2V0SW50ZXJzZWN0RWxlbWVudHMoY29udGV4dC52aWV3LCBtYXNrQkJveCk7XG59XG5leHBvcnRzLmdldE1hc2tlZEVsZW1lbnRzID0gZ2V0TWFza2VkRWxlbWVudHM7XG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gZ2V0U2libGluZ01hc2tFbGVtZW50cyhjb250ZXh0LCBzaWJsaW5nLCB0b2xlcmFuY2UpIHtcbiAgICB2YXIgbWFza0JCb3ggPSBnZXRNYXNrQkJveChjb250ZXh0LCB0b2xlcmFuY2UpO1xuICAgIC8vIOWmguaenCBiYm94IOi/h+Wwj+WImeS4jei/lOWbnlxuICAgIGlmICghbWFza0JCb3gpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciB2aWV3ID0gY29udGV4dC52aWV3O1xuICAgIHZhciBzdGFydCA9IGdldFNpYmxpbmdQb2ludCh2aWV3LCBzaWJsaW5nLCB7IHg6IG1hc2tCQm94LngsIHk6IG1hc2tCQm94LnkgfSk7XG4gICAgdmFyIGVuZCA9IGdldFNpYmxpbmdQb2ludCh2aWV3LCBzaWJsaW5nLCB7IHg6IG1hc2tCQm94Lm1heFgsIHk6IG1hc2tCQm94Lm1heFkgfSk7XG4gICAgdmFyIGJveCA9IHtcbiAgICAgICAgbWluWDogc3RhcnQueCxcbiAgICAgICAgbWluWTogc3RhcnQueSxcbiAgICAgICAgbWF4WDogZW5kLngsXG4gICAgICAgIG1heFk6IGVuZC55LFxuICAgIH07XG4gICAgcmV0dXJuIGdldEludGVyc2VjdEVsZW1lbnRzKHNpYmxpbmcsIGJveCk7XG59XG5leHBvcnRzLmdldFNpYmxpbmdNYXNrRWxlbWVudHMgPSBnZXRTaWJsaW5nTWFza0VsZW1lbnRzO1xuLyoqXG4gKiDojrflj5bmiYDmnInnmoTlm77ooajlhYPntKBcbiAqIEBwYXJhbSB2aWV3IFZpZXcvQ2hhcnRcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gZ2V0RWxlbWVudHModmlldykge1xuICAgIHZhciBnZW9tZXRyaWVzID0gdmlldy5nZW9tZXRyaWVzO1xuICAgIHZhciByc3QgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChnZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbSkge1xuICAgICAgICB2YXIgZWxlbWVudHMgPSBnZW9tLmVsZW1lbnRzO1xuICAgICAgICByc3QgPSByc3QuY29uY2F0KGVsZW1lbnRzKTtcbiAgICB9KTtcbiAgICBpZiAodmlldy52aWV3cyAmJiB2aWV3LnZpZXdzLmxlbmd0aCkge1xuICAgICAgICB1dGlsXzEuZWFjaCh2aWV3LnZpZXdzLCBmdW5jdGlvbiAoc3ViVmlldykge1xuICAgICAgICAgICAgcnN0ID0gcnN0LmNvbmNhdChnZXRFbGVtZW50cyhzdWJWaWV3KSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcnN0O1xufVxuZXhwb3J0cy5nZXRFbGVtZW50cyA9IGdldEVsZW1lbnRzO1xuLyoqXG4gKiDojrflj5bmiYDmnInnmoTlm77ooajlhYPntKBcbiAqIEBwYXJhbSB2aWV3IFZpZXcvQ2hhcnRcbiAqIEBwYXJhbSBmaWVsZCDlrZfmrrXlkI1cbiAqIEBwYXJhbSB2YWx1ZSDlrZfmrrXlgLxcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gZ2V0RWxlbWVudHNCeUZpZWxkKHZpZXcsIGZpZWxkLCB2YWx1ZSkge1xuICAgIHZhciBlbGVtZW50cyA9IGdldEVsZW1lbnRzKHZpZXcpO1xuICAgIHJldHVybiBlbGVtZW50cy5maWx0ZXIoZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBnZXRFbGVtZW50VmFsdWUoZWwsIGZpZWxkKSA9PT0gdmFsdWU7XG4gICAgfSk7XG59XG5leHBvcnRzLmdldEVsZW1lbnRzQnlGaWVsZCA9IGdldEVsZW1lbnRzQnlGaWVsZDtcbi8qKlxuICog5qC55o2u54q25oCB5ZCN6I635Y+W5Zu+6KGo5YWD57SgXG4gKiBAcGFyYW0gdmlldyBWaWV3L0NoYXJ0XG4gKiBAcGFyYW0gc3RhdGVOYW1lIOeKtuaAgeWQjVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBnZXRFbGVtZW50c0J5U3RhdGUodmlldywgc3RhdGVOYW1lKSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSB2aWV3Lmdlb21ldHJpZXM7XG4gICAgdmFyIHJzdCA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKGdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IGdlb20uZ2V0RWxlbWVudHNCeShmdW5jdGlvbiAoZWwpIHsgcmV0dXJuIGVsLmhhc1N0YXRlKHN0YXRlTmFtZSk7IH0pO1xuICAgICAgICByc3QgPSByc3QuY29uY2F0KGVsZW1lbnRzKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcnN0O1xufVxuZXhwb3J0cy5nZXRFbGVtZW50c0J5U3RhdGUgPSBnZXRFbGVtZW50c0J5U3RhdGU7XG4vKipcbiAqIOiOt+WPluWbvuihqOWFg+e0oOWvueW6lOWtl+auteeahOWAvFxuICogQHBhcmFtIGVsZW1lbnQg5Zu+6KGo5YWD57SgXG4gKiBAcGFyYW0gZmllbGQg5a2X5q615ZCNXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGdldEVsZW1lbnRWYWx1ZShlbGVtZW50LCBmaWVsZCkge1xuICAgIHZhciBtb2RlbCA9IGVsZW1lbnQuZ2V0TW9kZWwoKTtcbiAgICB2YXIgcmVjb3JkID0gbW9kZWwuZGF0YTtcbiAgICB2YXIgdmFsdWU7XG4gICAgaWYgKHV0aWxfMS5pc0FycmF5KHJlY29yZCkpIHtcbiAgICAgICAgdmFsdWUgPSByZWNvcmRbMF1bZmllbGRdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSByZWNvcmRbZmllbGRdO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5leHBvcnRzLmdldEVsZW1lbnRWYWx1ZSA9IGdldEVsZW1lbnRWYWx1ZTtcbi8qKlxuICog5Lik5Liq5YyF5Zu055uS5piv5ZCm55u45LqkXG4gKiBAcGFyYW0gYm94MSDljIXlm7Tnm5IxXG4gKiBAcGFyYW0gYm94MiDljIXlm7Tnm5IyXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGludGVyc2VjdFJlY3QoYm94MSwgYm94Mikge1xuICAgIHJldHVybiAhKGJveDIubWluWCA+IGJveDEubWF4WCB8fCBib3gyLm1heFggPCBib3gxLm1pblggfHwgYm94Mi5taW5ZID4gYm94MS5tYXhZIHx8IGJveDIubWF4WSA8IGJveDEubWluWSk7XG59XG5leHBvcnRzLmludGVyc2VjdFJlY3QgPSBpbnRlcnNlY3RSZWN0O1xuLyoqXG4gKiDojrflj5bljIXlm7Tnm5LlhoXnmoTlm77ooajlhYPntKBcbiAqIEBwYXJhbSB2aWV3IFZpZXcvQ2hhcnRcbiAqIEBwYXJhbSBib3gg5YyF5Zu055uSXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGdldEludGVyc2VjdEVsZW1lbnRzKHZpZXcsIGJveCkge1xuICAgIHZhciBlbGVtZW50cyA9IGdldEVsZW1lbnRzKHZpZXcpO1xuICAgIHZhciByc3QgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHZhciBzaGFwZSA9IGVsLnNoYXBlO1xuICAgICAgICB2YXIgc2hhcGVCQm94ID0gc2hhcGUuZ2V0Q2FudmFzQkJveCgpO1xuICAgICAgICBpZiAoaW50ZXJzZWN0UmVjdChib3gsIHNoYXBlQkJveCkpIHtcbiAgICAgICAgICAgIHJzdC5wdXNoKGVsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByc3Q7XG59XG5leHBvcnRzLmdldEludGVyc2VjdEVsZW1lbnRzID0gZ2V0SW50ZXJzZWN0RWxlbWVudHM7XG5mdW5jdGlvbiBwYXRoVG9Qb2ludHMocGF0aCkge1xuICAgIHZhciBwb2ludHMgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChwYXRoLCBmdW5jdGlvbiAoc2VnKSB7XG4gICAgICAgIHZhciBjb21tYW5kID0gc2VnWzBdO1xuICAgICAgICBpZiAoY29tbWFuZCAhPT0gJ0EnKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IHNlZy5sZW5ndGg7IGkgPSBpICsgMikge1xuICAgICAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdbaV0sIHNlZ1tpICsgMV1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsZW5ndGhfMSA9IHNlZy5sZW5ndGg7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnW2xlbmd0aF8xIC0gMl0sIHNlZ1tsZW5ndGhfMSAtIDFdXSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcG9pbnRzO1xufVxuLyoqXG4gKiDojrflj5bljIXlm7Tnm5LlhoXnmoTlm77ooajlhYPntKBcbiAqIEBwYXJhbSB2aWV3IFZpZXcvQ2hhcnRcbiAqIEBwYXJhbSBwYXRoIOi3r+W+hFxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBnZXRFbGVtZW50c0J5UGF0aCh2aWV3LCBwYXRoKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gZ2V0RWxlbWVudHModmlldyk7XG4gICAgdmFyIHBvaW50cyA9IHBhdGhUb1BvaW50cyhwYXRoKTtcbiAgICB2YXIgcnN0ID0gZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICB2YXIgc2hhcGUgPSBlbC5zaGFwZTtcbiAgICAgICAgdmFyIHNoYXBlUG9pbnRzO1xuICAgICAgICBpZiAoc2hhcGUuZ2V0KCd0eXBlJykgPT09ICdwYXRoJykge1xuICAgICAgICAgICAgc2hhcGVQb2ludHMgPSBwYXRoVG9Qb2ludHMoc2hhcGUuYXR0cigncGF0aCcpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBzaGFwZUJCb3ggPSBzaGFwZS5nZXRDYW52YXNCQm94KCk7XG4gICAgICAgICAgICBzaGFwZVBvaW50cyA9IGJib3hfMS50b1BvaW50cyhzaGFwZUJCb3gpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc19wb2x5Z29uc19pbnRlcnNlY3RfMS5kZWZhdWx0KHBvaW50cywgc2hhcGVQb2ludHMpO1xuICAgIH0pO1xuICAgIHJldHVybiByc3Q7XG59XG5leHBvcnRzLmdldEVsZW1lbnRzQnlQYXRoID0gZ2V0RWxlbWVudHNCeVBhdGg7XG4vKipcbiAqIOiOt+WPluW9k+WJjSBWaWV3IOeahOaJgOaciee7hOS7tlxuICogQHBhcmFtIHZpZXcgVmlldy9DaGFydFxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBnZXRDb21wb25lbnRzKHZpZXcpIHtcbiAgICByZXR1cm4gdmlldy5nZXRDb21wb25lbnRzKCkubWFwKGZ1bmN0aW9uIChjbykgeyByZXR1cm4gY28uY29tcG9uZW50OyB9KTtcbn1cbmV4cG9ydHMuZ2V0Q29tcG9uZW50cyA9IGdldENvbXBvbmVudHM7XG4vKiogQGlnbm9yZSAqL1xuZnVuY3Rpb24gZGlzdGFuY2UocDEsIHAyKSB7XG4gICAgdmFyIGR4ID0gcDIueCAtIHAxLng7XG4gICAgdmFyIGR5ID0gcDIueSAtIHAxLnk7XG4gICAgcmV0dXJuIE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG59XG5leHBvcnRzLmRpc3RhbmNlID0gZGlzdGFuY2U7XG4vKiogQGlnbm9yZSAqL1xuZnVuY3Rpb24gZ2V0U3BsaW5lKHBvaW50cywgeikge1xuICAgIGlmIChwb2ludHMubGVuZ3RoIDw9IDIpIHtcbiAgICAgICAgcmV0dXJuIHBhdGhfMS5nZXRMaW5lUGF0aChwb2ludHMsIGZhbHNlKTtcbiAgICB9XG4gICAgdmFyIGZpcnN0ID0gcG9pbnRzWzBdO1xuICAgIHZhciBhcnIgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICBhcnIucHVzaChwb2ludC54KTtcbiAgICAgICAgYXJyLnB1c2gocG9pbnQueSk7XG4gICAgfSk7XG4gICAgdmFyIHBhdGggPSBwYXRoXzEuY2F0bXVsbFJvbTJiZXppZXIoYXJyLCB6LCBudWxsKTtcbiAgICBwYXRoLnVuc2hpZnQoWydNJywgZmlyc3QueCwgZmlyc3QueV0pO1xuICAgIHJldHVybiBwYXRoO1xufVxuZXhwb3J0cy5nZXRTcGxpbmUgPSBnZXRTcGxpbmU7XG4vKipcbiAqIOajgOa1i+eCueaYr+WQpuWcqOWMheWbtOebkuWGhVxuICogQHBhcmFtIGJveCDljIXlm7Tnm5JcbiAqIEBwYXJhbSBwb2ludCDngrlcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gaXNJbkJveChib3gsIHBvaW50KSB7XG4gICAgcmV0dXJuIGJveC54IDw9IHBvaW50LnggJiYgYm94Lm1heFggPj0gcG9pbnQueCAmJiBib3gueSA8PSBwb2ludC55ICYmIGJveC5tYXhZID4gcG9pbnQueTtcbn1cbmV4cG9ydHMuaXNJbkJveCA9IGlzSW5Cb3g7XG4vKipcbiAqIOiOt+WPluWQjCB2aWV3IOWQjOS4gOe6p+eahCB2aWV3c1xuICogQHBhcmFtIHZpZXcg5b2T5YmNIHZpZXdcbiAqIEByZXR1cm5zIOWQjOS4gOe6p+eahCB2aWV3c1xuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBnZXRTaWxiaW5ncyh2aWV3KSB7XG4gICAgdmFyIHBhcmVudCA9IHZpZXcucGFyZW50O1xuICAgIHZhciBzaWJsaW5ncyA9IG51bGw7XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICBzaWJsaW5ncyA9IHBhcmVudC52aWV3cy5maWx0ZXIoZnVuY3Rpb24gKHN1YikgeyByZXR1cm4gc3ViICE9PSB2aWV3OyB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNpYmxpbmdzO1xufVxuZXhwb3J0cy5nZXRTaWxiaW5ncyA9IGdldFNpbGJpbmdzO1xuZnVuY3Rpb24gcG9pbnQyTm9ybWFsaXplKHZpZXcsIHBvaW50KSB7XG4gICAgdmFyIGNvb3JkID0gdmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgcmV0dXJuIGNvb3JkLmludmVydChwb2ludCk7XG59XG4vKipcbiAqIOWwhiB2aWV3IOS4iueahOS4gOeCuei9rOaNouaIkOWPpuS4gOS4qiB2aWV3IOeahOeCuVxuICogQHBhcmFtIHZpZXcg5b2T5YmN55qEIHZpZXdcbiAqIEBwYXJhbSBzaWJsaW5nIOWQjOS4gOWxgue6p+eahCB2aWV3XG4gKiBAcGFyYW0gcG9pbnQg5oyH5a6a54K5XG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGdldFNpYmxpbmdQb2ludCh2aWV3LCBzaWJsaW5nLCBwb2ludCkge1xuICAgIHZhciBub3JtYWxQb2ludCA9IHBvaW50Mk5vcm1hbGl6ZSh2aWV3LCBwb2ludCk7XG4gICAgcmV0dXJuIHNpYmxpbmcuZ2V0Q29vcmRpbmF0ZSgpLmNvbnZlcnQobm9ybWFsUG9pbnQpO1xufVxuZXhwb3J0cy5nZXRTaWJsaW5nUG9pbnQgPSBnZXRTaWJsaW5nUG9pbnQ7XG4vKipcbiAqIOaYr+WQpuWcqOiusOW9leS4re+8jOS4tOaXtuWboOS4uuaJgOacieeahCB2aWV3IOS4reeahOaVsOaNruS4jeaYr+W8leeUqO+8jOiAjOS9v+eUqOeahOaWueazlVxuICog5LiN5ZCMIHZpZXcg5LiK5a+55pWw5o2u55qE5byV55So5LiN55u4562J77yM5a+86Ie05peg5rOV55u05o6l55SoIGluY2x1ZGVzXG4gKiDlgYforr4geCwgeSDlgLznm7jnrYnml7bmmK/lkIzkuIDmnaHmlbDmja7vvIzov5nkuKrlgYforr7kuI3lrozlhajmraPnoa7vvIzogIzmlLnmiJAgaXNFcXVhbCDliJnmiJDmnKzlpKrpq5hcbiAqIOWQjumdouaUueaIkOWQjOS4gOS4quW8leeUqOaXtuWPr+S7peS/ruaUueWbnuadpVxuICogQHBhcmFtIHJlY29yZHNcbiAqIEBwYXJhbSByZWNvcmRcbiAqIEBwYXJhbSB4RmlsZWRcbiAqIEBwYXJhbSB5RmllbGRcbiAqIEByZXR1cm5zXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIGlzSW5SZWNvcmRzKHJlY29yZHMsIHJlY29yZCwgeEZpbGVkLCB5RmllbGQpIHtcbiAgICB2YXIgaXNJbiA9IGZhbHNlO1xuICAgIHV0aWxfMS5lYWNoKHJlY29yZHMsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIGlmIChyW3hGaWxlZF0gPT09IHJlY29yZFt4RmlsZWRdICYmIHJbeUZpZWxkXSA9PT0gcmVjb3JkW3lGaWVsZF0pIHtcbiAgICAgICAgICAgIGlzSW4gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGlzSW47XG59XG5leHBvcnRzLmlzSW5SZWNvcmRzID0gaXNJblJlY29yZHM7XG4vLyDnuqfogZTojrflj5YgZmllbGQg5a+55bqU55qEIHNjYWxl77yM5aaC5p6cIHZpZXcg5LiK5rKh5pyJ77yM6YGN5Y6G5a2QIHZpZXdcbmZ1bmN0aW9uIGdldFNjYWxlQnlGaWVsZCh2aWV3LCBmaWVsZCkge1xuICAgIHZhciBzY2FsZSA9IHZpZXcuZ2V0U2NhbGVCeUZpZWxkKGZpZWxkKTtcbiAgICBpZiAoIXNjYWxlICYmIHZpZXcudmlld3MpIHtcbiAgICAgICAgdXRpbF8xLmVhY2godmlldy52aWV3cywgZnVuY3Rpb24gKHN1YlZpZXcpIHtcbiAgICAgICAgICAgIHNjYWxlID0gZ2V0U2NhbGVCeUZpZWxkKHN1YlZpZXcsIGZpZWxkKTtcbiAgICAgICAgICAgIGlmIChzY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8g57uI5q2i5b6q546vXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc2NhbGU7XG59XG5leHBvcnRzLmdldFNjYWxlQnlGaWVsZCA9IGdldFNjYWxlQnlGaWVsZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBhZGRpbmdfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL3BhZGRpbmdcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2Jhc2VcIikpO1xudmFyIFBBRERJTkdfUklHSFQgPSAxMDtcbnZhciBQQURESU5HX1RPUCA9IDU7XG4vKipcbiAqIEJ1dHRvbiBhY3Rpb25cbiAqIEBpZ25vcmVcbiAqL1xudmFyIEJ1dHRvbkFjdGlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhCdXR0b25BY3Rpb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQnV0dG9uQWN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuYnV0dG9uR3JvdXAgPSBudWxsO1xuICAgICAgICBfdGhpcy5idXR0b25DZmcgPSB7XG4gICAgICAgICAgICBuYW1lOiAnYnV0dG9uJyxcbiAgICAgICAgICAgIHRleHQ6ICdidXR0b24nLFxuICAgICAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICBmaWxsOiAnIzMzMzMzMycsXG4gICAgICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFkZGluZzogWzgsIDEwXSxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZmlsbDogJyNmN2Y3ZjcnLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogJyNjY2NjY2MnLFxuICAgICAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdGl2ZVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZmlsbDogJyNlNmU2ZTYnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvLyBtaXgg6buY6K6k55qE6YWN572u5ZKM55So5oi36YWN572uXG4gICAgQnV0dG9uQWN0aW9uLnByb3RvdHlwZS5nZXRCdXR0b25DZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh0aGlzLmJ1dHRvbkNmZywgdGhpcy5jZmcpO1xuICAgIH07XG4gICAgLy8g57uY5Yi2IEJ1dHRvbiDlkowg5paH5pysXG4gICAgQnV0dG9uQWN0aW9uLnByb3RvdHlwZS5kcmF3QnV0dG9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29uZmlnID0gdGhpcy5nZXRCdXR0b25DZmcoKTtcbiAgICAgICAgdmFyIGdyb3VwID0gdGhpcy5jb250ZXh0LnZpZXcuZm9yZWdyb3VuZEdyb3VwLmFkZEdyb3VwKHtcbiAgICAgICAgICAgIG5hbWU6IGNvbmZpZy5uYW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8g5re75Yqg5paH5pysXG4gICAgICAgIHZhciB0ZXh0U2hhcGUgPSBncm91cC5hZGRTaGFwZSh7XG4gICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICBuYW1lOiAnYnV0dG9uLXRleHQnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB0ZXh0OiBjb25maWcudGV4dCB9LCBjb25maWcudGV4dFN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB0ZXh0QkJveCA9IHRleHRTaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIHZhciBwYWRkaW5nID0gcGFkZGluZ18xLnBhcnNlUGFkZGluZyhjb25maWcucGFkZGluZyk7XG4gICAgICAgIC8vIOa3u+WKoOiDjOaZr+aMiemSrlxuICAgICAgICB2YXIgYnV0dG9uU2hhcGUgPSBncm91cC5hZGRTaGFwZSh7XG4gICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICBuYW1lOiAnYnV0dG9uLXJlY3QnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB4OiB0ZXh0QkJveC54IC0gcGFkZGluZ1szXSwgeTogdGV4dEJCb3gueSAtIHBhZGRpbmdbMF0sIHdpZHRoOiB0ZXh0QkJveC53aWR0aCArIHBhZGRpbmdbMV0gKyBwYWRkaW5nWzNdLCBoZWlnaHQ6IHRleHRCQm94LmhlaWdodCArIHBhZGRpbmdbMF0gKyBwYWRkaW5nWzJdIH0sIGNvbmZpZy5zdHlsZSksXG4gICAgICAgIH0pO1xuICAgICAgICBidXR0b25TaGFwZS50b0JhY2soKTsgLy8g5Zyo5ZCO6Z2iXG4gICAgICAgIC8vIGFjdGl2ZSDmlYjmnpzlhoXnva5cbiAgICAgICAgZ3JvdXAub24oJ21vdXNlZW50ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBidXR0b25TaGFwZS5hdHRyKGNvbmZpZy5hY3RpdmVTdHlsZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBncm91cC5vbignbW91c2VsZWF2ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGJ1dHRvblNoYXBlLmF0dHIoY29uZmlnLnN0eWxlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYnV0dG9uR3JvdXAgPSBncm91cDtcbiAgICB9O1xuICAgIC8vIOmHjee9ruS9jee9rlxuICAgIEJ1dHRvbkFjdGlvbi5wcm90b3R5cGUucmVzZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGNvb3JkID0gdmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBwb2ludCA9IGNvb3JkLmNvbnZlcnQoeyB4OiAxLCB5OiAxIH0pOyAvLyDlkI7pnaLnm7TmjqXmlLnmiJDlt6bkuIrop5JcbiAgICAgICAgdmFyIGJ1dHRvbkdyb3VwID0gdGhpcy5idXR0b25Hcm91cDtcbiAgICAgICAgdmFyIGJib3ggPSBidXR0b25Hcm91cC5nZXRCQm94KCk7XG4gICAgICAgIHZhciBtYXRyaXggPSBtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0obnVsbCwgW1xuICAgICAgICAgICAgWyd0JywgcG9pbnQueCAtIGJib3gud2lkdGggLSBQQURESU5HX1JJR0hULCBwb2ludC55ICsgYmJveC5oZWlnaHQgKyBQQURESU5HX1RPUF0sXG4gICAgICAgIF0pO1xuICAgICAgICBidXR0b25Hcm91cC5zZXRNYXRyaXgobWF0cml4KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaYvuekulxuICAgICAqL1xuICAgIEJ1dHRvbkFjdGlvbi5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmJ1dHRvbkdyb3VwKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdCdXR0b24oKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlc2V0UG9zaXRpb24oKTtcbiAgICAgICAgdGhpcy5idXR0b25Hcm91cC5zaG93KCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpmpDol49cbiAgICAgKi9cbiAgICBCdXR0b25BY3Rpb24ucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1dHRvbkdyb3VwKSB7XG4gICAgICAgICAgICB0aGlzLmJ1dHRvbkdyb3VwLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZSA5q+BXG4gICAgICovXG4gICAgQnV0dG9uQWN0aW9uLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYnV0dG9uR3JvdXAgPSB0aGlzLmJ1dHRvbkdyb3VwO1xuICAgICAgICBpZiAoYnV0dG9uR3JvdXApIHtcbiAgICAgICAgICAgIGJ1dHRvbkdyb3VwLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgcmV0dXJuIEJ1dHRvbkFjdGlvbjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJ1dHRvbkFjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJ1dHRvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcbnZhciBESVNUQU5DRSA9IDQ7IC8vIOenu+WKqOeahOacgOWwj+i3neemu1xuLyoqXG4gKiBAaWdub3JlXG4gKiBWaWV3IOaUr+aMgSBEcmFnIOeahCBBY3Rpb25cbiAqL1xudmFyIERyYWcgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRHJhZywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBEcmFnKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgLy8gQWN0aW9uIOW8gOWni++8jOS4jeetieWQjOS6jiDmi5bmi73lvIDlp4vvvIzpnIDopoHliKTlrprnp7vliqjnmoTojIPlm7RcbiAgICAgICAgX3RoaXMuc3RhcnRpbmcgPSBmYWxzZTtcbiAgICAgICAgLy8g5ouW5ou95byA5aeLXG4gICAgICAgIF90aGlzLmRyYWdTdGFydCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOW8gOWni1xuICAgICAqL1xuICAgIERyYWcucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnN0YXJ0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gdGhpcy5jb250ZXh0LmdldEN1cnJlbnRQb2ludCgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5ouW5ou9XG4gICAgICovXG4gICAgRHJhZy5wcm90b3R5cGUuZHJhZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXJ0UG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY3VycmVudCA9IHRoaXMuY29udGV4dC5nZXRDdXJyZW50UG9pbnQoKTtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGV2ZW50ID0gdGhpcy5jb250ZXh0LmV2ZW50O1xuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXJ0KSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmRpc3RhbmNlKGN1cnJlbnQsIHRoaXMuc3RhcnRQb2ludCkgPiBESVNUQU5DRSkge1xuICAgICAgICAgICAgICAgIHZpZXcuZW1pdCgnZHJhZ3N0YXJ0Jywge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IGV2ZW50LnRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogZXZlbnQueSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdTdGFydCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2aWV3LmVtaXQoJ2RyYWcnLCB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0OiBldmVudC50YXJnZXQsXG4gICAgICAgICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICAgICAgICB5OiBldmVudC55LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe7k+adn1xuICAgICAqL1xuICAgIERyYWcucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuZHJhZ1N0YXJ0KSB7XG4gICAgICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICAgICAgdmFyIGV2ZW50XzEgPSB0aGlzLmNvbnRleHQuZXZlbnQ7XG4gICAgICAgICAgICB2aWV3LmVtaXQoJ2RyYWdlbmQnLCB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0OiBldmVudF8xLnRhcmdldCxcbiAgICAgICAgICAgICAgICB4OiBldmVudF8xLngsXG4gICAgICAgICAgICAgICAgeTogZXZlbnRfMS55LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGFydGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRyYWdTdGFydCA9IGZhbHNlO1xuICAgIH07XG4gICAgcmV0dXJuIERyYWc7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEcmFnO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHJhZy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgX18xID0gcmVxdWlyZShcIi4uXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsXCIpO1xudmFyIE1JTl9ESVNUQU5DRSA9IDU7XG4vKipcbiAqIEBpZ25vcmVcbiAqIFZpZXcg56e75Yqo55qEIEFjdGlvblxuICovXG52YXIgTW92ZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhNb3ZlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIE1vdmUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGFydGluZyA9IGZhbHNlO1xuICAgICAgICBfdGhpcy5pc01vdmluZyA9IGZhbHNlO1xuICAgICAgICAvLyBwcml2YXRlIGNhY2hlUmFuZ2UgPSBudWxsO1xuICAgICAgICBfdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcbiAgICAgICAgX3RoaXMuc3RhcnRNYXRyaXggPSBudWxsO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOW8gOWni+enu+WKqFxuICAgICAqL1xuICAgIE1vdmUucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnN0YXJ0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gdGhpcy5jb250ZXh0LmdldEN1cnJlbnRQb2ludCgpO1xuICAgICAgICAvLyDnvJPlrZjlvIDlp4vml7bnmoTnn6npmLXvvIzpmLLmraLlj43lpI3mi5bmi71cbiAgICAgICAgdGhpcy5zdGFydE1hdHJpeCA9IHRoaXMuY29udGV4dC52aWV3Lm1pZGRsZUdyb3VwLmdldE1hdHJpeCgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog56e75YqoXG4gICAgICovXG4gICAgTW92ZS5wcm90b3R5cGUubW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXJ0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHN0YXJ0UG9pbnQgPSB0aGlzLnN0YXJ0UG9pbnQ7XG4gICAgICAgIHZhciBjdXJyZW50UG9pbnQgPSB0aGlzLmNvbnRleHQuZ2V0Q3VycmVudFBvaW50KCk7XG4gICAgICAgIHZhciBkID0gdXRpbF8xLmRpc3RhbmNlKHN0YXJ0UG9pbnQsIGN1cnJlbnRQb2ludCk7XG4gICAgICAgIGlmIChkID4gTUlOX0RJU1RBTkNFICYmICF0aGlzLmlzTW92aW5nKSB7XG4gICAgICAgICAgICB0aGlzLmlzTW92aW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc01vdmluZykge1xuICAgICAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgICAgIHZhciBtYXRyaXggPSBtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0odGhpcy5zdGFydE1hdHJpeCwgW1xuICAgICAgICAgICAgICAgIFsndCcsIGN1cnJlbnRQb2ludC54IC0gc3RhcnRQb2ludC54LCBjdXJyZW50UG9pbnQueSAtIHN0YXJ0UG9pbnQueV0sXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIHZpZXcuYmFja2dyb3VuZEdyb3VwLnNldE1hdHJpeChtYXRyaXgpO1xuICAgICAgICAgICAgdmlldy5mb3JlZ3JvdW5kR3JvdXAuc2V0TWF0cml4KG1hdHJpeCk7XG4gICAgICAgICAgICB2aWV3Lm1pZGRsZUdyb3VwLnNldE1hdHJpeChtYXRyaXgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnu5PmnZ/np7vliqhcbiAgICAgKi9cbiAgICBNb3ZlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzTW92aW5nKSB7XG4gICAgICAgICAgICB0aGlzLmlzTW92aW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGFydE1hdHJpeCA9IG51bGw7XG4gICAgICAgIHRoaXMuc3RhcnRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWbnua7mlxuICAgICAqL1xuICAgIE1vdmUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnN0YXJ0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RhcnRQb2ludCA9IG51bGw7XG4gICAgICAgIHRoaXMuaXNNb3ZpbmcgPSBmYWxzZTtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmlldy5iYWNrZ3JvdW5kR3JvdXAucmVzZXRNYXRyaXgoKTtcbiAgICAgICAgdmlldy5mb3JlZ3JvdW5kR3JvdXAucmVzZXRNYXRyaXgoKTtcbiAgICAgICAgdmlldy5taWRkbGVHcm91cC5yZXNldE1hdHJpeCgpO1xuICAgICAgICB0aGlzLmlzTW92aW5nID0gZmFsc2U7XG4gICAgfTtcbiAgICByZXR1cm4gTW92ZTtcbn0oX18xLkFjdGlvbikpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTW92ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vdmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBfXzEgPSByZXF1aXJlKFwiLi5cIik7XG52YXIgRElNX1ggPSAneCc7XG52YXIgRElNX1kgPSAneSc7XG4vKipcbiAqIFNjYWxlIHRyYW5zbGF0ZVxuICogQGlnbm9yZVxuICovXG52YXIgU2NhbGVUcmFuc2xhdGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2NhbGVUcmFuc2xhdGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2NhbGVUcmFuc2xhdGUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5kaW1zID0gW0RJTV9YLCBESU1fWV07XG4gICAgICAgIF90aGlzLmNmZ0ZpZWxkcyA9IFsnZGltcyddO1xuICAgICAgICBfdGhpcy5jYWNoZVNjYWxlRGVmcyA9IHt9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8vIOaYr+WQpuaUr+aMgeWvueW6lOWtl+auteeahOW5s+enu1xuICAgIFNjYWxlVHJhbnNsYXRlLnByb3RvdHlwZS5oYXNEaW0gPSBmdW5jdGlvbiAoZGltKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpbXMuaW5jbHVkZXMoZGltKTtcbiAgICB9O1xuICAgIFNjYWxlVHJhbnNsYXRlLnByb3RvdHlwZS5nZXRTY2FsZSA9IGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgaWYgKGRpbSA9PT0gJ3gnKSB7XG4gICAgICAgICAgICByZXR1cm4gdmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2aWV3LmdldFlTY2FsZXMoKVswXTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2NhbGVUcmFuc2xhdGUucHJvdG90eXBlLnJlc2V0RGltID0gZnVuY3Rpb24gKGRpbSkge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICBpZiAodGhpcy5oYXNEaW0oZGltKSAmJiB0aGlzLmNhY2hlU2NhbGVEZWZzW2RpbV0pIHtcbiAgICAgICAgICAgIHZhciBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUoZGltKTtcbiAgICAgICAgICAgIHZpZXcuc2NhbGUoc2NhbGUuZmllbGQsIHRoaXMuY2FjaGVTY2FsZURlZnNbZGltXSk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2NhbGVEZWZzW2RpbV0gPSBudWxsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlm57mu5pcbiAgICAgKi9cbiAgICBTY2FsZVRyYW5zbGF0ZS5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVzZXREaW0oRElNX1gpO1xuICAgICAgICB0aGlzLnJlc2V0RGltKERJTV9ZKTtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmlldy5yZW5kZXIodHJ1ZSk7XG4gICAgfTtcbiAgICByZXR1cm4gU2NhbGVUcmFuc2xhdGU7XG59KF9fMS5BY3Rpb24pKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNjYWxlVHJhbnNsYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2NhbGUtdHJhbnNmb3JtLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgc2NhbGVfdHJhbnNmb3JtXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9zY2FsZS10cmFuc2Zvcm1cIikpO1xuLyoqXG4gKiDmi5bmi70gU2NhbGUg55qEIEFjdGlvblxuICogQGlnbm9yZVxuICovXG52YXIgU2NhbGVUcmFuc2xhdGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2NhbGVUcmFuc2xhdGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2NhbGVUcmFuc2xhdGUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcbiAgICAgICAgX3RoaXMuc3RhcnRpbmcgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMuc3RhcnRDYWNoZSA9IHt9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOW8gOWni1xuICAgICAqL1xuICAgIFNjYWxlVHJhbnNsYXRlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gdGhpcy5jb250ZXh0LmdldEN1cnJlbnRQb2ludCgpO1xuICAgICAgICB0aGlzLnN0YXJ0aW5nID0gdHJ1ZTtcbiAgICAgICAgdmFyIGRpbXMgPSB0aGlzLmRpbXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGRpbXMsIGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgICAgIHZhciBzY2FsZSA9IF90aGlzLmdldFNjYWxlKGRpbSk7XG4gICAgICAgICAgICB2YXIgbWluID0gc2NhbGUubWluLCBtYXggPSBzY2FsZS5tYXgsIHZhbHVlcyA9IHNjYWxlLnZhbHVlcztcbiAgICAgICAgICAgIF90aGlzLnN0YXJ0Q2FjaGVbZGltXSA9IHsgbWluOiBtaW4sIG1heDogbWF4LCB2YWx1ZXM6IHZhbHVlcyB9O1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOW5s+enu+WIhuexu+eahOW6pumHj1xuICAgIC8vIHByaXZhdGUgdHJhbnNsYXRlQ2F0ZWdvcnkoZGltLCBzY2FsZSwgbm9ybWFsUG9pbnQpIHtcbiAgICAvLyB9XG4gICAgLyoqXG4gICAgICog57uT5p2fXG4gICAgICovXG4gICAgU2NhbGVUcmFuc2xhdGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zdGFydFBvaW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5zdGFydGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXJ0Q2FjaGUgPSB7fTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOW5s+enu1xuICAgICAqL1xuICAgIFNjYWxlVHJhbnNsYXRlLnByb3RvdHlwZS50cmFuc2xhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmICghdGhpcy5zdGFydGluZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdGFydFBvaW50ID0gdGhpcy5zdGFydFBvaW50O1xuICAgICAgICB2YXIgY29vcmQgPSB0aGlzLmNvbnRleHQudmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBjdXJyZW50UG9pbnQgPSB0aGlzLmNvbnRleHQuZ2V0Q3VycmVudFBvaW50KCk7XG4gICAgICAgIHZhciBub3JtYWxTdGFydCA9IGNvb3JkLmludmVydChzdGFydFBvaW50KTtcbiAgICAgICAgdmFyIG5vcmFtbEN1cnJlbnQgPSBjb29yZC5pbnZlcnQoY3VycmVudFBvaW50KTtcbiAgICAgICAgdmFyIGR4ID0gbm9yYW1sQ3VycmVudC54IC0gbm9ybWFsU3RhcnQueDtcbiAgICAgICAgdmFyIGR5ID0gbm9yYW1sQ3VycmVudC55IC0gbm9ybWFsU3RhcnQueTtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQudmlldztcbiAgICAgICAgdmFyIGRpbXMgPSB0aGlzLmRpbXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGRpbXMsIGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgICAgIF90aGlzLnRyYW5zbGF0ZURpbShkaW0sIHsgeDogZHggKiAtMSwgeTogZHkgKiAtMSB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZpZXcucmVuZGVyKHRydWUpO1xuICAgIH07XG4gICAgLy8g5bmz56e75bqm6YePXG4gICAgU2NhbGVUcmFuc2xhdGUucHJvdG90eXBlLnRyYW5zbGF0ZURpbSA9IGZ1bmN0aW9uIChkaW0sIG5vcm1hbFBvaW50KSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0RpbShkaW0pKSB7XG4gICAgICAgICAgICB2YXIgc2NhbGUgPSB0aGlzLmdldFNjYWxlKGRpbSk7XG4gICAgICAgICAgICBpZiAoc2NhbGUuaXNMaW5lYXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZUxpbmVhcihkaW0sIHNjYWxlLCBub3JtYWxQb2ludCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyAgZWxzZSB7IC8vIOaaguaXtuS7heWkhOeQhui/nue7reWtl+autVxuICAgICAgICAgICAgLy8gdGhpcy50cmFuc2xhdGVDYXRlZ29yeShkaW0sIHNjYWxlLCBub3JtYWxQb2ludCk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIGxpbmVhciDluqbph4/lubPnp7tcbiAgICBTY2FsZVRyYW5zbGF0ZS5wcm90b3R5cGUudHJhbnNsYXRlTGluZWFyID0gZnVuY3Rpb24gKGRpbSwgc2NhbGUsIG5vcm1hbFBvaW50KSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuc3RhcnRDYWNoZVtkaW1dLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heDtcbiAgICAgICAgdmFyIHJhbmdlID0gbWF4IC0gbWluO1xuICAgICAgICB2YXIgZCA9IG5vcm1hbFBvaW50W2RpbV0gKiByYW5nZTtcbiAgICAgICAgLy8g5Y+q5pyJ56ys5LiA5qyh57yT5a2Y77yM5ZCm5YiZ5peg5rOV5Zue5ruaXG4gICAgICAgIGlmICghdGhpcy5jYWNoZVNjYWxlRGVmc1tkaW1dKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2NhbGVEZWZzW2RpbV0gPSB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIG5pY2U6IHNjYWxlLm5pY2UsXG4gICAgICAgICAgICAgICAgbWluOiBtaW4sXG4gICAgICAgICAgICAgICAgbWF4OiBtYXgsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHZpZXcuc2NhbGUoc2NhbGUuZmllbGQsIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIG5pY2U6IGZhbHNlLFxuICAgICAgICAgICAgbWluOiBtaW4gKyBkLFxuICAgICAgICAgICAgbWF4OiBtYXggKyBkLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOW5s+enu+WIhuexu+eahOW6pumHj1xuICAgIC8vIHByaXZhdGUgdHJhbnNsYXRlQ2F0ZWdvcnkoZGltLCBzY2FsZSwgbm9ybWFsUG9pbnQpIHtcbiAgICAvLyB9XG4gICAgLyoqXG4gICAgICog5Zue5ruaXG4gICAgICovXG4gICAgU2NhbGVUcmFuc2xhdGUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlc2V0LmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMuc3RhcnRQb2ludCA9IG51bGw7XG4gICAgICAgIHRoaXMuc3RhcnRpbmcgPSBmYWxzZTtcbiAgICB9O1xuICAgIHJldHVybiBTY2FsZVRyYW5zbGF0ZTtcbn0oc2NhbGVfdHJhbnNmb3JtXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU2NhbGVUcmFuc2xhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zY2FsZS10cmFuc2xhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBzY2FsZV90cmFuc2Zvcm1fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3NjYWxlLXRyYW5zZm9ybVwiKSk7XG4vKipcbiAqIOe8qeaUviBTY2FsZSDnmoQgQWN0aW9uXG4gKiBAaWdub3JlXG4gKi9cbnZhciBTY2FsZVRyYW5zbGF0ZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTY2FsZVRyYW5zbGF0ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTY2FsZVRyYW5zbGF0ZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnpvb21SYXRpbyA9IDAuMDU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICAgICAgLy8g5bmz56e75YiG57G755qE5bqm6YePXG4gICAgICAgIC8vIHByaXZhdGUgdHJhbnNsYXRlQ2F0ZWdvcnkoZGltLCBzY2FsZSwgbm9ybWFsUG9pbnQpIHtcbiAgICAgICAgLy8gfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiDnvKnlsI9cbiAgICAgKi9cbiAgICBTY2FsZVRyYW5zbGF0ZS5wcm90b3R5cGUuem9vbUluID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnpvb20odGhpcy56b29tUmF0aW8pO1xuICAgIH07XG4gICAgU2NhbGVUcmFuc2xhdGUucHJvdG90eXBlLnpvb20gPSBmdW5jdGlvbiAoc2NhbGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGRpbXMgPSB0aGlzLmRpbXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGRpbXMsIGZ1bmN0aW9uIChkaW0pIHtcbiAgICAgICAgICAgIF90aGlzLnpvb21EaW0oZGltLCBzY2FsZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbnRleHQudmlldy5yZW5kZXIodHJ1ZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmlL7lpKdcbiAgICAgKi9cbiAgICBTY2FsZVRyYW5zbGF0ZS5wcm90b3R5cGUuem9vbU91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy56b29tKC0xICogdGhpcy56b29tUmF0aW8pO1xuICAgIH07XG4gICAgLy8g57yp5pS+5bqm6YePXG4gICAgU2NhbGVUcmFuc2xhdGUucHJvdG90eXBlLnpvb21EaW0gPSBmdW5jdGlvbiAoZGltLCBkUmF0aW8pIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzRGltKGRpbSkpIHtcbiAgICAgICAgICAgIHZhciBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUoZGltKTtcbiAgICAgICAgICAgIGlmIChzY2FsZS5pc0xpbmVhcikge1xuICAgICAgICAgICAgICAgIHRoaXMuem9vbUxpbmVhcihkaW0sIHNjYWxlLCBkUmF0aW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gIGVsc2UgeyAvLyDmmoLml7bku4XlpITnkIbov57nu63lrZfmrrVcbiAgICAgICAgICAgIC8vIHRoaXMuem9vbUNhdGVnb3J5KGRpbSwgc2NhbGUsIG5vcm1hbFBvaW50KTtcbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8gbGluZWFyIOW6pumHj+W5s+enu1xuICAgIFNjYWxlVHJhbnNsYXRlLnByb3RvdHlwZS56b29tTGluZWFyID0gZnVuY3Rpb24gKGRpbSwgc2NhbGUsIGRSYXRpbykge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuY29udGV4dC52aWV3O1xuICAgICAgICAvLyDlj6rmnInnrKzkuIDmrKHnvJPlrZjvvIzlkKbliJnml6Dms5Xlm57mu5pcbiAgICAgICAgaWYgKCF0aGlzLmNhY2hlU2NhbGVEZWZzW2RpbV0pIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTY2FsZURlZnNbZGltXSA9IHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgbmljZTogc2NhbGUubmljZSxcbiAgICAgICAgICAgICAgICBtaW46IHNjYWxlLm1pbixcbiAgICAgICAgICAgICAgICBtYXg6IHNjYWxlLm1heCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8g5L2/55So5L2/55So5Y6f5aeL5bqm6YeP5L2c5Li657yp5pS+5qCH5YeGXG4gICAgICAgIHZhciBzY2FsZURlZiA9IHRoaXMuY2FjaGVTY2FsZURlZnNbZGltXTtcbiAgICAgICAgdmFyIHJhbmdlID0gc2NhbGVEZWYubWF4IC0gc2NhbGVEZWYubWluO1xuICAgICAgICB2YXIgbWluID0gc2NhbGUubWluLCBtYXggPSBzY2FsZS5tYXg7XG4gICAgICAgIHZhciBkID0gZFJhdGlvICogcmFuZ2U7XG4gICAgICAgIHZhciB0b01pbiA9IG1pbiAtIGQ7XG4gICAgICAgIHZhciB0b01heCA9IG1heCArIGQ7XG4gICAgICAgIHZhciBjdXJSYW5nZSA9IHRvTWF4IC0gdG9NaW47XG4gICAgICAgIHZhciBzY2FsZWQgPSBjdXJSYW5nZSAvIHJhbmdlO1xuICAgICAgICBpZiAodG9NYXggPiB0b01pbiAmJiBzY2FsZWQgPCAxMDAgJiYgc2NhbGVkID4gMC4wMSkge1xuICAgICAgICAgICAgdmlldy5zY2FsZShzY2FsZS5maWVsZCwge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBuaWNlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBtaW46IG1pbiAtIGQsXG4gICAgICAgICAgICAgICAgbWF4OiBtYXggKyBkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBTY2FsZVRyYW5zbGF0ZTtcbn0oc2NhbGVfdHJhbnNmb3JtXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU2NhbGVUcmFuc2xhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zY2FsZS16b29tLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuL2FjdGlvbi91dGlsXCIpO1xuLyoqXG4gKiDkuqTkupLnmoTkuIrkuIvmlodcbiAqL1xudmFyIENvbnRleHQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGV4dCh2aWV3KSB7XG4gICAgICAgIC8qKiDlvZPliY3miYDmnInnmoQgQWN0aW9uICovXG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IFtdO1xuICAgICAgICAvKiog5b2T5YmN5LqL5Lu25a+56LGhICovXG4gICAgICAgIHRoaXMuZXZlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLmNhY2hlTWFwID0ge307XG4gICAgICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOe8k+WtmOS/oeaBr1xuICAgICAqIEBwYXJhbSBwYXJhbXMg57yT5a2Y55qE5a2X5q61XG4gICAgICogIC0g5aaC5p6c5LiA5Liq5a2X5q615YiZ6I635Y+W57yT5a2YXG4gICAgICogIC0g5Lik5Liq5a2X5q615YiZ6K6+572u57yT5a2YXG4gICAgICovXG4gICAgQ29udGV4dC5wcm90b3R5cGUuY2FjaGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYXJhbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHBhcmFtc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJhbXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYWNoZU1hcFtwYXJhbXNbMF1dO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBhcmFtcy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVNYXBbcGFyYW1zWzBdXSA9IHBhcmFtc1sxXTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+WIEFjdGlvblxuICAgICAqIEBwYXJhbSBuYW1lIEFjdGlvbiDnmoTlkI3np7BcbiAgICAgKi9cbiAgICBDb250ZXh0LnByb3RvdHlwZS5nZXRBY3Rpb24gPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hY3Rpb25zLmZpbmQoZnVuY3Rpb24gKGFjdGlvbikgeyByZXR1cm4gYWN0aW9uLm5hbWUgPT09IG5hbWU7IH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+WIEFjdGlvblxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIOWvueixoVxuICAgICAqL1xuICAgIENvbnRleHQucHJvdG90eXBlLmFkZEFjdGlvbiA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hY3Rpb25zLnB1c2goYWN0aW9uKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOenu+mZpCBBY3Rpb25cbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiDlr7nosaFcbiAgICAgKi9cbiAgICBDb250ZXh0LnByb3RvdHlwZS5yZW1vdmVBY3Rpb24gPSBmdW5jdGlvbiAoYWN0aW9uKSB7XG4gICAgICAgIHZhciBhY3Rpb25zID0gdGhpcy5hY3Rpb25zO1xuICAgICAgICB2YXIgaW5kZXggPSB0aGlzLmFjdGlvbnMuaW5kZXhPZihhY3Rpb24pO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgYWN0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blvZPliY3nmoTngrlcbiAgICAgKi9cbiAgICBDb250ZXh0LnByb3RvdHlwZS5nZXRDdXJyZW50UG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBldmVudCA9IHRoaXMuZXZlbnQ7XG4gICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdmFyIGNhbnZhcyA9IHRoaXMudmlldy5nZXRDYW52YXMoKTtcbiAgICAgICAgICAgICAgICB2YXIgcG9pbnQgPSBjYW52YXMuZ2V0UG9pbnRCeUNsaWVudChldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB4OiBldmVudC54LFxuICAgICAgICAgICAgICAgICAgICB5OiBldmVudC55LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5blvZPliY0gc2hhcGVcbiAgICAgKiBAcmV0dXJucyBjdXJyZW50IHNoYXBlXG4gICAgICovXG4gICAgQ29udGV4dC5wcm90b3R5cGUuZ2V0Q3VycmVudFNoYXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldCh0aGlzLmV2ZW50LCBbJ2dFdmVudCcsICdzaGFwZSddKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOW9k+WJjeeahOinpuWPkeaYr+WQpuWcqCBWaWV3IOWGhVxuICAgICAqL1xuICAgIENvbnRleHQucHJvdG90eXBlLmlzSW5QbG90ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9pbnQgPSB0aGlzLmdldEN1cnJlbnRQb2ludCgpO1xuICAgICAgICBpZiAocG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZpZXcuaXNQb2ludEluUGxvdChwb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5piv5ZCm5Zyo5oyH5a6a55qE5Zu+5b2i5YaFXG4gICAgICogQHBhcmFtIG5hbWUgc2hhcGUg55qEIG5hbWVcbiAgICAgKi9cbiAgICBDb250ZXh0LnByb3RvdHlwZS5pc0luU2hhcGUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB2YXIgc2hhcGUgPSB0aGlzLmdldEN1cnJlbnRTaGFwZSgpOyAvLyDkuI3lho3ogIPomZHlnKggc2hhcGUg55qEIHBhcmVudCDlhoXnmoTmg4XlhrVcbiAgICAgICAgaWYgKHNoYXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gc2hhcGUuZ2V0KCduYW1lJykgPT09IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5b2T5YmN55qE6Kem5Y+R5piv57uE5Lu25YaF6YOoXG4gICAgICogQHBhcmFtIG5hbWUg57uE5Lu25ZCN77yM5Y+v5Lul5Li656m6XG4gICAgICovXG4gICAgQ29udGV4dC5wcm90b3R5cGUuaXNJbkNvbXBvbmVudCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHZhciBjb21wb25lbnRzID0gdXRpbF8yLmdldENvbXBvbmVudHModGhpcy52aWV3KTtcbiAgICAgICAgdmFyIHBvaW50ID0gdGhpcy5nZXRDdXJyZW50UG9pbnQoKTtcbiAgICAgICAgaWYgKHBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gISFjb21wb25lbnRzLmZpbmQoZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBiYm94ID0gY29tcG9uZW50LmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29tcG9uZW50LmdldCgnbmFtZScpID09PSBuYW1lICYmIHV0aWxfMi5pc0luQm94KGJib3gsIHBvaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1dGlsXzIuaXNJbkJveChiYm94LCBwb2ludCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6ZSA5q+BXG4gICAgICovXG4gICAgQ29udGV4dC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy52aWV3ID0gbnVsbDtcbiAgICAgICAgdGhpcy5ldmVudCA9IG51bGw7XG4gICAgICAgIC8vIOWFiOmUgOavgSBhY3Rpb24g5YaN5riF56m677yM5LiA6L656YGN5Y6G77yM5LiA6L655Yig6Zmk77yM5omA5Lul5pWw57uE6ZyA6KaB5pu05paw5byV55SoXG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuYWN0aW9ucy5zbGljZSgpLCBmdW5jdGlvbiAoYWN0aW9uKSB7XG4gICAgICAgICAgICBhY3Rpb24uZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hY3Rpb25zID0gbnVsbDtcbiAgICAgICAgdGhpcy5jYWNoZU1hcCA9IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGV4dDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDb250ZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udGV4dC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHJlZ2lzdGVyXzEgPSByZXF1aXJlKFwiLi9hY3Rpb24vcmVnaXN0ZXJcIik7XG52YXIgY29udGV4dF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29udGV4dFwiKSk7XG52YXIgaW50ZXJhY3Rpb25fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2ludGVyYWN0aW9uXCIpKTtcbi8vIOWwhuWtl+espuS4sui9rOaNouaIkCBhY3Rpb25cbmZ1bmN0aW9uIHBhcnNlQWN0aW9uKGFjdGlvblN0ciwgY29udGV4dCkge1xuICAgIHZhciBhcnIgPSBhY3Rpb25TdHIuc3BsaXQoJzonKTtcbiAgICB2YXIgYWN0aW9uTmFtZSA9IGFyclswXTtcbiAgICAvLyDlpoLmnpzlt7Lnu4/liJ3lp4vljJbov4cgYWN0aW9uIO+8jOWImeebtOaOpeW8leeUqOS5i+WJjeeahCBhY3Rpb25cbiAgICB2YXIgYWN0aW9uID0gY29udGV4dC5nZXRBY3Rpb24oYWN0aW9uTmFtZSkgfHwgcmVnaXN0ZXJfMS5jcmVhdGVBY3Rpb24oYWN0aW9uTmFtZSwgY29udGV4dCk7XG4gICAgaWYgKCFhY3Rpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlcmUgaXMgbm8gYWN0aW9uIG5hbWVkIFwiICsgYWN0aW9uTmFtZSk7XG4gICAgfVxuICAgIHZhciBtZXRob2ROYW1lID0gYXJyWzFdO1xuICAgIHJldHVybiB7XG4gICAgICAgIGFjdGlvbjogYWN0aW9uLFxuICAgICAgICBtZXRob2ROYW1lOiBtZXRob2ROYW1lLFxuICAgIH07XG59XG4vLyDmiafooYwgQWN0aW9uXG5mdW5jdGlvbiBleGVjdXRlQWN0aW9uKGFjdGlvbk9iamVjdCkge1xuICAgIHZhciBhY3Rpb24gPSBhY3Rpb25PYmplY3QuYWN0aW9uLCBtZXRob2ROYW1lID0gYWN0aW9uT2JqZWN0Lm1ldGhvZE5hbWU7XG4gICAgaWYgKGFjdGlvblttZXRob2ROYW1lXSkge1xuICAgICAgICBhY3Rpb25bbWV0aG9kTmFtZV0oKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFjdGlvbihcIiArIGFjdGlvbi5uYW1lICsgXCIpIGRvZXNuJ3QgaGF2ZSBhIG1ldGhvZCBjYWxsZWQgXCIgKyBtZXRob2ROYW1lKTtcbiAgICB9XG59XG52YXIgU1RFUF9OQU1FUyA9IHtcbiAgICBTVEFSVDogJ3N0YXJ0JyxcbiAgICBTSE9XX0VOQUJMRTogJ3Nob3dFbmFibGUnLFxuICAgIEVORDogJ2VuZCcsXG4gICAgUk9MTEJBQ0s6ICdyb2xsYmFjaycsXG4gICAgUFJPQ0VTU0lORzogJ3Byb2Nlc3NpbmcnLFxufTtcbi8qKlxuICog5pSv5oyB6K+t5rOV55qE5Lqk5LqS57G7XG4gKi9cbnZhciBHcmFtbWFySW50ZXJhY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR3JhbW1hckludGVyYWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyYW1tYXJJbnRlcmFjdGlvbih2aWV3LCBzdGVwcykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB2aWV3LCBzdGVwcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuY2FsbGJhY2tDYWNoZXMgPSB7fTtcbiAgICAgICAgLy8g5p+Q5Liq6Kem5Y+R5ZKM5Y+N6aaI5Zyo5pys546v6IqC5piv5ZCm5omn6KGM5oiWXG4gICAgICAgIF90aGlzLmVtaXRDYWNoZXMgPSB7fTtcbiAgICAgICAgX3RoaXMuc3RlcHMgPSBzdGVwcztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDliJ3lp4vljJZcbiAgICAgKi9cbiAgICBHcmFtbWFySW50ZXJhY3Rpb24ucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5pdENvbnRleHQoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuIXnkIbotYTmupBcbiAgICAgKi9cbiAgICBHcmFtbWFySW50ZXJhY3Rpb24ucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpOyAvLyDlhYjmuIXnkIbkuovku7ZcbiAgICAgICAgdGhpcy5zdGVwcyA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FsbGJhY2tDYWNoZXMgPSBudWxsO1xuICAgICAgICB0aGlzLnZpZXcgPSBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog57uR5a6a5LqL5Lu2XG4gICAgICovXG4gICAgR3JhbW1hckludGVyYWN0aW9uLnByb3RvdHlwZS5pbml0RXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLnN0ZXBzLCBmdW5jdGlvbiAoc3RlcEFyciwgc3RlcE5hbWUpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHN0ZXBBcnIsIGZ1bmN0aW9uIChzdGVwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gX3RoaXMuZ2V0QWN0aW9uQ2FsbGJhY2soc3RlcE5hbWUsIHN0ZXApO1xuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzlrZjlnKggY2FsbGJhY2vvvIzmiY3nu5HlrprvvIzmnInml7blgJnkvJrlh7rnjrDml6AgY2FsbGJhY2sg55qE5oOF5Ya1XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmJpbmRFdmVudChzdGVwLnRyaWdnZXIsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDmuIXnkIbnu5HlrprnmoTkuovku7ZcbiAgICAgKi9cbiAgICBHcmFtbWFySW50ZXJhY3Rpb24ucHJvdG90eXBlLmNsZWFyRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLnN0ZXBzLCBmdW5jdGlvbiAoc3RlcEFyciwgc3RlcE5hbWUpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHN0ZXBBcnIsIGZ1bmN0aW9uIChzdGVwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gX3RoaXMuZ2V0QWN0aW9uQ2FsbGJhY2soc3RlcE5hbWUsIHN0ZXApO1xuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5vZmZFdmVudChzdGVwLnRyaWdnZXIsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyDliJ3lp4vljJbkuIrkuIvmlofvvIzlubbliJ3lp4vljJYgYWN0aW9uXG4gICAgR3JhbW1hckludGVyYWN0aW9uLnByb3RvdHlwZS5pbml0Q29udGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZhciBjb250ZXh0ID0gbmV3IGNvbnRleHRfMS5kZWZhdWx0KHZpZXcpO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB2YXIgc3RlcHMgPSB0aGlzLnN0ZXBzO1xuICAgICAgICAvLyDnlJ/miJDlhbfkvZPnmoQgQWN0aW9uXG4gICAgICAgIHV0aWxfMS5lYWNoKHN0ZXBzLCBmdW5jdGlvbiAoc3ViU3RlcHMpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHN1YlN0ZXBzLCBmdW5jdGlvbiAoc3RlcCkge1xuICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzdGVwLmFjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5Lyg5YWl5Zue6LCD5Ye95pWw77yM5YiZ55u05o6l55Sf5oiQIENhbGxiYWNrQWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHN0ZXAuYWN0aW9uT2JqZWN0ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiByZWdpc3Rlcl8xLmNyZWF0ZUNhbGxiYWNrQWN0aW9uKHN0ZXAuYWN0aW9uLCBjb250ZXh0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6ICdleGVjdXRlJyxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzU3RyaW5nKHN0ZXAuYWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzmmK/lrZfnrKbkuLJcbiAgICAgICAgICAgICAgICAgICAgc3RlcC5hY3Rpb25PYmplY3QgPSBwYXJzZUFjdGlvbihzdGVwLmFjdGlvbiwgY29udGV4dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc0FycmF5KHN0ZXAuYWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzmmK/mlbDnu4RcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbkFyciA9IHN0ZXAuYWN0aW9uO1xuICAgICAgICAgICAgICAgICAgICBzdGVwLmFjdGlvbk9iamVjdCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChhY3Rpb25BcnIsIGZ1bmN0aW9uIChhY3Rpb25TdHIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAuYWN0aW9uT2JqZWN0LnB1c2gocGFyc2VBY3Rpb24oYWN0aW9uU3RyLCBjb250ZXh0KSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyDlpoLmnpwgYWN0aW9uIOaXouS4jeaYr+Wtl+espuS4su+8jOS5n+S4jeaYr+WHveaVsO+8jOWImeS4jeS8mueUn+aIkCBhY3Rpb25PYmplY3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIOaYr+WQpuWFgeiuuOaMh+WumumYtuauteWQjeensOaJp+ihjFxuICAgIEdyYW1tYXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuaXNBbGxvd1N0ZXAgPSBmdW5jdGlvbiAoc3RlcE5hbWUpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRTdGVwTmFtZSA9IHRoaXMuY3VycmVudFN0ZXBOYW1lO1xuICAgICAgICB2YXIgc3RlcHMgPSB0aGlzLnN0ZXBzO1xuICAgICAgICAvLyDnm7jlkIznmoTpmLbmrrXlhYHorrjlkIzml7bmiafooYxcbiAgICAgICAgaWYgKGN1cnJlbnRTdGVwTmFtZSA9PT0gc3RlcE5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGVwTmFtZSA9PT0gU1RFUF9OQU1FUy5TSE9XX0VOQUJMRSkge1xuICAgICAgICAgICAgLy8g56S66IO95Zyo5pW05Liq6L+H56iL5Lit6YO95Y+v55SoXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RlcE5hbWUgPT09IFNURVBfTkFNRVMuUFJPQ0VTU0lORykge1xuICAgICAgICAgICAgLy8g5Y+q5pyJ5b2T5YmN5pivIHN0YXJ0IOaXtu+8jOaJjeWFgeiuuCBwcm9jZXNzaW5nXG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFN0ZXBOYW1lID09PSBTVEVQX05BTUVTLlNUQVJUO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGVwTmFtZSA9PT0gU1RFUF9OQU1FUy5TVEFSVCkge1xuICAgICAgICAgICAgLy8g5aaC5p6c5b2T5YmN5pivIHByb2Nlc3NpbmfvvIzliJnml6Dms5Ugc3RhcnTvvIzlv4XpobvnrYnlvoUgZW5kIOWQjuaJjeiDveaJp+ihjFxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGVwTmFtZSAhPT0gU1RFUF9OQU1FUy5QUk9DRVNTSU5HO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGVwTmFtZSA9PT0gU1RFUF9OQU1FUy5FTkQpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50U3RlcE5hbWUgPT09IFNURVBfTkFNRVMuUFJPQ0VTU0lORyB8fCBjdXJyZW50U3RlcE5hbWUgPT09IFNURVBfTkFNRVMuU1RBUlQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0ZXBOYW1lID09PSBTVEVQX05BTUVTLlJPTExCQUNLKSB7XG4gICAgICAgICAgICBpZiAoc3RlcHNbU1RFUF9OQU1FUy5FTkRdKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5a6a5LmJ5LqGIGVuZCwg5Y+q5pyJIGVuZCDml7bmiY3lhYHorrjlm57mu5pcbiAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFN0ZXBOYW1lID09PSBTVEVQX05BTUVTLkVORDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRTdGVwTmFtZSA9PT0gU1RFUF9OQU1FUy5TVEFSVCkge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOacquWumuS5iSBlbmQsIOWImeWIpOaWreaYr+WQpuaYr+W8gOWni1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIC8vIOWFt+S9k+eahOaMh+WumumYtuauteaYr+WQpuWFgeiuuOaJp+ihjFxuICAgIEdyYW1tYXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuaXNBbGxvd0V4Y3V0ZSA9IGZ1bmN0aW9uIChzdGVwTmFtZSwgc3RlcCkge1xuICAgICAgICBpZiAodGhpcy5pc0FsbG93U3RlcChzdGVwTmFtZSkpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLmdldEtleShzdGVwTmFtZSwgc3RlcCk7XG4gICAgICAgICAgICAvLyDlpoLmnpzmmK/lnKjmnKznjq/oioLlhoXku4XlhYHorrjop6blj5HkuIDmrKHvvIzlkIzml7blt7Lnu4/op6blj5Hov4fvvIzliJnkuI3lhYHorrjlho3op6blj5FcbiAgICAgICAgICAgIGlmIChzdGVwLm9uY2UgJiYgdGhpcy5lbWl0Q2FjaGVzW2tleV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDlpoLmnpzmmK/lhYHorrjnmoTpmLbmrrXvvIzliJnpqozor4EgaXNFbmFibGUg5pa55rOVXG4gICAgICAgICAgICBpZiAoc3RlcC5pc0VuYWJsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzdGVwLmlzRW5hYmxlKHRoaXMuY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8g5aaC5p6c5rKh5pyJIGlzRW5hYmxlIOWImeWFgeiuuOaJp+ihjFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEdyYW1tYXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuZW50ZXJTdGVwID0gZnVuY3Rpb24gKHN0ZXBOYW1lKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFN0ZXBOYW1lID0gc3RlcE5hbWU7XG4gICAgICAgIHRoaXMuZW1pdENhY2hlcyA9IHt9OyAvLyDmuIXpmaTmiYDmnInmnKznjq/oioLop6blj5HnmoTnvJPlrZhcbiAgICB9O1xuICAgIC8vIOaJp+ihjOWujOafkOS4quinpuWPkeWSjOWPjemmiO+8iOWtkOeOr+iKgu+8iVxuICAgIEdyYW1tYXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuYWZ0ZXJFeGVjdXRlID0gZnVuY3Rpb24gKHN0ZXBOYW1lLCBzdGVwKSB7XG4gICAgICAgIC8vIHNob3cgZW5hYmxlIOS4jeiuoeWFpeato+W4uOeahOa1geeoi++8jOWFtuS7luaDheWGteWImeiuvue9ruW9k+WJjeeahCBzdGVwXG4gICAgICAgIGlmIChzdGVwTmFtZSAhPT0gU1RFUF9OQU1FUy5TSE9XX0VOQUJMRSAmJiB0aGlzLmN1cnJlbnRTdGVwTmFtZSAhPT0gc3RlcE5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMuZW50ZXJTdGVwKHN0ZXBOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIga2V5ID0gdGhpcy5nZXRLZXkoc3RlcE5hbWUsIHN0ZXApO1xuICAgICAgICAvLyDkuIDml6bmiafooYzvvIzliJnnvJPlrZjmoIforrDkuLrvvIzkuIDnm7Tkv53mjIHliLDot7Plh7rmlLnnjq/oioJcbiAgICAgICAgdGhpcy5lbWl0Q2FjaGVzW2tleV0gPSB0cnVlO1xuICAgIH07XG4gICAgLy8g6I635Y+W5p+Q5Liq546v6IqC55qE5ZSv5LiA55qE6ZSu5YC8XG4gICAgR3JhbW1hckludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRLZXkgPSBmdW5jdGlvbiAoc3RlcE5hbWUsIHN0ZXApIHtcbiAgICAgICAgcmV0dXJuIHN0ZXBOYW1lICsgc3RlcC50cmlnZ2VyICsgc3RlcC5hY3Rpb247XG4gICAgfTtcbiAgICAvLyDojrflj5Ygc3RlcCDnmoTlm57osIPlh73mlbDvvIzlpoLmnpzlt7Lnu4/nlJ/miJDvvIzliJnnm7TmjqXov5Tlm57vvIzlpoLmnpzmnKrnlJ/miJDvvIzliJnliJvlu7pcbiAgICBHcmFtbWFySW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldEFjdGlvbkNhbGxiYWNrID0gZnVuY3Rpb24gKHN0ZXBOYW1lLCBzdGVwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICB2YXIgY2FsbGJhY2tDYWNoZXMgPSB0aGlzLmNhbGxiYWNrQ2FjaGVzO1xuICAgICAgICB2YXIgYWN0aW9uT2JqZWN0ID0gc3RlcC5hY3Rpb25PYmplY3Q7XG4gICAgICAgIGlmIChzdGVwLmFjdGlvbiAmJiBhY3Rpb25PYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLmdldEtleShzdGVwTmFtZSwgc3RlcCk7XG4gICAgICAgICAgICBpZiAoIWNhbGxiYWNrQ2FjaGVzW2tleV0pIHtcbiAgICAgICAgICAgICAgICAvLyDliqjmgIHnlJ/miJDmiafooYznmoTmlrnms5XvvIzmiafooYzlr7nlupQgYWN0aW9uIOeahOWQjeensFxuICAgICAgICAgICAgICAgIHZhciBhY3Rpb25DYWxsYmFjayA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmV2ZW50ID0gZXZlbnQ7IC8vIOS/neivgeajgOa1i+aXtueahCBldmVudFxuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuaXNBbGxvd0V4Y3V0ZShzdGVwTmFtZSwgc3RlcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOWmguaenOaYr+aVsOe7hOaXtu+8jOWImeS+neasoeaJp+ihjFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KGFjdGlvbk9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChhY3Rpb25PYmplY3QsIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5ldmVudCA9IGV2ZW50OyAvLyDlj6/og73op6blj5HmlrDnmoTkuovku7bvvIzkv53or4HmiafooYzliY3nmoQgY29udGV4dC5ldmVudCDmmK/mraPnoa7nmoRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZUFjdGlvbihvYmopO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5ldmVudCA9IGV2ZW50OyAvLyDkv53or4HmiafooYzliY3nmoQgY29udGV4dC5ldmVudCDmmK/mraPnoa7nmoRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlQWN0aW9uKGFjdGlvbk9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5hZnRlckV4ZWN1dGUoc3RlcE5hbWUsIHN0ZXApO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0ZXAuY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmV2ZW50ID0gZXZlbnQ7IC8vIOS/neivgeaJp+ihjOWJjeeahCBjb250ZXh0LmV2ZW50IOaYr+ato+ehrueahFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAuY2FsbGJhY2soY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzmnKrpgJrov4fpqozor4HvvIzliJnkuovku7bkuI3opoHnu5HlrprlnKjkuIrpnaJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZXZlbnQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzorr7nva7kuoYgZGVib3VuY2VcbiAgICAgICAgICAgICAgICBpZiAoc3RlcC5kZWJvdW5jZSkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja0NhY2hlc1trZXldID0gdXRpbF8xLmRlYm91bmNlKGFjdGlvbkNhbGxiYWNrLCBzdGVwLmRlYm91bmNlLndhaXQsIHN0ZXAuZGVib3VuY2UuaW1tZWRpYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoc3RlcC50aHJvdHRsZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDorr7nva4gdGhyb3R0bGVcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tDYWNoZXNba2V5XSA9IHV0aWxfMS50aHJvdHRsZShhY3Rpb25DYWxsYmFjaywgc3RlcC50aHJvdHRsZS53YWl0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWFkaW5nOiBzdGVwLnRocm90dGxlLmxlYWRpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFpbGluZzogc3RlcC50aHJvdHRsZS50cmFpbGluZyxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyDnm7TmjqXorr7nva5cbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tDYWNoZXNba2V5XSA9IGFjdGlvbkNhbGxiYWNrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFja0NhY2hlc1trZXldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgR3JhbW1hckludGVyYWN0aW9uLnByb3RvdHlwZS5iaW5kRXZlbnQgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgbmFtZUFyciA9IGV2ZW50TmFtZS5zcGxpdCgnOicpO1xuICAgICAgICBpZiAobmFtZUFyclswXSA9PT0gJ3dpbmRvdycpIHtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKG5hbWVBcnJbMV0sIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lQXJyWzBdID09PSAnZG9jdW1lbnQnKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKG5hbWVBcnJbMV0sIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlldy5vbihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgR3JhbW1hckludGVyYWN0aW9uLnByb3RvdHlwZS5vZmZFdmVudCA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBuYW1lQXJyID0gZXZlbnROYW1lLnNwbGl0KCc6Jyk7XG4gICAgICAgIGlmIChuYW1lQXJyWzBdID09PSAnd2luZG93Jykge1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZUFyclsxXSwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5hbWVBcnJbMF0gPT09ICdkb2N1bWVudCcpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZUFyclsxXSwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3Lm9mZihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIEdyYW1tYXJJbnRlcmFjdGlvbjtcbn0oaW50ZXJhY3Rpb25fMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBHcmFtbWFySW50ZXJhY3Rpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncmFtbWFyLWludGVyYWN0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5jcmVhdGVJbnRlcmFjdGlvbiA9IGV4cG9ydHMucmVnaXN0ZXJJbnRlcmFjdGlvbiA9IGV4cG9ydHMuZ2V0SW50ZXJhY3Rpb24gPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBncmFtbWFyX2ludGVyYWN0aW9uXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9ncmFtbWFyLWludGVyYWN0aW9uXCIpKTtcbnZhciBJbnRlcmFjdGlvbnMgPSB7fTtcbi8qKlxuICog5qC55o2u5Lqk5LqS6KGM5Li65ZCN5a2X6I635Y+W5a+55bqU55qE5Lqk5LqS57G7XG4gKiBAcGFyYW0gbmFtZSDkuqTkupLlkI3lrZdcbiAqIEByZXR1cm5zIOS6pOS6kuexu1xuICovXG5mdW5jdGlvbiBnZXRJbnRlcmFjdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIEludGVyYWN0aW9uc1t1dGlsXzEubG93ZXJDYXNlKG5hbWUpXTtcbn1cbmV4cG9ydHMuZ2V0SW50ZXJhY3Rpb24gPSBnZXRJbnRlcmFjdGlvbjtcbi8qKlxuICog5rOo5YaM5Lqk5LqS6KGM5Li6XG4gKiBAcGFyYW0gbmFtZSDkuqTkupLooYzkuLrlkI3lrZdcbiAqIEBwYXJhbSBpbnRlcmFjdGlvbiDkuqTkupLnsbtcbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJJbnRlcmFjdGlvbihuYW1lLCBpbnRlcmFjdGlvbikge1xuICAgIEludGVyYWN0aW9uc1t1dGlsXzEubG93ZXJDYXNlKG5hbWUpXSA9IGludGVyYWN0aW9uO1xufVxuZXhwb3J0cy5yZWdpc3RlckludGVyYWN0aW9uID0gcmVnaXN0ZXJJbnRlcmFjdGlvbjtcbi8qKlxuICog5Yib5bu65Lqk5LqS5a6e5L6LXG4gKiBAcGFyYW0gbmFtZSDkuqTkupLlkI1cbiAqIEBwYXJhbSB2aWV3IOS6pOS6kuW6lOeUqOeahCBWaWV3IOWunuS+i1xuICogQHBhcmFtIGNmZyDkuqTkupLooYzkuLrphY3nva5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW50ZXJhY3Rpb24obmFtZSwgdmlldywgY2ZnKSB7XG4gICAgdmFyIGludGVyYWNpdG9uID0gZ2V0SW50ZXJhY3Rpb24obmFtZSk7XG4gICAgaWYgKCFpbnRlcmFjaXRvbikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHV0aWxfMS5pc1BsYWluT2JqZWN0KGludGVyYWNpdG9uKSkge1xuICAgICAgICAvLyDlpoLmnpzkuI0gY2xvbmUg5YiZ5Lya5aSa5LiqIGludGVyYWN0aW9uIOWunuS+i+WFseS6qyBzdGVwIOeahOWumuS5iVxuICAgICAgICB2YXIgc3RlcHMgPSB1dGlsXzEubWl4KHV0aWxfMS5jbG9uZShpbnRlcmFjaXRvbiksIGNmZyk7XG4gICAgICAgIHJldHVybiBuZXcgZ3JhbW1hcl9pbnRlcmFjdGlvbl8xLmRlZmF1bHQodmlldywgc3RlcHMpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGNscyA9IGludGVyYWNpdG9uO1xuICAgICAgICByZXR1cm4gbmV3IGNscyh2aWV3LCBjZmcpO1xuICAgIH1cbn1cbmV4cG9ydHMuY3JlYXRlSW50ZXJhY3Rpb24gPSBjcmVhdGVJbnRlcmFjdGlvbjtcbnZhciBpbnRlcmFjdGlvbl8xID0gcmVxdWlyZShcIi4vaW50ZXJhY3Rpb25cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJJbnRlcmFjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaW50ZXJhY3Rpb25fMS5kZWZhdWx0OyB9IH0pO1xudmFyIGFjdGlvbl8xID0gcmVxdWlyZShcIi4vYWN0aW9uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQWN0aW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBhY3Rpb25fMS5BY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckFjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYWN0aW9uXzEucmVnaXN0ZXJBY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRBY3Rpb25DbGFzc1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYWN0aW9uXzEuZ2V0QWN0aW9uQ2xhc3M7IH0gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKlxuICog5Lqk5LqS55qE5Z+657G744CCXG4gKi9cbnZhciBJbnRlcmFjdGlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBJbnRlcmFjdGlvbih2aWV3LCBjZmcpIHtcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdGhpcy5jZmcgPSBjZmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOWIneWni+WMluOAglxuICAgICAqL1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmluaXRFdmVudHMoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe7keWumuS6i+S7tlxuICAgICAqL1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5pbml0RXZlbnRzID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIC8qKlxuICAgICAqIOmUgOavgeS6i+S7tlxuICAgICAqL1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5jbGVhckV2ZW50cyA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICAvKipcbiAgICAgKiDplIDmr4HjgIJcbiAgICAgKi9cbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jbGVhckV2ZW50cygpO1xuICAgIH07XG4gICAgcmV0dXJuIEludGVyYWN0aW9uO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEludGVyYWN0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJhY3Rpb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnRlcmZhY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyVGhlbWUgPSBleHBvcnRzLmdldFRoZW1lID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aGVtZVwiKTtcbnZhciBsaWdodF8xID0gcmVxdWlyZShcIi4vc3R5bGUtc2hlZXQvbGlnaHRcIik7XG52YXIgZGVmYXVsdFRoZW1lID0gdGhlbWVfMS5jcmVhdGVUaGVtZUJ5U3R5bGVzaGVldChsaWdodF8xLmFudHZMaWdodCk7XG4vLyDmiYDmnInlt7Lnu4/lrZjlnKjnmoTkuLvpophcbnZhciBUaGVtZXMgPSB7XG4gICAgZGVmYXVsdDogZGVmYXVsdFRoZW1lLFxufTtcbi8qKlxuICog6I635Y+W5Li76aKY6YWN572u5L+h5oGv44CCXG4gKiBAcGFyYW0gdGhlbWUg5Li76aKY5ZCNXG4gKi9cbmZ1bmN0aW9uIGdldFRoZW1lKHRoZW1lKSB7XG4gICAgcmV0dXJuIHV0aWxfMS5nZXQoVGhlbWVzLCB1dGlsXzEubG93ZXJDYXNlKHRoZW1lKSwgVGhlbWVzLmRlZmF1bHQpO1xufVxuZXhwb3J0cy5nZXRUaGVtZSA9IGdldFRoZW1lO1xuLyoqXG4gKiDms6jlhozmlrDnmoTkuLvpopjphY3nva7kv6Hmga/jgIJcbiAqIEBwYXJhbSB0aGVtZSDkuLvpopjlkI3jgIJcbiAqIEBwYXJhbSB2YWx1ZSDlhbfkvZPnmoTkuLvpopjphY3nva7jgIJcbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJUaGVtZSh0aGVtZSwgdmFsdWUpIHtcbiAgICBUaGVtZXNbdXRpbF8xLmxvd2VyQ2FzZSh0aGVtZSldID0gdXRpbF8xLmRlZXBNaXgoe30sIFRoZW1lcy5kZWZhdWx0LCB2YWx1ZSk7XG59XG5leHBvcnRzLnJlZ2lzdGVyVGhlbWUgPSByZWdpc3RlclRoZW1lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmFudHZEYXJrID0gdm9pZCAwO1xudmFyIFdISVRFX0NPTE9SUyA9IHtcbiAgICAxMDA6ICcjMDAwJyxcbiAgICA5NTogJyMwRDBEMEQnLFxuICAgIDg1OiAnIzI2MjYyNicsXG4gICAgNjU6ICcjNTk1OTU5JyxcbiAgICA0NTogJyM4QzhDOEMnLFxuICAgIDI1OiAnI0JGQkZCRicsXG4gICAgMTU6ICcjRDlEOUQ5JyxcbiAgICA2OiAnI0YwRjBGMCcsXG59O1xudmFyIEJMQUNLX0NPTE9SUyA9IHtcbiAgICAxMDA6ICcjRkZGRkZGJyxcbiAgICA5NTogJyNGMkYyRjInLFxuICAgIDg1OiAnI0Q5RDlEOScsXG4gICAgNjU6ICcjQTZBNkE2JyxcbiAgICA0NTogJyM3MzczNzMnLFxuICAgIDI1OiAnIzQwNDA0MCcsXG4gICAgMTU6ICcjMjYyNjI2JyxcbiAgICA2OiAnIzBGMEYwRicsXG59O1xudmFyIFFVQUxJVEFUSVZFXzEwID0gW1xuICAgICcjNUI4RkY5JyxcbiAgICAnIzVBRDhBNicsXG4gICAgJyM1RDcwOTInLFxuICAgICcjRjZCRDE2JyxcbiAgICAnI0U4NjQ1MicsXG4gICAgJyM2REM4RUMnLFxuICAgICcjOTQ1RkI5JyxcbiAgICAnI0ZGOTg0NScsXG4gICAgJyMxRTk0OTMnLFxuICAgICcjRkY5OUMzJyxcbl07XG52YXIgUVVBTElUQVRJVkVfMjAgPSBbXG4gICAgJyM1QjhGRjknLFxuICAgICcjQ0REREZEJyxcbiAgICAnIzVBRDhBNicsXG4gICAgJyNDREYzRTQnLFxuICAgICcjNUQ3MDkyJyxcbiAgICAnI0NFRDRERScsXG4gICAgJyNGNkJEMTYnLFxuICAgICcjRkNFQkI5JyxcbiAgICAnI0U4NjQ1MicsXG4gICAgJyNGOEQwQ0InLFxuICAgICcjNkRDOEVDJyxcbiAgICAnI0QzRUVGOScsXG4gICAgJyM5NDVGQjknLFxuICAgICcjREVDRkVBJyxcbiAgICAnI0ZGOTg0NScsXG4gICAgJyNGRkUwQzcnLFxuICAgICcjMUU5NDkzJyxcbiAgICAnI0JCREVERScsXG4gICAgJyNGRjk5QzMnLFxuICAgICcjRkZFMEVEJyxcbl07XG5leHBvcnRzLmFudHZEYXJrID0ge1xuICAgIGJhY2tncm91bmRDb2xvcjogJyMxNDE0MTQnLFxuICAgIC8qKiDkuLvpopjoibIgKi9cbiAgICBicmFuZENvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiog5YiG57G76Imy5p2/IDHvvIzlnKjmlbDmja7ph4/lsI/kuo7nrYnkuo4gMTAg5pe25L2/55SoICovXG4gICAgcGFsZXR0ZVF1YWxpdGF0aXZlMTA6IFFVQUxJVEFUSVZFXzEwLFxuICAgIC8qKiDliIbnsbvoibLmnb8gMu+8jOWcqOaVsOaNrumHj+Wkp+S6jiAxMCDml7bkvb/nlKggKi9cbiAgICBwYWxldHRlUXVhbGl0YXRpdmUyMDogUVVBTElUQVRJVkVfMjAsXG4gICAgLyoqIOivreS5ieiJsiAqL1xuICAgIHBhbGV0dGVTZW1hbnRpY1JlZDogJyNGNDY2NEEnLFxuICAgIC8qKiDor63kuYnoibIgKi9cbiAgICBwYWxldHRlU2VtYW50aWNHcmVlbjogJyMzMEJGNzgnLFxuICAgIC8qKiDor63kuYnoibIgKi9cbiAgICBwYWxldHRlU2VtYW50aWNZZWxsb3c6ICcjRkFBRDE0JyxcbiAgICAvKiog5a2X5L2TICovXG4gICAgZm9udEZhbWlseTogXCJcXFwiLWFwcGxlLXN5c3RlbVxcXCIsIFxcXCJTZWdvZSBVSVxcXCIsIFJvYm90bywgXFxcIkhlbHZldGljYSBOZXVlXFxcIiwgQXJpYWwsXFxuICBcXFwiTm90byBTYW5zXFxcIiwgc2Fucy1zZXJpZiwgXFxcIkFwcGxlIENvbG9yIEVtb2ppXFxcIiwgXFxcIlNlZ29lIFVJIEVtb2ppXFxcIiwgXFxcIlNlZ29lIFVJIFN5bWJvbFxcXCIsXFxuICBcXFwiTm90byBDb2xvciBFbW9qaVxcXCJcIixcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLSDlnZDmoIfovbQgLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKiog5Z2Q5qCH6L2057q/6aKc6ImyICovXG4gICAgYXhpc0xpbmVCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzI1XSxcbiAgICAvKiog5Z2Q5qCH6L2057q/57KX57uGICovXG4gICAgYXhpc0xpbmVCb3JkZXI6IDAuNSxcbiAgICAvKiog5Z2Q5qCH6L2057q/IGxpbmVEYXNoIOiuvue9riAqL1xuICAgIGF4aXNMaW5lRGFzaDogbnVsbCxcbiAgICAvKiog5Z2Q5qCH6L205qCH6aKY6aKc6ImyICovXG4gICAgYXhpc1RpdGxlVGV4dEZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzY1XSxcbiAgICAvKiog5Z2Q5qCH6L205qCH6aKY5paH5pys5a2X5L2T5aSn5bCPICovXG4gICAgYXhpc1RpdGxlVGV4dEZvbnRTaXplOiAxMixcbiAgICAvKiog5Z2Q5qCH6L205qCH6aKY5paH5pys6KGM6auYICovXG4gICAgYXhpc1RpdGxlVGV4dExpbmVIZWlnaHQ6IDEyLFxuICAgIC8qKiDlnZDmoIfovbTmoIfpopjmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICBheGlzVGl0bGVUZXh0Rm9udFdlaWdodDogJ25vcm1hbCcsXG4gICAgLyoqIOWdkOagh+i9tOWIu+W6pue6v+minOiJsiAqL1xuICAgIGF4aXNUaWNrTGluZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMjVdLFxuICAgIC8qKiDlnZDmoIfovbTliLvluqbnur/plb/luqYgKi9cbiAgICBheGlzVGlja0xpbmVMZW5ndGg6IDQsXG4gICAgLyoqIOWdkOagh+i9tOWIu+W6pue6v+eyl+e7hiAqL1xuICAgIGF4aXNUaWNrTGluZUJvcmRlcjogMC41LFxuICAgIC8qKiDlnZDmoIfovbTmrKHliLvluqbnur/popzoibIgKi9cbiAgICBheGlzU3ViVGlja0xpbmVCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzE1XSxcbiAgICAvKiog5Z2Q5qCH6L205qyh5Yi75bqm57q/6ZW/5bqmICovXG4gICAgYXhpc1N1YlRpY2tMaW5lTGVuZ3RoOiAyLFxuICAgIC8qKiDlnZDmoIfovbTmrKHliLvluqbnur/nspfnu4YgKi9cbiAgICBheGlzU3ViVGlja0xpbmVCb3JkZXI6IDAuNSxcbiAgICAvKiog5Z2Q5qCH6L205Yi75bqm5paH5pys6aKc6ImyICovXG4gICAgYXhpc0xhYmVsRmlsbENvbG9yOiBCTEFDS19DT0xPUlNbNDVdLFxuICAgIC8qKiDlnZDmoIfovbTliLvluqbmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICBheGlzTGFiZWxGb250U2l6ZTogMTIsXG4gICAgLyoqIOWdkOagh+i9tOWIu+W6puaWh+acrOihjOmrmCAqL1xuICAgIGF4aXNMYWJlbExpbmVIZWlnaHQ6IDEyLFxuICAgIC8qKiDlnZDmoIfovbTliLvluqbmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICBheGlzTGFiZWxGb250V2VpZ2h0OiAnbm9ybWFsJyxcbiAgICAvKiog5Z2Q5qCH6L20572R5qC857q/6aKc6ImyICovXG4gICAgYXhpc0dyaWRCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzE1XSxcbiAgICAvKiog5Z2Q5qCH6L20572R5qC857q/57KX57uGICovXG4gICAgYXhpc0dyaWRCb3JkZXI6IDAuNSxcbiAgICAvKiog5Z2Q5qCH6L20572R5qC857q/6Jma57q/6K6+572uICovXG4gICAgYXhpc0dyaWRMaW5lRGFzaDogbnVsbCxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLSDlm77kvosgLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKiog5Zu+5L6L5qCH6aKY6aKc6ImyICovXG4gICAgbGVnZW5kVGl0bGVUZXh0RmlsbENvbG9yOiBCTEFDS19DT0xPUlNbNDVdLFxuICAgIC8qKiDlm77kvovmoIfpopjmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICBsZWdlbmRUaXRsZVRleHRGb250U2l6ZTogMTIsXG4gICAgLyoqIOWbvuS+i+agh+mimOaWh+acrOihjOmrmCAqL1xuICAgIGxlZ2VuZFRpdGxlVGV4dExpbmVIZWlnaHQ6IDIxLFxuICAgIC8qKiDlm77kvovmoIfpopjmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICBsZWdlbmRUaXRsZVRleHRGb250V2VpZ2h0OiAnbm9ybWFsJyxcbiAgICAvKiog5Zu+5L6LIG1hcmtlciDpopzoibIgKi9cbiAgICBsZWdlbmRNYXJrZXJDb2xvcjogUVVBTElUQVRJVkVfMTBbMF0sXG4gICAgLyoqIOWbvuS+iyBtYXJrZXIg6buY6K6k5Y2K5b6E5aSn5bCPICovXG4gICAgbGVnZW5kTWFya2VyU2l6ZTogNCxcbiAgICAvKiog5Zu+5L6LICdjaXJjbGUnIG1hcmtlciDljYrlvoQgKi9cbiAgICBsZWdlbmRDaXJjbGVNYXJrZXJTaXplOiA0LFxuICAgIC8qKiDlm77kvosgJ3NxdWFyZScgbWFya2VyIOWNiuW+hCAqL1xuICAgIGxlZ2VuZFNxdWFyZU1hcmtlclNpemU6IDQsXG4gICAgLyoqIOWbvuS+iyAnbGluZScgbWFya2VyIOWNiuW+hCAqL1xuICAgIGxlZ2VuZExpbmVNYXJrZXJTaXplOiA1LFxuICAgIC8qKiDlm77kvovpobnmlofmnKzpopzoibIgKi9cbiAgICBsZWdlbmRJdGVtTmFtZUZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzY1XSxcbiAgICAvKiog5Zu+5L6L6aG55paH5pys5a2X5L2T5aSn5bCPICovXG4gICAgbGVnZW5kSXRlbU5hbWVGb250U2l6ZTogMTIsXG4gICAgLyoqIOWbvuS+i+mhueaWh+acrOihjOmrmCAqL1xuICAgIGxlZ2VuZEl0ZW1OYW1lTGluZUhlaWdodDogMTIsXG4gICAgLyoqIOWbvuS+i+mhueeyl+e7hiAqL1xuICAgIGxlZ2VuZEl0ZW1OYW1lRm9udFdlaWdodDogJ25vcm1hbCcsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+Whq+WFheiJsiAqL1xuICAgIHNsaWRlclJhaWxGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1sxNV0sXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+i+ueahhueyl+e7hiAqL1xuICAgIHNsaWRlclJhaWxCb3JkZXI6IDAsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+i+ueahhuminOiJsiAqL1xuICAgIHNsaWRlclJhaWxCb3JkZXJDb2xvcjogbnVsbCxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X5a695bqmICovXG4gICAgc2xpZGVyUmFpbFdpZHRoOiAxMDAsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+mrmOW6piAqL1xuICAgIHNsaWRlclJhaWxIZWlnaHQ6IDEyLFxuICAgIC8qKiDov57nu63lm77kvovmlofmnKzpopzoibIgKi9cbiAgICBzbGlkZXJMYWJlbFRleHRGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s0NV0sXG4gICAgLyoqIOi/nue7reWbvuS+i+aWh+acrOWtl+S9k+Wkp+WwjyAqL1xuICAgIHNsaWRlckxhYmVsVGV4dEZvbnRTaXplOiAxMixcbiAgICAvKiog6L+e57ut5Zu+5L6L5paH5pys6KGM6auYICovXG4gICAgc2xpZGVyTGFiZWxUZXh0TGluZUhlaWdodDogMTIsXG4gICAgLyoqIOi/nue7reWbvuS+i+aWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIHNsaWRlckxhYmVsVGV4dEZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIC8qKiDov57nu63lm77kvovmu5HlnZfpopzoibIgKi9cbiAgICBzbGlkZXJIYW5kbGVyRmlsbENvbG9yOiBXSElURV9DT0xPUlNbNl0sXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+WuveW6piAqL1xuICAgIHNsaWRlckhhbmRsZXJXaWR0aDogMTAsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+mrmOW6piAqL1xuICAgIHNsaWRlckhhbmRsZXJIZWlnaHQ6IDE0LFxuICAgIC8qKiDov57nu63lm77kvovmu5HlnZfovrnmoYbnspfnu4YgKi9cbiAgICBzbGlkZXJIYW5kbGVyQm9yZGVyOiAxLFxuICAgIC8qKiDov57nu63lm77kvovmu5HlnZfovrnmoYbpopzoibIgKi9cbiAgICBzbGlkZXJIYW5kbGVyQm9yZGVyQ29sb3I6IFdISVRFX0NPTE9SU1syNV0sXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0gQW5ub3RhdGlvbu+8jOWbvuW9ouagh+azqCAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKiBhcmMg5Zu+5b2i5qCH5rOo5o+P6L656aKc6ImyICovXG4gICAgYW5ub3RhdGlvbkFyY0JvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTVdLFxuICAgIC8qKiBhcmMg5Zu+5b2i5qCH5rOo57KX57uGICovXG4gICAgYW5ub3RhdGlvbkFyY0JvcmRlcjogMC41LFxuICAgIC8qKiBsaW5lIOWbvuW9ouagh+azqOminOiJsiAqL1xuICAgIGFubm90YXRpb25MaW5lQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1syNV0sXG4gICAgLyoqIGxpbmUg5Zu+5b2i5qCH5rOo57KX57uGICovXG4gICAgYW5ub3RhdGlvbkxpbmVCb3JkZXI6IDAuNSxcbiAgICAvKiogbHViZSDlm77lvaLmoIfms6jnmoTomZrnur/pl7TpmpQgKi9cbiAgICBhbm5vdGF0aW9uTGluZURhc2g6IG51bGwsXG4gICAgLyoqIHRleHQg5Zu+5b2i5qCH5rOo5paH5pys6aKc6ImyICovXG4gICAgYW5ub3RhdGlvblRleHRGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s2NV0sXG4gICAgLyoqIHRleHQg5Zu+5b2i5qCH5rOo5paH5pys5a2X5L2T5aSn5bCPICovXG4gICAgYW5ub3RhdGlvblRleHRGb250U2l6ZTogMTIsXG4gICAgLyoqIHRleHQg5Zu+5b2i5qCH5rOo5paH5pys6KGM6auYICovXG4gICAgYW5ub3RhdGlvblRleHRMaW5lSGVpZ2h0OiAxMixcbiAgICAvKiogdGV4dCDlm77lvaLmoIfms6jmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICBhbm5vdGF0aW9uVGV4dEZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIC8qKiB0ZXh0IOWbvuW9ouagh+azqOaWh+acrOi+ueahhuminOiJsiAqL1xuICAgIGFubm90YXRpb25UZXh0Qm9yZGVyQ29sb3I6IFdISVRFX0NPTE9SU1s5NV0sXG4gICAgLyoqIHRleHQg5Zu+5b2i5qCH5rOo5paH5pys6L655qGG57KX57uGICovXG4gICAgYW5ub3RhdGlvblRleHRCb3JkZXI6IDEuNSxcbiAgICAvKiogcmVnaW9uIOWbvuW9ouagh+azqOWhq+WFheminOiJsiAqL1xuICAgIGFubm90YXRpb25SZWdpb25GaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiByZWdpb24g5Zu+5b2i5qCH5rOo5aGr5YWF6aKc6Imy6YCP5piO6ImyICovXG4gICAgYW5ub3RhdGlvblJlZ2lvbkZpbGxPcGFjaXR5OiAwLjA2LFxuICAgIC8qKiByZWdpb24g5Zu+5b2i5qCH5rOo5o+P6L6557KX57uGICovXG4gICAgYW5ub3RhdGlvblJlZ2lvbkJvcmRlcjogMCxcbiAgICAvKiogcmVnaW9uIOWbvuW9ouagh+azqOaPj+i+ueminOiJsiAqL1xuICAgIGFubm90YXRpb25SZWdpb25Cb3JkZXJDb2xvcjogbnVsbCxcbiAgICAvKiogZGF0YU1hcmtlciDlm77lvaLmoIfms6jnur/nmoTplb/luqYgKi9cbiAgICBhbm5vdGF0aW9uRGF0YU1hcmtlckxpbmVMZW5ndGg6IDE2LFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tIFRvb2x0aXAgLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKiogdG9vbHRpcCBjcm9zc2hhaXJzIOi+heWKqee6v+minOiJsiAqL1xuICAgIHRvb2x0aXBDcm9zc2hhaXJzQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1syNV0sXG4gICAgLyoqIHRvb2x0aXAgY3Jvc3NoYWlycyDovoXliqnnur/nspfnu4YgKi9cbiAgICB0b29sdGlwQ3Jvc3NoYWlyc0JvcmRlcjogMC41LFxuICAgIC8qKiB0b29sdGlwIGNyb3NzaGFpcnMg6L6F5Yqp57q/6Jma57q/6Ze06ZqUICovXG4gICAgdG9vbHRpcENyb3NzaGFpcnNMaW5lRGFzaDogbnVsbCxcbiAgICAvKiogdG9vbHRpcCDlhoXlrrnmoYbog4zmma/oibIgKi9cbiAgICB0b29sdGlwQ29udGFpbmVyRmlsbENvbG9yOiAnIzFmMWYxZicsXG4gICAgdG9vbHRpcENvbnRhaW5lckZpbGxPcGFjaXR5OiAwLjk1LFxuICAgIC8qKiB0b29sdGlwIOWGheWuueahhumYtOW9sSAqL1xuICAgIHRvb2x0aXBDb250YWluZXJTaGFkb3c6ICcwcHggMnB4IDRweCByZ2JhKDAsMCwwLC41KScsXG4gICAgLyoqIHRvb2x0aXAg5YaF5a655qGG5ZyG6KeSICovXG4gICAgdG9vbHRpcENvbnRhaW5lckJvcmRlclJhZGl1czogMyxcbiAgICAvKiogdG9vbHRpcCDmlofmnKzpopzoibIgKi9cbiAgICB0b29sdGlwVGV4dEZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzY1XSxcbiAgICAvKiogdG9vbHRpcCDmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICB0b29sdGlwVGV4dEZvbnRTaXplOiAxMixcbiAgICAvKiogdG9vbHRpcCDmlofmnKzooYzpq5ggKi9cbiAgICB0b29sdGlwVGV4dExpbmVIZWlnaHQ6IDEyLFxuICAgIC8qKiB0b29sdGlwIOaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIHRvb2x0aXBUZXh0Rm9udFdlaWdodDogJ2JvbGQnLFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tIEdlb21ldHJ5IGxhYmVscyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKiBHZW9tZXRyeSBsYWJlbCDmlofmnKzpopzoibIgKi9cbiAgICBsYWJlbEZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzY1XSxcbiAgICAvKiogR2VvbWV0cnkgbGFiZWwg5paH5pys5a2X5L2T5aSn5bCPICovXG4gICAgbGFiZWxGb250U2l6ZTogMTIsXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVsIOaWh+acrOihjOmrmCAqL1xuICAgIGxhYmVsTGluZUhlaWdodDogMTIsXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVsIOaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIGxhYmVsRm9udFdlaWdodDogJ25vcm1hbCcsXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVsIOaWh+acrOaPj+i+ueminOiJsiAqL1xuICAgIGxhYmVsQm9yZGVyQ29sb3I6IG51bGwsXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVsIOaWh+acrOaPj+i+ueeyl+e7hiAqL1xuICAgIGxhYmVsQm9yZGVyOiAwLFxuICAgIC8qKiBHZW9tZXRyeSBpbm5lckxhYmVsIOaWh+acrOminOiJsiAqL1xuICAgIGlubmVyTGFiZWxGaWxsQ29sb3I6IFdISVRFX0NPTE9SU1sxMDBdLFxuICAgIC8qKiBHZW9tZXRyeSBpbm5lckxhYmVsIOaWh+acrOWtl+S9k+Wkp+WwjyAqL1xuICAgIGlubmVyTGFiZWxGb250U2l6ZTogMTIsXG4gICAgLyoqIEdlb21ldHJ5IGlubmVyTGFiZWwg5paH5pys6KGM6auYICovXG4gICAgaW5uZXJMYWJlbExpbmVIZWlnaHQ6IDEyLFxuICAgIC8qKiBHZW9tZXRyeSBpbm5lckxhYmVsIOaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIGlubmVyTGFiZWxGb250V2VpZ2h0OiAnbm9ybWFsJyxcbiAgICAvKiogR2VvbWV0cnkgaW5uZXJMYWJlbCDmlofmnKzmj4/ovrnpopzoibIgKi9cbiAgICBpbm5lckxhYmVsQm9yZGVyQ29sb3I6IG51bGwsXG4gICAgLyoqIEdlb21ldHJ5IGlubmVyTGFiZWwg5paH5pys5o+P6L6557KX57uGICovXG4gICAgaW5uZXJMYWJlbEJvcmRlcjogMCxcbiAgICAvKiogR2VvbWV0cnkgbGFiZWzjgIDmlofmnKzov57mjqXnur/nspfnu4YgKi9cbiAgICBsYWJlbExpbmVCb3JkZXI6IDAuNSxcbiAgICAvKiogR2VvbWV0cnkgbGFiZWwg5paH5pys6L+e5o6l57q/6aKc6ImyICovXG4gICAgbGFiZWxMaW5lQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1syNV0sXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2VvbWV0cnkg5Zu+5b2i5qC35byPLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKiog54K55Zu+5aGr5YWF6aKc6ImyICovXG4gICAgcG9pbnRGaWxsQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiDngrnlm77loavlhYXpopzoibLpgI/mmI7luqYgKi9cbiAgICBwb2ludEZpbGxPcGFjaXR5OiAwLjk1LFxuICAgIC8qKiDngrnlm77lpKflsI8gKi9cbiAgICBwb2ludFNpemU6IDQsXG4gICAgLyoqIOeCueWbvuaPj+i+ueeyl+e7hiAqL1xuICAgIHBvaW50Qm9yZGVyOiAxLFxuICAgIC8qKiDngrnlm77mj4/ovrnpopzoibIgKi9cbiAgICBwb2ludEJvcmRlckNvbG9yOiBXSElURV9DT0xPUlNbMTAwXSxcbiAgICAvKiog54K55Zu+5o+P6L656YCP5piO5bqmICovXG4gICAgcG9pbnRCb3JkZXJPcGFjaXR5OiAxLFxuICAgIC8qKiDngrnlm74gYWN0aXZlIOeKtuaAgeS4i+aPj+i+ueminOiJsiAqL1xuICAgIHBvaW50QWN0aXZlQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiDngrnlm74gc2VsZWN0ZWQg54q25oCB5LiL5o+P6L6557KX57uGICovXG4gICAgcG9pbnRTZWxlY3RlZEJvcmRlcjogMixcbiAgICAvKiog54K55Zu+IHNlbGVjdGVkIOeKtuaAgeS4i+aPj+i+ueminOiJsiAqL1xuICAgIHBvaW50U2VsZWN0ZWRCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgLyoqIOeCueWbviBpbmFjdGl2ZSDnirbmgIHkuIvloavlhYXpopzoibLpgI/mmI7luqYgKi9cbiAgICBwb2ludEluYWN0aXZlRmlsbE9wYWNpdHk6IDAuMyxcbiAgICAvKiog54K55Zu+IGluYWN0aXZlIOeKtuaAgeS4i+aPj+i+uemAj+aYjuW6piAqL1xuICAgIHBvaW50SW5hY3RpdmVCb3JkZXJPcGFjaXR5OiAwLjMsXG4gICAgLyoqIOepuuW/g+eCueWbvuWkp+WwjyAqL1xuICAgIGhvbGxvd1BvaW50U2l6ZTogNCxcbiAgICAvKiog56m65b+D54K55Zu+5o+P6L6557KX57uGICovXG4gICAgaG9sbG93UG9pbnRCb3JkZXI6IDEsXG4gICAgLyoqIOepuuW/g+eCueWbvuaPj+i+ueminOiJsiAqL1xuICAgIGhvbGxvd1BvaW50Qm9yZGVyQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiDnqbrlv4Pngrnlm77mj4/ovrnpgI/mmI7luqYgKi9cbiAgICBob2xsb3dQb2ludEJvcmRlck9wYWNpdHk6IDAuOTUsXG4gICAgaG9sbG93UG9pbnRGaWxsQ29sb3I6IFdISVRFX0NPTE9SU1sxMDBdLFxuICAgIC8qKiDnqbrlv4Pngrnlm74gYWN0aXZlIOeKtuaAgeS4i+aPj+i+ueeyl+e7hiAqL1xuICAgIGhvbGxvd1BvaW50QWN0aXZlQm9yZGVyOiAxLFxuICAgIC8qKiDnqbrlv4Pngrnlm74gYWN0aXZlIOeKtuaAgeS4i+aPj+i+ueminOiJsiAqL1xuICAgIGhvbGxvd1BvaW50QWN0aXZlQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiDnqbrlv4Pngrnlm74gYWN0aXZlIOeKtuaAgeS4i+aPj+i+uemAj+aYjuW6piAqL1xuICAgIGhvbGxvd1BvaW50QWN0aXZlQm9yZGVyT3BhY2l0eTogMSxcbiAgICAvKiog56m65b+D54K55Zu+IHNlbGVjdGVkIOeKtuaAgeS4i+aPj+i+ueeyl+e7hiAqL1xuICAgIGhvbGxvd1BvaW50U2VsZWN0ZWRCb3JkZXI6IDIsXG4gICAgLyoqIOepuuW/g+eCueWbviBzZWxlY3RlZCDnirbmgIHkuIvmj4/ovrnpopzoibIgKi9cbiAgICBob2xsb3dQb2ludFNlbGVjdGVkQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiDnqbrlv4Pngrnlm74gc2VsZWN0ZWQg54q25oCB5LiL5o+P6L656YCP5piO5bqmICovXG4gICAgaG9sbG93UG9pbnRTZWxlY3RlZEJvcmRlck9wYWNpdHk6IDEsXG4gICAgLyoqIOepuuW/g+eCueWbviBpbmFjdGl2ZSDnirbmgIHkuIvmj4/ovrnpgI/mmI7luqYgKi9cbiAgICBob2xsb3dQb2ludEluYWN0aXZlQm9yZGVyT3BhY2l0eTogMC4zLFxuICAgIC8qKiDnur/lm77nspfnu4YgKi9cbiAgICBsaW5lQm9yZGVyOiAyLFxuICAgIC8qKiDnur/lm77popzoibIgKi9cbiAgICBsaW5lQm9yZGVyQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiDnur/lm77pgI/mmI7luqYgKi9cbiAgICBsaW5lQm9yZGVyT3BhY2l0eTogMSxcbiAgICAvKiog57q/5Zu+IEFjdGl2ZSDnirbmgIHkuIvnspfnu4YgKi9cbiAgICBsaW5lQWN0aXZlQm9yZGVyOiAzLFxuICAgIC8qKiDnur/lm74gc2VsZWN0ZWQg54q25oCB5LiL57KX57uGICovXG4gICAgbGluZVNlbGVjdGVkQm9yZGVyOiAzLFxuICAgIC8qKiDnur/lm74gaW5hY3RpdmUg54q25oCB5LiL6YCP5piO5bqmICovXG4gICAgbGluZUluYWN0aXZlQm9yZGVyT3BhY2l0eTogMC4zLFxuICAgIC8qKiBhcmVhIOWhq+WFheminOiJsiAqL1xuICAgIGFyZWFGaWxsQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiBhcmVhIOWhq+WFhemAj+aYjuW6piAqL1xuICAgIGFyZWFGaWxsT3BhY2l0eTogMC4yNSxcbiAgICAvKiogYXJlYSDlnKggYWN0aXZlIOeKtuaAgeS4i+eahOWhq+WFhemAj+aYjuW6piAqL1xuICAgIGFyZWFBY3RpdmVGaWxsQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIGFyZWFBY3RpdmVGaWxsT3BhY2l0eTogMC41LFxuICAgIC8qKiBhcmVhIOWcqCBzZWxlY3RlZCDnirbmgIHkuIvnmoTloavlhYXpgI/mmI7luqYgKi9cbiAgICBhcmVhU2VsZWN0ZWRGaWxsQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIGFyZWFTZWxlY3RlZEZpbGxPcGFjaXR5OiAwLjUsXG4gICAgLyoqIGFyZWEgaW5hY3RpdmUg54q25oCB5LiL5aGr5YWF6YCP5piO5bqmICovXG4gICAgYXJlYUluYWN0aXZlRmlsbE9wYWNpdHk6IDAuMyxcbiAgICAvKiogaG9sbG93QXJlYSDpopzoibIgKi9cbiAgICBob2xsb3dBcmVhQm9yZGVyQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiBob2xsb3dBcmVhIOi+ueahhueyl+e7hiAqL1xuICAgIGhvbGxvd0FyZWFCb3JkZXI6IDIsXG4gICAgLyoqIGhvbGxvd0FyZWEg6L655qGG6YCP5piO5bqmICovXG4gICAgaG9sbG93QXJlYUJvcmRlck9wYWNpdHk6IDEsXG4gICAgLyoqIGhvbGxvd0FyZWEgYWN0aXZlIOeKtuaAgeS4i+eahOi+ueahhueyl+e7hiAqL1xuICAgIGhvbGxvd0FyZWFBY3RpdmVCb3JkZXI6IDMsXG4gICAgaG9sbG93QXJlYUFjdGl2ZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiogaG9sbG93QXJlYSBzZWxlY3RlZCDnirbmgIHkuIvnmoTovrnmoYbnspfnu4YgKi9cbiAgICBob2xsb3dBcmVhU2VsZWN0ZWRCb3JkZXI6IDMsXG4gICAgaG9sbG93QXJlYVNlbGVjdGVkQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiBob2xsb3dBcmVhIGluYWN0aXZlIOeKtuaAgeS4i+eahOi+ueahhumAj+aYjuW6piAqL1xuICAgIGhvbGxvd0FyZWFJbmFjdGl2ZUJvcmRlck9wYWNpdHk6IDAuMyxcbiAgICAvKiogaW50ZXJ2YWwg5aGr5YWF6aKc6ImyICovXG4gICAgaW50ZXJ2YWxGaWxsQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiBpbnRlcnZhbCDloavlhYXpgI/mmI7luqYgKi9cbiAgICBpbnRlcnZhbEZpbGxPcGFjaXR5OiAwLjk1LFxuICAgIC8qKiBpbnRlcnZhbCBhY3RpdmUg54q25oCB5LiL6L655qGG57KX57uGICovXG4gICAgaW50ZXJ2YWxBY3RpdmVCb3JkZXI6IDEsXG4gICAgLyoqIGludGVydmFsIGFjdGl2ZSDnirbmgIHkuIvovrnmoYbpopzoibIgKi9cbiAgICBpbnRlcnZhbEFjdGl2ZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICBpbnRlcnZhbEFjdGl2ZUJvcmRlck9wYWNpdHk6IDEsXG4gICAgLyoqIGludGVydmFsIHNlbGVjdGVkIOeKtuaAgeS4i+i+ueahhueyl+e7hiAqL1xuICAgIGludGVydmFsU2VsZWN0ZWRCb3JkZXI6IDIsXG4gICAgLyoqIGludGVydmFsIHNlbGVjdGVkIOeKtuaAgeS4i+i+ueahhuminOiJsiAqL1xuICAgIGludGVydmFsU2VsZWN0ZWRCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgLyoqIGludGVydmFsIHNlbGVjdGVkIOeKtuaAgeS4i+i+ueahhumAj+aYjuW6piAqL1xuICAgIGludGVydmFsU2VsZWN0ZWRCb3JkZXJPcGFjaXR5OiAxLFxuICAgIC8qKiBpbnRlcnZhbCBpbmFjdGl2ZSDnirbmgIHkuIvovrnmoYbpgI/mmI7luqYgKi9cbiAgICBpbnRlcnZhbEluYWN0aXZlQm9yZGVyT3BhY2l0eTogMC4zLFxuICAgIC8qKiBpbnRlcnZhbCBpbmFjdGl2ZSDnirbmgIHkuIvloavlhYXpgI/mmI7luqYgKi9cbiAgICBpbnRlcnZhbEluYWN0aXZlRmlsbE9wYWNpdHk6IDAuMyxcbiAgICAvKiogaW50ZXJ2YWwg6L655qGG57KX57uGICovXG4gICAgaG9sbG93SW50ZXJ2YWxCb3JkZXI6IDIsXG4gICAgLyoqIGhvbGxvd0ludGVydmFsIOi+ueahhuminOiJsiAqL1xuICAgIGhvbGxvd0ludGVydmFsQm9yZGVyQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiBob2xsb3dJbnRlcnZhbCDovrnmoYbpgI/mmI7luqYgKi9cbiAgICBob2xsb3dJbnRlcnZhbEJvcmRlck9wYWNpdHk6IDEsXG4gICAgaG9sbG93SW50ZXJ2YWxGaWxsQ29sb3I6IFdISVRFX0NPTE9SU1sxMDBdLFxuICAgIC8qKiBob2xsb3dJbnRlcnZhbCBhY3RpdmUg54q25oCB5LiL6L655qGG57KX57uGICovXG4gICAgaG9sbG93SW50ZXJ2YWxBY3RpdmVCb3JkZXI6IDIsXG4gICAgLyoqIGhvbGxvd0ludGVydmFsIGFjdGl2ZSDnirbmgIHkuIvovrnmoYbpopzoibIgKi9cbiAgICBob2xsb3dJbnRlcnZhbEFjdGl2ZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiogaG9sbG93SW50ZXJ2YWwgc2VsZWN0ZWQg54q25oCB5LiL6L655qGG57KX57uGICovXG4gICAgaG9sbG93SW50ZXJ2YWxTZWxlY3RlZEJvcmRlcjogMyxcbiAgICAvKiogaG9sbG93SW50ZXJ2YWwgc2VsZWN0ZWQg54q25oCB5LiL6L655qGG6aKc6ImyICovXG4gICAgaG9sbG93SW50ZXJ2YWxTZWxlY3RlZEJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiogaG9sbG93SW50ZXJ2YWwgc2VsZWN0ZWQg54q25oCB5LiL6L655qGG6YCP5piO5bqmICovXG4gICAgaG9sbG93SW50ZXJ2YWxTZWxlY3RlZEJvcmRlck9wYWNpdHk6IDEsXG4gICAgLyoqIGhvbGxvd0ludGVydmFsIGluYWN0aXZlIOeKtuaAgeS4i+i+ueahhumAj+aYjuW6piAqL1xuICAgIGhvbGxvd0ludGVydmFsSW5hY3RpdmVCb3JkZXJPcGFjaXR5OiAwLjMsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGFyay5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuYW50dkxpZ2h0ID0gdm9pZCAwO1xudmFyIEJMQUNLX0NPTE9SUyA9IHtcbiAgICAxMDA6ICcjMDAwJyxcbiAgICA5NTogJyMwRDBEMEQnLFxuICAgIDg1OiAnIzI2MjYyNicsXG4gICAgNjU6ICcjNTk1OTU5JyxcbiAgICA0NTogJyM4QzhDOEMnLFxuICAgIDI1OiAnI0JGQkZCRicsXG4gICAgMTU6ICcjRDlEOUQ5JyxcbiAgICA2OiAnI0YwRjBGMCcsXG59O1xudmFyIFdISVRFX0NPTE9SUyA9IHtcbiAgICAxMDA6ICcjRkZGRkZGJyxcbiAgICA5NTogJyNGMkYyRjInLFxuICAgIDg1OiAnI0Q5RDlEOScsXG4gICAgNjU6ICcjQTZBNkE2JyxcbiAgICA0NTogJyM3MzczNzMnLFxuICAgIDI1OiAnIzQwNDA0MCcsXG4gICAgMTU6ICcjMjYyNjI2JyxcbiAgICA2OiAnIzBGMEYwRicsXG59O1xudmFyIFFVQUxJVEFUSVZFXzEwID0gW1xuICAgICcjNUI4RkY5JyxcbiAgICAnIzVBRDhBNicsXG4gICAgJyM1RDcwOTInLFxuICAgICcjRjZCRDE2JyxcbiAgICAnI0U4NjQ1MicsXG4gICAgJyM2REM4RUMnLFxuICAgICcjOTQ1RkI5JyxcbiAgICAnI0ZGOTg0NScsXG4gICAgJyMxRTk0OTMnLFxuICAgICcjRkY5OUMzJyxcbl07XG52YXIgUVVBTElUQVRJVkVfMjAgPSBbXG4gICAgJyM1QjhGRjknLFxuICAgICcjQ0REREZEJyxcbiAgICAnIzVBRDhBNicsXG4gICAgJyNDREYzRTQnLFxuICAgICcjNUQ3MDkyJyxcbiAgICAnI0NFRDRERScsXG4gICAgJyNGNkJEMTYnLFxuICAgICcjRkNFQkI5JyxcbiAgICAnI0U4NjQ1MicsXG4gICAgJyNGOEQwQ0InLFxuICAgICcjNkRDOEVDJyxcbiAgICAnI0QzRUVGOScsXG4gICAgJyM5NDVGQjknLFxuICAgICcjREVDRkVBJyxcbiAgICAnI0ZGOTg0NScsXG4gICAgJyNGRkUwQzcnLFxuICAgICcjMUU5NDkzJyxcbiAgICAnI0JCREVERScsXG4gICAgJyNGRjk5QzMnLFxuICAgICcjRkZFMEVEJyxcbl07XG5leHBvcnRzLmFudHZMaWdodCA9IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgLyoqIOS4u+mimOiJsiAqL1xuICAgIGJyYW5kQ29sb3I6IFFVQUxJVEFUSVZFXzEwWzBdLFxuICAgIC8qKiDliIbnsbvoibLmnb8gMe+8jOWcqOaVsOaNrumHj+Wwj+S6juetieS6jiAxMCDml7bkvb/nlKggKi9cbiAgICBwYWxldHRlUXVhbGl0YXRpdmUxMDogUVVBTElUQVRJVkVfMTAsXG4gICAgLyoqIOWIhuexu+iJsuadvyAy77yM5Zyo5pWw5o2u6YeP5aSn5LqOIDEwIOaXtuS9v+eUqCAqL1xuICAgIHBhbGV0dGVRdWFsaXRhdGl2ZTIwOiBRVUFMSVRBVElWRV8yMCxcbiAgICAvKiog6K+t5LmJ6ImyICovXG4gICAgcGFsZXR0ZVNlbWFudGljUmVkOiAnI0Y0NjY0QScsXG4gICAgLyoqIOivreS5ieiJsiAqL1xuICAgIHBhbGV0dGVTZW1hbnRpY0dyZWVuOiAnIzMwQkY3OCcsXG4gICAgLyoqIOivreS5ieiJsiAqL1xuICAgIHBhbGV0dGVTZW1hbnRpY1llbGxvdzogJyNGQUFEMTQnLFxuICAgIC8qKiDlrZfkvZMgKi9cbiAgICBmb250RmFtaWx5OiBcIlxcXCItYXBwbGUtc3lzdGVtXFxcIiwgXFxcIlNlZ29lIFVJXFxcIiwgUm9ib3RvLCBcXFwiSGVsdmV0aWNhIE5ldWVcXFwiLCBBcmlhbCxcXG4gIFxcXCJOb3RvIFNhbnNcXFwiLCBzYW5zLXNlcmlmLCBcXFwiQXBwbGUgQ29sb3IgRW1vamlcXFwiLCBcXFwiU2Vnb2UgVUkgRW1vamlcXFwiLCBcXFwiU2Vnb2UgVUkgU3ltYm9sXFxcIixcXG4gIFxcXCJOb3RvIENvbG9yIEVtb2ppXFxcIlwiLFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tIOWdkOagh+i9tCAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKiDlnZDmoIfovbTnur/popzoibIgKi9cbiAgICBheGlzTGluZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMjVdLFxuICAgIC8qKiDlnZDmoIfovbTnur/nspfnu4YgKi9cbiAgICBheGlzTGluZUJvcmRlcjogMC41LFxuICAgIC8qKiDlnZDmoIfovbTnur8gbGluZURhc2gg6K6+572uICovXG4gICAgYXhpc0xpbmVEYXNoOiBudWxsLFxuICAgIC8qKiDlnZDmoIfovbTmoIfpopjpopzoibIgKi9cbiAgICBheGlzVGl0bGVUZXh0RmlsbENvbG9yOiBCTEFDS19DT0xPUlNbNjVdLFxuICAgIC8qKiDlnZDmoIfovbTmoIfpopjmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICBheGlzVGl0bGVUZXh0Rm9udFNpemU6IDEyLFxuICAgIC8qKiDlnZDmoIfovbTmoIfpopjmlofmnKzooYzpq5ggKi9cbiAgICBheGlzVGl0bGVUZXh0TGluZUhlaWdodDogMTIsXG4gICAgLyoqIOWdkOagh+i9tOagh+mimOaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIGF4aXNUaXRsZVRleHRGb250V2VpZ2h0OiAnbm9ybWFsJyxcbiAgICAvKiog5Z2Q5qCH6L205Yi75bqm57q/6aKc6ImyICovXG4gICAgYXhpc1RpY2tMaW5lQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1syNV0sXG4gICAgLyoqIOWdkOagh+i9tOWIu+W6pue6v+mVv+W6piAqL1xuICAgIGF4aXNUaWNrTGluZUxlbmd0aDogNCxcbiAgICAvKiog5Z2Q5qCH6L205Yi75bqm57q/57KX57uGICovXG4gICAgYXhpc1RpY2tMaW5lQm9yZGVyOiAwLjUsXG4gICAgLyoqIOWdkOagh+i9tOasoeWIu+W6pue6v+minOiJsiAqL1xuICAgIGF4aXNTdWJUaWNrTGluZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTVdLFxuICAgIC8qKiDlnZDmoIfovbTmrKHliLvluqbnur/plb/luqYgKi9cbiAgICBheGlzU3ViVGlja0xpbmVMZW5ndGg6IDIsXG4gICAgLyoqIOWdkOagh+i9tOasoeWIu+W6pue6v+eyl+e7hiAqL1xuICAgIGF4aXNTdWJUaWNrTGluZUJvcmRlcjogMC41LFxuICAgIC8qKiDlnZDmoIfovbTliLvluqbmlofmnKzpopzoibIgKi9cbiAgICBheGlzTGFiZWxGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s0NV0sXG4gICAgLyoqIOWdkOagh+i9tOWIu+W6puaWh+acrOWtl+S9k+Wkp+WwjyAqL1xuICAgIGF4aXNMYWJlbEZvbnRTaXplOiAxMixcbiAgICAvKiog5Z2Q5qCH6L205Yi75bqm5paH5pys6KGM6auYICovXG4gICAgYXhpc0xhYmVsTGluZUhlaWdodDogMTIsXG4gICAgLyoqIOWdkOagh+i9tOWIu+W6puaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIGF4aXNMYWJlbEZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIC8qKiDlnZDmoIfovbTnvZHmoLznur/popzoibIgKi9cbiAgICBheGlzR3JpZEJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTVdLFxuICAgIC8qKiDlnZDmoIfovbTnvZHmoLznur/nspfnu4YgKi9cbiAgICBheGlzR3JpZEJvcmRlcjogMC41LFxuICAgIC8qKiDlnZDmoIfovbTnvZHmoLznur/omZrnur/orr7nva4gKi9cbiAgICBheGlzR3JpZExpbmVEYXNoOiBudWxsLFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tIOWbvuS+iyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKiDlm77kvovmoIfpopjpopzoibIgKi9cbiAgICBsZWdlbmRUaXRsZVRleHRGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s0NV0sXG4gICAgLyoqIOWbvuS+i+agh+mimOaWh+acrOWtl+S9k+Wkp+WwjyAqL1xuICAgIGxlZ2VuZFRpdGxlVGV4dEZvbnRTaXplOiAxMixcbiAgICAvKiog5Zu+5L6L5qCH6aKY5paH5pys6KGM6auYICovXG4gICAgbGVnZW5kVGl0bGVUZXh0TGluZUhlaWdodDogMjEsXG4gICAgLyoqIOWbvuS+i+agh+mimOaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIGxlZ2VuZFRpdGxlVGV4dEZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIC8qKiDlm77kvosgbWFya2VyIOminOiJsiAqL1xuICAgIGxlZ2VuZE1hcmtlckNvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiog5Zu+5L6LIG1hcmtlciDpu5jorqTljYrlvoTlpKflsI8gKi9cbiAgICBsZWdlbmRNYXJrZXJTaXplOiA0LFxuICAgIC8qKiDlm77kvosgJ2NpcmNsZScgbWFya2VyIOWNiuW+hCAqL1xuICAgIGxlZ2VuZENpcmNsZU1hcmtlclNpemU6IDQsXG4gICAgLyoqIOWbvuS+iyAnc3F1YXJlJyBtYXJrZXIg5Y2K5b6EICovXG4gICAgbGVnZW5kU3F1YXJlTWFya2VyU2l6ZTogNCxcbiAgICAvKiog5Zu+5L6LICdsaW5lJyBtYXJrZXIg5Y2K5b6EICovXG4gICAgbGVnZW5kTGluZU1hcmtlclNpemU6IDUsXG4gICAgLyoqIOWbvuS+i+mhueaWh+acrOminOiJsiAqL1xuICAgIGxlZ2VuZEl0ZW1OYW1lRmlsbENvbG9yOiBCTEFDS19DT0xPUlNbNjVdLFxuICAgIC8qKiDlm77kvovpobnmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICBsZWdlbmRJdGVtTmFtZUZvbnRTaXplOiAxMixcbiAgICAvKiog5Zu+5L6L6aG55paH5pys6KGM6auYICovXG4gICAgbGVnZW5kSXRlbU5hbWVMaW5lSGVpZ2h0OiAxMixcbiAgICAvKiog5Zu+5L6L6aG557KX57uGICovXG4gICAgbGVnZW5kSXRlbU5hbWVGb250V2VpZ2h0OiAnbm9ybWFsJyxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X5aGr5YWF6ImyICovXG4gICAgc2xpZGVyUmFpbEZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzE1XSxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X6L655qGG57KX57uGICovXG4gICAgc2xpZGVyUmFpbEJvcmRlcjogMCxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X6L655qGG6aKc6ImyICovXG4gICAgc2xpZGVyUmFpbEJvcmRlckNvbG9yOiBudWxsLFxuICAgIC8qKiDov57nu63lm77kvovmu5HlnZflrr3luqYgKi9cbiAgICBzbGlkZXJSYWlsV2lkdGg6IDEwMCxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X6auY5bqmICovXG4gICAgc2xpZGVyUmFpbEhlaWdodDogMTIsXG4gICAgLyoqIOi/nue7reWbvuS+i+aWh+acrOminOiJsiAqL1xuICAgIHNsaWRlckxhYmVsVGV4dEZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzQ1XSxcbiAgICAvKiog6L+e57ut5Zu+5L6L5paH5pys5a2X5L2T5aSn5bCPICovXG4gICAgc2xpZGVyTGFiZWxUZXh0Rm9udFNpemU6IDEyLFxuICAgIC8qKiDov57nu63lm77kvovmlofmnKzooYzpq5ggKi9cbiAgICBzbGlkZXJMYWJlbFRleHRMaW5lSGVpZ2h0OiAxMixcbiAgICAvKiog6L+e57ut5Zu+5L6L5paH5pys5a2X5L2T57KX57uGICovXG4gICAgc2xpZGVyTGFiZWxUZXh0Rm9udFdlaWdodDogJ25vcm1hbCcsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+minOiJsiAqL1xuICAgIHNsaWRlckhhbmRsZXJGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s2XSxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X5a695bqmICovXG4gICAgc2xpZGVySGFuZGxlcldpZHRoOiAxMCxcbiAgICAvKiog6L+e57ut5Zu+5L6L5ruR5Z2X6auY5bqmICovXG4gICAgc2xpZGVySGFuZGxlckhlaWdodDogMTQsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+i+ueahhueyl+e7hiAqL1xuICAgIHNsaWRlckhhbmRsZXJCb3JkZXI6IDEsXG4gICAgLyoqIOi/nue7reWbvuS+i+a7keWdl+i+ueahhuminOiJsiAqL1xuICAgIHNsaWRlckhhbmRsZXJCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzI1XSxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLSBBbm5vdGF0aW9u77yM5Zu+5b2i5qCH5rOoIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqIGFyYyDlm77lvaLmoIfms6jmj4/ovrnpopzoibIgKi9cbiAgICBhbm5vdGF0aW9uQXJjQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxNV0sXG4gICAgLyoqIGFyYyDlm77lvaLmoIfms6jnspfnu4YgKi9cbiAgICBhbm5vdGF0aW9uQXJjQm9yZGVyOiAwLjUsXG4gICAgLyoqIGxpbmUg5Zu+5b2i5qCH5rOo6aKc6ImyICovXG4gICAgYW5ub3RhdGlvbkxpbmVCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzI1XSxcbiAgICAvKiogbGluZSDlm77lvaLmoIfms6jnspfnu4YgKi9cbiAgICBhbm5vdGF0aW9uTGluZUJvcmRlcjogMC41LFxuICAgIC8qKiBsdWJlIOWbvuW9ouagh+azqOeahOiZmue6v+mXtOmalCAqL1xuICAgIGFubm90YXRpb25MaW5lRGFzaDogbnVsbCxcbiAgICAvKiogdGV4dCDlm77lvaLmoIfms6jmlofmnKzpopzoibIgKi9cbiAgICBhbm5vdGF0aW9uVGV4dEZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzY1XSxcbiAgICAvKiogdGV4dCDlm77lvaLmoIfms6jmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICBhbm5vdGF0aW9uVGV4dEZvbnRTaXplOiAxMixcbiAgICAvKiogdGV4dCDlm77lvaLmoIfms6jmlofmnKzooYzpq5ggKi9cbiAgICBhbm5vdGF0aW9uVGV4dExpbmVIZWlnaHQ6IDEyLFxuICAgIC8qKiB0ZXh0IOWbvuW9ouagh+azqOaWh+acrOWtl+S9k+eyl+e7hiAqL1xuICAgIGFubm90YXRpb25UZXh0Rm9udFdlaWdodDogJ25vcm1hbCcsXG4gICAgLyoqIHRleHQg5Zu+5b2i5qCH5rOo5paH5pys6L655qGG6aKc6ImyICovXG4gICAgYW5ub3RhdGlvblRleHRCb3JkZXJDb2xvcjogV0hJVEVfQ09MT1JTWzk1XSxcbiAgICAvKiogdGV4dCDlm77lvaLmoIfms6jmlofmnKzovrnmoYbnspfnu4YgKi9cbiAgICBhbm5vdGF0aW9uVGV4dEJvcmRlcjogMS41LFxuICAgIC8qKiByZWdpb24g5Zu+5b2i5qCH5rOo5aGr5YWF6aKc6ImyICovXG4gICAgYW5ub3RhdGlvblJlZ2lvbkZpbGxDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgLyoqIHJlZ2lvbiDlm77lvaLmoIfms6jloavlhYXpopzoibLpgI/mmI7oibIgKi9cbiAgICBhbm5vdGF0aW9uUmVnaW9uRmlsbE9wYWNpdHk6IDAuMDYsXG4gICAgLyoqIHJlZ2lvbiDlm77lvaLmoIfms6jmj4/ovrnnspfnu4YgKi9cbiAgICBhbm5vdGF0aW9uUmVnaW9uQm9yZGVyOiAwLFxuICAgIC8qKiByZWdpb24g5Zu+5b2i5qCH5rOo5o+P6L656aKc6ImyICovXG4gICAgYW5ub3RhdGlvblJlZ2lvbkJvcmRlckNvbG9yOiBudWxsLFxuICAgIC8qKiBkYXRhTWFya2VyIOWbvuW9ouagh+azqOe6v+eahOmVv+W6piAqL1xuICAgIGFubm90YXRpb25EYXRhTWFya2VyTGluZUxlbmd0aDogMTYsXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG9vbHRpcCAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKiB0b29sdGlwIGNyb3NzaGFpcnMg6L6F5Yqp57q/6aKc6ImyICovXG4gICAgdG9vbHRpcENyb3NzaGFpcnNCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzI1XSxcbiAgICAvKiogdG9vbHRpcCBjcm9zc2hhaXJzIOi+heWKqee6v+eyl+e7hiAqL1xuICAgIHRvb2x0aXBDcm9zc2hhaXJzQm9yZGVyOiAwLjUsXG4gICAgLyoqIHRvb2x0aXAgY3Jvc3NoYWlycyDovoXliqnnur/omZrnur/pl7TpmpQgKi9cbiAgICB0b29sdGlwQ3Jvc3NoYWlyc0xpbmVEYXNoOiBudWxsLFxuICAgIC8qKiB0b29sdGlwIOWGheWuueahhuiDjOaZr+iJsiAqL1xuICAgIHRvb2x0aXBDb250YWluZXJGaWxsQ29sb3I6ICdyZ2IoMjU1LCAyNTUsIDI1NSknLFxuICAgIHRvb2x0aXBDb250YWluZXJGaWxsT3BhY2l0eTogMC45NSxcbiAgICAvKiogdG9vbHRpcCDlhoXlrrnmoYbpmLTlvbEgKi9cbiAgICB0b29sdGlwQ29udGFpbmVyU2hhZG93OiAnMHB4IDBweCAxMHB4ICNhZWFlYWUnLFxuICAgIC8qKiB0b29sdGlwIOWGheWuueahhuWchuinkiAqL1xuICAgIHRvb2x0aXBDb250YWluZXJCb3JkZXJSYWRpdXM6IDMsXG4gICAgLyoqIHRvb2x0aXAg5paH5pys6aKc6ImyICovXG4gICAgdG9vbHRpcFRleHRGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s2NV0sXG4gICAgLyoqIHRvb2x0aXAg5paH5pys5a2X5L2T5aSn5bCPICovXG4gICAgdG9vbHRpcFRleHRGb250U2l6ZTogMTIsXG4gICAgLyoqIHRvb2x0aXAg5paH5pys6KGM6auYICovXG4gICAgdG9vbHRpcFRleHRMaW5lSGVpZ2h0OiAxMixcbiAgICAvKiogdG9vbHRpcCDmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICB0b29sdGlwVGV4dEZvbnRXZWlnaHQ6ICdib2xkJyxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLSBHZW9tZXRyeSBsYWJlbHMgLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKiogR2VvbWV0cnkgbGFiZWwg5paH5pys6aKc6ImyICovXG4gICAgbGFiZWxGaWxsQ29sb3I6IEJMQUNLX0NPTE9SU1s2NV0sXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVsIOaWh+acrOWtl+S9k+Wkp+WwjyAqL1xuICAgIGxhYmVsRm9udFNpemU6IDEyLFxuICAgIC8qKiBHZW9tZXRyeSBsYWJlbCDmlofmnKzooYzpq5ggKi9cbiAgICBsYWJlbExpbmVIZWlnaHQ6IDEyLFxuICAgIC8qKiBHZW9tZXRyeSBsYWJlbCDmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICBsYWJlbEZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIC8qKiBHZW9tZXRyeSBsYWJlbCDmlofmnKzmj4/ovrnpopzoibIgKi9cbiAgICBsYWJlbEJvcmRlckNvbG9yOiBudWxsLFxuICAgIC8qKiBHZW9tZXRyeSBsYWJlbCDmlofmnKzmj4/ovrnnspfnu4YgKi9cbiAgICBsYWJlbEJvcmRlcjogMCxcbiAgICAvKiogR2VvbWV0cnkgaW5uZXJMYWJlbCDmlofmnKzpopzoibIgKi9cbiAgICBpbm5lckxhYmVsRmlsbENvbG9yOiBXSElURV9DT0xPUlNbMTAwXSxcbiAgICAvKiogR2VvbWV0cnkgaW5uZXJMYWJlbCDmlofmnKzlrZfkvZPlpKflsI8gKi9cbiAgICBpbm5lckxhYmVsRm9udFNpemU6IDEyLFxuICAgIC8qKiBHZW9tZXRyeSBpbm5lckxhYmVsIOaWh+acrOihjOmrmCAqL1xuICAgIGlubmVyTGFiZWxMaW5lSGVpZ2h0OiAxMixcbiAgICAvKiogR2VvbWV0cnkgaW5uZXJMYWJlbCDmlofmnKzlrZfkvZPnspfnu4YgKi9cbiAgICBpbm5lckxhYmVsRm9udFdlaWdodDogJ25vcm1hbCcsXG4gICAgLyoqIEdlb21ldHJ5IGlubmVyTGFiZWwg5paH5pys5o+P6L656aKc6ImyICovXG4gICAgaW5uZXJMYWJlbEJvcmRlckNvbG9yOiBudWxsLFxuICAgIC8qKiBHZW9tZXRyeSBpbm5lckxhYmVsIOaWh+acrOaPj+i+ueeyl+e7hiAqL1xuICAgIGlubmVyTGFiZWxCb3JkZXI6IDAsXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVs44CA5paH5pys6L+e5o6l57q/57KX57uGICovXG4gICAgbGFiZWxMaW5lQm9yZGVyOiAwLjUsXG4gICAgLyoqIEdlb21ldHJ5IGxhYmVsIOaWh+acrOi/nuaOpee6v+minOiJsiAqL1xuICAgIGxhYmVsTGluZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMjVdLFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tIEdlb21ldHJ5IOWbvuW9ouagt+W8jy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqIOeCueWbvuWhq+WFheminOiJsiAqL1xuICAgIHBvaW50RmlsbENvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiog54K55Zu+5aGr5YWF6aKc6Imy6YCP5piO5bqmICovXG4gICAgcG9pbnRGaWxsT3BhY2l0eTogMC45NSxcbiAgICAvKiog54K55Zu+5aSn5bCPICovXG4gICAgcG9pbnRTaXplOiA0LFxuICAgIC8qKiDngrnlm77mj4/ovrnnspfnu4YgKi9cbiAgICBwb2ludEJvcmRlcjogMSxcbiAgICAvKiog54K55Zu+5o+P6L656aKc6ImyICovXG4gICAgcG9pbnRCb3JkZXJDb2xvcjogV0hJVEVfQ09MT1JTWzEwMF0sXG4gICAgLyoqIOeCueWbvuaPj+i+uemAj+aYjuW6piAqL1xuICAgIHBvaW50Qm9yZGVyT3BhY2l0eTogMSxcbiAgICAvKiog54K55Zu+IGFjdGl2ZSDnirbmgIHkuIvmj4/ovrnpopzoibIgKi9cbiAgICBwb2ludEFjdGl2ZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiog54K55Zu+IHNlbGVjdGVkIOeKtuaAgeS4i+aPj+i+ueeyl+e7hiAqL1xuICAgIHBvaW50U2VsZWN0ZWRCb3JkZXI6IDIsXG4gICAgLyoqIOeCueWbviBzZWxlY3RlZCDnirbmgIHkuIvmj4/ovrnpopzoibIgKi9cbiAgICBwb2ludFNlbGVjdGVkQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiDngrnlm74gaW5hY3RpdmUg54q25oCB5LiL5aGr5YWF6aKc6Imy6YCP5piO5bqmICovXG4gICAgcG9pbnRJbmFjdGl2ZUZpbGxPcGFjaXR5OiAwLjMsXG4gICAgLyoqIOeCueWbviBpbmFjdGl2ZSDnirbmgIHkuIvmj4/ovrnpgI/mmI7luqYgKi9cbiAgICBwb2ludEluYWN0aXZlQm9yZGVyT3BhY2l0eTogMC4zLFxuICAgIC8qKiDnqbrlv4Pngrnlm77lpKflsI8gKi9cbiAgICBob2xsb3dQb2ludFNpemU6IDQsXG4gICAgLyoqIOepuuW/g+eCueWbvuaPj+i+ueeyl+e7hiAqL1xuICAgIGhvbGxvd1BvaW50Qm9yZGVyOiAxLFxuICAgIC8qKiDnqbrlv4Pngrnlm77mj4/ovrnpopzoibIgKi9cbiAgICBob2xsb3dQb2ludEJvcmRlckNvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiog56m65b+D54K55Zu+5o+P6L656YCP5piO5bqmICovXG4gICAgaG9sbG93UG9pbnRCb3JkZXJPcGFjaXR5OiAwLjk1LFxuICAgIGhvbGxvd1BvaW50RmlsbENvbG9yOiBXSElURV9DT0xPUlNbMTAwXSxcbiAgICAvKiog56m65b+D54K55Zu+IGFjdGl2ZSDnirbmgIHkuIvmj4/ovrnnspfnu4YgKi9cbiAgICBob2xsb3dQb2ludEFjdGl2ZUJvcmRlcjogMSxcbiAgICAvKiog56m65b+D54K55Zu+IGFjdGl2ZSDnirbmgIHkuIvmj4/ovrnpopzoibIgKi9cbiAgICBob2xsb3dQb2ludEFjdGl2ZUJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiog56m65b+D54K55Zu+IGFjdGl2ZSDnirbmgIHkuIvmj4/ovrnpgI/mmI7luqYgKi9cbiAgICBob2xsb3dQb2ludEFjdGl2ZUJvcmRlck9wYWNpdHk6IDEsXG4gICAgLyoqIOepuuW/g+eCueWbviBzZWxlY3RlZCDnirbmgIHkuIvmj4/ovrnnspfnu4YgKi9cbiAgICBob2xsb3dQb2ludFNlbGVjdGVkQm9yZGVyOiAyLFxuICAgIC8qKiDnqbrlv4Pngrnlm74gc2VsZWN0ZWQg54q25oCB5LiL5o+P6L656aKc6ImyICovXG4gICAgaG9sbG93UG9pbnRTZWxlY3RlZEJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiog56m65b+D54K55Zu+IHNlbGVjdGVkIOeKtuaAgeS4i+aPj+i+uemAj+aYjuW6piAqL1xuICAgIGhvbGxvd1BvaW50U2VsZWN0ZWRCb3JkZXJPcGFjaXR5OiAxLFxuICAgIC8qKiDnqbrlv4Pngrnlm74gaW5hY3RpdmUg54q25oCB5LiL5o+P6L656YCP5piO5bqmICovXG4gICAgaG9sbG93UG9pbnRJbmFjdGl2ZUJvcmRlck9wYWNpdHk6IDAuMyxcbiAgICAvKiog57q/5Zu+57KX57uGICovXG4gICAgbGluZUJvcmRlcjogMixcbiAgICAvKiog57q/5Zu+6aKc6ImyICovXG4gICAgbGluZUJvcmRlckNvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiog57q/5Zu+6YCP5piO5bqmICovXG4gICAgbGluZUJvcmRlck9wYWNpdHk6IDEsXG4gICAgLyoqIOe6v+WbviBBY3RpdmUg54q25oCB5LiL57KX57uGICovXG4gICAgbGluZUFjdGl2ZUJvcmRlcjogMyxcbiAgICAvKiog57q/5Zu+IHNlbGVjdGVkIOeKtuaAgeS4i+eyl+e7hiAqL1xuICAgIGxpbmVTZWxlY3RlZEJvcmRlcjogMyxcbiAgICAvKiog57q/5Zu+IGluYWN0aXZlIOeKtuaAgeS4i+mAj+aYjuW6piAqL1xuICAgIGxpbmVJbmFjdGl2ZUJvcmRlck9wYWNpdHk6IDAuMyxcbiAgICAvKiogYXJlYSDloavlhYXpopzoibIgKi9cbiAgICBhcmVhRmlsbENvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiogYXJlYSDloavlhYXpgI/mmI7luqYgKi9cbiAgICBhcmVhRmlsbE9wYWNpdHk6IDAuMjUsXG4gICAgLyoqIGFyZWEg5ZyoIGFjdGl2ZSDnirbmgIHkuIvnmoTloavlhYXpgI/mmI7luqYgKi9cbiAgICBhcmVhQWN0aXZlRmlsbENvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICBhcmVhQWN0aXZlRmlsbE9wYWNpdHk6IDAuNSxcbiAgICAvKiogYXJlYSDlnKggc2VsZWN0ZWQg54q25oCB5LiL55qE5aGr5YWF6YCP5piO5bqmICovXG4gICAgYXJlYVNlbGVjdGVkRmlsbENvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICBhcmVhU2VsZWN0ZWRGaWxsT3BhY2l0eTogMC41LFxuICAgIC8qKiBhcmVhIGluYWN0aXZlIOeKtuaAgeS4i+Whq+WFhemAj+aYjuW6piAqL1xuICAgIGFyZWFJbmFjdGl2ZUZpbGxPcGFjaXR5OiAwLjMsXG4gICAgLyoqIGhvbGxvd0FyZWEg6aKc6ImyICovXG4gICAgaG9sbG93QXJlYUJvcmRlckNvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiogaG9sbG93QXJlYSDovrnmoYbnspfnu4YgKi9cbiAgICBob2xsb3dBcmVhQm9yZGVyOiAyLFxuICAgIC8qKiBob2xsb3dBcmVhIOi+ueahhumAj+aYjuW6piAqL1xuICAgIGhvbGxvd0FyZWFCb3JkZXJPcGFjaXR5OiAxLFxuICAgIC8qKiBob2xsb3dBcmVhIGFjdGl2ZSDnirbmgIHkuIvnmoTovrnmoYbnspfnu4YgKi9cbiAgICBob2xsb3dBcmVhQWN0aXZlQm9yZGVyOiAzLFxuICAgIGhvbGxvd0FyZWFBY3RpdmVCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgLyoqIGhvbGxvd0FyZWEgc2VsZWN0ZWQg54q25oCB5LiL55qE6L655qGG57KX57uGICovXG4gICAgaG9sbG93QXJlYVNlbGVjdGVkQm9yZGVyOiAzLFxuICAgIGhvbGxvd0FyZWFTZWxlY3RlZEJvcmRlckNvbG9yOiBCTEFDS19DT0xPUlNbMTAwXSxcbiAgICAvKiogaG9sbG93QXJlYSBpbmFjdGl2ZSDnirbmgIHkuIvnmoTovrnmoYbpgI/mmI7luqYgKi9cbiAgICBob2xsb3dBcmVhSW5hY3RpdmVCb3JkZXJPcGFjaXR5OiAwLjMsXG4gICAgLyoqIGludGVydmFsIOWhq+WFheminOiJsiAqL1xuICAgIGludGVydmFsRmlsbENvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiogaW50ZXJ2YWwg5aGr5YWF6YCP5piO5bqmICovXG4gICAgaW50ZXJ2YWxGaWxsT3BhY2l0eTogMC45NSxcbiAgICAvKiogaW50ZXJ2YWwgYWN0aXZlIOeKtuaAgeS4i+i+ueahhueyl+e7hiAqL1xuICAgIGludGVydmFsQWN0aXZlQm9yZGVyOiAxLFxuICAgIC8qKiBpbnRlcnZhbCBhY3RpdmUg54q25oCB5LiL6L655qGG6aKc6ImyICovXG4gICAgaW50ZXJ2YWxBY3RpdmVCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgaW50ZXJ2YWxBY3RpdmVCb3JkZXJPcGFjaXR5OiAxLFxuICAgIC8qKiBpbnRlcnZhbCBzZWxlY3RlZCDnirbmgIHkuIvovrnmoYbnspfnu4YgKi9cbiAgICBpbnRlcnZhbFNlbGVjdGVkQm9yZGVyOiAyLFxuICAgIC8qKiBpbnRlcnZhbCBzZWxlY3RlZCDnirbmgIHkuIvovrnmoYbpopzoibIgKi9cbiAgICBpbnRlcnZhbFNlbGVjdGVkQm9yZGVyQ29sb3I6IEJMQUNLX0NPTE9SU1sxMDBdLFxuICAgIC8qKiBpbnRlcnZhbCBzZWxlY3RlZCDnirbmgIHkuIvovrnmoYbpgI/mmI7luqYgKi9cbiAgICBpbnRlcnZhbFNlbGVjdGVkQm9yZGVyT3BhY2l0eTogMSxcbiAgICAvKiogaW50ZXJ2YWwgaW5hY3RpdmUg54q25oCB5LiL6L655qGG6YCP5piO5bqmICovXG4gICAgaW50ZXJ2YWxJbmFjdGl2ZUJvcmRlck9wYWNpdHk6IDAuMyxcbiAgICAvKiogaW50ZXJ2YWwgaW5hY3RpdmUg54q25oCB5LiL5aGr5YWF6YCP5piO5bqmICovXG4gICAgaW50ZXJ2YWxJbmFjdGl2ZUZpbGxPcGFjaXR5OiAwLjMsXG4gICAgLyoqIGludGVydmFsIOi+ueahhueyl+e7hiAqL1xuICAgIGhvbGxvd0ludGVydmFsQm9yZGVyOiAyLFxuICAgIC8qKiBob2xsb3dJbnRlcnZhbCDovrnmoYbpopzoibIgKi9cbiAgICBob2xsb3dJbnRlcnZhbEJvcmRlckNvbG9yOiBRVUFMSVRBVElWRV8xMFswXSxcbiAgICAvKiogaG9sbG93SW50ZXJ2YWwg6L655qGG6YCP5piO5bqmICovXG4gICAgaG9sbG93SW50ZXJ2YWxCb3JkZXJPcGFjaXR5OiAxLFxuICAgIGhvbGxvd0ludGVydmFsRmlsbENvbG9yOiBXSElURV9DT0xPUlNbMTAwXSxcbiAgICAvKiogaG9sbG93SW50ZXJ2YWwgYWN0aXZlIOeKtuaAgeS4i+i+ueahhueyl+e7hiAqL1xuICAgIGhvbGxvd0ludGVydmFsQWN0aXZlQm9yZGVyOiAyLFxuICAgIC8qKiBob2xsb3dJbnRlcnZhbCBhY3RpdmUg54q25oCB5LiL6L655qGG6aKc6ImyICovXG4gICAgaG9sbG93SW50ZXJ2YWxBY3RpdmVCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgLyoqIGhvbGxvd0ludGVydmFsIHNlbGVjdGVkIOeKtuaAgeS4i+i+ueahhueyl+e7hiAqL1xuICAgIGhvbGxvd0ludGVydmFsU2VsZWN0ZWRCb3JkZXI6IDMsXG4gICAgLyoqIGhvbGxvd0ludGVydmFsIHNlbGVjdGVkIOeKtuaAgeS4i+i+ueahhuminOiJsiAqL1xuICAgIGhvbGxvd0ludGVydmFsU2VsZWN0ZWRCb3JkZXJDb2xvcjogQkxBQ0tfQ09MT1JTWzEwMF0sXG4gICAgLyoqIGhvbGxvd0ludGVydmFsIHNlbGVjdGVkIOeKtuaAgeS4i+i+ueahhumAj+aYjuW6piAqL1xuICAgIGhvbGxvd0ludGVydmFsU2VsZWN0ZWRCb3JkZXJPcGFjaXR5OiAxLFxuICAgIC8qKiBob2xsb3dJbnRlcnZhbCBpbmFjdGl2ZSDnirbmgIHkuIvovrnmoYbpgI/mmI7luqYgKi9cbiAgICBob2xsb3dJbnRlcnZhbEluYWN0aXZlQm9yZGVyT3BhY2l0eTogMC4zLFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpZ2h0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRNYXBwaW5nVmFsdWUgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQGlnbm9yZVxuICogZ2V0IHRoZSBtYXBwaW5nIHZhbHVlIGJ5IGF0dHJpYnV0ZSwgaWYgbWFwcGluZyB2YWx1ZSBpcyBuaWwsIHJldHVybiBkZWZcbiAqIEBwYXJhbSBhdHRyXG4gKiBAcGFyYW0gdmFsdWVcbiAqIEBwYXJhbSBkZWZcbiAqIEByZXR1cm5zIGdldCBtYXBwaW5nIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGdldE1hcHBpbmdWYWx1ZShhdHRyLCB2YWx1ZSwgZGVmKSB7XG4gICAgaWYgKCFhdHRyKSB7XG4gICAgICAgIHJldHVybiBkZWY7XG4gICAgfVxuICAgIHZhciByO1xuICAgIC8vIOWkmuWPguaVsOaYoOWwhO+8jOmYu+atoueoi+W6j+aKpemUmVxuICAgIGlmIChhdHRyLmNhbGxiYWNrICYmIGF0dHIuY2FsbGJhY2subGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgcmVzdEFyZ3MgPSBBcnJheShhdHRyLmNhbGxiYWNrLmxlbmd0aCAtIDEpLmZpbGwoJycpO1xuICAgICAgICByID0gYXR0ci5tYXBwaW5nLmFwcGx5KGF0dHIsIHRzbGliXzEuX19zcHJlYWRBcnJheXMoW3ZhbHVlXSwgcmVzdEFyZ3MpKS5qb2luKCcnKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHIgPSBhdHRyLm1hcHBpbmcodmFsdWUpLmpvaW4oJycpO1xuICAgIH1cbiAgICByZXR1cm4gciB8fCBkZWY7XG59XG5leHBvcnRzLmdldE1hcHBpbmdWYWx1ZSA9IGdldE1hcHBpbmdWYWx1ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF0dHIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldEF4aXNUaXRsZVRleHQgPSBleHBvcnRzLmdldEF4aXNEaXJlY3Rpb24gPSBleHBvcnRzLmdldEF4aXNPcHRpb24gPSBleHBvcnRzLmdldENpcmNsZUF4aXNDZW50ZXJSYWRpdXMgPSBleHBvcnRzLmdldEF4aXNUaGVtZUNmZyA9IGV4cG9ydHMuZ2V0QXhpc0ZhY3RvckJ5UmVnaW9uID0gZXhwb3J0cy5pc1ZlcnRpY2FsID0gZXhwb3J0cy5nZXRBeGlzRmFjdG9yID0gZXhwb3J0cy5nZXRBeGlzUmVnaW9uID0gZXhwb3J0cy5nZXRDaXJjbGVBeGlzUmVsYXRpdmVSZWdpb24gPSBleHBvcnRzLmdldExpbmVBeGlzUmVsYXRpdmVSZWdpb24gPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4vc2NhbGVcIik7XG52YXIgbWF0cml4X3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9tYXRyaXgtdXRpbFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICogZ2V0IGF4aXMgcmVsYXRpdmUgcmVnaW9uICggMCB+IDEpIGJ5IGRpcmVjdGlvbiB3aGVuIGNvb3JkaW5hdGUgaXMgcmVjdFxuICogQHBhcmFtIGRpcmVjdGlvblxuICogQHJldHVybnMgYXhpcyBjb29yZGluYXRlIHJlZ2lvblxuICovXG5mdW5jdGlvbiBnZXRMaW5lQXhpc1JlbGF0aXZlUmVnaW9uKGRpcmVjdGlvbikge1xuICAgIHZhciBzdGFydDtcbiAgICB2YXIgZW5kO1xuICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICAgIGNhc2UgY29uc3RhbnRfMS5ESVJFQ1RJT04uVE9QOlxuICAgICAgICAgICAgc3RhcnQgPSB7IHg6IDAsIHk6IDEgfTtcbiAgICAgICAgICAgIGVuZCA9IHsgeDogMSwgeTogMSB9O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgY29uc3RhbnRfMS5ESVJFQ1RJT04uUklHSFQ6XG4gICAgICAgICAgICBzdGFydCA9IHsgeDogMSwgeTogMCB9O1xuICAgICAgICAgICAgZW5kID0geyB4OiAxLCB5OiAxIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT006XG4gICAgICAgICAgICBzdGFydCA9IHsgeDogMCwgeTogMCB9O1xuICAgICAgICAgICAgZW5kID0geyB4OiAxLCB5OiAwIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUOlxuICAgICAgICAgICAgc3RhcnQgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgICAgIGVuZCA9IHsgeDogMCwgeTogMSB9O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBzdGFydCA9IGVuZCA9IHsgeDogMCwgeTogMCB9O1xuICAgIH1cbiAgICByZXR1cm4geyBzdGFydDogc3RhcnQsIGVuZDogZW5kIH07XG59XG5leHBvcnRzLmdldExpbmVBeGlzUmVsYXRpdmVSZWdpb24gPSBnZXRMaW5lQXhpc1JlbGF0aXZlUmVnaW9uO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBnZXQgYXhpcyByZWxhdGl2ZSByZWdpb24gKCAwIH4gMSkgYnkgZGlyZWN0aW9uIHdoZW4gY29vcmRpbmF0ZSBpcyBwb2xhclxuICogQHBhcmFtIGNvb3JkaW5hdGVcbiAqIEByZXR1cm5zIGF4aXMgY29vcmRpbmF0ZSByZWdpb25cbiAqL1xuZnVuY3Rpb24gZ2V0Q2lyY2xlQXhpc1JlbGF0aXZlUmVnaW9uKGNvb3JkaW5hdGUpIHtcbiAgICB2YXIgc3RhcnQ7XG4gICAgdmFyIGVuZDtcbiAgICBpZiAoY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgc3RhcnQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgZW5kID0ge1xuICAgICAgICAgICAgeDogMSxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzdGFydCA9IHtcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICB9O1xuICAgICAgICBlbmQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0LCBlbmQ6IGVuZCB9O1xufVxuZXhwb3J0cy5nZXRDaXJjbGVBeGlzUmVsYXRpdmVSZWdpb24gPSBnZXRDaXJjbGVBeGlzUmVsYXRpdmVSZWdpb247XG4vKipcbiAqIEBpZ25vcmVcbiAqIGdldCB0aGUgYXhpcyByZWdpb24gZnJvbSBjb29yZGluYXRlXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHBhcmFtIGRpcmVjdGlvblxuICogQHJldHVybnMgdGhlIGF4aXMgcmVnaW9uIChzdGFydCBwb2ludCwgZW5kIHBvaW50KVxuICovXG5mdW5jdGlvbiBnZXRBeGlzUmVnaW9uKGNvb3JkaW5hdGUsIGRpcmVjdGlvbikge1xuICAgIHZhciByZWdpb24gPSB7IHN0YXJ0OiB7IHg6IDAsIHk6IDAgfSwgZW5kOiB7IHg6IDAsIHk6IDAgfSB9O1xuICAgIGlmIChjb29yZGluYXRlLmlzUmVjdCkge1xuICAgICAgICByZWdpb24gPSBnZXRMaW5lQXhpc1JlbGF0aXZlUmVnaW9uKGRpcmVjdGlvbik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvb3JkaW5hdGUuaXNQb2xhcikge1xuICAgICAgICByZWdpb24gPSBnZXRDaXJjbGVBeGlzUmVsYXRpdmVSZWdpb24oY29vcmRpbmF0ZSk7XG4gICAgfVxuICAgIHZhciBzdGFydCA9IHJlZ2lvbi5zdGFydCwgZW5kID0gcmVnaW9uLmVuZDtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogY29vcmRpbmF0ZS5jb252ZXJ0KHN0YXJ0KSxcbiAgICAgICAgZW5kOiBjb29yZGluYXRlLmNvbnZlcnQoZW5kKSxcbiAgICB9O1xufVxuZXhwb3J0cy5nZXRBeGlzUmVnaW9uID0gZ2V0QXhpc1JlZ2lvbjtcbi8qKlxuICogQGlnbm9yZVxuICogZ2V0IGF4aXMgZmFjdG9yXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHBhcmFtIGRpcmVjdGlvblxuICogQHJldHVybnMgZmFjdG9yXG4gKi9cbmZ1bmN0aW9uIGdldEF4aXNGYWN0b3IoY29vcmRpbmF0ZSwgZGlyZWN0aW9uKSB7XG4gICAgLy8gcmVjdCBjb29yZGluYXRlLCBieSBkaXJlY3Rpb25cbiAgICBpZiAoY29vcmRpbmF0ZS5pc1JlY3QpIHtcbiAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkXG4gICAgICAgICAgICA/IFtjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVCwgY29uc3RhbnRfMS5ESVJFQ1RJT04uQk9UVE9NXS5pbmNsdWRlcyhkaXJlY3Rpb24pXG4gICAgICAgICAgICAgICAgPyAxXG4gICAgICAgICAgICAgICAgOiAtMVxuICAgICAgICAgICAgOiBbY29uc3RhbnRfMS5ESVJFQ1RJT04uQk9UVE9NLCBjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVF0uaW5jbHVkZXMoZGlyZWN0aW9uKVxuICAgICAgICAgICAgICAgID8gLTFcbiAgICAgICAgICAgICAgICA6IDE7XG4gICAgfVxuICAgIC8vIHBvbGFyIHkgYXhpcywgYnkgYW5nbGVcbiAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gY29vcmRpbmF0ZS54LnN0YXJ0O1xuICAgICAgICByZXR1cm4gc3RhcnRBbmdsZSA8IDAgPyAtMSA6IDE7XG4gICAgfVxuICAgIHJldHVybiAxO1xufVxuZXhwb3J0cy5nZXRBeGlzRmFjdG9yID0gZ2V0QXhpc0ZhY3Rvcjtcbi8qKlxuICogQGlnbm9yZVxuICogd2hldGhlciB0aGUgYXhpcyBpc1ZlcnRpY2FsXG4gKiBAcGFyYW0gcmVnaW9uXG4gKiBAcmV0dXJucyBpc1ZlcnRpY2FsXG4gKi9cbmZ1bmN0aW9uIGlzVmVydGljYWwocmVnaW9uKSB7XG4gICAgdmFyIHN0YXJ0ID0gcmVnaW9uLnN0YXJ0LCBlbmQgPSByZWdpb24uZW5kO1xuICAgIHJldHVybiBzdGFydC54ID09PSBlbmQueDtcbn1cbmV4cG9ydHMuaXNWZXJ0aWNhbCA9IGlzVmVydGljYWw7XG4vKipcbiAqIEBpZ25vcmVcbiAqIGdldCBmYWN0b3IgYnkgcmVnaW9uIChyZWFsIHBvc2l0aW9uKVxuICogQHBhcmFtIHJlZ2lvblxuICogQHBhcmFtIGNlbnRlclxuICogQHJldHVybnMgZmFjdG9yXG4gKi9cbmZ1bmN0aW9uIGdldEF4aXNGYWN0b3JCeVJlZ2lvbihyZWdpb24sIGNlbnRlcikge1xuICAgIHZhciBzdGFydCA9IHJlZ2lvbi5zdGFydCwgZW5kID0gcmVnaW9uLmVuZDtcbiAgICB2YXIgaXNBeGlzVmVydGljYWwgPSBpc1ZlcnRpY2FsKHJlZ2lvbik7XG4gICAgLy8g5Z6C55u0XG4gICAgaWYgKGlzQXhpc1ZlcnRpY2FsKSB7XG4gICAgICAgIC8vIOW3puaWuSzku47kuIvliLDkuIrjgIHlj7Pmlrks5LuO5LiK5Yiw5LiLXG4gICAgICAgIGlmICgoc3RhcnQueSAtIGVuZC55KSAqIChjZW50ZXIueCAtIHN0YXJ0LngpID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIOS4i+aWuSzku47lt6bliLDlj7PjgIHkuIrmlrks5LuO5Y+z5Yiw5YGaXG4gICAgICAgIGlmICgoZW5kLnggLSBzdGFydC54KSAqIChzdGFydC55IC0gY2VudGVyLnkpID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnRzLmdldEF4aXNGYWN0b3JCeVJlZ2lvbiA9IGdldEF4aXNGYWN0b3JCeVJlZ2lvbjtcbi8qKlxuICogQGlnbm9yZVxuICogZ2V0IHRoZSBheGlzIGNmZyBmcm9tIHRoZW1lXG4gKiBAcGFyYW0gdGhlbWUgdmlldyB0aGVtZSBvYmplY3RcbiAqIEBwYXJhbSBkaXJlY3Rpb24gYXhpcyBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIGF4aXMgdGhlbWUgY2ZnXG4gKi9cbmZ1bmN0aW9uIGdldEF4aXNUaGVtZUNmZyh0aGVtZSwgZGlyZWN0aW9uKSB7XG4gICAgcmV0dXJuIHV0aWxfMS5nZXQodGhlbWUsIFsnY29tcG9uZW50cycsICdheGlzJywgZGlyZWN0aW9uXSwge30pO1xufVxuZXhwb3J0cy5nZXRBeGlzVGhlbWVDZmcgPSBnZXRBeGlzVGhlbWVDZmc7XG4vKipcbiAqIEBpZ25vcmVcbiAqIGdldCBjaXJjbGUgYXhpcyBjZW50ZXIgYW5kIHJhZGl1c1xuICogQHBhcmFtIGNvb3JkaW5hdGVcbiAqL1xuZnVuY3Rpb24gZ2V0Q2lyY2xlQXhpc0NlbnRlclJhZGl1cyhjb29yZGluYXRlKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHZhciB4ID0gY29vcmRpbmF0ZS54LCB5ID0gY29vcmRpbmF0ZS55LCBjZW50ZXIgPSBjb29yZGluYXRlLmNpcmNsZUNlbnRlcjtcbiAgICB2YXIgaXNSZWZsZWN0WSA9IHkuc3RhcnQgPiB5LmVuZDtcbiAgICB2YXIgc3RhcnQgPSBjb29yZGluYXRlLmlzVHJhbnNwb3NlZFxuICAgICAgICA/IGNvb3JkaW5hdGUuY29udmVydCh7XG4gICAgICAgICAgICB4OiBpc1JlZmxlY3RZID8gMCA6IDEsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICB9KVxuICAgICAgICA6IGNvb3JkaW5hdGUuY29udmVydCh7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogaXNSZWZsZWN0WSA/IDAgOiAxLFxuICAgICAgICB9KTtcbiAgICB2YXIgc3RhcnRWZWN0b3IgPSBbc3RhcnQueCAtIGNlbnRlci54LCBzdGFydC55IC0gY2VudGVyLnldO1xuICAgIHZhciBub3JtYWxWZWN0b3IgPSBbMSwgMF07XG4gICAgdmFyIHN0YXJ0QW5nbGUgPSBzdGFydC55ID4gY2VudGVyLnkgPyBtYXRyaXhfdXRpbF8xLnZlYzIuYW5nbGUoc3RhcnRWZWN0b3IsIG5vcm1hbFZlY3RvcikgOiBtYXRyaXhfdXRpbF8xLnZlYzIuYW5nbGUoc3RhcnRWZWN0b3IsIG5vcm1hbFZlY3RvcikgKiAtMTtcbiAgICB2YXIgZW5kQW5nbGUgPSBzdGFydEFuZ2xlICsgKHguZW5kIC0geC5zdGFydCk7XG4gICAgdmFyIHJhZGl1cyA9IE1hdGguc3FydChNYXRoLnBvdygoc3RhcnQueCAtIGNlbnRlci54KSwgMikgKyBNYXRoLnBvdygoc3RhcnQueSAtIGNlbnRlci55KSwgMikpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGNlbnRlcjogY2VudGVyLFxuICAgICAgICByYWRpdXM6IHJhZGl1cyxcbiAgICAgICAgc3RhcnRBbmdsZTogc3RhcnRBbmdsZSxcbiAgICAgICAgZW5kQW5nbGU6IGVuZEFuZ2xlLFxuICAgIH07XG59XG5leHBvcnRzLmdldENpcmNsZUF4aXNDZW50ZXJSYWRpdXMgPSBnZXRDaXJjbGVBeGlzQ2VudGVyUmFkaXVzO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDku47phY3nva7kuK3ojrflj5bljZXkuKrlrZfmrrXnmoQgYXhpcyDphY3nva5cbiAqIEBwYXJhbSBheGVzXG4gKiBAcGFyYW0gZmllbGRcbiAqIEByZXR1cm5zIHRoZSBheGlzIG9wdGlvbiBvZiBmaWVsZFxuICovXG5mdW5jdGlvbiBnZXRBeGlzT3B0aW9uKGF4ZXMsIGZpZWxkKSB7XG4gICAgaWYgKHV0aWxfMS5pc0Jvb2xlYW4oYXhlcykpIHtcbiAgICAgICAgcmV0dXJuIGF4ZXMgPT09IGZhbHNlID8gZmFsc2UgOiB7fTtcbiAgICB9XG4gICAgcmV0dXJuIHV0aWxfMS5nZXQoYXhlcywgW2ZpZWxkXSk7XG59XG5leHBvcnRzLmdldEF4aXNPcHRpb24gPSBnZXRBeGlzT3B0aW9uO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDlpoLmnpzphY3nva7kuoYgcG9zaXRpb27vvIzliJnkvb/nlKjphY3nva5cbiAqIEBwYXJhbSBheGlzT3B0aW9uXG4gKiBAcGFyYW0gZGVmXG4gKi9cbmZ1bmN0aW9uIGdldEF4aXNEaXJlY3Rpb24oYXhpc09wdGlvbiwgZGVmKSB7XG4gICAgcmV0dXJuIHV0aWxfMS5nZXQoYXhpc09wdGlvbiwgJ3Bvc2l0aW9uJywgZGVmKTtcbn1cbmV4cG9ydHMuZ2V0QXhpc0RpcmVjdGlvbiA9IGdldEF4aXNEaXJlY3Rpb247XG4vKipcbiAqIOiOt+WPliBheGlzIOeahCB0aXRsZSDmlofmnKxcbiAqIEBwYXJhbSBzY2FsZVxuICogQHBhcmFtIGF4aXNPcHRpb25cbiAqL1xuZnVuY3Rpb24gZ2V0QXhpc1RpdGxlVGV4dChzY2FsZSwgYXhpc09wdGlvbikge1xuICAgIHJldHVybiB1dGlsXzEuZ2V0KGF4aXNPcHRpb24sIFsndGl0bGUnLCAndGV4dCddLCBzY2FsZV8xLmdldE5hbWUoc2NhbGUpKTtcbn1cbmV4cG9ydHMuZ2V0QXhpc1RpdGxlVGV4dCA9IGdldEF4aXNUaXRsZVRleHQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1heGlzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50b1BvaW50cyA9IGV4cG9ydHMuZ2V0UmVnaW9uQkJveCA9IGV4cG9ydHMuQkJveCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xuLyoqXG4gKiDnlKjkuo7ljIXlm7Tnm5LorqHnrpfjgIJcbiAqL1xudmFyIEJCb3ggPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQkJveCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIGlmICh4ID09PSB2b2lkIDApIHsgeCA9IDA7IH1cbiAgICAgICAgaWYgKHkgPT09IHZvaWQgMCkgeyB5ID0gMDsgfVxuICAgICAgICBpZiAod2lkdGggPT09IHZvaWQgMCkgeyB3aWR0aCA9IDA7IH1cbiAgICAgICAgaWYgKGhlaWdodCA9PT0gdm9pZCAwKSB7IGhlaWdodCA9IDA7IH1cbiAgICAgICAgdGhpcy54ID0geDtcbiAgICAgICAgdGhpcy55ID0geTtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICB9XG4gICAgQkJveC5mcm9tUmFuZ2UgPSBmdW5jdGlvbiAobWluWCwgbWluWSwgbWF4WCwgbWF4WSkge1xuICAgICAgICByZXR1cm4gbmV3IEJCb3gobWluWCwgbWluWSwgbWF4WCAtIG1pblgsIG1heFkgLSBtaW5ZKTtcbiAgICB9O1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCQm94LnByb3RvdHlwZSwgXCJtaW5YXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy54O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcIm1heFhcIiwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnggKyB0aGlzLndpZHRoO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcIm1pbllcIiwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnk7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQkJveC5wcm90b3R5cGUsIFwibWF4WVwiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMueSArIHRoaXMuaGVpZ2h0O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcInRsXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4geyB4OiB0aGlzLngsIHk6IHRoaXMueSB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcInRyXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4geyB4OiB0aGlzLm1heFgsIHk6IHRoaXMueSB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcImJsXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4geyB4OiB0aGlzLngsIHk6IHRoaXMubWF4WSB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcImJyXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4geyB4OiB0aGlzLm1heFgsIHk6IHRoaXMubWF4WSB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcInRvcFwiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLnggKyB0aGlzLndpZHRoIC8gMixcbiAgICAgICAgICAgICAgICB5OiB0aGlzLm1pblksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcInJpZ2h0XCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMubWF4WCxcbiAgICAgICAgICAgICAgICB5OiB0aGlzLnkgKyB0aGlzLmhlaWdodCAvIDIsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcImJvdHRvbVwiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLnggKyB0aGlzLndpZHRoIC8gMixcbiAgICAgICAgICAgICAgICB5OiB0aGlzLm1heFksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJCb3gucHJvdG90eXBlLCBcImxlZnRcIiwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgeDogdGhpcy5taW5YLFxuICAgICAgICAgICAgICAgIHk6IHRoaXMueSArIHRoaXMuaGVpZ2h0IC8gMixcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgICAvLyBlbmQg6K6h566X5bGe5oCnXG4gICAgLyoqXG4gICAgICog5YyF5Zu055uS5piv5ZCm55u4562JXG4gICAgICogQHBhcmFtIHtCQm94fSBiYm94IOWMheWbtOebklxuICAgICAqIEByZXR1cm5zICAgICAg5YyF5Zu055uS5piv5ZCm55u4562JXG4gICAgICovXG4gICAgQkJveC5wcm90b3R5cGUuaXNFcXVhbCA9IGZ1bmN0aW9uIChiYm94KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnggPT09IGJib3gueCAmJiB0aGlzLnkgPT09IGJib3gueSAmJiB0aGlzLndpZHRoID09PSBiYm94LndpZHRoICYmIHRoaXMuaGVpZ2h0ID09PSBiYm94LmhlaWdodDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWFi+mahuWMheWbtOebklxuICAgICAqIEByZXR1cm5zIOWMheWbtOebklxuICAgICAqL1xuICAgIEJCb3gucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IEJCb3godGhpcy54LCB0aGlzLnksIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWPluW5tumbhlxuICAgICAqIEBwYXJhbSBzdWJCQm94XG4gICAgICovXG4gICAgQkJveC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3ViQkJveCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgc3ViQkJveFtfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiYm94ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICB1dGlsXzEuZWFjaChzdWJCQm94LCBmdW5jdGlvbiAoYikge1xuICAgICAgICAgICAgYmJveC54ID0gTWF0aC5taW4oYi54LCBiYm94LngpO1xuICAgICAgICAgICAgYmJveC55ID0gTWF0aC5taW4oYi55LCBiYm94LnkpO1xuICAgICAgICAgICAgYmJveC53aWR0aCA9IE1hdGgubWF4KGIubWF4WCwgYmJveC5tYXhYKSAtIGJib3gueDtcbiAgICAgICAgICAgIGJib3guaGVpZ2h0ID0gTWF0aC5tYXgoYi5tYXhZLCBiYm94Lm1heFkpIC0gYmJveC55O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGJib3g7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlj5bkuqTpm4ZcbiAgICAgKiBAcGFyYW0gc3ViQkJveFxuICAgICAqL1xuICAgIEJCb3gucHJvdG90eXBlLm1lcmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3ViQkJveCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgc3ViQkJveFtfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiYm94ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICB1dGlsXzEuZWFjaChzdWJCQm94LCBmdW5jdGlvbiAoYikge1xuICAgICAgICAgICAgYmJveC54ID0gTWF0aC5tYXgoYi54LCBiYm94LngpO1xuICAgICAgICAgICAgYmJveC55ID0gTWF0aC5tYXgoYi55LCBiYm94LnkpO1xuICAgICAgICAgICAgYmJveC53aWR0aCA9IE1hdGgubWluKGIubWF4WCwgYmJveC5tYXhYKSAtIGJib3gueDtcbiAgICAgICAgICAgIGJib3guaGVpZ2h0ID0gTWF0aC5taW4oYi5tYXhZLCBiYm94Lm1heFkpIC0gYmJveC55O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGJib3g7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBiYm94IOWJquijgVxuICAgICAqIEBwYXJhbSBzdWJCQm94XG4gICAgICogQHBhcmFtIGRpcmVjdGlvblxuICAgICAqL1xuICAgIEJCb3gucHJvdG90eXBlLmN1dCA9IGZ1bmN0aW9uIChzdWJCQm94LCBkaXJlY3Rpb24pIHtcbiAgICAgICAgdmFyIHdpZHRoID0gc3ViQkJveC53aWR0aDtcbiAgICAgICAgdmFyIGhlaWdodCA9IHN1YkJCb3guaGVpZ2h0O1xuICAgICAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5UT1A6XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUF9MRUZUOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5UT1BfUklHSFQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEJCb3guZnJvbVJhbmdlKHRoaXMubWluWCwgdGhpcy5taW5ZICsgaGVpZ2h0LCB0aGlzLm1heFgsIHRoaXMubWF4WSk7XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVF9UT1A6XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUX0JPVFRPTTpcbiAgICAgICAgICAgICAgICByZXR1cm4gQkJveC5mcm9tUmFuZ2UodGhpcy5taW5YLCB0aGlzLm1pblksIHRoaXMubWF4WCAtIHdpZHRoLCB0aGlzLm1heFkpO1xuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT006XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTV9MRUZUOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT01fUklHSFQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEJCb3guZnJvbVJhbmdlKHRoaXMubWluWCwgdGhpcy5taW5ZLCB0aGlzLm1heFgsIHRoaXMubWF4WSAtIGhlaWdodCk7XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLkxFRlQ6XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLkxFRlRfVE9QOlxuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUX0JPVFRPTTpcbiAgICAgICAgICAgICAgICByZXR1cm4gQkJveC5mcm9tUmFuZ2UodGhpcy5taW5YICsgd2lkdGgsIHRoaXMubWluWSwgdGhpcy5tYXhYLCB0aGlzLm1heFkpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAvLyDlhbbku5bmg4XlhrXkuI3oo4HliarvvIzljp/moLfov5Tlm55cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5pS257yp5b2i5oiQ5paw55qEXG4gICAgICogQHBhcmFtIGdhcFxuICAgICAqL1xuICAgIEJCb3gucHJvdG90eXBlLnNocmluayA9IGZ1bmN0aW9uIChnYXApIHtcbiAgICAgICAgdmFyIHRvcCA9IGdhcFswXSwgcmlnaHQgPSBnYXBbMV0sIGJvdHRvbSA9IGdhcFsyXSwgbGVmdCA9IGdhcFszXTtcbiAgICAgICAgcmV0dXJuIG5ldyBCQm94KHRoaXMueCArIGxlZnQsIHRoaXMueSArIHRvcCwgdGhpcy53aWR0aCAtIGxlZnQgLSByaWdodCwgdGhpcy5oZWlnaHQgLSB0b3AgLSBib3R0b20pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBnYXAgb2YgdHdvIGJib3gsIGlmIG5vdCBleGNlZWQsIHRoZW4gMFxuICAgICAqIEBwYXJhbSBiYm94XG4gICAgICogQHJldHVybnMgW3RvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdF1cbiAgICAgKi9cbiAgICBCQm94LnByb3RvdHlwZS5leGNlZWQgPSBmdW5jdGlvbiAoYmJveCkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgTWF0aC5tYXgoLXRoaXMubWluWSArIGJib3gubWluWSwgMCksXG4gICAgICAgICAgICBNYXRoLm1heCh0aGlzLm1heFggLSBiYm94Lm1heFgsIDApLFxuICAgICAgICAgICAgTWF0aC5tYXgodGhpcy5tYXhZIC0gYmJveC5tYXhZLCAwKSxcbiAgICAgICAgICAgIE1hdGgubWF4KC10aGlzLm1pblggKyBiYm94Lm1pblgsIDApLFxuICAgICAgICBdO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5YyF5Zu055uS5aSn5bCPXG4gICAgICogQHJldHVybnMg5YyF5Zu055uS5aSn5bCPXG4gICAgICovXG4gICAgQkJveC5wcm90b3R5cGUuc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lkdGggKiB0aGlzLmhlaWdodDtcbiAgICB9O1xuICAgIHJldHVybiBCQm94O1xufSgpKTtcbmV4cG9ydHMuQkJveCA9IEJCb3g7XG4vKipcbiAqIOS7juS4gOS4qiBiYm94IOeahCByZWdpb24g6I635Y+WIGJib3hcbiAqIEBwYXJhbSBiYm94XG4gKiBAcGFyYW0gcmVnaW9uXG4gKi9cbmV4cG9ydHMuZ2V0UmVnaW9uQkJveCA9IGZ1bmN0aW9uIChiYm94LCByZWdpb24pIHtcbiAgICB2YXIgc3RhcnQgPSByZWdpb24uc3RhcnQsIGVuZCA9IHJlZ2lvbi5lbmQ7XG4gICAgcmV0dXJuIG5ldyBCQm94KGJib3gueCArIGJib3gud2lkdGggKiBzdGFydC54LCBiYm94LnkgKyBiYm94LmhlaWdodCAqIHN0YXJ0LnksIGJib3gud2lkdGggKiBNYXRoLmFicyhlbmQueCAtIHN0YXJ0LngpLCBiYm94LmhlaWdodCAqIE1hdGguYWJzKGVuZC55IC0gc3RhcnQueSkpO1xufTtcbi8qKlxuICog5bCGIGJib3gg6L2s5o2i5oiQIHBvaW50c1xuICogQHBhcmFtIGJib3hcbiAqL1xuZnVuY3Rpb24gdG9Qb2ludHMoYmJveCkge1xuICAgIHJldHVybiBbXG4gICAgICAgIFtiYm94Lm1pblgsIGJib3gubWluWV0sXG4gICAgICAgIFtiYm94Lm1heFgsIGJib3gubWluWV0sXG4gICAgICAgIFtiYm94Lm1heFgsIGJib3gubWF4WV0sXG4gICAgICAgIFtiYm94Lm1pblgsIGJib3gubWF4WV0sXG4gICAgXTtcbn1cbmV4cG9ydHMudG9Qb2ludHMgPSB0b1BvaW50cztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJib3guanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldENvb3JkaW5hdGVDbGlwQ2ZnID0gZXhwb3J0cy5nZXRBbmdsZUJ5UG9pbnQgPSBleHBvcnRzLmlzUG9pbnRJbkNvb3JkaW5hdGUgPSBleHBvcnRzLmdldERpc3RhbmNlVG9DZW50ZXIgPSBleHBvcnRzLmlzRnVsbENpcmNsZSA9IGV4cG9ydHMuZ2V0WERpbWVuc2lvbkxlbmd0aCA9IHZvaWQgMDtcbnZhciBncmFwaGljc18xID0gcmVxdWlyZShcIi4vZ3JhcGhpY3NcIik7XG52YXIgaGVscGVyXzEgPSByZXF1aXJlKFwiLi9oZWxwZXJcIik7XG4vKipcbiAqIEBpZ25vcmVcbiAqIEdldHMgeCBkaW1lbnNpb24gbGVuZ3RoXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHJldHVybnMgeCBkaW1lbnNpb24gbGVuZ3RoXG4gKi9cbmZ1bmN0aW9uIGdldFhEaW1lbnNpb25MZW5ndGgoY29vcmRpbmF0ZSkge1xuICAgIGlmIChjb29yZGluYXRlLmlzUG9sYXIgJiYgIWNvb3JkaW5hdGUuaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgIC8vIOaegeWdkOagh+ezu+S4iyB3aWR0aCDkuLrlvKfplb9cbiAgICAgICAgcmV0dXJuIChjb29yZGluYXRlLmVuZEFuZ2xlIC0gY29vcmRpbmF0ZS5zdGFydEFuZ2xlKSAqIGNvb3JkaW5hdGUuZ2V0UmFkaXVzKCk7XG4gICAgfVxuICAgIC8vIOebtOinkuWdkOagh+ezu1xuICAgIHZhciBzdGFydCA9IGNvb3JkaW5hdGUuY29udmVydCh7IHg6IDAsIHk6IDAgfSk7XG4gICAgdmFyIGVuZCA9IGNvb3JkaW5hdGUuY29udmVydCh7IHg6IDEsIHk6IDAgfSk7XG4gICAgLy8g5Z2Q5qCH57O75pyJ5Y+v6IO95Y+R55SfIHRyYW5zcG9zZSDnrYnlj5jmjaLvvIzmiYDmnInpgJrov4fkuKTngrnkuYvpl7TnmoTot53nprvov5vooYzorqHnrpdcbiAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KGVuZC54IC0gc3RhcnQueCwgMikgKyBNYXRoLnBvdyhlbmQueSAtIHN0YXJ0LnksIDIpKTtcbn1cbmV4cG9ydHMuZ2V0WERpbWVuc2lvbkxlbmd0aCA9IGdldFhEaW1lbnNpb25MZW5ndGg7XG4vKipcbiAqIEBpZ25vcmVcbiAqIERldGVybWluZXMgd2hldGhlciBmdWxsIGNpcmNsZSBpc1xuICogQHBhcmFtIGNvb3JkaW5hdGVcbiAqIEByZXR1cm5zIHRydWUgaWYgZnVsbCBjaXJjbGVcbiAqL1xuZnVuY3Rpb24gaXNGdWxsQ2lyY2xlKGNvb3JkaW5hdGUpIHtcbiAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gY29vcmRpbmF0ZS5zdGFydEFuZ2xlLCBlbmRBbmdsZSA9IGNvb3JkaW5hdGUuZW5kQW5nbGU7XG4gICAgICAgIHJldHVybiBlbmRBbmdsZSAtIHN0YXJ0QW5nbGUgPT09IE1hdGguUEkgKiAyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnRzLmlzRnVsbENpcmNsZSA9IGlzRnVsbENpcmNsZTtcbi8qKlxuICogQGlnbm9yZVxuICog6I635Y+W5b2T5YmN54K55Yiw5Z2Q5qCH57O75ZyG5b+D55qE6Led56a7XG4gKiBAcGFyYW0gY29vcmRpbmF0ZSDlnZDmoIfns7tcbiAqIEBwYXJhbSBwb2ludCDlvZPliY3ngrlcbiAqIEByZXR1cm5zIGRpc3RhbmNlIHRvIGNlbnRlclxuICovXG5mdW5jdGlvbiBnZXREaXN0YW5jZVRvQ2VudGVyKGNvb3JkaW5hdGUsIHBvaW50KSB7XG4gICAgdmFyIGNlbnRlciA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgcmV0dXJuIE1hdGguc3FydChNYXRoLnBvdygocG9pbnQueCAtIGNlbnRlci54KSwgMikgKyBNYXRoLnBvdygocG9pbnQueSAtIGNlbnRlci55KSwgMikpO1xufVxuZXhwb3J0cy5nZXREaXN0YW5jZVRvQ2VudGVyID0gZ2V0RGlzdGFuY2VUb0NlbnRlcjtcbi8qKlxuICogQGlnbm9yZVxuICog5Z2Q5qCH54K55piv5ZCm5Zyo5Z2Q5qCH57O75LitXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHBhcmFtIHBvaW50XG4gKi9cbmZ1bmN0aW9uIGlzUG9pbnRJbkNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgcG9pbnQpIHtcbiAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XG4gICAgaWYgKGNvb3JkaW5hdGUpIHtcbiAgICAgICAgaWYgKGNvb3JkaW5hdGUudHlwZSA9PT0gJ3RoZXRhJykge1xuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gY29vcmRpbmF0ZS5zdGFydCwgZW5kID0gY29vcmRpbmF0ZS5lbmQ7XG4gICAgICAgICAgICByZXN1bHQgPSBoZWxwZXJfMS5pc0JldHdlZW4ocG9pbnQueCwgc3RhcnQueCwgZW5kLngpICYmIGhlbHBlcl8xLmlzQmV0d2Vlbihwb2ludC55LCBzdGFydC55LCBlbmQueSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgaW52ZXJ0UG9pbnQgPSBjb29yZGluYXRlLmludmVydChwb2ludCk7XG4gICAgICAgICAgICByZXN1bHQgPSBoZWxwZXJfMS5pc0JldHdlZW4oaW52ZXJ0UG9pbnQueCwgMCwgMSkgJiYgaGVscGVyXzEuaXNCZXR3ZWVuKGludmVydFBvaW50LnksIDAsIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnRzLmlzUG9pbnRJbkNvb3JkaW5hdGUgPSBpc1BvaW50SW5Db29yZGluYXRlO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDojrflj5bngrnliLDlnIblv4PnmoTov57nur/kuI7msLTlubPmlrnlkJHnmoTlpLnop5JcbiAqL1xuZnVuY3Rpb24gZ2V0QW5nbGVCeVBvaW50KGNvb3JkaW5hdGUsIHBvaW50KSB7XG4gICAgdmFyIGNlbnRlciA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgcmV0dXJuIE1hdGguYXRhbjIocG9pbnQueSAtIGNlbnRlci55LCBwb2ludC54IC0gY2VudGVyLngpO1xufVxuZXhwb3J0cy5nZXRBbmdsZUJ5UG9pbnQgPSBnZXRBbmdsZUJ5UG9pbnQ7XG4vKipcbiAqIEBpZ25vcmVcbiAqIOiOt+WPluWQjOWdkOagh+ezu+iMg+WbtOebuOWQjOeahOWJquWIh+WMuuWfn1xuICogQHBhcmFtIGNvb3JkaW5hdGVcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldENvb3JkaW5hdGVDbGlwQ2ZnKGNvb3JkaW5hdGUsIG1hcmdpbikge1xuICAgIGlmIChtYXJnaW4gPT09IHZvaWQgMCkgeyBtYXJnaW4gPSAwOyB9XG4gICAgdmFyIHN0YXJ0ID0gY29vcmRpbmF0ZS5zdGFydCwgZW5kID0gY29vcmRpbmF0ZS5lbmQ7XG4gICAgdmFyIHdpZHRoID0gY29vcmRpbmF0ZS5nZXRXaWR0aCgpO1xuICAgIHZhciBoZWlnaHQgPSBjb29yZGluYXRlLmdldEhlaWdodCgpO1xuICAgIGlmIChjb29yZGluYXRlLmlzUG9sYXIpIHtcbiAgICAgICAgdmFyIHN0YXJ0QW5nbGVfMSA9IGNvb3JkaW5hdGUuc3RhcnRBbmdsZSwgZW5kQW5nbGVfMSA9IGNvb3JkaW5hdGUuZW5kQW5nbGU7XG4gICAgICAgIHZhciBjZW50ZXJfMSA9IGNvb3JkaW5hdGUuZ2V0Q2VudGVyKCk7XG4gICAgICAgIHZhciByYWRpdXNfMSA9IGNvb3JkaW5hdGUuZ2V0UmFkaXVzKCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgICAgICBzdGFydFN0YXRlOiB7XG4gICAgICAgICAgICAgICAgcGF0aDogZ3JhcGhpY3NfMS5nZXRTZWN0b3JQYXRoKGNlbnRlcl8xLngsIGNlbnRlcl8xLnksIHJhZGl1c18xICsgbWFyZ2luLCBzdGFydEFuZ2xlXzEsIHN0YXJ0QW5nbGVfMSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZW5kU3RhdGU6IGZ1bmN0aW9uIChyYXRpbykge1xuICAgICAgICAgICAgICAgIHZhciBkaWZmID0gKGVuZEFuZ2xlXzEgLSBzdGFydEFuZ2xlXzEpICogcmF0aW8gKyBzdGFydEFuZ2xlXzE7XG4gICAgICAgICAgICAgICAgdmFyIHBhdGggPSBncmFwaGljc18xLmdldFNlY3RvclBhdGgoY2VudGVyXzEueCwgY2VudGVyXzEueSwgcmFkaXVzXzEgKyBtYXJnaW4sIHN0YXJ0QW5nbGVfMSwgZGlmZik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgcGF0aDogZ3JhcGhpY3NfMS5nZXRTZWN0b3JQYXRoKGNlbnRlcl8xLngsIGNlbnRlcl8xLnksIHJhZGl1c18xICsgbWFyZ2luLCBzdGFydEFuZ2xlXzEsIGVuZEFuZ2xlXzEpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgdmFyIGVuZFN0YXRlO1xuICAgIGlmIChjb29yZGluYXRlLmlzVHJhbnNwb3NlZCkge1xuICAgICAgICBlbmRTdGF0ZSA9IHtcbiAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0ICsgbWFyZ2luICogMixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGVuZFN0YXRlID0ge1xuICAgICAgICAgICAgd2lkdGg6IHdpZHRoICsgbWFyZ2luICogMixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICBzdGFydFN0YXRlOiB7XG4gICAgICAgICAgICB4OiBzdGFydC54IC0gbWFyZ2luLFxuICAgICAgICAgICAgeTogZW5kLnkgLSBtYXJnaW4sXG4gICAgICAgICAgICB3aWR0aDogY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQgPyB3aWR0aCArIG1hcmdpbiAqIDIgOiAwLFxuICAgICAgICAgICAgaGVpZ2h0OiBjb29yZGluYXRlLmlzVHJhbnNwb3NlZCA/IDAgOiBoZWlnaHQgKyBtYXJnaW4gKiAyLFxuICAgICAgICB9LFxuICAgICAgICBlbmRTdGF0ZTogZW5kU3RhdGUsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB4OiBzdGFydC54IC0gbWFyZ2luLFxuICAgICAgICAgICAgeTogZW5kLnkgLSBtYXJnaW4sXG4gICAgICAgICAgICB3aWR0aDogd2lkdGggKyBtYXJnaW4gKiAyLFxuICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBtYXJnaW4gKiAyLFxuICAgICAgICB9LFxuICAgIH07XG59XG5leHBvcnRzLmdldENvb3JkaW5hdGVDbGlwQ2ZnID0gZ2V0Q29vcmRpbmF0ZUNsaXBDZmc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb29yZGluYXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRUcmFuc2xhdGVEaXJlY3Rpb24gPSBleHBvcnRzLmRpcmVjdGlvblRvUG9zaXRpb24gPSB2b2lkIDA7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog5pa55L2N5bi46YeP6L2s5a6e6ZmF55qEIGJib3gg5L2N572u5aSn5bCPXG4gKiBAcGFyYW0gcGFyZW50QkJveFxuICogQHBhcmFtIGJib3hcbiAqIEBwYXJhbSBkaXJlY3Rpb25cbiAqL1xuZnVuY3Rpb24gZGlyZWN0aW9uVG9Qb3NpdGlvbihwYXJlbnRCQm94LCBiYm94LCBkaXJlY3Rpb24pIHtcbiAgICBpZiAoZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5UT1ApIHtcbiAgICAgICAgcmV0dXJuIFtwYXJlbnRCQm94Lm1pblggKyBwYXJlbnRCQm94LndpZHRoIC8gMiAtIGJib3gud2lkdGggLyAyLCBwYXJlbnRCQm94Lm1pblldO1xuICAgIH1cbiAgICBpZiAoZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT00pIHtcbiAgICAgICAgcmV0dXJuIFtwYXJlbnRCQm94Lm1pblggKyBwYXJlbnRCQm94LndpZHRoIC8gMiAtIGJib3gud2lkdGggLyAyLCBwYXJlbnRCQm94Lm1heFkgLSBiYm94LmhlaWdodF07XG4gICAgfVxuICAgIGlmIChkaXJlY3Rpb24gPT09IGNvbnN0YW50XzEuRElSRUNUSU9OLkxFRlQpIHtcbiAgICAgICAgcmV0dXJuIFtwYXJlbnRCQm94Lm1pblgsIHBhcmVudEJCb3gubWluWSArIHBhcmVudEJCb3guaGVpZ2h0IC8gMiAtIGJib3guaGVpZ2h0IC8gMl07XG4gICAgfVxuICAgIGlmIChkaXJlY3Rpb24gPT09IGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUKSB7XG4gICAgICAgIHJldHVybiBbcGFyZW50QkJveC5tYXhYIC0gYmJveC53aWR0aCwgcGFyZW50QkJveC5taW5ZICsgcGFyZW50QkJveC5oZWlnaHQgLyAyIC0gYmJveC5oZWlnaHQgLyAyXTtcbiAgICB9XG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gY29uc3RhbnRfMS5ESVJFQ1RJT04uVE9QX0xFRlQgfHwgZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUX1RPUCkge1xuICAgICAgICByZXR1cm4gW3BhcmVudEJCb3gudGwueCwgcGFyZW50QkJveC50bC55XTtcbiAgICB9XG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gY29uc3RhbnRfMS5ESVJFQ1RJT04uVE9QX1JJR0hUIHx8IGRpcmVjdGlvbiA9PT0gY29uc3RhbnRfMS5ESVJFQ1RJT04uUklHSFRfVE9QKSB7XG4gICAgICAgIHJldHVybiBbcGFyZW50QkJveC50ci54IC0gYmJveC53aWR0aCwgcGFyZW50QkJveC50ci55XTtcbiAgICB9XG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gY29uc3RhbnRfMS5ESVJFQ1RJT04uQk9UVE9NX0xFRlQgfHwgZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUX0JPVFRPTSkge1xuICAgICAgICByZXR1cm4gW3BhcmVudEJCb3guYmwueCwgcGFyZW50QkJveC5ibC55IC0gYmJveC5oZWlnaHRdO1xuICAgIH1cbiAgICBpZiAoZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT01fUklHSFQgfHwgZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVF9CT1RUT00pIHtcbiAgICAgICAgcmV0dXJuIFtwYXJlbnRCQm94LmJyLnggLSBiYm94LndpZHRoLCBwYXJlbnRCQm94LmJyLnkgLSBiYm94LmhlaWdodF07XG4gICAgfVxuICAgIHJldHVybiBbMCwgMF07XG59XG5leHBvcnRzLmRpcmVjdGlvblRvUG9zaXRpb24gPSBkaXJlY3Rpb25Ub1Bvc2l0aW9uO1xuLyoqXG4gKiBnZXQgZGlyZWN0aW9uIGFmdGVyIGNvb3JkaW5hdGUgdHJhbnNwb3NlXG4gKiBAcGFyYW0gZGlyZWN0aW9uXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHJldHVybnMgZGlyZWN0aW9uIGFmdGVyIHRyYW5zcG9zZSBvciBub3RcbiAqL1xuZnVuY3Rpb24gZ2V0VHJhbnNwb3NlZERpcmVjdGlvbihkaXJlY3Rpb24sIGNvb3JkaW5hdGUpIHtcbiAgICBpZiAoY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIGNhc2UgY29uc3RhbnRfMS5ESVJFQ1RJT04uQk9UVE9NOlxuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUO1xuICAgICAgICAgICAgY2FzZSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUOlxuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT007XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUOlxuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdGFudF8xLkRJUkVDVElPTi5UT1A7XG4gICAgICAgICAgICBjYXNlIGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUDpcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uc3RhbnRfMS5ESVJFQ1RJT04uUklHSFQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRpcmVjdGlvbjtcbn1cbmZ1bmN0aW9uIHJlZmxlY3RYKGRpcmVjdCkge1xuICAgIGlmIChkaXJlY3QgPT09IGNvbnN0YW50XzEuRElSRUNUSU9OLkxFRlQpIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0YW50XzEuRElSRUNUSU9OLlJJR0hUO1xuICAgIH1cbiAgICBpZiAoZGlyZWN0ID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVCkge1xuICAgICAgICByZXR1cm4gY29uc3RhbnRfMS5ESVJFQ1RJT04uTEVGVDtcbiAgICB9XG4gICAgcmV0dXJuIGRpcmVjdDtcbn1cbmZ1bmN0aW9uIHJlZmxlY3RZKGRpcmVjdCkge1xuICAgIGlmIChkaXJlY3QgPT09IGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUCkge1xuICAgICAgICByZXR1cm4gY29uc3RhbnRfMS5ESVJFQ1RJT04uQk9UVE9NO1xuICAgIH1cbiAgICBpZiAoZGlyZWN0ID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5CT1RUT00pIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0YW50XzEuRElSRUNUSU9OLlRPUDtcbiAgICB9XG4gICAgcmV0dXJuIGRpcmVjdDtcbn1cbi8qKlxuICogZ2V0IGRpcmVjdGlvbiBhZnRlciBjb29yZGluYXRlLnNjYWxlXG4gKiBAcGFyYW0gZGlyZWN0aW9uXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICovXG5mdW5jdGlvbiBnZXRTY2FsZURpcmVjdGlvbihkaXJlY3Rpb24sIGNvb3JkaW5hdGUpIHtcbiAgICB2YXIgeCA9IGNvb3JkaW5hdGUubWF0cml4WzBdO1xuICAgIHZhciB5ID0gY29vcmRpbmF0ZS5tYXRyaXhbNF07XG4gICAgdmFyIGQgPSBkaXJlY3Rpb247XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICAgIGQgPSByZWZsZWN0WChkKTtcbiAgICB9XG4gICAgaWYgKHkgPCAwKSB7XG4gICAgICAgIGQgPSByZWZsZWN0WShkKTtcbiAgICB9XG4gICAgcmV0dXJuIGQ7XG59XG4vKipcbiAqXG4gKiBAcGFyYW0gZGlyZWN0aW9uXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICovXG5mdW5jdGlvbiBnZXRSZWZsZWN0RGlyZWN0aW9uKGRpcmVjdGlvbiwgY29vcmRpbmF0ZSkge1xuICAgIHZhciBkID0gZGlyZWN0aW9uO1xuICAgIGlmIChjb29yZGluYXRlLmlzUmVmbGVjdCgneCcpKSB7XG4gICAgICAgIGQgPSByZWZsZWN0WChkKTtcbiAgICB9XG4gICAgaWYgKGNvb3JkaW5hdGUuaXNSZWZsZWN0KCd5JykpIHtcbiAgICAgICAgZCA9IHJlZmxlY3RZKGQpO1xuICAgIH1cbiAgICByZXR1cm4gZDtcbn1cbi8qKlxuICogQGlnbm9yZVxuICogZ2V0IGRpcmVjdGlvbiBhZnRlciBjb29yZGluYXRlIHRyYW5zbGF0ZVxuICogQHBhcmFtIGRpcmVjdGlvblxuICogQHBhcmFtIGNvb3JkaW5hdGVcbiAqL1xuZnVuY3Rpb24gZ2V0VHJhbnNsYXRlRGlyZWN0aW9uKGRpcmVjdGlvbiwgY29vcmRpbmF0ZSkge1xuICAgIHZhciBkID0gZGlyZWN0aW9uO1xuICAgIGQgPSBnZXRUcmFuc3Bvc2VkRGlyZWN0aW9uKGQsIGNvb3JkaW5hdGUpO1xuICAgIGQgPSBnZXRTY2FsZURpcmVjdGlvbihkLCBjb29yZGluYXRlKTtcbiAgICBkID0gZ2V0UmVmbGVjdERpcmVjdGlvbihkLCBjb29yZGluYXRlKTtcbiAgICByZXR1cm4gZDtcbn1cbmV4cG9ydHMuZ2V0VHJhbnNsYXRlRGlyZWN0aW9uID0gZ2V0VHJhbnNsYXRlRGlyZWN0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGlyZWN0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5yZW1vdmVEb20gPSBleHBvcnRzLmdldENoYXJ0U2l6ZSA9IHZvaWQgMDtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xuLyoqXG4gKiBnZXQgdGhlIGVsZW1lbnQncyBib3VuZGluZyBzaXplXG4gKiBAcGFyYW0gZWxlIGRvbSBlbGVtZW50XG4gKiBAcmV0dXJucyB0aGUgZWxlbWVudCB3aWR0aCBhbmQgaGVpZ2h0XG4gKi9cbmZ1bmN0aW9uIGdldEVsZW1lbnRTaXplKGVsZSkge1xuICAgIHZhciBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlKTtcbiAgICByZXR1cm4ge1xuICAgICAgICB3aWR0aDogKGVsZS5jbGllbnRXaWR0aCB8fCBwYXJzZUludChzdHlsZS53aWR0aCwgMTApKSAtXG4gICAgICAgICAgICBwYXJzZUludChzdHlsZS5wYWRkaW5nTGVmdCwgMTApIC1cbiAgICAgICAgICAgIHBhcnNlSW50KHN0eWxlLnBhZGRpbmdSaWdodCwgMTApLFxuICAgICAgICBoZWlnaHQ6IChlbGUuY2xpZW50SGVpZ2h0IHx8IHBhcnNlSW50KHN0eWxlLmhlaWdodCwgMTApKSAtXG4gICAgICAgICAgICBwYXJzZUludChzdHlsZS5wYWRkaW5nVG9wLCAxMCkgLVxuICAgICAgICAgICAgcGFyc2VJbnQoc3R5bGUucGFkZGluZ0JvdHRvbSwgMTApLFxuICAgIH07XG59XG4vKipcbiAqIGlzIHZhbHVlIGEgdmFsaWQgbnVtYmVyXG4gKiBAcGFyYW0gdiB0aGUgaW5wdXQgdmFsdWVcbiAqIEByZXR1cm5zIHdoZXRoZXIgaXQgaXMgYSBudW1iZXJcbiAqL1xuZnVuY3Rpb24gaXNOdW1iZXIodikge1xuICAgIHJldHVybiB0eXBlb2YgdiA9PT0gJ251bWJlcicgJiYgIWlzTmFOKHYpO1xufVxuLyoqXG4gKiBAaWdub3JlXG4gKiBjYWxjdWxhdGUgdGhlIGNoYXJ0IHNpemVcbiAqIEBwYXJhbSBlbGUgRE9NIGVsZW1lbnRcbiAqIEBwYXJhbSBhdXRvRml0IHNob3VsZCBhdXRvIGZpdFxuICogQHBhcmFtIHdpZHRoIGNoYXJ0IHdpZHRoIHdoaWNoIGlzIHNldCBieSB1c2VyXG4gKiBAcGFyYW0gaGVpZ2h0IGNoYXJ0IGhlaWdodCB3aGljaCBpcyBzZXQgYnkgdXNlclxuICogQHJldHVybnMgdGhlIGNoYXJ0IHdpZHRoIGFuZCBoZWlnaHRcbiAqL1xuZnVuY3Rpb24gZ2V0Q2hhcnRTaXplKGVsZSwgYXV0b0ZpdCwgd2lkdGgsIGhlaWdodCkge1xuICAgIHZhciB3ID0gd2lkdGg7XG4gICAgdmFyIGggPSBoZWlnaHQ7XG4gICAgaWYgKGF1dG9GaXQpIHtcbiAgICAgICAgdmFyIHNpemUgPSBnZXRFbGVtZW50U2l6ZShlbGUpO1xuICAgICAgICB3ID0gc2l6ZS53aWR0aCA/IHNpemUud2lkdGggOiB3O1xuICAgICAgICBoID0gc2l6ZS5oZWlnaHQgPyBzaXplLmhlaWdodCA6IGg7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoOiBNYXRoLm1heChpc051bWJlcih3KSA/IHcgOiBjb25zdGFudF8xLk1JTl9DSEFSVF9XSURUSCwgY29uc3RhbnRfMS5NSU5fQ0hBUlRfV0lEVEgpLFxuICAgICAgICBoZWlnaHQ6IE1hdGgubWF4KGlzTnVtYmVyKGgpID8gaCA6IGNvbnN0YW50XzEuTUlOX0NIQVJUX0hFSUdIVCwgY29uc3RhbnRfMS5NSU5fQ0hBUlRfSEVJR0hUKSxcbiAgICB9O1xufVxuZXhwb3J0cy5nZXRDaGFydFNpemUgPSBnZXRDaGFydFNpemU7XG4vKipcbiAqIEBpZ25vcmVcbiAqIHJlbW92ZSBodG1sIGVsZW1lbnQgZnJvbSBpdHMgcGFyZW50XG4gKiBAcGFyYW0gZG9tXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZURvbShkb20pIHtcbiAgICB2YXIgcGFyZW50ID0gZG9tLnBhcmVudE5vZGU7XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZG9tKTtcbiAgICB9XG59XG5leHBvcnRzLnJlbW92ZURvbSA9IHJlbW92ZURvbTtcbi8qKiBAaWdub3JlICovXG52YXIgZG9tX3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9kb20tdXRpbFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImNyZWF0ZURvbVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZG9tX3V0aWxfMS5jcmVhdGVEb207IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJtb2RpZnlDU1NcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRvbV91dGlsXzEubW9kaWZ5Q1NTOyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZG9tLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRBbmdsZVBvaW50ID0gZXhwb3J0cy5nZXRGYWN0VGl0bGVDb25maWcgPSB2b2lkIDA7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICog6I635Y+WIGZhY2V0IHRpdGxlIOeahOacgOS9s+m7mOiupOmFjee9ru+8jOmYsuatolxuICovXG5mdW5jdGlvbiBnZXRGYWN0VGl0bGVDb25maWcoZGlyZWN0aW9uKSB7XG4gICAgaWYgKFtjb25zdGFudF8xLkRJUkVDVElPTi5UT1AsIGNvbnN0YW50XzEuRElSRUNUSU9OLkJPVFRPTV0uaW5jbHVkZXMoZGlyZWN0aW9uKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2Zmc2V0WDogMCxcbiAgICAgICAgICAgIG9mZnNldFk6IGRpcmVjdGlvbiA9PT0gY29uc3RhbnRfMS5ESVJFQ1RJT04uVE9QID8gLTggOiA4LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5UT1AgPyAnYm90dG9tJyA6ICd0b3AnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKFtjb25zdGFudF8xLkRJUkVDVElPTi5MRUZULCBjb25zdGFudF8xLkRJUkVDVElPTi5SSUdIVF0uaW5jbHVkZXMoZGlyZWN0aW9uKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2Zmc2V0WDogZGlyZWN0aW9uID09PSBjb25zdGFudF8xLkRJUkVDVElPTi5MRUZUID8gLTggOiA4LFxuICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiBkaXJlY3Rpb24gPT09IGNvbnN0YW50XzEuRElSRUNUSU9OLkxFRlQgPyAncmlnaHQnIDogJ2xlZnQnLFxuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZScsXG4gICAgICAgICAgICAgICAgcm90YXRlOiBNYXRoLlBJIC8gMixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7fTtcbn1cbmV4cG9ydHMuZ2V0RmFjdFRpdGxlQ29uZmlnID0gZ2V0RmFjdFRpdGxlQ29uZmlnO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmoLnmja7op5LluqbvvIzojrflj5Yg4peLIOS4iueahOeCuVxuICogQHBhcmFtIGNlbnRlclxuICogQHBhcmFtIHJcbiAqIEBwYXJhbSBhbmdsZVxuICovXG5mdW5jdGlvbiBnZXRBbmdsZVBvaW50KGNlbnRlciwgciwgYW5nbGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBjZW50ZXIueCArIHIgKiBNYXRoLmNvcyhhbmdsZSksXG4gICAgICAgIHk6IGNlbnRlci55ICsgciAqIE1hdGguc2luKGFuZ2xlKSxcbiAgICB9O1xufVxuZXhwb3J0cy5nZXRBbmdsZVBvaW50ID0gZ2V0QW5nbGVQb2ludDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZhY2V0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRSZXBsYWNlQXR0cnMgPSBleHBvcnRzLmdldFBvbHlnb25DZW50cm9pZCA9IGV4cG9ydHMuZ2V0QW5nbGUgPSBleHBvcnRzLmdldEFyY1BhdGggPSBleHBvcnRzLmdldFNlY3RvclBhdGggPSBleHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4gPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vLyDojrflj5blm77lvaLnmoTljIXlm7Tnm5JcbmZ1bmN0aW9uIGdldFBvaW50c0JveChwb2ludHMpIHtcbiAgICBpZiAodXRpbF8xLmlzRW1wdHkocG9pbnRzKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIG1pblggPSBwb2ludHNbMF0ueDtcbiAgICB2YXIgbWF4WCA9IHBvaW50c1swXS54O1xuICAgIHZhciBtaW5ZID0gcG9pbnRzWzBdLnk7XG4gICAgdmFyIG1heFkgPSBwb2ludHNbMF0ueTtcbiAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICBtaW5YID0gbWluWCA+IHBvaW50LnggPyBwb2ludC54IDogbWluWDtcbiAgICAgICAgbWF4WCA9IG1heFggPCBwb2ludC54ID8gcG9pbnQueCA6IG1heFg7XG4gICAgICAgIG1pblkgPSBtaW5ZID4gcG9pbnQueSA/IHBvaW50LnkgOiBtaW5ZO1xuICAgICAgICBtYXhZID0gbWF4WSA8IHBvaW50LnkgPyBwb2ludC55IDogbWF4WTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW5YOiBtaW5YLFxuICAgICAgICBtYXhYOiBtYXhYLFxuICAgICAgICBtaW5ZOiBtaW5ZLFxuICAgICAgICBtYXhZOiBtYXhZLFxuICAgICAgICBjZW50ZXJYOiAobWluWCArIG1heFgpIC8gMixcbiAgICAgICAgY2VudGVyWTogKG1pblkgKyBtYXhZKSAvIDIsXG4gICAgfTtcbn1cbi8qKlxuICogQGlnbm9yZVxuICog5qC55o2u5byn5bqm6K6h566X5p6B5Z2Q5qCH57O75LiL55qE5Z2Q5qCH54K5XG4gKiBAcGFyYW0gY2VudGVyWFxuICogQHBhcmFtIGNlbnRlcllcbiAqIEBwYXJhbSByYWRpdXNcbiAqIEBwYXJhbSBhbmdsZUluUmFkaWFuXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBwb2xhclRvQ2FydGVzaWFuKGNlbnRlclgsIGNlbnRlclksIHJhZGl1cywgYW5nbGVJblJhZGlhbikge1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IGNlbnRlclggKyByYWRpdXMgKiBNYXRoLmNvcyhhbmdsZUluUmFkaWFuKSxcbiAgICAgICAgeTogY2VudGVyWSArIHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlSW5SYWRpYW4pLFxuICAgIH07XG59XG5leHBvcnRzLnBvbGFyVG9DYXJ0ZXNpYW4gPSBwb2xhclRvQ2FydGVzaWFuO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmoLnmja7otbflp4vop5LluqborqHnrpfnu5jliLbmiYflvaLnmoQgcGF0aFxuICogQHBhcmFtIGNlbnRlclhcbiAqIEBwYXJhbSBjZW50ZXJZXG4gKiBAcGFyYW0gcmFkaXVzXG4gKiBAcGFyYW0gc3RhcnRBbmdsZUluUmFkaWFuXG4gKiBAcGFyYW0gZW5kQW5nbGVJblJhZGlhblxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0U2VjdG9yUGF0aChjZW50ZXJYLCBjZW50ZXJZLCByYWRpdXMsIHN0YXJ0QW5nbGVJblJhZGlhbiwgZW5kQW5nbGVJblJhZGlhbiwgaW5uZXJSYWRpdXMpIHtcbiAgICBpZiAoaW5uZXJSYWRpdXMgPT09IHZvaWQgMCkgeyBpbm5lclJhZGl1cyA9IDA7IH1cbiAgICB2YXIgc3RhcnQgPSBwb2xhclRvQ2FydGVzaWFuKGNlbnRlclgsIGNlbnRlclksIHJhZGl1cywgc3RhcnRBbmdsZUluUmFkaWFuKTtcbiAgICB2YXIgZW5kID0gcG9sYXJUb0NhcnRlc2lhbihjZW50ZXJYLCBjZW50ZXJZLCByYWRpdXMsIGVuZEFuZ2xlSW5SYWRpYW4pO1xuICAgIHZhciBpbm5lclN0YXJ0ID0gcG9sYXJUb0NhcnRlc2lhbihjZW50ZXJYLCBjZW50ZXJZLCBpbm5lclJhZGl1cywgc3RhcnRBbmdsZUluUmFkaWFuKTtcbiAgICB2YXIgaW5uZXJFbmQgPSBwb2xhclRvQ2FydGVzaWFuKGNlbnRlclgsIGNlbnRlclksIGlubmVyUmFkaXVzLCBlbmRBbmdsZUluUmFkaWFuKTtcbiAgICBpZiAoZW5kQW5nbGVJblJhZGlhbiAtIHN0YXJ0QW5nbGVJblJhZGlhbiA9PT0gTWF0aC5QSSAqIDIpIHtcbiAgICAgICAgLy8g5pW05Liq5ZyG5piv5YiG5Ymy5oiQ5Lik5Liq5ZyGXG4gICAgICAgIHZhciBtaWRkbGVQb2ludCA9IHBvbGFyVG9DYXJ0ZXNpYW4oY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBzdGFydEFuZ2xlSW5SYWRpYW4gKyBNYXRoLlBJKTtcbiAgICAgICAgdmFyIGlubmVyTWlkZGxlUG9pbnQgPSBwb2xhclRvQ2FydGVzaWFuKGNlbnRlclgsIGNlbnRlclksIGlubmVyUmFkaXVzLCBzdGFydEFuZ2xlSW5SYWRpYW4gKyBNYXRoLlBJKTtcbiAgICAgICAgdmFyIGNpcmNsZVBhdGhDb21tYW5kcyA9IFtcbiAgICAgICAgICAgIFsnTScsIHN0YXJ0LngsIHN0YXJ0LnldLFxuICAgICAgICAgICAgWydBJywgcmFkaXVzLCByYWRpdXMsIDAsIDEsIDEsIG1pZGRsZVBvaW50LngsIG1pZGRsZVBvaW50LnldLFxuICAgICAgICAgICAgWydBJywgcmFkaXVzLCByYWRpdXMsIDAsIDEsIDEsIGVuZC54LCBlbmQueV0sXG4gICAgICAgICAgICBbJ00nLCBpbm5lclN0YXJ0LngsIGlubmVyU3RhcnQueV0sXG4gICAgICAgIF07XG4gICAgICAgIGlmIChpbm5lclJhZGl1cykge1xuICAgICAgICAgICAgY2lyY2xlUGF0aENvbW1hbmRzLnB1c2goWydBJywgaW5uZXJSYWRpdXMsIGlubmVyUmFkaXVzLCAwLCAxLCAwLCBpbm5lck1pZGRsZVBvaW50LngsIGlubmVyTWlkZGxlUG9pbnQueV0pO1xuICAgICAgICAgICAgY2lyY2xlUGF0aENvbW1hbmRzLnB1c2goWydBJywgaW5uZXJSYWRpdXMsIGlubmVyUmFkaXVzLCAwLCAxLCAwLCBpbm5lckVuZC54LCBpbm5lckVuZC55XSk7XG4gICAgICAgIH1cbiAgICAgICAgY2lyY2xlUGF0aENvbW1hbmRzLnB1c2goWydNJywgc3RhcnQueCwgc3RhcnQueV0pO1xuICAgICAgICBjaXJjbGVQYXRoQ29tbWFuZHMucHVzaChbJ1onXSk7XG4gICAgICAgIHJldHVybiBjaXJjbGVQYXRoQ29tbWFuZHM7XG4gICAgfVxuICAgIHZhciBhcmNTd2VlcCA9IGVuZEFuZ2xlSW5SYWRpYW4gLSBzdGFydEFuZ2xlSW5SYWRpYW4gPD0gTWF0aC5QSSA/IDAgOiAxO1xuICAgIHZhciBzZWN0b3JQYXRoQ29tbWFuZHMgPSBbXG4gICAgICAgIFsnTScsIHN0YXJ0LngsIHN0YXJ0LnldLFxuICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgYXJjU3dlZXAsIDEsIGVuZC54LCBlbmQueV0sXG4gICAgICAgIFsnTCcsIGlubmVyRW5kLngsIGlubmVyRW5kLnldLFxuICAgIF07XG4gICAgaWYgKGlubmVyUmFkaXVzKSB7XG4gICAgICAgIHNlY3RvclBhdGhDb21tYW5kcy5wdXNoKFsnQScsIGlubmVyUmFkaXVzLCBpbm5lclJhZGl1cywgMCwgYXJjU3dlZXAsIDAsIGlubmVyU3RhcnQueCwgaW5uZXJTdGFydC55XSk7XG4gICAgfVxuICAgIHNlY3RvclBhdGhDb21tYW5kcy5wdXNoKFsnTCcsIHN0YXJ0LngsIHN0YXJ0LnldKTtcbiAgICBzZWN0b3JQYXRoQ29tbWFuZHMucHVzaChbJ1onXSk7XG4gICAgcmV0dXJuIHNlY3RvclBhdGhDb21tYW5kcztcbn1cbmV4cG9ydHMuZ2V0U2VjdG9yUGF0aCA9IGdldFNlY3RvclBhdGg7XG4vKipcbiAqIEBpZ25vcmVcbiAqIEdldHMgYXJjIHBhdGhcbiAqIEBwYXJhbSBjZW50ZXJYXG4gKiBAcGFyYW0gY2VudGVyWVxuICogQHBhcmFtIHJhZGl1c1xuICogQHBhcmFtIHN0YXJ0QW5nbGVJblJhZGlhblxuICogQHBhcmFtIGVuZEFuZ2xlSW5SYWRpYW5cbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldEFyY1BhdGgoY2VudGVyWCwgY2VudGVyWSwgcmFkaXVzLCBzdGFydEFuZ2xlSW5SYWRpYW4sIGVuZEFuZ2xlSW5SYWRpYW4pIHtcbiAgICB2YXIgc3RhcnQgPSBwb2xhclRvQ2FydGVzaWFuKGNlbnRlclgsIGNlbnRlclksIHJhZGl1cywgc3RhcnRBbmdsZUluUmFkaWFuKTtcbiAgICB2YXIgZW5kID0gcG9sYXJUb0NhcnRlc2lhbihjZW50ZXJYLCBjZW50ZXJZLCByYWRpdXMsIGVuZEFuZ2xlSW5SYWRpYW4pO1xuICAgIGlmICh1dGlsXzEuaXNOdW1iZXJFcXVhbChlbmRBbmdsZUluUmFkaWFuIC0gc3RhcnRBbmdsZUluUmFkaWFuLCBNYXRoLlBJICogMikpIHtcbiAgICAgICAgdmFyIG1pZGRsZVBvaW50ID0gcG9sYXJUb0NhcnRlc2lhbihjZW50ZXJYLCBjZW50ZXJZLCByYWRpdXMsIHN0YXJ0QW5nbGVJblJhZGlhbiArIE1hdGguUEkpO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgWydNJywgc3RhcnQueCwgc3RhcnQueV0sXG4gICAgICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgMSwgMSwgbWlkZGxlUG9pbnQueCwgbWlkZGxlUG9pbnQueV0sXG4gICAgICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgMSwgMSwgc3RhcnQueCwgc3RhcnQueV0sXG4gICAgICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgMSwgMCwgbWlkZGxlUG9pbnQueCwgbWlkZGxlUG9pbnQueV0sXG4gICAgICAgICAgICBbJ0EnLCByYWRpdXMsIHJhZGl1cywgMCwgMSwgMCwgc3RhcnQueCwgc3RhcnQueV0sXG4gICAgICAgICAgICBbJ1onXSxcbiAgICAgICAgXTtcbiAgICB9XG4gICAgdmFyIGFyY1N3ZWVwID0gZW5kQW5nbGVJblJhZGlhbiAtIHN0YXJ0QW5nbGVJblJhZGlhbiA8PSBNYXRoLlBJID8gMCA6IDE7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgWydNJywgc3RhcnQueCwgc3RhcnQueV0sXG4gICAgICAgIFsnQScsIHJhZGl1cywgcmFkaXVzLCAwLCBhcmNTd2VlcCwgMSwgZW5kLngsIGVuZC55XSxcbiAgICBdO1xufVxuZXhwb3J0cy5nZXRBcmNQYXRoID0gZ2V0QXJjUGF0aDtcbi8qKlxuICogQGlnbm9yZVxuICog5LuO5pWw5o2u5qih5Z6L5Lit55qEIHBvaW50cyDmjaLnrpfop5LluqZcbiAqIEBwYXJhbSBzaGFwZU1vZGVsXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0QW5nbGUoc2hhcGVNb2RlbCwgY29vcmRpbmF0ZSkge1xuICAgIHZhciBwb2ludHMgPSBzaGFwZU1vZGVsLnBvaW50cztcbiAgICB2YXIgYm94ID0gZ2V0UG9pbnRzQm94KHBvaW50cyk7XG4gICAgdmFyIGVuZEFuZ2xlO1xuICAgIHZhciBzdGFydEFuZ2xlO1xuICAgIHZhciBjb29yZFN0YXJ0QW5nbGUgPSBjb29yZGluYXRlLnN0YXJ0QW5nbGUsIGNvb3JkRW5kQW5nbGUgPSBjb29yZGluYXRlLmVuZEFuZ2xlO1xuICAgIHZhciBkaWZmQW5nbGUgPSBjb29yZEVuZEFuZ2xlIC0gY29vcmRTdGFydEFuZ2xlO1xuICAgIGlmIChjb29yZGluYXRlLmlzVHJhbnNwb3NlZCkge1xuICAgICAgICBlbmRBbmdsZSA9IGJveC5tYXhZICogZGlmZkFuZ2xlO1xuICAgICAgICBzdGFydEFuZ2xlID0gYm94Lm1pblkgKiBkaWZmQW5nbGU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBlbmRBbmdsZSA9IGJveC5tYXhYICogZGlmZkFuZ2xlO1xuICAgICAgICBzdGFydEFuZ2xlID0gYm94Lm1pblggKiBkaWZmQW5nbGU7XG4gICAgfVxuICAgIGVuZEFuZ2xlICs9IGNvb3JkU3RhcnRBbmdsZTtcbiAgICBzdGFydEFuZ2xlICs9IGNvb3JkU3RhcnRBbmdsZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydEFuZ2xlOiBzdGFydEFuZ2xlLFxuICAgICAgICBlbmRBbmdsZTogZW5kQW5nbGUsXG4gICAgfTtcbn1cbmV4cG9ydHMuZ2V0QW5nbGUgPSBnZXRBbmdsZTtcbi8qKlxuICogQGlnbm9yZVxuICog6K6h566X5aSa6L655b2i6YeN5b+DOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9DZW50cm9pZCNPZl9hX3BvbHlnb25cbiAqL1xuZnVuY3Rpb24gZ2V0UG9seWdvbkNlbnRyb2lkKHhzLCB5cykge1xuICAgIGlmICh1dGlsXzEuaXNOdW1iZXIoeHMpICYmIHV0aWxfMS5pc051bWJlcih5cykpIHtcbiAgICAgICAgLy8g5pmu6YCa6Imy5Z2X5Zu+77yMeHMg5ZKMIHlzIOaYr+aVsOWAvFxuICAgICAgICByZXR1cm4gW3hzLCB5c107XG4gICAgfVxuICAgIHZhciBpID0gLTE7XG4gICAgdmFyIHggPSAwO1xuICAgIHZhciB5ID0gMDtcbiAgICB2YXIgZm9ybWVyO1xuICAgIHZhciBjdXJyZW50ID0geHMubGVuZ3RoIC0gMTtcbiAgICB2YXIgZGlmZjtcbiAgICB2YXIgayA9IDA7XG4gICAgd2hpbGUgKCsraSA8IHhzLmxlbmd0aCkge1xuICAgICAgICBmb3JtZXIgPSBjdXJyZW50O1xuICAgICAgICBjdXJyZW50ID0gaTtcbiAgICAgICAgayArPSBkaWZmID0geHNbZm9ybWVyXSAqIHlzW2N1cnJlbnRdIC0geHNbY3VycmVudF0gKiB5c1tmb3JtZXJdO1xuICAgICAgICB4ICs9ICh4c1tmb3JtZXJdICsgeHNbY3VycmVudF0pICogZGlmZjtcbiAgICAgICAgeSArPSAoeXNbZm9ybWVyXSArIHlzW2N1cnJlbnRdKSAqIGRpZmY7XG4gICAgfVxuICAgIGsgKj0gMztcbiAgICByZXR1cm4gW3ggLyBrLCB5IC8ga107XG59XG5leHBvcnRzLmdldFBvbHlnb25DZW50cm9pZCA9IGdldFBvbHlnb25DZW50cm9pZDtcbi8qKlxuICogQGlnbm9yZVxuICog6I635Y+W6ZyA6KaB5pu/5o2i55qE5bGe5oCn77yM5aaC5p6c5Y6f5YWI5Zu+5b2i5YWD57Sg5a2Y5Zyo77yM6ICM5paw5Zu+5b2i5LiN5a2Y5Zyo77yM5YiZ6K6+572uIHVuZGVmaW5lZFxuICovXG5mdW5jdGlvbiBnZXRSZXBsYWNlQXR0cnMoc291cmNlU2hhcGUsIHRhcmdldFNoYXBlKSB7XG4gICAgdmFyIG9yaWdpbkF0dHJzID0gc291cmNlU2hhcGUuYXR0cigpO1xuICAgIHZhciBuZXdBdHRycyA9IHRhcmdldFNoYXBlLmF0dHIoKTtcbiAgICB1dGlsXzEuZWFjaChvcmlnaW5BdHRycywgZnVuY3Rpb24gKHYsIGspIHtcbiAgICAgICAgaWYgKG5ld0F0dHJzW2tdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5ld0F0dHJzW2tdID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld0F0dHJzO1xufVxuZXhwb3J0cy5nZXRSZXBsYWNlQXR0cnMgPSBnZXRSZXBsYWNlQXR0cnM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncmFwaGljcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuc2hvd0dyaWQgPSBleHBvcnRzLmdldENpcmNsZUdyaWRJdGVtcyA9IGV4cG9ydHMuZ2V0TGluZUdyaWRJdGVtcyA9IGV4cG9ydHMuZ2V0R3JpZFRoZW1lQ2ZnID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBnZXQgdGhlIGdyaWQgdGhlbWUgYnkgdHlwZVxuICogQHBhcmFtIHRoZW1lXG4gKiBAcGFyYW0gZGlyZWN0aW9uXG4gKiBAcmV0dXJucyB0aGVtZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gZ2V0R3JpZFRoZW1lQ2ZnKHRoZW1lLCBkaXJlY3Rpb24pIHtcbiAgICByZXR1cm4gdXRpbF8xLmdldCh0aGVtZSwgWydjb21wb25lbnRzJywgJ2F4aXMnLCBkaXJlY3Rpb24sICdncmlkJ10sIHt9KTtcbn1cbmV4cG9ydHMuZ2V0R3JpZFRoZW1lQ2ZnID0gZ2V0R3JpZFRoZW1lQ2ZnO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBnZXQgYXhpcyBncmlkIGl0ZW1zXG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHBhcmFtIHNjYWxlXG4gKiBAcGFyYW0gZGltXG4gKiBAcmV0dXJuIGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGdldExpbmVHcmlkSXRlbXMoY29vcmRpbmF0ZSwgc2NhbGUsIGRpbSwgYWxpZ25UaWNrKSB7XG4gICAgdmFyIGl0ZW1zID0gW107XG4gICAgdmFyIHRpY2tzID0gc2NhbGUuZ2V0VGlja3MoKTtcbiAgICBpZiAoY29vcmRpbmF0ZS5pc1BvbGFyKSB7XG4gICAgICAgIC8vIOihpeWFqCB0aWNrc1xuICAgICAgICB0aWNrcy5wdXNoKHtcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICB0aWNrVmFsdWU6ICcnLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdGlja3MucmVkdWNlKGZ1bmN0aW9uIChwcmVUaWNrLCBjdXJyZW50VGljaywgY3VycmVudEluZGV4KSB7XG4gICAgICAgIHZhciBjdXJyZW50VmFsdWUgPSBjdXJyZW50VGljay52YWx1ZTtcbiAgICAgICAgaWYgKGFsaWduVGljaykge1xuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGUuY29udmVydChkaW0gPT09ICd5JyA/IHsgeDogMCwgeTogY3VycmVudFZhbHVlIH0gOiB7IHg6IGN1cnJlbnRWYWx1ZSwgeTogMCB9KSxcbiAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZS5jb252ZXJ0KGRpbSA9PT0gJ3knID8geyB4OiAxLCB5OiBjdXJyZW50VmFsdWUgfSA6IHsgeDogY3VycmVudFZhbHVlLCB5OiAxIH0pLFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50SW5kZXgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJlVmFsdWUgPSBwcmVUaWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIHZhciBtaWRkbGVWYWx1ZSA9IChwcmVWYWx1ZSArIGN1cnJlbnRWYWx1ZSkgLyAyO1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGUuY29udmVydChkaW0gPT09ICd5JyA/IHsgeDogMCwgeTogbWlkZGxlVmFsdWUgfSA6IHsgeDogbWlkZGxlVmFsdWUsIHk6IDAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlLmNvbnZlcnQoZGltID09PSAneScgPyB7IHg6IDEsIHk6IG1pZGRsZVZhbHVlIH0gOiB7IHg6IG1pZGRsZVZhbHVlLCB5OiAxIH0pLFxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdXJyZW50VGljaztcbiAgICB9LCB0aWNrc1swXSk7XG4gICAgcmV0dXJuIGl0ZW1zO1xufVxuZXhwb3J0cy5nZXRMaW5lR3JpZEl0ZW1zID0gZ2V0TGluZUdyaWRJdGVtcztcbi8qKlxuICogQGlnbm9yZVxuICogZ2V0XG4gKiBAcGFyYW0gY29vcmRpbmF0ZVxuICogQHBhcmFtIHhTY2FsZVxuICogQHBhcmFtIHlTY2FsZVxuICogQHBhcmFtIGRpbVxuICogQHJldHVybnMgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0Q2lyY2xlR3JpZEl0ZW1zKGNvb3JkaW5hdGUsIHhTY2FsZSwgeVNjYWxlLCBhbGlnblRpY2ssIGRpbSkge1xuICAgIHZhciBjb3VudCA9IHhTY2FsZS52YWx1ZXMubGVuZ3RoO1xuICAgIHZhciBpdGVtcyA9IFtdO1xuICAgIHZhciB0aWNrcyA9IHlTY2FsZS5nZXRUaWNrcygpO1xuICAgIHRpY2tzLnJlZHVjZShmdW5jdGlvbiAocHJlVGljaywgY3VycmVudFRpY2spIHtcbiAgICAgICAgdmFyIHByZVZhbHVlID0gcHJlVGljayA/IHByZVRpY2sudmFsdWUgOiBjdXJyZW50VGljay52YWx1ZTsgLy8g5Y+q5pyJ5LiA6aG55pWw5o2u5pe25Y+W5b2T5YmN5YC8XG4gICAgICAgIHZhciBjdXJyZW50VmFsdWUgPSBjdXJyZW50VGljay52YWx1ZTtcbiAgICAgICAgdmFyIG1pZGRsZVZhbHVlID0gKHByZVZhbHVlICsgY3VycmVudFZhbHVlKSAvIDI7XG4gICAgICAgIGlmIChkaW0gPT09ICd4Jykge1xuICAgICAgICAgICAgLy8g5aaC5p6c5pivIHgg6L205L2c5Li65Y2K5b6E6L2077yM6YKj5LmI5Y+q6ZyA6KaB5Y+W5ZyG5byn5pS25bC+5Lik5Liq5Y2z5Y+vXG4gICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZS5jb252ZXJ0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IGFsaWduVGljayA/IGN1cnJlbnRWYWx1ZSA6IG1pZGRsZVZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGUuY29udmVydCh7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBhbGlnblRpY2sgPyBjdXJyZW50VmFsdWUgOiBtaWRkbGVWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IDEsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgIHBvaW50czogdXRpbF8xLm1hcChBcnJheShjb3VudCArIDEpLCBmdW5jdGlvbiAoX18sIGlkeCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29vcmRpbmF0ZS5jb252ZXJ0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IGlkeCAvIGNvdW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgeTogYWxpZ25UaWNrID8gY3VycmVudFZhbHVlIDogbWlkZGxlVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGN1cnJlbnRUaWNrO1xuICAgIH0sIHRpY2tzWzBdKTtcbiAgICByZXR1cm4gaXRlbXM7XG59XG5leHBvcnRzLmdldENpcmNsZUdyaWRJdGVtcyA9IGdldENpcmNsZUdyaWRJdGVtcztcbi8qKlxuICogQGlnbm9yZVxuICogc2hvdyBncmlkIG9yIG5vdFxuICogQHBhcmFtIGF4aXNUaGVtZVxuICogQHBhcmFtIGF4aXNPcHRpb25cbiAqL1xuZnVuY3Rpb24gc2hvd0dyaWQoYXhpc1RoZW1lLCBheGlzT3B0aW9uKSB7XG4gICAgdmFyIHVzZXJHcmlkID0gdXRpbF8xLmdldChheGlzT3B0aW9uLCAnZ3JpZCcpO1xuICAgIGlmICh1c2VyR3JpZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciB0aGVtZUdyaWQgPSB1dGlsXzEuZ2V0KGF4aXNUaGVtZSwgJ2dyaWQnKTtcbiAgICByZXR1cm4gISh1c2VyR3JpZCA9PT0gdW5kZWZpbmVkICYmIHRoZW1lR3JpZCA9PT0gbnVsbCk7XG59XG5leHBvcnRzLnNob3dHcmlkID0gc2hvd0dyaWQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncmlkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy51bmlxID0gZXhwb3J0cy5vbWl0ID0gZXhwb3J0cy5wYWRFbmQgPSBleHBvcnRzLmlzQmV0d2VlbiA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKlxuICogQGlnbm9yZVxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGJldHdlZW4gaXNcbiAqIEBwYXJhbSB2YWx1ZVxuICogQHBhcmFtIHN0YXJ0XG4gKiBAcGFyYW0gZW5kXG4gKiBAcmV0dXJucyB0cnVlIGlmIGJldHdlZW5cbiAqL1xuZnVuY3Rpb24gaXNCZXR3ZWVuKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gICAgdmFyIG1pbiA9IE1hdGgubWluKHN0YXJ0LCBlbmQpO1xuICAgIHZhciBtYXggPSBNYXRoLm1heChzdGFydCwgZW5kKTtcbiAgICByZXR1cm4gdmFsdWUgPj0gbWluICYmIHZhbHVlIDw9IG1heDtcbn1cbmV4cG9ydHMuaXNCZXR3ZWVuID0gaXNCZXR3ZWVuO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBwYWRzIHRoZSBjdXJyZW50IHN0cmluZy9hcnJheSB3aXRoIGEgZ2l2ZW4gdmFsdWUgKHJlcGVhdGVkLCBpZiBuZWVkZWQpIHNvIHRoYXQgdGhlIHJlc3VsdGluZyByZWFjaGVzIGEgZ2l2ZW4gbGVuZ3RoLlxuICogVGhlIHBhZGRpbmcgaXMgYXBwbGllZCBmcm9tIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgdmFsdWUuXG4gKlxuICogQHBhcmFtIHNvdXJjZVxuICogQHBhcmFtIHRhcmdldExlbmd0aFxuICogQHBhcmFtIHBhZFZhbHVlXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBwYWRFbmQoc291cmNlLCB0YXJnZXRMZW5ndGgsIHBhZFZhbHVlKSB7XG4gICAgaWYgKHV0aWxfMS5pc1N0cmluZyhzb3VyY2UpKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2UucGFkRW5kKHRhcmdldExlbmd0aCwgcGFkVmFsdWUpO1xuICAgIH1cbiAgICBlbHNlIGlmICh1dGlsXzEuaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICAgIHZhciBzb3VyY2VMZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgICAgICBpZiAoc291cmNlTGVuZ3RoIDwgdGFyZ2V0TGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgZGlmZiA9IHRhcmdldExlbmd0aCAtIHNvdXJjZUxlbmd0aDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGlmZjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgc291cmNlLnB1c2gocGFkVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2U7XG59XG5leHBvcnRzLnBhZEVuZCA9IHBhZEVuZDtcbi8qKlxuICogQGlnbm9yZVxuICogb21pdCBrZXlzIG9mIGFuIG9iamVjdC5cbiAqIEBwYXJhbSBvYmpcbiAqIEBwYXJhbSBrZXlzXG4gKi9cbmZ1bmN0aW9uIG9taXQob2JqLCBrZXlzKSB7XG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgZGVsZXRlIG9ialtrZXldO1xuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG59XG5leHBvcnRzLm9taXQgPSBvbWl0O1xuLyoqXG4gKiBAaWdub3JlXG4gKiBAcGFyYW0gc291cmNlQXJyYXlcbiAqIEBwYXJhbSB0YXJnZXRBcnJheVxuICogQHBhcmFtIG1hcFxuICovXG5mdW5jdGlvbiB1bmlxKHNvdXJjZUFycmF5LCB0YXJnZXRBcnJheSwgbWFwKSB7XG4gICAgaWYgKHRhcmdldEFycmF5ID09PSB2b2lkIDApIHsgdGFyZ2V0QXJyYXkgPSBbXTsgfVxuICAgIGlmIChtYXAgPT09IHZvaWQgMCkgeyBtYXAgPSB7fTsgfVxuICAgIGZvciAodmFyIF9pID0gMCwgc291cmNlQXJyYXlfMSA9IHNvdXJjZUFycmF5OyBfaSA8IHNvdXJjZUFycmF5XzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VBcnJheV8xW19pXTtcbiAgICAgICAgaWYgKCFtYXBbc291cmNlXSkge1xuICAgICAgICAgICAgdGFyZ2V0QXJyYXkucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgbWFwW3NvdXJjZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXRBcnJheTtcbn1cbmV4cG9ydHMudW5pcSA9IHVuaXE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1oZWxwZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldEN1c3RvbUxlZ2VuZEl0ZW1zID0gZXhwb3J0cy5nZXRMZWdlbmRJdGVtcyA9IGV4cG9ydHMuZ2V0TGVnZW5kTGF5b3V0ID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRcIik7XG52YXIgYXR0cl8xID0gcmVxdWlyZShcIi4vYXR0clwiKTtcbnZhciBtYXJrZXJfMSA9IHJlcXVpcmUoXCIuL21hcmtlclwiKTtcbmZ1bmN0aW9uIHNldE1hcmtlclN5bWJvbChtYXJrZXIpIHtcbiAgICB2YXIgc3ltYm9sID0gbWFya2VyLnN5bWJvbDtcbiAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHN5bWJvbCkgJiYgbWFya2VyXzEuTWFya2VyU3ltYm9sc1tzeW1ib2xdKSB7XG4gICAgICAgIG1hcmtlci5zeW1ib2wgPSBtYXJrZXJfMS5NYXJrZXJTeW1ib2xzW3N5bWJvbF07XG4gICAgfVxufVxuLyoqXG4gKiBAaWdub3JlXG4gKiBnZXQgdGhlIGxlZ2VuZCBsYXlvdXQgZnJvbSBkaXJlY3Rpb25cbiAqIEBwYXJhbSBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIGxheW91dCAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnXG4gKi9cbmZ1bmN0aW9uIGdldExlZ2VuZExheW91dChkaXJlY3Rpb24pIHtcbiAgICByZXR1cm4gZGlyZWN0aW9uLnN0YXJ0c1dpdGgoY29uc3RhbnRfMS5ESVJFQ1RJT04uTEVGVCkgfHwgZGlyZWN0aW9uLnN0YXJ0c1dpdGgoY29uc3RhbnRfMS5ESVJFQ1RJT04uUklHSFQpID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcbn1cbmV4cG9ydHMuZ2V0TGVnZW5kTGF5b3V0ID0gZ2V0TGVnZW5kTGF5b3V0O1xuLyoqXG4gKiBAaWdub3JlXG4gKiBnZXQgdGhlIGxlZ2VuZCBpdGVtc1xuICogQHBhcmFtIHZpZXdcbiAqIEBwYXJhbSBnZW9tZXRyeVxuICogQHBhcmFtIGF0dHJcbiAqIEBwYXJhbSB0aGVtZU1hcmtlclxuICogQHBhcmFtIHVzZXJNYXJrZXJcbiAqIEByZXR1cm5zIGxlZ2VuZCBpdGVtc1xuICovXG5mdW5jdGlvbiBnZXRMZWdlbmRJdGVtcyh2aWV3LCBnZW9tZXRyeSwgYXR0ciwgdGhlbWVNYXJrZXIsIHVzZXJNYXJrZXIpIHtcbiAgICB2YXIgc2NhbGUgPSBhdHRyLmdldFNjYWxlKGF0dHIudHlwZSk7XG4gICAgaWYgKHNjYWxlLmlzQ2F0ZWdvcnkpIHtcbiAgICAgICAgdmFyIGZpZWxkXzEgPSBzY2FsZS5maWVsZDtcbiAgICAgICAgdmFyIGNvbG9yQXR0cl8xID0gZ2VvbWV0cnkuZ2V0QXR0cmlidXRlKCdjb2xvcicpO1xuICAgICAgICB2YXIgc2hhcGVBdHRyXzEgPSBnZW9tZXRyeS5nZXRBdHRyaWJ1dGUoJ3NoYXBlJyk7XG4gICAgICAgIHZhciBkZWZhdWx0Q29sb3JfMSA9IHZpZXcuZ2V0VGhlbWUoKS5kZWZhdWx0Q29sb3I7XG4gICAgICAgIHZhciBpc0luUG9sYXJfMSA9IGdlb21ldHJ5LmNvb3JkaW5hdGUuaXNQb2xhcjtcbiAgICAgICAgcmV0dXJuIHNjYWxlLmdldFRpY2tzKCkubWFwKGZ1bmN0aW9uICh0aWNrKSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICB2YXIgdGV4dCA9IHRpY2sudGV4dCwgc2NhbGVWYWx1ZSA9IHRpY2sudmFsdWU7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IHRleHQ7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBzY2FsZS5pbnZlcnQoc2NhbGVWYWx1ZSk7XG4gICAgICAgICAgICAvLyDpgJrov4fov4fmu6Tlm77kvovpobnnmoTmlbDmja7vvIzmnaXnnIvmmK/lkKYgdW5jaGVja2VkXG4gICAgICAgICAgICB2YXIgdW5jaGVja2VkID0gdmlldy5maWx0ZXJGaWVsZERhdGEoZmllbGRfMSwgWyhfYSA9IHt9LCBfYVtmaWVsZF8xXSA9IHZhbHVlLCBfYSldKS5sZW5ndGggPT09IDA7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB2YXIgY29sb3IgPSBhdHRyXzEuZ2V0TWFwcGluZ1ZhbHVlKGNvbG9yQXR0cl8xLCB2YWx1ZSwgZGVmYXVsdENvbG9yXzEpO1xuICAgICAgICAgICAgdmFyIHNoYXBlID0gYXR0cl8xLmdldE1hcHBpbmdWYWx1ZShzaGFwZUF0dHJfMSwgdmFsdWUsICdwb2ludCcpO1xuICAgICAgICAgICAgdmFyIG1hcmtlciA9IGdlb21ldHJ5LmdldFNoYXBlTWFya2VyKHNoYXBlLCB7XG4gICAgICAgICAgICAgICAgY29sb3I6IGNvbG9yLFxuICAgICAgICAgICAgICAgIGlzSW5Qb2xhcjogaXNJblBvbGFyXzEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHRoZSBtYXJrZXIgY29uZmlndXJlIG9yZGVyIHNob3VsZCBiZSBlbnN1cmVcbiAgICAgICAgICAgIG1hcmtlciA9IHV0aWxfMS5kZWVwTWl4KHt9LCB0aGVtZU1hcmtlciwgbWFya2VyLCB1c2VyTWFya2VyKTtcbiAgICAgICAgICAgIHNldE1hcmtlclN5bWJvbChtYXJrZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IHZhbHVlLCBuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWUsIG1hcmtlcjogbWFya2VyLCB1bmNoZWNrZWQ6IHVuY2hlY2tlZCB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xufVxuZXhwb3J0cy5nZXRMZWdlbmRJdGVtcyA9IGdldExlZ2VuZEl0ZW1zO1xuLyoqXG4gKiBAaWdub3JlXG4gKiBjdXN0b20gbGVnZW5kIOeahCBpdGVtcyDojrflj5ZcbiAqIEBwYXJhbSB0aGVtZU1hcmtlclxuICogQHBhcmFtIHVzZXJNYXJrZXJcbiAqIEBwYXJhbSBjdXN0b21JdGVtc1xuICovXG5mdW5jdGlvbiBnZXRDdXN0b21MZWdlbmRJdGVtcyh0aGVtZU1hcmtlciwgdXNlck1hcmtlciwgY3VzdG9tSXRlbXMpIHtcbiAgICAvLyDlpoLmnpzmnInoh6rlrprkuYnnmoQgaXRlbe+8jOmCo+S5iOWwseebtOaOpeS9v+eUqO+8jOW5tuWQiOW5tuS4u+mimOeahCBtYXJrZXIg6YWN572uXG4gICAgcmV0dXJuIGN1c3RvbUl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICB2YXIgbWFya2VyID0gdXRpbF8xLmRlZXBNaXgoe30sIHRoZW1lTWFya2VyLCB1c2VyTWFya2VyLCBpdGVtLm1hcmtlcik7XG4gICAgICAgIHNldE1hcmtlclN5bWJvbChtYXJrZXIpO1xuICAgICAgICBpdGVtLm1hcmtlciA9IG1hcmtlcjtcbiAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgfSk7XG59XG5leHBvcnRzLmdldEN1c3RvbUxlZ2VuZEl0ZW1zID0gZ2V0Q3VzdG9tTGVnZW5kSXRlbXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sZWdlbmQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLk1hcmtlclN5bWJvbHMgPSB2b2lkIDA7XG4vKiogQGlnbm9yZSAqL1xuZXhwb3J0cy5NYXJrZXJTeW1ib2xzID0ge1xuICAgIGhleGFnb246IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHZhciBkaWZmWCA9IChyIC8gMikgKiBNYXRoLnNxcnQoMyk7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCB4LCB5IC0gcl0sXG4gICAgICAgICAgICBbJ0wnLCB4ICsgZGlmZlgsIHkgLSByIC8gMl0sXG4gICAgICAgICAgICBbJ0wnLCB4ICsgZGlmZlgsIHkgKyByIC8gMl0sXG4gICAgICAgICAgICBbJ0wnLCB4LCB5ICsgcl0sXG4gICAgICAgICAgICBbJ0wnLCB4IC0gZGlmZlgsIHkgKyByIC8gMl0sXG4gICAgICAgICAgICBbJ0wnLCB4IC0gZGlmZlgsIHkgLSByIC8gMl0sXG4gICAgICAgICAgICBbJ1onXSxcbiAgICAgICAgXTtcbiAgICB9LFxuICAgIGJvd3RpZTogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgdmFyIGRpZmZZID0gciAtIDEuNTtcbiAgICAgICAgcmV0dXJuIFtbJ00nLCB4IC0gciwgeSAtIGRpZmZZXSwgWydMJywgeCArIHIsIHkgKyBkaWZmWV0sIFsnTCcsIHggKyByLCB5IC0gZGlmZlldLCBbJ0wnLCB4IC0gciwgeSArIGRpZmZZXSwgWydaJ11dO1xuICAgIH0sXG4gICAgY3Jvc3M6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCB4IC0gciwgeSAtIHJdLFxuICAgICAgICAgICAgWydMJywgeCArIHIsIHkgKyByXSxcbiAgICAgICAgICAgIFsnTScsIHggKyByLCB5IC0gcl0sXG4gICAgICAgICAgICBbJ0wnLCB4IC0gciwgeSArIHJdLFxuICAgICAgICBdO1xuICAgIH0sXG4gICAgdGljazogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHggLSByIC8gMiwgeSAtIHJdLFxuICAgICAgICAgICAgWydMJywgeCArIHIgLyAyLCB5IC0gcl0sXG4gICAgICAgICAgICBbJ00nLCB4LCB5IC0gcl0sXG4gICAgICAgICAgICBbJ0wnLCB4LCB5ICsgcl0sXG4gICAgICAgICAgICBbJ00nLCB4IC0gciAvIDIsIHkgKyByXSxcbiAgICAgICAgICAgIFsnTCcsIHggKyByIC8gMiwgeSArIHJdLFxuICAgICAgICBdO1xuICAgIH0sXG4gICAgcGx1czogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHggLSByLCB5XSxcbiAgICAgICAgICAgIFsnTCcsIHggKyByLCB5XSxcbiAgICAgICAgICAgIFsnTScsIHgsIHkgLSByXSxcbiAgICAgICAgICAgIFsnTCcsIHgsIHkgKyByXSxcbiAgICAgICAgXTtcbiAgICB9LFxuICAgIGh5cGhlbjogZnVuY3Rpb24gKHgsIHksIHIpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHggLSByLCB5XSxcbiAgICAgICAgICAgIFsnTCcsIHggKyByLCB5XSxcbiAgICAgICAgXTtcbiAgICB9LFxuICAgIGxpbmU6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCB4LCB5IC0gcl0sXG4gICAgICAgICAgICBbJ0wnLCB4LCB5ICsgcl0sXG4gICAgICAgIF07XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXJrZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnBhcnNlUGFkZGluZyA9IGV4cG9ydHMuaXNBdXRvUGFkZGluZyA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDmmK/lkKbmmK/oh6rliqggcGFkZGluZ1xuICogQHBhcmFtIHBhZGRpbmdcbiAqL1xuZnVuY3Rpb24gaXNBdXRvUGFkZGluZyhwYWRkaW5nKSB7XG4gICAgcmV0dXJuICF1dGlsXzEuaXNOdW1iZXIocGFkZGluZykgJiYgIXV0aWxfMS5pc0FycmF5KHBhZGRpbmcpO1xufVxuZXhwb3J0cy5pc0F1dG9QYWRkaW5nID0gaXNBdXRvUGFkZGluZztcbi8qKlxuICogQGlnbm9yZVxuICogcGFkZGluZyDnmoTop6PmnpDpgLvovpFcbiAqIEBwYXJhbSBwYWRkaW5nXG4gKiBAcmV0dXJuIFsgdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0IF1cbiAqL1xuZnVuY3Rpb24gcGFyc2VQYWRkaW5nKHBhZGRpbmcpIHtcbiAgICBpZiAocGFkZGluZyA9PT0gdm9pZCAwKSB7IHBhZGRpbmcgPSAwOyB9XG4gICAgdmFyIHBhZGRpbmdBcnJheSA9IHV0aWxfMS5pc0FycmF5KHBhZGRpbmcpID8gcGFkZGluZyA6IFtwYWRkaW5nXTtcbiAgICBzd2l0Y2ggKHBhZGRpbmdBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgcGFkZGluZ0FycmF5ID0gWzAsIDAsIDAsIDBdO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHBhZGRpbmdBcnJheSA9IG5ldyBBcnJheSg0KS5maWxsKHBhZGRpbmdBcnJheVswXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgcGFkZGluZ0FycmF5ID0gdHNsaWJfMS5fX3NwcmVhZEFycmF5cyhwYWRkaW5nQXJyYXksIHBhZGRpbmdBcnJheSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgcGFkZGluZ0FycmF5ID0gdHNsaWJfMS5fX3NwcmVhZEFycmF5cyhwYWRkaW5nQXJyYXksIFtwYWRkaW5nQXJyYXlbMV1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgLy8g5YW25LuW5oOF5Ya177yM5Y+q5Y675Zub5LiqXG4gICAgICAgICAgICBwYWRkaW5nQXJyYXkgPSBwYWRkaW5nQXJyYXkuc2xpY2UoMCwgNCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHBhZGRpbmdBcnJheTtcbn1cbmV4cG9ydHMucGFyc2VQYWRkaW5nID0gcGFyc2VQYWRkaW5nO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFkZGluZy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0TmFtZSA9IGV4cG9ydHMuc3luY1NjYWxlID0gZXhwb3J0cy5jcmVhdGVTY2FsZUJ5RmllbGQgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vZGVwZW5kZW50c1wiKTtcbnZhciBkYXRlUmVnZXggPSAvXig/Oig/ITAwMDApWzAtOV17NH0oWy0vLl0rKSg/Oig/OjA/WzEtOV18MVswLTJdKVxcMSg/OjA/WzEtOV18MVswLTldfDJbMC04XSl8KD86MD9bMTMtOV18MVswLTJdKVxcMSg/OjI5fDMwKXwoPzowP1sxMzU3OF18MVswMl0pXFwxKD86MzEpKXwoPzpbMC05XXsyfSg/OjBbNDhdfFsyNDY4XVswNDhdfFsxMzU3OV1bMjZdKXwoPzowWzQ4XXxbMjQ2OF1bMDQ4XXxbMTM1NzldWzI2XSkwMCkoWy0vLl0rKTA/MlxcMig/OjI5KSkoXFxzKyhbMDFdfChbMDFdWzAtOV18MlswLTNdKSk6KFswLTldfFswLTVdWzAtOV0pOihbMC05XXxbMC01XVswLTldKSk/JC87XG4vKipcbiAqIOiOt+WPluWtl+auteWvueW6lOaVsOaNrueahOexu+Wei1xuICogQHBhcmFtIGZpZWxkIOaVsOaNruWtl+auteWQjVxuICogQHBhcmFtIGRhdGEg5pWw5o2u5rqQXG4gKiBAcmV0dXJucyBkZWZhdWx0IHR5cGUg6L+U5Zue5a+55bqU55qE5pWw5o2u57G75Z6LXG4gKi9cbmZ1bmN0aW9uIGdldERlZmF1bHRUeXBlKHZhbHVlKSB7XG4gICAgdmFyIHR5cGUgPSAnbGluZWFyJztcbiAgICBpZiAoZGF0ZVJlZ2V4LnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHR5cGUgPSAndGltZSc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHV0aWxfMS5pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgdHlwZSA9ICdjYXQnO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZTtcbn1cbi8qKlxuICogQGlnbm9yZVxuICog5Li65oyH5a6a55qEIGBmaWVsZGAg5a2X5q615pWw5o2u5Yib5bu6IHNjYWxlXG4gKiBAcGFyYW0gZmllbGQg5a2X5q615ZCNXG4gKiBAcGFyYW0gW2RhdGFdIOaVsOaNrumbhu+8jOWPr+S4uuepulxuICogQHBhcmFtIFtzY2FsZURlZl0g5YiX5a6a5LmJ77yM5Y+v5Li656m6XG4gKiBAcmV0dXJucyBzY2FsZSDov5Tlm57liJvlu7rnmoQgU2NhbGUg5a6e5L6LXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVNjYWxlQnlGaWVsZChmaWVsZCwgZGF0YSwgc2NhbGVEZWYpIHtcbiAgICB2YXIgdmFsaWREYXRhID0gZGF0YSB8fCBbXTtcbiAgICBpZiAodXRpbF8xLmlzTnVtYmVyKGZpZWxkKSB8fCAodXRpbF8xLmlzTmlsKHV0aWxfMS5maXJzdFZhbHVlKHZhbGlkRGF0YSwgZmllbGQpKSAmJiB1dGlsXzEuaXNFbXB0eShzY2FsZURlZikpKSB7XG4gICAgICAgIHZhciBJZGVudGl0eSA9IGRlcGVuZGVudHNfMS5nZXRTY2FsZSgnaWRlbnRpdHknKTtcbiAgICAgICAgcmV0dXJuIG5ldyBJZGVudGl0eSh7XG4gICAgICAgICAgICBmaWVsZDogZmllbGQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIHZhbHVlczogW2ZpZWxkXSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHZhciB2YWx1ZXMgPSB1dGlsXzEudmFsdWVzT2ZLZXkodmFsaWREYXRhLCBmaWVsZCk7XG4gICAgLy8g5aaC5p6c5bey57uP5a6a5LmJ6L+H6L+Z5Liq5bqm6YePXG4gICAgdmFyIHR5cGUgPSB1dGlsXzEuZ2V0KHNjYWxlRGVmLCAndHlwZScsIGdldERlZmF1bHRUeXBlKHZhbHVlc1swXSkpO1xuICAgIHZhciBTY2FsZUN0b3IgPSBkZXBlbmRlbnRzXzEuZ2V0U2NhbGUodHlwZSk7XG4gICAgcmV0dXJuIG5ldyBTY2FsZUN0b3IodHNsaWJfMS5fX2Fzc2lnbih7IGZpZWxkOiBmaWVsZCxcbiAgICAgICAgdmFsdWVzOiB2YWx1ZXMgfSwgc2NhbGVEZWYpKTtcbn1cbmV4cG9ydHMuY3JlYXRlU2NhbGVCeUZpZWxkID0gY3JlYXRlU2NhbGVCeUZpZWxkO1xuLyoqXG4gKiBAaWdub3JlXG4gKiDlkIzmraUgc2NhbGVcbiAqIEB0b2RvIOaYr+WQpuWPr+S7pemAmui/hyBzY2FsZS51cGRhdGUoKSDmlrnms5Xov5vooYzmm7TmlrBcbiAqIEBwYXJhbSBzY2FsZSDpnIDopoHlkIzmraXnmoQgc2NhbGUg5a6e5L6LXG4gKiBAcGFyYW0gbmV3U2NhbGUg5ZCM5q2l5rqQIFNjYWxlXG4gKi9cbmZ1bmN0aW9uIHN5bmNTY2FsZShzY2FsZSwgbmV3U2NhbGUpIHtcbiAgICBpZiAoc2NhbGUudHlwZSAhPT0gJ2lkZW50aXR5JyAmJiBuZXdTY2FsZS50eXBlICE9PSAnaWRlbnRpdHknKSB7XG4gICAgICAgIHZhciBvYmogPSB7fTtcbiAgICAgICAgZm9yICh2YXIgayBpbiBuZXdTY2FsZSkge1xuICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuZXdTY2FsZSwgaykpIHtcbiAgICAgICAgICAgICAgICBvYmpba10gPSBuZXdTY2FsZVtrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzY2FsZS5jaGFuZ2Uob2JqKTtcbiAgICB9XG59XG5leHBvcnRzLnN5bmNTY2FsZSA9IHN5bmNTY2FsZTtcbi8qKlxuICogQGlnbm9yZVxuICogZ2V0IHRoZSBzY2FsZSBuYW1lLCBpZiBhbGlhcyBleGlzdCwgcmV0dXJuIGFsaWFzLCBvciBlbHNlIGZpZWxkXG4gKiBAcGFyYW0gc2NhbGVcbiAqIEByZXR1cm5zIHRoZSBuYW1lIG9mIGZpZWxkXG4gKi9cbmZ1bmN0aW9uIGdldE5hbWUoc2NhbGUpIHtcbiAgICByZXR1cm4gc2NhbGUuYWxpYXMgfHwgc2NhbGUuZmllbGQ7XG59XG5leHBvcnRzLmdldE5hbWUgPSBnZXROYW1lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2NhbGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNyZWF0ZVRoZW1lQnlTdHlsZXNoZWV0ID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgVE9PTFRJUF9DU1NfQ09OU1QgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiQGFudHYvY29tcG9uZW50L2xpYi90b29sdGlwL2Nzcy1jb25zdFwiKSk7XG52YXIgbWF0cml4X3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9tYXRyaXgtdXRpbFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBncmFwaGljc18xID0gcmVxdWlyZShcIi4uL3V0aWwvZ3JhcGhpY3NcIik7XG4vKipcbiAqIOagueaNruS4u+mimOagt+W8j+ihqOeUn+aIkOS4u+mimOe7k+aehFxuICogQHBhcmFtIHN0eWxlU2hlZXQg5Li76aKY5qC35byP6KGoXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVRoZW1lQnlTdHlsZXNoZWV0KHN0eWxlU2hlZXQpIHtcbiAgICB2YXIgX2E7XG4gICAgdmFyIHNoYXBlU3R5bGVzID0ge1xuICAgICAgICBwb2ludDoge1xuICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIGZpbGw6IHN0eWxlU2hlZXQucG9pbnRGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgcjogc3R5bGVTaGVldC5wb2ludFNpemUsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LnBvaW50Qm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LnBvaW50Qm9yZGVyLFxuICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBzdHlsZVNoZWV0LnBvaW50RmlsbE9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LnBvaW50QWN0aXZlQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LnBvaW50QWN0aXZlQm9yZGVyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LnBvaW50U2VsZWN0ZWRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQucG9pbnRTZWxlY3RlZEJvcmRlcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBzdHlsZVNoZWV0LnBvaW50SW5hY3RpdmVGaWxsT3BhY2l0eSxcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LnBvaW50SW5hY3RpdmVCb3JkZXJPcGFjaXR5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgaG9sbG93UG9pbnQ6IHtcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmhvbGxvd1BvaW50RmlsbENvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5ob2xsb3dQb2ludEJvcmRlcixcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuaG9sbG93UG9pbnRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LmhvbGxvd1BvaW50Qm9yZGVyT3BhY2l0eSxcbiAgICAgICAgICAgICAgICByOiBzdHlsZVNoZWV0LmhvbGxvd1BvaW50U2l6ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuaG9sbG93UG9pbnRBY3RpdmVCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LmhvbGxvd1BvaW50QWN0aXZlQm9yZGVyT3BhY2l0eSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5ob2xsb3dQb2ludFNlbGVjdGVkQm9yZGVyLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5ob2xsb3dQb2ludFNlbGVjdGVkQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgc3Ryb2tlT3BhY2l0eTogc3R5bGVTaGVldC5ob2xsb3dQb2ludFNlbGVjdGVkQm9yZGVyT3BhY2l0eSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgIHN0cm9rZU9wYWNpdHk6IHN0eWxlU2hlZXQuaG9sbG93UG9pbnRJbmFjdGl2ZUJvcmRlck9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBhcmVhOiB7XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgZmlsbDogc3R5bGVTaGVldC5hcmVhRmlsbENvbG9yLFxuICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBzdHlsZVNoZWV0LmFyZWFGaWxsT3BhY2l0eSxcbiAgICAgICAgICAgICAgICBzdHJva2U6IG51bGwsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IHN0eWxlU2hlZXQuYXJlYUFjdGl2ZUZpbGxPcGFjaXR5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IHN0eWxlU2hlZXQuYXJlYVNlbGVjdGVkRmlsbE9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eTogc3R5bGVTaGVldC5hcmVhSW5hY3RpdmVGaWxsT3BhY2l0eSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGhvbGxvd0FyZWE6IHtcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBudWxsLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5ob2xsb3dBcmVhQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LmhvbGxvd0FyZWFCb3JkZXIsXG4gICAgICAgICAgICAgICAgc3Ryb2tlT3BhY2l0eTogc3R5bGVTaGVldC5ob2xsb3dBcmVhQm9yZGVyT3BhY2l0eSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBudWxsLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5ob2xsb3dBcmVhQWN0aXZlQm9yZGVyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgZmlsbDogbnVsbCxcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuaG9sbG93QXJlYVNlbGVjdGVkQm9yZGVyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlT3BhY2l0eTogc3R5bGVTaGVldC5ob2xsb3dBcmVhSW5hY3RpdmVCb3JkZXJPcGFjaXR5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgaW50ZXJ2YWw6IHtcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmludGVydmFsRmlsbENvbG9yLFxuICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBzdHlsZVNoZWV0LmludGVydmFsRmlsbE9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmludGVydmFsQWN0aXZlQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LmludGVydmFsQWN0aXZlQm9yZGVyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmludGVydmFsU2VsZWN0ZWRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuaW50ZXJ2YWxTZWxlY3RlZEJvcmRlcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBzdHlsZVNoZWV0LmludGVydmFsSW5hY3RpdmVGaWxsT3BhY2l0eSxcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LmludGVydmFsSW5hY3RpdmVCb3JkZXJPcGFjaXR5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgaG9sbG93SW50ZXJ2YWw6IHtcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmhvbGxvd0ludGVydmFsRmlsbENvbG9yLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5ob2xsb3dJbnRlcnZhbEJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5ob2xsb3dJbnRlcnZhbEJvcmRlcixcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LmhvbGxvd0ludGVydmFsQm9yZGVyT3BhY2l0eSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuaG9sbG93SW50ZXJ2YWxBY3RpdmVCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuaG9sbG93SW50ZXJ2YWxBY3RpdmVCb3JkZXIsXG4gICAgICAgICAgICAgICAgc3Ryb2tlT3BhY2l0eTogc3R5bGVTaGVldC5ob2xsb3dJbnRlcnZhbEFjdGl2ZUJvcmRlck9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuaG9sbG93SW50ZXJ2YWxTZWxlY3RlZEJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5ob2xsb3dJbnRlcnZhbFNlbGVjdGVkQm9yZGVyLFxuICAgICAgICAgICAgICAgIHN0cm9rZU9wYWNpdHk6IHN0eWxlU2hlZXQuaG9sbG93SW50ZXJ2YWxTZWxlY3RlZEJvcmRlck9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuaG9sbG93SW50ZXJ2YWxJbmFjdGl2ZUJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5ob2xsb3dJbnRlcnZhbEluYWN0aXZlQm9yZGVyLFxuICAgICAgICAgICAgICAgIHN0cm9rZU9wYWNpdHk6IHN0eWxlU2hlZXQuaG9sbG93SW50ZXJ2YWxJbmFjdGl2ZUJvcmRlck9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmxpbmVCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQubGluZUJvcmRlcixcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LmxpbmVCb3JkZXJPcGFjaXR5LFxuICAgICAgICAgICAgICAgIGZpbGw6IG51bGwsXG4gICAgICAgICAgICAgICAgbGluZUFwcGVuZFdpZHRoOiAxMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQubGluZUFjdGl2ZUJvcmRlcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5saW5lU2VsZWN0ZWRCb3JkZXIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiBzdHlsZVNoZWV0LmxpbmVJbmFjdGl2ZUJvcmRlck9wYWNpdHksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgIH07XG4gICAgdmFyIGF4aXNTdHlsZXMgPSB7XG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgcG9zaXRpb246ICdjZW50ZXInLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmF4aXNUaXRsZVRleHRGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6IHN0eWxlU2hlZXQuYXhpc1RpdGxlVGV4dEZvbnRTaXplLFxuICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IHN0eWxlU2hlZXQuYXhpc1RpdGxlVGV4dExpbmVIZWlnaHQsXG4gICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICBmb250RmFtaWx5OiBzdHlsZVNoZWV0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgIGF1dG9FbGxpcHNpczogdHJ1ZSxcbiAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgb2Zmc2V0OiAxNixcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZmlsbDogc3R5bGVTaGVldC5heGlzTGFiZWxGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6IHN0eWxlU2hlZXQuYXhpc0xhYmVsRm9udFNpemUsXG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogc3R5bGVTaGVldC5heGlzTGFiZWxMaW5lSGVpZ2h0LFxuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZScsXG4gICAgICAgICAgICAgICAgZm9udEZhbWlseTogc3R5bGVTaGVldC5mb250RmFtaWx5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgbGluZToge1xuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYXhpc0xpbmVCb3JkZXIsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmF4aXNMaW5lQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYXhpc1RpY2tMaW5lQm9yZGVyLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5heGlzVGlja0xpbmVCb3JkZXJDb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhbGlnblRpY2s6IHRydWUsXG4gICAgICAgICAgICBsZW5ndGg6IHN0eWxlU2hlZXQuYXhpc1RpY2tMaW5lTGVuZ3RoLFxuICAgICAgICB9LFxuICAgICAgICBzdWJUaWNrTGluZTogbnVsbCxcbiAgICAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAgICB9O1xuICAgIHZhciBheGlzR3JpZFN0eWxlcyA9IHtcbiAgICAgICAgbGluZToge1xuICAgICAgICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuYXhpc0dyaWRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYXhpc0dyaWRCb3JkZXIsXG4gICAgICAgICAgICAgICAgbGluZURhc2g6IHN0eWxlU2hlZXQuYXhpc0dyaWRMaW5lRGFzaCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFsaWduVGljazogdHJ1ZSxcbiAgICAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAgICB9O1xuICAgIHZhciBsZWdlbmRTdHlsZXMgPSB7XG4gICAgICAgIHRpdGxlOiBudWxsLFxuICAgICAgICBtYXJrZXI6IHtcbiAgICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHI6IHN0eWxlU2hlZXQubGVnZW5kQ2lyY2xlTWFya2VyU2l6ZSxcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmxlZ2VuZE1hcmtlckNvbG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgaXRlbU5hbWU6IHtcbiAgICAgICAgICAgIHNwYWNpbmc6IDUsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIGZpbGw6IHN0eWxlU2hlZXQubGVnZW5kSXRlbU5hbWVGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgZm9udEZhbWlseTogc3R5bGVTaGVldC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiBzdHlsZVNoZWV0LmxlZ2VuZEl0ZW1OYW1lRm9udFNpemUsXG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogc3R5bGVTaGVldC5sZWdlbmRJdGVtTmFtZUxpbmVIZWlnaHQsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogc3R5bGVTaGVldC5sZWdlbmRJdGVtTmFtZUZvbnRXZWlnaHQsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBmbGlwUGFnZTogdHJ1ZSxcbiAgICAgICAgYW5pbWF0ZTogZmFsc2UsXG4gICAgICAgIG1heEl0ZW1XaWR0aDogMC4yLFxuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYmFja2dyb3VuZDogc3R5bGVTaGVldC5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIGRlZmF1bHRDb2xvcjogc3R5bGVTaGVldC5icmFuZENvbG9yLFxuICAgICAgICBwYWRkaW5nOiAnYXV0bycsXG4gICAgICAgIGZvbnRGYW1pbHk6IHN0eWxlU2hlZXQuZm9udEZhbWlseSxcbiAgICAgICAgLyoqIOS4gOiIrOafseeKtuWbvuWuveW6puWNoOavlCAqL1xuICAgICAgICBjb2x1bW5XaWR0aFJhdGlvOiAxIC8gMixcbiAgICAgICAgLyoqIOafseeKtuWbvuacgOWkp+WuveW6piAqL1xuICAgICAgICBtYXhDb2x1bW5XaWR0aDogbnVsbCxcbiAgICAgICAgLyoqIOafseeKtuWbvuacgOWwj+WuveW6piAqL1xuICAgICAgICBtaW5Db2x1bW5XaWR0aDogbnVsbCxcbiAgICAgICAgLyoqIOeOq+eRsOWbvuWNoOavlCAqL1xuICAgICAgICByb3NlV2lkdGhSYXRpbzogMC45OTk5OTk5LFxuICAgICAgICAvKiog5aSa5bGC6aW85Zu+L+eOr+WbvuWNoOavlCAqL1xuICAgICAgICBtdWx0aXBsZVBpZVdpZHRoUmF0aW86IDEgLyAxLjMsXG4gICAgICAgIGNvbG9yczEwOiBzdHlsZVNoZWV0LnBhbGV0dGVRdWFsaXRhdGl2ZTEwLFxuICAgICAgICBjb2xvcnMyMDogc3R5bGVTaGVldC5wYWxldHRlUXVhbGl0YXRpdmUyMCxcbiAgICAgICAgc2hhcGVzOiB7XG4gICAgICAgICAgICBwb2ludDogW1xuICAgICAgICAgICAgICAgICdob2xsb3ctY2lyY2xlJyxcbiAgICAgICAgICAgICAgICAnaG9sbG93LXNxdWFyZScsXG4gICAgICAgICAgICAgICAgJ2hvbGxvdy1ib3d0aWUnLFxuICAgICAgICAgICAgICAgICdob2xsb3ctZGlhbW9uZCcsXG4gICAgICAgICAgICAgICAgJ2hvbGxvdy1oZXhhZ29uJyxcbiAgICAgICAgICAgICAgICAnaG9sbG93LXRyaWFuZ2xlJyxcbiAgICAgICAgICAgICAgICAnaG9sbG93LXRyaWFuZ2xlLWRvd24nLFxuICAgICAgICAgICAgICAgICdjaXJjbGUnLFxuICAgICAgICAgICAgICAgICdzcXVhcmUnLFxuICAgICAgICAgICAgICAgICdib3d0aWUnLFxuICAgICAgICAgICAgICAgICdkaWFtb25kJyxcbiAgICAgICAgICAgICAgICAnaGV4YWdvbicsXG4gICAgICAgICAgICAgICAgJ3RyaWFuZ2xlJyxcbiAgICAgICAgICAgICAgICAndHJpYW5nbGUtZG93bicsXG4gICAgICAgICAgICAgICAgJ2Nyb3NzJyxcbiAgICAgICAgICAgICAgICAndGljaycsXG4gICAgICAgICAgICAgICAgJ3BsdXMnLFxuICAgICAgICAgICAgICAgICdoeXBoZW4nLFxuICAgICAgICAgICAgICAgICdsaW5lJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBsaW5lOiBbJ2xpbmUnLCAnZGFzaCcsICdkb3QnLCAnc21vb3RoJ10sXG4gICAgICAgICAgICBhcmVhOiBbJ2FyZWEnLCAnc21vb3RoJywgJ2xpbmUnLCAnc21vb3RoLWxpbmUnXSxcbiAgICAgICAgICAgIGludGVydmFsOiBbJ3JlY3QnLCAnaG9sbG93LXJlY3QnLCAnbGluZScsICd0aWNrJ10sXG4gICAgICAgIH0sXG4gICAgICAgIHNpemVzOiBbMSwgMTBdLFxuICAgICAgICBnZW9tZXRyaWVzOiB7XG4gICAgICAgICAgICBpbnRlcnZhbDoge1xuICAgICAgICAgICAgICAgIHJlY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5pbnRlcnZhbC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb29yZGluYXRlID0gZWxlbWVudC5nZW9tZXRyeS5jb29yZGluYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29yZGluYXRlLmlzUG9sYXIgJiYgY29vcmRpbmF0ZS5pc1RyYW5zcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9hID0gZ3JhcGhpY3NfMS5nZXRBbmdsZShlbGVtZW50LmdldE1vZGVsKCksIGNvb3JkaW5hdGUpLCBzdGFydEFuZ2xlID0gX2Euc3RhcnRBbmdsZSwgZW5kQW5nbGUgPSBfYS5lbmRBbmdsZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1pZGRsZUFuZ2xlID0gKHN0YXJ0QW5nbGUgKyBlbmRBbmdsZSkgLyAyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgciA9IDcuNTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSByICogTWF0aC5jb3MobWlkZGxlQW5nbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeSA9IHIgKiBNYXRoLnNpbihtaWRkbGVBbmdsZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXg6IG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShudWxsLCBbWyd0JywgeCwgeV1dKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNoYXBlU3R5bGVzLmludGVydmFsLnNlbGVjdGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdob2xsb3ctcmVjdCc6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGZ1bm5lbDoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaW50ZXJ2YWwuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaW50ZXJ2YWwuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcHlyYW1pZDoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaW50ZXJ2YWwuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaW50ZXJ2YWwuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZG90OiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHNoYXBlU3R5bGVzLmxpbmUuZGVmYXVsdCksIHsgbGluZURhc2g6IFsxLCAxXSB9KSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzaGFwZVN0eWxlcy5saW5lLmFjdGl2ZSksIHsgbGluZURhc2g6IFsxLCAxXSB9KSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHNoYXBlU3R5bGVzLmxpbmUuaW5hY3RpdmUpLCB7IGxpbmVEYXNoOiBbMSwgMV0gfSksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzaGFwZVN0eWxlcy5saW5lLnNlbGVjdGVkKSwgeyBsaW5lRGFzaDogWzEsIDFdIH0pLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGFzaDoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzaGFwZVN0eWxlcy5saW5lLmRlZmF1bHQpLCB7IGxpbmVEYXNoOiBbNS41LCAxXSB9KSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzaGFwZVN0eWxlcy5saW5lLmFjdGl2ZSksIHsgbGluZURhc2g6IFs1LjUsIDFdIH0pLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcGVTdHlsZXMubGluZS5pbmFjdGl2ZSksIHsgbGluZURhc2g6IFs1LjUsIDFdIH0pLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcGVTdHlsZXMubGluZS5zZWxlY3RlZCksIHsgbGluZURhc2g6IFs1LjUsIDFdIH0pLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc21vb3RoOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGh2OiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHZoOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGh2aDoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB2aHY6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcG9seWdvbjoge1xuICAgICAgICAgICAgICAgIHBvbHlnb246IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmludGVydmFsLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5pbnRlcnZhbC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5pbnRlcnZhbC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvaW50OiB7XG4gICAgICAgICAgICAgICAgY2lyY2xlOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5wb2ludC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5wb2ludC5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzcXVhcmU6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5wb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5wb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGJvd3RpZToge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGlhbW9uZDoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaGV4YWdvbjoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdHJpYW5nbGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5wb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5wb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICd0cmlhbmdsZS1kb3duJzoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMucG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLnBvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2hvbGxvdy1jaXJjbGUnOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAnaG9sbG93LXNxdWFyZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdob2xsb3ctYm93dGllJzoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2hvbGxvdy1kaWFtb25kJzoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2hvbGxvdy1oZXhhZ29uJzoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2hvbGxvdy10cmlhbmdsZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdob2xsb3ctdHJpYW5nbGUtZG93bic6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNyb3NzOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aWNrOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBwbHVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93UG9pbnQuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBoeXBoZW46IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd1BvaW50LmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dQb2ludC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFyZWE6IHtcbiAgICAgICAgICAgICAgICBhcmVhOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5hcmVhLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmFyZWEuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmFyZWEuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuYXJlYS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNtb290aDoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuYXJlYS5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5hcmVhLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5hcmVhLmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmFyZWEuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dBcmVhLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0FyZWEuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0FyZWEuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93QXJlYS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdzbW9vdGgtbGluZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0FyZWEuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93QXJlYS5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93QXJlYS5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dBcmVhLnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2NoZW1hOiB7XG4gICAgICAgICAgICAgICAgY2FuZGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93SW50ZXJ2YWwuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMuaG9sbG93SW50ZXJ2YWwuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBib3g6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmhvbGxvd0ludGVydmFsLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5ob2xsb3dJbnRlcnZhbC5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVkZ2U6IHtcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHZodjoge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmluYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzbW9vdGg6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5pbmFjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLnNlbGVjdGVkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYXJjOiB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzaGFwZVN0eWxlcy5saW5lLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuYWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpbmFjdGl2ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHNoYXBlU3R5bGVzLmxpbmUuaW5hY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogc2hhcGVTdHlsZXMubGluZS5zZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgY29tcG9uZW50czoge1xuICAgICAgICAgICAgYXhpczoge1xuICAgICAgICAgICAgICAgIHRvcDogdXRpbF8xLmRlZXBNaXgoe30sIGF4aXNTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICd0b3AnLFxuICAgICAgICAgICAgICAgICAgICBncmlkOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdmVydGljYWxMaW1pdExlbmd0aDogMSAvIDIsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgYm90dG9tOiB1dGlsXzEuZGVlcE1peCh7fSwgYXhpc1N0eWxlcywge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2JvdHRvbScsXG4gICAgICAgICAgICAgICAgICAgIGdyaWQ6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbExpbWl0TGVuZ3RoOiAxIC8gMixcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBsZWZ0OiB1dGlsXzEuZGVlcE1peCh7fSwgYXhpc1N0eWxlcywge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2xlZnQnLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiA4LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgbGluZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdGlja0xpbmU6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGdyaWQ6IGF4aXNHcmlkU3R5bGVzLFxuICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbExpbWl0TGVuZ3RoOiAxIC8gMyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICByaWdodDogdXRpbF8xLmRlZXBNaXgoe30sIGF4aXNTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdyaWdodCcsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDgsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBsaW5lOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0aWNrTGluZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZ3JpZDogYXhpc0dyaWRTdHlsZXMsXG4gICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsTGltaXRMZW5ndGg6IDEgLyAzLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGNpcmNsZTogdXRpbF8xLmRlZXBNaXgoe30sIGF4aXNTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDgsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGdyaWQ6IHV0aWxfMS5kZWVwTWl4KHt9LCBheGlzR3JpZFN0eWxlcywgeyBsaW5lOiB7IHR5cGU6ICdsaW5lJyB9IH0pLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHJhZGl1czogdXRpbF8xLmRlZXBNaXgoe30sIGF4aXNTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDgsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGdyaWQ6IHV0aWxfMS5kZWVwTWl4KHt9LCBheGlzR3JpZFN0eWxlcywgeyBsaW5lOiB7IHR5cGU6ICdjaXJjbGUnIH0gfSksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgcmlnaHQ6IHV0aWxfMS5kZWVwTWl4KHt9LCBsZWdlbmRTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgbGF5b3V0OiAndmVydGljYWwnLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGxlZnQ6IHV0aWxfMS5kZWVwTWl4KHt9LCBsZWdlbmRTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgbGF5b3V0OiAndmVydGljYWwnLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRvcDogdXRpbF8xLmRlZXBNaXgoe30sIGxlZ2VuZFN0eWxlcywge1xuICAgICAgICAgICAgICAgICAgICBsYXlvdXQ6ICdob3Jpem9udGFsJyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBib3R0b206IHV0aWxfMS5kZWVwTWl4KHt9LCBsZWdlbmRTdHlsZXMsIHtcbiAgICAgICAgICAgICAgICAgICAgbGF5b3V0OiAnaG9yaXpvbnRhbCcsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgY29udGludW91czoge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdHJhY2s6IHt9LFxuICAgICAgICAgICAgICAgICAgICByYWlsOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnY29sb3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZTogc3R5bGVTaGVldC5zbGlkZXJSYWlsSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdExlbmd0aDogc3R5bGVTaGVldC5zbGlkZXJSYWlsV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHN0eWxlU2hlZXQuc2xpZGVyUmFpbEZpbGxDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuc2xpZGVyUmFpbEJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5zbGlkZXJSYWlsQm9yZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduOiAncmFpbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFjaW5nOiA0LFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LnNsaWRlckxhYmVsVGV4dEZpbGxDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogc3R5bGVTaGVldC5zbGlkZXJMYWJlbFRleHRGb250U2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lSGVpZ2h0OiBzdHlsZVNoZWV0LnNsaWRlckxhYmVsVGV4dExpbmVIZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiBzdHlsZVNoZWV0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBzdHlsZVNoZWV0LnNsaWRlckhhbmRsZXJXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogc3R5bGVTaGVldC5zbGlkZXJIYW5kbGVyRmlsbENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5zbGlkZXJIYW5kbGVyQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzbGlkYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIC8vIOWbvuS+i+S4juWbm+adoei+ueS5i+mXtOeahOmXtOi3nVxuICAgICAgICAgICAgICAgIG1hcmdpbjogWzAsIDAsIDAsIDBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgICBzaG93Q29udGVudDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBmb2xsb3c6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dNYXJrZXJzOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNoYXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZW50ZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2F1dG8nLFxuICAgICAgICAgICAgICAgIG1hcmtlcjoge1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICAgICAgc2hhZG93Qmx1cjogMTAsXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd09mZnNldFg6IDAsXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd09mZlNldFk6IDAsXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd0NvbG9yOiAncmdiYSgwLDAsMCwwLjA5KScsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNyb3NzaGFpcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQudG9vbHRpcENyb3NzaGFpcnNCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQudG9vbHRpcENyb3NzaGFpcnNCb3JkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFja2dyb3VuZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC4yNSknLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBmb2xsb3c6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgLy8gdG9vbHRpcCBkb20g5qC35byPXG4gICAgICAgICAgICAgICAgZG9tU3R5bGVzOiAoX2EgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgX2FbXCJcIiArIFRPT0xUSVBfQ1NTX0NPTlNULkNPTlRBSU5FUl9DTEFTU10gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgekluZGV4OiA4LFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogJ2xlZnQgMC40cyBjdWJpYy1iZXppZXIoMC4yMywgMSwgMC4zMiwgMSkgMHMsIHRvcCAwLjRzIGN1YmljLWJlemllcigwLjIzLCAxLCAwLjMyLCAxKSAwcycsXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHN0eWxlU2hlZXQudG9vbHRpcENvbnRhaW5lckZpbGxDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IHN0eWxlU2hlZXQudG9vbHRpcENvbnRhaW5lckZpbGxPcGFjaXR5LFxuICAgICAgICAgICAgICAgICAgICAgICAgYm94U2hhZG93OiBzdHlsZVNoZWV0LnRvb2x0aXBDb250YWluZXJTaGFkb3csXG4gICAgICAgICAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6IHN0eWxlU2hlZXQudG9vbHRpcENvbnRhaW5lckJvcmRlclJhZGl1cyArIFwicHhcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yOiBzdHlsZVNoZWV0LnRvb2x0aXBUZXh0RmlsbENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IHN0eWxlU2hlZXQudG9vbHRpcFRleHRGb250U2l6ZSArIFwicHhcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6IHN0eWxlU2hlZXQuZm9udEZhbWlseSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IHN0eWxlU2hlZXQudG9vbHRpcFRleHRMaW5lSGVpZ2h0ICsgXCJweFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogJzAgMTJweCAwIDEycHgnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBfYVtcIlwiICsgVE9PTFRJUF9DU1NfQ09OU1QuVElUTEVfQ0xBU1NdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5Ub3A6ICcxMnB4JyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgX2FbXCJcIiArIFRPT0xUSVBfQ1NTX0NPTlNULkxJU1RfQ0xBU1NdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdFN0eWxlVHlwZTogJ25vbmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogMCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgX2FbXCJcIiArIFRPT0xUSVBfQ1NTX0NPTlNULkxJU1RfSVRFTV9DTEFTU10gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaXN0U3R5bGVUeXBlOiAnbm9uZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5Ub3A6ICcxMnB4JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbkxlZnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5SaWdodDogMCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgX2FbXCJcIiArIFRPT0xUSVBfQ1NTX0NPTlNULk1BUktFUl9DTEFTU10gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogJzhweCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6ICc4cHgnLFxuICAgICAgICAgICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6ICdpbmxpbmUtYmxvY2snLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luUmlnaHQ6ICc4cHgnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBfYVtcIlwiICsgVE9PTFRJUF9DU1NfQ09OU1QuVkFMVUVfQ0xBU1NdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaycsXG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdDogJ3JpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbkxlZnQ6ICczMHB4JyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgX2EpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFubm90YXRpb246IHtcbiAgICAgICAgICAgICAgICBhcmM6IHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5hbm5vdGF0aW9uQXJjQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYW5ub3RhdGlvbkFyY0JvcmRlcixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5hbm5vdGF0aW9uTGluZUJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZURhc2g6IHN0eWxlU2hlZXQuYW5ub3RhdGlvbkxpbmVEYXNoLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LmFubm90YXRpb25MaW5lQm9yZGVyLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Qm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Qm9yZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Rm9udFNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6IHN0eWxlU2hlZXQuZm9udEZhbWlseSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdib3R0b20nLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5hbm5vdGF0aW9uVGV4dEJvcmRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Rm9udFNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogc3R5bGVTaGVldC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhbmltYXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnaW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIHRvcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblJlZ2lvbkJvcmRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5hbm5vdGF0aW9uUmVnaW9uQm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmFubm90YXRpb25SZWdpb25GaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eTogc3R5bGVTaGVldC5hbm5vdGF0aW9uUmVnaW9uRmlsbE9wYWNpdHksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbWFnZToge1xuICAgICAgICAgICAgICAgICAgICB0b3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBhbmltYXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGF0YU1hcmtlcjoge1xuICAgICAgICAgICAgICAgICAgICB0b3A6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHBvaW50OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHI6IDMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmJyYW5kQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAyLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuYW5ub3RhdGlvbkxpbmVCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYW5ub3RhdGlvbkxpbmVCb3JkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiBzdHlsZVNoZWV0LmFubm90YXRpb25EYXRhTWFya2VyTGluZUxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdGV4dDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdzdGFydCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogc3R5bGVTaGVldC5hbm5vdGF0aW9uVGV4dEZpbGxDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRCb3JkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRGb250U2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiBzdHlsZVNoZWV0LmZvbnRGYW1pbHksXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246ICd1cHdhcmQnLFxuICAgICAgICAgICAgICAgICAgICBhdXRvQWRqdXN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhbmltYXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGF0YVJlZ2lvbjoge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogc3R5bGVTaGVldC5hbm5vdGF0aW9uUmVnaW9uRmlsbENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBzdHlsZVNoZWV0LmFubm90YXRpb25SZWdpb25GaWxsT3BhY2l0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdib3R0b20nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IHN0eWxlU2hlZXQuYW5ub3RhdGlvblRleHRGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Qm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Qm9yZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiBzdHlsZVNoZWV0LmFubm90YXRpb25UZXh0Rm9udFNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogc3R5bGVTaGVldC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgICBvZmZzZXQ6IDEyLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmxhYmVsRmlsbENvbG9yLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiBzdHlsZVNoZWV0LmxhYmVsRm9udFNpemUsXG4gICAgICAgICAgICAgICAgZm9udEZhbWlseTogc3R5bGVTaGVldC5mb250RmFtaWx5LFxuICAgICAgICAgICAgICAgIHN0cm9rZTogc3R5bGVTaGVldC5sYWJlbEJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5sYWJlbEJvcmRlcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBpbm5lckxhYmVsczoge1xuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBzdHlsZVNoZWV0LmlubmVyTGFiZWxGaWxsQ29sb3IsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6IHN0eWxlU2hlZXQuaW5uZXJMYWJlbEZvbnRTaXplLFxuICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6IHN0eWxlU2hlZXQuZm9udEZhbWlseSxcbiAgICAgICAgICAgICAgICBzdHJva2U6IHN0eWxlU2hlZXQuaW5uZXJMYWJlbEJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5pbm5lckxhYmVsQm9yZGVyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHBpZUxhYmVsczoge1xuICAgICAgICAgICAgbGFiZWxIZWlnaHQ6IDE0LFxuICAgICAgICAgICAgb2Zmc2V0OiAzMCxcbiAgICAgICAgICAgIGxhYmVsTGluZToge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGVTaGVldC5sYWJlbExpbmVCb3JkZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICB9LFxuICAgIH07XG59XG5leHBvcnRzLmNyZWF0ZVRoZW1lQnlTdHlsZXNoZWV0ID0gY3JlYXRlVGhlbWVCeVN0eWxlc2hlZXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0VG9vbHRpcEl0ZW1zID0gZXhwb3J0cy5maW5kRGF0YUJ5UG9pbnQgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50XCIpO1xudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiLi9zY2FsZVwiKTtcbmZ1bmN0aW9uIHNuYXBFcXVhbCh2MSwgdjIsIHNjYWxlKSB7XG4gICAgdmFyIHZhbHVlMSA9IHNjYWxlLnRyYW5zbGF0ZSh2MSk7XG4gICAgdmFyIHZhbHVlMiA9IHNjYWxlLnRyYW5zbGF0ZSh2Mik7XG4gICAgcmV0dXJuIHV0aWxfMS5pc051bWJlckVxdWFsKHZhbHVlMSwgdmFsdWUyKTtcbn1cbmZ1bmN0aW9uIGdldFhWYWx1ZUJ5UG9pbnQocG9pbnQsIGdlb21ldHJ5KSB7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBnZW9tZXRyeS5jb29yZGluYXRlO1xuICAgIHZhciB4U2NhbGUgPSBnZW9tZXRyeS5nZXRYU2NhbGUoKTtcbiAgICB2YXIgcmFuZ2UgPSB4U2NhbGUucmFuZ2U7XG4gICAgdmFyIHJhbmdlTWF4ID0gcmFuZ2VbcmFuZ2UubGVuZ3RoIC0gMV07XG4gICAgdmFyIHJhbmdlTWluID0gcmFuZ2VbMF07XG4gICAgdmFyIGludmVydFBvaW50ID0gY29vcmRpbmF0ZS5pbnZlcnQocG9pbnQpO1xuICAgIHZhciB4VmFsdWUgPSBpbnZlcnRQb2ludC54O1xuICAgIGlmIChjb29yZGluYXRlLmlzUG9sYXIgJiYgeFZhbHVlID4gKDEgKyByYW5nZU1heCkgLyAyKSB7XG4gICAgICAgIHhWYWx1ZSA9IHJhbmdlTWluOyAvLyDmnoHlnZDmoIfkuIvvvIxzY2FsZSDnmoQgcmFuZ2Ug6KKr5YGa6L+H54m55q6K5aSE55CGXG4gICAgfVxuICAgIHJldHVybiB4U2NhbGUudHJhbnNsYXRlKHhTY2FsZS5pbnZlcnQoeFZhbHVlKSk7XG59XG5mdW5jdGlvbiBmaWx0ZXJZVmFsdWUoZGF0YSwgcG9pbnQsIGdlb21ldHJ5KSB7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBnZW9tZXRyeS5jb29yZGluYXRlO1xuICAgIHZhciB5U2NhbGUgPSBnZW9tZXRyeS5nZXRZU2NhbGUoKTtcbiAgICB2YXIgeUZpZWxkID0geVNjYWxlLmZpZWxkO1xuICAgIHZhciBpbnZlcnRQb2ludCA9IGNvb3JkaW5hdGUuaW52ZXJ0KHBvaW50KTtcbiAgICB2YXIgeVZhbHVlID0geVNjYWxlLmludmVydChpbnZlcnRQb2ludC55KTtcbiAgICB2YXIgcmVzdWx0ID0gdXRpbF8xLmZpbmQoZGF0YSwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICB2YXIgb3JpZ2luRGF0YSA9IG9ialtjb25zdGFudF8xLkZJRUxEX09SSUdJTl07XG4gICAgICAgIHJldHVybiBvcmlnaW5EYXRhW3lGaWVsZF1bMF0gPD0geVZhbHVlICYmIG9yaWdpbkRhdGFbeUZpZWxkXVsxXSA+PSB5VmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdCB8fCBkYXRhW2RhdGEubGVuZ3RoIC0gMV07XG59XG52YXIgZ2V0WERpc3RhbmNlID0gdXRpbF8xLm1lbW9pemUoZnVuY3Rpb24gKHNjYWxlKSB7XG4gICAgaWYgKHNjYWxlLmlzQ2F0ZWdvcnkpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIHZhciBzY2FsZVZhbHVlcyA9IHNjYWxlLnZhbHVlczsgLy8gdmFsdWVzIOaYr+aXoOW6j+eahFxuICAgIHZhciBsZW5ndGggPSBzY2FsZVZhbHVlcy5sZW5ndGg7XG4gICAgdmFyIG1pbiA9IHNjYWxlLnRyYW5zbGF0ZShzY2FsZVZhbHVlc1swXSk7XG4gICAgdmFyIG1heCA9IG1pbjtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHNjYWxlVmFsdWVzW2luZGV4XTtcbiAgICAgICAgLy8g5pe26Ze057G75Z6L6ZyA6KaBIHRyYW5zbGF0ZVxuICAgICAgICB2YXIgbnVtZXJpY1ZhbHVlID0gc2NhbGUudHJhbnNsYXRlKHZhbHVlKTtcbiAgICAgICAgaWYgKG51bWVyaWNWYWx1ZSA8IG1pbikge1xuICAgICAgICAgICAgbWluID0gbnVtZXJpY1ZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChudW1lcmljVmFsdWUgPiBtYXgpIHtcbiAgICAgICAgICAgIG1heCA9IG51bWVyaWNWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gKG1heCAtIG1pbikgLyAobGVuZ3RoIC0gMSk7XG59KTtcbmZ1bmN0aW9uIGdldFRvb2x0aXBUaXRsZShvcmlnaW5EYXRhLCBnZW9tZXRyeSwgdGl0bGUpIHtcbiAgICB2YXIgdGl0bGVGaWVsZCA9IHRpdGxlO1xuICAgIGlmICghdGl0bGUpIHtcbiAgICAgICAgdmFyIHBvc2l0aW9uQXR0ciA9IGdlb21ldHJ5LmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKTtcbiAgICAgICAgdmFyIGZpZWxkcyA9IHBvc2l0aW9uQXR0ci5nZXRGaWVsZHMoKTtcbiAgICAgICAgdGl0bGVGaWVsZCA9IGZpZWxkc1swXTtcbiAgICB9XG4gICAgdmFyIHNjYWxlcyA9IGdlb21ldHJ5LnNjYWxlcztcbiAgICBpZiAoc2NhbGVzW3RpdGxlRmllbGRdKSB7XG4gICAgICAgIC8vIOWmguaenOWIm+W7uuS6huivpeWtl+auteWvueW6lOeahCBzY2FsZe+8jOWImemAmui/hyBzY2FsZS5nZXRUZXh0KCkg5pa55byP5Y+W5YC877yM5Zug5Li655So5oi35Y+v6IO95a+55pWw5o2u6L+b6KGM5LqG5qC85byP5YyWXG4gICAgICAgIHJldHVybiBzY2FsZXNbdGl0bGVGaWVsZF0uZ2V0VGV4dChvcmlnaW5EYXRhW3RpdGxlRmllbGRdKTtcbiAgICB9XG4gICAgLy8g5aaC5p6c5rKh5pyJ5a+55bqU55qEIHNjYWxl77yM5YiZ5LuO5Y6f5aeL5pWw5o2u5Lit5Y+W5YC877yM5aaC5p6c5Y6f5aeL5pWw5o2u5Lit5LuN5LiN5a2Y5Zyo77yM5YiZ55u05o6l5pS+5ZueIHRpdGxlIOWAvFxuICAgIHJldHVybiB1dGlsXzEuaGFzS2V5KG9yaWdpbkRhdGEsIHRpdGxlRmllbGQpID8gb3JpZ2luRGF0YVt0aXRsZUZpZWxkXSA6IHRpdGxlRmllbGQ7XG59XG5mdW5jdGlvbiBnZXRBdHRyaWJ1dGVzRm9yTGVnZW5kKGdlb21ldHJ5KSB7XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSB1dGlsXzEudmFsdWVzKGdlb21ldHJ5LmF0dHJpYnV0ZXMpO1xuICAgIHJldHVybiB1dGlsXzEuZmlsdGVyKGF0dHJpYnV0ZXMsIGZ1bmN0aW9uIChhdHRyaWJ1dGUpIHsgcmV0dXJuIHV0aWxfMS5jb250YWlucyhjb25zdGFudF8xLkdST1VQX0FUVFJTLCBhdHRyaWJ1dGUudHlwZSk7IH0pO1xufVxuZnVuY3Rpb24gZ2V0VG9vbHRpcFZhbHVlU2NhbGUoZ2VvbWV0cnkpIHtcbiAgICB2YXIgYXR0cmlidXRlcyA9IGdldEF0dHJpYnV0ZXNGb3JMZWdlbmQoZ2VvbWV0cnkpO1xuICAgIHZhciBzY2FsZTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIGF0dHJpYnV0ZXNfMSA9IGF0dHJpYnV0ZXM7IF9pIDwgYXR0cmlidXRlc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgYXR0cmlidXRlID0gYXR0cmlidXRlc18xW19pXTtcbiAgICAgICAgdmFyIHRtcFNjYWxlID0gYXR0cmlidXRlLmdldFNjYWxlKGF0dHJpYnV0ZS50eXBlKTtcbiAgICAgICAgaWYgKHRtcFNjYWxlICYmIHRtcFNjYWxlLmlzTGluZWFyKSB7XG4gICAgICAgICAgICAvLyDlpoLmnpzmjIflrprlrZfmrrXmmK/pnZ4gcG9zaXRpb24g55qE77yM5ZCM5pe25piv6L+e57ut55qEXG4gICAgICAgICAgICBzY2FsZSA9IHRtcFNjYWxlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIHhTY2FsZSA9IGdlb21ldHJ5LmdldFhTY2FsZSgpO1xuICAgIHZhciB5U2NhbGUgPSBnZW9tZXRyeS5nZXRZU2NhbGUoKTtcbiAgICByZXR1cm4gc2NhbGUgfHwgeVNjYWxlIHx8IHhTY2FsZTtcbn1cbmZ1bmN0aW9uIGdldFRvb2x0aXBWYWx1ZShvcmlnaW5EYXRhLCB2YWx1ZVNjYWxlKSB7XG4gICAgdmFyIGZpZWxkID0gdmFsdWVTY2FsZS5maWVsZDtcbiAgICB2YXIgdmFsdWUgPSBvcmlnaW5EYXRhW2ZpZWxkXTtcbiAgICBpZiAodXRpbF8xLmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHZhciB0ZXh0cyA9IHZhbHVlLm1hcChmdW5jdGlvbiAoZWFjaFZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVTY2FsZS5nZXRUZXh0KGVhY2hWYWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGV4dHMuam9pbignLScpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVTY2FsZS5nZXRUZXh0KHZhbHVlKTtcbn1cbi8vIOagueaNruWOn+Wni+aVsOaNruiOt+WPliB0b29sdGlwIGl0ZW0g5LitIG5hbWUg5YC8XG5mdW5jdGlvbiBnZXRUb29sdGlwTmFtZShvcmlnaW5EYXRhLCBnZW9tZXRyeSkge1xuICAgIHZhciBuYW1lU2NhbGU7XG4gICAgdmFyIGdyb3VwU2NhbGVzID0gZ2VvbWV0cnkuZ2V0R3JvdXBTY2FsZXMoKTtcbiAgICBpZiAoZ3JvdXBTY2FsZXMubGVuZ3RoKSB7XG4gICAgICAgIC8vIOWmguaenOWtmOWcqOWIhue7hOexu+Wei++8jOWPluesrOS4gOS4quWIhue7hOexu+Wei1xuICAgICAgICBuYW1lU2NhbGUgPSBncm91cFNjYWxlc1swXTtcbiAgICB9XG4gICAgaWYgKG5hbWVTY2FsZSkge1xuICAgICAgICB2YXIgZmllbGQgPSBuYW1lU2NhbGUuZmllbGQ7XG4gICAgICAgIHJldHVybiBuYW1lU2NhbGUuZ2V0VGV4dChvcmlnaW5EYXRhW2ZpZWxkXSk7XG4gICAgfVxuICAgIHZhciB2YWx1ZVNjYWxlID0gZ2V0VG9vbHRpcFZhbHVlU2NhbGUoZ2VvbWV0cnkpO1xuICAgIHJldHVybiBzY2FsZV8xLmdldE5hbWUodmFsdWVTY2FsZSk7XG59XG4vKipcbiAqIEBpZ25vcmVcbiAqIEZpbmRzIGRhdGEgZnJvbSBnZW9tZXRyeSBieSBwb2ludFxuICogQHBhcmFtIHBvaW50IGNhbnZhcyBwb2ludFxuICogQHBhcmFtIGRhdGEgYW4gaXRlbSBvZiBnZW9tZXRyeS5kYXRhQXJyYXlcbiAqIEBwYXJhbSBnZW9tZXRyeVxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZmluZERhdGFCeVBvaW50KHBvaW50LCBkYXRhLCBnZW9tZXRyeSkge1xuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIGdlb21ldHJ5VHlwZSA9IGdlb21ldHJ5LnR5cGU7XG4gICAgdmFyIHhTY2FsZSA9IGdlb21ldHJ5LmdldFhTY2FsZSgpO1xuICAgIHZhciB5U2NhbGUgPSBnZW9tZXRyeS5nZXRZU2NhbGUoKTtcbiAgICB2YXIgeEZpZWxkID0geFNjYWxlLmZpZWxkO1xuICAgIHZhciB5RmllbGQgPSB5U2NhbGUuZmllbGQ7XG4gICAgdmFyIHJzdCA9IG51bGw7XG4gICAgLy8g54Ot5Yqb5Zu+6YeH55So5pyA5bCP6YC86L+R562W55Wl5p+l5om+IHBvaW50IOWHu+S4reeahOaVsOaNrlxuICAgIGlmIChnZW9tZXRyeVR5cGUgPT09ICdoZWF0bWFwJyB8fCBnZW9tZXRyeVR5cGUgPT09ICdwb2ludCcpIHtcbiAgICAgICAgLy8g5bCGIHBvaW50IOeUu+W4g+WdkOagh+i9rOaNouS4uuWOn+Wni+aVsOaNruWAvFxuICAgICAgICB2YXIgY29vcmRpbmF0ZSA9IGdlb21ldHJ5LmNvb3JkaW5hdGU7XG4gICAgICAgIHZhciBpbnZlcnRQb2ludCA9IGNvb3JkaW5hdGUuaW52ZXJ0KHBvaW50KTsgLy8g6L2s5o2i5oiQ5b2S5LiA5YyW55qE5pWw5o2uXG4gICAgICAgIHZhciB4ID0geFNjYWxlLmludmVydChpbnZlcnRQb2ludC54KTsgLy8g6L2s5o2i5Li65Y6f5aeL5YC8XG4gICAgICAgIHZhciB5ID0geVNjYWxlLmludmVydChpbnZlcnRQb2ludC55KTsgLy8g6L2s5o2i5Li65Y6f5aeL5YC8XG4gICAgICAgIHZhciBtaW4gPSBJbmZpbml0eTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGRhdGEubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgb2JqID0gZGF0YVtpbmRleF07XG4gICAgICAgICAgICB2YXIgb3JpZ2luRGF0YSA9IG9ialtjb25zdGFudF8xLkZJRUxEX09SSUdJTl07XG4gICAgICAgICAgICB2YXIgcmFuZ2UgPSBNYXRoLnBvdygob3JpZ2luRGF0YVt4RmllbGRdIC0geCksIDIpICsgTWF0aC5wb3coKG9yaWdpbkRhdGFbeUZpZWxkXSAtIHkpLCAyKTtcbiAgICAgICAgICAgIGlmIChyYW5nZSA8IG1pbikge1xuICAgICAgICAgICAgICAgIG1pbiA9IHJhbmdlO1xuICAgICAgICAgICAgICAgIHJzdCA9IG9iajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcnN0O1xuICAgIH1cbiAgICAvLyDlhbbku5YgR2VvbWV0cnkg57G75Z6L5oyJ54WnIHgg5a2X5q615pWw5o2u6L+b6KGM5p+l5om+XG4gICAgdmFyIGZpcnN0ID0gZGF0YVswXTtcbiAgICB2YXIgbGFzdCA9IGRhdGFbZGF0YS5sZW5ndGggLSAxXTtcbiAgICB2YXIgeFZhbHVlID0gZ2V0WFZhbHVlQnlQb2ludChwb2ludCwgZ2VvbWV0cnkpO1xuICAgIHZhciBmaXJzdFhWYWx1ZSA9IGZpcnN0W2NvbnN0YW50XzEuRklFTERfT1JJR0lOXVt4RmllbGRdO1xuICAgIHZhciBmaXJzdFlWYWx1ZSA9IGZpcnN0W2NvbnN0YW50XzEuRklFTERfT1JJR0lOXVt5RmllbGRdO1xuICAgIHZhciBsYXN0WFZhbHVlID0gbGFzdFtjb25zdGFudF8xLkZJRUxEX09SSUdJTl1beEZpZWxkXTtcbiAgICB2YXIgaXNZQXJyYXkgPSB5U2NhbGUuaXNMaW5lYXIgJiYgdXRpbF8xLmlzQXJyYXkoZmlyc3RZVmFsdWUpOyAvLyDogIPomZEgeCDnu7Tluqbnm7jlkIzvvIx5IOaYr+aVsOe7hOWMuumXtOeahOaDheWGtVxuICAgIC8vIOWmguaenCB4IOeahOWAvOaYr+aVsOe7hFxuICAgIGlmICh1dGlsXzEuaXNBcnJheShmaXJzdFhWYWx1ZSkpIHtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGRhdGEubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgcmVjb3JkID0gZGF0YVtpbmRleF07XG4gICAgICAgICAgICB2YXIgb3JpZ2luRGF0YSA9IHJlY29yZFtjb25zdGFudF8xLkZJRUxEX09SSUdJTl07XG4gICAgICAgICAgICAvLyB4VmFsdWUg5ZyoIG9yaWdpbkRhdGFbeEZpZWxkXSDnmoTmlbDlgLzljLrpl7TlhoVcbiAgICAgICAgICAgIGlmICh4U2NhbGUudHJhbnNsYXRlKG9yaWdpbkRhdGFbeEZpZWxkXVswXSkgPD0geFZhbHVlICYmIHhTY2FsZS50cmFuc2xhdGUob3JpZ2luRGF0YVt4RmllbGRdWzFdKSA+PSB4VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNZQXJyYXkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5bGC5Y+g55u05pa55Zu+5Zy65pmv77yMeCDlkowgeSDpg73mmK/mlbDnu4TljLrpl7RcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNBcnJheShyc3QpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByc3QgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByc3QucHVzaChyZWNvcmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcnN0ID0gcmVjb3JkO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KHJzdCkpIHtcbiAgICAgICAgICAgIHJzdCA9IGZpbHRlcllWYWx1ZShyc3QsIHBvaW50LCBnZW9tZXRyeSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBuZXh0ID0gdm9pZCAwO1xuICAgICAgICBpZiAoIXhTY2FsZS5pc0xpbmVhciAmJiB4U2NhbGUudHlwZSAhPT0gJ3RpbWVDYXQnKSB7XG4gICAgICAgICAgICAvLyB4IOi9tOWvueW6lOeahOaVsOaNruS4uumdnue6v+aAp+S7peWPiumdnuaXtumXtOexu+Wei+eahOaVsOaNrumHh+eUqOmBjeWOhuafpeaJvlxuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGRhdGEubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlY29yZCA9IGRhdGFbaW5kZXhdO1xuICAgICAgICAgICAgICAgIHZhciBvcmlnaW5EYXRhID0gcmVjb3JkW2NvbnN0YW50XzEuRklFTERfT1JJR0lOXTtcbiAgICAgICAgICAgICAgICBpZiAoc25hcEVxdWFsKG9yaWdpbkRhdGFbeEZpZWxkXSwgeFZhbHVlLCB4U2NhbGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1lBcnJheSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNBcnJheShyc3QpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcnN0ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByc3QucHVzaChyZWNvcmQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcnN0ID0gcmVjb3JkO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoeFNjYWxlLnRyYW5zbGF0ZShvcmlnaW5EYXRhW3hGaWVsZF0pIDw9IHhWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0ID0gcmVjb3JkO1xuICAgICAgICAgICAgICAgICAgICBuZXh0ID0gZGF0YVtpbmRleCArIDFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheShyc3QpKSB7XG4gICAgICAgICAgICAgICAgcnN0ID0gZmlsdGVyWVZhbHVlKHJzdCwgcG9pbnQsIGdlb21ldHJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHgg6L205a+55bqU55qE5pWw5o2u5Li657q/5oCn5Lul5Y+K5pe26Ze057G75Z6L77yM6L+b6KGM5LqM5YiG5p+l5om+77yM5oCn6IO95pu05aW9XG4gICAgICAgICAgICBpZiAoKHhWYWx1ZSA+IHhTY2FsZS50cmFuc2xhdGUobGFzdFhWYWx1ZSkgfHwgeFZhbHVlIDwgeFNjYWxlLnRyYW5zbGF0ZShmaXJzdFhWYWx1ZSkpICYmXG4gICAgICAgICAgICAgICAgKHhWYWx1ZSA+IHhTY2FsZS5tYXggfHwgeFZhbHVlIDwgeFNjYWxlLm1pbikpIHtcbiAgICAgICAgICAgICAgICAvLyDkuI3lnKjmlbDmja7ojIPlm7TlhoVcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBmaXJzdElkeCA9IDA7XG4gICAgICAgICAgICB2YXIgbGFzdElkeCA9IGRhdGEubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIHZhciBtaWRkbGVJZHggPSB2b2lkIDA7XG4gICAgICAgICAgICB3aGlsZSAoZmlyc3RJZHggPD0gbGFzdElkeCkge1xuICAgICAgICAgICAgICAgIG1pZGRsZUlkeCA9IE1hdGguZmxvb3IoKGZpcnN0SWR4ICsgbGFzdElkeCkgLyAyKTtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGRhdGFbbWlkZGxlSWR4XVtjb25zdGFudF8xLkZJRUxEX09SSUdJTl1beEZpZWxkXTtcbiAgICAgICAgICAgICAgICBpZiAoc25hcEVxdWFsKGl0ZW0sIHhWYWx1ZSwgeFNjYWxlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVttaWRkbGVJZHhdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoeFNjYWxlLnRyYW5zbGF0ZShpdGVtKSA8PSB4U2NhbGUudHJhbnNsYXRlKHhWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RJZHggPSBtaWRkbGVJZHggKyAxO1xuICAgICAgICAgICAgICAgICAgICBsYXN0ID0gZGF0YVttaWRkbGVJZHhdO1xuICAgICAgICAgICAgICAgICAgICBuZXh0ID0gZGF0YVttaWRkbGVJZHggKyAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsYXN0SWR4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0ID0gZGF0YVswXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBsYXN0SWR4ID0gbWlkZGxlSWR4IC0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhc3QgJiYgbmV4dCkge1xuICAgICAgICAgICAgLy8g6K6h566X5pyA6YC86L+R55qEXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoeFNjYWxlLnRyYW5zbGF0ZShsYXN0W2NvbnN0YW50XzEuRklFTERfT1JJR0lOXVt4RmllbGRdKSAtIHhWYWx1ZSkgPlxuICAgICAgICAgICAgICAgIE1hdGguYWJzKHhTY2FsZS50cmFuc2xhdGUobmV4dFtjb25zdGFudF8xLkZJRUxEX09SSUdJTl1beEZpZWxkXSkgLSB4VmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgbGFzdCA9IG5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIGRpc3RhbmNlID0gZ2V0WERpc3RhbmNlKGdlb21ldHJ5LmdldFhTY2FsZSgpKTsgLy8g5q+P5Liq5YiG57G76Ze055qE5bmz5Z2H6Ze06LedXG4gICAgaWYgKCFyc3QgJiYgTWF0aC5hYnMoeFNjYWxlLnRyYW5zbGF0ZShsYXN0W2NvbnN0YW50XzEuRklFTERfT1JJR0lOXVt4RmllbGRdKSAtIHhWYWx1ZSkgPD0gZGlzdGFuY2UgLyAyKSB7XG4gICAgICAgIHJzdCA9IGxhc3Q7XG4gICAgfVxuICAgIHJldHVybiByc3Q7XG59XG5leHBvcnRzLmZpbmREYXRhQnlQb2ludCA9IGZpbmREYXRhQnlQb2ludDtcbi8qKlxuICogQGlnbm9yZVxuICogR2V0cyB0b29sdGlwIGl0ZW1zXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIGdlb21ldHJ5XG4gKiBAcGFyYW0gW3RpdGxlXVxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0VG9vbHRpcEl0ZW1zKGRhdGEsIGdlb21ldHJ5LCB0aXRsZSkge1xuICAgIGlmICh0aXRsZSA9PT0gdm9pZCAwKSB7IHRpdGxlID0gJyc7IH1cbiAgICB2YXIgb3JpZ2luRGF0YSA9IGRhdGFbY29uc3RhbnRfMS5GSUVMRF9PUklHSU5dO1xuICAgIHZhciB0b29sdGlwVGl0bGUgPSBnZXRUb29sdGlwVGl0bGUob3JpZ2luRGF0YSwgZ2VvbWV0cnksIHRpdGxlKTtcbiAgICB2YXIgdG9vbHRpcE9wdGlvbiA9IGdlb21ldHJ5LnRvb2x0aXBPcHRpb247XG4gICAgdmFyIGRlZmF1bHRDb2xvciA9IGdlb21ldHJ5LnRoZW1lLmRlZmF1bHRDb2xvcjtcbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB2YXIgbmFtZTtcbiAgICB2YXIgdmFsdWU7XG4gICAgZnVuY3Rpb24gYWRkSXRlbShpdGVtTmFtZSwgaXRlbVZhbHVlKSB7XG4gICAgICAgIGlmICghdXRpbF8xLmlzTmlsKGl0ZW1WYWx1ZSkgJiYgaXRlbVZhbHVlICE9PSAnJykge1xuICAgICAgICAgICAgLy8g5YC85Li6IG51bGznmoTml7blgJnvvIzlv73op4ZcbiAgICAgICAgICAgIHZhciBpdGVtID0ge1xuICAgICAgICAgICAgICAgIHRpdGxlOiB0b29sdGlwVGl0bGUsXG4gICAgICAgICAgICAgICAgZGF0YTogb3JpZ2luRGF0YSxcbiAgICAgICAgICAgICAgICBtYXBwaW5nRGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICBuYW1lOiBpdGVtTmFtZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogaXRlbVZhbHVlLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBkYXRhLmNvbG9yIHx8IGRlZmF1bHRDb2xvcixcbiAgICAgICAgICAgICAgICBtYXJrZXI6IHRydWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaXRlbXMucHVzaChpdGVtKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAodXRpbF8xLmlzT2JqZWN0KHRvb2x0aXBPcHRpb24pKSB7XG4gICAgICAgIHZhciBmaWVsZHMgPSB0b29sdGlwT3B0aW9uLmZpZWxkcywgY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9uLmNhbGxiYWNrO1xuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIC8vIOeUqOaIt+WumuS5ieS6huWbnuiwg+WHveaVsFxuICAgICAgICAgICAgdmFyIGNhbGxiYWNrUGFyYW1zID0gZmllbGRzLm1hcChmdW5jdGlvbiAoZmllbGQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtjb25zdGFudF8xLkZJRUxEX09SSUdJTl1bZmllbGRdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgY2ZnID0gY2FsbGJhY2suYXBwbHkodm9pZCAwLCBjYWxsYmFja1BhcmFtcyk7XG4gICAgICAgICAgICB2YXIgaXRlbUNmZyA9IHRzbGliXzEuX19hc3NpZ24oeyBkYXRhOiBkYXRhW2NvbnN0YW50XzEuRklFTERfT1JJR0lOXSwgbWFwcGluZ0RhdGE6IGRhdGEsIHRpdGxlOiB0b29sdGlwVGl0bGUsIGNvbG9yOiBkYXRhLmNvbG9yIHx8IGRlZmF1bHRDb2xvciwgbWFya2VyOiB0cnVlIH0sIGNmZyk7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKGl0ZW1DZmcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHNjYWxlcyA9IGdlb21ldHJ5LnNjYWxlcztcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgZmllbGRzXzEgPSBmaWVsZHM7IF9pIDwgZmllbGRzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gZmllbGRzXzFbX2ldO1xuICAgICAgICAgICAgICAgIGlmICghdXRpbF8xLmlzTmlsKG9yaWdpbkRhdGFbZmllbGRdKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlrZfmrrXmlbDmja7kuLpudWxsLCB1bmRlZmluZWQg5pe25LiN5pi+56S6XG4gICAgICAgICAgICAgICAgICAgIHZhciBzY2FsZSA9IHNjYWxlc1tmaWVsZF07XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBzY2FsZV8xLmdldE5hbWUoc2NhbGUpO1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHNjYWxlLmdldFRleHQob3JpZ2luRGF0YVtmaWVsZF0pO1xuICAgICAgICAgICAgICAgICAgICBhZGRJdGVtKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciB2YWx1ZVNjYWxlID0gZ2V0VG9vbHRpcFZhbHVlU2NhbGUoZ2VvbWV0cnkpO1xuICAgICAgICBpZiAoIXV0aWxfMS5pc05pbChvcmlnaW5EYXRhW3ZhbHVlU2NhbGUuZmllbGRdKSkge1xuICAgICAgICAgICAgLy8g5a2X5q615pWw5o2u5Li6bnVsbCAsdW5kZWZpbmVk5pe25LiN5pi+56S6XG4gICAgICAgICAgICB2YWx1ZSA9IGdldFRvb2x0aXBWYWx1ZShvcmlnaW5EYXRhLCB2YWx1ZVNjYWxlKTtcbiAgICAgICAgICAgIG5hbWUgPSBnZXRUb29sdGlwTmFtZShvcmlnaW5EYXRhLCBnZW9tZXRyeSk7XG4gICAgICAgICAgICBhZGRJdGVtKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG59XG5leHBvcnRzLmdldFRvb2x0aXBJdGVtcyA9IGdldFRvb2x0aXBJdGVtcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRvb2x0aXAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnpvb20gPSBleHBvcnRzLmdldElkZW50aXR5TWF0cml4ID0gZXhwb3J0cy5yb3RhdGUgPSBleHBvcnRzLnRyYW5zbGF0ZSA9IGV4cG9ydHMudHJhbnNmb3JtID0gdm9pZCAwO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgdHJhbnNmb3JtID0gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtO1xuZXhwb3J0cy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4vKipcbiAqIOWvueWFg+e0oOi/m+ihjOW5s+enu+aTjeS9nOOAglxuICogQHBhcmFtIGVsZW1lbnQg6L+b6KGM5Y+Y5o2i55qE5YWD57SgXG4gKiBAcGFyYW0geCB4IOaWueWQkeS9jeenu1xuICogQHBhcmFtIHkgeSDmlrnlkJHkvY3np7tcbiAqL1xuZnVuY3Rpb24gdHJhbnNsYXRlKGVsZW1lbnQsIHgsIHkpIHtcbiAgICB2YXIgbWF0cml4ID0gdHJhbnNmb3JtKGVsZW1lbnQuZ2V0TWF0cml4KCksIFtbJ3QnLCB4LCB5XV0pO1xuICAgIGVsZW1lbnQuc2V0TWF0cml4KG1hdHJpeCk7XG59XG5leHBvcnRzLnRyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbi8qKlxuICog5a+55YWD57Sg6L+b6KGM5peL6L2s5pON5L2c44CCXG4gKiBAcGFyYW0gZWxlbWVudCDov5vooYzlj5jmjaLnmoTlhYPntKBcbiAqIEBwYXJhbSByb3RhdGVSYWRpYW4g5peL6L2s5byn5bqmXG4gKi9cbmZ1bmN0aW9uIHJvdGF0ZShlbGVtZW50LCByb3RhdGVSYWRpYW4pIHtcbiAgICB2YXIgX2EgPSBlbGVtZW50LmF0dHIoKSwgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgIHZhciBtYXRyaXggPSB0cmFuc2Zvcm0oZWxlbWVudC5nZXRNYXRyaXgoKSwgW1xuICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICBbJ3InLCByb3RhdGVSYWRpYW5dLFxuICAgICAgICBbJ3QnLCB4LCB5XSxcbiAgICBdKTtcbiAgICBlbGVtZW50LnNldE1hdHJpeChtYXRyaXgpO1xufVxuZXhwb3J0cy5yb3RhdGUgPSByb3RhdGU7XG4vKipcbiAqIOiOt+WPluWFg+efqemYteOAglxuICogQHJldHVybnMgaWRlbnRpdHkgbWF0cml4XG4gKi9cbmZ1bmN0aW9uIGdldElkZW50aXR5TWF0cml4KCkge1xuICAgIHJldHVybiBbMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMV07XG59XG5leHBvcnRzLmdldElkZW50aXR5TWF0cml4ID0gZ2V0SWRlbnRpdHlNYXRyaXg7XG4vKipcbiAqIOWbtOe7leWbvuW9ouS4reW/g+eCuei/m+ihjOe8qeaUvlxuICogQHBhcmFtIGVsZW1lbnQg6L+b6KGM57yp5pS+55qE5Zu+5b2i5YWD57SgXG4gKiBAcGFyYW0gcmF0aW8g57yp5pS+5q+U5L6LXG4gKi9cbmZ1bmN0aW9uIHpvb20oZWxlbWVudCwgcmF0aW8pIHtcbiAgICB2YXIgYmJveCA9IGVsZW1lbnQuZ2V0QkJveCgpO1xuICAgIHZhciB4ID0gKGJib3gubWluWCArIGJib3gubWF4WCkgLyAyO1xuICAgIHZhciB5ID0gKGJib3gubWluWSArIGJib3gubWF4WSkgLyAyO1xuICAgIGVsZW1lbnQuYXBwbHlUb01hdHJpeChbeCwgeSwgMV0pO1xuICAgIHZhciBtYXRyaXggPSB0cmFuc2Zvcm0oZWxlbWVudC5nZXRNYXRyaXgoKSwgW1xuICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICBbJ3MnLCByYXRpbywgcmF0aW9dLFxuICAgICAgICBbJ3QnLCB4LCB5XSxcbiAgICBdKTtcbiAgICBlbGVtZW50LnNldE1hdHJpeChtYXRyaXgpO1xufVxuZXhwb3J0cy56b29tID0gem9vbTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRyYW5zZm9ybS5qcy5tYXAiLCIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgZ2xvYmFsLCBkZWZpbmUsIFN5c3RlbSwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG52YXIgX19leHRlbmRzO1xyXG52YXIgX19hc3NpZ247XHJcbnZhciBfX3Jlc3Q7XHJcbnZhciBfX2RlY29yYXRlO1xyXG52YXIgX19wYXJhbTtcclxudmFyIF9fbWV0YWRhdGE7XHJcbnZhciBfX2F3YWl0ZXI7XHJcbnZhciBfX2dlbmVyYXRvcjtcclxudmFyIF9fZXhwb3J0U3RhcjtcclxudmFyIF9fdmFsdWVzO1xyXG52YXIgX19yZWFkO1xyXG52YXIgX19zcHJlYWQ7XHJcbnZhciBfX3NwcmVhZEFycmF5cztcclxudmFyIF9fYXdhaXQ7XHJcbnZhciBfX2FzeW5jR2VuZXJhdG9yO1xyXG52YXIgX19hc3luY0RlbGVnYXRvcjtcclxudmFyIF9fYXN5bmNWYWx1ZXM7XHJcbnZhciBfX21ha2VUZW1wbGF0ZU9iamVjdDtcclxudmFyIF9faW1wb3J0U3RhcjtcclxudmFyIF9faW1wb3J0RGVmYXVsdDtcclxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQ7XHJcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0O1xyXG52YXIgX19jcmVhdGVCaW5kaW5nO1xyXG4oZnVuY3Rpb24gKGZhY3RvcnkpIHtcclxuICAgIHZhciByb290ID0gdHlwZW9mIGdsb2JhbCA9PT0gXCJvYmplY3RcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IHR5cGVvZiB0aGlzID09PSBcIm9iamVjdFwiID8gdGhpcyA6IHt9O1xyXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XHJcbiAgICAgICAgZGVmaW5lKFwidHNsaWJcIiwgW1wiZXhwb3J0c1wiXSwgZnVuY3Rpb24gKGV4cG9ydHMpIHsgZmFjdG9yeShjcmVhdGVFeHBvcnRlcihyb290LCBjcmVhdGVFeHBvcnRlcihleHBvcnRzKSkpOyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgICAgZmFjdG9yeShjcmVhdGVFeHBvcnRlcihyb290LCBjcmVhdGVFeHBvcnRlcihtb2R1bGUuZXhwb3J0cykpKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGZhY3RvcnkoY3JlYXRlRXhwb3J0ZXIocm9vdCkpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gY3JlYXRlRXhwb3J0ZXIoZXhwb3J0cywgcHJldmlvdXMpIHtcclxuICAgICAgICBpZiAoZXhwb3J0cyAhPT0gcm9vdCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGlkLCB2KSB7IHJldHVybiBleHBvcnRzW2lkXSA9IHByZXZpb3VzID8gcHJldmlvdXMoaWQsIHYpIDogdjsgfTtcclxuICAgIH1cclxufSlcclxuKGZ1bmN0aW9uIChleHBvcnRlcikge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuXHJcbiAgICBfX2V4dGVuZHMgPSBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fcmVzdCA9IGZ1bmN0aW9uIChzLCBlKSB7XHJcbiAgICAgICAgdmFyIHQgPSB7fTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH07XHJcblxyXG4gICAgX19kZWNvcmF0ZSA9IGZ1bmN0aW9uIChkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgICAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fcGFyYW0gPSBmdW5jdGlvbiAocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fbWV0YWRhdGEgPSBmdW5jdGlvbiAobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgICAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2F3YWl0ZXIgPSBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICAgICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICAgICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgX19nZW5lcmF0b3IgPSBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xyXG4gICAgICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICAgICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICAgICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX2V4cG9ydFN0YXIgPSBmdW5jdGlvbihtLCBvKSB7XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICAgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfSk7XHJcbiAgICB9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICAgICAgb1trMl0gPSBtW2tdO1xyXG4gICAgfSk7XHJcblxyXG4gICAgX192YWx1ZXMgPSBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICAgICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICAgICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fcmVhZCA9IGZ1bmN0aW9uIChvLCBuKSB7XHJcbiAgICAgICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICAgICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgICAgIGZpbmFsbHkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcjtcclxuICAgIH07XHJcblxyXG4gICAgX19zcHJlYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fc3ByZWFkQXJyYXlzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgICAgICByZXR1cm4gcjtcclxuICAgIH07XHJcblxyXG4gICAgX19hd2FpdCA9IGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXN5bmNHZW5lcmF0b3IgPSBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICAgICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgICAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgICAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICAgICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX2FzeW5jRGVsZWdhdG9yID0gZnVuY3Rpb24gKG8pIHtcclxuICAgICAgICB2YXIgaSwgcDtcclxuICAgICAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxuICAgIH07XHJcblxyXG4gICAgX19hc3luY1ZhbHVlcyA9IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgICAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICAgICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX21ha2VUZW1wbGF0ZU9iamVjdCA9IGZ1bmN0aW9uIChjb29rZWQsIHJhdykge1xyXG4gICAgICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICAgICAgcmV0dXJuIGNvb2tlZDtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxuICAgIH0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxuICAgIH07XHJcblxyXG4gICAgX19pbXBvcnRTdGFyID0gZnVuY3Rpb24gKG1vZCkge1xyXG4gICAgICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcclxuICAgICAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIF9faW1wb3J0RGVmYXVsdCA9IGZ1bmN0aW9uIChtb2QpIHtcclxuICAgICAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcclxuICAgIH07XHJcblxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCA9IGZ1bmN0aW9uIChyZWNlaXZlciwgcHJpdmF0ZU1hcCkge1xyXG4gICAgICAgIGlmICghcHJpdmF0ZU1hcC5oYXMocmVjZWl2ZXIpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhdHRlbXB0ZWQgdG8gZ2V0IHByaXZhdGUgZmllbGQgb24gbm9uLWluc3RhbmNlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHJpdmF0ZU1hcC5nZXQocmVjZWl2ZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0ID0gZnVuY3Rpb24gKHJlY2VpdmVyLCBwcml2YXRlTWFwLCB2YWx1ZSkge1xyXG4gICAgICAgIGlmICghcHJpdmF0ZU1hcC5oYXMocmVjZWl2ZXIpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhdHRlbXB0ZWQgdG8gc2V0IHByaXZhdGUgZmllbGQgb24gbm9uLWluc3RhbmNlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwcml2YXRlTWFwLnNldChyZWNlaXZlciwgdmFsdWUpO1xyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgZXhwb3J0ZXIoXCJfX2V4dGVuZHNcIiwgX19leHRlbmRzKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3NpZ25cIiwgX19hc3NpZ24pO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3Jlc3RcIiwgX19yZXN0KTtcclxuICAgIGV4cG9ydGVyKFwiX19kZWNvcmF0ZVwiLCBfX2RlY29yYXRlKTtcclxuICAgIGV4cG9ydGVyKFwiX19wYXJhbVwiLCBfX3BhcmFtKTtcclxuICAgIGV4cG9ydGVyKFwiX19tZXRhZGF0YVwiLCBfX21ldGFkYXRhKTtcclxuICAgIGV4cG9ydGVyKFwiX19hd2FpdGVyXCIsIF9fYXdhaXRlcik7XHJcbiAgICBleHBvcnRlcihcIl9fZ2VuZXJhdG9yXCIsIF9fZ2VuZXJhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19leHBvcnRTdGFyXCIsIF9fZXhwb3J0U3Rhcik7XHJcbiAgICBleHBvcnRlcihcIl9fY3JlYXRlQmluZGluZ1wiLCBfX2NyZWF0ZUJpbmRpbmcpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3ZhbHVlc1wiLCBfX3ZhbHVlcyk7XHJcbiAgICBleHBvcnRlcihcIl9fcmVhZFwiLCBfX3JlYWQpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3NwcmVhZFwiLCBfX3NwcmVhZCk7XHJcbiAgICBleHBvcnRlcihcIl9fc3ByZWFkQXJyYXlzXCIsIF9fc3ByZWFkQXJyYXlzKTtcclxuICAgIGV4cG9ydGVyKFwiX19hd2FpdFwiLCBfX2F3YWl0KTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY0dlbmVyYXRvclwiLCBfX2FzeW5jR2VuZXJhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY0RlbGVnYXRvclwiLCBfX2FzeW5jRGVsZWdhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY1ZhbHVlc1wiLCBfX2FzeW5jVmFsdWVzKTtcclxuICAgIGV4cG9ydGVyKFwiX19tYWtlVGVtcGxhdGVPYmplY3RcIiwgX19tYWtlVGVtcGxhdGVPYmplY3QpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2ltcG9ydFN0YXJcIiwgX19pbXBvcnRTdGFyKTtcclxuICAgIGV4cG9ydGVyKFwiX19pbXBvcnREZWZhdWx0XCIsIF9faW1wb3J0RGVmYXVsdCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRHZXRcIiwgX19jbGFzc1ByaXZhdGVGaWVsZEdldCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRTZXRcIiwgX19jbGFzc1ByaXZhdGVGaWVsZFNldCk7XHJcbn0pO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuVklFV19MQVlFUl9MSUZFX0NZQ0xFID0gdm9pZCAwO1xudmFyIFZJRVdfTEFZRVJfTElGRV9DWUNMRTtcbihmdW5jdGlvbiAoVklFV19MQVlFUl9MSUZFX0NZQ0xFKSB7XG4gICAgVklFV19MQVlFUl9MSUZFX0NZQ0xFW1wiQkVGT1JFX0lOSVRcIl0gPSBcImJlZm9yZWluaXRcIjtcbiAgICBWSUVXX0xBWUVSX0xJRkVfQ1lDTEVbXCJBRlRFUl9JTklUXCJdID0gXCJhZnRlcmluaXRcIjtcbiAgICBWSUVXX0xBWUVSX0xJRkVfQ1lDTEVbXCJCRUZPUkVfUkVOREVSXCJdID0gXCJiZWZvcmVyZW5kZXJcIjtcbiAgICBWSUVXX0xBWUVSX0xJRkVfQ1lDTEVbXCJBRlRFUl9SRU5ERVJcIl0gPSBcImFmdGVycmVuZGVyXCI7XG4gICAgVklFV19MQVlFUl9MSUZFX0NZQ0xFW1wiQkVGT1JFX0NIQU5HRV9EQVRBXCJdID0gXCJiZWZvcmVjaGFuZ2VkYXRhXCI7XG4gICAgVklFV19MQVlFUl9MSUZFX0NZQ0xFW1wiQUZURVJfQ0hBTkdFX0RBVEFcIl0gPSBcImFmdGVyY2hhbmdlZGF0YVwiO1xufSkoVklFV19MQVlFUl9MSUZFX0NZQ0xFID0gZXhwb3J0cy5WSUVXX0xBWUVSX0xJRkVfQ1lDTEUgfHwgKGV4cG9ydHMuVklFV19MQVlFUl9MSUZFX0NZQ0xFID0ge30pKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50cy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRvbV91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvZG9tLXV0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcmVzaXplX29ic2VydmVyX3BvbHlmaWxsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwicmVzaXplLW9ic2VydmVyLXBvbHlmaWxsXCIpKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZS9nbG9iYWxcIik7XG52YXIgdGhlbWVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3RoZW1lXCIpKTtcbi8qKlxuICogQ2FudmFzIGNvbnRyb2xsZXJcbiAqIDEuIGNyZWF0ZSBHLkNhbnZhcywgZGVzdHJveSBHLkNhbnZhc1xuICogMi4gcHJvY2VzcyBhdXRvIGZpdCBjb250YWluZXJcbiAqIDMuIEFQSSBmb3IgRy5DYW52YXNcbiAqL1xudmFyIENhbnZhc0NvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ2FudmFzQ29udHJvbGxlcihjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHdoZW4gdGhlIGNvbnRhaW5lciBzaXplIGNoYW5nZWQsIHRyaWdnZXIgaXQgYWZ0ZXIgMzAwbXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uUmVzaXplID0gdXRpbF8xLmRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5wbG90LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBfYSA9IF90aGlzLmdldENhbnZhc1NpemUoKSwgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICAgICAgICAgICAgLyoqIGhlaWdodCBtZWFzdXJl5LiN5YeG5a+86Ie06YeN5aSNIGZvcmNlRml0ICovXG4gICAgICAgICAgICBpZiAoX3RoaXMud2lkdGggPT09IHdpZHRoICYmIF90aGlzLmhlaWdodCA9PT0gaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZ290IG5ldyB3aWR0aCwgaGVpZ2h0LCByZS1yZW5kZXIgdGhlIHBsb3RcbiAgICAgICAgICAgIF90aGlzLndpZHRoID0gd2lkdGg7XG4gICAgICAgICAgICBfdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgICAgICBfdGhpcy5wbG90LnVwZGF0ZUNvbmZpZyh7IHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfSk7XG4gICAgICAgICAgICBfdGhpcy5wbG90LnJlbmRlcigpO1xuICAgICAgICB9LCAzMDApO1xuICAgICAgICB2YXIgY29udGFpbmVyRE9NID0gY2ZnLmNvbnRhaW5lckRPTSwgcGxvdCA9IGNmZy5wbG90O1xuICAgICAgICB0aGlzLmNvbnRhaW5lckRPTSA9IGNvbnRhaW5lckRPTTtcbiAgICAgICAgdGhpcy5wbG90ID0gcGxvdDtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGdldCBjYW52YXMgc2l6ZSBmcm9tIHByb3BzLlxuICAgICAqIEByZXR1cm5zIHRoZSB3aWR0aCwgaGVpZ2h0IG9mIGNhbnZhc1xuICAgICAqL1xuICAgIENhbnZhc0NvbnRyb2xsZXIucHJvdG90eXBlLmdldENhbnZhc1NpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aGVtZSA9IGdsb2JhbF8xLmdldEdsb2JhbFRoZW1lKCk7XG4gICAgICAgIHZhciB3aWR0aCA9IHRoaXMucGxvdC53aWR0aCA/IHRoaXMucGxvdC53aWR0aCA6IHRoZW1lLndpZHRoO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gdGhpcy5wbG90LmhlaWdodCA/IHRoaXMucGxvdC5oZWlnaHQgOiB0aGVtZS5oZWlnaHQ7XG4gICAgICAgIC8vIGlmIGZvcmNlRml0ID0gdHJ1ZSwgdGhlbiB1c2UgdGhlIGNvbnRhaW5lcidzIHNpemUgYXMgZGVmYXVsdC5cbiAgICAgICAgaWYgKHRoaXMucGxvdC5mb3JjZUZpdCkge1xuICAgICAgICAgICAgd2lkdGggPSB0aGlzLmNvbnRhaW5lckRPTS5vZmZzZXRXaWR0aCA/IHRoaXMuY29udGFpbmVyRE9NLm9mZnNldFdpZHRoIDogd2lkdGg7XG4gICAgICAgICAgICBoZWlnaHQgPSB0aGlzLmNvbnRhaW5lckRPTS5vZmZzZXRIZWlnaHQgPyB0aGlzLmNvbnRhaW5lckRPTS5vZmZzZXRIZWlnaHQgOiBoZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgd2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCB9O1xuICAgIH07XG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBjYW52YXMgZG9tXG4gICAgICogQHJldHVybnMgQ2FudmFzIERPTVxuICAgICAqL1xuICAgIENhbnZhc0NvbnRyb2xsZXIucHJvdG90eXBlLmdldENhbnZhc0RPTSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzLmdldCgnY29udGFpbmVyJyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiB1cGRhdGUgdGhlIHBsb3Qgc2l6ZVxuICAgICAqL1xuICAgIENhbnZhc0NvbnRyb2xsZXIucHJvdG90eXBlLnVwZGF0ZUNhbnZhc1NpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0Q2FudmFzU2l6ZSgpLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMuY2FudmFzLmNoYW5nZVNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIC8vIHRoaXMucGxvdC51cGRhdGVSYW5nZSgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog5qC55o2u5Li76aKY6LCD5pW0Y2FudmFz5qC35byPXG4gICAgICovXG4gICAgQ2FudmFzQ29udHJvbGxlci5wcm90b3R5cGUudXBkYXRlQ2FudmFzVGhlbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aGVtZSA9IHRoaXMucGxvdC50aGVtZTtcbiAgICAgICAgdmFyIGdsb2JhbFRoZW1lID0gdGhlbWVfMS5kZWZhdWx0LmdldEdsb2JhbFRoZW1lKHRoZW1lKTtcbiAgICAgICAgdmFyIGZpbGwgPSB1dGlsXzEuZ2V0KGdsb2JhbFRoZW1lLCAnYmFja2dyb3VuZFN0eWxlLmZpbGwnKTtcbiAgICAgICAgaWYgKGZpbGwpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ2FudmFzU3R5bGUoe1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogZmlsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiB1cGRhdGUgdGhlIGNhbnZhcyBkb20gc3R5bGVzXG4gICAgICogQHBhcmFtIHN0eWxlc1xuICAgICAqL1xuICAgIENhbnZhc0NvbnRyb2xsZXIucHJvdG90eXBlLnVwZGF0ZUNhbnZhc1N0eWxlID0gZnVuY3Rpb24gKHN0eWxlcykge1xuICAgICAgICAvLyDkv67mlLnlrrnlmajnmoTmoLflvI9cbiAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1ModGhpcy5nZXRDYW52YXNET00oKSwgc3R5bGVzKTtcbiAgICAgICAgLy8g5L+u5pS5IGNhbnZhcyDnmoTmoLflvI9cbiAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1ModGhpcy5jYW52YXMuZ2V0KCdlbCcpLCB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyxcbiAgICAgICAgICAgIHZlcnRpY2FsQWxpZ246ICdtaWRkbGUnLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGRlc3Ryb3kgdGhlIHBsb3QsIHJlbW92ZSByZXNpemUgZXZlbnQuXG4gICAgICovXG4gICAgQ2FudmFzQ29udHJvbGxlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gcmVtb3ZlIGV2ZW50XG4gICAgICAgIGlmICh0aGlzLnJlc2l6ZU9ic2VydmVyKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLnVub2JzZXJ2ZSh0aGlzLmNvbnRhaW5lckRPTSk7XG4gICAgICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyRE9NID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICAvLyByZW1vdmUgRy5DYW52YXNcbiAgICAgICAgdGhpcy5jYW52YXMuZGVzdHJveSgpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogd2hlbiBmb3JjZUZpdCA9IHRydWUsIHRoZW4gYmluZCB0aGUgZXZlbnQgdG8gbGlzdGVuIHRoZSBjb250YWluZXIgc2l6ZSBjaGFuZ2VcbiAgICAgKi9cbiAgICBDYW52YXNDb250cm9sbGVyLnByb3RvdHlwZS5iaW5kRm9yY2VGaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmb3JjZUZpdCA9IHRoaXMucGxvdC5mb3JjZUZpdDtcbiAgICAgICAgLy8gdXNlIFJlc2l6ZU9ic2VydmVyIHRvIGxpc3RlbiB0aGUgY29udGFpbmVyIHNpemUgY2hhbmdlLlxuICAgICAgICBpZiAoZm9yY2VGaXQpIHtcbiAgICAgICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgcmVzaXplX29ic2VydmVyX3BvbHlmaWxsXzEuZGVmYXVsdCh0aGlzLm9uUmVzaXplKTtcbiAgICAgICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmNvbnRhaW5lckRPTSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGluaXQgbGlmZSBjaXJjbGVcbiAgICAgKi9cbiAgICBDYW52YXNDb250cm9sbGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmluaXRHQ2FudmFzKCk7XG4gICAgICAgIHRoaXMuYmluZEZvcmNlRml0KCk7XG4gICAgICAgIC8vIOi/veWKoOWuueWZqOeahCBjc3Mg5qC35byP77yM6Ziy5q2iIHRvb2x0aXAg55qE5L2N572u5Y+C6ICD54K55LiN5q2j56GuXG4gICAgICAgIHRoaXMudXBkYXRlQ2FudmFzU3R5bGUoeyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGluaXQgRy5DYW52YXMgaW5zdGFuY2VcbiAgICAgKi9cbiAgICBDYW52YXNDb250cm9sbGVyLnByb3RvdHlwZS5pbml0R0NhbnZhcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLyoqIOWIm+W7umNhbnZhcyAqL1xuICAgICAgICB2YXIgX2EgPSB0aGlzLnBsb3QsIF9iID0gX2EucmVuZGVyZXIsIHJlbmRlcmVyID0gX2IgPT09IHZvaWQgMCA/ICdjYW52YXMnIDogX2IsIHBpeGVsUmF0aW8gPSBfYS5waXhlbFJhdGlvLCBfYyA9IF9hLmxvY2FsUmVmcmVzaCwgbG9jYWxSZWZyZXNoID0gX2MgPT09IHZvaWQgMCA/IGZhbHNlIDogX2M7XG4gICAgICAgIHZhciBfZCA9IHRoaXMuZ2V0Q2FudmFzU2l6ZSgpLCB3aWR0aCA9IF9kLndpZHRoLCBoZWlnaHQgPSBfZC5oZWlnaHQ7XG4gICAgICAgIHZhciBHID0gcmVuZGVyZXIgPT09ICdjYW52YXMnID8gZGVwZW5kZW50c18xLkNhbnZhcyA6IGRlcGVuZGVudHNfMS5TVkc7XG4gICAgICAgIHRoaXMuY2FudmFzID0gbmV3IEcoe1xuICAgICAgICAgICAgbG9jYWxSZWZyZXNoOiBsb2NhbFJlZnJlc2gsXG4gICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyRE9NLFxuICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgICAgICBwaXhlbFJhdGlvOiBwaXhlbFJhdGlvLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgdGhpcy51cGRhdGVDYW52YXNUaGVtZSgpO1xuICAgIH07XG4gICAgcmV0dXJuIENhbnZhc0NvbnRyb2xsZXI7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2FudmFzQ29udHJvbGxlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNhbnZhcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbmZ1bmN0aW9uIGlzU2FtZVNoYXBlKHNoYXBlMSwgc2hhcGUyKSB7XG4gICAgaWYgKHNoYXBlMSAmJiBzaGFwZTIgJiYgc2hhcGUxID09PSBzaGFwZTIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGlzUG9pbnRJbkJCb3gocG9pbnQsIGJib3gpIHtcbiAgICBpZiAocG9pbnQueCA+PSBiYm94Lm1pblggJiYgcG9pbnQueCA8PSBiYm94Lm1heFggJiYgcG9pbnQueSA+PSBiYm94Lm1pblkgJiYgcG9pbnQueSA8PSBiYm94Lm1heFkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbnZhciBFdmVudENvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRXZlbnRDb250cm9sbGVyKGNmZykge1xuICAgICAgICB0aGlzLnBsb3QgPSBjZmcucGxvdDtcbiAgICAgICAgdGhpcy5jYW52YXMgPSBjZmcuY2FudmFzO1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBbXTtcbiAgICB9XG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmFkZEV2ZW50KHRoaXMuY2FudmFzLCAnbW91c2Vkb3duJywgdXRpbF8xLndyYXBCZWhhdmlvcih0aGlzLCAnb25FdmVudHMnKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnQodGhpcy5jYW52YXMsICdtb3VzZW1vdmUnLCB1dGlsXzEud3JhcEJlaGF2aW9yKHRoaXMsICdvbk1vdmUnKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnQodGhpcy5jYW52YXMsICdtb3VzZXVwJywgdXRpbF8xLndyYXBCZWhhdmlvcih0aGlzLCAnb25FdmVudHMnKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnQodGhpcy5jYW52YXMsICdjbGljaycsIHV0aWxfMS53cmFwQmVoYXZpb3IodGhpcywgJ29uRXZlbnRzJykpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50KHRoaXMuY2FudmFzLCAnZGJsY2xpY2snLCB1dGlsXzEud3JhcEJlaGF2aW9yKHRoaXMsICdvbkV2ZW50cycpKTtcbiAgICAgICAgdGhpcy5hZGRFdmVudCh0aGlzLmNhbnZhcywgJ2NvbnRleHRtZW51JywgdXRpbF8xLndyYXBCZWhhdmlvcih0aGlzLCAnb25FdmVudHMnKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnQodGhpcy5jYW52YXMsICd3aGVlbCcsIHV0aWxfMS53cmFwQmVoYXZpb3IodGhpcywgJ29uRXZlbnRzJykpO1xuICAgIH07XG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5jbGVhckV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGV2ZW50SGFuZGxlcnMgPSB0aGlzLmV2ZW50SGFuZGxlcnM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGV2ZW50SGFuZGxlcnMsIGZ1bmN0aW9uIChlaCkge1xuICAgICAgICAgICAgZWgudGFyZ2V0Lm9mZihlaC50eXBlLCBlaC5oYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLmFkZEV2ZW50ID0gZnVuY3Rpb24gKHRhcmdldCwgZXZlbnRUeXBlLCBoYW5kbGVyKSB7XG4gICAgICAgIHRhcmdldC5vbihldmVudFR5cGUsIGhhbmRsZXIpO1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcnMucHVzaCh7IHRhcmdldDogdGFyZ2V0LCB0eXBlOiBldmVudFR5cGUsIGhhbmRsZXI6IGhhbmRsZXIgfSk7XG4gICAgfTtcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLm9uRXZlbnRzID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciBldmVudE9iaiA9IHRoaXMuZ2V0RXZlbnRPYmooZXYpO1xuICAgICAgICB2YXIgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICAvLyDliKTmlq3mmK/lkKbmi77lj5bliLB2aWV35Lul5aSW55qEc2hhcGVcbiAgICAgICAgaWYgKCF0aGlzLmlzU2hhcGVJblZpZXcodGFyZ2V0KSAmJiB0YXJnZXQubmFtZSkge1xuICAgICAgICAgICAgdGhpcy5wbG90LmVtaXQodGFyZ2V0Lm5hbWUgKyBcIjpcIiArIGV2LnR5cGUsIGV2KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBsb3QuZW1pdChcIlwiICsgZXYudHlwZSwgZXZlbnRPYmopO1xuICAgICAgICAvLyBsYXllcuS6i+S7tlxuICAgICAgICB2YXIgbGF5ZXJzID0gdGhpcy5wbG90LmdldExheWVycygpO1xuICAgICAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMub25MYXllckV2ZW50KGxheWVycywgZXZlbnRPYmosIGV2LnR5cGUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLm9uTW92ZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICB2YXIgZXZlbnRPYmogPSB0aGlzLmdldEV2ZW50T2JqKGV2KTtcbiAgICAgICAgLy8gc2hhcGXnmoRtb3VzZWVudGVyLCBtb3VzZWxlYXZl5ZKMbW91c2Vtb3Zl5LqL5Lu2XG4gICAgICAgIGlmICghdGhpcy5pc1NoYXBlSW5WaWV3KHRhcmdldCkgJiYgdGFyZ2V0Lm5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMucGxvdC5lbWl0KHRhcmdldC5uYW1lICsgXCI6XCIgKyBldi50eXBlLCBldmVudE9iaik7XG4gICAgICAgICAgICAvLyBtb3VzZWxlYXZlICYgbW91c2VlbnRlclxuICAgICAgICAgICAgaWYgKHRoaXMubGFzdFNoYXBlICYmICFpc1NhbWVTaGFwZSh0YXJnZXQsIHRoaXMubGFzdFNoYXBlKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxhc3RTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsb3QuZW1pdCh0aGlzLmxhc3RTaGFwZS5uYW1lICsgXCI6bW91c2VsZWF2ZVwiLCBldmVudE9iaik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucGxvdC5lbWl0KHRhcmdldC5uYW1lICsgXCI6bW91c2VlbnRlclwiLCBldmVudE9iaik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmxhc3RTaGFwZSA9IHRhcmdldDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBsb3QuZW1pdCgnbW91c2Vtb3ZlJywgZXZlbnRPYmopO1xuICAgICAgICAvLyBsYXllcuS6i+S7tlxuICAgICAgICB2YXIgbGF5ZXJzID0gdGhpcy5wbG90LmdldExheWVycygpO1xuICAgICAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMub25MYXllckV2ZW50KGxheWVycywgZXZlbnRPYmosICdtb3VzZW1vdmUnKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRXZlbnRDb250cm9sbGVyLnByb3RvdHlwZS5pc1NoYXBlSW5WaWV3ID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBncm91cE5hbWUgPSBbJ2Zyb250Z3JvdW5kR3JvdXAnLCAnYmFja2dyb3VuZEdyb3VwJywgJ3BhbmVsR3JvdXAnXTtcbiAgICAgICAgdmFyIHBhcmVudCA9IHNoYXBlLmdldCgncGFyZW50Jyk7XG4gICAgICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgICAgICAgIHZhciBwYXJlbnROYW1lID0gcGFyZW50LmdldCgnbmFtZScpO1xuICAgICAgICAgICAgaWYgKHBhcmVudE5hbWUgJiYgdXRpbF8xLmNvbnRhaW5zKGdyb3VwTmFtZSwgcGFyZW50TmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXQoJ3BhcmVudCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEV2ZW50Q29udHJvbGxlci5wcm90b3R5cGUuZ2V0RXZlbnRPYmogPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdmFyIG9iaiA9IHtcbiAgICAgICAgICAgIGNsaWVudFg6IGV2LmNsaWVudFgsXG4gICAgICAgICAgICBjbGllbnRZOiBldi5jbGllbnRZLFxuICAgICAgICAgICAgeDogZXYueCxcbiAgICAgICAgICAgIHk6IGV2LnksXG4gICAgICAgICAgICBwbG90OiB0aGlzLnBsb3QsXG4gICAgICAgICAgICBkYXRhOiBldi5kYXRhID8gZXYuZGF0YS5kYXRhIDogbnVsbCxcbiAgICAgICAgICAgIGNhbnZhczogdGhpcy5jYW52YXMsXG4gICAgICAgICAgICB0YXJnZXQ6IGV2LnRhcmdldCxcbiAgICAgICAgICAgIGdFdmVudDogZXYsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfTtcbiAgICBFdmVudENvbnRyb2xsZXIucHJvdG90eXBlLm9uTGF5ZXJFdmVudCA9IGZ1bmN0aW9uIChsYXllcnMsIGV2ZW50T2JqLCBldmVudE5hbWUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2gobGF5ZXJzLCBmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gbGF5ZXIuZ2V0R2xvYmFsQkJveCgpO1xuICAgICAgICAgICAgaWYgKGlzUG9pbnRJbkJCb3goeyB4OiBldmVudE9iai54LCB5OiBldmVudE9iai55IH0sIGJib3gpKSB7XG4gICAgICAgICAgICAgICAgbGF5ZXIuZW1pdChcIlwiICsgZXZlbnROYW1lLCBldmVudE9iaik7XG4gICAgICAgICAgICAgICAgdmFyIHN1YkxheWVycyA9IGxheWVyLmxheWVycztcbiAgICAgICAgICAgICAgICBpZiAoc3ViTGF5ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMub25MYXllckV2ZW50KHN1YkxheWVycywgZXZlbnRPYmosIGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBFdmVudENvbnRyb2xsZXI7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRXZlbnRDb250cm9sbGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vdXRpbC9iYm94XCIpKTtcbnZhciBjb21tb25fMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2NvbW1vblwiKTtcbi8qKlxuICog5aSE55CG5Zu+6KGocGFkZGluZ+eahOmAu+i+ke+8mlxuICog5rOo5YaM5Y+C5LiOcGFkZGluZ+eahOiHquWumuS5iee7hOS7tlxuICovXG52YXIgUGFkZGluZ0NvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUGFkZGluZ0NvbnRyb2xsZXIoY2ZnKSB7XG4gICAgICAgIHRoaXMuaW5uZXJQYWRkaW5nQ29tcG9uZW50cyA9IFtdO1xuICAgICAgICB0aGlzLm91dGVyUGFkZGluZ0NvbXBvbmVudHMgPSBbXTtcbiAgICAgICAgdGhpcy5wbG90ID0gY2ZnLnBsb3Q7XG4gICAgfVxuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5yZWdpc3RlclBhZGRpbmcgPSBmdW5jdGlvbiAoY29tcG9uZW50LCB0eXBlLCBjaGVja0lmRXhpc3QpIHtcbiAgICAgICAgaWYgKHR5cGUgPT09IHZvaWQgMCkgeyB0eXBlID0gJ291dGVyJzsgfVxuICAgICAgICBpZiAoY2hlY2tJZkV4aXN0ID09PSB2b2lkIDApIHsgY2hlY2tJZkV4aXN0ID0gZmFsc2U7IH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdpbm5lcicpIHtcbiAgICAgICAgICAgIGlmIChjaGVja0lmRXhpc3QpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaW5uZXJQYWRkaW5nQ29tcG9uZW50cy5maW5kKGZ1bmN0aW9uIChjKSB7IHJldHVybiBjID09IGNvbXBvbmVudDsgfSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbm5lclBhZGRpbmdDb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlubmVyUGFkZGluZ0NvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNoZWNrSWZFeGlzdCkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5vdXRlclBhZGRpbmdDb21wb25lbnRzLmZpbmQoZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMgPT0gY29tcG9uZW50OyB9KSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGVyUGFkZGluZ0NvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3V0ZXJQYWRkaW5nQ29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5nZXRQYWRkaW5nQ29tcG9uZW50cyA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIGlmICh0eXBlID09PSB2b2lkIDApIHsgdHlwZSA9ICdvdXRlcic7IH1cbiAgICAgICAgcmV0dXJuICh0eXBlID09PSAnb3V0ZXInID8gdGhpcy5vdXRlclBhZGRpbmdDb21wb25lbnRzIDogdGhpcy5pbm5lclBhZGRpbmdDb21wb25lbnRzKSB8fCBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOa4hemZpOW3sue7j+azqOWGjOeahOWFg+e0oFxuICAgICAqL1xuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbm5lclBhZGRpbmdDb21wb25lbnRzID0gW107XG4gICAgICAgIC8vIOS4gOS6m+e7hOS7tuaYr+WcqHZpZXfmuLLmn5PlrozmiJDkuYvlkI7muLLmn5PliJ3lp4vljJbnmoRcbiAgICAgICAgLy8gVE9ETzogYWZ0ZXJSZW5kZXLnmoTku4DkuYjml7blgJnmuIXpmaRcbiAgICAgICAgdGhpcy5vdXRlclBhZGRpbmdDb21wb25lbnRzID0gdXRpbF8xLmZpbHRlcih0aGlzLm91dGVyUGFkZGluZ0NvbXBvbmVudHMsIGZ1bmN0aW9uIChjb21wb25lbnQpIHsgcmV0dXJuIGNvbXBvbmVudC5hZnRlclJlbmRlcjsgfSk7XG4gICAgfTtcbiAgICBQYWRkaW5nQ29udHJvbGxlci5wcm90b3R5cGUuY2xlYXJPdXRlckNvbXBvbmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMub3V0ZXJQYWRkaW5nQ29tcG9uZW50cywgZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudC5hZnRlclJlbmRlcikge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm91dGVyUGFkZGluZ0NvbXBvbmVudHMgPSBbXTtcbiAgICB9O1xuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5nZXRQYWRkaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIHBhZGRpbmcgPSBwcm9wcy5wYWRkaW5nID8gcHJvcHMucGFkZGluZyA6IHRoaXMucGxvdC5jb25maWcudGhlbWUucGFkZGluZztcbiAgICAgICAgaWYgKHBhZGRpbmcgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgcmV0dXJuIFswLCAwLCAwLCAxXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFkZGluZztcbiAgICB9O1xuICAgIC8qKiB2aWV35bGC55qEcGFkZGluZ+iuoeeulyAqL1xuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5wcm9jZXNzQXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYWRkaW5nID0gdGhpcy5fZ2V0SW5uZXJBdXRvUGFkZGluZygpO1xuICAgICAgICB0aGlzLnBsb3QudXBkYXRlQ29uZmlnKHtcbiAgICAgICAgICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBsb3QucmVuZGVyKCk7XG4gICAgfTtcbiAgICBQYWRkaW5nQ29udHJvbGxlci5wcm90b3R5cGUucHJvY2Vzc091dGVyUGFkZGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnBsb3QubGF5ZXJCQm94KSB7XG4gICAgICAgICAgICB0aGlzLnBsb3QubGF5ZXJCQm94ID0gbmV3IGJib3hfMS5kZWZhdWx0KHRoaXMucGxvdC54LCB0aGlzLnBsb3QueSwgdGhpcy5wbG90LndpZHRoLCB0aGlzLnBsb3QuaGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdmlld01pblggPSB0aGlzLnBsb3QubGF5ZXJCQm94Lm1pblg7XG4gICAgICAgIHZhciB2aWV3TWF4WCA9IHRoaXMucGxvdC5sYXllckJCb3gubWF4WDtcbiAgICAgICAgdmFyIHZpZXdNaW5ZID0gdGhpcy5wbG90LmxheWVyQkJveC5taW5ZO1xuICAgICAgICB2YXIgdmlld01heFkgPSB0aGlzLnBsb3QubGF5ZXJCQm94Lm1heFk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMub3V0ZXJQYWRkaW5nQ29tcG9uZW50cywgZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gY29tcG9uZW50LnBvc2l0aW9uO1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudC5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgX2EgPSBjb21wb25lbnQuZ2V0QkJveCgpLCBtaW5YID0gX2EubWluWCwgbWF4WCA9IF9hLm1heFgsIG1pblkgPSBfYS5taW5ZLCBtYXhZID0gX2EubWF4WTtcbiAgICAgICAgICAgIGlmIChtYXhZID49IHZpZXdNaW5ZICYmIG1heFkgPD0gdmlld01heFkgJiYgcG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICAgICAgdmlld01pblkgPSBtYXhZO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1pblkgPj0gdmlld01pblkgJiYgbWluWSA8PSB2aWV3TWF4WSAmJiBwb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICAgICAgICAgICAgICB2aWV3TWF4WSA9IG1pblk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF4WCA+IHZpZXdNaW5YICYmIG1heFggPD0gdmlld01heFggJiYgcG9zaXRpb24gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgICAgIHZpZXdNaW5YID0gbWF4WDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtaW5YID49IHZpZXdNaW5YICYmIG1heFggPD0gdmlld01heFggJiYgcG9zaXRpb24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgICAgICB2aWV3TWF4WCA9IG1pblg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IGJib3hfMS5kZWZhdWx0KHZpZXdNaW5YLCB2aWV3TWluWSwgdmlld01heFggLSB2aWV3TWluWCwgdmlld01heFkgLSB2aWV3TWluWSk7XG4gICAgfTtcbiAgICBQYWRkaW5nQ29udHJvbGxlci5wcm90b3R5cGUuX2dldElubmVyQXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5wbG90LnZpZXc7XG4gICAgICAgIHZhciB2aWV3UmFuZ2UgPSB2aWV3LmNvb3JkaW5hdGVCQm94O1xuICAgICAgICB2YXIgbWF4WCA9IHZpZXdSYW5nZS5tYXhYLCBtYXhZID0gdmlld1JhbmdlLm1heFksIG1pblkgPSB2aWV3UmFuZ2UubWluWSwgbWluWCA9IHZpZXdSYW5nZS5taW5YO1xuICAgICAgICB2YXIgYmxlZWRpbmcgPSB0aGlzLnBsb3QuY29uZmlnLnRoZW1lLmJsZWVkaW5nO1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoYmxlZWRpbmcpKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChibGVlZGluZywgZnVuY3Rpb24gKGl0LCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYmxlZWRpbmdbaW5kZXhdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGJsZWVkaW5nW2luZGV4XSA9IGJsZWVkaW5nW2luZGV4XShwcm9wcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ibGVlZGluZyA9IHV0aWxfMS5jbG9uZShibGVlZGluZyk7XG4gICAgICAgIC8vIOWPguS4jmF1dG8gcGFkZGluZ+eahGNvbXBvbmVudHM6IGF4aXMgbGVnZW5kIGxhYmVsIGFubm90YXRpb25cbiAgICAgICAgdmFyIGNvbXBvbmVudHNfYmJveCA9IFtuZXcgYmJveF8xLmRlZmF1bHQodmlld1JhbmdlLm1pblgsIHZpZXdSYW5nZS5taW5ZLCB2aWV3UmFuZ2Uud2lkdGgsIHZpZXdSYW5nZS5oZWlnaHQpXTtcbiAgICAgICAgaWYgKCgoX2EgPSB0aGlzLnBsb3QuY29uZmlnLmNvb3JkaW5hdGUpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS50eXBlKSA9PT0gJ2NhcnRlc2lhbicpIHtcbiAgICAgICAgICAgIHRoaXMuX2dldENhcnRlc2lhbkF4aXModmlldywgY29tcG9uZW50c19iYm94WzBdLCBjb21wb25lbnRzX2Jib3gpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBib3ggPSB0aGlzLl9tZXJnZUJCb3goY29tcG9uZW50c19iYm94KTtcbiAgICAgICAgdGhpcy5fZ2V0TGVnZW5kKHZpZXcsIGJveCwgY29tcG9uZW50c19iYm94KTtcbiAgICAgICAgYm94ID0gdGhpcy5fbWVyZ2VCQm94KGNvbXBvbmVudHNfYmJveCk7XG4gICAgICAgIC8vIOWPguS4jmF1dG8gcGFkZGluZ+eahOiHquWumuS5iee7hOS7tlxuICAgICAgICB2YXIgY29tcG9uZW50cyA9IHRoaXMuaW5uZXJQYWRkaW5nQ29tcG9uZW50cztcbiAgICAgICAgdXRpbF8xLmVhY2goY29tcG9uZW50cywgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgdmFyIGNvbXBvbmVudCA9IG9iajtcbiAgICAgICAgICAgIHZhciBiYm94ID0gY29tcG9uZW50LmdldEJCb3goKTtcbiAgICAgICAgICAgIGNvbXBvbmVudHNfYmJveC5wdXNoKGJib3gpO1xuICAgICAgICB9KTtcbiAgICAgICAgYm94ID0gdGhpcy5fbWVyZ2VCQm94KGNvbXBvbmVudHNfYmJveCk7XG4gICAgICAgIHZhciBwYWRkaW5nID0gW1xuICAgICAgICAgICAgbWluWSAtIGJveC5taW5ZICsgdGhpcy5ibGVlZGluZ1swXSxcbiAgICAgICAgICAgIGJveC5tYXhYIC0gbWF4WCArIHRoaXMuYmxlZWRpbmdbMV0sXG4gICAgICAgICAgICBib3gubWF4WSAtIG1heFkgKyB0aGlzLmJsZWVkaW5nWzJdLFxuICAgICAgICAgICAgbWluWCAtIGJveC5taW5YICsgdGhpcy5ibGVlZGluZ1szXSxcbiAgICAgICAgXTtcbiAgICAgICAgLy8gbGFiZWzjgIFhbm5vdGF0aW9u562JXG4gICAgICAgIHZhciBwYW5lbFBhZGRpbmcgPSB0aGlzLl9nZXRQYW5lbCh2aWV3KTtcbiAgICAgICAgcGFkZGluZ1swXSArPSBwYW5lbFBhZGRpbmdbMF07XG4gICAgICAgIHBhZGRpbmdbMV0gKz0gcGFuZWxQYWRkaW5nWzFdO1xuICAgICAgICBwYWRkaW5nWzJdICs9IHBhbmVsUGFkZGluZ1syXTtcbiAgICAgICAgcGFkZGluZ1szXSArPSBwYW5lbFBhZGRpbmdbM107XG4gICAgICAgIHJldHVybiBwYWRkaW5nO1xuICAgIH07XG4gICAgUGFkZGluZ0NvbnRyb2xsZXIucHJvdG90eXBlLl9nZXRDYXJ0ZXNpYW5BeGlzID0gZnVuY3Rpb24gKHZpZXcsIGdsb2JhbEJCb3gsIGJib3hlcykge1xuICAgICAgICB2YXIgYXhlcyA9IGNvbW1vbl8xLmdldEF4aXNDb21wb25lbnRzKHZpZXcpO1xuICAgICAgICB2YXIgaXNUcmFuc3Bvc2VkID0gdmlldy5nZXRDb29yZGluYXRlKCkuaXNUcmFuc3Bvc2VkO1xuICAgICAgICB1dGlsXzEuZWFjaChheGVzLCBmdW5jdGlvbiAoYXhpcykge1xuICAgICAgICAgICAgaWYgKGF4aXMuZ2V0KCdncm91cCcpLmdldCgnY2hpbGRyZW4nKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcG9zaXRpb24gPSBheGlzLmdldCgncG9zaXRpb24nKTtcbiAgICAgICAgICAgIHZhciBfYSA9IGF4aXMuZ2V0TGF5b3V0QkJveCgpLCBtaW5YID0gX2EubWluWCwgbWluWSA9IF9hLm1pblksIHdpZHRoID0gX2Eud2lkdGgsIGhlaWdodCA9IF9hLmhlaWdodDtcbiAgICAgICAgICAgIGlmICghaXNUcmFuc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgYmJveGVzLnB1c2gobmV3IGJib3hfMS5kZWZhdWx0KGdsb2JhbEJCb3gubWluWCAtIHdpZHRoLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgICAgICAgICBiYm94ZXMucHVzaChuZXcgYmJveF8xLmRlZmF1bHQobWluWCwgZ2xvYmFsQkJveC5tYXhZLCB3aWR0aCwgaGVpZ2h0KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGJib3hlcy5wdXNoKG5ldyBiYm94XzEuZGVmYXVsdChnbG9iYWxCQm94Lm1heFgsIG1pblksIHdpZHRoLCBoZWlnaHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICAgICAgICAgIGJib3hlcy5wdXNoKG5ldyBiYm94XzEuZGVmYXVsdChnbG9iYWxCQm94Lm1pblggLSB3aWR0aCwgbWluWSwgd2lkdGgsIGhlaWdodCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGJib3hlcy5wdXNoKG5ldyBiYm94XzEuZGVmYXVsdChtaW5YLCBnbG9iYWxCQm94Lm1heFksIHdpZHRoLCBoZWlnaHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAocG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICAgICAgICAgIGJib3hlcy5wdXNoKG5ldyBiYm94XzEuZGVmYXVsdChnbG9iYWxCQm94Lm1heFgsIG1pblksIHdpZHRoLCBoZWlnaHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUGFkZGluZ0NvbnRyb2xsZXIucHJvdG90eXBlLl9nZXRMZWdlbmQgPSBmdW5jdGlvbiAodmlldywgZ2xvYmFsQkJveCwgYmJveGVzKSB7XG4gICAgICAgIHZhciBsZWdlbmRzID0gY29tbW9uXzEuZ2V0TGVnZW5kQ29tcG9uZW50cyh2aWV3KTtcbiAgICAgICAgdXRpbF8xLmVhY2gobGVnZW5kcywgZnVuY3Rpb24gKGxlZ2VuZCkge1xuICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gbGVnZW5kLmdldCgncG9zaXRpb24nKS5zcGxpdCgnLScpWzBdO1xuICAgICAgICAgICAgdmFyIF9hID0gbGVnZW5kLmdldExheW91dEJCb3goKSwgbWluWCA9IF9hLm1pblgsIG1pblkgPSBfYS5taW5ZLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgICAgICBpZiAocG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICAgICAgYmJveGVzLnB1c2gobmV3IGJib3hfMS5kZWZhdWx0KG1pblgsIGdsb2JhbEJCb3gubWluWSAtIGhlaWdodCwgd2lkdGgsIGhlaWdodCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICAgICAgYmJveGVzLnB1c2gobmV3IGJib3hfMS5kZWZhdWx0KG1pblgsIGdsb2JhbEJCb3gubWF4WSwgd2lkdGgsIGhlaWdodCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocG9zaXRpb24gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgICAgIGJib3hlcy5wdXNoKG5ldyBiYm94XzEuZGVmYXVsdChnbG9iYWxCQm94Lm1pblggLSB3aWR0aCwgbWluWSwgd2lkdGgsIGhlaWdodCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYmJveGVzLnB1c2gobmV3IGJib3hfMS5kZWZhdWx0KGdsb2JhbEJCb3gubWF4WCwgbWluWSwgd2lkdGgsIGhlaWdodCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5fZ2V0UGFuZWwgPSBmdW5jdGlvbiAodmlldykge1xuICAgICAgICB2YXIgZ3JvdXBzID0gW107XG4gICAgICAgIHZhciBnZW9tcyA9IHZpZXcuZ2VvbWV0cmllcztcbiAgICAgICAgdXRpbF8xLmVhY2goZ2VvbXMsIGZ1bmN0aW9uIChnZW9tKSB7XG4gICAgICAgICAgICBpZiAoZ2VvbS5sYWJlbHNDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICBncm91cHMucHVzaChnZW9tLmxhYmVsc0NvbnRhaW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgbWluWCA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WCA9IC1JbmZpbml0eTtcbiAgICAgICAgdmFyIG1pblkgPSBJbmZpbml0eTtcbiAgICAgICAgdmFyIG1heFkgPSAtSW5maW5pdHk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGdyb3VwcywgZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBncm91cC5nZXQoJ2NoaWxkcmVuJyk7XG4gICAgICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgIGlmIChjaGlsZC50eXBlID09PSAnZ3JvdXAnICYmIGNoaWxkLmdldCgnY2hpbGRyZW4nKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgYmJveCA9IGNoaWxkLmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICBpZiAoYmJveC5taW5YIDwgbWluWCkge1xuICAgICAgICAgICAgICAgICAgICBtaW5YID0gYmJveC5taW5YO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYmJveC5tYXhYID4gbWF4WCkge1xuICAgICAgICAgICAgICAgICAgICBtYXhYID0gYmJveC5tYXhYO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYmJveC5taW5ZIDwgbWluWSkge1xuICAgICAgICAgICAgICAgICAgICBtaW5ZID0gYmJveC5taW5ZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYmJveC5tYXhZID4gbWF4WSkge1xuICAgICAgICAgICAgICAgICAgICBtYXhZID0gYmJveC5tYXhZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHBhbmVsUmFuZ2UgPSB2aWV3LmNvb3JkaW5hdGVCQm94O1xuICAgICAgICAvL3JpZ2h0XG4gICAgICAgIHZhciByaWdodERpc3QgPSBNYXRoLm1heChtYXhYIC0gcGFyc2VGbG9hdChwYW5lbFJhbmdlLm1heFgpLCAwKTtcbiAgICAgICAgaWYgKHJpZ2h0RGlzdCA+IDApIHtcbiAgICAgICAgICAgIHZhciByYXRpbyA9IHBhbmVsUmFuZ2Uud2lkdGggLyAocGFuZWxSYW5nZS53aWR0aCArIHJpZ2h0RGlzdCk7XG4gICAgICAgICAgICByaWdodERpc3QgKj0gcmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgLy9sZWZ0XG4gICAgICAgIHZhciBsZWZ0RGlzdCA9IE1hdGgubWF4KHBhcnNlRmxvYXQocGFuZWxSYW5nZS5taW5YKSAtIG1pblgsIDApO1xuICAgICAgICBpZiAobGVmdERpc3QgPiAwKSB7XG4gICAgICAgICAgICB2YXIgcmF0aW8gPSBwYW5lbFJhbmdlLndpZHRoIC8gKHBhbmVsUmFuZ2Uud2lkdGggKyBsZWZ0RGlzdCk7XG4gICAgICAgICAgICBsZWZ0RGlzdCAqPSByYXRpbztcbiAgICAgICAgfVxuICAgICAgICAvL3RvcFxuICAgICAgICB2YXIgdG9wRGlzdCA9IE1hdGgubWF4KHBhcnNlRmxvYXQocGFuZWxSYW5nZS5taW5ZKSAtIG1pblksIDApO1xuICAgICAgICBpZiAodG9wRGlzdCA+IDApIHtcbiAgICAgICAgICAgIHZhciByYXRpbyA9IHBhbmVsUmFuZ2UuaGVpZ2h0IC8gKHBhbmVsUmFuZ2UuaGVpZ2h0ICsgdG9wRGlzdCk7XG4gICAgICAgICAgICB0b3BEaXN0ICo9IHJhdGlvO1xuICAgICAgICB9XG4gICAgICAgIC8vYm90dG9tXG4gICAgICAgIHZhciBib3R0b21EaXN0ID0gTWF0aC5tYXgobWF4WSAtIHBhcnNlRmxvYXQocGFuZWxSYW5nZS5tYXhZKSwgMCk7XG4gICAgICAgIGlmIChib3R0b21EaXN0ID4gMCkge1xuICAgICAgICAgICAgdmFyIHJhdGlvID0gcGFuZWxSYW5nZS5oZWlnaHQgLyAocGFuZWxSYW5nZS5oZWlnaHQgKyBib3R0b21EaXN0KTtcbiAgICAgICAgICAgIGJvdHRvbURpc3QgKj0gcmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFt0b3BEaXN0LCByaWdodERpc3QsIGJvdHRvbURpc3QsIGxlZnREaXN0XTtcbiAgICB9O1xuICAgIFBhZGRpbmdDb250cm9sbGVyLnByb3RvdHlwZS5fbWVyZ2VCQm94ID0gZnVuY3Rpb24gKGJib3hlcykge1xuICAgICAgICB2YXIgbWluWCA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WCA9IC1JbmZpbml0eTtcbiAgICAgICAgdmFyIG1pblkgPSBJbmZpbml0eTtcbiAgICAgICAgdmFyIG1heFkgPSAtSW5maW5pdHk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGJib3hlcywgZnVuY3Rpb24gKGJib3gpIHtcbiAgICAgICAgICAgIHZhciBib3ggPSBiYm94O1xuICAgICAgICAgICAgbWluWCA9IE1hdGgubWluKGJveC5taW5YLCBtaW5YKTtcbiAgICAgICAgICAgIG1heFggPSBNYXRoLm1heChib3gubWF4WCwgbWF4WCk7XG4gICAgICAgICAgICBtaW5ZID0gTWF0aC5taW4oYm94Lm1pblksIG1pblkpO1xuICAgICAgICAgICAgbWF4WSA9IE1hdGgubWF4KGJveC5tYXhZLCBtYXhZKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IG1pblg6IG1pblgsIG1heFg6IG1heFgsIG1pblk6IG1pblksIG1heFk6IG1heFkgfTtcbiAgICB9O1xuICAgIHJldHVybiBQYWRkaW5nQ29udHJvbGxlcjtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQYWRkaW5nQ29udHJvbGxlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhZGRpbmcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNvbXBhcmUgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9mYWN0b3J5XCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbnZhciBzdGF0ZV9tYW5hZ2VyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vdXRpbC9zdGF0ZS1tYW5hZ2VyXCIpKTtcbmZ1bmN0aW9uIGNvbXBhcmUob3JpZ2luLCBjb25kaXRpb24pIHtcbiAgICBpZiAoIXV0aWxfMS5pc0Z1bmN0aW9uKGNvbmRpdGlvbikpIHtcbiAgICAgICAgdmFyIG5hbWVfMSA9IGNvbmRpdGlvbi5uYW1lLCBleHAgPSBjb25kaXRpb24uZXhwO1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24oZXhwKSkge1xuICAgICAgICAgICAgcmV0dXJuIGV4cChvcmlnaW5bbmFtZV8xXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbltuYW1lXzFdID09PSBleHA7XG4gICAgfVxuICAgIHJldHVybiBjb25kaXRpb24ob3JpZ2luKTtcbn1cbmV4cG9ydHMuY29tcGFyZSA9IGNvbXBhcmU7XG52YXIgU3RhdGVDb250cm9sbGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFN0YXRlQ29udHJvbGxlcihjZmcpIHtcbiAgICAgICAgdGhpcy5zaGFwZUNvbnRhaW5lcnMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLCBjZmcpO1xuICAgIH1cbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLmNyZWF0ZVN0YXRlTWFuYWdlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zdGF0ZU1hbmFnZXIgPSBuZXcgc3RhdGVfbWFuYWdlcl8xLmRlZmF1bHQoKTtcbiAgICB9O1xuICAgIFN0YXRlQ29udHJvbGxlci5wcm90b3R5cGUuYmluZFN0YXRlTWFuYWdlciA9IGZ1bmN0aW9uIChtYW5hZ2VyLCBjZmcpIHtcbiAgICAgICAgdGhpcy5zdGF0ZU1hbmFnZXIgPSBtYW5hZ2VyO1xuICAgICAgICBpZiAoY2ZnLnNldFN0YXRlKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVTdGF0ZVByb2Nlc3MoY2ZnLnNldFN0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2ZnLm9uU3RhdGVDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlQ2hhbmdlUHJvY2VzcyhjZmcub25TdGF0ZUNoYW5nZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFN0YXRlQ29udHJvbGxlci5wcm90b3R5cGUuZGVmYXVsdFN0YXRlcyA9IGZ1bmN0aW9uIChzdGF0ZXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2goc3RhdGVzLCBmdW5jdGlvbiAoc3RhdGUsIHR5cGUpIHtcbiAgICAgICAgICAgIHZhciBjb25kaXRpb24gPSBzdGF0ZS5jb25kaXRpb24sIHJlbGF0ZWQgPSBzdGF0ZS5yZWxhdGVkO1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyB0eXBlOiB0eXBlLCBjb25kaXRpb246IGNvbmRpdGlvbiwgcmVsYXRlZDogcmVsYXRlZCB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdHlwZSA9IGNmZy50eXBlLCBjb25kaXRpb24gPSBjZmcuY29uZGl0aW9uLCByZWxhdGVkID0gY2ZnLnJlbGF0ZWQ7XG4gICAgICAgIHRoaXMuc2hhcGVzID0gdGhpcy5fZ2V0U2hhcGVzKCk7XG4gICAgICAgIHRoaXMub3JpZ2luQXR0cnMgPSB0aGlzLl9nZXRPcmlnaW5BdHRycygpO1xuICAgICAgICAvLyB0aGlzLnJlc2V0WkluZGV4KCk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc2hhcGVPcmlnaW4gPSBzaGFwZS5nZXQoJ29yaWdpbicpLmRhdGE7XG4gICAgICAgICAgICB2YXIgb3JpZ2luID0gdXRpbF8xLmlzQXJyYXkoc2hhcGVPcmlnaW4pID8gc2hhcGVPcmlnaW5bMF0gOiBzaGFwZU9yaWdpbjtcbiAgICAgICAgICAgIGlmIChjb21wYXJlKG9yaWdpbiwgY29uZGl0aW9uKSkge1xuICAgICAgICAgICAgICAgIHZhciBzdGF0ZVN0eWxlID0gY2ZnLnN0eWxlID8gY2ZnLnN0eWxlIDogX3RoaXMuX2dldERlZmF1bHRTdGF0ZVN0eWxlKHR5cGUsIHNoYXBlKTtcbiAgICAgICAgICAgICAgICB2YXIgb3JpZ2luQXR0ciA9IF90aGlzLm9yaWdpbkF0dHJzW2luZGV4XTtcbiAgICAgICAgICAgICAgICB2YXIgYXR0cnMgPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHN0YXRlU3R5bGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzID0gc3RhdGVTdHlsZShvcmlnaW5BdHRyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzID0gdXRpbF8xLm1peCh7fSwgb3JpZ2luQXR0ciwgc3RhdGVTdHlsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNoYXBlLmF0dHIoYXR0cnMpO1xuICAgICAgICAgICAgICAgIF90aGlzLnNldFpJbmRleCh0eXBlLCBzaGFwZSk7XG4gICAgICAgICAgICAgICAgLy8gY29uc3QgY2FudmFzID0gdGhpcy5wbG90LmNhbnZhcztcbiAgICAgICAgICAgICAgICAvLyBjYW52YXMuZHJhdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8g57uE5Lu25LiO5Zu+5b2i5a+554q25oCB6YeP55qE5ZON5bqU5LiN5LiA5a6a5ZCM5q2lXG4gICAgICAgIGlmIChyZWxhdGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJzZXJSZWxhdGVkKHR5cGUsIHJlbGF0ZWQsIGNvbmRpdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLl91cGRhdGVTdGF0ZVByb2Nlc3MgPSBmdW5jdGlvbiAoc2V0U3RhdGVDZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2goc2V0U3RhdGVDZmcsIGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgICAgIHZhciBzdGF0ZSA9IGNmZy5zdGF0ZTtcbiAgICAgICAgICAgIHZhciBoYW5kbGVyO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHN0YXRlKSkge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IHN0YXRlKGUpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zdGF0ZU1hbmFnZXIuc2V0U3RhdGUocy5uYW1lLCBzLmV4cCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnN0YXRlTWFuYWdlci5zZXRTdGF0ZShzdGF0ZS5uYW1lLCBzdGF0ZS5leHApO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2ZnLmV2ZW50KSB7XG4gICAgICAgICAgICAgICAgZXZlbnRfMS5vbkV2ZW50KF90aGlzLnBsb3QsIF90aGlzLl9ldmVudFBhcnNlcihjZmcuZXZlbnQpLCBoYW5kbGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLl9zdGF0ZUNoYW5nZVByb2Nlc3MgPSBmdW5jdGlvbiAob25DaGFuZ2VDZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2gob25DaGFuZ2VDZmcsIGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgICAgIF90aGlzLnN0YXRlTWFuYWdlci5vbihjZmcubmFtZSArIFwiOmNoYW5nZVwiLCBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgICAgICAgICBjZmcuY2FsbGJhY2socHJvcHMsIF90aGlzLnBsb3QpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU3RhdGVDb250cm9sbGVyLnByb3RvdHlwZS5fZ2V0U2hhcGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2hhcGVzID0gW107XG4gICAgICAgIHZhciBnZW9tcyA9IHRoaXMucGxvdC52aWV3Lmdlb21ldHJpZXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGdlb21zLCBmdW5jdGlvbiAoZ2VvbSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlQ29udGFpbmVyID0gZ2VvbS5jb250YWluZXI7XG4gICAgICAgICAgICBfdGhpcy5zaGFwZUNvbnRhaW5lcnMucHVzaChzaGFwZUNvbnRhaW5lcik7XG4gICAgICAgICAgICBpZiAoIWdlb20uZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgc2hhcGVzLnB1c2guYXBwbHkoc2hhcGVzLCBnZW9tLmdldFNoYXBlcygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZXM7XG4gICAgfTtcbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLl9nZXRPcmlnaW5BdHRycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF0dHJzID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgICAgIGF0dHJzLnB1c2godXRpbF8xLmNsb25lKHNoYXBlLmF0dHIoKSkpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGF0dHJzO1xuICAgIH07XG4gICAgLy8g5bCGZzIgZ2VvbXRyeei9rOS4unBsb3TlsYJnZW9tZXRyeVxuICAgIFN0YXRlQ29udHJvbGxlci5wcm90b3R5cGUuX2V2ZW50UGFyc2VyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHZhciBldmVudENmZyA9IGV2ZW50LnNwbGl0KCc6Jyk7XG4gICAgICAgIHZhciBldmVudFRhcmdldCA9IHRoaXMucGxvdC5nZW9tZXRyeVBhcnNlcignZzInLCBldmVudENmZ1swXSk7XG4gICAgICAgIHZhciBldmVudE5hbWUgPSBldmVudENmZ1sxXTtcbiAgICAgICAgcmV0dXJuIGV2ZW50VGFyZ2V0ICsgXCI6XCIgKyBldmVudE5hbWU7XG4gICAgfTtcbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLl9nZXREZWZhdWx0U3RhdGVTdHlsZSA9IGZ1bmN0aW9uICh0eXBlLCBzaGFwZSkge1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnBsb3QudGhlbWU7XG4gICAgICAgIHZhciBwbG90R2VvbVR5cGUgPSB0aGlzLnBsb3QuZ2VvbWV0cnlQYXJzZXIoJ3Bsb3QnLCBzaGFwZS5uYW1lKTtcbiAgICAgICAgdmFyIHN0eWxlRmllbGQgPSBwbG90R2VvbVR5cGUgKyBcIlN0eWxlXCI7XG4gICAgICAgIGlmICh0aGVtZVtzdHlsZUZpZWxkXSkge1xuICAgICAgICAgICAgdmFyIHN0eWxlID0gdGhlbWVbc3R5bGVGaWVsZF1bdHlwZV07XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24oc3R5bGUpKSB7XG4gICAgICAgICAgICAgICAgc3R5bGUgPSBzdHlsZShzaGFwZS5hdHRyKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9O1xuICAgIFN0YXRlQ29udHJvbGxlci5wcm90b3R5cGUuX3BhcnNlclJlbGF0ZWQgPSBmdW5jdGlvbiAodHlwZSwgcmVsYXRlZCwgY29uZGl0aW9uKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHJlbGF0ZWQsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMucGxvdFtyXSkge1xuICAgICAgICAgICAgICAgIC8vIGZpeG1lOiDoh6rlrprkuYnnu4Tku7ZcbiAgICAgICAgICAgICAgICAvLyB0aGlzLnBsb3Rbcl0uc2V0U3RhdGUodHlwZSwgY29uZGl0aW9uKTtcbiAgICAgICAgICAgICAgICB2YXIgbWV0aG9kID0gZmFjdG9yeV8xLmdldENvbXBvbmVudFN0YXRlTWV0aG9kKHIsIHR5cGUpO1xuICAgICAgICAgICAgICAgIG1ldGhvZChfdGhpcy5wbG90LCBjb25kaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIHByaXZhdGUgc2V0XG4gICAgU3RhdGVDb250cm9sbGVyLnByb3RvdHlwZS5zZXRaSW5kZXggPSBmdW5jdGlvbiAoc3RhdGVUeXBlLCBzaGFwZSkge1xuICAgICAgICBpZiAoc3RhdGVUeXBlID09PSAnYWN0aXZlJyB8fCBzdGF0ZVR5cGUgPT09ICdzZWxlY3RlZCcpIHtcbiAgICAgICAgICAgIC8vIHNoYXBlLnNldFpJbmRleCgxKTtcbiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHNoYXBlLmdldCgncGFyZW50JykuZ2V0KCdjaGlsZHJlbicpO1xuICAgICAgICAgICAgY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV0uc2V0WkluZGV4KDApO1xuICAgICAgICAgICAgc2hhcGUuc2V0WkluZGV4KDEpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTdGF0ZUNvbnRyb2xsZXIucHJvdG90eXBlLnJlc2V0WkluZGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLnNoYXBlQ29udGFpbmVycywgZnVuY3Rpb24gKGNvbnRhaW5lcikge1xuICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gY29udGFpbmVyLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIGNoaWxkcmVuLnNvcnQoZnVuY3Rpb24gKG9iajEsIG9iajIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqMS5fSU5ERVggLSBvYmoyLl9JTkRFWDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTdGF0ZUNvbnRyb2xsZXI7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhdGVDb250cm9sbGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciB0aGVtZV8yID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvcmVzcG9uc2l2ZS90aGVtZVwiKTtcbnZhciB0aGVtZV8zID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lL3RoZW1lXCIpO1xuLyoqXG4gKiDotJ/otKPlm77ooah0aGVtZeeahOeuoeeQhlxuICovXG52YXIgRzJEZWZhdWx0VGhlbWUgPSBkZXBlbmRlbnRzXzEuZ2V0VGhlbWUoKTtcbnZhciBUaGVtZUNvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVGhlbWVDb250cm9sbGVyKCkge1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDojrflj5bmjIflrprnmoTlhajlsYB0aGVtZVxuICAgICAqIEBwYXJhbSB0aGVtZVxuICAgICAqL1xuICAgIFRoZW1lQ29udHJvbGxlci5nZXRHbG9iYWxUaGVtZSA9IGZ1bmN0aW9uICh0aGVtZSkge1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHRoZW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoZW1lXzEuZ2V0R2xvYmFsVGhlbWUodGhlbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgdGhlbWVfMS5nZXRHbG9iYWxUaGVtZSgpLCB0aGVtZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDpgJrov4cgdGhlbWUg5ZKM5Zu+6KGo57G75Z6L77yM6I635Y+W5b2T5YmNIHBsb3Qg5a+55bqU55qE5Li76aKYXG4gICAgICogQHBhcmFtIHByb3BzXG4gICAgICogQHBhcmFtIHR5cGVcbiAgICAgKi9cbiAgICBUaGVtZUNvbnRyb2xsZXIucHJvdG90eXBlLmdldFBsb3RUaGVtZSA9IGZ1bmN0aW9uIChwcm9wcywgdHlwZSkge1xuICAgICAgICB2YXIgdGhlbWUgPSBwcm9wcy50aGVtZTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc1N0cmluZyh0aGVtZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgdGhlbWVfMS5nZXRHbG9iYWxUaGVtZSh0aGVtZSksIHRoZW1lXzEuZ2V0VGhlbWUodHlwZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgdGhlbWVfMS5nZXRHbG9iYWxUaGVtZSgpLCB0aGVtZV8xLmdldFRoZW1lKHR5cGUpLCB0aGVtZV8zLmNvbnZlcnRUaGVtZVRvRzJUaGVtZSh0eXBlLCB0aGVtZSkpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W6L2s5YyW5oiQIEcyIOeahOe7k+aehOS4u+mimFxuICAgICAqIEBwYXJhbSBwcm9wc1xuICAgICAqIEBwYXJhbSB0eXBlXG4gICAgICovXG4gICAgVGhlbWVDb250cm9sbGVyLnByb3RvdHlwZS5nZXRUaGVtZSA9IGZ1bmN0aW9uIChwcm9wcywgdHlwZSkge1xuICAgICAgICB2YXIgcGxvdEcyVGhlbWUgPSB0aGVtZV8xLmNvbnZlcnRUb0cyVGhlbWUodGhpcy5nZXRQbG90VGhlbWUocHJvcHMsIHR5cGUpKTtcbiAgICAgICAgdmFyIGcyVGhlbWUgPSB1dGlsXzEuZGVlcE1peCh7fSwgRzJEZWZhdWx0VGhlbWUsIHBsb3RHMlRoZW1lKTtcbiAgICAgICAgcmV0dXJuIGcyVGhlbWU7XG4gICAgfTtcbiAgICBUaGVtZUNvbnRyb2xsZXIucHJvdG90eXBlLmdldFJlc3BvbnNpdmVUaGVtZSA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIHJldHVybiB0aGVtZV8yLmdldFJlc3BvbnNpdmVUaGVtZSh0eXBlKSB8fCB0aGVtZV8yLmdldFJlc3BvbnNpdmVUaGVtZSgnZGVmYXVsdCcpO1xuICAgIH07XG4gICAgcmV0dXJuIFRoZW1lQ29udHJvbGxlcjtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUaGVtZUNvbnRyb2xsZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0UGxvdFR5cGUgPSBleHBvcnRzLnJlZ2lzdGVyUGxvdFR5cGUgPSB2b2lkIDA7XG4vKiog5omA5pyJ57uf6K6h5Zu+5b2iICovXG52YXIgR0xPQkFMX1BMT1RfTUFQID0ge307XG5mdW5jdGlvbiByZWdpc3RlclBsb3RUeXBlKG5hbWUsIGN0cikge1xuICAgIEdMT0JBTF9QTE9UX01BUFtuYW1lLnRvTG93ZXJDYXNlKCldID0gY3RyO1xufVxuZXhwb3J0cy5yZWdpc3RlclBsb3RUeXBlID0gcmVnaXN0ZXJQbG90VHlwZTtcbmZ1bmN0aW9uIGdldFBsb3RUeXBlKG5hbWUpIHtcbiAgICByZXR1cm4gR0xPQkFMX1BMT1RfTUFQW25hbWUudG9Mb3dlckNhc2UoKV07XG59XG5leHBvcnRzLmdldFBsb3RUeXBlID0gZ2V0UGxvdFR5cGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nbG9iYWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBldmVudF9lbWl0dGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiQGFudHYvZXZlbnQtZW1pdHRlclwiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2V2ZW50XCIpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi91dGlsL2Jib3hcIikpO1xudmFyIExheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExheWVyLCBfc3VwZXIpO1xuICAgIC8qKlxuICAgICAqIGxheWVyIGJhc2UgZm9yIGcycGxvdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExheWVyKHByb3BzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmxheWVycyA9IFtdO1xuICAgICAgICBfdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMudmlzaWJpbGl0eSA9IHRydWU7XG4gICAgICAgIF90aGlzLnJlbmRlcmVkID0gZmFsc2U7XG4gICAgICAgIF90aGlzLmV2ZW50SGFuZGxlcnMgPSBbXTtcbiAgICAgICAgX3RoaXMub3B0aW9ucyA9IF90aGlzLmdldE9wdGlvbnMocHJvcHMpO1xuICAgICAgICBfdGhpcy5wcm9jZXNzT3B0aW9ucyhfdGhpcy5vcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBMYXllci5wcm90b3R5cGUucHJvY2Vzc09wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gb3B0aW9ucy5pZDtcbiAgICAgICAgdGhpcy54ID0gb3B0aW9ucy54IHx8IDA7XG4gICAgICAgIHRoaXMueSA9IG9wdGlvbnMueSB8fCAwO1xuICAgICAgICB0aGlzLndpZHRoID0gb3B0aW9ucy53aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBvcHRpb25zLmhlaWdodDtcbiAgICAgICAgdGhpcy5jYW52YXMgPSBvcHRpb25zLmNhbnZhcztcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBvcHRpb25zLnBhcmVudDtcbiAgICB9O1xuICAgIExheWVyLnByb3RvdHlwZS51cGRhdGVDb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLm9wdGlvbnMsIGNmZyk7XG4gICAgICAgIHRoaXMucHJvY2Vzc09wdGlvbnModGhpcy5vcHRpb25zKTtcbiAgICB9O1xuICAgIExheWVyLnByb3RvdHlwZS5iZWZvcmVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGluaXQgbGlmZSBjeWNsZVxuICAgICAqL1xuICAgIExheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmxheWVyQkJveCA9IHRoaXMuZ2V0TGF5ZXJCQm94KCk7XG4gICAgICAgIHRoaXMubGF5ZXJSZWdpb24gPSB0aGlzLmdldExheWVyUmVnaW9uKCk7XG4gICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgbGF5ZXIuaW5pdCgpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExheWVyLnByb3RvdHlwZS5hZnRlckluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogcmVuZGVyIGxheWVyIHJlY3Vyc2l2ZWx5XG4gICAgICovXG4gICAgTGF5ZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gZml4bWU6IOetiXBsb3TkuI3lho3nu6fmib9sYXllcu+8jOi/meS4quWwseWPr+S7peaMquWIsOaehOmAoOWHveaVsOmHjOWOu++8jOS4jemcgOimgeWGjeWKoOaYr+WQpnJlbmRlcui/h+eahOWIpOaWreS6hlxuICAgICAgICBpZiAoIXRoaXMucmVuZGVyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyID0gdGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC5jb250YWluZXIuYWRkR3JvdXAoKSA6IHRoaXMuY2FudmFzLmFkZEdyb3VwKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW5kZXJlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuYmVmb3JlSW5pdCgpO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICAgICAgdGhpcy5hZnRlckluaXQoKTtcbiAgICAgICAgLy8odGhpcy5jb250YWluZXIsIFtbJ3QnLCB0aGlzLngsIHRoaXMueV1dKTtcbiAgICAgICAgdGhpcy5lYWNoTGF5ZXIoZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgICAgICBsYXllci5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGNsZWFyIGxheWVyIGNvbnRlbnRcbiAgICAgKi9cbiAgICBMYXllci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgbGF5ZXIuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sYXllcnMgPSBbXTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGRlc3Ryb3kgbGF5ZXIgcmVjdXJzaXZlbHksIHJlbW92ZSB0aGUgY29udGFpbmVyIG9mIGxheWVyXG4gICAgICovXG4gICAgTGF5ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgbGF5ZXIuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5ldmVudEhhbmRsZXJzLCBmdW5jdGlvbiAoaCkge1xuICAgICAgICAgICAgX3RoaXMub2ZmKGguZXZlbnROYW1lLCBoLmhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKHRydWUpO1xuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBkaXNwbGF5IGxheWVyXG4gICAgICovXG4gICAgTGF5ZXIucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmF0dHIoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgdHJ1ZSk7XG4gICAgICAgIHRoaXMudmlzaWJpbGl0eSA9IHRydWU7XG4gICAgICAgIHRoaXMuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIGhpZGUgbGF5ZXJcbiAgICAgKi9cbiAgICBMYXllci5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuYXR0cigndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICB0aGlzLnZpc2liaWxpdHkgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogYWRkIGNoaWxkcmVuIGxheWVyXG4gICAgICogQHBhcmFtIGxheWVyXG4gICAgICovXG4gICAgTGF5ZXIucHJvdG90eXBlLmFkZExheWVyID0gZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgIHZhciBpZHggPSB1dGlsXzEuZmluZEluZGV4KHRoaXMubGF5ZXJzLCBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbSA9PT0gbGF5ZXI7IH0pO1xuICAgICAgICBpZiAoaWR4IDwgMCkge1xuICAgICAgICAgICAgaWYgKGxheWVyLnBhcmVudCAhPT0gdGhpcykge1xuICAgICAgICAgICAgICAgIGxheWVyLnBhcmVudCA9IHRoaXM7XG4gICAgICAgICAgICAgICAgbGF5ZXIuaW5pdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5sYXllcnMucHVzaChsYXllcik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIHJlbW92ZSBjaGlsZHJlbiBsYXllclxuICAgICAqIEBwYXJhbSBsYXllclxuICAgICAqL1xuICAgIExheWVyLnByb3RvdHlwZS5yZW1vdmVMYXllciA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICB2YXIgaWR4ID0gdXRpbF8xLmZpbmRJbmRleCh0aGlzLmxheWVycywgZnVuY3Rpb24gKGl0ZW0pIHsgcmV0dXJuIGl0ZW0gPT09IGxheWVyOyB9KTtcbiAgICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmxheWVycy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICogdXBkYXRlIGxheWVyJ3MgZGlzcGxheSByYW5nZVxuICAgICAqIEBwYXJhbSBwcm9wc1xuICAgICAqIEBwYXJhbSByZWN1cnNpdmUgd2hldGhlciB1cGRhdGUgY2hpbGRyZW4gbGF5ZXJzIG9yIG5vdFxuICAgICAqL1xuICAgIExheWVyLnByb3RvdHlwZS51cGRhdGVCQm94ID0gZnVuY3Rpb24gKHByb3BzLCByZWN1cnNpdmUpIHtcbiAgICAgICAgaWYgKHJlY3Vyc2l2ZSA9PT0gdm9pZCAwKSB7IHJlY3Vyc2l2ZSA9IGZhbHNlOyB9XG4gICAgICAgIHZhciBvcmlnaW5SYW5nZSA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMueCxcbiAgICAgICAgICAgIHk6IHRoaXMueSxcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG5ld1JhbmdlID0gdXRpbF8xLmRlZXBNaXgoe30sIG9yaWdpblJhbmdlLCBwcm9wcyk7XG4gICAgICAgIHRoaXMueCA9IG5ld1JhbmdlLng7XG4gICAgICAgIHRoaXMueSA9IG5ld1JhbmdlLnk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXdSYW5nZS53aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBuZXdSYW5nZS5oZWlnaHQ7XG4gICAgICAgIHRoaXMubGF5ZXJCQm94ID0gdGhpcy5nZXRMYXllckJCb3goKTtcbiAgICAgICAgdGhpcy5sYXllclJlZ2lvbiA9IHRoaXMuZ2V0TGF5ZXJSZWdpb24oKTtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgaWYgKHJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgdGhpcy5lYWNoTGF5ZXIoZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgICAgICAgICAgbGF5ZXIudXBkYXRlQkJveEJ5UGFyZW50KCk7XG4gICAgICAgICAgICAgICAgbGF5ZXIucmVuZGVyKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiB1cGRhdGUgZGlzcGxheSByYW5nZSBhY2NvcmRpbmcgdG8gcGFyZW50IGxheWVyJ3MgcmFuZ2VcbiAgICAgKi9cbiAgICBMYXllci5wcm90b3R5cGUudXBkYXRlQkJveEJ5UGFyZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmVnaW9uID0gdGhpcy5sYXllclJlZ2lvbjtcbiAgICAgICAgdGhpcy54ID0gdGhpcy5wYXJlbnQueCArIHRoaXMucGFyZW50LndpZHRoICogcmVnaW9uLnN0YXJ0Lng7XG4gICAgICAgIHRoaXMueSA9IHRoaXMucGFyZW50LnkgKyB0aGlzLnBhcmVudC5oZWlnaHQgKiByZWdpb24uc3RhcnQueTtcbiAgICAgICAgdGhpcy53aWR0aCA9IHRoaXMucGFyZW50LndpZHRoICogKHJlZ2lvbi5lbmQueCAtIHJlZ2lvbi5zdGFydC54KTtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnBhcmVudC5oZWlnaHQgKiAocmVnaW9uLmVuZC55IC0gcmVnaW9uLnN0YXJ0LnkpO1xuICAgICAgICB0aGlzLmxheWVyQkJveCA9IHRoaXMuZ2V0TGF5ZXJCQm94KCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBnZXQgZ2xvYmFsIHBvc2l0aW9uIG9mIGxheWVyXG4gICAgICovXG4gICAgTGF5ZXIucHJvdG90eXBlLmdldEdsb2JhbFBvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ2xvYmFsWCA9IHRoaXMueDtcbiAgICAgICAgdmFyIGdsb2JhbFkgPSB0aGlzLnk7XG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudDtcbiAgICAgICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgICAgICAgZ2xvYmFsWCArPSBwYXJlbnQueDtcbiAgICAgICAgICAgIGdsb2JhbFkgKz0gcGFyZW50Lnk7XG4gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHg6IGdsb2JhbFgsIHk6IGdsb2JhbFkgfTtcbiAgICB9O1xuICAgIExheWVyLnByb3RvdHlwZS5nZXRHbG9iYWxCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ2xvYmFsUG9zaXRpb24gPSB0aGlzLmdldEdsb2JhbFBvc2l0aW9uKCk7XG4gICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQoZ2xvYmFsUG9zaXRpb24ueCwgZ2xvYmFsUG9zaXRpb24ueSwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuICAgIH07XG4gICAgTGF5ZXIucHJvdG90eXBlLmdldE9wdGlvbnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIHBhcmVudFdpZHRoID0gMDtcbiAgICAgICAgdmFyIHBhcmVudEhlaWdodCA9IDA7XG4gICAgICAgIGlmIChwcm9wcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIHBhcmVudFdpZHRoID0gcHJvcHMucGFyZW50LndpZHRoO1xuICAgICAgICAgICAgcGFyZW50SGVpZ2h0ID0gcHJvcHMucGFyZW50LmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgIHdpZHRoOiBwYXJlbnRXaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogcGFyZW50SGVpZ2h0LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRPcHRpb25zLCBwcm9wcyk7XG4gICAgfTtcbiAgICBMYXllci5wcm90b3R5cGUuZWFjaExheWVyID0gZnVuY3Rpb24gKGNiKSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMubGF5ZXJzLCBjYik7XG4gICAgfTtcbiAgICBMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoZXZlbnRQYXJzZXIpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGV2ZW50c05hbWUgPSB1dGlsXzEua2V5cyhldmVudF8xLkxBWUVSX0VWRU5UX01BUCk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGV2ZW50UGFyc2VyLCBmdW5jdGlvbiAoZSwgaykge1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5jb250YWlucyhldmVudHNOYW1lLCBrKSAmJiB1dGlsXzEuaXNGdW5jdGlvbihlKSkge1xuICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWUgPSBldmVudF8xLkxBWUVSX0VWRU5UX01BUFtrXSB8fCBrO1xuICAgICAgICAgICAgICAgIHZhciBoYW5kbGVyID0gZTtcbiAgICAgICAgICAgICAgICBfdGhpcy5vbihldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIF90aGlzLmV2ZW50SGFuZGxlcnMucHVzaCh7IG5hbWU6IGV2ZW50TmFtZSwgaGFuZGxlcjogaGFuZGxlciB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBMYXllci5wcm90b3R5cGUuZ2V0TGF5ZXJCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IGJib3hfMS5kZWZhdWx0KHRoaXMueCwgdGhpcy55LCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG4gICAgfTtcbiAgICBMYXllci5wcm90b3R5cGUuZ2V0TGF5ZXJSZWdpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdmFyIHBhcmVudFdpZHRoID0gdGhpcy5wYXJlbnQud2lkdGg7XG4gICAgICAgICAgICB2YXIgcGFyZW50SGVpZ2h0ID0gdGhpcy5wYXJlbnQuaGVpZ2h0O1xuICAgICAgICAgICAgdmFyIHBhcmVudFggPSB0aGlzLnBhcmVudC54O1xuICAgICAgICAgICAgdmFyIHBhcmVudFkgPSB0aGlzLnBhcmVudC55O1xuICAgICAgICAgICAgdmFyIHN0YXJ0WCA9ICh0aGlzLnggLSBwYXJlbnRYKSAvIHBhcmVudFdpZHRoO1xuICAgICAgICAgICAgdmFyIHN0YXJ0WSA9ICh0aGlzLnkgLSBwYXJlbnRZKSAvIHBhcmVudEhlaWdodDtcbiAgICAgICAgICAgIHZhciBlbmRYID0gKHRoaXMueCArIHRoaXMud2lkdGggLSBwYXJlbnRYKSAvIHBhcmVudFdpZHRoO1xuICAgICAgICAgICAgdmFyIGVuZFkgPSAodGhpcy55ICsgdGhpcy5oZWlnaHQgLSBwYXJlbnRZKSAvIHBhcmVudEhlaWdodDtcbiAgICAgICAgICAgIHJldHVybiB7IHN0YXJ0OiB7IHg6IHN0YXJ0WCwgeTogc3RhcnRZIH0sIGVuZDogeyB4OiBlbmRYLCB5OiBlbmRZIH0gfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBzdGFydDogeyB4OiAwLCB5OiAwIH0sIGVuZDogeyB4OiAxLCB5OiAxIH0gfTtcbiAgICB9O1xuICAgIHJldHVybiBMYXllcjtcbn0oZXZlbnRfZW1pdHRlcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExheWVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBldmVudF9lbWl0dGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiQGFudHYvZXZlbnQtZW1pdHRlclwiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY2FudmFzXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jb250cm9sbGVyL2NhbnZhc1wiKSk7XG52YXIgZXZlbnRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbnRyb2xsZXIvZXZlbnRcIikpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4vZ2xvYmFsXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgdmlld19sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdmlldy1sYXllclwiKSk7XG52YXIgZXZlbnRfMiA9IHJlcXVpcmUoXCIuLi91dGlsL2V2ZW50XCIpO1xudmFyIEJhc2VQbG90ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJhc2VQbG90LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhc2VQbG90KGNvbnRhaW5lciwgcHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuY29udGFpbmVyRE9NID0gdHlwZW9mIGNvbnRhaW5lciA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjb250YWluZXIpIDogY29udGFpbmVyO1xuICAgICAgICBfdGhpcy5mb3JjZUZpdCA9ICF1dGlsXzEuaXNOaWwocHJvcHMuZm9yY2VGaXQpID8gcHJvcHMuZm9yY2VGaXQgOiB1dGlsXzEuaXNOaWwocHJvcHMud2lkdGgpICYmIHV0aWxfMS5pc05pbChwcm9wcy5oZWlnaHQpO1xuICAgICAgICBfdGhpcy5yZW5kZXJlciA9IHByb3BzLnJlbmRlcmVyIHx8ICdjYW52YXMnO1xuICAgICAgICBfdGhpcy5waXhlbFJhdGlvID0gcHJvcHMucGl4ZWxSYXRpbyB8fCBudWxsO1xuICAgICAgICBfdGhpcy53aWR0aCA9IHByb3BzLndpZHRoO1xuICAgICAgICBfdGhpcy5oZWlnaHQgPSBwcm9wcy5oZWlnaHQ7XG4gICAgICAgIF90aGlzLnRoZW1lID0gcHJvcHMudGhlbWU7XG4gICAgICAgIF90aGlzLmxvY2FsUmVmcmVzaCA9IHByb3BzLmxvY2FsUmVmcmVzaDtcbiAgICAgICAgX3RoaXMuY2FudmFzQ29udHJvbGxlciA9IG5ldyBjYW52YXNfMS5kZWZhdWx0KHtcbiAgICAgICAgICAgIGNvbnRhaW5lckRPTTogX3RoaXMuY29udGFpbmVyRE9NLFxuICAgICAgICAgICAgcGxvdDogX3RoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICAvKiogdXBkYXRlIGxheWVyIHByb3BlcnRpZXMgKi9cbiAgICAgICAgX3RoaXMud2lkdGggPSBfdGhpcy5jYW52YXNDb250cm9sbGVyLndpZHRoO1xuICAgICAgICBfdGhpcy5oZWlnaHQgPSBfdGhpcy5jYW52YXNDb250cm9sbGVyLmhlaWdodDtcbiAgICAgICAgX3RoaXMuY2FudmFzID0gX3RoaXMuY2FudmFzQ29udHJvbGxlci5jYW52YXM7XG4gICAgICAgIF90aGlzLmxheWVycyA9IFtdO1xuICAgICAgICBfdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMuY3JlYXRlTGF5ZXJzKHByb3BzKTtcbiAgICAgICAgLyoqIGJpbmQgZXZlbnRzICovXG4gICAgICAgIF90aGlzLmV2ZW50Q29udHJvbGxlciA9IG5ldyBldmVudF8xLmRlZmF1bHQoe1xuICAgICAgICAgICAgcGxvdDogX3RoaXMsXG4gICAgICAgICAgICBjYW52YXM6IF90aGlzLmNhbnZhc0NvbnRyb2xsZXIuY2FudmFzLFxuICAgICAgICB9KTtcbiAgICAgICAgX3RoaXMuZXZlbnRDb250cm9sbGVyLmJpbmRFdmVudHMoKTtcbiAgICAgICAgX3RoaXMucGFyc2VFdmVudHMocHJvcHMpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKiDnlJ/lkb3lkajmnJ8gKi9cbiAgICBCYXNlUGxvdC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5lYWNoTGF5ZXIoZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgICAgICBsYXllci5kZXN0cm95KCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNhbnZhc0NvbnRyb2xsZXIuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLmV2ZW50Q29udHJvbGxlci5jbGVhckV2ZW50cygpO1xuICAgICAgICB0aGlzLmxheWVycyA9IFtdO1xuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDph43mlrDnu5jliLblm77lvaJcbiAgICAgKi9cbiAgICBCYXNlUGxvdC5wcm90b3R5cGUucmVwYWludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jYW52YXNDb250cm9sbGVyLmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBCYXNlUGxvdC5wcm90b3R5cGUudXBkYXRlQ29uZmlnID0gZnVuY3Rpb24gKGNvbmZpZywgYWxsKSB7XG4gICAgICAgIGlmIChhbGwgPT09IHZvaWQgMCkgeyBhbGwgPSBmYWxzZTsgfVxuICAgICAgICBpZiAoYWxsKSB7XG4gICAgICAgICAgICB0aGlzLmVhY2hMYXllcihmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAobGF5ZXIgaW5zdGFuY2VvZiB2aWV3X2xheWVyXzEuZGVmYXVsdCkge1xuICAgICAgICAgICAgICAgICAgICBsYXllci51cGRhdGVDb25maWcoY29uZmlnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICAgICAgaWYgKGxheWVyIGluc3RhbmNlb2YgbGF5ZXJfMS5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgbGF5ZXIudXBkYXRlQ29uZmlnKGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmZpZy53aWR0aCkge1xuICAgICAgICAgICAgdGhpcy53aWR0aCA9IGNvbmZpZy53aWR0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZmlnLmhlaWdodCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBjb25maWcuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcudGhlbWUpIHtcbiAgICAgICAgICAgIHRoaXMudGhlbWUgPSBjb25maWcudGhlbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jYW52YXNDb250cm9sbGVyLnVwZGF0ZUNhbnZhc1NpemUoKTtcbiAgICAgICAgdGhpcy5jYW52YXNDb250cm9sbGVyLnVwZGF0ZUNhbnZhc1RoZW1lKCk7XG4gICAgfTtcbiAgICBCYXNlUGxvdC5wcm90b3R5cGUuY2hhbmdlRGF0YSA9IGZ1bmN0aW9uIChkYXRhLCBhbGwpIHtcbiAgICAgICAgaWYgKGFsbCA9PT0gdm9pZCAwKSB7IGFsbCA9IGZhbHNlOyB9XG4gICAgICAgIGlmIChhbGwpIHtcbiAgICAgICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgICAgIGlmIChsYXllciBpbnN0YW5jZW9mIHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGxheWVyLmNoYW5nZURhdGEoZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgICAgIGlmIChsYXllciBpbnN0YW5jZW9mIHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgbGF5ZXIuY2hhbmdlRGF0YShkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgQmFzZVBsb3QucHJvdG90eXBlLmdldFNjYWxlQnlGaWVsZCA9IGZ1bmN0aW9uIChmaWVsZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sYXllcnNbMF0uZ2V0U2NhbGVCeUZpZWxkKGZpZWxkKTtcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXRYU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxheWVyc1swXS5nZXRYU2NhbGUoKTtcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXRZU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxheWVyc1swXS5nZXRZU2NhbGUoKTtcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXRDb2xvclNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sYXllcnNbMF0uZ2V0Q29sb3JTY2FsZSgpO1xuICAgIH07XG4gICAgQmFzZVBsb3QucHJvdG90eXBlLmdldFBsb3RUaGVtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy5sYXllcnNbMF07XG4gICAgICAgIHJldHVybiBsYXllci5nZXRQbG90VGhlbWUoKTtcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXREYXRhID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgcmV0dXJuIGxheWVyLmdldERhdGEoKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe7keWumuS4gOS4quWklumDqOeahHN0YXRlTWFuYWdlclxuICAgICAqIOWFiOebtOaOpeS8oOmAkue7meWQhOS4quWtkCBMYXllclxuICAgICAqXG4gICAgICogIEBwYXJhbSBzdGF0ZU1hbmFnZXJcbiAgICAgKiAgQHBhcmFtIGNmZ1xuICAgICAqL1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5iaW5kU3RhdGVNYW5hZ2VyID0gZnVuY3Rpb24gKHN0YXRlTWFuYWdlciwgY2ZnKSB7XG4gICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgaWYgKGxheWVyIGluc3RhbmNlb2Ygdmlld19sYXllcl8xLmRlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICBsYXllci5iaW5kU3RhdGVNYW5hZ2VyKHN0YXRlTWFuYWdlciwgY2ZnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlk43lupTnirbmgIHph4/mm7TmlrDnmoTlv6vmjbfmlrnms5VcbiAgICAgKlxuICAgICAqICBAcGFyYW0gY29uZGl0aW9uXG4gICAgICogQHBhcmFtIHN0eWxlXG4gICAgICovXG4gICAgQmFzZVBsb3QucHJvdG90eXBlLnNldEFjdGl2ZSA9IGZ1bmN0aW9uIChjb25kaXRpb24sIHN0eWxlKSB7XG4gICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgaWYgKGxheWVyIGluc3RhbmNlb2Ygdmlld19sYXllcl8xLmRlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICBsYXllci5zZXRBY3RpdmUoY29uZGl0aW9uLCBzdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQmFzZVBsb3QucHJvdG90eXBlLnNldFNlbGVjdGVkID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgc3R5bGUpIHtcbiAgICAgICAgdGhpcy5lYWNoTGF5ZXIoZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgICAgICBpZiAobGF5ZXIgaW5zdGFuY2VvZiB2aWV3X2xheWVyXzEuZGVmYXVsdCkge1xuICAgICAgICAgICAgICAgIGxheWVyLnNldFNlbGVjdGVkKGNvbmRpdGlvbiwgc3R5bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5zZXREaXNhYmxlID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgc3R5bGUpIHtcbiAgICAgICAgdGhpcy5lYWNoTGF5ZXIoZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgICAgICBpZiAobGF5ZXIgaW5zdGFuY2VvZiB2aWV3X2xheWVyXzEuZGVmYXVsdCkge1xuICAgICAgICAgICAgICAgIGxheWVyLnNldERpc2FibGUoY29uZGl0aW9uLCBzdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQmFzZVBsb3QucHJvdG90eXBlLnNldERlZmF1bHQgPSBmdW5jdGlvbiAoY29uZGl0aW9uLCBzdHlsZSkge1xuICAgICAgICB0aGlzLmVhY2hMYXllcihmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICAgICAgICAgIGlmIChsYXllciBpbnN0YW5jZW9mIHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgbGF5ZXIuc2V0RGVmYXVsdChjb25kaXRpb24sIHN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDojrflj5YgUGxvdCDnmoQgVmlld1xuICAgICAqL1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXRWaWV3ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDkuLTml7bvvJrpgb/lhY0gZ2V0TGF5ZXIg55qE57G75Z6L6L2s5o2i6Zeu6aKYXG4gICAgICAgIHJldHVybiB0aGlzLmxheWVyc1swXS52aWV3O1xuICAgIH07XG4gICAgLyoqXG4gICAgICog6I635Y+W5Zu+5b2i5LiL55qE5Zu+5bGCIExheWVy77yM6buY6K6k56ys5LiA5LiqIExheWVyXG4gICAgICogQHBhcmFtIGlkeFxuICAgICAqL1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXRMYXllciA9IGZ1bmN0aW9uIChpZHgpIHtcbiAgICAgICAgaWYgKGlkeCA9PT0gdm9pZCAwKSB7IGlkeCA9IDA7IH1cbiAgICAgICAgcmV0dXJuIHRoaXMubGF5ZXJzW2lkeF07XG4gICAgfTtcbiAgICBCYXNlUGxvdC5wcm90b3R5cGUuZ2V0Q2FudmFzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW52YXNDb250cm9sbGVyLmNhbnZhcztcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5nZXRMYXllcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxheWVycztcbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZWFjaExheWVyKGZ1bmN0aW9uIChsYXllcikgeyByZXR1cm4gbGF5ZXIucmVuZGVyKCk7IH0pO1xuICAgIH07XG4gICAgQmFzZVBsb3QucHJvdG90eXBlLmVhY2hMYXllciA9IGZ1bmN0aW9uIChjYikge1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmxheWVycywgY2IpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogYWRkIGNoaWxkcmVuIGxheWVyXG4gICAgICogQHBhcmFtIGxheWVyXG4gICAgICovXG4gICAgQmFzZVBsb3QucHJvdG90eXBlLmFkZExheWVyID0gZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgIHZhciBpZHggPSB1dGlsXzEuZmluZEluZGV4KHRoaXMubGF5ZXJzLCBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbSA9PT0gbGF5ZXI7IH0pO1xuICAgICAgICBpZiAoaWR4IDwgMCkge1xuICAgICAgICAgICAgdGhpcy5sYXllcnMucHVzaChsYXllcik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJhc2VQbG90LnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgaWYgKHByb3BzLmxheWVycykge1xuICAgICAgICAgICAgLy8gVE9ETzogY29tYm8gcGxvdFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHByb3BzLnR5cGUpIHtcbiAgICAgICAgICAgIHZhciB2aWV3TGF5ZXJDdHIgPSBnbG9iYWxfMS5nZXRQbG90VHlwZShwcm9wcy50eXBlKTtcbiAgICAgICAgICAgIHZhciB2aWV3TGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcywge1xuICAgICAgICAgICAgICAgIGNhbnZhczogdGhpcy5jYW52YXNDb250cm9sbGVyLmNhbnZhcyxcbiAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHZpZXdMYXllciA9IG5ldyB2aWV3TGF5ZXJDdHIodmlld0xheWVyUHJvcHMpO1xuICAgICAgICAgICAgdGhpcy5hZGRMYXllcih2aWV3TGF5ZXIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBCYXNlUGxvdC5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGV2ZW50c05hbWUgPSB1dGlsXzEua2V5cyhldmVudF8yLkNBTlZBU19FVkVOVF9NQVApO1xuICAgICAgICBpZiAocHJvcHMuZXZlbnRzKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwcm9wcy5ldmVudHMsIGZ1bmN0aW9uIChlLCBrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5jb250YWlucyhldmVudHNOYW1lLCBrKSAmJiB1dGlsXzEuaXNGdW5jdGlvbihlKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnROYW1lID0gZXZlbnRfMi5DQU5WQVNfRVZFTlRfTUFQW2tdIHx8IGs7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVyID0gZTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMub24oZXZlbnROYW1lLCBoYW5kbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIEJhc2VQbG90O1xufShldmVudF9lbWl0dGVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQmFzZVBsb3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wbG90LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uL2RlcGVuZGVudHNcIik7XG52YXIgZGVzY3JpcHRpb25fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9jb21wb25lbnRzL2Rlc2NyaXB0aW9uXCIpKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vY29tcG9uZW50cy9sYWJlbC9iYXNlXCIpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi9jb21wb25lbnRzL2ZhY3RvcnlcIik7XG52YXIgaW5kZXhfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9pbnRlcmFjdGlvbi9pbmRleFwiKSk7XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2V2ZW50XCIpO1xudmFyIHBhZGRpbmdfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbnRyb2xsZXIvcGFkZGluZ1wiKSk7XG52YXIgc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbnRyb2xsZXIvc3RhdGVcIikpO1xudmFyIHRoZW1lXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jb250cm9sbGVyL3RoZW1lXCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIGNvbW1vbl8xID0gcmVxdWlyZShcIi4uL3V0aWwvY29tbW9uXCIpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuLi91dGlsL2Jib3hcIikpO1xudmFyIGNvbnN0YW50c18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzXCIpO1xudmFyIFZpZXdMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhWaWV3TGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVmlld0xheWVyKHByb3BzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHByb3BzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5pbnRlcmFjdGlvbnMgPSBbXTtcbiAgICAgICAgX3RoaXMubGFiZWxzID0gW107XG4gICAgICAgIF90aGlzLm9wdGlvbnMgPSBfdGhpcy5nZXRPcHRpb25zKHByb3BzKTtcbiAgICAgICAgX3RoaXMuaW5pdGlhbE9wdGlvbnMgPSB1dGlsXzEuZGVlcE1peCh7fSwgX3RoaXMub3B0aW9ucyk7XG4gICAgICAgIF90aGlzLnBhZGRpbmdDb250cm9sbGVyID0gbmV3IHBhZGRpbmdfMS5kZWZhdWx0KHtcbiAgICAgICAgICAgIHBsb3Q6IF90aGlzLFxuICAgICAgICB9KTtcbiAgICAgICAgX3RoaXMuc3RhdGVDb250cm9sbGVyID0gbmV3IHN0YXRlXzEuZGVmYXVsdCh7XG4gICAgICAgICAgICBwbG90OiBfdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIF90aGlzLnRoZW1lQ29udHJvbGxlciA9IG5ldyB0aGVtZV8xLmRlZmF1bHQoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBWaWV3TGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXJlcjogJ2NhbnZhcycsXG4gICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFsaWduVG86ICdsZWZ0JyxcbiAgICAgICAgICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgICAgIGFsaWduVG86ICdsZWZ0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYWRkaW5nOiAnYXV0bycsXG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnYm90dG9tLWNlbnRlcicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hhcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNob3dDcm9zc2hhaXJzOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNyb3NzaGFpcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3gnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAyMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB4QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzcGFjaW5nOiAxMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogMTIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGludGVyYWN0aW9uczogW3sgdHlwZTogJ3Rvb2x0aXAnIH0sIHsgdHlwZTogJ2xlZ2VuZC1hY3RpdmUnIH0sIHsgdHlwZTogJ2xlZ2VuZC1maWx0ZXInIH1dLFxuICAgICAgICAgICAgYW5pbWF0aW9uOiB0cnVlLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5nZXRPcHRpb25zID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBjdXJPcHRpb25zID0gdGhpcy5vcHRpb25zIHx8IHt9O1xuICAgICAgICB2YXIgb3B0aW9ucyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0T3B0aW9ucy5jYWxsKHRoaXMsIHByb3BzKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmNvbnN0cnVjdG9yLmdldERlZmF1bHRPcHRpb25zKHByb3BzKTtcbiAgICAgICAgLy8gaW50ZXJhY3Rpb25zIOmcgOimgeWQiOW5tuWOu+mHjeS4i++8jOWmguaenOacieabtOaWsCBpbnRlcmFjdGlvbnPvvIzpnIDopoHljrvmjonlvZPliY3nmoQgaW50ZXJhY3Rpb25zIOmFjee9rlxuICAgICAgICB2YXIgaW50ZXJhY3Rpb25zID0gdXRpbF8xLnJlZHVjZSh1dGlsXzEuZmxhdHRlbih1dGlsXzEubWFwKFtvcHRpb25zLCBkZWZhdWx0T3B0aW9ucywgdXRpbF8xLmhhc0tleShwcm9wcywgJ2ludGVyYWN0aW9ucycpID8gcHJvcHMgOiBjdXJPcHRpb25zXSwgZnVuY3Rpb24gKHNyYykge1xuICAgICAgICAgICAgcmV0dXJuIHV0aWxfMS5nZXQoc3JjLCAnaW50ZXJhY3Rpb25zJywgW10pO1xuICAgICAgICB9KSksIGZ1bmN0aW9uIChyZXN1bHQsIGN1cikge1xuICAgICAgICAgICAgdmFyIGlkeCA9IHV0aWxfMS5maW5kSW5kZXgocmVzdWx0LCBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbS50eXBlID09PSBjdXIudHlwZTsgfSk7XG4gICAgICAgICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHNsaWJfMS5fX3NwcmVhZEFycmF5cyhyZXN1bHQsIFtjdXJdKTtcbiAgICAgICAgfSwgW10pO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIG9wdGlvbnMsIGRlZmF1bHRPcHRpb25zLCBjdXJPcHRpb25zLCBwcm9wcywgeyBpbnRlcmFjdGlvbnM6IGludGVyYWN0aW9ucyB9KTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuYmVmb3JlSW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5lbWl0KGNvbnN0YW50c18xLlZJRVdfTEFZRVJfTElGRV9DWUNMRS5CRUZPUkVfSU5JVCk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYmVmb3JlSW5pdC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy50aGVtZSA9IHRoaXMudGhlbWVDb250cm9sbGVyLmdldFRoZW1lKHRoaXMub3B0aW9ucywgdGhpcy50eXBlKTtcbiAgICAgICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAgICAgICBkYXRhOiB0aGlzLnByb2Nlc3NEYXRhKHRoaXMub3B0aW9ucy5kYXRhKSxcbiAgICAgICAgICAgIHNjYWxlczoge30sXG4gICAgICAgICAgICBsZWdlbmRzOiB7fSxcbiAgICAgICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgICBzaG93VGl0bGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXhlczoge30sXG4gICAgICAgICAgICBjb29yZGluYXRlOiB7IHR5cGU6ICdjYXJ0ZXNpYW4nIH0sXG4gICAgICAgICAgICBnZW9tZXRyaWVzOiBbXSxcbiAgICAgICAgICAgIGFubm90YXRpb25zOiBbXSxcbiAgICAgICAgICAgIGludGVyYWN0aW9uczogW10sXG4gICAgICAgICAgICB0aGVtZTogdGhpcy50aGVtZSxcbiAgICAgICAgICAgIHBhbmVsUmFuZ2U6IHt9LFxuICAgICAgICAgICAgYW5pbWF0ZToge30sXG4gICAgICAgICAgICB2aWV3czogW10sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucGFkZGluZ0NvbnRyb2xsZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5kcmF3VGl0bGUoKTtcbiAgICAgICAgdGhpcy5kcmF3RGVzY3JpcHRpb24oKTtcbiAgICAgICAgLy8g5pyJ5LqbaW50ZXJhY3Rpb27opoHosIPmlbTphY3nva7pobnvvIzmiYDku6Xpobrluo/mj5DliY1cbiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbigpO1xuICAgICAgICB0aGlzLmNvb3JkKCk7XG4gICAgICAgIHRoaXMuc2NhbGUoKTtcbiAgICAgICAgdGhpcy5heGlzKCk7XG4gICAgICAgIHRoaXMudG9vbHRpcCgpO1xuICAgICAgICB0aGlzLmxlZ2VuZCgpO1xuICAgICAgICB0aGlzLmFkZEdlb21ldHJ5KCk7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbigpO1xuICAgICAgICB0aGlzLmFuaW1hdGlvbigpO1xuICAgICAgICB0aGlzLnZpZXdSYW5nZSA9IHRoaXMuZ2V0Vmlld1JhbmdlKCk7XG4gICAgICAgIHZhciByZWdpb24gPSB0aGlzLnZpZXdSYW5nZVRvUmVnaW9uKHRoaXMudmlld1JhbmdlKTtcbiAgICAgICAgdGhpcy52aWV3ID0gbmV3IGRlcGVuZGVudHNfMS5WaWV3KHtcbiAgICAgICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgICAgIGNhbnZhczogdGhpcy5jYW52YXMsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kR3JvdXA6IHRoaXMuY29udGFpbmVyLmFkZEdyb3VwKCksXG4gICAgICAgICAgICBtaWRkbGVHcm91cDogdGhpcy5jb250YWluZXIuYWRkR3JvdXAoKSxcbiAgICAgICAgICAgIGZvcmVncm91bmRHcm91cDogdGhpcy5jb250YWluZXIuYWRkR3JvdXAoKSxcbiAgICAgICAgICAgIHBhZGRpbmc6IHRoaXMucGFkZGluZ0NvbnRyb2xsZXIuZ2V0UGFkZGluZygpLFxuICAgICAgICAgICAgdGhlbWU6IHRoaXMudGhlbWUsXG4gICAgICAgICAgICBvcHRpb25zOiB0aGlzLmNvbmZpZyxcbiAgICAgICAgICAgIGxpbWl0SW5QbG90OiB0aGlzLmlzTGltaXRJblBsb3QoKSxcbiAgICAgICAgICAgIHJlZ2lvbjogcmVnaW9uLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hcHBseUludGVyYWN0aW9ucygpO1xuICAgICAgICB0aGlzLnZpZXcub24oZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUkVOREVSLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5hZnRlclJlbmRlcigpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuYWZ0ZXJJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFmdGVySW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAoIXRoaXMudmlldyB8fCB0aGlzLnZpZXcuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wYWRkaW5nICE9PSAnYXV0bycpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VFdmVudHMoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRzXzEuVklFV19MQVlFUl9MSUZFX0NZQ0xFLkFGVEVSX0lOSVQpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXcgfHwgdGhpcy52aWV3LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgcGFkZGluZyA9IG9wdGlvbnMucGFkZGluZyA/IG9wdGlvbnMucGFkZGluZyA6IHRoaXMuY29uZmlnLnRoZW1lLnBhZGRpbmc7XG4gICAgICAgIC8qKiBkZWZhdWx0U3RhdGUgKi9cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdFN0YXRlICYmIHBhZGRpbmcgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZUNvbnRyb2xsZXIuZGVmYXVsdFN0YXRlcyhvcHRpb25zLmRlZmF1bHRTdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIGF1dG9wYWRkaW5nICovXG4gICAgICAgIGlmIChwYWRkaW5nID09PSAnYXV0bycpIHtcbiAgICAgICAgICAgIHRoaXMucGFkZGluZ0NvbnRyb2xsZXIucHJvY2Vzc0F1dG9QYWRkaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCgoX2IgPSAoX2EgPSBvcHRpb25zLnRvb2x0aXApID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jdXN0b20pID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5vbkNoYW5nZSkgJiYgb3B0aW9ucy5wYWRkaW5nICE9PSAnYXV0bycpIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tVG9vbHRpcCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog5a6M5pW055Sf5ZG95ZGo5pyf5riy5p+TICovXG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZW1pdChjb25zdGFudHNfMS5WSUVXX0xBWUVSX0xJRkVfQ1lDTEUuQkVGT1JFX1JFTkRFUik7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucmVuZGVyLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5vcHRpb25zLmRhdGE7XG4gICAgICAgIGlmICghdXRpbF8xLmlzRW1wdHkoZGF0YSkpIHtcbiAgICAgICAgICAgIHRoaXMudmlldy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRzXzEuVklFV19MQVlFUl9MSUZFX0NZQ0xFLkFGVEVSX1JFTkRFUik7XG4gICAgfTtcbiAgICAvKiog55S75biD6YeN57uYICovXG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5yZXBhaW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jYW52YXMpIHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5nZXRTY2FsZUJ5RmllbGQgPSBmdW5jdGlvbiAoZmllbGQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoZmllbGQpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5nZXRYU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4RmllbGQgPSB0aGlzLm9wdGlvbnMueEZpZWxkO1xuICAgICAgICBpZiAoeEZpZWxkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZCh4RmllbGQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmdldFlTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHlGaWVsZCA9IHRoaXMub3B0aW9ucy55RmllbGQ7XG4gICAgICAgIGlmICh5RmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKHlGaWVsZCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZ2V0Q29sb3JTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmICh1dGlsXzEuY29udGFpbnMob3B0aW9ucywgJ2NvbG9yRmllbGQnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQob3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZ2V0U2hhcGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ2VvbWV0cmllcyA9IHRoaXMudmlldy5nZW9tZXRyaWVzO1xuICAgICAgICB2YXIgc2hhcGVzID0ge307XG4gICAgICAgIC8vIHRvZG86IGdlb21ldHJ5IOexu+Wei+i9rOivkVxuICAgICAgICB1dGlsXzEuZWFjaChnZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbSkge1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBnZW9tLnR5cGU7XG4gICAgICAgICAgICBzaGFwZXNbdHlwZV0gPSBnZW9tLmdldFNoYXBlcygpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHNoYXBlcztcbiAgICB9O1xuICAgIC8qKiDplIDmr4EgKi9cbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZG9EZXN0cm95KCk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgLyoqIOabtOaWsOmFjee9rumhuSAqL1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUudXBkYXRlQ29uZmlnID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB0aGlzLmRvRGVzdHJveSgpO1xuICAgICAgICBpZiAoIWNmZy5wYWRkaW5nICYmIHRoaXMuaW5pdGlhbE9wdGlvbnMucGFkZGluZyAmJiB0aGlzLmluaXRpYWxPcHRpb25zLnBhZGRpbmcgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgY2ZnLnBhZGRpbmcgPSAnYXV0byc7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zID0gdGhpcy5nZXRPcHRpb25zKGNmZyk7XG4gICAgICAgIHRoaXMucHJvY2Vzc09wdGlvbnModGhpcy5vcHRpb25zKTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuY2hhbmdlRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHRoaXMuZW1pdChjb25zdGFudHNfMS5WSUVXX0xBWUVSX0xJRkVfQ1lDTEUuQkVGT1JFX0NIQU5HRV9EQVRBKTtcbiAgICAgICAgdmFyIGlzRW1wdHlCZWZvcmUgPSB1dGlsXzEuaXNFbXB0eSh0aGlzLm9wdGlvbnMuZGF0YSk7XG4gICAgICAgIHRoaXMub3B0aW9ucy5kYXRhID0gdGhpcy5wcm9jZXNzRGF0YShkYXRhKTtcbiAgICAgICAgLy8g5aaC5p6c5LmL5YmN5rKh5pyJIGRhdGFcbiAgICAgICAgaWYgKGlzRW1wdHlCZWZvcmUpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5wYWRkaW5nID0gdGhpcy5pbml0aWFsT3B0aW9ucy5wYWRkaW5nIHx8ICdhdXRvJztcbiAgICAgICAgICAgIHRoaXMudmlldy5kYXRhKHRoaXMub3B0aW9ucy5kYXRhKTtcbiAgICAgICAgICAgIHRoaXMudmlldy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlldy5jaGFuZ2VEYXRhKHRoaXMub3B0aW9ucy5kYXRhKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoY29uc3RhbnRzXzEuVklFV19MQVlFUl9MSUZFX0NZQ0xFLkFGVEVSX0NIQU5HRV9EQVRBKTtcbiAgICB9O1xuICAgIC8vIHBsb3Qg5LiN5pat6ZSA5q+B6YeN5bu677yM6ZyA6KaB5LiA5LiqYXBp6I635Y+W5pyA5paw55qEcGxvdFxuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZ2V0UGxvdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOiOt+WPluW3sua4suafk+eahOaVsOaNruagh+etvue7hOS7tlxuICAgICAqL1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZ2V0TGFiZWxzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sYWJlbHM7XG4gICAgfTtcbiAgICAvLyDojrflj5blr7nlupTnmoRHMiBUaGVtZVxuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZ2V0VGhlbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy50aGVtZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGhlbWVDb250cm9sbGVyLmdldFRoZW1lKHRoaXMub3B0aW9ucywgdGhpcy50eXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50aGVtZTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZ2V0UmVzcG9uc2l2ZVRoZW1lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50aGVtZUNvbnRyb2xsZXIuZ2V0UmVzcG9uc2l2ZVRoZW1lKHRoaXMudHlwZSk7XG4gICAgfTtcbiAgICAvLyDojrflj5blr7nlupTnmoRQbG90IFRoZW1lXG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5nZXRQbG90VGhlbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRoZW1lQ29udHJvbGxlci5nZXRQbG90VGhlbWUodGhpcy5vcHRpb25zLCB0aGlzLnR5cGUpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5nZXRJbnRlcmFjdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmludGVyYWN0aW9ucztcbiAgICB9O1xuICAgIC8vIOe7keWumuS4gOS4quWklumDqOeahHN0YXRlTWFuYWdlclxuICAgIFZpZXdMYXllci5wcm90b3R5cGUuYmluZFN0YXRlTWFuYWdlciA9IGZ1bmN0aW9uIChzdGF0ZU1hbmFnZXIsIGNmZykge1xuICAgICAgICB0aGlzLnN0YXRlQ29udHJvbGxlci5iaW5kU3RhdGVNYW5hZ2VyKHN0YXRlTWFuYWdlciwgY2ZnKTtcbiAgICB9O1xuICAgIC8vIOWTjeW6lOeKtuaAgemHj+abtOaWsOeahOW/q+aNt+aWueazlVxuICAgIFZpZXdMYXllci5wcm90b3R5cGUuc2V0QWN0aXZlID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgc3R5bGUpIHtcbiAgICAgICAgdGhpcy5zdGF0ZUNvbnRyb2xsZXIuc2V0U3RhdGUoeyB0eXBlOiAnYWN0aXZlJywgY29uZGl0aW9uOiBjb25kaXRpb24sIHN0eWxlOiBzdHlsZSB9KTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuc2V0U2VsZWN0ZWQgPSBmdW5jdGlvbiAoY29uZGl0aW9uLCBzdHlsZSkge1xuICAgICAgICB0aGlzLnN0YXRlQ29udHJvbGxlci5zZXRTdGF0ZSh7IHR5cGU6ICdzZWxlY3RlZCcsIGNvbmRpdGlvbjogY29uZGl0aW9uLCBzdHlsZTogc3R5bGUgfSk7XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLnNldERpc2FibGUgPSBmdW5jdGlvbiAoY29uZGl0aW9uLCBzdHlsZSkge1xuICAgICAgICB0aGlzLnN0YXRlQ29udHJvbGxlci5zZXRTdGF0ZSh7IHR5cGU6ICdkaXNhYmxlJywgY29uZGl0aW9uOiBjb25kaXRpb24sIHN0eWxlOiBzdHlsZSB9KTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuc2V0RGVmYXVsdCA9IGZ1bmN0aW9uIChjb25kaXRpb24sIHN0eWxlKSB7XG4gICAgICAgIHRoaXMuc3RhdGVDb250cm9sbGVyLnNldFN0YXRlKHsgdHlwZTogJ2RlZmF1bHQnLCBjb25kaXRpb246IGNvbmRpdGlvbiwgc3R5bGU6IHN0eWxlIH0pO1xuICAgIH07XG4gICAgLy8g6I635Y+WIFZpZXdMYXllciDnmoTmlbDmja7poblcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmdldERhdGEgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzRGF0YSgodGhpcy5vcHRpb25zLmRhdGEgfHwgW10pLnNsaWNlKHN0YXJ0LCBlbmQpKTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUucHJvY2Vzc0RhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8qKiBzY2FsZSBtZXRh6YWN572uICovXG4gICAgICAgIC8vIDEuIHRoaXMuY29uZmlnLnNjYWxlc+S4reW3suacieWtkOWbvuW9ouWcqOWkhOeQhnhBeGlzL3lBeGlz5piv5YaZ5YWl55qEeEZpZWxkL3lGaWVsZOWvueW6lOeahHNjYWxl5L+h5oGv77yM6L+Z6YeM5YaN5qOA5p+l55So5oi36K6+572u55qEbWV0Ye+8jOWwhm1ldGHkv6Hmga/lkIjlubbliLDpu5jorqTnmoRzY2FsZeS4rVxuICAgICAgICAvLyAyLiDlkIzml7Z4QXhpcy95QXhpc+S4reeahHR5cGXkvJjlhYjnuqfmm7Tpq5jvvIzopobnm5ZtZXRh5Lit55qEdHlwZemFjee9rlxuICAgICAgICB2YXIgc2NhbGVUeXBlcyA9IHV0aWxfMS5tYXBWYWx1ZXModGhpcy5jb25maWcuc2NhbGVzLCBmdW5jdGlvbiAoc2NhbGVDb25maWcpIHtcbiAgICAgICAgICAgIHZhciB0eXBlID0gc2NhbGVDb25maWcudHlwZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlID8geyB0eXBlOiB0eXBlIH0gOiB7fTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBzY2FsZXMgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5jb25maWcuc2NhbGVzLCB0aGlzLm9wdGlvbnMubWV0YSB8fCB7fSwgc2NhbGVUeXBlcyk7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5heGlzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeEF4aXNfcGFyc2VyID0gZmFjdG9yeV8xLmdldENvbXBvbmVudCgnYXhpcycsIHtcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICBkaW06ICd4JyxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB5QXhpc19wYXJzZXIgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdheGlzJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgICAgIGRpbTogJ3knLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGF4ZXNDb25maWcgPSB7fTtcbiAgICAgICAgYXhlc0NvbmZpZ1t0aGlzLm9wdGlvbnMueEZpZWxkXSA9IHhBeGlzX3BhcnNlcjtcbiAgICAgICAgYXhlc0NvbmZpZ1t0aGlzLm9wdGlvbnMueUZpZWxkXSA9IHlBeGlzX3BhcnNlcjtcbiAgICAgICAgLyoqIOWtmOWCqOWdkOagh+i9tOmFjee9rumhueWIsGNvbmZpZyAqL1xuICAgICAgICB0aGlzLnNldENvbmZpZygnYXhlcycsIGF4ZXNDb25maWcpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS50b29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnRvb2x0aXAudmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29uZmlnKCd0b29sdGlwJywgZmFsc2UpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHV0aWxfMS5nZXQodGhpcy5vcHRpb25zLCAndG9vbHRpcCcpO1xuICAgICAgICBpZiAoKF9hID0gdG9vbHRpcE9wdGlvbnMuY3VzdG9tKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0b29sdGlwT3B0aW9ucy5jb250YWluZXIgPSB0b29sdGlwT3B0aW9ucy5jdXN0b20uY29udGFpbmVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX2IgPSB0b29sdGlwT3B0aW9ucy5jdXN0b20pID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jdXN0b21Db250ZW50KSB7XG4gICAgICAgICAgICB0b29sdGlwT3B0aW9ucy5jdXN0b21Db250ZW50ID0gdG9vbHRpcE9wdGlvbnMuY3VzdG9tLmN1c3RvbUNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ3Rvb2x0aXAnLCB1dGlsXzEuZGVlcE1peCh7fSwgdG9vbHRpcE9wdGlvbnMpKTtcbiAgICAgICAgdXRpbF8xLmRlZXBNaXgodGhpcy5jb25maWcudGhlbWUudG9vbHRpcCwgdGhpcy5vcHRpb25zLnRvb2x0aXAuZG9tU3R5bGVzKTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuY3JlYXRlVG9vbHRpcENvbnRhaW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBjb250YWluZXIuY2xhc3NOYW1lID0gJ2cyLXRvb2x0aXAnO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5jdXN0b21Ub29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3VzdG9tQ29udGVudENmZyA9IHRoaXMub3B0aW9ucy50b29sdGlwLmN1c3RvbTtcbiAgICAgICAgdmFyIGNvbnRhaW5lcjtcbiAgICAgICAgaWYgKGN1c3RvbUNvbnRlbnRDZmcuY29udGFpbmVyKSB7XG4gICAgICAgICAgICBjb250YWluZXIgPSB1dGlsXzEuaXNTdHJpbmcoY3VzdG9tQ29udGVudENmZy5jb250YWluZXIpXG4gICAgICAgICAgICAgICAgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjdXN0b21Db250ZW50Q2ZnLmNvbnRhaW5lcilcbiAgICAgICAgICAgICAgICA6IGN1c3RvbUNvbnRlbnRDZmcuY29udGFpbmVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICAgICAgICBjb250YWluZXIgPSB0aGlzLmNyZWF0ZVRvb2x0aXBDb250YWluZXIoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXcub24oJ3Rvb2x0aXA6c2hvdycsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgaWYgKGN1c3RvbUNvbnRlbnRDZmcgPT09IG51bGwgfHwgY3VzdG9tQ29udGVudENmZyA9PT0gdm9pZCAwID8gdm9pZCAwIDogY3VzdG9tQ29udGVudENmZy5vbkNoYW5nZSkge1xuICAgICAgICAgICAgICAgIGN1c3RvbUNvbnRlbnRDZmcub25DaGFuZ2UoY29udGFpbmVyLCBldik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpZXcuaGlkZVRvb2x0aXAoKTtcbiAgICAgICAgdGhpcy52aWV3Lm9uKCd0b29sdGlwOmNoYW5nZScsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgY3VzdG9tQ29udGVudENmZy5vbkNoYW5nZShjb250YWluZXIsIGV2KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmdldExlZ2VuZFBvc2l0aW9uID0gZnVuY3Rpb24gKHBvc2l0aW9uKSB7XG4gICAgICAgIHZhciBwb3NpdGlvbkxpc3QgPSBwb3NpdGlvbi5zcGxpdCgnLScpO1xuICAgICAgICAvLyBHMiA0LjAg5YW85a65IFhYWC1jZW50ZXIg5YiwIFhYWCDnmoTlnLrmma9cbiAgICAgICAgaWYgKHBvc2l0aW9uTGlzdCAmJiBwb3NpdGlvbkxpc3QubGVuZ3RoID4gMSAmJiBwb3NpdGlvbkxpc3RbMV0gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gcG9zaXRpb25MaXN0WzBdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3NpdGlvbjtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUubGVnZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGVnZW5kLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLnNldENvbmZpZygnbGVnZW5kcycsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLnRoZW1lLmxlZ2VuZCwgdGhpcy5vcHRpb25zLmxlZ2VuZCk7XG4gICAgICAgIHZhciBsZWdlbmRDb25maWcgPSB7XG4gICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5nZXRMZWdlbmRQb3NpdGlvbih1dGlsXzEuZ2V0KG9wdGlvbnMsICdwb3NpdGlvbicpKSxcbiAgICAgICAgICAgIG9mZnNldFg6IHV0aWxfMS5nZXQob3B0aW9ucywgJ29mZnNldFgnKSxcbiAgICAgICAgICAgIG9mZnNldFk6IHV0aWxfMS5nZXQob3B0aW9ucywgJ29mZnNldFknKSxcbiAgICAgICAgICAgIGZsaXBQYWdlOiB1dGlsXzEuZ2V0KG9wdGlvbnMsICdmbGlwUGFnZScpLFxuICAgICAgICAgICAgbWFya2VyOiB1dGlsXzEuZ2V0KG9wdGlvbnMsICdtYXJrZXInKSxcbiAgICAgICAgICAgIHRpdGxlOiAoKF9hID0gb3B0aW9ucy50aXRsZSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLnZpc2libGUpID8gdXRpbF8xLmdldChvcHRpb25zLCAndGl0bGUnKSA6IG51bGwsXG4gICAgICAgICAgICBpdGVtTmFtZTogdXRpbF8xLmdldChvcHRpb25zLCAndGV4dCcpLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldENvbmZpZygnbGVnZW5kcycsIGxlZ2VuZENvbmZpZyk7XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmFubm90YXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBjb25maWcgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmNvb3JkaW5hdGUudHlwZSA9PT0gJ2NhcnRlc2lhbicgJiYgdGhpcy5vcHRpb25zLmd1aWRlTGluZSkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2godGhpcy5vcHRpb25zLmd1aWRlTGluZSwgZnVuY3Rpb24gKGxpbmUpIHtcbiAgICAgICAgICAgICAgICB2YXIgZ3VpZGVMaW5lID0gZmFjdG9yeV8xLmdldENvbXBvbmVudCgnZ3VpZGVMaW5lJywge1xuICAgICAgICAgICAgICAgICAgICBwbG90OiBfdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgY2ZnOiBsaW5lLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbmZpZy5wdXNoKGd1aWRlTGluZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnYW5ub3RhdGlvbnMnLCBjb25maWcpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5pbnRlcmFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLmludGVyYWN0aW9ucywgaW50ZXJhY3Rpb25zID0gX2EgPT09IHZvaWQgMCA/IFtdIDogX2E7XG4gICAgICAgIHV0aWxfMS5lYWNoKGludGVyYWN0aW9ucywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGludGVyYWN0aW9uLnR5cGU7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3NsaWRlcicgfHwgdHlwZSA9PT0gJ3Njcm9sbGJhcicpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXhpc0NvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfdGhpcy5vcHRpb25zLnhBeGlzID0gdXRpbF8xLmRlZXBNaXgoe30sIF90aGlzLm9wdGlvbnMueEF4aXMsIGF4aXNDb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMuc2V0Q29uZmlnKCdpbnRlcmFjdGlvbicsIGludGVyYWN0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hbmltYXRpb24gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLnNldENvbmZpZygnYW5pbWF0ZScsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5hcHBseUludGVyYWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHJhbmdlID0gYmJveF8xLmRlZmF1bHQuZnJvbUJCb3hPYmplY3QodGhpcy5sYXllckJCb3gpO1xuICAgICAgICAvLyDkuLTml7bljrvmjokgdGl0bGUvZGVzY3JpcHRpb24g55qE5Y2g55SoXG4gICAgICAgIHZhciB0aXRsZU9yRGVzYyA9IHRoaXMudGl0bGUgfHwgdGhpcy5kZXNjcmlwdGlvbjtcbiAgICAgICAgdmFyIGV4dHJhQkJveCA9IG5ldyBiYm94XzEuZGVmYXVsdChyYW5nZS5taW5YLCByYW5nZS5taW5ZLCByYW5nZS53aWR0aCwgdGl0bGVPckRlc2MgPyB0aXRsZU9yRGVzYy5nZXRCQm94KCkubWF4WSA6IDApO1xuICAgICAgICByYW5nZSA9IHJhbmdlLmN1dChleHRyYUJCb3gsIGJib3hfMS5ESVJFQ1RJT04uVE9QKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLmludGVyYWN0aW9ucywgaW50ZXJhY3Rpb25zID0gX2EgPT09IHZvaWQgMCA/IFtdIDogX2E7XG4gICAgICAgIGlmICh0aGlzLmludGVyYWN0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoaW5zdCkge1xuICAgICAgICAgICAgICAgIGluc3QuZGVzdHJveSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnMgPSBbXTtcbiAgICAgICAgaW50ZXJhY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICB2YXIgQ3RvciA9IGluZGV4XzEuZGVmYXVsdC5nZXRJbnRlcmFjdGlvbihpbnRlcmFjdGlvbi50eXBlLCBfdGhpcy50eXBlKTtcbiAgICAgICAgICAgIGlmIChDdG9yKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluc3QgPSBuZXcgQ3Rvcih7IHZpZXc6IF90aGlzLnZpZXcgfSwgX3RoaXMsIEN0b3IuZ2V0SW50ZXJhY3Rpb25SYW5nZShyYW5nZSwgaW50ZXJhY3Rpb24uY2ZnKSwgaW50ZXJhY3Rpb24uY2ZnKTtcbiAgICAgICAgICAgICAgICBpbnN0LnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIF90aGlzLmludGVyYWN0aW9ucy5wdXNoKGluc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDorr7nva5HMiBjb25maWfvvIzluKbmnInnsbvlnovmjqjlr7wgKi9cbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLnNldENvbmZpZyA9IGZ1bmN0aW9uIChrZXksIGNvbmZpZykge1xuICAgICAgICBpZiAoa2V5ID09PSAnZ2VvbWV0cnknKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5nZW9tZXRyaWVzLnB1c2goY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoa2V5ID09PSAnaW50ZXJhY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5pbnRlcmFjdGlvbnMucHVzaChjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ1trZXldID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLmNvbmZpZ1trZXldLCBjb25maWcpO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uIChldmVudFBhcnNlcikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKG9wdGlvbnMuZXZlbnRzKSB7XG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgb3B0aW9ucy5ldmVudHMpO1xuICAgICAgICAgICAgdmFyIGV2ZW50bWFwXzEgPSBldmVudFBhcnNlciA/IGV2ZW50UGFyc2VyLkVWRU5UX01BUCA6IGV2ZW50XzEuRVZFTlRfTUFQO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gob3B0aW9ucy5ldmVudHMsIGZ1bmN0aW9uIChlLCBrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWUgPSBldmVudG1hcF8xW2tdIHx8IGs7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVyID0gZTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRfMS5vbkV2ZW50KF90aGlzLCBldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmRyYXdUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmxheWVyQkJveDtcbiAgICAgICAgaWYgKHRoaXMudGl0bGUpIHtcbiAgICAgICAgICAgIHRoaXMudGl0bGUuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy50aXRsZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbW1vbl8xLmlzVGV4dFVzYWJsZShwcm9wcy50aXRsZSkpIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLmNvbmZpZy50aGVtZTtcbiAgICAgICAgICAgIHZhciB0aXRsZSA9IG5ldyBkZXNjcmlwdGlvbl8xLmRlZmF1bHQoe1xuICAgICAgICAgICAgICAgIGxlZnRNYXJnaW46IHJhbmdlLm1pblggKyB0aGVtZS50aXRsZS5wYWRkaW5nWzNdLFxuICAgICAgICAgICAgICAgIHJpZ2h0TWFyZ2luOiByYW5nZS5tYXhYIC0gdGhlbWUudGl0bGUucGFkZGluZ1sxXSxcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW46IHJhbmdlLm1pblkgKyB0aGVtZS50aXRsZS5wYWRkaW5nWzBdLFxuICAgICAgICAgICAgICAgIHRleHQ6IHByb3BzLnRpdGxlLnRleHQsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHV0aWxfMS5taXgodGhlbWUudGl0bGUsIHByb3BzLnRpdGxlLnN0eWxlKSxcbiAgICAgICAgICAgICAgICB3cmFwcGVyV2lkdGg6IHdpZHRoIC0gdGhlbWUudGl0bGUucGFkZGluZ1szXSAtIHRoZW1lLnRpdGxlLnBhZGRpbmdbMV0sXG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiB0aGlzLmNvbnRhaW5lci5hZGRHcm91cCgpLFxuICAgICAgICAgICAgICAgIHRoZW1lOiB0aGVtZSxcbiAgICAgICAgICAgICAgICBpbmRleDogY29tbW9uXzEuaXNUZXh0VXNhYmxlKHByb3BzLmRlc2NyaXB0aW9uKSA/IDAgOiAxLFxuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICAgICAgYWxpZ25UbzogcHJvcHMudGl0bGUuYWxpZ25UbyxcbiAgICAgICAgICAgICAgICBuYW1lOiAndGl0bGUnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnRpdGxlID0gdGl0bGU7XG4gICAgICAgICAgICB0aGlzLnBhZGRpbmdDb250cm9sbGVyLnJlZ2lzdGVyUGFkZGluZyh0aXRsZSwgJ291dGVyJyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZHJhd0Rlc2NyaXB0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciByYW5nZSA9IHRoaXMubGF5ZXJCQm94O1xuICAgICAgICBpZiAodGhpcy5kZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhpcy5kZXNjcmlwdGlvbi5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tbW9uXzEuaXNUZXh0VXNhYmxlKHByb3BzLmRlc2NyaXB0aW9uKSkge1xuICAgICAgICAgICAgdmFyIHdpZHRoID0gdGhpcy53aWR0aDtcbiAgICAgICAgICAgIHZhciB0aGVtZSA9IHRoaXMuY29uZmlnLnRoZW1lO1xuICAgICAgICAgICAgdmFyIHRvcE1hcmdpbiA9IDA7XG4gICAgICAgICAgICBpZiAodGhpcy50aXRsZSkge1xuICAgICAgICAgICAgICAgIHZhciB0aXRsZUJCb3ggPSB0aGlzLnRpdGxlLmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW4gKz0gdGl0bGVCQm94Lm1pblkgKyB0aXRsZUJCb3guaGVpZ2h0O1xuICAgICAgICAgICAgICAgIHRvcE1hcmdpbiArPSB0aGVtZS5kZXNjcmlwdGlvbi5wYWRkaW5nWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5pegdGl0bGXnmoTmg4XlhrXkuIvkvb/nlKh0aXRsZeeahOS4inBhZGRpbmdcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW4gKz0gcmFuZ2UubWluWSArIHRoZW1lLnRpdGxlLnBhZGRpbmdbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGVzY3JpcHRpb24gPSBuZXcgZGVzY3JpcHRpb25fMS5kZWZhdWx0KHtcbiAgICAgICAgICAgICAgICBsZWZ0TWFyZ2luOiByYW5nZS5taW5YICsgdGhlbWUuZGVzY3JpcHRpb24ucGFkZGluZ1szXSxcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW46IHRvcE1hcmdpbixcbiAgICAgICAgICAgICAgICByaWdodE1hcmdpbjogcmFuZ2UubWF4WCAtIHRoZW1lLnRpdGxlLnBhZGRpbmdbMV0sXG4gICAgICAgICAgICAgICAgdGV4dDogcHJvcHMuZGVzY3JpcHRpb24udGV4dCxcbiAgICAgICAgICAgICAgICBzdHlsZTogdXRpbF8xLm1peCh0aGVtZS5kZXNjcmlwdGlvbiwgcHJvcHMuZGVzY3JpcHRpb24uc3R5bGUpLFxuICAgICAgICAgICAgICAgIHdyYXBwZXJXaWR0aDogd2lkdGggLSB0aGVtZS5kZXNjcmlwdGlvbi5wYWRkaW5nWzNdIC0gdGhlbWUuZGVzY3JpcHRpb24ucGFkZGluZ1sxXSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLmFkZEdyb3VwKCksXG4gICAgICAgICAgICAgICAgdGhlbWU6IHRoZW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiAxLFxuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICAgICAgYWxpZ25UbzogcHJvcHMuZGVzY3JpcHRpb24uYWxpZ25UbyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnZGVzY3JpcHRpb24nLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247XG4gICAgICAgICAgICB0aGlzLnBhZGRpbmdDb250cm9sbGVyLnJlZ2lzdGVyUGFkZGluZyhkZXNjcmlwdGlvbiwgJ291dGVyJyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUuZG9SZW5kZXJMYWJlbCA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgbGFiZWwpIHtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5sYWJlbHMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBpdGVtLmRlc3Ryb3koKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubGFiZWxzID0gW107XG4gICAgICAgIHZhciBjb25maWcgPSB7XG4gICAgICAgICAgICBsYXllcjogdGhpcyxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogZ2VvbWV0cnkubGFiZWxzQ29udGFpbmVyLFxuICAgICAgICAgICAgZ2VvbWV0cnk6IGdlb21ldHJ5LFxuICAgICAgICAgICAgbGFiZWw6IGxhYmVsLFxuICAgICAgICB9O1xuICAgICAgICB2YXIgQ3RvciA9IGJhc2VfMS5nZXRMYWJlbENvbXBvbmVudChsYWJlbC50eXBlKTtcbiAgICAgICAgaWYgKEN0b3IpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbF8xID0gbmV3IEN0b3IoY29uZmlnKTtcbiAgICAgICAgICAgIGxhYmVsXzEuaW5pdCgpO1xuICAgICAgICAgICAgbGFiZWxfMS5yZW5kZXIoKTtcbiAgICAgICAgICAgIHRoaXMubGFiZWxzLnB1c2gobGFiZWxfMSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKiDmir3lj5ZkZXN0cm955ZKMdXBkYXRlQ29uZmln5YWx5pyJ5Luj56CB5Li6X2Rlc3Ryb3nmlrnms5UgKi9cbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmRvRGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5kb0Rlc3Ryb3lJbnRlcmFjdGlvbnMoKTtcbiAgICAgICAgdGhpcy5kb0Rlc3Ryb3lMYWJlbHMoKTtcbiAgICAgICAgLyoqIOmUgOavgWcyLnZpZXflrp7kvosgKi9cbiAgICAgICAgaWYgKCF0aGlzLnZpZXcuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmRvRGVzdHJveUludGVyYWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g56e76Zmk5rOo5YaM55qEIGludGVyYWN0aW9uc1xuICAgICAgICBpZiAodGhpcy5pbnRlcmFjdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKGluc3QpIHtcbiAgICAgICAgICAgICAgICBpbnN0LmRlc3Ryb3koKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW50ZXJhY3Rpb25zID0gW107XG4gICAgfTtcbiAgICBWaWV3TGF5ZXIucHJvdG90eXBlLmRvRGVzdHJveUxhYmVscyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g56e76Zmk5ZCEIGdlb21ldHJ5IOeahCBsYWJlbFxuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICBsYWJlbC5kZXN0cm95KCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxhYmVscyA9IFtdO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5nZXRWaWV3UmFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIC8vIOaciSBSYW5nZSDnmoQgSW50ZXJhY3Rpb24g5Y+C5LiOIFZpZXdNYXJnaW4g6K6h566XXG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucy5pbnRlcmFjdGlvbnMsIGludGVyYWN0aW9ucyA9IF9hID09PSB2b2lkIDAgPyBbXSA6IF9hO1xuICAgICAgICAvLyBjb25zdCBsYXllckJCb3ggPSB0aGlzLmxheWVyQkJveDtcbiAgICAgICAgdmFyIGxheWVyQkJveCA9IHRoaXMucGFkZGluZ0NvbnRyb2xsZXIucHJvY2Vzc091dGVyUGFkZGluZygpO1xuICAgICAgICBpbnRlcmFjdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgICAgIHZhciBDdG9yID0gaW5kZXhfMS5kZWZhdWx0LmdldEludGVyYWN0aW9uKGludGVyYWN0aW9uLnR5cGUsIF90aGlzLnR5cGUpO1xuICAgICAgICAgICAgdmFyIHJhbmdlID0gQ3RvciAmJiBDdG9yLmdldEludGVyYWN0aW9uUmFuZ2UobGF5ZXJCQm94LCBpbnRlcmFjdGlvbi5jZmcpO1xuICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gJyc7XG4gICAgICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgICAgICAvLyDlhYjlj6rogIPomZEgUmFuZ2Ug6Z2g6L6555qE5oOF5Ya1XG4gICAgICAgICAgICAgICAgaWYgKHJhbmdlLm1heFkgPT09IGxheWVyQkJveC5tYXhZICYmIHJhbmdlLm1pblkgPiBsYXllckJCb3gubWluWSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBtYXJnaW5bMl0gKz0gcmFuZ2UuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICdib3R0b20nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChyYW5nZS5tYXhYID09PSBsYXllckJCb3gubWF4WCAmJiByYW5nZS5taW5YID4gbGF5ZXJCQm94Lm1pblgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbWFyZ2luWzFdICs9IHJhbmdlLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICdyaWdodCc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJhbmdlLm1pblggPT09IGxheWVyQkJveC5taW5YICYmIHJhbmdlLm1heFggPiBsYXllckJCb3gubWF4WCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBtYXJnaW5bM10gKz0gcmFuZ2Uud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gJ2xlZnQnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChyYW5nZS5taW5ZID09PSBsYXllckJCb3gubWluWSAmJiByYW5nZS5tYXhZIDwgbGF5ZXJCQm94Lm1heFkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbWFyZ2luWzBdICs9IHJhbmdlLmhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSAndG9wJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgX3RoaXMucGFkZGluZ0NvbnRyb2xsZXIucmVnaXN0ZXJQYWRkaW5nKHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGludGVyYWN0aW9uLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGdldEJCb3g6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByYW5nZTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgICAgICAgICAgICAgIH0sICdvdXRlcicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHZpZXdSYW5nZSA9IHRoaXMucGFkZGluZ0NvbnRyb2xsZXIucHJvY2Vzc091dGVyUGFkZGluZygpO1xuICAgICAgICByZXR1cm4gdmlld1JhbmdlO1xuICAgIH07XG4gICAgVmlld0xheWVyLnByb3RvdHlwZS5pc0xpbWl0SW5QbG90ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeUF4aXNPcHRpb25zID0gdGhpcy5vcHRpb25zLnlBeGlzO1xuICAgICAgICBpZiAodXRpbF8xLmhhc0tleSh5QXhpc09wdGlvbnMsICdtYXgnKSB8fFxuICAgICAgICAgICAgdXRpbF8xLmhhc0tleSh5QXhpc09wdGlvbnMsICdtaW4nKSB8fFxuICAgICAgICAgICAgdXRpbF8xLmhhc0tleSh5QXhpc09wdGlvbnMsICdtYXhMaW1pdCcpIHx8XG4gICAgICAgICAgICB1dGlsXzEuaGFzS2V5KHlBeGlzT3B0aW9ucywgJ21pbkxpbWl0JykpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIFZpZXdMYXllci5wcm90b3R5cGUudmlld1JhbmdlVG9SZWdpb24gPSBmdW5jdGlvbiAodmlld1JhbmdlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIHggPSBfYS54LCB5ID0gX2EueSwgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICAgICAgICB2YXIgc3RhcnQgPSB7IHg6IDAsIHk6IDAgfSwgZW5kID0geyB4OiAxLCB5OiAxIH07XG4gICAgICAgIHN0YXJ0LnggPSB2aWV3UmFuZ2UubWluWCAvICh4ICsgd2lkdGgpO1xuICAgICAgICBzdGFydC55ID0gdmlld1JhbmdlLm1pblkgLyAoeSArIGhlaWdodCk7XG4gICAgICAgIGVuZC54ID0gdmlld1JhbmdlLm1heFggLyAoeCArIHdpZHRoKTtcbiAgICAgICAgZW5kLnkgPSB2aWV3UmFuZ2UubWF4WSAvICh5ICsgaGVpZ2h0KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogZW5kLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFZpZXdMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBWaWV3TGF5ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD12aWV3LWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCJAYW50di9zY2FsZVwiKTtcbnZhciBkZXNjcmlwdGlvbl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2NvbXBvbmVudHMvZGVzY3JpcHRpb25cIikpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi91dGlsL2Jib3hcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZS9sYXllclwiKSk7XG52YXIgY29tbW9uXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9jb21tb25cIik7XG52YXIgdGhlbWVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlL2NvbnRyb2xsZXIvdGhlbWVcIikpO1xudmFyIHRoZW1lXzIgPSByZXF1aXJlKFwiLi4vdGhlbWVcIik7XG52YXIgTEVHRU5EX01BUkdJTiA9IDU7XG52YXIgQ29tYm9WaWV3TGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ29tYm9WaWV3TGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ29tYm9WaWV3TGF5ZXIocHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgcHJvcHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmdlb21MYXllcnMgPSBbXTtcbiAgICAgICAgX3RoaXMubGVnZW5kcyA9IFtdO1xuICAgICAgICBfdGhpcy5yZXF1aXJlZEZpZWxkID0gWyd4RmllbGQnLCAneUZpZWxkJ107XG4gICAgICAgIF90aGlzLm9wdGlvbnMgPSBfdGhpcy5nZXRPcHRpb25zKHByb3BzKTtcbiAgICAgICAgX3RoaXMuaW5pdGlhbE9wdGlvbnMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBfdGhpcy50aGVtZUNvbnRyb2xsZXIgPSBuZXcgdGhlbWVfMS5kZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQ29tYm9WaWV3TGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFsaWduVG86ICdsZWZ0JyxcbiAgICAgICAgICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgICAgIGFsaWduVG86ICdsZWZ0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgY3VyT3B0aW9ucyA9IHRoaXMub3B0aW9ucyB8fCB7fTtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSBfc3VwZXIucHJvdG90eXBlLmdldE9wdGlvbnMuY2FsbCh0aGlzLCBwcm9wcyk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdmFyIGRlZmF1bHRPcHRpb25zID0gdGhpcy5jb25zdHJ1Y3Rvci5nZXREZWZhdWx0T3B0aW9ucyhwcm9wcyk7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgb3B0aW9ucywgZGVmYXVsdE9wdGlvbnMsIGN1ck9wdGlvbnMsIHByb3BzKTtcbiAgICB9O1xuICAgIENvbWJvVmlld0xheWVyLnByb3RvdHlwZS5jaGVja0RhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHZhciBfYyA9IHRoaXMub3B0aW9ucywgZGF0YSA9IF9jLmRhdGEsIHhGaWVsZCA9IF9jLnhGaWVsZCwgeUZpZWxkID0gX2MueUZpZWxkO1xuICAgICAgICAvLyDliKTmlq0xOiDmsqHmnInphY3nva7lv4XpgInlrZfmrrXml7bkuI3nu5jliLZcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJlcXVpcmVkRmllbGQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IHRoaXMucmVxdWlyZWRGaWVsZFtpXTtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmhhc0tleSh0aGlzLm9wdGlvbnMsIGZpZWxkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyDliKTmlq0yOiB5RmllbGTkuI3mmK/mlbDnu4TmiJblj6rorr7nva7kuobkuIDkuKrlrZfmrrXml7bkuI3nu5jliLZcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNBcnJheSh5RmllbGQpIHx8IHlGaWVsZC5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Yik5patMzpkYXRh5Li656m65pe25LiN57uY5Yi2IGRhdGE6W11cbiAgICAgICAgaWYgKCF1dGlsXzEuaXNBcnJheShkYXRhKSB8fCBkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWIpOaWrTQ6IOWGheW1jOS4pOWxguepuuaVsOaNruaXtuS4jee7mOWItiBkYXRhOltbXSxbXV1cbiAgICAgICAgaWYgKCgoX2EgPSBkYXRhWzBdKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubGVuZ3RoKSA9PT0gMCAmJiAoKF9iID0gZGF0YVsxXSkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmxlbmd0aCkgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyDliKTmlq0177ya5LiA5bGC5pWw5o2u5Li656m65pe277yM5Yip55So55u45YWz5pig5bCE5a2X5q616KGl6b2Q5pWw5o2uIGRhdGE6W1tdLFt7dHlwZTonYScsdmFsdWU6MTB9XVxuICAgICAgICB1dGlsXzEuZWFjaChkYXRhLCBmdW5jdGlvbiAoZCwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmlzQXJyYXkoZCkgfHwgZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB2YXIgbW9ja0RhdGEgPSBfdGhpcy5nZXRNb2NrRGF0YShpbmRleCk7XG4gICAgICAgICAgICAgICAgZGF0YVtpbmRleF0gPSBtb2NrRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOWIpOaWrTY6IOS4pOS7veaVsOaNrnhGaWVsZOaIluWAvOS4jeS4gOiHtOaXtuS4jee7mOWItlxuICAgICAgICBpZiAoIWRhdGFbMF1bMF1beEZpZWxkXSB8fCAhZGF0YVsxXVswXVt4RmllbGRdKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0LmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMudGhlbWUgPSB0aGlzLnRoZW1lQ29udHJvbGxlci5nZXRUaGVtZSh0aGlzLm9wdGlvbnMsIHRoaXMudHlwZSk7XG4gICAgICAgIHRoaXMuZHJhd1RpdGxlKCk7XG4gICAgICAgIHRoaXMuZHJhd0Rlc2NyaXB0aW9uKCk7XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUudXBkYXRlQ29uZmlnID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB0aGlzLmRvRGVzdHJveSgpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB0aGlzLmdldE9wdGlvbnMoY2ZnKTtcbiAgICAgICAgdGhpcy5wcm9jZXNzT3B0aW9ucyh0aGlzLm9wdGlvbnMpO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmNoYW5nZURhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICBpZiAoKGRhdGEgJiYgZGF0YS5sZW5ndGggPCAyKSB8fCAhdXRpbF8xLmlzQXJyYXkoZGF0YVswXSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmdlb21MYXllcnMsIGZ1bmN0aW9uIChsYXllciwgaW5kZXgpIHtcbiAgICAgICAgICAgIGxheWVyLmNoYW5nZURhdGEoZGF0YVtpbmRleF0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbWJvVmlld0xheWVyLnByb3RvdHlwZS5jaGFuZ2VEYXRhQnlJbmRleCA9IGZ1bmN0aW9uIChkYXRhLCBpbmRleCkge1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoZGF0YVswXSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZ2VvbUxheWVyID0gdGhpcy5nZW9tTGF5ZXJzW2luZGV4XTtcbiAgICAgICAgZ2VvbUxheWVyLmNoYW5nZURhdGEoZGF0YSk7XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUuZG9EZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmdlb21MYXllcnMsIGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgICAgICAgbGF5ZXIuZG9EZXN0cm95KCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdlb21MYXllcnMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5sZWdlbmRzLCBmdW5jdGlvbiAobGVnZW5kKSB7XG4gICAgICAgICAgICBsZWdlbmQuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sZWdlbmRzID0gW107XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUuY3JlYXRlTGF5ZXIgPSBmdW5jdGlvbiAoTGF5ZXJDdHIsIGRhdGEsIGNvbmZpZykge1xuICAgICAgICB2YXIgdmlld1JhbmdlID0gdGhpcy5nZXRWaWV3UmFuZ2UoKTtcbiAgICAgICAgdmFyIGxheWVyID0gbmV3IExheWVyQ3RyKHRzbGliXzEuX19hc3NpZ24oeyBjYW52YXM6IHRoaXMuY2FudmFzLCBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLCB4OiB2aWV3UmFuZ2UubWluWCwgeTogdmlld1JhbmdlLm1pblksIHdpZHRoOiB2aWV3UmFuZ2Uud2lkdGgsIGhlaWdodDogdmlld1JhbmdlLmhlaWdodCwgZGF0YTogZGF0YSB9LCBjb25maWcpKTtcbiAgICAgICAgdGhpcy5nZW9tTGF5ZXJzLnB1c2gobGF5ZXIpO1xuICAgICAgICByZXR1cm4gbGF5ZXI7XG4gICAgfTtcbiAgICAvLyDkuLTml7bkv67lpI0gdjEg5Y+M6L205Zu+5Zyo5bem5L6n5pWw5o2u5Li6MOeahOaXtuWAmeWPs+S+p3NjYWxl5aSE55CG6ZSZ6K+v55qE6Zeu6aKYXG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmdldExlZnRZQXhpc01heCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxlZnRTY2FsZURhdGEgPSB0aGlzLmdldFNjYWxlRGF0YSgwKTtcbiAgICAgICAgdmFyIHJpZ2h0U2NhbGVEYXRhID0gdGhpcy5nZXRTY2FsZURhdGEoMSk7XG4gICAgICAgIHJldHVybiBsZWZ0U2NhbGVEYXRhLm1pbiA9PSAwICYmIGxlZnRTY2FsZURhdGEubWF4ID09PSAwID8gTWF0aC5tYXgocmlnaHRTY2FsZURhdGEubWF4LCAwKSA6IGxlZnRTY2FsZURhdGEubWF4O1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLnlBeGlzID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBsZWZ0U2NhbGVEYXRhID0gdGhpcy5nZXRTY2FsZURhdGEoMCk7XG4gICAgICAgIHZhciB5QXhpcyA9IHRoaXMub3B0aW9ucy55QXhpcztcbiAgICAgICAgdmFyIGNvbmZpZyA9IGluZGV4ID09PSAwID8geUF4aXMubGVmdENvbmZpZyA6IHlBeGlzLnJpZ2h0Q29uZmlnO1xuICAgICAgICB2YXIgY29sb3JWYWx1ZSA9IHRoaXMuY29sb3JzW2luZGV4XTtcbiAgICAgICAgdmFyIHlBeGlzQ29uZmlnID0gdXRpbF8xLmNsb25lKGNvbmZpZyk7XG4gICAgICAgIHZhciBzdHlsZU1hcCA9IHtcbiAgICAgICAgICAgIHRpdGxlOiAnc3Ryb2tlJyxcbiAgICAgICAgICAgIGxpbmU6ICdzdHJva2UnLFxuICAgICAgICAgICAgbGFiZWw6ICdmaWxsJyxcbiAgICAgICAgICAgIHRpY2tMaW5lOiAnc3Ryb2tlJyxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGNvbmZpZy52aXNpYmxlICYmIGNvbmZpZy5jb2xvck1hcHBpbmcpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHlBeGlzQ29uZmlnLCBmdW5jdGlvbiAoY29uZmlnLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNTdHJpbmcoY29uZmlnKSAmJiB1dGlsXzEuaGFzS2V5KHN0eWxlTWFwLCBuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc3R5bGVLZXkgPSBzdHlsZU1hcFtuYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb25maWcuc3R5bGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5zdHlsZSA9IHt9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5zdHlsZVtzdHlsZUtleV0gPSBjb2xvclZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29uZmlnLnZpc2libGUpIHtcbiAgICAgICAgICAgIHlBeGlzQ29uZmlnLnRpdGxlLnZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHlBeGlzQ29uZmlnLnRpY2tMaW5lLnZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHlBeGlzQ29uZmlnLmxhYmVsLnZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHlBeGlzQ29uZmlnLmxpbmUudmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgeUF4aXNDb25maWcudmlzaWJsZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHlBeGlzR2xvYmFsQ29uZmlnID0gdGhpcy5nZXRZQXhpc0dsb2JhbENvbmZpZygpO1xuICAgICAgICBpZiAoaW5kZXggPT09IDAgJiYgbGVmdFNjYWxlRGF0YS5tYXggPT09IDAgJiYgbGVmdFNjYWxlRGF0YS5taW4gPT09IDApIHtcbiAgICAgICAgICAgIHlBeGlzQ29uZmlnLm1heCA9IHRoaXMuZ2V0TGVmdFlBeGlzTWF4KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCB5QXhpc0dsb2JhbENvbmZpZywgeUF4aXNDb25maWcpO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmdldFRpY2tzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeUF4aXMgPSB0aGlzLm9wdGlvbnMueUF4aXM7XG4gICAgICAgIHZhciBsZWZ0U2NhbGVEYXRhID0gdGhpcy5nZXRTY2FsZURhdGEoMCk7XG4gICAgICAgIC8vIOWPluWIsOW3pui9tHRpY2tz5pWw6YePXG4gICAgICAgIHZhciBTY2FsZSA9IHNjYWxlXzEuZ2V0U2NhbGUoJ2xpbmVhcicpO1xuICAgICAgICB2YXIgbGluZWFyU2NhbGUgPSBuZXcgU2NhbGUodXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogdGhpcy5nZXRMZWZ0WUF4aXNNYXgoKSxcbiAgICAgICAgICAgIG5pY2U6IHRydWUsXG4gICAgICAgICAgICB2YWx1ZXM6IGxlZnRTY2FsZURhdGEudmFsdWVzLFxuICAgICAgICB9LCB7XG4gICAgICAgICAgICB0aWNrQ291bnQ6IHlBeGlzLnRpY2tDb3VudCxcbiAgICAgICAgfSkpO1xuICAgICAgICB2YXIgdGlja0NvdW50ID0gbGluZWFyU2NhbGUudGlja3MubGVuZ3RoO1xuICAgICAgICAvLyDnlJ/miJDlj7PovbR0aWNrc1xuICAgICAgICB2YXIgbWF4ID0geUF4aXMubWF4ID8gbGluZWFyU2NhbGUubWF4IDogdGhpcy5nZXRTY2FsZURhdGEoMSkubWF4O1xuICAgICAgICB2YXIgdGlja0ludGVydmFsID0gbWF4IC8gKHRpY2tDb3VudCAtIDEpO1xuICAgICAgICB2YXIgdGlja3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aWNrQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgdmFyIHRpY2tWYWx1ZSA9IGkgKiB0aWNrSW50ZXJ2YWw7XG4gICAgICAgICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodGlja1ZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRpY2tWYWx1ZSA9IHBhcnNlRmxvYXQodGlja1ZhbHVlLnRvRml4ZWQoMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGlja3MucHVzaCh0aWNrVmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aWNrcztcbiAgICB9O1xuICAgIENvbWJvVmlld0xheWVyLnByb3RvdHlwZS5nZXRTY2FsZURhdGEgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBkYXRhID0gX2EuZGF0YSwgeUZpZWxkID0gX2EueUZpZWxkLCB5QXhpcyA9IF9hLnlBeGlzO1xuICAgICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKGRhdGFbaW5kZXhdLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZFt5RmllbGRbaW5kZXhdXSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YWx1ZXMuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSAtIGI7IH0pO1xuICAgICAgICB2YXIgbWluID0gdmFsdWVzWzBdO1xuICAgICAgICB2YXIgbWF4ID0geUF4aXMubWF4ID8geUF4aXMubWF4IDogdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIHsgbWluOiBtaW4sIG1heDogbWF4LCB2YWx1ZXM6IHZhbHVlcyB9O1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmdldERhdGFCeVhGaWVsZCA9IGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBkYXRhID0gX2EuZGF0YSwgeEZpZWxkID0gX2EueEZpZWxkO1xuICAgICAgICB2YXIgZGF0YVNvdXJjZSA9IGRhdGFbaW5kZXhdO1xuICAgICAgICByZXR1cm4gZGF0YVNvdXJjZS5maWx0ZXIoZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHJldHVybiBkW3hGaWVsZF0gPT09IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbWJvVmlld0xheWVyLnByb3RvdHlwZS5nZXRZQXhpc0dsb2JhbENvbmZpZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLnlBeGlzLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heCwgdGlja0NvdW50ID0gX2EudGlja0NvdW50O1xuICAgICAgICByZXR1cm4geyBtaW46IG1pbiwgbWF4OiBtYXgsIHRpY2tDb3VudDogdGlja0NvdW50IH07XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUuYWRqdXN0TGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICB2YXIgYmxlZWRpbmcgPSB0aGVtZV8yLmdldEdsb2JhbFRoZW1lKCkuYmxlZWRpbmc7XG4gICAgICAgIGlmICh1dGlsXzEuaXNBcnJheShibGVlZGluZykpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGJsZWVkaW5nLCBmdW5jdGlvbiAoaXQsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBibGVlZGluZ1tpbmRleF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgYmxlZWRpbmdbaW5kZXhdID0gYmxlZWRpbmdbaW5kZXhdKF90aGlzLm9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2aWV3UmFuZ2UgPSB0aGlzLmdldFZpZXdSYW5nZSgpO1xuICAgICAgICB2YXIgbGVmdFBhZGRpbmcgPSB0aGlzLnRyYW5zZnJvbVBhZGRpbmcodGhpcy5nZW9tTGF5ZXJzWzBdLm9wdGlvbnMucGFkZGluZyk7XG4gICAgICAgIHZhciByaWdodFBhZGRpbmcgPSB0aGlzLnRyYW5zZnJvbVBhZGRpbmcodGhpcy5nZW9tTGF5ZXJzWzFdLm9wdGlvbnMucGFkZGluZyk7XG4gICAgICAgIC8vIOiOt+WPlmxlZ2VuZEhlaWdodOW5tuWKoOWFpeS4iumDqHBhZGRpbmdcbiAgICAgICAgdmFyIGxlZ2VuZEhlaWdodCA9IDA7XG4gICAgICAgIHZhciBsZWdlbmRBQkJveDtcbiAgICAgICAgdmFyIGxlZ2VuZEJCQm94O1xuICAgICAgICBpZiAoKF9hID0gdGhpcy5vcHRpb25zLmxlZ2VuZCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLnZpc2libGUpIHtcbiAgICAgICAgICAgIGxlZ2VuZEFCQm94ID0gdGhpcy5sZWdlbmRzWzBdLmdldExheW91dEJCb3goKTtcbiAgICAgICAgICAgIGxlZ2VuZEJCQm94ID0gdGhpcy5sZWdlbmRzWzFdLmdldExheW91dEJCb3goKTtcbiAgICAgICAgICAgIGxlZ2VuZEhlaWdodCA9IGxlZ2VuZEFCQm94LmhlaWdodCArIExFR0VORF9NQVJHSU4gKiAyO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWQjOatpeW3puWPs3BhZGRpbmdcbiAgICAgICAgLy8gY29uc3QgdW5pcXVlUGFkZGluZyA9IFtsZWZ0UGFkZGluZ1swXSArIGxlZ2VuZEhlaWdodCwgcmlnaHRQYWRkaW5nWzFdLCByaWdodFBhZGRpbmdbMl0sIGxlZnRQYWRkaW5nWzNdXTtcbiAgICAgICAgdmFyIHVuaXF1ZVBhZGRpbmcgPSBsZWZ0UGFkZGluZy5tYXAoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICAvLyDlhbzlrrnogIHniYjmnKxcbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLm1heC5hcHBseShudWxsLCBbaXRlbSArIGxlZ2VuZEhlaWdodCwgcmlnaHRQYWRkaW5nW2luZGV4XV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4LmFwcGx5KG51bGwsIFtpdGVtLCByaWdodFBhZGRpbmdbaW5kZXhdXSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdlb21MYXllcnNbMF0udXBkYXRlQ29uZmlnKHtcbiAgICAgICAgICAgIHBhZGRpbmc6IHVuaXF1ZVBhZGRpbmcsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdlb21MYXllcnNbMF0ucmVuZGVyKCk7XG4gICAgICAgIHRoaXMuZ2VvbUxheWVyc1sxXS51cGRhdGVDb25maWcoe1xuICAgICAgICAgICAgcGFkZGluZzogdW5pcXVlUGFkZGluZyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2VvbUxheWVyc1sxXS5yZW5kZXIoKTtcbiAgICAgICAgLy8g5pu05pawbGVnZW5k55qE5L2N572uXG4gICAgICAgIGlmICgoX2IgPSB0aGlzLm9wdGlvbnMubGVnZW5kKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5sZWdlbmRzWzBdLnNldExvY2F0aW9uKHtcbiAgICAgICAgICAgICAgICB4OiBibGVlZGluZ1szXSxcbiAgICAgICAgICAgICAgICB5OiB2aWV3UmFuZ2UubWluWSArIExFR0VORF9NQVJHSU4sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubGVnZW5kc1sxXS5zZXRMb2NhdGlvbih7XG4gICAgICAgICAgICAgICAgeDogdmlld1JhbmdlLm1heFggLSBibGVlZGluZ1sxXSAtIGxlZ2VuZEJCQm94LndpZHRoLFxuICAgICAgICAgICAgICAgIHk6IHZpZXdSYW5nZS5taW5ZICsgTEVHRU5EX01BUkdJTixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBwYWRkaW5nIOmihOWkhOeQhlxuICAgICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyIHwgbnVtYmVyW119IHBhZGRpbmdcbiAgICAgKi9cbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUudHJhbnNmcm9tUGFkZGluZyA9IGZ1bmN0aW9uIChwYWRkaW5nKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFkZGluZyA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHBhZGRpbmcgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gW051bWJlcihwYWRkaW5nKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhZGRpbmc7XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUubGVnZW5kRmlsdGVyID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBsZWdlbmQgPSB0aGlzLmxlZ2VuZHNbaW5kZXhdO1xuICAgICAgICB2YXIgbGVnZW5kX2dyb3VwID0gbGVnZW5kLmdldCgnZ3JvdXAnKTtcbiAgICAgICAgbGVnZW5kX2dyb3VwLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gbGVnZW5kLmdldCgnaXRlbXMnKVswXTtcbiAgICAgICAgICAgIGlmICghaXRlbS51bmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICBsZWdlbmQuc2V0SXRlbVN0YXRlKGl0ZW0sICd1bmNoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5oaWRlTGF5ZXIoaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGVnZW5kLnNldEl0ZW1TdGF0ZShpdGVtLCAndW5jaGVja2VkJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgIF90aGlzLnNob3dMYXllcihpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmhpZGVMYXllciA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmdlb21MYXllcnNbaW5kZXhdO1xuICAgICAgICB2YXIgZmllbGQgPSB0aGlzLm9wdGlvbnMueUZpZWxkW2luZGV4XTtcbiAgICAgICAgLy8g6ZqQ6JePbGF5ZXLml7blj6rpmpDol495QXhpc+WSjGdlb21ldHJ5XG4gICAgICAgIHZhciB2aWV3ID0gbGF5ZXIudmlldztcbiAgICAgICAgdmFyIGF4aXNDb250YWluZXIgPSB0aGlzLmdldFlBeGlzQ29udGFpbmVyKHZpZXcsIGZpZWxkKTtcbiAgICAgICAgaWYgKGF4aXNDb250YWluZXIpIHtcbiAgICAgICAgICAgIGF4aXNDb250YWluZXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0R2VvbWV0cnlWaXNpYmlsaXR5KHZpZXcsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLnNob3dMYXllciA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmdlb21MYXllcnNbaW5kZXhdO1xuICAgICAgICB2YXIgZmllbGQgPSB0aGlzLm9wdGlvbnMueUZpZWxkW2luZGV4XTtcbiAgICAgICAgdmFyIHZpZXcgPSBsYXllci52aWV3O1xuICAgICAgICB2YXIgYXhpc0NvbnRhaW5lciA9IHRoaXMuZ2V0WUF4aXNDb250YWluZXIodmlldywgZmllbGQpO1xuICAgICAgICBpZiAoYXhpc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgYXhpc0NvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldEdlb21ldHJ5VmlzaWJpbGl0eSh2aWV3LCB0cnVlKTtcbiAgICAgICAgdGhpcy5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLnNldEdlb21ldHJ5VmlzaWJpbGl0eSA9IGZ1bmN0aW9uICh2aWV3LCBzaG93KSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHZpZXcuZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb20pIHtcbiAgICAgICAgICAgIHZhciBjb250YWluZXIgPSBnZW9tLmNvbnRhaW5lciwgbGFiZWxzQ29udGFpbmVyID0gZ2VvbS5sYWJlbHNDb250YWluZXI7XG4gICAgICAgICAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLnNldCgndmlzaWJsZScsIHNob3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhYmVsc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIGxhYmVsc0NvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBzaG93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb21ib1ZpZXdMYXllci5wcm90b3R5cGUuZ2V0WUF4aXNDb250YWluZXIgPSBmdW5jdGlvbiAodmlldywgZmllbGQpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lcjtcbiAgICAgICAgdmFyIGF4aXNDdHIgPSB2aWV3LmNvbnRyb2xsZXJzLmZpbHRlcihmdW5jdGlvbiAoY3RyKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8xLmhhc0tleShjdHIsICdheGlzQ29udGFpbmVyJyk7XG4gICAgICAgIH0pWzBdO1xuICAgICAgICBpZiAoYXhpc0N0cikge1xuICAgICAgICAgICAgdmFyIGN0ciA9IGF4aXNDdHI7XG4gICAgICAgICAgICB2YXIgYXhpc0dyb3VwcyA9IGN0ci5heGlzQ29udGFpbmVyLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGF4aXNHcm91cHMsIGZ1bmN0aW9uIChnKSB7XG4gICAgICAgICAgICAgICAgdmFyIGF4aXNGaWVsZCA9IGcuZ2V0KCdjb21wb25lbnQnKS5nZXQoJ2ZpZWxkJyk7XG4gICAgICAgICAgICAgICAgaWYgKGF4aXNGaWVsZCA9PT0gZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29udGFpbmVyO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmdldFVuQ2hlY2tlZFZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5sZWdlbmRzLCBmdW5jdGlvbiAobGVnZW5kKSB7XG4gICAgICAgICAgICB2YXIgdW5jaGVja2VkSXRlbXMgPSBsZWdlbmQuZ2V0SXRlbXNCeVN0YXRlKCd1bmNoZWNrZWQnKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHVuY2hlY2tlZEl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHZhbHVlLnB1c2goaXRlbS5uYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmRyYXdUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmxheWVyQkJveDtcbiAgICAgICAgaWYgKHRoaXMudGl0bGUpIHtcbiAgICAgICAgICAgIHRoaXMudGl0bGUuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy50aXRsZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbW1vbl8xLmlzVGV4dFVzYWJsZShwcm9wcy50aXRsZSkpIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnRoZW1lO1xuICAgICAgICAgICAgdmFyIHRpdGxlID0gbmV3IGRlc2NyaXB0aW9uXzEuZGVmYXVsdCh7XG4gICAgICAgICAgICAgICAgbGVmdE1hcmdpbjogcmFuZ2UubWluWCArIHRoZW1lLnRpdGxlLnBhZGRpbmdbM10sXG4gICAgICAgICAgICAgICAgcmlnaHRNYXJnaW46IHJhbmdlLm1heFggLSB0aGVtZS50aXRsZS5wYWRkaW5nWzFdLFxuICAgICAgICAgICAgICAgIHRvcE1hcmdpbjogcmFuZ2UubWluWSArIHRoZW1lLnRpdGxlLnBhZGRpbmdbMF0sXG4gICAgICAgICAgICAgICAgdGV4dDogcHJvcHMudGl0bGUudGV4dCxcbiAgICAgICAgICAgICAgICBzdHlsZTogdXRpbF8xLm1peCh0aGVtZS50aXRsZSwgcHJvcHMudGl0bGUuc3R5bGUpLFxuICAgICAgICAgICAgICAgIHdyYXBwZXJXaWR0aDogd2lkdGggLSB0aGVtZS50aXRsZS5wYWRkaW5nWzNdIC0gdGhlbWUudGl0bGUucGFkZGluZ1sxXSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLmFkZEdyb3VwKCksXG4gICAgICAgICAgICAgICAgdGhlbWU6IHRoZW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiBjb21tb25fMS5pc1RleHRVc2FibGUocHJvcHMuZGVzY3JpcHRpb24pID8gMCA6IDEsXG4gICAgICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgICAgICAgICBhbGlnblRvOiBwcm9wcy50aXRsZS5hbGlnblRvLFxuICAgICAgICAgICAgICAgIG5hbWU6ICd0aXRsZScsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMudGl0bGUgPSB0aXRsZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmRyYXdEZXNjcmlwdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmxheWVyQkJveDtcbiAgICAgICAgaWYgKHRoaXMuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRpb24uZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbW1vbl8xLmlzVGV4dFVzYWJsZShwcm9wcy5kZXNjcmlwdGlvbikpIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnRoZW1lO1xuICAgICAgICAgICAgdmFyIHRvcE1hcmdpbiA9IDA7XG4gICAgICAgICAgICBpZiAodGhpcy50aXRsZSkge1xuICAgICAgICAgICAgICAgIHZhciB0aXRsZUJCb3ggPSB0aGlzLnRpdGxlLmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW4gKz0gdGl0bGVCQm94Lm1pblkgKyB0aXRsZUJCb3guaGVpZ2h0O1xuICAgICAgICAgICAgICAgIHRvcE1hcmdpbiArPSB0aGVtZS5kZXNjcmlwdGlvbi5wYWRkaW5nWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5pegdGl0bGXnmoTmg4XlhrXkuIvkvb/nlKh0aXRsZeeahOS4inBhZGRpbmdcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW4gKz0gcmFuZ2UubWluWSArIHRoZW1lLnRpdGxlLnBhZGRpbmdbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGVzY3JpcHRpb24gPSBuZXcgZGVzY3JpcHRpb25fMS5kZWZhdWx0KHtcbiAgICAgICAgICAgICAgICBsZWZ0TWFyZ2luOiByYW5nZS5taW5YICsgdGhlbWUuZGVzY3JpcHRpb24ucGFkZGluZ1szXSxcbiAgICAgICAgICAgICAgICB0b3BNYXJnaW46IHRvcE1hcmdpbixcbiAgICAgICAgICAgICAgICByaWdodE1hcmdpbjogcmFuZ2UubWF4WCAtIHRoZW1lLnRpdGxlLnBhZGRpbmdbMV0sXG4gICAgICAgICAgICAgICAgdGV4dDogcHJvcHMuZGVzY3JpcHRpb24udGV4dCxcbiAgICAgICAgICAgICAgICBzdHlsZTogdXRpbF8xLm1peCh0aGVtZS5kZXNjcmlwdGlvbiwgcHJvcHMuZGVzY3JpcHRpb24uc3R5bGUpLFxuICAgICAgICAgICAgICAgIHdyYXBwZXJXaWR0aDogd2lkdGggLSB0aGVtZS5kZXNjcmlwdGlvbi5wYWRkaW5nWzNdIC0gdGhlbWUuZGVzY3JpcHRpb24ucGFkZGluZ1sxXSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLmFkZEdyb3VwKCksXG4gICAgICAgICAgICAgICAgdGhlbWU6IHRoZW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiAxLFxuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICAgICAgYWxpZ25UbzogcHJvcHMuZGVzY3JpcHRpb24uYWxpZ25UbyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnZGVzY3JpcHRpb24nLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbWJvVmlld0xheWVyLnByb3RvdHlwZS5nZXRWaWV3UmFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5sYXllckJCb3gpIHtcbiAgICAgICAgICAgIHRoaXMubGF5ZXJCQm94ID0gbmV3IGJib3hfMS5kZWZhdWx0KHRoaXMueCwgdGhpcy55LCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHZpZXdNaW5YID0gdGhpcy5sYXllckJCb3gubWluWDtcbiAgICAgICAgdmFyIHZpZXdNYXhYID0gdGhpcy5sYXllckJCb3gubWF4WDtcbiAgICAgICAgdmFyIHZpZXdNaW5ZID0gdGhpcy5sYXllckJCb3gubWluWTtcbiAgICAgICAgdmFyIHZpZXdNYXhZID0gdGhpcy5sYXllckJCb3gubWF4WTtcbiAgICAgICAgdmFyIGNvbXBvbmVudHMgPSBbdGhpcy50aXRsZSwgdGhpcy5kZXNjcmlwdGlvbl07XG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbXBvbmVudHMsIGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcG9zaXRpb24gPSBjb21wb25lbnQucG9zaXRpb247XG4gICAgICAgICAgICAgICAgdmFyIF9hID0gY29tcG9uZW50LmdldEJCb3goKSwgbWluWCA9IF9hLm1pblgsIG1heFggPSBfYS5tYXhYLCBtaW5ZID0gX2EubWluWSwgbWF4WSA9IF9hLm1heFk7XG4gICAgICAgICAgICAgICAgaWYgKG1heFkgPj0gdmlld01pblkgJiYgbWF4WSA8PSB2aWV3TWF4WSAmJiBwb3NpdGlvbiA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdmlld01pblkgPSBtYXhZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWluWSA+PSB2aWV3TWluWSAmJiBtaW5ZIDw9IHZpZXdNYXhZICYmIHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgICAgICAgICB2aWV3TWF4WSA9IG1pblk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtYXhYID4gdmlld01pblggJiYgbWF4WCA8PSB2aWV3TWF4WCAmJiBwb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZXdNaW5YID0gbWF4WDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1pblggPj0gdmlld01pblggJiYgbWF4WCA8PSB2aWV3TWF4WCAmJiBwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgICAgICAgICB2aWV3TWF4WCA9IG1pblg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBiYm94XzEuZGVmYXVsdCh2aWV3TWluWCwgdmlld01pblksIHZpZXdNYXhYIC0gdmlld01pblgsIHZpZXdNYXhZIC0gdmlld01pblkpO1xuICAgIH07XG4gICAgQ29tYm9WaWV3TGF5ZXIucHJvdG90eXBlLmdldE1vY2tEYXRhID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQ7XG4gICAgICAgIHZhciBtb2NrID0ge307XG4gICAgICAgIG1vY2tbeEZpZWxkXSA9ICdudWxsJztcbiAgICAgICAgbW9ja1t5RmllbGRbaW5kZXhdXSA9IDA7XG4gICAgICAgIHJldHVybiBbbW9ja107XG4gICAgfTtcbiAgICByZXR1cm4gQ29tYm9WaWV3TGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29tYm9WaWV3TGF5ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBDb2x1bW5MaW5lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbHVtbkxpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ29sdW1uTGluZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBDb2x1bW5MaW5lLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnY29sdW1uTGluZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBDb2x1bW5MaW5lLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBDb2x1bW5MaW5lO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sdW1uTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiQGFudHYvY29tcG9uZW50XCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL3Bsb3RzL2xpbmUvbGF5ZXJcIikpO1xudmFyIGxheWVyXzIgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vcGxvdHMvY29sdW1uL2xheWVyXCIpKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIGRlZmF1bHRMaW5lQ29uZmlnID0ge1xuICAgIGNvbG9yOiAnI2Y1YmMzMicsXG4gICAgbGluZVNpemU6IDQsXG4gICAgY29ubmVjdE51bGw6IHRydWUsXG4gICAgcG9pbnQ6IHtcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgIHNpemU6IDMsXG4gICAgICAgIHNoYXBlOiAnY2lyY2xlJyxcbiAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIHN0cm9rZTogJyNmZmYnLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgfSxcbn07XG52YXIgZGVmYXVsdENvbHVtbkNvbmZpZyA9IHtcbiAgICBjb2xvcjogJyM1QjhGRjknLFxufTtcbnZhciBkZWZhdWx0WUF4aXNDb25maWcgPSB7XG4gICAgdmlzaWJsZTogdHJ1ZSxcbiAgICBjb2xvck1hcHBpbmc6IHRydWUsXG4gICAgZ3JpZDoge1xuICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgIH0sXG4gICAgbGluZToge1xuICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICB9LFxuICAgIHRpY2tMaW5lOiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgIGF1dG9Sb3RhdGU6IGZhbHNlLFxuICAgIH0sXG4gICAgdGl0bGU6IHtcbiAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgIHNwYWNpbmc6IDEyLFxuICAgIH0sXG59O1xudmFyIENvbHVtbkxpbmVMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhDb2x1bW5MaW5lTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ29sdW1uTGluZUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdjb2x1bW5MaW5lJztcbiAgICAgICAgX3RoaXMubGVnZW5kcyA9IFtdO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIENvbHVtbkxpbmVMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICBsZWZ0Q29uZmlnOiBkZWZhdWx0WUF4aXNDb25maWcsXG4gICAgICAgICAgICAgICAgcmlnaHRDb25maWc6IGRlZmF1bHRZQXhpc0NvbmZpZyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lQ29uZmlnOiBkZWZhdWx0TGluZUNvbmZpZyxcbiAgICAgICAgICAgIGNvbHVtbkNvbmZpZzogZGVmYXVsdENvbHVtbkNvbmZpZyxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuYmVmb3JlSW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgdmFyIF9jID0gdGhpcywgb3B0aW9ucyA9IF9jLm9wdGlvbnMsIGluaXRpYWxPcHRpb25zID0gX2MuaW5pdGlhbE9wdGlvbnM7XG4gICAgICAgIGlmIChvcHRpb25zLmxpbmVTZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgb3B0aW9ucy55QXhpcy5yaWdodENvbmZpZy5jb2xvck1hcHBpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghKChfYSA9IGluaXRpYWxPcHRpb25zLmxpbmVDb25maWcpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5saW5lU2l6ZSkpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmxpbmVDb25maWcubGluZVNpemUgPSAzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEoKF9iID0gaW5pdGlhbE9wdGlvbnMubGluZUNvbmZpZykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmNvbG9yKSkge1xuICAgICAgICAgICAgICAgIHZhciBfZCA9IHRoZW1lXzEuZ2V0R2xvYmFsVGhlbWUoKSwgY29sb3JzID0gX2QuY29sb3JzLCBjb2xvcnNfMjAgPSBfZC5jb2xvcnNfMjA7XG4gICAgICAgICAgICAgICAgdmFyIHNlcmllc1ZhbHVlID0gdGhpcy5nZXRWYWx1ZUJ5U2VyaWVzRmllbGQoKTtcbiAgICAgICAgICAgICAgICB2YXIgY29sb3JTZXJpZXNfMSA9IHNlcmllc1ZhbHVlLmxlbmd0aCA+IGNvbG9ycy5sZW5ndGggPyBjb2xvcnNfMjAgOiBjb2xvcnM7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9yUGxhdGVzXzEgPSBbXTtcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChzZXJpZXNWYWx1ZSwgZnVuY3Rpb24gKHYsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbG9yUGxhdGVzXzEucHVzaChjb2xvclNlcmllc18xW2luZGV4ICsgMV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubGluZUNvbmZpZy5jb2xvciA9IGNvbG9yUGxhdGVzXzE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0LmNhbGwodGhpcyk7XG4gICAgICAgIGlmICghdGhpcy5jaGVja0RhdGEoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgZGF0YSA9IF9hLmRhdGEsIG1ldGEgPSBfYS5tZXRhLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZCwgbGluZVNlcmllc0ZpZWxkID0gX2EubGluZVNlcmllc0ZpZWxkLCBsZWdlbmQgPSBfYS5sZWdlbmQsIGxpbmVDb25maWcgPSBfYS5saW5lQ29uZmlnLCBjb2x1bW5Db25maWcgPSBfYS5jb2x1bW5Db25maWcsIGV2ZW50cyA9IF9hLmV2ZW50cywgY3VzdG9tTWV0YSA9IF9hLmN1c3RvbU1ldGE7XG4gICAgICAgIHRoaXMuY29sb3JzID0gW2NvbHVtbkNvbmZpZy5jb2xvciwgbGluZUNvbmZpZy5jb2xvcl07XG4gICAgICAgIC8vIGRyYXcgY29sdW1uXG4gICAgICAgIHRoaXMuZHJhd0NvbHVtbigpO1xuICAgICAgICAvL2RyYXcgbGluZVxuICAgICAgICB2YXIgbWV0YUluZm8gPSB7fTtcbiAgICAgICAgbWV0YUluZm9beUZpZWxkWzFdXSA9IHsgdGlja3M6IHRoaXMuZ2V0VGlja3MoKSB9O1xuICAgICAgICB2YXIgbGluZSA9IHRoaXMuY3JlYXRlTGF5ZXIobGF5ZXJfMS5kZWZhdWx0LCBkYXRhWzFdLCB0c2xpYl8xLl9fYXNzaWduKHsgeEZpZWxkOiB4RmllbGQsIHlGaWVsZDogeUZpZWxkWzFdLCBzZXJpZXNGaWVsZDogbGluZVNlcmllc0ZpZWxkLCBtZXRhOiAhY3VzdG9tTWV0YSA/IHV0aWxfMS5kZWVwTWl4KHt9LCBtZXRhLCBtZXRhSW5mbykgOiBtZXRhLCB4QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSwgeUF4aXM6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdyaWdodCcsXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG5pY2U6IHRydWUsXG4gICAgICAgICAgICB9LCB0aGlzLnlBeGlzKDEpKSwgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSwgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LCBldmVudHM6IGV2ZW50cyB9LCBsaW5lQ29uZmlnKSk7XG4gICAgICAgIGxpbmUucmVuZGVyKCk7XG4gICAgICAgIGlmIChsZWdlbmQudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5jdXN0b21MZWdlbmQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkanVzdExheW91dCgpO1xuICAgIH07XG4gICAgQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5kcmF3Q29sdW1uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIGRhdGEgPSBfYS5kYXRhLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZCwgeEF4aXMgPSBfYS54QXhpcywgdG9vbHRpcCA9IF9hLnRvb2x0aXAsIGNvbHVtbkNvbmZpZyA9IF9hLmNvbHVtbkNvbmZpZywgbWV0YSA9IF9hLm1ldGEsIGV2ZW50cyA9IF9hLmV2ZW50cztcbiAgICAgICAgdmFyIGNvbHVtbiA9IHRoaXMuY3JlYXRlTGF5ZXIobGF5ZXJfMi5kZWZhdWx0LCBkYXRhWzBdLCB0c2xpYl8xLl9fYXNzaWduKHsgeEZpZWxkOiB4RmllbGQsIHlGaWVsZDogeUZpZWxkWzBdLCBtZXRhOiBtZXRhLFxuICAgICAgICAgICAgeEF4aXM6IHhBeGlzLCB5QXhpczogdXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgfSwgdGhpcy55QXhpcygwKSksIHRvb2x0aXA6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGN1c3RvbToge1xuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24gKGNvbnRhaW5lckRvbSwgZXYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnRvb2x0aXAoY29udGFpbmVyRG9tLCBldik7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sIHRvb2x0aXApLCBldmVudHM6IGV2ZW50cyB9LCBjb2x1bW5Db25maWcpKTtcbiAgICAgICAgY29sdW1uLnJlbmRlcigpO1xuICAgIH07XG4gICAgQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS50b29sdGlwID0gZnVuY3Rpb24gKGRvbSwgZXYpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZCwgdG9vbHRpcCA9IF9hLnRvb2x0aXA7XG4gICAgICAgIHZhciBvcmlnaW5JdGVtID0gdXRpbF8xLmNsb25lKGV2Lml0ZW1zWzBdKTtcbiAgICAgICAgdmFyIGRhdGFJdGVtc0EgPSB0aGlzLmdldERhdGFCeVhGaWVsZChldi50aXRsZSwgMSk7XG4gICAgICAgIHZhciBmb3JtYXR0ZXIgPSB1dGlsXzEuZ2V0KHRvb2x0aXAsICdmb3JtYXR0ZXInKTtcbiAgICAgICAgaWYgKGRhdGFJdGVtc0EpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGRhdGFJdGVtc0EsIGZ1bmN0aW9uIChkLCBpbmRleCkge1xuICAgICAgICAgICAgICAgIHZhciBzZXJpZXNGaWVsZCA9IF90aGlzLmdlb21MYXllcnNbMV0ub3B0aW9ucy5zZXJpZXNGaWVsZDtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IHNlcmllc0ZpZWxkID8gZFtzZXJpZXNGaWVsZF0gOiB5RmllbGRbMV07XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5pyJIGZvcm1hdHRlciDlsLHmiafooYwgZm9ybWF0dGVy77yM5ZCm5YiZ5LiN5aSE55CGXG4gICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSBmb3JtYXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgPyBmb3JtYXR0ZXIoZFt4RmllbGRdLCBkW3lGaWVsZFsxXV0sIGRbc2VyaWVzRmllbGRdKVxuICAgICAgICAgICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZFt5RmllbGRbMV1dLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGV2Lml0ZW1zLnB1c2godHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3JpZ2luSXRlbSksIHsgbWFwcGluZ0RhdGE6IHV0aWxfMS5kZWVwTWl4KHt9LCBvcmlnaW5JdGVtLm1hcHBpbmdEYXRhLCB7IF9vcmlnaW46IGRhdGFJdGVtc0EgfSksIGRhdGE6IGQgfSksIGl0ZW0pLCB7IGNvbG9yOiB1dGlsXzEuaXNBcnJheShfdGhpcy5jb2xvcnNbMV0pID8gX3RoaXMuY29sb3JzWzFdW2luZGV4XSA6IF90aGlzLmNvbG9yc1sxXSB9KSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxlZ2VuZC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgdW5DaGVja2VkVmFsdWVfMSA9IHRoaXMuZ2V0VW5DaGVja2VkVmFsdWUoKTtcbiAgICAgICAgICAgIHZhciB0b3RhbEl0ZW1zID0gdGhpcy5sZWdlbmRzWzBdLmdldCgnaXRlbXMnKS5sZW5ndGggKyB0aGlzLmxlZ2VuZHNbMV0uZ2V0KCdpdGVtcycpLmxlbmd0aDtcbiAgICAgICAgICAgIC8vIOWmguaenGxlZ2VuZOWFqOmDqOaYr3VuY2hlY2tlZOeahOeKtuaAge+8jHRvb2x0aXDkuI3mmL7npLpcbiAgICAgICAgICAgIGlmICh1bkNoZWNrZWRWYWx1ZV8xLmxlbmd0aCA9PT0gdG90YWxJdGVtcykge1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGxlZ2VuZOmDqOWIhmNoZWNrZWTnmoTml7blgJnvvIzmoLnmja5jaGVja2Vk54q25oCBZmlsdGVyIGl0ZW1zXG4gICAgICAgICAgICB2YXIgdW5pcUtleXNfMSA9IFtdO1xuICAgICAgICAgICAgdmFyIHVuaXFJdGVtc18xID0gW107XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChldi5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGl0ZW0ubmFtZTtcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWxfMS5jb250YWlucyh1bmlxS2V5c18xLCBuYW1lKSAmJiAhdXRpbF8xLmNvbnRhaW5zKHVuQ2hlY2tlZFZhbHVlXzEsIG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuaXFLZXlzXzEucHVzaChuYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgdW5pcUl0ZW1zXzEucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGV2Lml0ZW1zLCBmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCB1bmlxSXRlbXNfMS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgZXYuaXRlbXNbaW5kZXhdID0gdW5pcUl0ZW1zXzFbaW5kZXhdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXYuaXRlbXMucG9wKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuY3VzdG9tTGVnZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHlGaWVsZCA9IF9hLnlGaWVsZCwgbGVnZW5kID0gX2EubGVnZW5kO1xuICAgICAgICB2YXIgY29sb3JzID0gdGhpcy5jb2xvcnM7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lci5hZGRHcm91cCgpO1xuICAgICAgICB2YXIgbGVnZW5kQ2ZnID0gbGVnZW5kO1xuICAgICAgICB2YXIgc3ltYm9scyA9IFsnc3F1YXJlJywgJ2NpcmNsZSddO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmdlb21MYXllcnMsIGZ1bmN0aW9uIChnZW9tLCBpbmRleCkge1xuICAgICAgICAgICAgdmFyIGxlZ2VuZDtcbiAgICAgICAgICAgIGlmIChnZW9tLm9wdGlvbnMuc2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gX3RoaXMuZ2V0VmFsdWVCeVNlcmllc0ZpZWxkKCk7XG4gICAgICAgICAgICAgICAgbGVnZW5kID0gX3RoaXMuY3JlYXRlTm9ybWFsTGVnZW5kKHZhbHVlcywgc3ltYm9sc1tpbmRleF0sIGNvbG9yc1tpbmRleF0sIGxlZ2VuZENmZywgY29udGFpbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxlZ2VuZCA9IF90aGlzLmNyZWF0ZVNpbmdsZUxlZ2VuZCh5RmllbGRbaW5kZXhdLCBzeW1ib2xzW2luZGV4XSwgY29sb3JzW2luZGV4XSwgbGVnZW5kQ2ZnLCBjb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMubGVnZW5kcy5wdXNoKGxlZ2VuZCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDkvb/nlKhsZWdlbmTlgZrlm77lsYLnrZvpgIlcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5nZW9tTGF5ZXJzLCBmdW5jdGlvbiAoZ2VvbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmIChnZW9tLm9wdGlvbnMuc2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5tdWx0aXBsZUxlZ2VuZEZpbHRlcihpbmRleCwgZ2VvbS5vcHRpb25zLnNlcmllc0ZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIF90aGlzLmxlZ2VuZEZpbHRlcihpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5jcmVhdGVTaW5nbGVMZWdlbmQgPSBmdW5jdGlvbiAobmFtZSwgc3ltYm9sLCBjb2xvciwgY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIG1hcmtlckNmZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICBzeW1ib2w6IHN5bWJvbCxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sIGNmZy5tYXJrZXIpO1xuICAgICAgICB2YXIgaXRlbXMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgICB1bmNoZWNrZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1hcmtlcjogbWFya2VyQ2ZnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgICAgdmFyIGxlZ2VuZCA9IG5ldyBjb21wb25lbnRfMS5MZWdlbmQuQ2F0ZWdvcnkoe1xuICAgICAgICAgICAgaWQ6IHRoaXMudHlwZSxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICBpdGVtczogaXRlbXMsXG4gICAgICAgICAgICB1cGRhdGVBdXRvUmVuZGVyOiB0cnVlLFxuICAgICAgICAgICAgaXRlbUJhY2tncm91bmQ6IG51bGwsXG4gICAgICAgICAgICBpdGVtTmFtZTogY2ZnLnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICBsZWdlbmQuaW5pdCgpO1xuICAgICAgICBsZWdlbmQucmVuZGVyKCk7XG4gICAgICAgIHJldHVybiBsZWdlbmQ7XG4gICAgfTtcbiAgICBDb2x1bW5MaW5lTGF5ZXIucHJvdG90eXBlLmNyZWF0ZU5vcm1hbExlZ2VuZCA9IGZ1bmN0aW9uICh2YWx1ZXMsIHN5bWJvbCwgY29sb3IsIGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBsZWdlbmRJdGVtcyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaCh2YWx1ZXMsIGZ1bmN0aW9uICh2LCBpbmRleCkge1xuICAgICAgICAgICAgbGVnZW5kSXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgbmFtZTogdixcbiAgICAgICAgICAgICAgICB1bmNoZWNrZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1hcmtlcjoge1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2w6IHN5bWJvbCxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcltpbmRleF0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGxlZ2VuZCA9IG5ldyBjb21wb25lbnRfMS5MZWdlbmQuQ2F0ZWdvcnkoe1xuICAgICAgICAgICAgaWQ6IHRoaXMudHlwZSxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICBpdGVtczogbGVnZW5kSXRlbXMsXG4gICAgICAgICAgICB1cGRhdGVBdXRvUmVuZGVyOiB0cnVlLFxuICAgICAgICAgICAgaXRlbUJhY2tncm91bmQ6IG51bGwsXG4gICAgICAgICAgICBpdGVtTmFtZTogY2ZnLnRleHQsXG4gICAgICAgICAgICBvZmZzZXRYOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgbGVnZW5kLmluaXQoKTtcbiAgICAgICAgbGVnZW5kLnJlbmRlcigpO1xuICAgICAgICByZXR1cm4gbGVnZW5kO1xuICAgIH07XG4gICAgQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5tdWx0aXBsZUxlZ2VuZEZpbHRlciA9IGZ1bmN0aW9uIChpbmRleCwgZmllbGQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGxlZ2VuZCA9IHRoaXMubGVnZW5kc1tpbmRleF07XG4gICAgICAgIHZhciBmaWx0ZXJlZFZhbHVlID0gW107XG4gICAgICAgIHZhciBsZWdlbmRfZ3JvdXAgPSBsZWdlbmQuZ2V0KCdncm91cCcpO1xuICAgICAgICB2YXIgbGF5ZXJIaWRlID0gZmFsc2U7XG4gICAgICAgIGxlZ2VuZF9ncm91cC5vbignY2xpY2snLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciB2aWV3ID0gX3RoaXMuZ2VvbUxheWVyc1tpbmRleF0udmlldztcbiAgICAgICAgICAgIHZhciBpdGVtID0gZXYudGFyZ2V0LmdldCgnZGVsZWdhdGVPYmplY3QnKS5pdGVtO1xuICAgICAgICAgICAgaWYgKGl0ZW0udW5jaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGxheWVySGlkZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zaG93TGF5ZXIoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICBsYXllckhpZGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdXRpbF8xLnB1bGwoZmlsdGVyZWRWYWx1ZSwgaXRlbS5uYW1lKTtcbiAgICAgICAgICAgICAgICB2aWV3LmZpbHRlcihpdGVtLnZhbHVlLCBmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gIXV0aWxfMS5jb250YWlucyhmaWx0ZXJlZFZhbHVlLCBmKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2aWV3LnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIGxlZ2VuZC5zZXRJdGVtU3RhdGUoaXRlbSwgJ3VuY2hlY2tlZCcsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxlZ2VuZC5zZXRJdGVtU3RhdGUoaXRlbSwgJ3VuY2hlY2tlZCcsIHRydWUpO1xuICAgICAgICAgICAgICAgIGZpbHRlcmVkVmFsdWUucHVzaChpdGVtLm5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZFZhbHVlLmxlbmd0aCA9PT0gX3RoaXMubGVnZW5kc1tpbmRleF0uZ2V0KCdpdGVtcycpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzliIbnu4TliIbnsbvlhajpg6jooqt1bmNoZWNr5LqG77yM55u05o6l6ZqQ6JeP5Zu+5bGC77yM6L+Z5qC35LuN54S25Y+v5LuldHJpZ2dlciB0b29sdGlwXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmhpZGVMYXllcihpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGxheWVySGlkZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2aWV3LmZpbHRlcihmaWVsZCwgZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhdXRpbF8xLmNvbnRhaW5zKGZpbHRlcmVkVmFsdWUsIGYpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgdmlldy5yZW5kZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5jYW52YXMuZHJhdygpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuZ2V0VmFsdWVCeVNlcmllc0ZpZWxkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIGxpbmVTZXJpZXNGaWVsZCA9IF9hLmxpbmVTZXJpZXNGaWVsZCwgZGF0YSA9IF9hLmRhdGE7XG4gICAgICAgIHZhciBsaW5lRGF0YSA9IGRhdGFbMV07XG4gICAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2gobGluZURhdGEsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICB2YXIgdiA9IGRbbGluZVNlcmllc0ZpZWxkXTtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmNvbnRhaW5zKHZhbHVlcywgdikpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCh2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfTtcbiAgICByZXR1cm4gQ29sdW1uTGluZUxheWVyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sdW1uTGluZUxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnY29sdW1uTGluZScsIENvbHVtbkxpbmVMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgRHVhbExpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRHVhbExpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRHVhbExpbmUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgRHVhbExpbmUucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdkdWFsTGluZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBEdWFsTGluZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gRHVhbExpbmU7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEdWFsTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiQGFudHYvY29tcG9uZW50XCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL3Bsb3RzL2xpbmUvbGF5ZXJcIikpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlZmF1bHRMaW5lQ29uZmlnID0ge1xuICAgIGxpbmVTaXplOiAyLFxuICAgIGNvbm5lY3ROdWxsOiB0cnVlLFxuICAgIHBvaW50OiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICBzaXplOiAzLFxuICAgICAgICBzaGFwZTogJ2NpcmNsZScsXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICBzdHJva2U6ICcjZmZmJyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIGxhYmVsOiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgIH0sXG59O1xudmFyIGRlZmF1bHRZQXhpc0NvbmZpZyA9IHtcbiAgICB2aXNpYmxlOiB0cnVlLFxuICAgIGNvbG9yTWFwcGluZzogdHJ1ZSxcbiAgICBncmlkOiB7XG4gICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgfSxcbiAgICBsaW5lOiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgIH0sXG4gICAgdGlja0xpbmU6IHtcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgfSxcbiAgICBsYWJlbDoge1xuICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgfSxcbiAgICB0aXRsZToge1xuICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiAxMixcbiAgICB9LFxufTtcbnZhciBEdWFsTGluZUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKER1YWxMaW5lTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRHVhbExpbmVMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnZHVhbExpbmUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIER1YWxMaW5lTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICBsZWZ0Q29uZmlnOiBkZWZhdWx0WUF4aXNDb25maWcsXG4gICAgICAgICAgICAgICAgcmlnaHRDb25maWc6IGRlZmF1bHRZQXhpc0NvbmZpZyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAvLyDoh6rlj6TnuqLok53lh7pjcC4uLi5cbiAgICAgICAgICAgIGxpbmVDb25maWdzOiBbXG4gICAgICAgICAgICAgICAgdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRMaW5lQ29uZmlnLCB7IGNvbG9yOiAnIzVCOEZGOScgfSksXG4gICAgICAgICAgICAgICAgdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRMaW5lQ29uZmlnLCB7IGNvbG9yOiAnI2U3NmM1ZScgfSksXG4gICAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIER1YWxMaW5lTGF5ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAoIXRoaXMuY2hlY2tEYXRhKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIGRhdGEgPSBfYS5kYXRhLCBtZXRhID0gX2EubWV0YSwgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQsIHhBeGlzID0gX2EueEF4aXMsIHRvb2x0aXAgPSBfYS50b29sdGlwLCBsaW5lQ29uZmlncyA9IF9hLmxpbmVDb25maWdzLCBsZWdlbmQgPSBfYS5sZWdlbmQsIGV2ZW50cyA9IF9hLmV2ZW50cywgY3VzdG9tTWV0YSA9IF9hLmN1c3RvbU1ldGE7XG4gICAgICAgIHRoaXMuY29sb3JzID0gW2xpbmVDb25maWdzWzBdLmNvbG9yLCBsaW5lQ29uZmlnc1sxXS5jb2xvcl07XG4gICAgICAgIHZhciB5QXhpc0dsb2JhbENvbmZpZyA9IHRoaXMuZ2V0WUF4aXNHbG9iYWxDb25maWcoKTtcbiAgICAgICAgLy9kcmF3IGZpcnN0IGxpbmVcbiAgICAgICAgdmFyIGxlZnRMaW5lID0gdGhpcy5jcmVhdGVMYXllcihsYXllcl8xLmRlZmF1bHQsIGRhdGFbMF0sIHRzbGliXzEuX19hc3NpZ24oeyBtZXRhOiBtZXRhLFxuICAgICAgICAgICAgeEZpZWxkOiB4RmllbGQsIHlGaWVsZDogeUZpZWxkWzBdLCB4QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSwgeUF4aXM6IHV0aWxfMS5kZWVwTWl4KHt9LCB5QXhpc0dsb2JhbENvbmZpZywge1xuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgfSwgdGhpcy55QXhpcygwKSksIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sIGV2ZW50czogZXZlbnRzIH0sIGxpbmVDb25maWdzWzBdKSk7XG4gICAgICAgIGxlZnRMaW5lLnJlbmRlcigpO1xuICAgICAgICAvL2RyYXcgc2Vjb25kIGxpbmVcbiAgICAgICAgdmFyIG1ldGFJbmZvID0ge307XG4gICAgICAgIG1ldGFJbmZvW3lGaWVsZFsxXV0gPSB7IHRpY2tzOiB0aGlzLmdldFRpY2tzKCkgfTtcbiAgICAgICAgdmFyIHJpZ2h0TGluZSA9IHRoaXMuY3JlYXRlTGF5ZXIobGF5ZXJfMS5kZWZhdWx0LCBkYXRhWzFdLCB0c2xpYl8xLl9fYXNzaWduKHsgeEZpZWxkOiB4RmllbGQsIHlGaWVsZDogeUZpZWxkWzFdLCBtZXRhOiAhY3VzdG9tTWV0YSA/IHV0aWxfMS5kZWVwTWl4KHt9LCBtZXRhLCBtZXRhSW5mbykgOiBtZXRhLCBzZXJpZUZpZWxkOiB5RmllbGRbMV0sIHhBeGlzOiB4QXhpcywgeUF4aXM6IHV0aWxfMS5kZWVwTWl4KHt9LCB5QXhpc0dsb2JhbENvbmZpZywge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAncmlnaHQnLFxuICAgICAgICAgICAgICAgIG5pY2U6IGZhbHNlLFxuICAgICAgICAgICAgfSwgdGhpcy55QXhpcygxKSksIHRvb2x0aXA6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGN1c3RvbToge1xuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24gKGNvbnRhaW5lckRvbSwgZXYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnRvb2x0aXAoY29udGFpbmVyRG9tLCBldik7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sIHRvb2x0aXApLCBldmVudHM6IGV2ZW50cyB9LCBsaW5lQ29uZmlnc1sxXSkpO1xuICAgICAgICByaWdodExpbmUucmVuZGVyKCk7XG4gICAgICAgIGlmIChsZWdlbmQudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5jdXN0b21MZWdlbmQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkanVzdExheW91dCgpO1xuICAgIH07XG4gICAgRHVhbExpbmVMYXllci5wcm90b3R5cGUudG9vbHRpcCA9IGZ1bmN0aW9uIChkb20sIGV2KSB7XG4gICAgICAgIHZhciB1bkNoZWNrZWRWYWx1ZSA9IHRoaXMuZ2V0VW5DaGVja2VkVmFsdWUoKTtcbiAgICAgICAgLy8g5aaC5p6cbGVnZW5k5YWo6YOo5pivdW5jaGVja2Vk55qE54q25oCB77yMdG9vbHRpcOS4jeaYvuekulxuICAgICAgICBpZiAodW5DaGVja2VkVmFsdWUubGVuZ3RoID09PSB0aGlzLmNvbG9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRvbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZG9tLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICB9XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgeUZpZWxkID0gX2EueUZpZWxkLCBsZWdlbmQgPSBfYS5sZWdlbmQ7XG4gICAgICAgIHZhciBvcmlnaW5JdGVtID0gdXRpbF8xLmNsb25lKGV2Lml0ZW1zWzBdKTtcbiAgICAgICAgdmFyIGRhdGFJdGVtc0EgPSB0aGlzLmdldERhdGFCeVhGaWVsZChldi50aXRsZSwgMClbMF07XG4gICAgICAgIGlmIChkYXRhSXRlbXNBKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmZpbmRJbmRleChldi5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHsgcmV0dXJuIGl0ZW0ubmFtZSA9PT0geUZpZWxkWzBdOyB9KSA8IDApIHtcbiAgICAgICAgICAgICAgICBldi5pdGVtcy5wdXNoKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgb3JpZ2luSXRlbSksIHsgbWFwcGluZ0RhdGE6IHV0aWxfMS5kZWVwTWl4KHt9LCBvcmlnaW5JdGVtLm1hcHBpbmdEYXRhLCB7IF9vcmlnaW46IGRhdGFJdGVtc0EgfSksIGRhdGE6IGRhdGFJdGVtc0EsIG5hbWU6IHlGaWVsZFswXSwgdmFsdWU6IGRhdGFJdGVtc0FbeUZpZWxkWzBdXSwgY29sb3I6IHRoaXMuY29sb3JzWzBdIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobGVnZW5kLnZpc2libGUpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHRoaXMubGVnZW5kcywgZnVuY3Rpb24gKGxlZ2VuZCwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGxlZ2VuZC5nZXQoJ2l0ZW1zJylbMF07XG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0udW5jaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzcGxpY2VJbmRleCA9IGluZGV4ID09PSAwID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgICAgIGV2Lml0ZW1zLnNwbGljZShzcGxpY2VJbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIER1YWxMaW5lTGF5ZXIucHJvdG90eXBlLmN1c3RvbUxlZ2VuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCB5RmllbGQgPSBfYS55RmllbGQsIGxlZ2VuZCA9IF9hLmxlZ2VuZDtcbiAgICAgICAgdmFyIGNvbG9ycyA9IHRoaXMuY29sb3JzO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5jb250YWluZXIuYWRkR3JvdXAoKTtcbiAgICAgICAgdmFyIGxlZ2VuZENmZyA9IGxlZ2VuZDtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5nZW9tTGF5ZXJzLCBmdW5jdGlvbiAobGluZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBtYXJrZXJDZmcgPSB1dGlsXzEuZGVlcE1peCh7fSwge1xuICAgICAgICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogY29sb3JzW2luZGV4XSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSwgbGVnZW5kQ2ZnLm1hcmtlcik7XG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiB5RmllbGRbaW5kZXhdLFxuICAgICAgICAgICAgICAgICAgICB1bmNoZWNrZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtYXJrZXI6IG1hcmtlckNmZyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHZhciBsZWdlbmQgPSBuZXcgY29tcG9uZW50XzEuTGVnZW5kLkNhdGVnb3J5KHtcbiAgICAgICAgICAgICAgICBpZDogX3RoaXMudHlwZSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IGNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICAgICAgaXRlbXM6IGl0ZW1zLFxuICAgICAgICAgICAgICAgIHVwZGF0ZUF1dG9SZW5kZXI6IHRydWUsXG4gICAgICAgICAgICAgICAgaXRlbUJhY2tncm91bmQ6IG51bGwsXG4gICAgICAgICAgICAgICAgaXRlbU5hbWU6IGxlZ2VuZENmZy50ZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBsZWdlbmQuaW5pdCgpO1xuICAgICAgICAgICAgbGVnZW5kLnJlbmRlcigpO1xuICAgICAgICAgICAgX3RoaXMubGVnZW5kcy5wdXNoKGxlZ2VuZCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDkvb/nlKhsZWdlbmTlgZrlm77lsYLnrZvpgIlcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5nZW9tTGF5ZXJzLCBmdW5jdGlvbiAobGluZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIF90aGlzLmxlZ2VuZEZpbHRlcihpbmRleCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIER1YWxMaW5lTGF5ZXI7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEdWFsTGluZUxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZHVhbExpbmUnLCBEdWFsTGluZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBHcm91cGVkQ29sdW1uTGluZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cGVkQ29sdW1uTGluZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBHcm91cGVkQ29sdW1uTGluZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBHcm91cGVkQ29sdW1uTGluZS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2dyb3VwZWRDb2x1bW5MaW5lJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEdyb3VwZWRDb2x1bW5MaW5lLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBHcm91cGVkQ29sdW1uTGluZTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdyb3VwZWRDb2x1bW5MaW5lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2NvbHVtbi1saW5lL2xheWVyXCIpKTtcbnZhciBsYXllcl8yID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL3Bsb3RzL2dyb3VwZWQtY29sdW1uL2xheWVyXCIpKTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIGRlZmF1bHRMaW5lQ29uZmlnID0ge1xuICAgIGNvbG9yOiAnI2Y1YmMzMicsXG4gICAgbGluZVNpemU6IDQsXG4gICAgY29ubmVjdE51bGw6IHRydWUsXG4gICAgcG9pbnQ6IHtcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgIHNpemU6IDMsXG4gICAgICAgIHNoYXBlOiAnY2lyY2xlJyxcbiAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIHN0cm9rZTogJyNmZmYnLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgfSxcbn07XG52YXIgZGVmYXVsdENvbHVtbkNvbmZpZyA9IHtcbiAgICBjb2xvcjogWycjNUI4RkY5JywgJyM1QUQ4QTYnLCAnIzVENzA5MicsICcjRjZCRDE2JywgJyNFODY4NEEnLCAnIzZEQzhFQycsICcjOTI3MENBJywgJyNGRjlENEQnLCAnIzI2OUE5OScsICcjRkY5OUMzJ10sXG59O1xudmFyIGRlZmF1bHRZQXhpc0NvbmZpZyA9IHtcbiAgICB2aXNpYmxlOiB0cnVlLFxuICAgIGNvbG9yTWFwcGluZzogdHJ1ZSxcbiAgICBncmlkOiB7XG4gICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgfSxcbiAgICBsaW5lOiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgIH0sXG4gICAgdGlja0xpbmU6IHtcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgfSxcbiAgICBsYWJlbDoge1xuICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgfSxcbiAgICB0aXRsZToge1xuICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgc3BhY2luZzogMTIsXG4gICAgfSxcbn07XG52YXIgR3JvdXBlZENvbHVtbkxpbmVMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cGVkQ29sdW1uTGluZUxheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyb3VwZWRDb2x1bW5MaW5lTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2dyb3VwZWRDb2x1bW5MaW5lJztcbiAgICAgICAgX3RoaXMucmVxdWlyZWRGaWVsZCA9IFsneEZpZWxkJywgJ3lGaWVsZCcsICdjb2x1bW5Hcm91cEZpZWxkJ107XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgR3JvdXBlZENvbHVtbkxpbmVMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICBsZWZ0Q29uZmlnOiB1dGlsXzEuZGVlcE1peCh7fSwgZGVmYXVsdFlBeGlzQ29uZmlnLCB7IGNvbG9yTWFwcGluZzogZmFsc2UgfSksXG4gICAgICAgICAgICAgICAgcmlnaHRDb25maWc6IGRlZmF1bHRZQXhpc0NvbmZpZyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lQ29uZmlnOiBkZWZhdWx0TGluZUNvbmZpZyxcbiAgICAgICAgICAgIGNvbHVtbkNvbmZpZzogZGVmYXVsdENvbHVtbkNvbmZpZyxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEdyb3VwZWRDb2x1bW5MaW5lTGF5ZXIucHJvdG90eXBlLmJlZm9yZUluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHZhciBfYyA9IHRoaXMsIG9wdGlvbnMgPSBfYy5vcHRpb25zLCBpbml0aWFsT3B0aW9ucyA9IF9jLmluaXRpYWxPcHRpb25zO1xuICAgICAgICB2YXIgZ3JvdXBlZFZhbHVlID0gdGhpcy5nZXRWYWx1ZUJ5R3JvdXBGaWVsZCgpO1xuICAgICAgICBpZiAob3B0aW9ucy5saW5lU2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMueUF4aXMucmlnaHRDb25maWcuY29sb3JNYXBwaW5nID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISgoX2EgPSBpbml0aWFsT3B0aW9ucy5saW5lQ29uZmlnKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubGluZVNpemUpKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5saW5lQ29uZmlnLmxpbmVTaXplID0gMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghKChfYiA9IGluaXRpYWxPcHRpb25zLmxpbmVDb25maWcpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jb2xvcikpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2QgPSB0aGVtZV8xLmdldEdsb2JhbFRoZW1lKCksIGNvbG9ycyA9IF9kLmNvbG9ycywgY29sb3JzXzIwID0gX2QuY29sb3JzXzIwO1xuICAgICAgICAgICAgICAgIHZhciBzZXJpZXNWYWx1ZSA9IHRoaXMuZ2V0VmFsdWVCeVNlcmllc0ZpZWxkKCk7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9yU2VyaWVzXzEgPSBzZXJpZXNWYWx1ZS5sZW5ndGggPiBjb2xvcnMubGVuZ3RoID8gY29sb3JzXzIwIDogY29sb3JzO1xuICAgICAgICAgICAgICAgIHZhciBjb2xvclBsYXRlc18xID0gW107XG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0SW5kZXhfMSA9IGdyb3VwZWRWYWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2goc2VyaWVzVmFsdWUsIGZ1bmN0aW9uICh2LCBpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICBjb2xvclBsYXRlc18xLnB1c2goY29sb3JTZXJpZXNfMVtpbmRleCArIHN0YXJ0SW5kZXhfMV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubGluZUNvbmZpZy5jb2xvciA9IGNvbG9yUGxhdGVzXzE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbG9yID0gdGhpcy5vcHRpb25zLmNvbHVtbkNvbmZpZy5jb2xvcjtcbiAgICAgICAgdGhpcy5vcHRpb25zLmNvbHVtbkNvbmZpZy5jb2xvciA9IGNvbG9yLnNsaWNlKDAsIGdyb3VwZWRWYWx1ZS5sZW5ndGgpO1xuICAgIH07XG4gICAgR3JvdXBlZENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuZHJhd0NvbHVtbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBkYXRhID0gX2EuZGF0YSwgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQsIGNvbHVtbkdyb3VwRmllbGQgPSBfYS5jb2x1bW5Hcm91cEZpZWxkLCB4QXhpcyA9IF9hLnhBeGlzLCB0b29sdGlwID0gX2EudG9vbHRpcCwgY29sdW1uQ29uZmlnID0gX2EuY29sdW1uQ29uZmlnLCBldmVudHMgPSBfYS5ldmVudHM7XG4gICAgICAgIHZhciBjb2x1bW4gPSB0aGlzLmNyZWF0ZUxheWVyKGxheWVyXzIuZGVmYXVsdCwgZGF0YVswXSwgdHNsaWJfMS5fX2Fzc2lnbih7IHhGaWVsZDogeEZpZWxkLCB5RmllbGQ6IHlGaWVsZFswXSwgZ3JvdXBGaWVsZDogY29sdW1uR3JvdXBGaWVsZCwgeEF4aXM6IHhBeGlzLCB5QXhpczogdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMueUF4aXMoMCksIHtcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgfSksIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSwgdG9vbHRpcDogdXRpbF8xLmRlZXBNaXgoe30sIHRvb2x0aXAsIHtcbiAgICAgICAgICAgICAgICBzaG93TWFya2VyczogZmFsc2UsXG4gICAgICAgICAgICAgICAgY3VzdG9tOiB7XG4gICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiBmdW5jdGlvbiAoY29udGFpbmVyRG9tLCBldikge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudG9vbHRpcChjb250YWluZXJEb20sIGV2KTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksIGV2ZW50czogZXZlbnRzIH0sIGNvbHVtbkNvbmZpZykpO1xuICAgICAgICBjb2x1bW4ucmVuZGVyKCk7XG4gICAgfTtcbiAgICBHcm91cGVkQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5jdXN0b21MZWdlbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgeUZpZWxkID0gX2EueUZpZWxkLCBsZWdlbmQgPSBfYS5sZWdlbmQ7XG4gICAgICAgIHZhciBjb2xvcnMgPSB0aGlzLmNvbG9ycztcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyLmFkZEdyb3VwKCk7XG4gICAgICAgIHZhciBsZWdlbmRDZmcgPSBsZWdlbmQ7XG4gICAgICAgIHZhciBzeW1ib2xzID0gWydzcXVhcmUnLCAnY2lyY2xlJ107XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZ2VvbUxheWVycywgZnVuY3Rpb24gKGdlb20sIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgbGVnZW5kO1xuICAgICAgICAgICAgaWYgKGdlb20ub3B0aW9ucy5zZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBfdGhpcy5nZXRWYWx1ZUJ5U2VyaWVzRmllbGQoKTtcbiAgICAgICAgICAgICAgICBsZWdlbmQgPSBfdGhpcy5jcmVhdGVOb3JtYWxMZWdlbmQodmFsdWVzLCBzeW1ib2xzW2luZGV4XSwgY29sb3JzW2luZGV4XSwgbGVnZW5kQ2ZnLCBjb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZ2VvbS5vcHRpb25zLmdyb3VwRmllbGQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gX3RoaXMuZ2V0VmFsdWVCeUdyb3VwRmllbGQoKTtcbiAgICAgICAgICAgICAgICBsZWdlbmQgPSBfdGhpcy5jcmVhdGVOb3JtYWxMZWdlbmQodmFsdWVzLCBzeW1ib2xzW2luZGV4XSwgY29sb3JzW2luZGV4XSwgbGVnZW5kQ2ZnLCBjb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGVnZW5kID0gX3RoaXMuY3JlYXRlU2luZ2xlTGVnZW5kKHlGaWVsZFtpbmRleF0sIHN5bWJvbHNbaW5kZXhdLCBjb2xvcnNbaW5kZXhdLCBsZWdlbmRDZmcsIGNvbnRhaW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5sZWdlbmRzLnB1c2gobGVnZW5kKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOS9v+eUqGxlZ2VuZOWBmuWbvuWxguetm+mAiVxuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmdlb21MYXllcnMsIGZ1bmN0aW9uIChnZW9tLCBpbmRleCkge1xuICAgICAgICAgICAgaWYgKGdlb20ub3B0aW9ucy5zZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgICAgIF90aGlzLm11bHRpcGxlTGVnZW5kRmlsdGVyKGluZGV4LCBnZW9tLm9wdGlvbnMuc2VyaWVzRmllbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZ2VvbS5vcHRpb25zLmdyb3VwRmllbGQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5tdWx0aXBsZUxlZ2VuZEZpbHRlcihpbmRleCwgZ2VvbS5vcHRpb25zLmdyb3VwRmllbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgX3RoaXMubGVnZW5kRmlsdGVyKGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBHcm91cGVkQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5nZXRWYWx1ZUJ5R3JvdXBGaWVsZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBjb2x1bW5Hcm91cEZpZWxkID0gX2EuY29sdW1uR3JvdXBGaWVsZCwgZGF0YSA9IF9hLmRhdGE7XG4gICAgICAgIHZhciBjb2x1bW5EYXRhID0gZGF0YVswXTtcbiAgICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChjb2x1bW5EYXRhLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdmFyIHYgPSBkW2NvbHVtbkdyb3VwRmllbGRdO1xuICAgICAgICAgICAgaWYgKCF1dGlsXzEuY29udGFpbnModmFsdWVzLCB2KSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9O1xuICAgIEdyb3VwZWRDb2x1bW5MaW5lTGF5ZXIucHJvdG90eXBlLmdldE1vY2tEYXRhID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQsIGNvbHVtbkdyb3VwRmllbGQgPSBfYS5jb2x1bW5Hcm91cEZpZWxkO1xuICAgICAgICB2YXIgbW9ja0EgPSB7fTtcbiAgICAgICAgbW9ja0FbeEZpZWxkXSA9ICdudWxsXzEnO1xuICAgICAgICBtb2NrQVt5RmllbGRbaW5kZXhdXSA9IDA7XG4gICAgICAgIG1vY2tBW2NvbHVtbkdyb3VwRmllbGRdID0gJ251bGxfYSc7XG4gICAgICAgIHZhciBtb2NrQiA9IHt9O1xuICAgICAgICBtb2NrQlt4RmllbGRdID0gJ251bGxfMSc7XG4gICAgICAgIG1vY2tCW3lGaWVsZFtpbmRleF1dID0gMTtcbiAgICAgICAgbW9ja0JbY29sdW1uR3JvdXBGaWVsZF0gPSAnbnVsbF9hJztcbiAgICAgICAgcmV0dXJuIFttb2NrQSwgbW9ja0JdO1xuICAgIH07XG4gICAgcmV0dXJuIEdyb3VwZWRDb2x1bW5MaW5lTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JvdXBlZENvbHVtbkxpbmVMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ2dyb3VwZWRDb2x1bW5MaW5lJywgR3JvdXBlZENvbHVtbkxpbmVMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgU3RhY2tlZENvbHVtbkxpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZENvbHVtbkxpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tlZENvbHVtbkxpbmUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgU3RhY2tlZENvbHVtbkxpbmUucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdzdGFja2VkQ29sdW1uTGluZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBTdGFja2VkQ29sdW1uTGluZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gU3RhY2tlZENvbHVtbkxpbmU7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGFja2VkQ29sdW1uTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9jb2x1bW4tbGluZS9sYXllclwiKSk7XG52YXIgbGF5ZXJfMiA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9wbG90cy9zdGFja2VkLWNvbHVtbi9sYXllclwiKSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciBkZWZhdWx0TGluZUNvbmZpZyA9IHtcbiAgICBjb2xvcjogJyNmNWJjMzInLFxuICAgIGxpbmVTaXplOiA0LFxuICAgIGNvbm5lY3ROdWxsOiB0cnVlLFxuICAgIHBvaW50OiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICBzaXplOiAzLFxuICAgICAgICBzaGFwZTogJ2NpcmNsZScsXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICBzdHJva2U6ICcjZmZmJyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIGxhYmVsOiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgIH0sXG59O1xudmFyIGRlZmF1bHRDb2x1bW5Db25maWcgPSB7XG4gICAgY29sb3I6IFsnIzVCOEZGOScsICcjNUFEOEE2JywgJyM1RDcwOTInLCAnI0Y2QkQxNicsICcjRTg2ODRBJywgJyM2REM4RUMnLCAnIzkyNzBDQScsICcjRkY5RDREJywgJyMyNjlBOTknLCAnI0ZGOTlDMyddLFxufTtcbnZhciBkZWZhdWx0WUF4aXNDb25maWcgPSB7XG4gICAgdmlzaWJsZTogdHJ1ZSxcbiAgICBjb2xvck1hcHBpbmc6IHRydWUsXG4gICAgZ3JpZDoge1xuICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgIH0sXG4gICAgbGluZToge1xuICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICB9LFxuICAgIHRpY2tMaW5lOiB7XG4gICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgIGF1dG9Sb3RhdGU6IGZhbHNlLFxuICAgIH0sXG4gICAgdGl0bGU6IHtcbiAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgIHNwYWNpbmc6IDEyLFxuICAgIH0sXG59O1xudmFyIFN0YWNrZWRDb2x1bW5MaW5lTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZENvbHVtbkxpbmVMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkQ29sdW1uTGluZUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdncm91cGVkQ29sdW1uTGluZSc7XG4gICAgICAgIF90aGlzLnJlcXVpcmVkRmllbGQgPSBbJ3hGaWVsZCcsICd5RmllbGQnLCAnY29sdW1uU3RhY2tGaWVsZCddO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFN0YWNrZWRDb2x1bW5MaW5lTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgbGVmdENvbmZpZzogdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRZQXhpc0NvbmZpZywgeyBjb2xvck1hcHBpbmc6IGZhbHNlIH0pLFxuICAgICAgICAgICAgICAgIHJpZ2h0Q29uZmlnOiBkZWZhdWx0WUF4aXNDb25maWcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZUNvbmZpZzogZGVmYXVsdExpbmVDb25maWcsXG4gICAgICAgICAgICBjb2x1bW5Db25maWc6IGRlZmF1bHRDb2x1bW5Db25maWcsXG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBTdGFja2VkQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5iZWZvcmVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICB2YXIgc3RhY2tlZFZhbHVlID0gdGhpcy5nZXRWYWx1ZUJ5U3RhY2tGaWVsZCgpO1xuICAgICAgICB2YXIgX2MgPSB0aGlzLCBvcHRpb25zID0gX2Mub3B0aW9ucywgaW5pdGlhbE9wdGlvbnMgPSBfYy5pbml0aWFsT3B0aW9ucztcbiAgICAgICAgaWYgKG9wdGlvbnMubGluZVNlcmllc0ZpZWxkKSB7XG4gICAgICAgICAgICBvcHRpb25zLnlBeGlzLnJpZ2h0Q29uZmlnLmNvbG9yTWFwcGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKCEoKF9hID0gaW5pdGlhbE9wdGlvbnMubGluZUNvbmZpZykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmxpbmVTaXplKSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubGluZUNvbmZpZy5saW5lU2l6ZSA9IDM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISgoX2IgPSBpbml0aWFsT3B0aW9ucy5saW5lQ29uZmlnKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9kID0gdGhlbWVfMS5nZXRHbG9iYWxUaGVtZSgpLCBjb2xvcnMgPSBfZC5jb2xvcnMsIGNvbG9yc18yMCA9IF9kLmNvbG9yc18yMDtcbiAgICAgICAgICAgICAgICB2YXIgc2VyaWVzVmFsdWUgPSB0aGlzLmdldFZhbHVlQnlTZXJpZXNGaWVsZCgpO1xuICAgICAgICAgICAgICAgIHZhciBjb2xvclNlcmllc18xID0gc2VyaWVzVmFsdWUubGVuZ3RoID4gY29sb3JzLmxlbmd0aCA/IGNvbG9yc18yMCA6IGNvbG9ycztcbiAgICAgICAgICAgICAgICB2YXIgY29sb3JQbGF0ZXNfMSA9IFtdO1xuICAgICAgICAgICAgICAgIHZhciBzdGFydEluZGV4XzEgPSBzdGFja2VkVmFsdWUubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKHNlcmllc1ZhbHVlLCBmdW5jdGlvbiAodiwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sb3JQbGF0ZXNfMS5wdXNoKGNvbG9yU2VyaWVzXzFbaW5kZXggKyBzdGFydEluZGV4XzFdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmxpbmVDb25maWcuY29sb3IgPSBjb2xvclBsYXRlc18xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBjb2xvciA9IHRoaXMub3B0aW9ucy5jb2x1bW5Db25maWcuY29sb3I7XG4gICAgICAgIHRoaXMub3B0aW9ucy5jb2x1bW5Db25maWcuY29sb3IgPSBjb2xvci5zbGljZSgwLCBzdGFja2VkVmFsdWUubGVuZ3RoKTtcbiAgICB9O1xuICAgIFN0YWNrZWRDb2x1bW5MaW5lTGF5ZXIucHJvdG90eXBlLmRyYXdDb2x1bW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgZGF0YSA9IF9hLmRhdGEsIHhGaWVsZCA9IF9hLnhGaWVsZCwgeUZpZWxkID0gX2EueUZpZWxkLCBjb2x1bW5TdGFja0ZpZWxkID0gX2EuY29sdW1uU3RhY2tGaWVsZCwgeEF4aXMgPSBfYS54QXhpcywgdG9vbHRpcCA9IF9hLnRvb2x0aXAsIGNvbHVtbkNvbmZpZyA9IF9hLmNvbHVtbkNvbmZpZywgZXZlbnRzID0gX2EuZXZlbnRzO1xuICAgICAgICB2YXIgY29sdW1uID0gdGhpcy5jcmVhdGVMYXllcihsYXllcl8yLmRlZmF1bHQsIGRhdGFbMF0sIHRzbGliXzEuX19hc3NpZ24oeyB4RmllbGQ6IHhGaWVsZCwgeUZpZWxkOiB5RmllbGRbMF0sIHN0YWNrRmllbGQ6IGNvbHVtblN0YWNrRmllbGQsIHhBeGlzOiB4QXhpcywgeUF4aXM6IHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLnlBeGlzKDApLCB7XG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbmljZTogdHJ1ZSxcbiAgICAgICAgICAgIH0pLCBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sIHRvb2x0aXA6IHV0aWxfMS5kZWVwTWl4KHt9LCB0b29sdGlwLCB7XG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGN1c3RvbToge1xuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24gKGNvbnRhaW5lckRvbSwgZXYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnRvb2x0aXAoY29udGFpbmVyRG9tLCBldik7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLCBldmVudHM6IGV2ZW50cyB9LCBjb2x1bW5Db25maWcpKTtcbiAgICAgICAgY29sdW1uLnJlbmRlcigpO1xuICAgIH07XG4gICAgU3RhY2tlZENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuY3VzdG9tTGVnZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHlGaWVsZCA9IF9hLnlGaWVsZCwgbGVnZW5kID0gX2EubGVnZW5kO1xuICAgICAgICB2YXIgY29sb3JzID0gdGhpcy5jb2xvcnM7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lci5hZGRHcm91cCgpO1xuICAgICAgICB2YXIgbGVnZW5kQ2ZnID0gbGVnZW5kO1xuICAgICAgICB2YXIgc3ltYm9scyA9IFsnc3F1YXJlJywgJ2NpcmNsZSddO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmdlb21MYXllcnMsIGZ1bmN0aW9uIChnZW9tLCBpbmRleCkge1xuICAgICAgICAgICAgdmFyIGxlZ2VuZDtcbiAgICAgICAgICAgIGlmIChnZW9tLm9wdGlvbnMuc2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gX3RoaXMuZ2V0VmFsdWVCeVNlcmllc0ZpZWxkKCk7XG4gICAgICAgICAgICAgICAgbGVnZW5kID0gX3RoaXMuY3JlYXRlTm9ybWFsTGVnZW5kKHZhbHVlcywgc3ltYm9sc1tpbmRleF0sIGNvbG9yc1tpbmRleF0sIGxlZ2VuZENmZywgY29udGFpbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGdlb20ub3B0aW9ucy5zdGFja0ZpZWxkKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IF90aGlzLmdldFZhbHVlQnlTdGFja0ZpZWxkKCk7XG4gICAgICAgICAgICAgICAgbGVnZW5kID0gX3RoaXMuY3JlYXRlTm9ybWFsTGVnZW5kKHZhbHVlcywgc3ltYm9sc1tpbmRleF0sIGNvbG9yc1tpbmRleF0sIGxlZ2VuZENmZywgY29udGFpbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxlZ2VuZCA9IF90aGlzLmNyZWF0ZVNpbmdsZUxlZ2VuZCh5RmllbGRbaW5kZXhdLCBzeW1ib2xzW2luZGV4XSwgY29sb3JzW2luZGV4XSwgbGVnZW5kQ2ZnLCBjb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMubGVnZW5kcy5wdXNoKGxlZ2VuZCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDkvb/nlKhsZWdlbmTlgZrlm77lsYLnrZvpgIlcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5nZW9tTGF5ZXJzLCBmdW5jdGlvbiAoZ2VvbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmIChnZW9tLm9wdGlvbnMuc2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5tdWx0aXBsZUxlZ2VuZEZpbHRlcihpbmRleCwgZ2VvbS5vcHRpb25zLnNlcmllc0ZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGdlb20ub3B0aW9ucy5zdGFja0ZpZWxkKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMubXVsdGlwbGVMZWdlbmRGaWx0ZXIoaW5kZXgsIGdlb20ub3B0aW9ucy5zdGFja0ZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIF90aGlzLmxlZ2VuZEZpbHRlcihpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU3RhY2tlZENvbHVtbkxpbmVMYXllci5wcm90b3R5cGUuZ2V0VmFsdWVCeVN0YWNrRmllbGQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgY29sdW1uU3RhY2tGaWVsZCA9IF9hLmNvbHVtblN0YWNrRmllbGQsIGRhdGEgPSBfYS5kYXRhO1xuICAgICAgICB2YXIgY29sdW1uRGF0YSA9IGRhdGFbMF07XG4gICAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2goY29sdW1uRGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciB2ID0gZFtjb2x1bW5TdGFja0ZpZWxkXTtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmNvbnRhaW5zKHZhbHVlcywgdikpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCh2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfTtcbiAgICBTdGFja2VkQ29sdW1uTGluZUxheWVyLnByb3RvdHlwZS5nZXRVbkNoZWNrZWRWYWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMubGVnZW5kcywgZnVuY3Rpb24gKGxlZ2VuZCkge1xuICAgICAgICAgICAgdmFyIHVuY2hlY2tlZEl0ZW1zID0gbGVnZW5kLmdldEl0ZW1zQnlTdGF0ZSgndW5jaGVja2VkJyk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaCh1bmNoZWNrZWRJdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICB2YWx1ZS5wdXNoKGl0ZW0ubmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuICAgIFN0YWNrZWRDb2x1bW5MaW5lTGF5ZXIucHJvdG90eXBlLmdldE1vY2tEYXRhID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQsIGNvbHVtblN0YWNrRmllbGQgPSBfYS5jb2x1bW5TdGFja0ZpZWxkO1xuICAgICAgICB2YXIgbW9ja0EgPSB7fTtcbiAgICAgICAgbW9ja0FbeEZpZWxkXSA9ICdudWxsXzEnO1xuICAgICAgICBtb2NrQVt5RmllbGRbaW5kZXhdXSA9IDA7XG4gICAgICAgIG1vY2tBW2NvbHVtblN0YWNrRmllbGRdID0gJ251bGxfYSc7XG4gICAgICAgIHZhciBtb2NrQiA9IHt9O1xuICAgICAgICBtb2NrQlt4RmllbGRdID0gJ251bGxfMSc7XG4gICAgICAgIG1vY2tCW3lGaWVsZFtpbmRleF1dID0gMTtcbiAgICAgICAgbW9ja0JbY29sdW1uU3RhY2tGaWVsZF0gPSAnbnVsbF9hJztcbiAgICAgICAgcmV0dXJuIFttb2NrQSwgbW9ja0JdO1xuICAgIH07XG4gICAgcmV0dXJuIFN0YWNrZWRDb2x1bW5MaW5lTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tlZENvbHVtbkxpbmVMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3N0YWNrZWRDb2x1bW5MaW5lJywgU3RhY2tlZENvbHVtbkxpbmVMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGZvcm1hdHRlcl8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZm9ybWF0dGVyXCIpO1xuZnVuY3Rpb24gcHJvcGVydHlNYXBwaW5nKHNvdXJjZSwgdGFyZ2V0LCBmaWVsZCkge1xuICAgIGlmIChzb3VyY2VbZmllbGRdKSB7XG4gICAgICAgIHRhcmdldFtmaWVsZF0gPSBzb3VyY2VbZmllbGRdO1xuICAgIH1cbn1cbnZhciBBeGlzUGFyc2VyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEF4aXNQYXJzZXIoY2ZnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gZmFsc2U7XG4gICAgICAgIHRoaXMucGxvdCA9IGNmZy5wbG90O1xuICAgICAgICB0aGlzLmRpbSA9IGNmZy5kaW07XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cbiAgICBBeGlzUGFyc2VyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGZhbHNlO1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnBsb3QuZ2V0UGxvdFRoZW1lKCk7XG4gICAgICAgIHRoaXMudGhlbWVDb25maWcgPSB0aGVtZSAmJiB0aGVtZS5heGlzICYmIHRoZW1lLmF4aXNbdGhpcy5kaW1dO1xuICAgICAgICBpZiAodGhpcy5fbmVlZERyYXcoKSkge1xuICAgICAgICAgICAgdGhpcy5fc3R5bGVQYXJzZXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQXhpc1BhcnNlci5wcm90b3R5cGUuX3N0eWxlUGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMubG9jYWxQcm9wcyk7XG4gICAgICAgIHRoaXMuX2lzVmlzaWJsZSgnbGluZScpID8gdGhpcy5fbGluZVBhcnNlcigpIDogKHRoaXMuY29uZmlnLmxpbmUgPSBudWxsKTtcbiAgICAgICAgdGhpcy5faXNWaXNpYmxlKCdncmlkJykgPyB0aGlzLl9ncmlkUGFyc2VyKCkgOiAodGhpcy5jb25maWcuZ3JpZCA9IG51bGwpO1xuICAgICAgICB0aGlzLl9pc1Zpc2libGUoJ3RpY2tMaW5lJykgPyB0aGlzLl90aWNrTGluZVBhcnNlcigpIDogKHRoaXMuY29uZmlnLnRpY2tMaW5lID0gbnVsbCk7XG4gICAgICAgIHRoaXMuX2lzVmlzaWJsZSgnbGFiZWwnKSA/IHRoaXMuX2xhYmVsUGFyc2VyKCkgOiAodGhpcy5jb25maWcubGFiZWwgPSBudWxsKTtcbiAgICAgICAgdGhpcy5faXNWaXNpYmxlKCd0aXRsZScpID8gdGhpcy5fdGl0bGVQYXJzZXIoKSA6ICh0aGlzLmNvbmZpZy50aXRsZSA9IG51bGwpO1xuICAgICAgICBwcm9wZXJ0eU1hcHBpbmcodGhpcy5sb2NhbFByb3BzLCB0aGlzLmNvbmZpZywgJ2F1dG9IaWRlTGFiZWwnKTtcbiAgICAgICAgcHJvcGVydHlNYXBwaW5nKHRoaXMubG9jYWxQcm9wcywgdGhpcy5jb25maWcsICdhdXRvUm90YXRlTGFiZWwnKTtcbiAgICAgICAgcHJvcGVydHlNYXBwaW5nKHRoaXMubG9jYWxQcm9wcywgdGhpcy5jb25maWcsICdhdXRvUm90YXRlVGl0bGUnKTtcbiAgICB9O1xuICAgIEF4aXNQYXJzZXIucHJvdG90eXBlLl9uZWVkRHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLyoqIOWmguaenOWcqOWbvuihqOmFjee9rumhuemHjOayoeacieiuvue9ruWdkOagh+i9tOaVtOS9k+eahHZpc2liaWxpdHnliJnljrvlr7nlupTnmoR0aGVtZeWPliAqL1xuICAgICAgICB2YXIgcHJvcG9zID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHZhciBwcm9wc0NvbmZpZyA9IHByb3Bvc1t0aGlzLmRpbSArIFwiQXhpc1wiXSA/IHByb3Bvc1t0aGlzLmRpbSArIFwiQXhpc1wiXSA6IHt9O1xuICAgICAgICB2YXIgY29uZmlnID0gdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMudGhlbWVDb25maWcsIHByb3BzQ29uZmlnKTtcbiAgICAgICAgdGhpcy5sb2NhbFByb3BzID0gY29uZmlnO1xuICAgICAgICBpZiAoY29uZmlnLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEF4aXNQYXJzZXIucHJvdG90eXBlLl9saW5lUGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbmZpZy5saW5lID0gdGhpcy5sb2NhbFByb3BzLmxpbmU7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsUHJvcHMubGluZS5zdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcubGluZSA9IHsgc3R5bGU6IHRoaXMubG9jYWxQcm9wcy5saW5lLnN0eWxlIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hcHBseVRoZW1lQ29uZmlnKCdsaW5lJyk7XG4gICAgfTtcbiAgICBBeGlzUGFyc2VyLnByb3RvdHlwZS5fZ3JpZFBhcnNlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hLCBfYiwgX2MsIF9kLCBfZTtcbiAgICAgICAgdmFyIHN0eWxlID0gKF9iID0gKF9hID0gdGhpcy5sb2NhbFByb3BzLmdyaWQpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5saW5lKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Iuc3R5bGU7XG4gICAgICAgIHZhciB0eXBlID0gKF9kID0gKF9jID0gdGhpcy5sb2NhbFByb3BzLmdyaWQpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5saW5lKSA9PT0gbnVsbCB8fCBfZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2QudHlwZTtcbiAgICAgICAgdmFyIGFsdGVybmF0ZUNvbG9yID0gKF9lID0gdGhpcy5sb2NhbFByb3BzLmdyaWQpID09PSBudWxsIHx8IF9lID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZS5hbHRlcm5hdGVDb2xvcjtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHN0eWxlKSkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuZ3JpZCA9IGZ1bmN0aW9uICh0ZXh0LCBpbmRleCwgY291bnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgY2ZnID0gc3R5bGUodGV4dCwgaW5kZXgsIGNvdW50KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHV0aWxfMS5kZWVwTWl4KHt9LCB1dGlsXzEuZ2V0KF90aGlzLnRoZW1lQ29uZmlnLCBcImdyaWQubGluZS5zdHlsZVwiKSwgY2ZnKSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgYWx0ZXJuYXRlQ29sb3I6IGFsdGVybmF0ZUNvbG9yLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5ncmlkID0ge1xuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYWx0ZXJuYXRlQ29sb3I6IGFsdGVybmF0ZUNvbG9yLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlUaGVtZUNvbmZpZygnZ3JpZCcpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBeGlzUGFyc2VyLnByb3RvdHlwZS5fdGlja0xpbmVQYXJzZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLnRpY2tMaW5lID0gdGhpcy5sb2NhbFByb3BzLnRpY2tMaW5lO1xuICAgICAgICBpZiAodGhpcy5sb2NhbFByb3BzLnRpY2tMaW5lLnN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy50aWNrTGluZSA9IHsgc3R5bGU6IHRoaXMubG9jYWxQcm9wcy50aWNrTGluZS5zdHlsZSB9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYXBwbHlUaGVtZUNvbmZpZygndGlja0xpbmUnKTtcbiAgICB9O1xuICAgIEF4aXNQYXJzZXIucHJvdG90eXBlLl9sYWJlbFBhcnNlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5sb2NhbFByb3BzLmxhYmVsLCBzdHlsZSA9IF9hLnN0eWxlLCByZXN0TGFiZWxQcm9wcyA9IHRzbGliXzEuX19yZXN0KF9hLCBbXCJzdHlsZVwiXSk7XG4gICAgICAgIHZhciBsYWJlbENvbmZpZyA9IHRzbGliXzEuX19hc3NpZ24oe30sIHJlc3RMYWJlbFByb3BzKTtcbiAgICAgICAgaWYgKHN0eWxlKSB7XG4gICAgICAgICAgICBsYWJlbENvbmZpZy5zdHlsZSA9IHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMubG9jYWxQcm9wcy5sYWJlbC5zdHlsZSk7XG4gICAgICAgIH1cbiAgICAgICAgbGFiZWxDb25maWcuc3R5bGUgPSB1dGlsXzEuZGVlcE1peCh7fSwgdXRpbF8xLmdldCh0aGlzLnRoZW1lQ29uZmlnLCAnbGFiZWwuc3R5bGUnKSwgbGFiZWxDb25maWcuc3R5bGUpO1xuICAgICAgICB2YXIgZm9ybWF0dGVyID0gdGhpcy5wYXJzZUZvcm1hdHRlcihsYWJlbENvbmZpZyk7XG4gICAgICAgIGxhYmVsQ29uZmlnLmZvcm1hdHRlciA9IGZvcm1hdHRlcjtcbiAgICAgICAgdGhpcy5jb25maWcubGFiZWwgPSBsYWJlbENvbmZpZztcbiAgICB9O1xuICAgIEF4aXNQYXJzZXIucHJvdG90eXBlLl90aXRsZVBhcnNlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpdGxlQ29uZmlnID0gdHNsaWJfMS5fX2Fzc2lnbih7fSwgdGhpcy5sb2NhbFByb3BzLnRpdGxlKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5sb2NhbFByb3BzLnRpdGxlLCB2aXNpYmxlID0gX2EudmlzaWJsZSwgc3R5bGUgPSBfYS5zdHlsZSwgdGV4dCA9IF9hLnRleHQ7XG4gICAgICAgIGlmICghdmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuc2hvd1RpdGxlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5zaG93VGl0bGUgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHN0eWxlKSB7XG4gICAgICAgICAgICAgICAgdGl0bGVDb25maWcuc3R5bGUgPSBzdHlsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRpdGxlQ29uZmlnLnN0eWxlID0gdXRpbF8xLmRlZXBNaXgoe30sIHV0aWxfMS5nZXQodGhpcy5jb25maWcsICd0aXRsZS5zdHlsZScpLCB0aXRsZUNvbmZpZy50ZXh0U3R5bGUpO1xuICAgICAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICAgICAgICB0aXRsZUNvbmZpZy50ZXh0ID0gdGV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbmZpZy50aXRsZSA9IHRpdGxlQ29uZmlnO1xuICAgIH07XG4gICAgQXhpc1BhcnNlci5wcm90b3R5cGUuX2lzVmlzaWJsZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsUHJvcHNbbmFtZV0gJiYgdGhpcy5sb2NhbFByb3BzW25hbWVdLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEF4aXNQYXJzZXIucHJvdG90eXBlLmFwcGx5VGhlbWVDb25maWcgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICB0aGlzLmNvbmZpZ1t0eXBlXSA9IHV0aWxfMS5kZWVwTWl4KHt9LCB1dGlsXzEuZ2V0KHRoaXMudGhlbWVDb25maWcsIHR5cGUgKyBcIi5zdHlsZVwiKSwgdGhpcy5jb25maWdbdHlwZV0pO1xuICAgIH07XG4gICAgQXhpc1BhcnNlci5wcm90b3R5cGUucGFyc2VGb3JtYXR0ZXIgPSBmdW5jdGlvbiAobGFiZWxDb25maWcpIHtcbiAgICAgICAgdmFyIGZvcm1hdHRlciA9IGZvcm1hdHRlcl8xLmNvbWJpbmVGb3JtYXR0ZXIoZm9ybWF0dGVyXzEuZ2V0Tm9vcEZvcm1hdHRlcigpLCBmb3JtYXR0ZXJfMS5nZXRQcmVjaXNpb25Gb3JtYXR0ZXIobGFiZWxDb25maWcucHJlY2lzaW9uKSwgZm9ybWF0dGVyXzEuZ2V0U3VmZml4Rm9ybWF0dGVyKGxhYmVsQ29uZmlnLnN1ZmZpeCkpO1xuICAgICAgICBpZiAobGFiZWxDb25maWcuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZXIgPSBmb3JtYXR0ZXJfMS5jb21iaW5lRm9ybWF0dGVyKGZvcm1hdHRlciwgbGFiZWxDb25maWcuZm9ybWF0dGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybWF0dGVyO1xuICAgIH07XG4gICAgcmV0dXJuIEF4aXNQYXJzZXI7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXhpc1BhcnNlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhcnNlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8vIGltcG9ydCB7IGNvbXBhcmUgfSBmcm9tICcuLi8uLi9iYXNlL2NvbnRyb2xsZXIvc3RhdGUnO1xuLy8g5a+5YXhpcyBsYWJlbOWSjGxhYmVs5qC35byP6L+b6KGM57yT5a2YXG52YXIgbGFiZWxzO1xudmFyIG9yaWdpbkF0dHJzO1xuZnVuY3Rpb24gb25BY3RpdmUocGxvdCwgY29uZGl0aW9uKSB7XG4gICAgaWYgKCFsYWJlbHMpIHtcbiAgICAgICAgZ2V0QWxsQXhpc0xhYmVscyhwbG90KTtcbiAgICB9XG4gICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgdmFyIF9hID0gYmVmb3JlQ29tcGFyZShsYWJlbCwgY29uZGl0aW9uKSwgbGFiZWxEYXRhID0gX2EubGFiZWxEYXRhLCBjb24gPSBfYS5jb247XG4gICAgICAgIGlmIChjb21wYXJlKGxhYmVsRGF0YSwgY29uKSkge1xuICAgICAgICAgICAgdmFyIGRpc2FibGVTdHlsZSA9IGxhYmVsQWN0aXZlU3R5bGUoKTtcbiAgICAgICAgICAgIGxhYmVsLnNoYXBlLmF0dHIoZGlzYWJsZVN0eWxlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gb25EaXNhYmxlKHBsb3QsIGNvbmRpdGlvbikge1xuICAgIGlmICghbGFiZWxzKSB7XG4gICAgICAgIGdldEFsbEF4aXNMYWJlbHMocGxvdCk7XG4gICAgfVxuICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsLCBpbmRleCkge1xuICAgICAgICB2YXIgX2EgPSBiZWZvcmVDb21wYXJlKGxhYmVsLCBjb25kaXRpb24pLCBsYWJlbERhdGEgPSBfYS5sYWJlbERhdGEsIGNvbiA9IF9hLmNvbjtcbiAgICAgICAgaWYgKGNvbXBhcmUobGFiZWxEYXRhLCBjb24pKSB7XG4gICAgICAgICAgICB2YXIgb3JpZ2luQXR0ciA9IG9yaWdpbkF0dHJzW2luZGV4XTtcbiAgICAgICAgICAgIHZhciBkaXNhYmxlU3R5bGUgPSBsYWJlbERpc2FibGVTdHlsZShvcmlnaW5BdHRyKTtcbiAgICAgICAgICAgIGxhYmVsLnNoYXBlLmF0dHIoZGlzYWJsZVN0eWxlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gZ2V0QWxsQXhpc0xhYmVscyhwbG90KSB7XG4gICAgdmFyIF9hO1xuICAgIGxhYmVscyA9IFtdO1xuICAgIG9yaWdpbkF0dHJzID0gW107XG4gICAgdmFyIGF4ZXMgPSAoX2EgPSBwbG90LnZpZXcuZ2V0Q29udHJvbGxlcignYXhpcycpKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZ2V0Q29tcG9uZW50cygpO1xuICAgIHV0aWxfMS5lYWNoKGF4ZXMsIGZ1bmN0aW9uIChheGlzQ29tcG9uZW50T3B0aW9uKSB7XG4gICAgICAgIHZhciBheGlzID0gYXhpc0NvbXBvbmVudE9wdGlvbi5jb21wb25lbnQ7XG4gICAgICAgIHZhciBsYWJlbEFyciA9IFtdO1xuICAgICAgICB2YXIgc2NhbGUgPSBnZXRTY2FsZShwbG90LCBheGlzKTtcbiAgICAgICAgdmFyIGxhYmVsU2hhcGVzID0gYXhpcy5nZXQoJ2xhYmVsUmVuZGVyZXInKS5nZXQoJ2dyb3VwJykuZ2V0KCdjaGlsZHJlbicpO1xuICAgICAgICB1dGlsXzEuZWFjaChsYWJlbFNoYXBlcywgZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgICAgICBpZiAoc2hhcGUudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxBcnIucHVzaCh7IHNoYXBlOiBzaGFwZSB9KTtcbiAgICAgICAgICAgICAgICBvcmlnaW5BdHRycy5wdXNoKHNoYXBlLmF0dHIoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoc2NhbGUpIHtcbiAgICAgICAgICAgIC8vIOWPluWIsHNjYWxlIHZhbHVlc+S9nOS4uuWOn+Wni+aVsOaNru+8jOmBv+WFjeiiq2xhYmVsIGZvcm1hdOeahOW9seWTjVxuICAgICAgICAgICAgdmFyIHRpY2tzXzEgPSBzY2FsZS50aWNrcywgZmllbGRfMSA9IHNjYWxlLmZpZWxkO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxBcnIsIGZ1bmN0aW9uIChsYWJlbCwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBsYWJlbC52YWx1ZSA9IHRpY2tzXzFbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGxhYmVsLnNjYWxlRmllbGQgPSBmaWVsZF8xO1xuICAgICAgICAgICAgICAgIGxhYmVsLnR5cGUgPSBzY2FsZS50eXBlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgbGFiZWxzLnB1c2guYXBwbHkobGFiZWxzLCBsYWJlbEFycik7XG4gICAgfSk7XG59XG4vLyDojrflj5blnZDmoIfovbTlr7nlupTnmoRzY2FsZVxuZnVuY3Rpb24gZ2V0U2NhbGUocGxvdCwgYXhpcykge1xuICAgIHZhciBwcm9wcyA9IHBsb3Qub3B0aW9ucztcbiAgICB2YXIgZGltID0gJ3knO1xuICAgIHZhciBwb3NpdGlvbiA9IGF4aXMuZ2V0KCdwb3NpdGlvbicpO1xuICAgIGlmIChwb3NpdGlvbiA9PT0gJ2JvdHRvbScgfHwgcG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICAgIGRpbSA9ICd4JztcbiAgICB9XG4gICAgdmFyIHNjYWxlRmllbGQgPSBwcm9wc1tkaW0gKyBcIkZpZWxkXCJdO1xuICAgIHJldHVybiBwbG90LnZpZXcuZ2V0KCdzY2FsZXMnKVtzY2FsZUZpZWxkXTtcbn1cbmZ1bmN0aW9uIGJlZm9yZUNvbXBhcmUobGFiZWwsIGNvbmRpdGlvbikge1xuICAgIHZhciBfYTtcbiAgICB2YXIgbGFiZWxEYXRhID0gKF9hID0ge30sIF9hW2xhYmVsLnNjYWxlRmllbGRdID0gbGFiZWwudmFsdWUsIF9hKTtcbiAgICB2YXIgY29uID0gdXRpbF8xLmNsb25lKGNvbmRpdGlvbik7XG4gICAgaWYgKGxhYmVsLnR5cGUgPT09ICd0aW1lJyAmJiB1dGlsXzEuaXNPYmplY3QoY29uZGl0aW9uKSAmJiAhdXRpbF8xLmlzRnVuY3Rpb24oY29uLmV4cCkpIHtcbiAgICAgICAgY29uLmV4cCA9IG5ldyBEYXRlKGNvbi5leHApLmdldFRpbWUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgbGFiZWxEYXRhOiBsYWJlbERhdGEsIGNvbjogY29uIH07XG59XG5mdW5jdGlvbiBsYWJlbERpc2FibGVTdHlsZShzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IG9wYWNpdHk6IG9wYWNpdHkgKiAwLjIgfTtcbn1cbmZ1bmN0aW9uIGxhYmVsQWN0aXZlU3R5bGUoKSB7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogMSwgZm9udFdlaWdodDogNjAwLCBmaWxsOiAncmVkJyB9O1xufVxuZnVuY3Rpb24gY29tcGFyZShvcmlnaW4sIGNvbmRpdGlvbikge1xuICAgIGlmICghdXRpbF8xLmlzRnVuY3Rpb24oY29uZGl0aW9uKSkge1xuICAgICAgICB2YXIgbmFtZV8xID0gY29uZGl0aW9uLm5hbWUsIGV4cCA9IGNvbmRpdGlvbi5leHA7XG4gICAgICAgIGlmICghb3JpZ2luW25hbWVfMV0pIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24oZXhwKSkge1xuICAgICAgICAgICAgcmV0dXJuIGV4cChvcmlnaW5bbmFtZV8xXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbltuYW1lXzFdID09PSBleHA7XG4gICAgfVxuICAgIHJldHVybiBjb25kaXRpb24ob3JpZ2luKTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICBhY3RpdmU6IG9uQWN0aXZlLFxuICAgIHNlbGVjdGVkOiBvbkFjdGl2ZSxcbiAgICBkaXNhYmxlOiBvbkRpc2FibGUsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBldmVudF9lbWl0dGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiQGFudHYvZXZlbnQtZW1pdHRlclwiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIOe7hOS7tuWfuuexu1xuICpcbiAqICDliJvlu7rlkozmuLLmn5NcbiAqICAtIDEuIG5ldyBDb21wb25lbnQoKVxuICogIC0gMi4gaW5pdCgpXG4gKiAgLSAyLiByZW5kZXIoKVxuICogIOabtOaWsFxuICogIC0gMS4gdXBkYXRlKClcbiAqICAtIDIuIHJlbmRlcigpXG4gKlxuICovXG52YXIgQmFzZUNvbXBvbmVudCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhCYXNlQ29tcG9uZW50LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhc2VDb21wb25lbnQoY29uZmlnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmNvbnRhaW5lciA9IGNvbmZpZy5jb250YWluZXI7XG4gICAgICAgIF90aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICBfdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIF90aGlzLmRpc3Bvc2FibGVzID0gW107XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQmFzZUNvbXBvbmVudC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmdyb3VwKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRHcm91cCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5pdENvbmZpZyh0aGlzLmNvbmZpZyk7XG4gICAgfTtcbiAgICBCYXNlQ29tcG9uZW50LnByb3RvdHlwZS5nZXRHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JvdXA7XG4gICAgfTtcbiAgICBCYXNlQ29tcG9uZW50LnByb3RvdHlwZS5nZXRDb25maWcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZztcbiAgICB9O1xuICAgIEJhc2VDb21wb25lbnQucHJvdG90eXBlLmdldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEdyb3VwKCkuZ2V0QkJveCgpO1xuICAgIH07XG4gICAgQmFzZUNvbXBvbmVudC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZ3JvdXAuY2xlYXIoKTtcbiAgICB9O1xuICAgIEJhc2VDb21wb25lbnQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5ncm91cC5jbGVhcigpO1xuICAgICAgICB0aGlzLnJlbmRlcklubmVyKHRoaXMuZ3JvdXApO1xuICAgICAgICB0aGlzLmdldENhbnZhcygpLmRyYXcoKTtcbiAgICB9O1xuICAgIEJhc2VDb21wb25lbnQucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMuY29uZmlnKSwgY29uZmlnKTtcbiAgICAgICAgdGhpcy5pbml0Q29uZmlnKHRoaXMuY29uZmlnKTtcbiAgICB9O1xuICAgIEJhc2VDb21wb25lbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZGlzcG9zYWJsZXMsIGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGlzcG9zYWJsZXMgPSBbXTtcbiAgICAgICAgdGhpcy5ncm91cC5yZW1vdmUodHJ1ZSk7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9O1xuICAgIEJhc2VDb21wb25lbnQucHJvdG90eXBlLmluaXRHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5ncm91cCA9IHRoaXMuY29udGFpbmVyLmFkZEdyb3VwKCk7XG4gICAgfTtcbiAgICBCYXNlQ29tcG9uZW50LnByb3RvdHlwZS5nZXRDYW52YXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5nZXQoJ2NhbnZhcycpO1xuICAgIH07XG4gICAgQmFzZUNvbXBvbmVudC5wcm90b3R5cGUuYWRkRGlzcG9zYWJsZSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICB0aGlzLmRpc3Bvc2FibGVzLnB1c2goZm4pO1xuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEJhc2VDb21wb25lbnQucHJvdG90eXBlLmluaXRDb25maWcgPSBmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIHJldHVybiBCYXNlQ29tcG9uZW50O1xufShldmVudF9lbWl0dGVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQmFzZUNvbXBvbmVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbnZhciBnX3V0aWxfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2ctdXRpbFwiKTtcbnZhciBCcmVhZGNydW1iID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJyZWFkY3J1bWIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQnJlYWRjcnVtYigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmxpc3RlbmVycyA9IFtdO1xuICAgICAgICBfdGhpcy5vbkl0ZW1Hcm91cFRvZ2dsZUFjdGl2ZSA9IGZ1bmN0aW9uIChpdGVtR3JvdXAsIGFjdGl2ZSkgeyByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHJlY3RTaGFwZSA9IGl0ZW1Hcm91cC5nZXQoJ2NoaWxkcmVuJykuZmluZChmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbS5nZXQoJ2NsYXNzJykgPT09ICdpdGVtLWJhY2tncm91bmQnOyB9KTtcbiAgICAgICAgICAgIGlmIChyZWN0U2hhcGUpIHtcbiAgICAgICAgICAgICAgICByZWN0U2hhcGUuYXR0cihhY3RpdmUgPyBfdGhpcy5pdGVtQWN0aXZlQmFja2dyb3VuZFN0eWxlIDogX3RoaXMuaXRlbUJhY2tncm91bmRTdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5nZXRDYW52YXMoKS5kcmF3KCk7XG4gICAgICAgIH07IH07XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQnJlYWRjcnVtYi5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vZmZFdmVudHMoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBCcmVhZGNydW1iLnByb3RvdHlwZS5pbml0Q29uZmlnID0gZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICB0aGlzLnggPSBjb25maWcueDtcbiAgICAgICAgdGhpcy55ID0gY29uZmlnLnk7XG4gICAgICAgIHRoaXMuaXRlbXMgPSBjb25maWcuaXRlbXMgfHwgW107XG4gICAgICAgIHRoaXMuaXRlbVBhZGRpbmcgPSBjb25maWcuaXRlbVBhZGRpbmcgfHwgWzIsIDgsIDIsIDhdO1xuICAgICAgICB0aGlzLmJhY2tncm91bmRTdHlsZSA9IHRzbGliXzEuX19hc3NpZ24oeyBsaW5lV2lkdGg6IDEsIHN0cm9rZTogJyNmZmZmZmYnIH0sIChjb25maWcuYmFja2dyb3VuZFN0eWxlIHx8IHt9KSk7XG4gICAgICAgIHRoaXMuaXRlbUJhY2tncm91bmRTdHlsZSA9IHRzbGliXzEuX19hc3NpZ24oeyBmaWxsOiAnI2ZmZicgfSwgKGNvbmZpZy5pdGVtQmFja2dyb3VuZFN0eWxlIHx8IHt9KSk7XG4gICAgICAgIHRoaXMuaXRlbUFjdGl2ZUJhY2tncm91bmRTdHlsZSA9IHRzbGliXzEuX19hc3NpZ24oeyBmaWxsOiAnI2NjYycsIG9wYWNpdHk6IDAuMiB9LCAoY29uZmlnLml0ZW1BY3RpdmVCYWNrZ3JvdW5kU3R5bGUgfHwge30pKTtcbiAgICAgICAgdGhpcy5zZXBhcmF0b3IgPSBjb25maWcuc2VwYXJhdG9yIHx8ICcvJztcbiAgICAgICAgdGhpcy5zZXBhcmF0b3JTdHlsZSA9IHRzbGliXzEuX19hc3NpZ24oeyB0ZXh0QmFzZWxpbmU6ICd0b3AnLCBmaWxsOiAnIzAwMDAwMCcsIG9wYWNpdHk6IDAuNDUgfSwgKGNvbmZpZy5zZXBhcmF0b3JTdHlsZSB8fCB7fSkpO1xuICAgICAgICB0aGlzLml0ZW1XaWR0aCA9IGNvbmZpZy5pdGVtV2lkdGg7XG4gICAgICAgIHRoaXMuaXRlbUhlaWdodCA9IGNvbmZpZy5pdGVtSGVpZ2h0O1xuICAgICAgICB0aGlzLm1heEl0ZW1XaWR0aCA9IGNvbmZpZy5tYXhJdGVtV2lkdGg7XG4gICAgICAgIHRoaXMudGV4dFN0eWxlID0gdHNsaWJfMS5fX2Fzc2lnbih7IHRleHRCYXNlbGluZTogJ3RvcCcsIGZpbGw6ICcjMDAwMDAwJywgb3BhY2l0eTogMC40NSB9LCAoY29uZmlnLnRleHRTdHlsZSB8fCB7fSkpO1xuICAgIH07XG4gICAgQnJlYWRjcnVtYi5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHN0YXJ0WCA9IDA7XG4gICAgICAgIHZhciBzdGFydFkgPSAwO1xuICAgICAgICB0aGlzLm9mZkV2ZW50cygpO1xuICAgICAgICB0aGlzLnJlbmRlckl0ZW1zKGdyb3VwLCBzdGFydFgsIHN0YXJ0WSk7XG4gICAgICAgIC8vdGhpcy5iaW5kRXZlbnRzKGdyb3VwKTtcbiAgICAgICAgZ191dGlsXzEubW92ZSh0aGlzLmdyb3VwLCB0aGlzLngsIHRoaXMueSk7XG4gICAgfTtcbiAgICBCcmVhZGNydW1iLnByb3RvdHlwZS5yZW5kZXJJdGVtcyA9IGZ1bmN0aW9uIChncm91cCwgc3RhcnRYLCBzdGFydFkpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hID0gdGhpcy5pdGVtUGFkZGluZywgdG9wUGFkZGluZyA9IF9hWzBdLCByaWdodFBhZGRpbmcgPSBfYVsxXSwgYm90dG9tUGFkZGluZyA9IF9hWzJdLCBsZWZ0UGFkZGluZyA9IF9hWzNdO1xuICAgICAgICB2YXIgaXRlbUhlaWdodDtcbiAgICAgICAgLy8gYmFja2dyb3VuZFxuICAgICAgICB2YXIgYmFja2dyb3VuZFJlY3QgPSBncm91cC5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgIGNsYXNzOiAnYnJlYWRjcnVtYi1iYWNrZ3JvdW5kJyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogc3RhcnRYLCB5OiBzdGFydFksIHdpZHRoOiAxLCBoZWlnaHQ6IDEgfSwgdGhpcy5iYWNrZ3JvdW5kU3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpZHgpIHtcbiAgICAgICAgICAgIC8vIGl0ZW0gZ3JvdXBcbiAgICAgICAgICAgIHZhciBpdGVtR3JvdXAgPSBncm91cC5hZGRHcm91cCh7XG4gICAgICAgICAgICAgICAgaWQ6IFwiaXRlbS1ncm91cC1cIiArIGl0ZW0ua2V5LFxuICAgICAgICAgICAgICAgIC8vIGRhdGE6IGl0ZW0ua2V5LFxuICAgICAgICAgICAgICAgIGRhdGE6IGl0ZW0sXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdpdGVtLWdyb3VwJyxcbiAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBiYWNrZ3JvdW5kIHJlY3RcbiAgICAgICAgICAgIHZhciByZWN0U2hhcGUgPSBpdGVtR3JvdXAuYWRkU2hhcGUoJ3JlY3QnLCB7XG4gICAgICAgICAgICAgICAgaWQ6IFwiaXRlbS1iYWNrZ3JvdW5kLVwiICsgaXRlbS5rZXksXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdpdGVtLWJhY2tncm91bmQnLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyB4OiBzdGFydFgsIHk6IHN0YXJ0WSwgd2lkdGg6IGxlZnRQYWRkaW5nICsgcmlnaHRQYWRkaW5nLCBoZWlnaHQ6IHRvcFBhZGRpbmcgKyBib3R0b21QYWRkaW5nIH0sIF90aGlzLml0ZW1CYWNrZ3JvdW5kU3R5bGUpLCB7IGN1cnNvcjogJ3BvaW50ZXInIH0pLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWN0U2hhcGUubmFtZSA9ICdicmVhZGNydW1iJztcbiAgICAgICAgICAgIC8vIHRleHQgc2hhcGVcbiAgICAgICAgICAgIHZhciB0ZXh0U2hhcGUgPSBpdGVtR3JvdXAuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgaWQ6IFwiaXRlbS10ZXh0LVwiICsgaXRlbS5rZXksXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdpdGVtLXRleHQnLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oeyB4OiBzdGFydFggKyBsZWZ0UGFkZGluZywgeTogc3RhcnRZICsgdG9wUGFkZGluZywgdGV4dDogaXRlbS50ZXh0IH0sIF90aGlzLnRleHRTdHlsZSksIHsgY3Vyc29yOiAncG9pbnRlcicgfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRleHRTaGFwZS5uYW1lID0gJ2JyZWFkY3J1bWInO1xuICAgICAgICAgICAgdmFyIHRleHRTaGFwZUJCb3ggPSB0ZXh0U2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgaXRlbUhlaWdodCA9IF90aGlzLml0ZW1IZWlnaHQgfHwgdGV4dFNoYXBlQkJveC5oZWlnaHQ7XG4gICAgICAgICAgICB2YXIgaXRlbVdpZHRoID0gX3RoaXMuaXRlbVdpZHRoIHx8IHRleHRTaGFwZUJCb3gud2lkdGg7XG4gICAgICAgICAgICBpZiAoX3RoaXMubWF4SXRlbVdpZHRoKSB7XG4gICAgICAgICAgICAgICAgaXRlbVdpZHRoID0gTWF0aC5taW4oaXRlbVdpZHRoLCBfdGhpcy5tYXhJdGVtV2lkdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdXBkYXRlIGJhY2tncm91bmQgcmVjdFxuICAgICAgICAgICAgdmFyIGJhY2tncm91bmRSZWN0QXR0ciA9IHtcbiAgICAgICAgICAgICAgICB4OiBzdGFydFgsXG4gICAgICAgICAgICAgICAgeTogc3RhcnRZLFxuICAgICAgICAgICAgICAgIHdpZHRoOiBpdGVtV2lkdGggKyBsZWZ0UGFkZGluZyArIHJpZ2h0UGFkZGluZyxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGl0ZW1IZWlnaHQgKyB0b3BQYWRkaW5nICsgYm90dG9tUGFkZGluZyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZWN0U2hhcGUuYXR0cignd2lkdGgnLCBiYWNrZ3JvdW5kUmVjdEF0dHIud2lkdGgpO1xuICAgICAgICAgICAgcmVjdFNoYXBlLmF0dHIoJ2hlaWdodCcsIGJhY2tncm91bmRSZWN0QXR0ci5oZWlnaHQpO1xuICAgICAgICAgICAgLy8gY2xpcFxuICAgICAgICAgICAgaXRlbUdyb3VwLnNldENsaXAoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgICAgICAgICBhdHRyczogYmFja2dyb3VuZFJlY3RBdHRyLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzdGFydFggKz0gYmFja2dyb3VuZFJlY3RBdHRyLndpZHRoO1xuICAgICAgICAgICAgLy8gc2VwYXJhdG9yXG4gICAgICAgICAgICBpZiAoaWR4ICE9PSBfdGhpcy5pdGVtcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcFNoYXBlID0gZ3JvdXAuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogc3RhcnRYLCB5OiBzdGFydFkgKyB0b3BQYWRkaW5nLCB0ZXh0OiBfdGhpcy5zZXBhcmF0b3IgfSwgX3RoaXMuc2VwYXJhdG9yU3R5bGUpLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ3NlcGFyYXRvcicsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3RhcnRYICs9IHNlcFNoYXBlLmdldEJCb3goKS53aWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHVwZGF0ZSBiYWNrZ3JvdW5kXG4gICAgICAgIGJhY2tncm91bmRSZWN0LmF0dHIoe1xuICAgICAgICAgICAgd2lkdGg6IHN0YXJ0WCxcbiAgICAgICAgICAgIGhlaWdodDogaXRlbUhlaWdodCArIHRvcFBhZGRpbmcgKyBib3R0b21QYWRkaW5nLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJyZWFkY3J1bWIucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5pdGVtcztcbiAgICAgICAgdmFyIGl0ZW1Hcm91cHMgPSBncm91cC5nZXQoJ2NoaWxkcmVuJykuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtLmdldCgnY2xhc3MnKSA9PT0gJ2l0ZW0tZ3JvdXAnOyB9KTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKGV2ZW50LCBpdGVtR3JvdXAsIGVtaXRFdmVudE5hbWUpIHsgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBpdGVtR3JvdXAuZ2V0KCdkYXRhJyk7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IGl0ZW1zLmZpbmQoZnVuY3Rpb24gKHZhbCkgeyByZXR1cm4gdmFsLmtleSA9PT0ga2V5OyB9KTtcbiAgICAgICAgICAgIF90aGlzLmVtaXQoZW1pdEV2ZW50TmFtZSwge1xuICAgICAgICAgICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTsgfTtcbiAgICAgICAgaXRlbUdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtR3JvdXApIHtcbiAgICAgICAgICAgIHZhciBjbGlja0NhbGxiYWNrID0gY2FsbGJhY2soJ2NsaWNrJywgaXRlbUdyb3VwLCAnb25JdGVtQ2xpY2snKTtcbiAgICAgICAgICAgIHZhciBkYmxjbGlja0NhbGxiYWNrID0gY2FsbGJhY2soJ2RibGNsaWNrJywgaXRlbUdyb3VwLCAnb25JdGVtRGJsY2xpY2snKTtcbiAgICAgICAgICAgIHZhciBtb3VzZUVudGVyQ2FsbGJhY2sgPSBfdGhpcy5vbkl0ZW1Hcm91cFRvZ2dsZUFjdGl2ZShpdGVtR3JvdXAsIHRydWUpO1xuICAgICAgICAgICAgdmFyIG1vdXNlTGVhdmVDYWxsYmFjayA9IF90aGlzLm9uSXRlbUdyb3VwVG9nZ2xlQWN0aXZlKGl0ZW1Hcm91cCwgZmFsc2UpO1xuICAgICAgICAgICAgaXRlbUdyb3VwLm9uKCdjbGljaycsIGNsaWNrQ2FsbGJhY2spO1xuICAgICAgICAgICAgaXRlbUdyb3VwLm9uKCdkYmxjbGljaycsIGRibGNsaWNrQ2FsbGJhY2spO1xuICAgICAgICAgICAgaXRlbUdyb3VwLm9uKCdtb3VzZWVudGVyJywgbW91c2VFbnRlckNhbGxiYWNrKTtcbiAgICAgICAgICAgIGl0ZW1Hcm91cC5vbignbW91c2VsZWF2ZScsIG1vdXNlTGVhdmVDYWxsYmFjayk7XG4gICAgICAgICAgICBfdGhpcy5saXN0ZW5lcnMucHVzaCh7IHRhcmdldDogaXRlbUdyb3VwLCBldmVudDogJ2NsaWNrJywgY2FsbGJhY2s6IGNsaWNrQ2FsbGJhY2sgfSk7XG4gICAgICAgICAgICBfdGhpcy5saXN0ZW5lcnMucHVzaCh7IHRhcmdldDogaXRlbUdyb3VwLCBldmVudDogJ2RibGNsaWNrJywgY2FsbGJhY2s6IGRibGNsaWNrQ2FsbGJhY2sgfSk7XG4gICAgICAgICAgICBfdGhpcy5saXN0ZW5lcnMucHVzaCh7IHRhcmdldDogaXRlbUdyb3VwLCBldmVudDogJ21vdXNlZW50ZXInLCBjYWxsYmFjazogbW91c2VFbnRlckNhbGxiYWNrIH0pO1xuICAgICAgICAgICAgX3RoaXMubGlzdGVuZXJzLnB1c2goeyB0YXJnZXQ6IGl0ZW1Hcm91cCwgZXZlbnQ6ICdtb3VzZWxlYXZlJywgY2FsbGJhY2s6IG1vdXNlTGVhdmVDYWxsYmFjayB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBCcmVhZGNydW1iLnByb3RvdHlwZS5vZmZFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmxpc3RlbmVycykge1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAoX2EpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gX2EudGFyZ2V0LCBldmVudCA9IF9hLmV2ZW50LCBjYWxsYmFjayA9IF9hLmNhbGxiYWNrO1xuICAgICAgICAgICAgICAgIHRhcmdldC5vZmYoZXZlbnQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XG4gICAgfTtcbiAgICByZXR1cm4gQnJlYWRjcnVtYjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJyZWFkY3J1bWI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1icmVhZGNydW1iLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDljLrln5/ov57mjqXnu4Tku7bvvIznlKjkuo7loIblj6Dmn7Hnirblm77lkozloIblj6DmnaHlvaLlm75cbiAqL1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHN0YXRlXzEgPSByZXF1aXJlKFwiLi4vYmFzZS9jb250cm9sbGVyL3N0YXRlXCIpO1xuZnVuY3Rpb24gcGFyc2VQb2ludHMoc2hhcGUsIGNvb3JkKSB7XG4gICAgdmFyIHBhcnNlZFBvaW50cyA9IFtdO1xuICAgIHZhciBwb2ludHMgPSBzaGFwZS5nZXQoJ29yaWdpbicpLnBvaW50cztcbiAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgIHBhcnNlZFBvaW50cy5wdXNoKGNvb3JkLmNvbnZlcnRQb2ludChwKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHBhcnNlZFBvaW50cztcbn1cbmZ1bmN0aW9uIGdldERlZmF1bHRTdHlsZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBhcmVhU3R5bGU6IHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDAuMixcbiAgICAgICAgfSxcbiAgICAgICAgbGluZVN0eWxlOiB7XG4gICAgICAgICAgICBsaW5lV2lkdGg6IDIsXG4gICAgICAgICAgICBvcGFjaXR5OiAwLjEsXG4gICAgICAgIH0sXG4gICAgfTtcbn1cbnZhciBDb25uZWN0ZWRBcmVhID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbm5lY3RlZEFyZWEoY2ZnKSB7XG4gICAgICAgIHRoaXMuYXJlYXMgPSBbXTtcbiAgICAgICAgdGhpcy5saW5lcyA9IFtdO1xuICAgICAgICB0aGlzLl9hcmVhU3R5bGUgPSB7fTtcbiAgICAgICAgdGhpcy5fbGluZVN0eWxlID0ge307XG4gICAgICAgIHV0aWxfMS5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICAgICAgdGhpcy5faW5pdCgpO1xuICAgIH1cbiAgICBDb25uZWN0ZWRBcmVhLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZ3JvdXBlZFNoYXBlcyA9IHRoaXMuX2dldEdyb3VwZWRTaGFwZXMoKTtcbiAgICAgICAgdXRpbF8xLmVhY2goZ3JvdXBlZFNoYXBlcywgZnVuY3Rpb24gKHNoYXBlcywgbmFtZSkge1xuICAgICAgICAgICAgaWYgKHNoYXBlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX2RyYXdDb25uZWN0aW9uKHNoYXBlcywgbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy50cmlnZ2VyT24pIHtcbiAgICAgICAgICAgIHRoaXMuX2FkZEludGVyYWN0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5hbmltYXRpb24pIHtcbiAgICAgICAgICAgIC8vIOWmguaenOWumuS5ieS6hnRyaWdnZXJPbueahOaWueW8j++8jOWImee7hOS7tuaYr+WTjeW6lOS6pOS6kueahO+8jOWIneWni+WMluS4uuS4jeWPr+ingeeKtuaAge+8jOWboOatpOaXoOmcgOWKqOeUu1xuICAgICAgICAgICAgdGhpcy5faW5pdGlhbEFuaW1hdGlvbigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb25uZWN0ZWRBcmVhLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYXJlYXMgPSBbXTtcbiAgICAgICAgdGhpcy5saW5lcyA9IFtdO1xuICAgIH07XG4gICAgQ29ubmVjdGVkQXJlYS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29ubmVjdGVkQXJlYS5wcm90b3R5cGUuc2V0U3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUsIGNvbmRpdGlvbikge1xuICAgICAgICBpZiAoc3RhdGUgPT09ICdhY3RpdmUnKSB7XG4gICAgICAgICAgICB0aGlzLl9vbkFjdGl2ZShjb25kaXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ2Rpc2FibGVkJykge1xuICAgICAgICAgICAgdGhpcy5fb25EaXNhYmxlZChjb25kaXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ3NlbGVjdGVkJykge1xuICAgICAgICAgICAgdGhpcy5fb25TZWxlY3RlZChjb25kaXRpb24pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb25uZWN0ZWRBcmVhLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy52aWV3LmJhY2tncm91bmRHcm91cDtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBsYXllci5hZGRHcm91cCgpO1xuICAgICAgICB0aGlzLmRyYXcoKTtcbiAgICAgICAgdGhpcy52aWV3Lm9uKCdiZWZvcmVyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5jbGVhcigpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbm5lY3RlZEFyZWEucHJvdG90eXBlLl9nZXRHcm91cGVkU2hhcGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAvLyDmoLnmja7loIblj6DlrZfmrrXlr7lzaGFwZei/m+ihjOWIhue7hFxuICAgICAgICB2YXIgdmFsdWVzID0gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZCh0aGlzLmZpZWxkKS52YWx1ZXM7XG4gICAgICAgIHZhciBnZW9tZXRyeSA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdO1xuICAgICAgICB2YXIgc2hhcGVzID0gZ2VvbWV0cnkuZ2V0U2hhcGVzKCk7XG4gICAgICAgIC8vIOWIm+W7uuWIhue7hFxuICAgICAgICB2YXIgZ3JvdXBzID0ge307XG4gICAgICAgIHV0aWxfMS5lYWNoKHZhbHVlcywgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgIGdyb3Vwc1t2XSA9IFtdO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8g5omn6KGM5YiG57uEXG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlcywgZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgICAgICB2YXIgb3JpZ2luID0gc2hhcGUuZ2V0KCdvcmlnaW4nKS5kYXRhO1xuICAgICAgICAgICAgdmFyIGtleSA9IG9yaWdpbltfdGhpcy5maWVsZF07XG4gICAgICAgICAgICBncm91cHNba2V5XS5wdXNoKHNoYXBlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBncm91cHM7XG4gICAgfTtcbiAgICBDb25uZWN0ZWRBcmVhLnByb3RvdHlwZS5fZHJhd0Nvbm5lY3Rpb24gPSBmdW5jdGlvbiAoc2hhcGVzLCBuYW1lKSB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogcHJlZmVyLWZvci1vZlxuICAgICAgICB2YXIgb3JpZ2luQ29sb3IgPSBzaGFwZXNbMF0uYXR0cignZmlsbCcpO1xuICAgICAgICB0aGlzLl9hcmVhU3R5bGVbbmFtZV0gPSB0aGlzLl9nZXRTaGFwZVN0eWxlKG9yaWdpbkNvbG9yLCAnYXJlYScpO1xuICAgICAgICB0aGlzLl9saW5lU3R5bGVbbmFtZV0gPSB0aGlzLl9nZXRTaGFwZVN0eWxlKG9yaWdpbkNvbG9yLCAnbGluZScpO1xuICAgICAgICB2YXIgY29vcmQgPSB0aGlzLnZpZXcuZ2VvbWV0cmllc1swXS5jb29yZGluYXRlO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNoYXBlcy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50ID0gcGFyc2VQb2ludHMoc2hhcGVzW2ldLCBjb29yZCk7XG4gICAgICAgICAgICB2YXIgbmV4dCA9IHBhcnNlUG9pbnRzKHNoYXBlc1tpICsgMV0sIGNvb3JkKTtcbiAgICAgICAgICAgIHZhciBhcmVhU3R5bGUgPSB1dGlsXzEubWl4KHt9LCB0aGlzLl9hcmVhU3R5bGVbbmFtZV0pO1xuICAgICAgICAgICAgdmFyIGxpbmVTdHlsZSA9IHV0aWxfMS5taXgoe30sIHRoaXMuX2xpbmVTdHlsZVtuYW1lXSk7XG4gICAgICAgICAgICBpZiAodGhpcy50cmlnZ2VyT24pIHtcbiAgICAgICAgICAgICAgICBhcmVhU3R5bGUub3BhY2l0eSA9IDA7XG4gICAgICAgICAgICAgICAgbGluZVN0eWxlLm9wYWNpdHkgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGFyZWEgPSB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdXRpbF8xLm1peCh7fSwgYXJlYVN0eWxlLCB7XG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTScsIGN1cnJlbnRbMl0ueCwgY3VycmVudFsyXS55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIG5leHRbMV0ueCwgbmV4dFsxXS55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIG5leHRbMF0ueCwgbmV4dFswXS55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIGN1cnJlbnRbM10ueCwgY3VycmVudFszXS55XSxcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBuYW1lOiAnY29ubmVjdGVkQXJlYScsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBsaW5lID0gdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5taXgoe30sIGxpbmVTdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCBjdXJyZW50WzJdLngsIGN1cnJlbnRbMl0ueV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBuZXh0WzFdLngsIG5leHRbMV0ueV0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgbmFtZTogJ2Nvbm5lY3RlZEFyZWEnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyDlnKjovoXliqnlm77lvaLkuIrorrDlvZXmlbDmja7vvIznlKjku6XkuqTkupLlkozlk43lupTnirbmgIHph49cbiAgICAgICAgICAgIHZhciBvcmlnaW5EYXRhID0gc2hhcGVzW2ldLmdldCgnb3JpZ2luJykuZGF0YTtcbiAgICAgICAgICAgIGFyZWEuc2V0KCdkYXRhJywgb3JpZ2luRGF0YSk7XG4gICAgICAgICAgICBsaW5lLnNldCgnZGF0YScsIG9yaWdpbkRhdGEpO1xuICAgICAgICAgICAgdGhpcy5hcmVhcy5wdXNoKGFyZWEpO1xuICAgICAgICAgICAgdGhpcy5saW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb25uZWN0ZWRBcmVhLnByb3RvdHlwZS5fZ2V0U2hhcGVTdHlsZSA9IGZ1bmN0aW9uIChvcmlnaW5Db2xvciwgc2hhcGVUeXBlKSB7XG4gICAgICAgIHZhciBzdHlsZU5hbWUgPSBzaGFwZVR5cGUgKyBcIlN0eWxlXCI7XG4gICAgICAgIC8vIOWmguaenOeUqOaIt+iHquW3seaMh+WumuS6huagt+W8j++8jOWImeS4jemHh+eUqOm7mOiupOminOiJsuaYoOWwhFxuICAgICAgICBpZiAodGhpc1tzdHlsZU5hbWVdKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tzdHlsZU5hbWVdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkZWZhdWx0U3R5bGUgPSBnZXREZWZhdWx0U3R5bGUoKVtzdHlsZU5hbWVdO1xuICAgICAgICB2YXIgbWFwcGVkU3R5bGUgPSB7IGZpbGw6IG9yaWdpbkNvbG9yIH07XG4gICAgICAgIGlmIChzaGFwZVR5cGUgPT09ICdsaW5lJykge1xuICAgICAgICAgICAgbWFwcGVkU3R5bGUgPSB7IHN0cm9rZTogb3JpZ2luQ29sb3IgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXRpbF8xLm1peChkZWZhdWx0U3R5bGUsIG1hcHBlZFN0eWxlKTtcbiAgICB9O1xuICAgIENvbm5lY3RlZEFyZWEucHJvdG90eXBlLl9hZGRJbnRlcmFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGV2ZW50TmFtZSA9IHRoaXMudHJpZ2dlck9uO1xuICAgICAgICB0aGlzLnZpZXcub24oXCJpbnRlcnZhbDpcIiArIGV2ZW50TmFtZSwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciBvcmlnaW4gPSBlLnRhcmdldC5nZXQoJ29yaWdpbicpLmRhdGFbX3RoaXMuZmllbGRdO1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoJ2FjdGl2ZScsIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBfdGhpcy5maWVsZCxcbiAgICAgICAgICAgICAgICBleHA6IG9yaWdpbixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoJ2Rpc2FibGVkJywge1xuICAgICAgICAgICAgICAgIG5hbWU6IF90aGlzLmZpZWxkLFxuICAgICAgICAgICAgICAgIGV4cDogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQgIT09IG9yaWdpbjtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBfdGhpcy52aWV3LmNhbnZhcy5kcmF3KCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDlvZPpvKDmoIfnp7vliqjliLDlhbbku5bljLrln5/ml7blj5bmtojmmL7npLpcbiAgICAgICAgdGhpcy52aWV3Lm9uKCdtb3VzZW1vdmUnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKGUuZ0V2ZW50LnRhcmdldC5nZXQoJ25hbWUnKSAhPT0gJ2ludGVydmFsJykge1xuICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKCdkaXNhYmxlZCcsIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogX3RoaXMuZmllbGQsXG4gICAgICAgICAgICAgICAgICAgIGV4cDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQ29ubmVjdGVkQXJlYS5wcm90b3R5cGUuX2luaXRpYWxBbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGNsaXBJbuWKqOeUu1xuICAgICAgICB2YXIgX2EgPSB0aGlzLnZpZXcuY29vcmRpbmF0ZUJCb3gsIHggPSBfYS54LCB5ID0gX2EueSwgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXRDbGlwKHtcbiAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnNldCgnYW5pbWF0aW5nJywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmdldENsaXAoKS5hbmltYXRlKHtcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgfSwgNjAwLCAnZWFzZVF1YWRPdXQnLCBmdW5jdGlvbiAoKSB7IH0sIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgICAgIDQwMCk7XG4gICAgfTtcbiAgICBDb25uZWN0ZWRBcmVhLnByb3RvdHlwZS5fb25BY3RpdmUgPSBmdW5jdGlvbiAoY29uZGl0aW9uKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuYXJlYXMsIGZ1bmN0aW9uIChhcmVhKSB7XG4gICAgICAgICAgICB2YXIgc2hhcGVEYXRhID0gYXJlYS5nZXQoJ2RhdGEnKTtcbiAgICAgICAgICAgIHZhciBzdHlsZUZpZWxkID0gc2hhcGVEYXRhW190aGlzLmZpZWxkXTtcbiAgICAgICAgICAgIGlmIChzdGF0ZV8xLmNvbXBhcmUoc2hhcGVEYXRhLCBjb25kaXRpb24pKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9wYWNpdHkgPSBfdGhpcy5fYXJlYVN0eWxlW3N0eWxlRmllbGRdLm9wYWNpdHkgfHwgMTtcbiAgICAgICAgICAgICAgICAvLyBhcmVhLmF0dHIoJ29wYWNpdHknLHRoaXMuX2FyZWFTdHlsZVtzdHlsZUZpZWxkXS5vcGFjaXR5IHx8IDEpO1xuICAgICAgICAgICAgICAgIGFyZWEuc3RvcEFuaW1hdGUoKTtcbiAgICAgICAgICAgICAgICBhcmVhLmFuaW1hdGUoeyBvcGFjaXR5OiBvcGFjaXR5IH0sIDQwMCwgJ2Vhc2VRdWFkT3V0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmxpbmVzLCBmdW5jdGlvbiAobGluZSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlRGF0YSA9IGxpbmUuZ2V0KCdkYXRhJyk7XG4gICAgICAgICAgICB2YXIgc3R5bGVGaWVsZCA9IHNoYXBlRGF0YVtfdGhpcy5maWVsZF07XG4gICAgICAgICAgICBpZiAoc3RhdGVfMS5jb21wYXJlKHNoYXBlRGF0YSwgY29uZGl0aW9uKSkge1xuICAgICAgICAgICAgICAgIHZhciBvcGFjaXR5ID0gX3RoaXMuX2xpbmVTdHlsZVtzdHlsZUZpZWxkXS5vcGFjaXR5IHx8IDE7XG4gICAgICAgICAgICAgICAgLy8gbGluZS5hdHRyKCdvcGFjaXR5Jyx0aGlzLl9saW5lU3R5bGVbc3R5bGVGaWVsZF0ub3BhY2l0eSB8fCAxKTtcbiAgICAgICAgICAgICAgICBsaW5lLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICAgICAgbGluZS5hbmltYXRlKHsgb3BhY2l0eTogb3BhY2l0eSB9LCA0MDAsICdlYXNlUXVhZE91dCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbm5lY3RlZEFyZWEucHJvdG90eXBlLl9vbkRpc2FibGVkID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmFyZWFzLCBmdW5jdGlvbiAoYXJlYSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlRGF0YSA9IGFyZWEuZ2V0KCdkYXRhJyk7XG4gICAgICAgICAgICBpZiAoc3RhdGVfMS5jb21wYXJlKHNoYXBlRGF0YSwgY29uZGl0aW9uKSkge1xuICAgICAgICAgICAgICAgIC8vIGFyZWEuYXR0cignb3BhY2l0eScsMCk7XG4gICAgICAgICAgICAgICAgYXJlYS5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgICAgIGFyZWEuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICAgICAgfSwgNDAwLCAnZWFzZVF1YWRPdXQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMubGluZXMsIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICB2YXIgc2hhcGVEYXRhID0gbGluZS5nZXQoJ2RhdGEnKTtcbiAgICAgICAgICAgIGlmIChzdGF0ZV8xLmNvbXBhcmUoc2hhcGVEYXRhLCBjb25kaXRpb24pKSB7XG4gICAgICAgICAgICAgICAgLy8gbGluZS5hdHRyKCdvcGFjaXR5JywwKTtcbiAgICAgICAgICAgICAgICBsaW5lLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICAgICAgbGluZS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgICAgICB9LCA0MDAsICdlYXNlUXVhZE91dCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbm5lY3RlZEFyZWEucHJvdG90eXBlLl9vblNlbGVjdGVkID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICB0aGlzLl9vbkFjdGl2ZShjb25kaXRpb24pO1xuICAgIH07XG4gICAgQ29ubmVjdGVkQXJlYS5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmluZCh0aGlzLnZpZXcuZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb20pIHsgcmV0dXJuIGdlb20udHlwZSA9PT0gJ2ludGVydmFsJzsgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQ29ubmVjdGVkQXJlYTtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDb25uZWN0ZWRBcmVhO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdGVkLWFyZWEuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBhbmltYXRlXzEgPSByZXF1aXJlKFwiQGFudHYvZzIvbGliL2FuaW1hdGVcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG5mdW5jdGlvbiBwYXJzZVBvaW50cyhzaGFwZSwgY29vcmQpIHtcbiAgICB2YXIgcGFyc2VkUG9pbnRzID0gW107XG4gICAgdmFyIHBvaW50cyA9IHNoYXBlLmdldCgnb3JpZ2luJykucG9pbnRzO1xuICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHApIHtcbiAgICAgICAgcGFyc2VkUG9pbnRzLnB1c2goY29vcmQuY29udmVydFBvaW50KHApKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcGFyc2VkUG9pbnRzO1xufVxudmFyIENvbnZlcnNpb25UYWcgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udmVyc2lvblRhZyhjZmcpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB1dGlsXzEuZGVlcE1peCh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yLmdldERlZmF1bHRPcHRpb25zKGNmZyksIGNmZyk7XG4gICAgICAgIHRoaXMuX2luaXQoKTtcbiAgICB9XG4gICAgQ29udmVyc2lvblRhZy5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uIChfYSkge1xuICAgICAgICB2YXIgdHJhbnNwb3NlID0gX2EudHJhbnNwb3NlO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHNpemU6IHRyYW5zcG9zZSA/IDMyIDogODAsXG4gICAgICAgICAgICBzcGFjaW5nOiB0cmFuc3Bvc2UgPyA4IDogMTIsXG4gICAgICAgICAgICBvZmZzZXQ6IHRyYW5zcG9zZSA/IDMyIDogMCxcbiAgICAgICAgICAgIGFycm93OiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBoZWFkU2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC4wNSknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC44NSknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZm9ybWF0dGVyOiBmdW5jdGlvbiAodmFsdWVVcHBlciwgdmFsdWVMb3dlcikgeyByZXR1cm4gKCgxMDAgKiB2YWx1ZUxvd2VyKSAvIHZhbHVlVXBwZXIpLnRvRml4ZWQoMikgKyBcIiVcIjsgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhbmltYXRpb246IHV0aWxfMS5kZWVwTWl4KHt9LCBhbmltYXRlXzEuREVGQVVMVF9BTklNQVRFX0NGRyksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBDb252ZXJzaW9uVGFnLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy52aWV3LmJhY2tncm91bmRHcm91cDtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBsYXllci5hZGRHcm91cCgpO1xuICAgICAgICB0aGlzLmRyYXcoKTtcbiAgICAgICAgdGhpcy52aWV3Lm9uKCdiZWZvcmVyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5jbGVhcigpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbnZlcnNpb25UYWcucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0cmFuc3Bvc2UgPSB0aGlzLnRyYW5zcG9zZTtcbiAgICAgICAgdmFyIHZhbHVlcyA9IHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQodGhpcy5maWVsZCkudmFsdWVzO1xuICAgICAgICB2YXIgZ2VvbWV0cnkgPSB0aGlzLnZpZXcuZ2VvbWV0cmllc1swXTtcbiAgICAgICAgdmFyIHNoYXBlcyA9IGdlb21ldHJ5LmdldFNoYXBlcygpO1xuICAgICAgICB2YXIgc2hhcGVMb3dlciwgdmFsdWVMb3dlciwgc2hhcGVVcHBlciwgdmFsdWVVcHBlcjtcbiAgICAgICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgICAgICAgc2hhcGVzLmZvckVhY2goZnVuY3Rpb24gKHNoYXBlTG93ZXIsIGkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZUxvd2VyID0gdmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChpKysgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9kcmF3VGFnKHNoYXBlVXBwZXIsIHZhbHVlVXBwZXIsIHNoYXBlTG93ZXIsIHZhbHVlTG93ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YWx1ZVVwcGVyID0gdmFsdWVMb3dlcjtcbiAgICAgICAgICAgICAgICBzaGFwZVVwcGVyID0gc2hhcGVMb3dlcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc2hhcGVzLmZvckVhY2goZnVuY3Rpb24gKHNoYXBlVXBwZXIsIGkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVVwcGVyID0gdmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChpKysgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9kcmF3VGFnKHNoYXBlVXBwZXIsIHZhbHVlVXBwZXIsIHNoYXBlTG93ZXIsIHZhbHVlTG93ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YWx1ZUxvd2VyID0gdmFsdWVVcHBlcjtcbiAgICAgICAgICAgICAgICBzaGFwZUxvd2VyID0gc2hhcGVVcHBlcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb252ZXJzaW9uVGFnLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb252ZXJzaW9uVGFnLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb252ZXJzaW9uVGFnLnByb3RvdHlwZS5fZHJhd1RhZyA9IGZ1bmN0aW9uIChzaGFwZVVwcGVyLCB2YWx1ZVVwcGVyLCBzaGFwZUxvd2VyLCB2YWx1ZUxvd2VyKSB7XG4gICAgICAgIHZhciB0cmFuc3Bvc2UgPSB0aGlzLnRyYW5zcG9zZTtcbiAgICAgICAgdmFyIGNvb3JkID0gdGhpcy52aWV3Lmdlb21ldHJpZXNbMF0uY29vcmRpbmF0ZTtcbiAgICAgICAgdmFyIHBvaW50VXBwZXIgPSBwYXJzZVBvaW50cyhzaGFwZVVwcGVyLCBjb29yZClbdHJhbnNwb3NlID8gMyA6IDBdO1xuICAgICAgICB2YXIgcG9pbnRMb3dlciA9IHBhcnNlUG9pbnRzKHNoYXBlTG93ZXIsIGNvb3JkKVt0cmFuc3Bvc2UgPyAwIDogM107XG4gICAgICAgIHRoaXMuX2RyYXdUYWdBcnJvdyhwb2ludFVwcGVyLCBwb2ludExvd2VyKTtcbiAgICAgICAgdGhpcy5fZHJhd1RhZ1ZhbHVlKHBvaW50VXBwZXIsIHZhbHVlVXBwZXIsIHBvaW50TG93ZXIsIHZhbHVlTG93ZXIpO1xuICAgIH07XG4gICAgQ29udmVyc2lvblRhZy5wcm90b3R5cGUuX2RyYXdUYWdBcnJvdyA9IGZ1bmN0aW9uIChwb2ludFVwcGVyLCBwb2ludExvd2VyKSB7XG4gICAgICAgIHZhciBzcGFjaW5nID0gdGhpcy5zcGFjaW5nO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBzaXplID0gX2Euc2l6ZSwgb2Zmc2V0ID0gX2Eub2Zmc2V0LCBhbmltYXRpb24gPSBfYS5hbmltYXRpb24sIHRyYW5zcG9zZSA9IF9hLnRyYW5zcG9zZTtcbiAgICAgICAgdmFyIGhlYWRTaXplID0gdGhpcy5hcnJvdy5oZWFkU2l6ZTtcbiAgICAgICAgdmFyIHRvdGFsSGVpZ2h0ID0gcG9pbnRMb3dlci55IC0gcG9pbnRVcHBlci55O1xuICAgICAgICB2YXIgdG90YWxXaWR0aCA9IHBvaW50TG93ZXIueCAtIHBvaW50VXBwZXIueDtcbiAgICAgICAgdmFyIHBvaW50cztcbiAgICAgICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgICAgICAgaWYgKCh0b3RhbFdpZHRoIC0gaGVhZFNpemUpIC8gMiA8IHNwYWNpbmcpIHtcbiAgICAgICAgICAgICAgICAvLyDlvZPmn7Hpl7Tot53kuI3otrPlrrnnurPnrq3lpLTlsJbkuI7pl7TpmpTml7bvvIznlLvkuInop5LlubbmjKTljaDpl7TpmpRcbiAgICAgICAgICAgICAgICBzcGFjaW5nID0gTWF0aC5tYXgoMSwgKHRvdGFsV2lkdGggLSBoZWFkU2l6ZSkgLyAyKTtcbiAgICAgICAgICAgICAgICBwb2ludHMgPSBbXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludFVwcGVyLnggKyBzcGFjaW5nLCBwb2ludFVwcGVyLnkgLSBvZmZzZXRdLFxuICAgICAgICAgICAgICAgICAgICBbcG9pbnRVcHBlci54ICsgc3BhY2luZywgcG9pbnRVcHBlci55IC0gb2Zmc2V0IC0gc2l6ZV0sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludExvd2VyLnggLSBzcGFjaW5nLCBwb2ludExvd2VyLnkgLSBvZmZzZXQgLSBzaXplIC8gMl0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOW9k+afsemXtOi3nei2s+Wkn+aXtu+8jOeUu+WujOaVtOWbvuW9ouW5tueVmeWHuumXtOmalOOAglxuICAgICAgICAgICAgICAgIHBvaW50cyA9IFtcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50VXBwZXIueCArIHNwYWNpbmcsIHBvaW50VXBwZXIueSAtIG9mZnNldF0sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludFVwcGVyLnggKyBzcGFjaW5nLCBwb2ludFVwcGVyLnkgLSBvZmZzZXQgLSBzaXplXSxcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50TG93ZXIueCAtIHNwYWNpbmcgLSBoZWFkU2l6ZSwgcG9pbnRMb3dlci55IC0gb2Zmc2V0IC0gc2l6ZV0sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludExvd2VyLnggLSBzcGFjaW5nLCBwb2ludExvd2VyLnkgLSBvZmZzZXQgLSBzaXplIC8gMl0sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludExvd2VyLnggLSBzcGFjaW5nIC0gaGVhZFNpemUsIHBvaW50TG93ZXIueSAtIG9mZnNldF0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICgodG90YWxIZWlnaHQgLSBoZWFkU2l6ZSkgLyAyIDwgc3BhY2luZykge1xuICAgICAgICAgICAgICAgIC8vIOW9k+afsemXtOi3neS4jei2s+Wuuee6s+eureWktOWwluS4jumXtOmalOaXtu+8jOeUu+S4ieinkuW5tuaMpOWNoOmXtOmalFxuICAgICAgICAgICAgICAgIHNwYWNpbmcgPSBNYXRoLm1heCgxLCAodG90YWxIZWlnaHQgLSBoZWFkU2l6ZSkgLyAyKTtcbiAgICAgICAgICAgICAgICBwb2ludHMgPSBbXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludFVwcGVyLnggKyBvZmZzZXQsIHBvaW50VXBwZXIueSArIHNwYWNpbmddLFxuICAgICAgICAgICAgICAgICAgICBbcG9pbnRVcHBlci54ICsgb2Zmc2V0ICsgc2l6ZSwgcG9pbnRVcHBlci55ICsgc3BhY2luZ10sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludExvd2VyLnggKyBvZmZzZXQgKyBzaXplIC8gMiwgcG9pbnRMb3dlci55IC0gc3BhY2luZ10sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOW9k+afsemXtOi3nei2s+Wkn+aXtu+8jOeUu+WujOaVtOWbvuW9ouW5tueVmeWHuumXtOmalOOAglxuICAgICAgICAgICAgICAgIHBvaW50cyA9IFtcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50VXBwZXIueCArIG9mZnNldCwgcG9pbnRVcHBlci55ICsgc3BhY2luZ10sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludFVwcGVyLnggKyBvZmZzZXQgKyBzaXplLCBwb2ludFVwcGVyLnkgKyBzcGFjaW5nXSxcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50TG93ZXIueCArIG9mZnNldCArIHNpemUsIHBvaW50TG93ZXIueSAtIHNwYWNpbmcgLSBoZWFkU2l6ZV0sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludExvd2VyLnggKyBvZmZzZXQgKyBzaXplIC8gMiwgcG9pbnRMb3dlci55IC0gc3BhY2luZ10sXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludExvd2VyLnggKyBvZmZzZXQsIHBvaW50TG93ZXIueSAtIHNwYWNpbmcgLSBoZWFkU2l6ZV0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgdGFnQXJyb3cgPSB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncG9seWdvbicsIHtcbiAgICAgICAgICAgIG5hbWU6ICdhcnJvdycsXG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCB0aGlzLmFycm93LnN0eWxlKSwgeyBwb2ludHM6IHBvaW50cyB9KSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChhbmltYXRpb24gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLl9mYWRlSW5UYWdTaGFwZSh0YWdBcnJvdyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbnZlcnNpb25UYWcucHJvdG90eXBlLl9kcmF3VGFnVmFsdWUgPSBmdW5jdGlvbiAocG9pbnRVcHBlciwgdmFsdWVVcHBlciwgcG9pbnRMb3dlciwgdmFsdWVMb3dlcikge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLCBzaXplID0gX2Euc2l6ZSwgb2Zmc2V0ID0gX2Eub2Zmc2V0LCBhbmltYXRpb24gPSBfYS5hbmltYXRpb24sIHRyYW5zcG9zZSA9IF9hLnRyYW5zcG9zZTtcbiAgICAgICAgdmFyIHRleHQgPSB0aGlzLnZhbHVlLmZvcm1hdHRlcih2YWx1ZVVwcGVyLCB2YWx1ZUxvd2VyKTtcbiAgICAgICAgdmFyIHRhZ1ZhbHVlID0gdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICBuYW1lOiAndmFsdWUnLFxuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgdGhpcy52YWx1ZS5zdHlsZSksIHsgdGV4dDogdGV4dCwgeDogdHJhbnNwb3NlID8gKHBvaW50VXBwZXIueCArIHBvaW50TG93ZXIueCkgLyAyIDogcG9pbnRVcHBlci54ICsgb2Zmc2V0ICsgc2l6ZSAvIDIsIHk6IHRyYW5zcG9zZSA/IHBvaW50VXBwZXIueSAtIG9mZnNldCAtIHNpemUgLyAyIDogKHBvaW50VXBwZXIueSArIHBvaW50TG93ZXIueSkgLyAyLCB0ZXh0QWxpZ246ICdjZW50ZXInLCB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgICAgICAgdmFyIHRvdGFsV2lkdGggPSBwb2ludExvd2VyLnggLSBwb2ludFVwcGVyLng7XG4gICAgICAgICAgICB2YXIgdGV4dFdpZHRoID0gdGFnVmFsdWUuZ2V0QkJveCgpLndpZHRoO1xuICAgICAgICAgICAgaWYgKHRleHRXaWR0aCA+IHRvdGFsV2lkdGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgY1dpZHRoID0gdGV4dFdpZHRoIC8gdGV4dC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIGNFbmQgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWxXaWR0aCAvIGNXaWR0aCkgLSAxKTtcbiAgICAgICAgICAgICAgICB2YXIgdGV4dEFkanVzdGVkID0gdGV4dC5zbGljZSgwLCBjRW5kKSArIFwiLi4uXCI7XG4gICAgICAgICAgICAgICAgdGFnVmFsdWUuYXR0cigndGV4dCcsIHRleHRBZGp1c3RlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFuaW1hdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZhZGVJblRhZ1NoYXBlKHRhZ1ZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udmVyc2lvblRhZy5wcm90b3R5cGUuX2ZhZGVJblRhZ1NoYXBlID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBhbmltYXRpb24gPSB0aGlzLmFuaW1hdGlvbjtcbiAgICAgICAgdmFyIG9wYWNpdHkgPSBzaGFwZS5hdHRyKCdvcGFjaXR5Jyk7XG4gICAgICAgIHNoYXBlLmF0dHIoJ29wYWNpdHknLCAwKTtcbiAgICAgICAgdmFyIGR1cmF0aW9uID0gdXRpbF8xLmdldChhbmltYXRpb24sICdhcHBlYXInLCBhbmltYXRlXzEuREVGQVVMVF9BTklNQVRFX0NGRy5hcHBlYXIpLmR1cmF0aW9uO1xuICAgICAgICBzaGFwZS5hbmltYXRlKHsgb3BhY2l0eTogb3BhY2l0eSB9LCBkdXJhdGlvbik7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udmVyc2lvblRhZztcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDb252ZXJzaW9uVGFnO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udmVyc2lvbi10YWcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb21tb25fMSA9IHJlcXVpcmUoXCIuLi91dGlsL2NvbW1vblwiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vdXRpbC9iYm94XCIpKTtcbi8qKlxuICog5Zu+6KGo55qE5paH5a2X5o+P6L+w77yM5LiA6Iis55So5LqO55Sf5oiQ5Zu+6KGo55qE5qCH6aKY5ZKM5Ymv5qCH6aKYXG4gKi9cbnZhciBUZXh0RGVzY3JpcHRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVGV4dERlc2NyaXB0aW9uKGNmZykge1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0gJ3RvcCc7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIHV0aWxfMS5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIFRleHREZXNjcmlwdGlvbi5wcm90b3R5cGUuZ2V0QkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMuc2hhcGUpIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIHZhciBiYm94ID0gdGhpcy5zaGFwZS5nZXRCQm94KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5pbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiYm94XzEuZGVmYXVsdC5mcm9tQkJveE9iamVjdChiYm94KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwYWRkaW5nXzEgPSB0aGlzLnBsb3QudGhlbWUuZGVzY3JpcHRpb24ucGFkZGluZztcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheShwYWRkaW5nXzEpKSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gocGFkZGluZ18xLCBmdW5jdGlvbiAoaXQsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcGFkZGluZ18xW2luZGV4XSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ18xW2luZGV4XSA9IHBhZGRpbmdfMVtpbmRleF0oX3RoaXMucGxvdC5vcHRpb25zLmxlZ2VuZC5wb3NpdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQoYmJveC5tYXhYLCBiYm94Lm1pblksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIFRleHREZXNjcmlwdGlvbi5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnNoYXBlKSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB0aGlzLnNoYXBlLmF0dHIoJ3RleHQnLCAnJyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRleHREZXNjcmlwdGlvbi5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2hhcGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhcGUucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgVGV4dERlc2NyaXB0aW9uLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGVudCA9IHRoaXMudGV4dFdyYXBwZXIoKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5nZXRQb3NpdGlvbigpLCB4ID0gX2EueCwgeSA9IF9hLnk7XG4gICAgICAgIHRoaXMuc2hhcGUgPSB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEubWl4KHtcbiAgICAgICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICAgICAgdGV4dDogY29udGVudCxcbiAgICAgICAgICAgIH0sIHRoaXMuc3R5bGUsIHtcbiAgICAgICAgICAgICAgICB0ZXh0QWxpZ246IHRoaXMuZ2V0VGV4dEFsaWduKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5zaGFwZS5uYW1lID0gdGhpcy5uYW1lO1xuICAgIH07XG4gICAgVGV4dERlc2NyaXB0aW9uLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuYWxpZ25UbyA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICByZXR1cm4geyB4OiB0aGlzLmxlZnRNYXJnaW4sIHk6IHRoaXMudG9wTWFyZ2luIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5hbGlnblRvID09PSAnbWlkZGxlJykge1xuICAgICAgICAgICAgcmV0dXJuIHsgeDogdGhpcy5sZWZ0TWFyZ2luICsgdGhpcy53cmFwcGVyV2lkdGggLyAyLCB5OiB0aGlzLnRvcE1hcmdpbiB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHsgeDogdGhpcy5yaWdodE1hcmdpbiwgeTogdGhpcy50b3BNYXJnaW4gfTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVGV4dERlc2NyaXB0aW9uLnByb3RvdHlwZS5nZXRUZXh0QWxpZ24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmFsaWduVG8gPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgcmV0dXJuICdsZWZ0JztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmFsaWduVG8gPT09ICdtaWRkbGUnKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2NlbnRlcic7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gJ3JpZ2h0JztcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqXG4gICAgICog5b2TdGV4dOi/h+mVv+aXtu+8jOm7mOiupOaNouihjFxuICAgICAqIDEuIOazqOaEj+WIneWni3RleHTluKbmjaLooYznrKbnmoTlnLrmma9cbiAgICAgKi9cbiAgICBUZXh0RGVzY3JpcHRpb24ucHJvdG90eXBlLnRleHRXcmFwcGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd2lkdGggPSB0aGlzLndyYXBwZXJXaWR0aDtcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5zdHlsZTtcbiAgICAgICAgdmFyIHRleHRDb250ZW50ID0gdGhpcy50ZXh0O1xuICAgICAgICB2YXIgdFNoYXBlID0gdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHRleHQ6ICcnLCB4OiAwLCB5OiAwIH0sIHN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB0ZXh0QXJyID0gdGV4dENvbnRlbnQuc3BsaXQoJ1xcbicpO1xuICAgICAgICB2YXIgd3JhcHBlZFRleHRBcnIgPSB0ZXh0QXJyLm1hcChmdW5jdGlvbiAod3JhcHBlZFRleHQpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0ID0gJyc7XG4gICAgICAgICAgICB2YXIgY2hhcnMgPSB3cmFwcGVkVGV4dC5zcGxpdCgnJyk7XG4gICAgICAgICAgICB2YXIgYnJlYWtJbmRleCA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBpdGVtID0gY2hhcnNbaV07XG4gICAgICAgICAgICAgICAgdFNoYXBlLmF0dHIoJ3RleHQnLCAodGV4dCArPSBpdGVtKSk7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRXaWR0aCA9IHRTaGFwZS5nZXRCQm94KCkud2lkdGggLSAxO1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50V2lkdGggPiB3aWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzmmK/nrKzkuIDkuKrlrZfnrKblsLHlpKfkuo7lrr3luqbkuI3lgZrku7vkvZXmjaLooYzlpITnkIZcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrSW5kZXgucHVzaChpKTtcbiAgICAgICAgICAgICAgICAgICAgdGV4dCA9ICcnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb21tb25fMS5icmVha1RleHQoY2hhcnMsIGJyZWFrSW5kZXgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdFNoYXBlLnJlbW92ZSgpO1xuICAgICAgICByZXR1cm4gd3JhcHBlZFRleHRBcnIuam9pbignXFxuJyk7XG4gICAgfTtcbiAgICByZXR1cm4gVGV4dERlc2NyaXB0aW9uO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRleHREZXNjcmlwdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlc2NyaXB0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRDb21wb25lbnRTdGF0ZU1ldGhvZCA9IGV4cG9ydHMuZ2V0Q29tcG9uZW50ID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vLyBjb21wb25lbnRzIHBhcnNlclxudmFyIHBhcnNlcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYXhpcy9wYXJzZXJcIikpO1xudmFyIGd1aWRlX2xpbmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2d1aWRlLWxpbmVcIikpO1xudmFyIHBhcnNlcl8yID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGFiZWwvcGFyc2VyXCIpKTtcbi8vIGNvbXBvbmVudHMgc3RhdGUgbWV0aG9kc1xudmFyIHN0YXRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9heGlzL3N0YXRlXCIpKTtcbnZhciBzdGF0ZV8yID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGFiZWwvc3RhdGVcIikpO1xudmFyIHN0YXRlXzMgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi90b29sdGlwL3N0YXRlXCIpKTtcbnZhciBDT01QT05FTlRfTUFQUEVSID0ge1xuICAgIGF4aXM6IHBhcnNlcl8xLmRlZmF1bHQsXG4gICAgbGFiZWw6IHBhcnNlcl8yLmRlZmF1bHQsXG4gICAgZ3VpZGVMaW5lOiBndWlkZV9saW5lXzEuZGVmYXVsdCxcbn07XG52YXIgU1RBVEVfTUFQUEVSID0ge1xuICAgIHRvb2x0aXA6IHN0YXRlXzMuZGVmYXVsdCxcbiAgICBsYWJlbDogc3RhdGVfMi5kZWZhdWx0LFxuICAgIGF4aXM6IHN0YXRlXzEuZGVmYXVsdCxcbn07XG5mdW5jdGlvbiBnZXRDb21wb25lbnQobmFtZSwgY2ZnKSB7XG4gICAgdmFyIENvbXBvbmVudHMgPSBDT01QT05FTlRfTUFQUEVSW25hbWVdO1xuICAgIHJldHVybiBuZXcgQ29tcG9uZW50cyhjZmcpLmNvbmZpZztcbn1cbmV4cG9ydHMuZ2V0Q29tcG9uZW50ID0gZ2V0Q29tcG9uZW50O1xuZnVuY3Rpb24gZ2V0Q29tcG9uZW50U3RhdGVNZXRob2QobmFtZSwgdHlwZSkge1xuICAgIHJldHVybiBTVEFURV9NQVBQRVJbbmFtZV1bdHlwZV07XG59XG5leHBvcnRzLmdldENvbXBvbmVudFN0YXRlTWV0aG9kID0gZ2V0Q29tcG9uZW50U3RhdGVNZXRob2Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mYWN0b3J5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiQGFudHYvc2NhbGVcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbWF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0aFwiKTtcbnZhciBHdWlkZUxpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gR3VpZGVMaW5lKGNmZykge1xuICAgICAgICB1dGlsXzEuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgICAgIHRoaXMuX2luaXQoKTtcbiAgICB9XG4gICAgR3VpZGVMaW5lLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5wbG90Lm9wdGlvbnMsIHlGaWVsZCA9IF9hLnlGaWVsZCwgZGF0YSA9IF9hLmRhdGE7XG4gICAgICAgIHZhciBwbG90RGF0YSA9IHRoaXMucGxvdC5wcm9jZXNzRGF0YShkYXRhKTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0VtcHR5KHBsb3REYXRhKSB8fCAhdXRpbF8xLmlzTnVtYmVyKHBsb3REYXRhWzBdW3lGaWVsZF0pKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRlZmF1bHRTdHlsZSA9IHRoaXMuZ2V0RGVmYXVsdFN0eWxlKCk7XG4gICAgICAgIHZhciBiYXNlQ29uZmlnID0ge1xuICAgICAgICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgdG9wOiB0cnVlLFxuICAgICAgICAgICAgc3RhcnQ6IHRoaXMuY2ZnLnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiB0aGlzLmNmZy5lbmQsXG4gICAgICAgIH07XG4gICAgICAgIGJhc2VDb25maWcuc3R5bGUgPSB1dGlsXzEuZGVlcE1peCh7fSwgZGVmYXVsdFN0eWxlLmxpbmUuc3R5bGUsIHRoaXMuY2ZnLmxpbmVTdHlsZSk7XG4gICAgICAgIGJhc2VDb25maWcudGV4dCA9IHV0aWxfMS5kZWVwTWl4KHt9LCBkZWZhdWx0U3R5bGUudGV4dCwgdGhpcy5jZmcudGV4dCk7XG4gICAgICAgIGlmICh0aGlzLmNmZy50eXBlKSB7XG4gICAgICAgICAgICB2YXIgc3RhdGVWYWx1ZSA9IHRoaXMuX2dldFN0YXRlKHRoaXMuY2ZnLnR5cGUpO1xuICAgICAgICAgICAgdmFyIHNjYWxlID0gdGhpcy5nZXRZU2NhbGUoKTtcbiAgICAgICAgICAgIHZhciBwZXJjZW50ID0gKDEuMCAtIHNjYWxlLnNjYWxlKHN0YXRlVmFsdWUpKSAqIDEwMCArIFwiJVwiO1xuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gWycwJScsIHBlcmNlbnRdO1xuICAgICAgICAgICAgdmFyIGVuZCA9IFsnMTAwJScsIHBlcmNlbnRdO1xuICAgICAgICAgICAgdGhpcy5jb25maWcgPSB1dGlsXzEubWl4KHtcbiAgICAgICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICAgICAgZW5kOiBlbmQsXG4gICAgICAgICAgICB9LCBiYXNlQ29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBfYiA9IHRoaXMuY2ZnLCBzdGFydF8xID0gX2Iuc3RhcnQsIGVuZF8xID0gX2IuZW5kO1xuICAgICAgICAgICAgdGhpcy5jb25maWcgPSB1dGlsXzEuY2xvbmUoYmFzZUNvbmZpZyk7XG4gICAgICAgICAgICB2YXIgeFNjYWxlXzEgPSB0aGlzLmdldFhTY2FsZSgpO1xuICAgICAgICAgICAgdmFyIHlTY2FsZV8xID0gdGhpcy5nZXRZU2NhbGUoKTtcbiAgICAgICAgICAgIHZhciBzdGFydERhdGFfMSA9IHV0aWxfMS5jbG9uZShzdGFydF8xKTtcbiAgICAgICAgICAgIHZhciBlbmREYXRhXzEgPSB1dGlsXzEuY2xvbmUoZW5kXzEpO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goc3RhcnRfMSwgZnVuY3Rpb24gKHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGlmICghdXRpbF8xLmNvbnRhaW5zKHV0aWxfMS50b0FycmF5KHN0YXJ0XzFbaW5kZXhdKSwgJyUnKSB8fCB1dGlsXzEuaXNOdW1iZXIoc3RhcnRfMVtpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnREYXRhXzFbaW5kZXhdID0geFNjYWxlXzEuc2NhbGUoc3RhcnRfMVswXSkgKiAxMDAgKyBcIiVcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0RGF0YV8xW2luZGV4XSA9ICgxLjAgLSB5U2NhbGVfMS5zY2FsZShzdGFydF8xWzFdKSkgKiAxMDAgKyBcIiVcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZW5kXzEsIGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXV0aWxfMS5jb250YWlucyh1dGlsXzEudG9BcnJheShlbmRfMVtpbmRleF0pLCAnJScpIHx8IHV0aWxfMS5pc051bWJlcihlbmRfMVtpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5kRGF0YV8xW2luZGV4XSA9IHhTY2FsZV8xLnNjYWxlKGVuZF8xWzBdKSAqIDEwMCArIFwiJVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5kRGF0YV8xW2luZGV4XSA9ICgxLjAgLSB5U2NhbGVfMS5zY2FsZShlbmRfMVsxXSkpICogMTAwICsgXCIlXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnN0YXJ0ID0gc3RhcnREYXRhXzE7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5lbmQgPSBlbmREYXRhXzE7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEd1aWRlTGluZS5wcm90b3R5cGUuZ2V0WVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWluVmFsdWUgPSB0aGlzLl9nZXRTdGF0ZSgnbWluJyk7XG4gICAgICAgIHZhciBtYXhWYWx1ZSA9IHRoaXMuX2dldFN0YXRlKCdtYXgnKTtcbiAgICAgICAgdmFyIFNjYWxlID0gc2NhbGVfMS5nZXRTY2FsZSgnbGluZWFyJyk7XG4gICAgICAgIC8vIOmHjeaWsOe7hOe7h3NjYWxl5bm25L2/55Soc2NhbGXnmoRtaW7lkoxtYXjmnaXorqHnrpdndWlkZSBwb2ludOeahOeZvuWIhuavlOS9jee9ru+8jOS7pemBv+WFjeWPl25pY2XnmoTlvbHlk41cbiAgICAgICAgdmFyIHNjYWxlID0gbmV3IFNjYWxlKHV0aWxfMS5taXgoe30sIHtcbiAgICAgICAgICAgIG1pbjogdGhpcy5wbG90LnR5cGUgPT09ICdjb2x1bW4nID8gMCA6IG1pblZhbHVlLFxuICAgICAgICAgICAgbWF4OiBtYXhWYWx1ZSxcbiAgICAgICAgICAgIG5pY2U6IHRydWUsXG4gICAgICAgICAgICB2YWx1ZXM6IHRoaXMudmFsdWVzLFxuICAgICAgICB9LCB0aGlzLnBsb3QuY29uZmlnLnNjYWxlc1t0aGlzLnBsb3Qub3B0aW9ucy55RmllbGRdKSk7XG4gICAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9O1xuICAgIEd1aWRlTGluZS5wcm90b3R5cGUuZ2V0WFNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsdWVzID0gdGhpcy5leHRyYWN0WFZhbHVlKCk7XG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcodmFsdWVzWzBdKSkge1xuICAgICAgICAgICAgdmFyIFNjYWxlID0gc2NhbGVfMS5nZXRTY2FsZSgnY2F0Jyk7XG4gICAgICAgICAgICB2YXIgc2NhbGUgPSBuZXcgU2NhbGUodXRpbF8xLm1peCh7fSwge1xuICAgICAgICAgICAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgICAgICAgICAgfSwgdGhpcy5wbG90LmNvbmZpZy5zY2FsZXNbdGhpcy5wbG90Lm9wdGlvbnMueEZpZWxkXSkpO1xuICAgICAgICAgICAgcmV0dXJuIHNjYWxlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIG1pbiA9IE1hdGgubWluLmFwcGx5KE1hdGgsIHZhbHVlcyk7XG4gICAgICAgICAgICB2YXIgbWF4ID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgdmFsdWVzKTtcbiAgICAgICAgICAgIHZhciBTY2FsZSA9IHNjYWxlXzEuZ2V0U2NhbGUoJ2xpbmVhcicpO1xuICAgICAgICAgICAgdmFyIHNjYWxlID0gbmV3IFNjYWxlKHV0aWxfMS5taXgoe30sIHtcbiAgICAgICAgICAgICAgICBtaW46IG1pbixcbiAgICAgICAgICAgICAgICBtYXg6IG1heCxcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgICAgICAgICAgfSwgdGhpcy5wbG90LmNvbmZpZy5zY2FsZXNbdGhpcy5wbG90Lm9wdGlvbnMueEZpZWxkXSkpO1xuICAgICAgICAgICAgcmV0dXJuIHNjYWxlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBHdWlkZUxpbmUucHJvdG90eXBlLl9nZXRTdGF0ZSA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsdWVzID0gdGhpcy5fZXh0cmFjdFZhbHVlcygpO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ21lZGlhbicpIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRoXzEuZ2V0TWVkaWFuKHRoaXMudmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ21lYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0aF8xLmdldE1lYW4odGhpcy52YWx1ZXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4LmFwcGx5KE1hdGgsIHRoaXMudmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ21pbicpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1pbi5hcHBseShNYXRoLCB0aGlzLnZhbHVlcyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEd1aWRlTGluZS5wcm90b3R5cGUuX2V4dHJhY3RWYWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgZmllbGQgPSBwcm9wcy55RmllbGQ7XG4gICAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLnBsb3QucHJvY2Vzc0RhdGEocHJvcHMuZGF0YSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGRhdGEsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoZFtmaWVsZF0pKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2guYXBwbHkodmFsdWVzLCBkW2ZpZWxkXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChkW2ZpZWxkXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH07XG4gICAgR3VpZGVMaW5lLnByb3RvdHlwZS5leHRyYWN0WFZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIGZpZWxkID0gcHJvcHMueEZpZWxkO1xuICAgICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5wbG90LnByb2Nlc3NEYXRhKHByb3BzLmRhdGEpO1xuICAgICAgICB1dGlsXzEuZWFjaChkYXRhLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0FycmF5KGRbZmllbGRdKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoLmFwcGx5KHZhbHVlcywgZFtmaWVsZF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goZFtmaWVsZF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9O1xuICAgIEd1aWRlTGluZS5wcm90b3R5cGUuZ2V0RGVmYXVsdFN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmdldERlZmF1bHRUZXh0QWxpZ24oKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDIsXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJyMzMzMzMzMnLFxuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjcsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVEYXNoOiBbMCwgMF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgY29udGVudDogJycsXG4gICAgICAgICAgICAgICAgb2Zmc2V0WTogLTUsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDE0LFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICd3aGl0ZScsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiB0aGlzLmdldERlZmF1bHRUZXh0QWxpZ24oKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIEd1aWRlTGluZS5wcm90b3R5cGUuZ2V0RGVmYXVsdFRleHRBbGlnbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRleHRDb25maWcgPSB0aGlzLmNmZy50ZXh0O1xuICAgICAgICBpZiAodGV4dENvbmZpZykge1xuICAgICAgICAgICAgaWYgKCF0ZXh0Q29uZmlnLnBvc2l0aW9uIHx8IHRleHRDb25maWcucG9zaXRpb24gPT09ICdzdGFydCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2xlZnQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRleHRDb25maWcucG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdjZW50ZXInO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRleHRDb25maWcucG9zaXRpb24gPT09ICdlbmQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdyaWdodCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBHdWlkZUxpbmU7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3VpZGVMaW5lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z3VpZGUtbGluZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0TGFiZWxDb21wb25lbnQgPSBleHBvcnRzLnJlZ2lzdGVyTGFiZWxDb21wb25lbnQgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgTGFiZWxDb21wb25lbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTGFiZWxDb21wb25lbnQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGFiZWxDb21wb25lbnQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5sYWJlbHNDZmdNYXAgPSB7fTtcbiAgICAgICAgX3RoaXMubGFzdExhYmVsc0NmZ01hcCA9IHt9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2VvbWV0cnk7XG4gICAgfTtcbiAgICBMYWJlbENvbXBvbmVudC5wcm90b3R5cGUuZ2V0TGFiZWxzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sYWJlbHM7XG4gICAgfTtcbiAgICBMYWJlbENvbXBvbmVudC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2hvdygpO1xuICAgIH07XG4gICAgTGFiZWxDb21wb25lbnQucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmhpZGUoKTtcbiAgICB9O1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5pbml0Q29uZmlnID0gZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmxheWVyID0gY29uZmlnLmxheWVyO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMubGF5ZXIudmlldztcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdGhpcy5nZW9tZXRyeSA9IGNvbmZpZy5nZW9tZXRyeTtcbiAgICAgICAgdGhpcy5jb29yZCA9IHZpZXcuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB1dGlsXzEuZGVlcE1peCh0aGlzLmdldERlZmF1bHRPcHRpb25zKCksIGNvbmZpZy5sYWJlbCk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmNsZWFyKCk7XG4gICAgICAgICAgICBfdGhpcy5sYWJlbHNDZmdNYXAgPSB7fTtcbiAgICAgICAgICAgIF90aGlzLmxhc3RMYWJlbHNDZmdNYXAgPSB7fTtcbiAgICAgICAgICAgIF90aGlzLnJlbmRlcigpO1xuICAgICAgICB9O1xuICAgICAgICB2aWV3Lm9uKGRlcGVuZGVudHNfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1BBSU5ULCBjYWxsYmFjayk7XG4gICAgICAgIHRoaXMuYWRkRGlzcG9zYWJsZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2aWV3Lm9mZihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9QQUlOVCwgY2FsbGJhY2spO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmxhYmVscyA9IFtdO1xuICAgICAgICB0aGlzLmxhYmVsc0NmZ01hcCA9IHt9O1xuICAgICAgICAvLyDnu5jliLYgTGFiZWwg5Zu+5b2iXG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZ2VvbWV0cnkuZWxlbWVudHMsIGZ1bmN0aW9uIChlbGVtZW50LCBlbGVtZW50SWR4KSB7XG4gICAgICAgICAgICB2YXIgbGFiZWxzID0gW10uY29uY2F0KF90aGlzLmRyYXdMYWJlbEl0ZW0oZ3JvdXAsIGVsZW1lbnQsIGVsZW1lbnRJZHgpKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsLCBpZHgpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5hZGp1c3RMYWJlbChsYWJlbCwgZWxlbWVudCwgaWR4KTtcbiAgICAgICAgICAgICAgICBpZiAoIWxhYmVsLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5sYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmxhYmVsc0NmZ01hcFtsYWJlbC5nZXQoJ2lkJyldID0gdXRpbF8xLmNsb25lKGxhYmVsLmF0dHJzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOaJp+ihjOW4g+WxgFxuICAgICAgICB0aGlzLmxheW91dExhYmVscyh0aGlzLmdlb21ldHJ5LCB0aGlzLmxhYmVscyk7XG4gICAgICAgIC8vIOaJp+ihjOWKqOeUu++8muWPgueFpyBHMiBMYWJlbCDliqjnlLtcbiAgICAgICAgdmFyIGxhc3RMYWJlbHNDZmdNYXAgPSB0aGlzLmxhc3RMYWJlbHNDZmdNYXA7XG4gICAgICAgIHZhciBsYWJlbHNDZmdNYXAgPSB0aGlzLmxhYmVsc0NmZ01hcDtcbiAgICAgICAgdmFyIGFuaW1hdGVDZmcgPSB0aGlzLmdlb21ldHJ5LmFuaW1hdGVPcHRpb24gPyBkZXBlbmRlbnRzXzEuZ2V0RGVmYXVsdEFuaW1hdGVDZmcoJ2xhYmVsJywgdGhpcy5jb29yZCkgOiBmYWxzZTtcbiAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxzQ2ZnTWFwLCBmdW5jdGlvbiAoYXR0cnMsIGlkKSB7XG4gICAgICAgICAgICB2YXIgc2hhcGUgPSBncm91cC5maW5kQnlJZChpZCk7XG4gICAgICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICAgICAgICBpZiAobGFzdExhYmVsc0NmZ01hcFtpZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZEF0dHJzID0gbGFzdExhYmVsc0NmZ01hcFtpZF07XG4gICAgICAgICAgICAgICAgICAgIC8vIOWbvuW9ouWPkeeUn+abtOaWsFxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlQW5pbWF0ZUNmZyA9IHV0aWxfMS5nZXQoYW5pbWF0ZUNmZywgJ3VwZGF0ZScpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodXBkYXRlQW5pbWF0ZUNmZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGUuc3RvcEFuaW1hdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlLmF0dHIob2xkQXR0cnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW50c18xLmRvQW5pbWF0ZShzaGFwZSwgdXBkYXRlQW5pbWF0ZUNmZywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvQXR0cnM6IHRzbGliXzEuX19hc3NpZ24oe30sIGF0dHJzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlOiBfdGhpcy5jb29yZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyDmlrDnlJ/miJDnmoQgc2hhcGVcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGVhckFuaW1hdGVDZmcgPSB1dGlsXzEuZ2V0KGFuaW1hdGVDZmcsICdhcHBlYXInKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFwcGVhckFuaW1hdGVDZmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbnRzXzEuZG9BbmltYXRlKHNoYXBlLCBhcHBlYXJBbmltYXRlQ2ZnLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9BdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcGUuYXR0cigpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlOiBfdGhpcy5jb29yZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGxhc3RMYWJlbHNDZmdNYXBbaWRdO1xuICAgICAgICB9KTtcbiAgICAgICAgdXRpbF8xLmVhY2gobGFzdExhYmVsc0NmZ01hcCwgZnVuY3Rpb24gKGF0dHJzLCBpZCkge1xuICAgICAgICAgICAgLy8g56e76ZmkXG4gICAgICAgICAgICB2YXIgbGVhdmVBbmltYXRlQ2ZnID0gdXRpbF8xLmdldChhbmltYXRlQ2ZnLCAnbGVhdmUnKTtcbiAgICAgICAgICAgIGlmIChsZWF2ZUFuaW1hdGVDZmcpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGVtcFNoYXBlID0gZ3JvdXAuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbGFiZWwnLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRlbXBTaGFwZS5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgICAgIGRlcGVuZGVudHNfMS5kb0FuaW1hdGUodGVtcFNoYXBlLCBsZWF2ZUFuaW1hdGVDZmcsIHtcbiAgICAgICAgICAgICAgICAgICAgdG9BdHRyczogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZTogX3RoaXMuY29vcmQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxhc3RMYWJlbHNDZmdNYXAgPSB0aGlzLmxhYmVsc0NmZ01hcDtcbiAgICB9O1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5kcmF3TGFiZWxUZXh0ID0gZnVuY3Rpb24gKGdyb3VwLCBhdHRycywgZXh0cmFDZmdzKSB7XG4gICAgICAgIGlmIChleHRyYUNmZ3MgPT09IHZvaWQgMCkgeyBleHRyYUNmZ3MgPSB7fTsgfVxuICAgICAgICByZXR1cm4gZ3JvdXAuYWRkU2hhcGUoJ3RleHQnLCB0c2xpYl8xLl9fYXNzaWduKHsgYXR0cnM6IGF0dHJzIH0sIGV4dHJhQ2ZncykpO1xuICAgIH07XG4gICAgTGFiZWxDb21wb25lbnQucHJvdG90eXBlLmRyYXdMYWJlbEl0ZW0gPSBmdW5jdGlvbiAoZ3JvdXAsIGVsZW1lbnQsIGVsZW1lbnRJbmRleCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbW9kZWwgPSBlbGVtZW50LmdldE1vZGVsKCk7XG4gICAgICAgIHZhciBpdGVtcyA9IFtdLmNvbmNhdCh0aGlzLmdldExhYmVsSXRlbUF0dHJzKGVsZW1lbnQsIGVsZW1lbnRJbmRleCkpO1xuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KCk7XG4gICAgICAgIHZhciBvZmZzZXRQb2ludCA9IHRoaXMuZ2V0TGFiZWxPZmZzZXQoKTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5tYXAoaXRlbXMsIGZ1bmN0aW9uIChhdHRycywgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IHtcbiAgICAgICAgICAgICAgICB4OiBhdHRycy54ICsgb2Zmc2V0UG9pbnQueCxcbiAgICAgICAgICAgICAgICB5OiBhdHRycy55ICsgb2Zmc2V0UG9pbnQueSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB2YXIgZGF0YUl0ZW0gPSB1dGlsXzEuaXNBcnJheShtb2RlbC5tYXBwaW5nRGF0YSkgPyBtb2RlbC5tYXBwaW5nRGF0YVtpbmRleF0gOiBtb2RlbC5tYXBwaW5nRGF0YTtcbiAgICAgICAgICAgIHZhciBpZCA9IF90aGlzLmdldExhYmVsSWQoZGF0YUl0ZW0pO1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmRyYXdMYWJlbFRleHQoZ3JvdXAsIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgYXR0cnMpLCBwb3NpdGlvbiksIChfYSA9IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbGFiZWwnLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgX2FbZGVwZW5kZW50c18xLk9SSUdJTl0gPSBkYXRhSXRlbSxcbiAgICAgICAgICAgICAgICBfYSkpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDojrflj5blvZPliY0gTGFiZWwg55qEIG9mZnNldCAqL1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5nZXREZWZhdWx0T2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gTnVtYmVyKHRoaXMub3B0aW9ucy5vZmZzZXQpO1xuICAgIH07XG4gICAgLyoqIOm7mOiupOWunueOsO+8muiOt+WPluW9k+WJjSBMYWJlbCDnmoQgb2Zmc2V0IOeCue+8muWMheaLrCBvZmZzZXTjgIFvZmZzZXRY44CBb2Zmc2V0WSAqL1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5nZXRMYWJlbE9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB1dGlsXzEuaXNOdW1iZXIob2Zmc2V0WCkgPyBvZmZzZXRYIDogMCxcbiAgICAgICAgICAgIHk6IHV0aWxfMS5pc051bWJlcihvZmZzZXRZKSA/IG9mZnNldFkgOiAwLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqIOmAmui/h+aMh+WumuaWueWQkeWSjOezu+aVsOiOt+WPluaVtOS9kyBvZmZzZXQg54K5ICovXG4gICAgTGFiZWxDb21wb25lbnQucHJvdG90eXBlLmdldExhYmVsT2Zmc2V0QnlEaW1BbmRGYWN0b3IgPSBmdW5jdGlvbiAoZGltLCBmYWN0b3IpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFk7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLmdldERlZmF1bHRPZmZzZXQoKTtcbiAgICAgICAgdmFyIG9mZnNldFBvaW50ID0ge1xuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgIH07XG4gICAgICAgIG9mZnNldFBvaW50W2RpbV0gPSBvZmZzZXQgKiBmYWN0b3I7XG4gICAgICAgIGlmICh1dGlsXzEuaXNOdW1iZXIob2Zmc2V0WCkpIHtcbiAgICAgICAgICAgIG9mZnNldFBvaW50LnggKz0gb2Zmc2V0WDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKG9mZnNldFkpKSB7XG4gICAgICAgICAgICBvZmZzZXRQb2ludC55ICs9IG9mZnNldFk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9mZnNldFBvaW50O1xuICAgIH07XG4gICAgLyoqIOWIneWni+WMlum7mOiupOWFqOWxgOmFjee9riAqL1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH07XG4gICAgLyoqIOaVtOeQhuWvueaJgOaciSBMYWJlbHMg55qE5biD5bGA6LCD5pW0ICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIExhYmVsQ29tcG9uZW50LnByb3RvdHlwZS5sYXlvdXRMYWJlbHMgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGxhYmVscykge1xuICAgICAgICAvLyBlbXB0eVxuICAgIH07XG4gICAgTGFiZWxDb21wb25lbnQucHJvdG90eXBlLmdldExhYmVsSWQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgb3JpZ2luID0gZGF0YS5fb3JpZ2luO1xuICAgICAgICB2YXIgdHlwZSA9IHRoaXMuZ2VvbWV0cnkudHlwZTtcbiAgICAgICAgdmFyIHhTY2FsZSA9IHRoaXMuZ2VvbWV0cnkuZ2V0WFNjYWxlKCk7XG4gICAgICAgIHZhciB5U2NhbGUgPSB0aGlzLmdlb21ldHJ5LmdldFlTY2FsZSgpO1xuICAgICAgICB2YXIgbGFiZWxJZCA9IHRoaXMuZ2VvbWV0cnkuZ2V0RWxlbWVudElkKGRhdGEpO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2xpbmUnIHx8IHR5cGUgPT09ICdhcmVhJykge1xuICAgICAgICAgICAgLy8g5oqY57q/5Zu+5Lul5Y+K5Yy65Z+f5Zu+77yM5LiA5p2h57q/5Lya5a+55bqU5LiA57uE5pWw5o2u77yM5Y2z5aSa5LiqIGxhYmVsc++8jOS4uuS6huWMuuWIhui/meS6myBsYWJlbHPvvIzpnIDopoHlnKggbGluZSBpZCDnmoTliY3mj5DkuIvliqDkuIogeCDlrZfmrrXlgLxcbiAgICAgICAgICAgIGxhYmVsSWQgKz0gXCIgXCIgKyBvcmlnaW5beFNjYWxlLmZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlID09PSAncGF0aCcpIHtcbiAgICAgICAgICAgIC8vIHBhdGgg6Lev5b6E5Zu+77yM5peg5bqP77yM5pyJ5Y+v6IO95a2Y5Zyo55u45ZCMIHgg5LiN5ZCMIHkg55qE5oOF5Ya177yM6ZyA6KaB6YCa6L+HIHggeSDmnaXnoa7lrprllK/kuIAgaWRcbiAgICAgICAgICAgIGxhYmVsSWQgKz0gXCIgXCIgKyBvcmlnaW5beFNjYWxlLmZpZWxkXSArIFwiLVwiICsgb3JpZ2luW3lTY2FsZS5maWVsZF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxhYmVsSWQ7XG4gICAgfTtcbiAgICBMYWJlbENvbXBvbmVudC5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZUJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb29yZCA9IHRoaXMuY29vcmQ7XG4gICAgICAgIHZhciBzdGFydCA9IGNvb3JkLnN0YXJ0LCBlbmQgPSBjb29yZC5lbmQ7XG4gICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQoTWF0aC5taW4oc3RhcnQueCwgZW5kLngpLCBNYXRoLm1pbihzdGFydC55LCBlbmQueSksIGNvb3JkLmdldFdpZHRoKCksIGNvb3JkLmdldEhlaWdodCgpKTtcbiAgICB9O1xuICAgIHJldHVybiBMYWJlbENvbXBvbmVudDtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExhYmVsQ29tcG9uZW50O1xuLy8gTGFiZWwg57uE5Lu25rOo5YaMXG52YXIgTEFCRUxfQ09ORklHX01BUCA9IHt9O1xuZnVuY3Rpb24gcmVnaXN0ZXJMYWJlbENvbXBvbmVudCh0eXBlLCBjb21wb25lbnQpIHtcbiAgICBMQUJFTF9DT05GSUdfTUFQW3R5cGVdID0gY29tcG9uZW50O1xufVxuZXhwb3J0cy5yZWdpc3RlckxhYmVsQ29tcG9uZW50ID0gcmVnaXN0ZXJMYWJlbENvbXBvbmVudDtcbmZ1bmN0aW9uIGdldExhYmVsQ29tcG9uZW50KHR5cGUpIHtcbiAgICByZXR1cm4gTEFCRUxfQ09ORklHX01BUFt0eXBlXTtcbn1cbmV4cG9ydHMuZ2V0TGFiZWxDb21wb25lbnQgPSBnZXRMYWJlbENvbXBvbmVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBmb3JtYXR0ZXJfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2Zvcm1hdHRlclwiKTtcbnZhciBMYWJlbFBhcnNlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMYWJlbFBhcnNlcihjZmcpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSB7fTtcbiAgICAgICAgdmFyIHBsb3QgPSBjZmcucGxvdCwgcmVzdCA9IHRzbGliXzEuX19yZXN0KGNmZywgW1wicGxvdFwiXSk7XG4gICAgICAgIHRoaXMucGxvdCA9IHBsb3Q7XG4gICAgICAgIHRoaXMub3JpZ2luQ29uZmlnID0gcmVzdDtcbiAgICAgICAgdGhpcy5pbml0KGNmZyk7XG4gICAgfVxuICAgIExhYmVsUGFyc2VyLnByb3RvdHlwZS5nZXRDb25maWcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZztcbiAgICB9O1xuICAgIExhYmVsUGFyc2VyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuYXNzaWduKHRoaXMuY29uZmlnLCBjZmcpO1xuICAgICAgICB0aGlzLmNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5wYXJzZUNhbGxCYWNrKHZhbCk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBMYWJlbFBhcnNlci5wcm90b3R5cGUucGFyc2VDYWxsQmFjayA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgdmFyIGxhYmVsUHJvcHMgPSB0aGlzLm9yaWdpbkNvbmZpZztcbiAgICAgICAgdmFyIHRoZW1lID0gdGhpcy5wbG90LmdldFBsb3RUaGVtZSgpO1xuICAgICAgICB2YXIgY29uZmlnID0gdHNsaWJfMS5fX2Fzc2lnbih7fSwgbGFiZWxQcm9wcyk7XG4gICAgICAgIHRoaXMucGFyc2VPZmZzZXQobGFiZWxQcm9wcywgY29uZmlnKTtcbiAgICAgICAgaWYgKGxhYmVsUHJvcHMucG9zaXRpb24pIHtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihsYWJlbFByb3BzLnBvc2l0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5wb3NpdGlvbiA9IGxhYmVsUHJvcHMucG9zaXRpb24odmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5wb3NpdGlvbiA9IGxhYmVsUHJvcHMucG9zaXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYXJzZUZvcm1hdHRlcihjb25maWcpO1xuICAgICAgICBpZiAobGFiZWxQcm9wcy5zdHlsZSkge1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGxhYmVsUHJvcHMuc3R5bGUpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLnRleHRTdHlsZSA9IGxhYmVsUHJvcHMuc3R5bGUodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbmZpZy50ZXh0U3R5bGUgPSBsYWJlbFByb3BzLnN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbmZpZy50ZXh0U3R5bGUgPSB1dGlsXzEuZGVlcE1peCh7fSwgdXRpbF8xLmdldCh0aGVtZSwgJ2xhYmVsLnN0eWxlJyksIGNvbmZpZy50ZXh0U3R5bGUpO1xuICAgICAgICBpZiAobGFiZWxQcm9wcy5hdXRvUm90YXRlKSB7XG4gICAgICAgICAgICBjb25maWcuYXV0b1JvdGF0ZSA9IGxhYmVsUHJvcHMuYXV0b1JvdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uZmlnO1xuICAgIH07XG4gICAgTGFiZWxQYXJzZXIucHJvdG90eXBlLnBhcnNlT2Zmc2V0ID0gZnVuY3Rpb24gKHByb3BzLCBjb25maWcpIHtcbiAgICAgICAgdmFyIG1hcHBlciA9IFsnb2Zmc2V0JywgJ29mZnNldFgnLCAnb2Zmc2V0WSddO1xuICAgICAgICB2YXIgY291bnQgPSAwO1xuICAgICAgICB1dGlsXzEuZWFjaChtYXBwZXIsIGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmhhcyhwcm9wcywgbSkpIHtcbiAgICAgICAgICAgICAgICBjb25maWdbbV0gPSBwcm9wc1ttXTtcbiAgICAgICAgICAgICAgICBjb3VudCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8g5aaC55So5oi35rKh5pyJ6K6+572ub2Zmc2V077yM6ICMbGFiZWwgcG9zaXRpb27lj4jkuLptaWRkbGXml7bvvIzliJnpu5jorqTorr7nva5vZmZzZXTkuLowXG4gICAgICAgIGlmIChjb3VudCA9PT0gMCAmJiB1dGlsXzEuZ2V0KHByb3BzLCAncG9zaXRpb24nKSA9PT0gJ21pZGRsZScpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vZmZzZXQgPSAwO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMYWJlbFBhcnNlci5wcm90b3R5cGUucGFyc2VGb3JtYXR0ZXIgPSBmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgICAgIHZhciBsYWJlbFByb3BzID0gdGhpcy5vcmlnaW5Db25maWc7XG4gICAgICAgIGNvbmZpZy5jb250ZW50ID0gZnVuY3Rpb24gKGRhdGEsIGluZGV4KSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB2YXIgdGV4dCA9IGRhdGFbbGFiZWxQcm9wcy5maWVsZHNbMF1dO1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlcl8xLmNvbWJpbmVGb3JtYXR0ZXIoZm9ybWF0dGVyXzEuZ2V0Tm9vcEZvcm1hdHRlcigpLCBmb3JtYXR0ZXJfMS5nZXRQcmVjaXNpb25Gb3JtYXR0ZXIobGFiZWxQcm9wcy5wcmVjaXNpb24pLCBmb3JtYXR0ZXJfMS5nZXRTdWZmaXhGb3JtYXR0ZXIobGFiZWxQcm9wcy5zdWZmaXgpLCBsYWJlbFByb3BzLmZvcm1hdHRlclxuICAgICAgICAgICAgICAgID8gbGFiZWxQcm9wcy5mb3JtYXR0ZXJcbiAgICAgICAgICAgICAgICA6IGZvcm1hdHRlcl8xLmdldE5vb3BGb3JtYXR0ZXIoKSkodGV4dCwgZGF0YSwgaW5kZXgpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIExhYmVsUGFyc2VyO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExhYmVsUGFyc2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFyc2VyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbnZhciBwb2ludF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcG9pbnRcIikpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIHZpZXdfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3ZpZXdcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgUG9pbnRBdXRvTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUG9pbnRBdXRvTGFiZWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUG9pbnRBdXRvTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUG9pbnRBdXRvTGFiZWwucHJvdG90eXBlLmxheW91dExhYmVscyA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgbGFiZWxzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIGRvbmVzID0gW107XG4gICAgICAgIHZhciBwYW5lbCA9IGJib3hfMS5kZWZhdWx0LmZyb21CQm94T2JqZWN0KHRoaXMuZ2V0Q29vcmRpbmF0ZUJCb3goKSk7XG4gICAgICAgIHZhciBfYiA9IGdlb21ldHJ5LmdldFhZRmllbGRzKCksIHhGaWVsZCA9IF9iWzBdLCB5RmllbGQgPSBfYlsxXTtcbiAgICAgICAgdmFyIGdyb3VwZWRNYXAgPSB1dGlsXzEuZ3JvdXBCeShsYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCkgeyByZXR1cm4gbGFiZWwuZ2V0KGRlcGVuZGVudHNfMS5PUklHSU4pW2RlcGVuZGVudHNfMS5GSUVMRF9PUklHSU5dW3hGaWVsZF07IH0pO1xuICAgICAgICB2YXIgb2Zmc2V0ID0gKF9hID0gbGFiZWxzWzBdKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZ2V0KCdvZmZzZXQnKTtcbiAgICAgICAgdXRpbF8xLmVhY2godXRpbF8xLmtleXMoZ3JvdXBlZE1hcCkucmV2ZXJzZSgpLCBmdW5jdGlvbiAoeFZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgZ3JvdXAgPSBfdGhpcy5zb3J0TGFiZWxzKGdlb21ldHJ5LCBncm91cGVkTWFwW3hWYWx1ZV0pO1xuICAgICAgICAgICAgd2hpbGUgKGdyb3VwLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IGdyb3VwLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgaWYgKHZpZXdfMS5jaGVja09yaWdpbkVxdWFsKGxhYmVsLCBkb25lcywgZnVuY3Rpb24gKGRhdHVtTGVmdCwgZGF0dW1SaWdodCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0dW1MZWZ0Ll9vcmlnaW5beEZpZWxkXSA9PT0gZGF0dW1SaWdodC5fb3JpZ2luW3hGaWVsZF0gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdHVtTGVmdC5fb3JpZ2luW3lGaWVsZF0gPT09IGRhdHVtUmlnaHQuX29yaWdpblt5RmllbGRdO1xuICAgICAgICAgICAgICAgIH0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZpZXdfMS5tb3ZlSW5QYW5lbChsYWJlbCwgcGFuZWwpO1xuICAgICAgICAgICAgICAgIHZhciB1cEZhaWwgPSB2aWV3XzEuY2hlY2tTaGFwZU92ZXJsYXAobGFiZWwsIGRvbmVzKTtcbiAgICAgICAgICAgICAgICB2YXIgZG93bkZhaWwgPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgaWYgKHVwRmFpbCkge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbC5hdHRyKCd5JywgbGFiZWwuYXR0cigneScpICsgMiAqIG9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgIHZpZXdfMS5tb3ZlSW5QYW5lbChsYWJlbCwgcGFuZWwpO1xuICAgICAgICAgICAgICAgICAgICBkb3duRmFpbCA9IHZpZXdfMS5jaGVja1NoYXBlT3ZlcmxhcChsYWJlbCwgZG9uZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoZG93bkZhaWwpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG9uZXMucHVzaChsYWJlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqIOWvuSBMYWJlbHMg5o6S5bqP77yM5o6S5bqP6aG65bqP5Yaz5a6a6Ieq5Yqo5biD5bGA5LyY5YWI57qnICovXG4gICAgUG9pbnRBdXRvTGFiZWwucHJvdG90eXBlLnNvcnRMYWJlbHMgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGxhYmVscykge1xuICAgICAgICB2YXIgeUZpZWxkID0gZ2VvbWV0cnkuZ2V0WFlGaWVsZHMoKVsxXTtcbiAgICAgICAgdmFyIHNvcnRlZCA9IFtdO1xuICAgICAgICAvLyDpobrluo/vvJrnrKzkuIDkuKrjgIHmnIDlkI7kuIDkuKrjgIHlho3lhbbku5ZcbiAgICAgICAgbGFiZWxzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBiLmdldChkZXBlbmRlbnRzXzEuT1JJR0lOKVtkZXBlbmRlbnRzXzEuRklFTERfT1JJR0lOXVt5RmllbGRdIC0gYS5nZXQoZGVwZW5kZW50c18xLk9SSUdJTilbZGVwZW5kZW50c18xLkZJRUxEX09SSUdJTl1beUZpZWxkXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChsYWJlbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc29ydGVkLnB1c2gobGFiZWxzLnNoaWZ0KCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsYWJlbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc29ydGVkLnB1c2gobGFiZWxzLnBvcCgpKTtcbiAgICAgICAgfVxuICAgICAgICBzb3J0ZWQucHVzaC5hcHBseShzb3J0ZWQsIGxhYmVscyk7XG4gICAgICAgIHJldHVybiBzb3J0ZWQ7XG4gICAgfTtcbiAgICByZXR1cm4gUG9pbnRBdXRvTGFiZWw7XG59KHBvaW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG9pbnRBdXRvTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgncG9pbnQtYXV0bycsIFBvaW50QXV0b0xhYmVsKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvaW50LWF1dG8uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vLi4vZGVwZW5kZW50c1wiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9sYWJlbC9iYXNlXCIpKTtcbnZhciBjb21tb25fMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2NvbW1vblwiKTtcbi8qKlxuICog6K+05piOOlxuICog6YCC55So5LqO5bGV56S66Z2i56ev5Zu+5ZKM5oqY57q/5Zu+5LiK5pWw5o2u54K555qEbGFiZWxcbiAqICovXG52YXIgUG9pbnRMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQb2ludExhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBvaW50TGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUG9pbnRMYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aGVtZSA9IHRoaXMubGF5ZXIudGhlbWU7XG4gICAgICAgIHZhciBfYSA9IHRoZW1lLmxhYmVsLCBsYWJlbCA9IF9hID09PSB2b2lkIDAgPyB7fSA6IF9hO1xuICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih7IG9mZnNldFg6IDAsIG9mZnNldFk6IDAgfSwgbGFiZWwpO1xuICAgIH07XG4gICAgUG9pbnRMYWJlbC5wcm90b3R5cGUuZ2V0TGFiZWxPZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldExhYmVsT2Zmc2V0QnlEaW1BbmRGYWN0b3IoJ3knLCAtMSk7XG4gICAgfTtcbiAgICBQb2ludExhYmVsLnByb3RvdHlwZS5nZXRMYWJlbEl0ZW1BdHRycyA9IGZ1bmN0aW9uIChlbGVtZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHN0eWxlID0gX2Euc3R5bGUsIGZvcm1hdHRlciA9IF9hLmZvcm1hdHRlcjtcbiAgICAgICAgdmFyIG1hcHBpbmdEYXRhID0gdXRpbF8xLmdldChlbGVtZW50LCAnbW9kZWwubWFwcGluZ0RhdGEnLCBbXSk7XG4gICAgICAgIHJldHVybiB1dGlsXzEubWFwKG1hcHBpbmdEYXRhLCBmdW5jdGlvbiAoZGF0dW0sIGRhdHVtSW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IF90aGlzLmdldFZhbHVlKGRhdHVtKTtcbiAgICAgICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgX3RoaXMuZ2V0UG9zaXRpb24oZGF0dW0pKSwgeyB0ZXh0OiBmb3JtYXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgPyBmb3JtYXR0ZXIodmFsdWUsIChfYSA9IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgX2FbZGVwZW5kZW50c18xLl9PUklHSU5dID0gZGF0dW0uX29yaWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hLm1hcHBpbmdEYXR1bSA9IGRhdHVtLFxuICAgICAgICAgICAgICAgICAgICAgICAgX2EubWFwcGluZ0RhdHVtSW5kZXggPSBkYXR1bUluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgX2EuZWxlbWVudCA9IGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBfYS5lbGVtZW50SW5kZXggPSBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hKSwgaW5kZXgpXG4gICAgICAgICAgICAgICAgICAgIDogdmFsdWUsIHRleHRBbGlnbjogJ2NlbnRlcicsIHRleHRCYXNlbGluZTogJ21pZGRsZScgfSksIHN0eWxlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBQb2ludExhYmVsLnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uIChkYXR1bSkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldChkYXR1bS5fb3JpZ2luLCB0aGlzLmxheWVyLm9wdGlvbnMueUZpZWxkKTtcbiAgICB9O1xuICAgIFBvaW50TGFiZWwucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKGRhdHVtKSB7XG4gICAgICAgIHZhciBwb3MgPSB7XG4gICAgICAgICAgICB4OiB1dGlsXzEuaXNBcnJheShkYXR1bS54KSA/IHV0aWxfMS5sYXN0KGRhdHVtLngpIDogZGF0dW0ueCxcbiAgICAgICAgICAgIHk6IHV0aWxfMS5pc0FycmF5KGRhdHVtLnkpID8gdXRpbF8xLmxhc3QoZGF0dW0ueSkgOiBkYXR1bS55LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgIH07XG4gICAgUG9pbnRMYWJlbC5wcm90b3R5cGUubGF5b3V0TGFiZWxzID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBsYWJlbHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuYWRqdXN0UG9zaXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb3ZlcmxhcCA9IHRoaXMuaXNPdmVybGFwcGVkKGxhYmVscyk7XG4gICAgICAgIC8vIOinhOWImTHvvJrlhYjmqKrlkJHvvIzkvJjlhYjmmL7npLrmqKrlkJHkuIrlj5jljJbotovlir/lpKfnmoRsYWJlbFxuICAgICAgICBpZiAob3ZlcmxhcCkge1xuICAgICAgICAgICAgdmFyIHRvbGVyYW5jZV8xID0gdGhpcy5nZXRHbG9iYWxUb2xlcmFuY2UobGFiZWxzKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsLCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubGFiZWxSZXNhbXBsaW5nQnlDaGFuZ2UobGFiZWwsIGxhYmVscywgaW5kZXgsIHRvbGVyYW5jZV8xKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBvdmVybGFwID0gdGhpcy5pc092ZXJsYXBwZWQobGFiZWxzKTtcbiAgICAgICAgLy8g6KeE5YiZMu+8miDlkI7nurXlkJHvvIzkvJjlhYjkv53nlZnnurXlkJHmnIDpq5jngrlsYWJlbFxuICAgICAgICBpZiAob3ZlcmxhcCkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgaWYgKGxhYmVsLmdldCgndmlzaWJsZScpKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNsZWFyT3ZlcmxhcHBpbmcobGFiZWwsIGxhYmVscywgaW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQb2ludExhYmVsLnByb3RvdHlwZS5hZGp1c3RMYWJlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgLyoqIOagueaNruWPmOWMlui/m+ihjOaKveagt++8jOS/neeVmeWPmOWMlui+g+Wkp+eahOeCue+8jOexu+S8vOS6jueCueeugOWMlueul+azlSAqL1xuICAgIFBvaW50TGFiZWwucHJvdG90eXBlLmxhYmVsUmVzYW1wbGluZ0J5Q2hhbmdlID0gZnVuY3Rpb24gKGxhYmVsLCBsYWJlbHMsIGluZGV4LCB0b2xlcmFuY2UpIHtcbiAgICAgICAgdmFyIHByZXZpb3VzID0gdGhpcy5maW5kUHJldmlvdXMoaW5kZXgsIGxhYmVscyk7XG4gICAgICAgIHZhciBjdXJyZW50Q2VudGVyID0gdGhpcy5nZXRDZW50ZXIobGFiZWwpO1xuICAgICAgICB2YXIgcHJldmlvdXNDZW50ZXIgPSB0aGlzLmdldENlbnRlcihwcmV2aW91cyk7XG4gICAgICAgIHZhciBkaXN0WCA9IHByZXZpb3VzQ2VudGVyLnggLSBjdXJyZW50Q2VudGVyLng7XG4gICAgICAgIHZhciBkaXN0WSA9IHByZXZpb3VzQ2VudGVyLnkgLSBjdXJyZW50Q2VudGVyLnk7XG4gICAgICAgIHZhciBkaXN0ID0gTWF0aC5zcXJ0KGRpc3RYICogZGlzdFggKyBkaXN0WSAqIGRpc3RZKTtcbiAgICAgICAgaWYgKGRpc3QgPCB0b2xlcmFuY2UpIHtcbiAgICAgICAgICAgIGxhYmVsLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUG9pbnRMYWJlbC5wcm90b3R5cGUuY2xlYXJPdmVybGFwcGluZyA9IGZ1bmN0aW9uIChsYWJlbCwgbGFiZWxzLCBpbmRleCkge1xuICAgICAgICAvLyDmib7liLDmiYDmnInkuI7lvZPliY3ngrlvdmVybGFw55qEbm9kZVxuICAgICAgICB2YXIgb3ZlcmxhcHBlZCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhYmVscy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSBsYWJlbHNbaV07XG4gICAgICAgICAgICBpZiAoaSAhPT0gaW5kZXggJiYgY3VycmVudC5nZXQoJ3Zpc2libGUnKSkge1xuICAgICAgICAgICAgICAgIHZhciBpc092ZXJsYXAgPSBjb21tb25fMS5pc0JCb3hJbnRlcnNlY3QobGFiZWwuZ2V0QkJveCgpLCBjdXJyZW50LmdldEJCb3goKSk7XG4gICAgICAgICAgICAgICAgaWYgKGlzT3ZlcmxhcCkge1xuICAgICAgICAgICAgICAgICAgICBvdmVybGFwcGVkLnB1c2goY3VycmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOWvuW92ZXJhcHBlZCBsYWJlbOi/m+ihjOWkhOeQhlxuICAgICAgICBpZiAob3ZlcmxhcHBlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBvdmVybGFwcGVkLnB1c2gobGFiZWwpO1xuICAgICAgICAgICAgb3ZlcmxhcHBlZC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGIubWluWSAtIGEubWluWTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8g6ZqQ6JeP6Zmk5pyA6auY54K55Lul5aSW55qEbGFiZWxcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKG92ZXJsYXBwZWQsIGZ1bmN0aW9uIChsYWJlbCwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqIOajgOa1i+S4gOe7hGxhYmVs5Lit5piv5ZCm5a2Y5Zyo6YeN5Y+gICoqL1xuICAgIFBvaW50TGFiZWwucHJvdG90eXBlLmlzT3ZlcmxhcHBlZCA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsYWJlbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChsYWJlbHNbaV0uZ2V0KCd2aXNpYmxlJykpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWxBQkJveCA9IGxhYmVsc1tpXS5nZXRCQm94KCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsYWJlbHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGogIT09IGkgJiYgbGFiZWxzW2pdLmdldCgndmlzaWJsZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxCQkJveCA9IGxhYmVsc1tqXS5nZXRCQm94KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW50ZXJzZWN0aW9uID0gY29tbW9uXzEuaXNCQm94SW50ZXJzZWN0KGxhYmVsQUJCb3gsIGxhYmVsQkJCb3gpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludGVyc2VjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIFBvaW50TGFiZWwucHJvdG90eXBlLmdldEdsb2JhbFRvbGVyYW5jZSA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgdmFyIGxhYmVsc0Nsb25lID0gbGFiZWxzLnNsaWNlKCk7XG4gICAgICAgIGxhYmVsc0Nsb25lLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBiLmdldEJCb3goKS53aWR0aCAtIGEuZ2V0QkJveCgpLndpZHRoO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobGFiZWxzQ2xvbmVbMF0uZ2V0QkJveCgpLndpZHRoKTtcbiAgICB9O1xuICAgIFBvaW50TGFiZWwucHJvdG90eXBlLmZpbmRQcmV2aW91cyA9IGZ1bmN0aW9uIChpbmRleCwgbGFiZWxzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSBpbmRleCAtIDE7IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmIChsYWJlbHNbaV0uZ2V0KCd2aXNpYmxlJykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGFiZWxzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBQb2ludExhYmVsLnByb3RvdHlwZS5nZXRDZW50ZXIgPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgdmFyIF9hID0gbGFiZWwuZ2V0QkJveCgpLCBtaW5YID0gX2EubWluWCwgbWF4WCA9IF9hLm1heFgsIG1pblkgPSBfYS5taW5ZLCBtYXhZID0gX2EubWF4WTtcbiAgICAgICAgcmV0dXJuIHsgeDogbWluWCArIChtYXhYIC0gbWluWCkgLyAyLCB5OiBtaW5ZICsgKG1heFkgLSBtaW5ZKSAvIDIgfTtcbiAgICB9O1xuICAgIHJldHVybiBQb2ludExhYmVsO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG9pbnRMYWJlbDtcbmJhc2VfMS5yZWdpc3RlckxhYmVsQ29tcG9uZW50KCdwb2ludCcsIFBvaW50TGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cG9pbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgc3RhdGVfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2NvbnRyb2xsZXIvc3RhdGVcIik7XG4vLyDlr7lsYWJlbOWSjGxhYmVs5qC35byP6L+b6KGM57yT5a2YXG52YXIgbGFiZWxzO1xudmFyIG9yaWdpbkF0dHJzO1xuZnVuY3Rpb24gb25BY3RpdmUocGxvdCwgY29uZGl0aW9uKSB7XG4gICAgaWYgKCFsYWJlbHMpIHtcbiAgICAgICAgZ2V0QWxsTGFiZWxzKHBsb3QpO1xuICAgIH1cbiAgICB1dGlsXzEuZWFjaChsYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG9yaWdpbiA9IGxhYmVsLmdldCgnb3JpZ2luJyk7XG4gICAgICAgIGlmIChzdGF0ZV8xLmNvbXBhcmUob3JpZ2luLCBjb25kaXRpb24pKSB7XG4gICAgICAgICAgICB2YXIgb3JpZ2luQXR0ciA9IG9yaWdpbkF0dHJzW2luZGV4XTtcbiAgICAgICAgICAgIHZhciBzdHlsZSA9IHV0aWxfMS5taXgoe30sIG9yaWdpbkF0dHIsIHsgb3BhY2l0eTogMSB9KTtcbiAgICAgICAgICAgIGxhYmVsLmF0dHIoc3R5bGUpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiBvbkRpc2FibGUocGxvdCwgY29uZGl0aW9uKSB7XG4gICAgaWYgKCFsYWJlbHMpIHtcbiAgICAgICAgZ2V0QWxsTGFiZWxzKHBsb3QpO1xuICAgIH1cbiAgICB1dGlsXzEuZWFjaChsYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG9yaWdpbiA9IGxhYmVsLmdldCgnb3JpZ2luJyk7XG4gICAgICAgIGlmIChzdGF0ZV8xLmNvbXBhcmUob3JpZ2luLCBjb25kaXRpb24pKSB7XG4gICAgICAgICAgICB2YXIgb3JpZ2luQXR0ciA9IG9yaWdpbkF0dHJzW2luZGV4XTtcbiAgICAgICAgICAgIHZhciBkaXNhYmxlU3R5bGUgPSBsYWJlbERpc2FibGVTdHlsZShvcmlnaW5BdHRyKTtcbiAgICAgICAgICAgIGxhYmVsLmF0dHIoZGlzYWJsZVN0eWxlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gZ2V0QWxsTGFiZWxzKHBsb3QpIHtcbiAgICBsYWJlbHMgPSBbXTtcbiAgICBvcmlnaW5BdHRycyA9IFtdO1xuICAgIHZhciBnZW9tcyA9IHBsb3Qudmlldy5nZXQoJ2VsZW1lbnRzJyk7XG4gICAgdXRpbF8xLmVhY2goZ2VvbXMsIGZ1bmN0aW9uIChnZW9tKSB7XG4gICAgICAgIHZhciBnZW9tTGFiZWxzID0gZ2VvbS5nZXQoJ2xhYmVscycpO1xuICAgICAgICBpZiAoZ2VvbUxhYmVscykge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZ2VvbUxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxzLnB1c2gobGFiZWwpO1xuICAgICAgICAgICAgICAgIG9yaWdpbkF0dHJzLnB1c2gobGFiZWwuYXR0cigpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiBsYWJlbERpc2FibGVTdHlsZShzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IG9wYWNpdHk6IG9wYWNpdHkgKiAwLjIgfTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICBhY3RpdmU6IG9uQWN0aXZlLFxuICAgIHNlbGVjdGVkOiBvbkFjdGl2ZSxcbiAgICBkaXNhYmxlOiBvbkRpc2FibGUsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vZGVwZW5kZW50c1wiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBhbmltYXRlXzEgPSByZXF1aXJlKFwiQGFudHYvZzIvbGliL2FuaW1hdGVcIik7XG52YXIgREVGQVVMVF9TVFlMRSA9IHtcbiAgICBzdHJva2U6ICd0cmFuc3BhcmVudCcsXG4gICAgZmlsbDogJyNGQ0M1MDknLFxuICAgIGxpbmVXaWR0aDogMCxcbn07XG52YXIgQUNUSVZFX1NUWUxFID0ge1xuICAgIHN0cm9rZTogJyNGRkYnLFxuICAgIGZpbGw6ICcjRkNDNTA5JyxcbiAgICBsaW5lV2lkdGg6IDEsXG59O1xudmFyIFNFTEVDVEVEX1NUWUxFID0ge1xuICAgIHN0cm9rZTogJ3JnYmEoMCwwLDAsMC44NSknLFxuICAgIGZpbGw6ICcjRkNDNTA5JyxcbiAgICBsaW5lV2lkdGg6IDEsXG59O1xuLyoqXG4gKiDmoIfms6jngrkg57uY5Yi25Zyo5pyA6aG25bGCXG4gKi9cbnZhciBNYXJrZXJQb2ludCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNYXJrZXJQb2ludChjZmcpIHtcbiAgICAgICAgdGhpcy5wb2ludHMgPSBbXTtcbiAgICAgICAgdGhpcy5sYWJlbHMgPSBbXTtcbiAgICAgICAgdGhpcy5uYW1lID0gJ21hcmtlclBvaW50cyc7XG4gICAgICAgIHRoaXMuZGVmYXVsdENmZyA9IHtcbiAgICAgICAgICAgIG9mZnNldFg6IDAsXG4gICAgICAgICAgICBvZmZzZXRZOiAwLFxuICAgICAgICAgICAgc3R5bGU6IHsgbm9ybWFsOiBERUZBVUxUX1NUWUxFLCBzZWxlY3RlZDogU0VMRUNURURfU1RZTEUsIGFjdGl2ZTogQUNUSVZFX1NUWUxFIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG9mZnNldFk6IC04LFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAndG9wJyxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgwLCAwLCAwLCAwLjg1KScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhbmltYXRpb246IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnZpZXcgPSBjZmcudmlldztcbiAgICAgICAgdGhpcy5zaXplID0gY2ZnLnNpemUgfHwgNjtcbiAgICAgICAgdGhpcy5jb25maWcgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5kZWZhdWx0Q2ZnLCBjZmcpO1xuICAgICAgICB0aGlzLl9pbml0KCk7XG4gICAgfVxuICAgIE1hcmtlclBvaW50LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYXRhQXJyYXkgPSB0aGlzLmdldERhdGFBcnJheSgpO1xuICAgICAgICB0aGlzLl9yZW5kZXJQb2ludHMoZGF0YUFycmF5KTtcbiAgICAgICAgdGhpcy52aWV3LmNhbnZhcy5kcmF3KCk7XG4gICAgICAgIHRoaXMuX2FkZEludGVyYWN0aW9uKCk7XG4gICAgfTtcbiAgICBNYXJrZXJQb2ludC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTWFya2VyUG9pbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wb2ludHMgPSBbXTtcbiAgICAgICAgdGhpcy5sYWJlbHMgPSBbXTtcbiAgICB9O1xuICAgIE1hcmtlclBvaW50LnByb3RvdHlwZS5nZXREYXRhQXJyYXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBnZW9tZXRyeSA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdO1xuICAgICAgICByZXR1cm4gZ2VvbWV0cnkuZGF0YUFycmF5O1xuICAgIH07XG4gICAgTWFya2VyUG9pbnQucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLnZpZXcuZm9yZWdyb3VuZEdyb3VwO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGxheWVyLmFkZEdyb3VwKCk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIHRoaXMudmlldy5vbignYmVmb3JlcmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBNYXJrZXJQb2ludC5wcm90b3R5cGUuX3JlbmRlclBvaW50cyA9IGZ1bmN0aW9uIChkYXRhQXJyYXkpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5jb25maWcuZGF0YSwgZnVuY3Rpb24gKGRhdGFJdGVtLCBkYXRhSXRlbUlkeCkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZGF0YUFycmF5LCBmdW5jdGlvbiAoZGF0YXVtKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9yaWdpbiA9IHV0aWxfMS5maW5kKGRhdGF1bSwgZnVuY3Rpb24gKGQpIHsgcmV0dXJuIHV0aWxfMS5pc01hdGNoKGQuX29yaWdpbiwgZGF0YUl0ZW0pOyB9KTtcbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb2ludEF0dHJzID0gX3RoaXMuY29uZmlnLnN0eWxlLm5vcm1hbDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdyb3VwID0gX3RoaXMuY29udGFpbmVyLmFkZEdyb3VwKHsgbmFtZTogX3RoaXMubmFtZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHggPSBvcmlnaW4ueCwgeSA9IG9yaWdpbi55O1xuICAgICAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoeCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSB4WzBdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheSh5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHlbMF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHN5bWJvbCA9IF90aGlzLmNvbmZpZy5zeW1ib2w7XG4gICAgICAgICAgICAgICAgICAgIHZhciBfYSA9IF90aGlzLmNvbmZpZywgb2Zmc2V0WCA9IF9hLm9mZnNldFgsIG9mZnNldFkgPSBfYS5vZmZzZXRZO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcG9pbnQgPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcoc3ltYm9sKSAmJiBzeW1ib2wuc3RhcnRzV2l0aCgnaW1hZ2U6Ly8nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGltYWdlVXJsID0gc3ltYm9sLnN1YnN0cig4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50ID0gZ3JvdXAuYWRkU2hhcGUoJ2ltYWdlJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHggLSBfdGhpcy5zaXplIC8gMiArIG9mZnNldFgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHkgLSBfdGhpcy5zaXplIC8gMiArIG9mZnNldFksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZzogaW1hZ2VVcmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBfdGhpcy5zaXplLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IF90aGlzLnNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gdXRpbF8xLmlzU3RyaW5nKHN5bWJvbCkgPyBkZXBlbmRlbnRzXzEuTWFya2VyU3ltYm9sc1tzeW1ib2xdIDogc3ltYm9sO1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnQgPSBncm91cC5hZGRTaGFwZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ21hcmtlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ21hcmtlci1wb2ludCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IFwicG9pbnQtXCIgKyBkYXRhSXRlbUlkeCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHsgeDogeCArIG9mZnNldFgsIHk6IHkgKyBvZmZzZXRZLCByOiBfdGhpcy5zaXplIC8gMiB9LCBwb2ludEF0dHJzKSwgeyBzeW1ib2w6IHN5bWJvbCB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnBvaW50cy5wdXNoKHBvaW50KTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2FuaW1hdGVQb2ludChwb2ludCk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9yZW5kZXJMYWJlbChncm91cCwgb3JpZ2luLCBkYXRhSXRlbUlkeCk7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLnNldCgnZGF0YScsIGRhdGFJdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuc2V0KCdvcmlnaW4nLCBvcmlnaW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIE1hcmtlclBvaW50LnByb3RvdHlwZS5fcmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoY29udGFpbmVyLCBvcmlnaW4sIGluZGV4KSB7XG4gICAgICAgIHZhciBsYWJlbENmZyA9IHRoaXMuY29uZmlnLmxhYmVsO1xuICAgICAgICBpZiAobGFiZWxDZmcgJiYgbGFiZWxDZmcudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIF9hID0gbGFiZWxDZmcub2Zmc2V0WCwgb2Zmc2V0WCA9IF9hID09PSB2b2lkIDAgPyAwIDogX2EsIF9iID0gbGFiZWxDZmcub2Zmc2V0WSwgb2Zmc2V0WSA9IF9iID09PSB2b2lkIDAgPyAwIDogX2IsIGZvcm1hdHRlciA9IGxhYmVsQ2ZnLmZvcm1hdHRlciwgcG9zaXRpb24gPSBsYWJlbENmZy5wb3NpdGlvbiwgZmllbGQgPSBsYWJlbENmZy5maWVsZDtcbiAgICAgICAgICAgIHZhciB0ZXh0ID0gb3JpZ2luLl9vcmlnaW5bZmllbGRdO1xuICAgICAgICAgICAgaWYgKGZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgIHRleHQgPSBmb3JtYXR0ZXIodGV4dCwgeyBfb3JpZ2luOiBvcmlnaW4uX29yaWdpbiB9LCBpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeCA9IHV0aWxfMS5pc0FycmF5KG9yaWdpbi54KSA/IG9yaWdpbi54WzBdIDogb3JpZ2luLng7XG4gICAgICAgICAgICB2YXIgeSA9IHV0aWxfMS5pc0FycmF5KG9yaWdpbi55KSA/IG9yaWdpbi55WzBdIDogb3JpZ2luLnk7XG4gICAgICAgICAgICB2YXIgbGFiZWwgPSBjb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgbmFtZTogJ21hcmtlci1sYWJlbCcsXG4gICAgICAgICAgICAgICAgaWQ6IFwibGFiZWwtXCIgKyBpbmRleCxcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHsgeDogeCArIG9mZnNldFgsIHk6IHkgKyBvZmZzZXRZLCB0ZXh0OiB0ZXh0IHx8ICcnIH0sIGxhYmVsQ2ZnLnN0eWxlKSwgeyB0ZXh0QWxpZ246ICdjZW50ZXInLCB0ZXh0QmFzZWxpbmU6IHBvc2l0aW9uID09PSAndG9wJyA/ICdib3R0b20nIDogJ3RvcCcgfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubGFiZWxzLnB1c2gobGFiZWwpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNYXJrZXJQb2ludC5wcm90b3R5cGUuX2FkZEludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5jb25maWcuZXZlbnRzO1xuICAgICAgICB1dGlsXzEuZWFjaChldmVudHMsIGZ1bmN0aW9uIChjYiwgZXZlbnROYW1lKSB7XG4gICAgICAgICAgICBfdGhpcy5jb250YWluZXIub24oX3RoaXMubmFtZSArIFwiOlwiICsgZXZlbnROYW1lLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGNiKGUpO1xuICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldC5nZXQoJ3BhcmVudCcpO1xuICAgICAgICAgICAgICAgIHZhciBwb2ludFNoYXBlID0gdGFyZ2V0LmdldCgnY2hpbGRyZW4nKVswXTtcbiAgICAgICAgICAgICAgICBpZiAocG9pbnRTaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHBvaW50U2hhcGUuZ2V0KCdkYXRhJyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZCA9IHBvaW50U2hhcGUuZ2V0KCdpZCcpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgY29uZGl0aW9uID0geyBpZDogaWQsIGRhdGE6IGRhdGEgfTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2NsaWNrJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnNlbGVjdGVkUG9pbnQgJiYgX3RoaXMuc2VsZWN0ZWRQb2ludC5nZXQoJ2lkJykgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2VsZWN0ZWRQb2ludCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoJ2luYWN0aXZlJywgY29uZGl0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNlbGVjdGVkUG9pbnQgPSBwb2ludFNoYXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKCdzZWxlY3RlZCcsIGNvbmRpdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnROYW1lID09PSAnbW91c2VlbnRlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKCdhY3RpdmUnLCBjb25kaXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50TmFtZSA9PT0gJ21vdXNlbGVhdmUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSgnaW5hY3RpdmUnLCBjb25kaXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF90aGlzLnZpZXcuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX3RoaXMudmlldy5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldC5nZXQoJ3BhcmVudCcpO1xuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0IHx8ICh0YXJnZXQuZ2V0KCduYW1lJykgIT09IF90aGlzLm5hbWUgJiYgX3RoaXMuc2VsZWN0ZWRQb2ludCkpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2VsZWN0ZWRQb2ludCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKCdpbmFjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIE1hcmtlclBvaW50LnByb3RvdHlwZS5zZXRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgY29uZGl0aW9uKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ2FjdGl2ZScpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZWxlY3RlZFBvaW50IHx8IGNvbmRpdGlvbi5pZCAhPT0gdGhpcy5zZWxlY3RlZFBvaW50LmdldCgnaWQnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29uQWN0aXZlKGNvbmRpdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT09ICdpbmFjdGl2ZScpIHtcbiAgICAgICAgICAgIHRoaXMucG9pbnRzLmZvckVhY2goZnVuY3Rpb24gKHApIHsgcmV0dXJuIF90aGlzLl9vbkluYWN0aXZlKHApOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZSA9PT0gJ3NlbGVjdGVkJykge1xuICAgICAgICAgICAgdGhpcy5fb25TZWxlY3RlZChjb25kaXRpb24pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNYXJrZXJQb2ludC5wcm90b3R5cGUuX29uQWN0aXZlID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgYWN0aXZlID0gdGhpcy5jb25maWcuc3R5bGUuYWN0aXZlO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICBpZiAocG9pbnQuZ2V0KCdpZCcpID09PSBjb25kaXRpb24uaWQpIHtcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChhY3RpdmUsIGZ1bmN0aW9uICh2LCBrKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvaW50LmF0dHIoaywgdik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5fb25JbmFjdGl2ZShwb2ludCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgTWFya2VyUG9pbnQucHJvdG90eXBlLl9vbkluYWN0aXZlID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciBub3JtYWwgPSB0aGlzLmNvbmZpZy5zdHlsZS5ub3JtYWw7XG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RlZFBvaW50IHx8IHBvaW50LmdldCgnaWQnKSAhPT0gdGhpcy5zZWxlY3RlZFBvaW50LmdldCgnaWQnKSkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobm9ybWFsLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgICAgIHBvaW50LmF0dHIoaywgdik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTWFya2VyUG9pbnQucHJvdG90eXBlLl9vblNlbGVjdGVkID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2VsZWN0ZWQgPSB0aGlzLmNvbmZpZy5zdHlsZS5zZWxlY3RlZDtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5wb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICAgICAgaWYgKHBvaW50LmdldCgnaWQnKSA9PT0gY29uZGl0aW9uLmlkKSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2goc2VsZWN0ZWQsIGZ1bmN0aW9uICh2LCBrKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvaW50LmF0dHIoaywgdik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5fb25JbmFjdGl2ZShwb2ludCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqIHBvaW50IGFuaW1hdGlvbiwgbm90IGZvciBsYWJlbCAqL1xuICAgIE1hcmtlclBvaW50LnByb3RvdHlwZS5fYW5pbWF0ZVBvaW50ID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY29uZmlnLCBhbmltYXRpb24gPSBfYS5hbmltYXRpb24sIHNpemUgPSBfYS5zaXplO1xuICAgICAgICBpZiAoYW5pbWF0aW9uICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdmFyIF9iID0gYW5pbWF0aW9uLCBfYyA9IF9iLmVuZFN0YXRlLCBlbmRTdGF0ZSA9IF9jID09PSB2b2lkIDAgPyB7fSA6IF9jLCBfZCA9IF9iLmFuaW1hdGVDZmcsIGFuaW1hdGVDZmcgPSBfZCA9PT0gdm9pZCAwID8gYW5pbWF0ZV8xLkRFRkFVTFRfQU5JTUFURV9DRkcuYXBwZWFyIDogX2Q7XG4gICAgICAgICAgICBzaGFwZS5hbmltYXRlKHRzbGliXzEuX19hc3NpZ24oeyByOiBOdW1iZXIuaXNOYU4oZW5kU3RhdGUuc2l6ZSAvIDIpID8gc2l6ZSAvIDIgOiBlbmRTdGF0ZS5zaXplIC8gMiB9LCBlbmRTdGF0ZSksIGFuaW1hdGVDZmcpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gTWFya2VyUG9pbnQ7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTWFya2VyUG9pbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXJrZXItcG9pbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZG9tX3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9kb20tdXRpbFwiKTtcbnZhciBTdGF0aXN0aWNIdG1sID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFN0YXRpc3RpY0h0bWwoY2ZnKSB7XG4gICAgICAgIHZhciBkZWZhdWx0T3B0aW9ucyA9IHRoaXMuZ2V0RGVmYXVsdE9wdGlvbnMoKTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoZGVmYXVsdE9wdGlvbnMsIGNmZywge30pO1xuICAgICAgICB0aGlzLnggPSB0aGlzLm9wdGlvbnMueDtcbiAgICAgICAgdGhpcy55ID0gdGhpcy5vcHRpb25zLnk7XG4gICAgICAgIHRoaXMuaHRtbCA9IHRoaXMub3B0aW9ucy5odG1sO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMub3B0aW9ucy5jb250YWluZXI7XG4gICAgfVxuICAgIFN0YXRpc3RpY0h0bWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0VsZW1lbnQodGhpcy5jb250YWluZXIpKSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXJOb2RlID0gZG9tX3V0aWxfMS5jcmVhdGVEb20oJzxkaXYgY2xhc3M9XCJnMnBsb3QtaHRtbFN0YXRpc3RpY1wiPjwvZGl2PicpO1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy53cmFwcGVyTm9kZSk7XG4gICAgICAgICAgICBkb21fdXRpbF8xLm1vZGlmeUNTUyh0aGlzLndyYXBwZXJOb2RlLCB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgaHRtbE5vZGUgPSB0aGlzLmh0bWw7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXJOb2RlLmFwcGVuZENoaWxkKGh0bWxOb2RlKTtcbiAgICAgICAgICAgIHRoaXMuc2V0RG9tUG9zaXRpb24odGhpcy54LCB0aGlzLnkpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTdGF0aXN0aWNIdG1sLnByb3RvdHlwZS51cGRhdGVIdG1sID0gZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc1R5cGUoY29udGVudCwgJ0hUTUxEaXZFbGVtZW50JykpIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlck5vZGUuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXJOb2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyTm9kZS5pbm5lckhUTUwgPSBjb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0RG9tUG9zaXRpb24odGhpcy54LCB0aGlzLnkpO1xuICAgIH07XG4gICAgU3RhdGlzdGljSHRtbC5wcm90b3R5cGUudXBkYXRlUG9zaXRpb24gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB0aGlzLnggPSB4O1xuICAgICAgICB0aGlzLnkgPSB5O1xuICAgICAgICB0aGlzLnNldERvbVBvc2l0aW9uKHgsIHkpO1xuICAgIH07XG4gICAgU3RhdGlzdGljSHRtbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy53cmFwcGVyTm9kZSk7XG4gICAgfTtcbiAgICBTdGF0aXN0aWNIdG1sLnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDAsXG4gICAgICAgICAgICBodG1sOiAnJyxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAgICAgICAgIGFsaWduWDogJ21pZGRsZScsXG4gICAgICAgICAgICBhbGlnblk6ICdtaWRkbGUnLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgU3RhdGlzdGljSHRtbC5wcm90b3R5cGUuc2V0RG9tUG9zaXRpb24gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgeFBvc2l0aW9uID0geDtcbiAgICAgICAgdmFyIHlQb3NpdGlvbiA9IHk7XG4gICAgICAgIHZhciB3aWR0aCA9IGRvbV91dGlsXzEuZ2V0T3V0ZXJXaWR0aCh0aGlzLndyYXBwZXJOb2RlKTtcbiAgICAgICAgdmFyIGhlaWdodCA9IGRvbV91dGlsXzEuZ2V0T3V0ZXJIZWlnaHQodGhpcy53cmFwcGVyTm9kZSk7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWxpZ25YID09PSAnbWlkZGxlJykge1xuICAgICAgICAgICAgeFBvc2l0aW9uID0geCAtIHdpZHRoIC8gMjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFsaWduWSA9PT0gJ21pZGRsZScpIHtcbiAgICAgICAgICAgIHlQb3NpdGlvbiA9IHkgLSBoZWlnaHQgLyAyO1xuICAgICAgICB9XG4gICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKHRoaXMud3JhcHBlck5vZGUsIHtcbiAgICAgICAgICAgIHRvcDogTWF0aC5yb3VuZCh5UG9zaXRpb24pICsgXCJweFwiLFxuICAgICAgICAgICAgbGVmdDogTWF0aC5yb3VuZCh4UG9zaXRpb24pICsgXCJweFwiLFxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiDmlK/mjIFBbnQgRGVzaWduIENoYXJ0c1xuICAgICAgICAgICAgICogcmVuZGVy5piv5byC5q2l55qE5pON5L2c77yM6I635Y+W5Yiw55qEIHdpZHRoIOS4uiAwXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRyYW5zZm9ybTogd2lkdGggPiAwID8gJ25vbmUnIDogJ3RyYW5zbGF0ZSgtNTAlLCAtNTAlKScsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIFN0YXRpc3RpY0h0bWw7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhdGlzdGljSHRtbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRpc3RpYy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogQGZpbGUg5pKt5pS+6L2057uE5Lu25oyJ6ZKuXG4gKiBAYXV0aG9yIGJsYWNrZ2FuZ2xpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2Jhc2VcIikpO1xudmFyIEJ1dHRvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhCdXR0b24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQnV0dG9uKGNmZykge1xuICAgICAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgdXRpbF8xLmRlZXBNaXgoe30sIGNmZykpIHx8IHRoaXM7XG4gICAgfVxuICAgIEJ1dHRvbi5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5pbml0RWxlbWVudChncm91cCk7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudCgpO1xuICAgICAgICB0aGlzLnJlbmRlck1hcmtlcigpO1xuICAgICAgICBncm91cC5vZmYoJ2NsaWNrJyk7XG4gICAgICAgIGdyb3VwLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmVtaXQoJ2NsaWNrJyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQnV0dG9uLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmdyb3VwLm9mZigpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIEJ1dHRvbi5wcm90b3R5cGUuaW5pdEVsZW1lbnQgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdGhpcy5jaXJjbGUgPSBncm91cC5hZGRTaGFwZSgnY2lyY2xlJywge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLmNvbmZpZy54LFxuICAgICAgICAgICAgICAgIHk6IHRoaXMuY29uZmlnLnksXG4gICAgICAgICAgICAgICAgcjogdGhpcy5jb25maWcucixcbiAgICAgICAgICAgICAgICBmaWxsOiAnIzYwNzg4OScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdGFydE1hcmtlciA9IGdyb3VwLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICBwYXRoOiB0aGlzLmdldFN0YXJ0TWFya2VyUGF0aCgpLFxuICAgICAgICAgICAgICAgIGZpbGw6ICcjZmZmZmZmJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBhdXNlR3JvdXBNYXJrZXIgPSBncm91cC5hZGRHcm91cCgpO1xuICAgICAgICB2YXIgd2lkdGggPSAoMSAvIDQpICogdGhpcy5jb25maWcucjtcbiAgICAgICAgdmFyIGhlaWdodCA9IDAuNSAqIHRoaXMuY29uZmlnLnIgKiBNYXRoLnNxcnQoMyk7XG4gICAgICAgIHRoaXMucGF1c2VMZWZ0TWFya2VyID0gdGhpcy5wYXVzZUdyb3VwTWFya2VyLmFkZFNoYXBlKCdyZWN0Jywge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLmNvbmZpZy54IC0gKDEgLyA0ICsgMSAvIDgpICogdGhpcy5jb25maWcucixcbiAgICAgICAgICAgICAgICB5OiB0aGlzLmNvbmZpZy55IC0gaGVpZ2h0IC8gMixcbiAgICAgICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgICAgICAgICAgZmlsbDogJyNmZmZmZmYnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGF1c2VSaWdodE1hcmtlciA9IHRoaXMucGF1c2VHcm91cE1hcmtlci5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogdGhpcy5jb25maWcueCArICgxIC8gOCkgKiB0aGlzLmNvbmZpZy5yLFxuICAgICAgICAgICAgICAgIHk6IHRoaXMuY29uZmlnLnkgLSBoZWlnaHQgLyAyLFxuICAgICAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICAgICAgICBmaWxsOiAnI2ZmZmZmZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJ1dHRvbi5wcm90b3R5cGUudXBkYXRlRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jaXJjbGUuYXR0cigneCcsIHRoaXMuY29uZmlnLngpO1xuICAgICAgICB0aGlzLmNpcmNsZS5hdHRyKCd5JywgdGhpcy5jb25maWcueSk7XG4gICAgICAgIHRoaXMuY2lyY2xlLmF0dHIoJ3InLCB0aGlzLmNvbmZpZy5yKTtcbiAgICAgICAgdGhpcy5zdGFydE1hcmtlci5hdHRyKCdwYXRoJywgdGhpcy5nZXRTdGFydE1hcmtlclBhdGgoKSk7XG4gICAgICAgIHZhciB3aWR0aCA9ICgxIC8gNCkgKiB0aGlzLmNvbmZpZy5yO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gMC41ICogdGhpcy5jb25maWcuciAqIE1hdGguc3FydCgzKTtcbiAgICAgICAgdGhpcy5wYXVzZUxlZnRNYXJrZXIuYXR0cigneCcsIHRoaXMuY29uZmlnLnggLSAoMSAvIDQgKyAxIC8gOCkgKiB0aGlzLmNvbmZpZy5yKTtcbiAgICAgICAgdGhpcy5wYXVzZUxlZnRNYXJrZXIuYXR0cigneScsIHRoaXMuY29uZmlnLnkgLSBoZWlnaHQgLyAyKTtcbiAgICAgICAgdGhpcy5wYXVzZUxlZnRNYXJrZXIuYXR0cignd2lkdGgnLCB3aWR0aCk7XG4gICAgICAgIHRoaXMucGF1c2VMZWZ0TWFya2VyLmF0dHIoJ2hlaWdodCcsIGhlaWdodCk7XG4gICAgICAgIHRoaXMucGF1c2VSaWdodE1hcmtlci5hdHRyKCd4JywgdGhpcy5jb25maWcueCArICgxIC8gOCkgKiB0aGlzLmNvbmZpZy5yKTtcbiAgICAgICAgdGhpcy5wYXVzZVJpZ2h0TWFya2VyLmF0dHIoJ3knLCB0aGlzLmNvbmZpZy55IC0gaGVpZ2h0IC8gMik7XG4gICAgICAgIHRoaXMucGF1c2VSaWdodE1hcmtlci5hdHRyKCd3aWR0aCcsIHdpZHRoKTtcbiAgICAgICAgdGhpcy5wYXVzZVJpZ2h0TWFya2VyLmF0dHIoJ2hlaWdodCcsIGhlaWdodCk7XG4gICAgfTtcbiAgICBCdXR0b24ucHJvdG90eXBlLnJlbmRlck1hcmtlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmlzUGxheSkge1xuICAgICAgICAgICAgdGhpcy5zdGFydE1hcmtlci5oaWRlKCk7XG4gICAgICAgICAgICB0aGlzLnBhdXNlR3JvdXBNYXJrZXIuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdGFydE1hcmtlci5zaG93KCk7XG4gICAgICAgICAgICB0aGlzLnBhdXNlR3JvdXBNYXJrZXIuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog6I635Y+W5pKt5pS+6ZSuIG1hcmtlciBwYXRoICovXG4gICAgQnV0dG9uLnByb3RvdHlwZS5nZXRTdGFydE1hcmtlclBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzaWRlTGVuZ3RoID0gMC41ICogdGhpcy5jb25maWcuciAqIE1hdGguc3FydCgzKTtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsIHRoaXMuY29uZmlnLnggLSBzaWRlTGVuZ3RoIC8gTWF0aC5zcXJ0KDMpIC8gMiwgdGhpcy5jb25maWcueSAtIHNpZGVMZW5ndGggLyAyXSxcbiAgICAgICAgICAgIFsnTCcsIHRoaXMuY29uZmlnLnggKyBzaWRlTGVuZ3RoIC8gTWF0aC5zcXJ0KDMpLCB0aGlzLmNvbmZpZy55XSxcbiAgICAgICAgICAgIFsnTCcsIHRoaXMuY29uZmlnLnggLSBzaWRlTGVuZ3RoIC8gTWF0aC5zcXJ0KDMpIC8gMiwgdGhpcy5jb25maWcueSArIHNpZGVMZW5ndGggLyAyXSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIHJldHVybiBCdXR0b247XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCdXR0b247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1idXR0b24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBmaWxlIOWfuuS6jiBHIOeahOaSreaUvui9tOe7hOS7tlxuICogQGF1dGhvciBibGFja2dhbmdsaW9uXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJ1dHRvbl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYnV0dG9uXCIpKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG52YXIgVElNRUxJTkVfU1RBUlQgPSAndGltZWxpbmVzdGFydCc7XG52YXIgVElNRUxJTkVfQ0hBTkdFID0gJ3RpbWVsaW5lY2hhbmdlJztcbnZhciBUSU1FTElORV9FTkQgPSAndGltZWxpbmVlbmQnO1xudmFyIFRJTUVMSU5FX1VQREFURSA9ICd0aW1lbGluZXVwZGF0ZSc7XG52YXIgUEFERElOR19MRUZUID0gMjA7XG52YXIgUEFERElOR19SSUdIVCA9IDIwO1xuLyoqXG4gKiDlj4LogIPnpLrkvotcbiAqIGh0dHBzOi8vd3d3LmdhcG1pbmRlci5vcmcvdG9vbHMvIyRzdGF0ZSR0aW1lJHZhbHVlPTE4NzAmZGVsYXk6MTAwOzsmY2hhcnQtdHlwZT1idWJibGVzXG4gKi9cbnZhciBUaW1lTGluZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUaW1lTGluZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUaW1lTGluZShjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgIHNwZWVkOiAxLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgIH0sIGNmZykpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLm9uVGltZVNlbGVjdE1vdXNlTW92ZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIHggPSB1dGlsXzEuZ2V0KGUsICd0b3VjaGVzLjAucGFnZVgnLCBlLnBhZ2VYKTtcbiAgICAgICAgICAgIHZhciBvZmZzZXRYID0geCAtIF90aGlzLnByZXZYO1xuICAgICAgICAgICAgX3RoaXMuc2V0VGltZVNlbGVjdFgob2Zmc2V0WCk7XG4gICAgICAgICAgICBfdGhpcy5wcmV2WCA9IHg7XG4gICAgICAgIH07XG4gICAgICAgIF90aGlzLm9uVGltZVNlbGVjdE1vdXNlVXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5zeW5jQ3Vycm5lbnRUaWNrKCk7XG4gICAgICAgICAgICBfdGhpcy5lbWl0KFRJTUVMSU5FX0VORCwgbnVsbCk7XG4gICAgICAgICAgICAvLyDlj5bmtojkuovku7ZcbiAgICAgICAgICAgIHZhciBjb250YWluZXJET00gPSBfdGhpcy5nZXRDYW52YXMoKS5nZXQoJ2NvbnRhaW5lcicpO1xuICAgICAgICAgICAgaWYgKGNvbnRhaW5lckRPTSkge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lckRPTS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZU1vdmUpO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lckRPTS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgX3RoaXMub25UaW1lU2VsZWN0TW91c2VVcCk7XG4gICAgICAgICAgICAgICAgLy8g6Ziy5q2i5ruR5Yqo5YiwIGNhbnZhcyDlpJbpg6jkuYvlkI7vvIznirbmgIHkuKLlpLFcbiAgICAgICAgICAgICAgICBjb250YWluZXJET00ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIF90aGlzLm9uVGltZVNlbGVjdE1vdXNlVXApO1xuICAgICAgICAgICAgICAgIC8vIOenu+WKqOerr+S6i+S7tlxuICAgICAgICAgICAgICAgIGNvbnRhaW5lckRPTS5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZU1vdmUpO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lckRPTS5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIF90aGlzLm9uVGltZVNlbGVjdE1vdXNlVXApO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lckRPTS5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIF90aGlzLm9uVGltZVNlbGVjdE1vdXNlVXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZURvd24gPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgLy8g5Y+W5Ye65Y6f55Sf5LqL5Lu2XG4gICAgICAgICAgICB2YXIgZXZlbnQgPSBlLm9yaWdpbmFsRXZlbnQ7XG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBpZiAoX3RoaXMuaXNQbGF5ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoVElNRUxJTkVfU1RBUlQsIG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8g5Y+W5raI5pKt5pS+54q25oCBXG4gICAgICAgICAgICAgICAgX3RoaXMuaXNQbGF5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgLy8g5ouW5Yqo6L+H56iL5Lit55qE5pKt5pS+5pqC5YGc5LiN6ZyA6KaB6LCD5pW0IHRpY2sg5L2N572u77yM6Ziy5q2i5YGP56e7XG4gICAgICAgICAgICAgICAgX3RoaXMuY2hhbmdlUGxheVN0YXR1cyhmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5wcmV2WCA9IHV0aWxfMS5nZXQoZXZlbnQsICd0b3VjaGVzLjAucGFnZVgnLCBldmVudC5wYWdlWCk7XG4gICAgICAgICAgICAvLyDlvIDlp4vmu5HliqjnmoTml7blgJnvvIznu5HlrpogbW92ZSDlkowgdXAg5LqL5Lu2XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyRE9NID0gX3RoaXMuZ2V0Q2FudmFzKCkuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgICAgIGNvbnRhaW5lckRPTS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZU1vdmUpO1xuICAgICAgICAgICAgY29udGFpbmVyRE9NLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZVVwKTtcbiAgICAgICAgICAgIGNvbnRhaW5lckRPTS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgX3RoaXMub25UaW1lU2VsZWN0TW91c2VVcCk7XG4gICAgICAgICAgICAvLyDnp7vliqjnq6/kuovku7ZcbiAgICAgICAgICAgIGNvbnRhaW5lckRPTS5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZU1vdmUpO1xuICAgICAgICAgICAgY29udGFpbmVyRE9NLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgX3RoaXMub25UaW1lU2VsZWN0TW91c2VVcCk7XG4gICAgICAgICAgICBjb250YWluZXJET00uYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZVVwKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUaW1lTGluZS5wcm90b3R5cGUucmVuZGVySW5uZXIgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb25maWcsIHRpY2tzID0gX2EudGlja3MsIGRlZmF1bHRDdXJyZW50VGljayA9IF9hLmRlZmF1bHRDdXJyZW50VGljaztcbiAgICAgICAgaWYgKHRpY2tzICYmIHRpY2tzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50VGljayA9IHRoaXMuY29uZmlnLnRpY2tzLmluY2x1ZGVzKGRlZmF1bHRDdXJyZW50VGljaykgPyBkZWZhdWx0Q3VycmVudFRpY2sgOiB0aWNrc1swXTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyUGxheUJ1dHRvbihncm91cCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclRpbWVMaW5lKGdyb3VwKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyVGltZVNlbGVjdChncm91cCwgdGhpcy5jdXJyZW50VGljayk7XG4gICAgICAgICAgICB0aGlzLmluaXRFdmVudCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmm7TmlrDphY3nva5cbiAgICBUaW1lTGluZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnVwZGF0ZS5jYWxsKHRoaXMsIGNmZyk7XG4gICAgICAgIC8vIOabtOaWsOaXtumcgOimgeinpuWPkeS4gOasoe+8jOadpei/h+a7pOaVsOaNrlxuICAgICAgICB0aGlzLmVtaXQoVElNRUxJTkVfVVBEQVRFLCB0aGlzLmN1cnJlbnRUaWNrKTtcbiAgICB9O1xuICAgIFRpbWVMaW5lLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy50aW1lTGluZUJ1dHRvbi5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMudGltZUxpbmVCdXR0b24ub2ZmKCk7XG4gICAgICAgIHRoaXMudGltZVNlbGVjdC5vZmYoKTtcbiAgICAgICAgaWYgKHRoaXMucGxheUhhbmRsZXIpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnBsYXlIYW5kbGVyKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVGltZUxpbmUucHJvdG90eXBlLnJlbmRlclBsYXlCdXR0b24gPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb25maWcsIGhlaWdodCA9IF9hLmhlaWdodCwgeCA9IF9hLngsIHkgPSBfYS55O1xuICAgICAgICB2YXIgcmF0aW8gPSAwLjg7XG4gICAgICAgIHZhciByID0gKGhlaWdodCAvIDIpICogcmF0aW87XG4gICAgICAgIGlmICh0aGlzLnRpbWVMaW5lQnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVMaW5lQnV0dG9uLnVwZGF0ZSh7XG4gICAgICAgICAgICAgICAgeDogeCArIHIsXG4gICAgICAgICAgICAgICAgeTogeSArIHIgKyAoaGVpZ2h0ICogKDEgLSByYXRpbykpIC8gMixcbiAgICAgICAgICAgICAgICByOiByLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVMaW5lQnV0dG9uID0gbmV3IGJ1dHRvbl8xLmRlZmF1bHQoe1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogZ3JvdXAsXG4gICAgICAgICAgICAgICAgeDogeCArIHIsXG4gICAgICAgICAgICAgICAgeTogeSArIHIgKyAoaGVpZ2h0ICogKDEgLSByYXRpbykpIC8gMixcbiAgICAgICAgICAgICAgICByOiByLFxuICAgICAgICAgICAgICAgIGlzUGxheTogdGhpcy5pc1BsYXksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMudGltZUxpbmVCdXR0b24uaW5pdCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZUxpbmVCdXR0b24ucmVuZGVyKCk7XG4gICAgfTtcbiAgICBUaW1lTGluZS5wcm90b3R5cGUuZ2V0VGltZUxpbmVQYXRoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLnRpbWVMaW5lLCB4ID0gX2EueCwgeSA9IF9hLnksIHdpZHRoID0gX2Eud2lkdGgsIGhlaWdodCA9IF9hLmhlaWdodDtcbiAgICAgICAgdmFyIHIgPSBoZWlnaHQgLyAyO1xuICAgICAgICBpZiAod2lkdGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gKFwiTVwiICsgeCArIFwiLCBcIiArIHkgK1xuICAgICAgICAgICAgICAgIChcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiA5MCAwLDAgXCIgKyB4ICsgXCIsXCIgKyAoeSArIGhlaWdodCkpICtcbiAgICAgICAgICAgICAgICAoXCJMXCIgKyAoeCArIHdpZHRoKSArIFwiLCBcIiArICh5ICsgaGVpZ2h0KSkgK1xuICAgICAgICAgICAgICAgIChcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiA5MCAwLDAgXCIgKyAoeCArIHdpZHRoKSArIFwiLFwiICsgeSkgK1xuICAgICAgICAgICAgICAgIChcIkxcIiArIHggKyBcIiwgXCIgKyB5KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH07XG4gICAgVGltZUxpbmUucHJvdG90eXBlLnJlbmRlclRpbWVMaW5lID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY29uZmlnLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQsIHRpY2tzID0gX2EudGlja3MsIHggPSBfYS54LCB5ID0gX2EueTtcbiAgICAgICAgaWYgKCF0aGlzLnRpbWVMaW5lKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVMaW5lID0ge307XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOm7mOiupOmrmOW6puaYr+ecn+WunumrmOW6piAxNSUgKi9cbiAgICAgICAgdGhpcy50aW1lTGluZS5oZWlnaHQgPSBoZWlnaHQgKiAwLjE1O1xuICAgICAgICB0aGlzLnRpbWVMaW5lLnggPSB4ICsgaGVpZ2h0ICsgUEFERElOR19MRUZUO1xuICAgICAgICB0aGlzLnRpbWVMaW5lLnkgPSB5ICsgKGhlaWdodCAvIDIgLSB0aGlzLnRpbWVMaW5lLmhlaWdodCAvIDIpO1xuICAgICAgICB0aGlzLnRpbWVMaW5lLndpZHRoID0gd2lkdGggLSB0aGlzLnRpbWVMaW5lLnggLSBQQURESU5HX1JJR0hUO1xuICAgICAgICBpZiAodGhpcy50aW1lTGluZSAmJiB0aGlzLnRpbWVMaW5lLnNoYXBlKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVMaW5lLnNoYXBlLmF0dHIoJ3BhdGgnLCB0aGlzLmdldFRpbWVMaW5lUGF0aCgpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudGltZUxpbmUuc2hhcGUgPSBncm91cC5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiB0aGlzLmdldFRpbWVMaW5lUGF0aCgpLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzYwNzg4OScsXG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGludGVydmFsID0gdGhpcy50aW1lTGluZS53aWR0aCAvICh0aWNrcy5sZW5ndGggLSAxKTtcbiAgICAgICAgdGhpcy50aWNrUG9zTGlzdCA9IFtdO1xuICAgICAgICBpZiAodGhpcy50aW1lTGluZS50ZXh0TGlzdCAmJiB0aGlzLnRpbWVMaW5lLnRleHRMaXN0Lmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy50aW1lTGluZS50ZXh0TGlzdC5mb3JFYWNoKGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGV4dC5kZXN0cm95KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFzdFggPSAtSW5maW5pdHk7XG4gICAgICAgIHRoaXMudGltZUxpbmUudGV4dExpc3QgPSB0aWNrcy5tYXAoZnVuY3Rpb24gKHRpY2ssIGluZGV4KSB7XG4gICAgICAgICAgICBfdGhpcy50aWNrUG9zTGlzdC5wdXNoKF90aGlzLnRpbWVMaW5lLnggKyBpbmRleCAqIGludGVydmFsKTtcbiAgICAgICAgICAgIHZhciB0ZXh0ID0gZ3JvdXAuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgeDogX3RoaXMudGltZUxpbmUueCArIGluZGV4ICogaW50ZXJ2YWwsXG4gICAgICAgICAgICAgICAgICAgIHk6IF90aGlzLnRpbWVMaW5lLnkgKyBfdGhpcy50aW1lTGluZS5oZWlnaHQgKyA1LFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiB0aWNrLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICd0b3AnLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzYwNzg4OScsXG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuMzUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIGJib3ggPSB0ZXh0LmdldEJCb3goKTtcbiAgICAgICAgICAgIC8vIOaKveagt++8jOagh+etvuS4juagh+etvumXtOi3neS4jeWwj+S6jiAxMFxuICAgICAgICAgICAgaWYgKGJib3gubWluWCA+IGxhc3RYKSB7XG4gICAgICAgICAgICAgICAgdGV4dC5zaG93KCk7XG4gICAgICAgICAgICAgICAgbGFzdFggPSBiYm94Lm1pblggKyBiYm94LndpZHRoICsgMTA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ZXh0LmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0ZXh0O1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRpbWVMaW5lLnByb3RvdHlwZS5yZW5kZXJUaW1lU2VsZWN0ID0gZnVuY3Rpb24gKGdyb3VwLCB0aWNrVmFsdWUpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb25maWcsIHRpY2tzID0gX2EudGlja3MsIGhlaWdodCA9IF9hLmhlaWdodDtcbiAgICAgICAgdmFyIGludGVydmFsID0gdGhpcy50aW1lTGluZS53aWR0aCAvICh0aWNrcy5sZW5ndGggLSAxKTtcbiAgICAgICAgdmFyIGluZGV4ID0gdXRpbF8xLmZpbmRJbmRleCh0aWNrcywgZnVuY3Rpb24gKHRpY2spIHsgcmV0dXJuIHRpY2sgPT09IHRpY2tWYWx1ZTsgfSk7XG4gICAgICAgIHZhciB4ID0gdGhpcy50aW1lTGluZS54ICsgaW5kZXggKiBpbnRlcnZhbDtcbiAgICAgICAgdmFyIHkgPSB0aGlzLmNvbmZpZy55ICsgaGVpZ2h0IC8gMjtcbiAgICAgICAgdmFyIHIgPSBoZWlnaHQgKiAwLjE1O1xuICAgICAgICBpZiAodGhpcy50aW1lU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVTZWxlY3QuYXR0cigneCcsIHgpO1xuICAgICAgICAgICAgdGhpcy50aW1lU2VsZWN0LmF0dHIoJ3knLCB5KTtcbiAgICAgICAgICAgIHRoaXMudGltZVNlbGVjdC5hdHRyKCdyJywgcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVTZWxlY3QgPSBncm91cC5hZGRTaGFwZSgnY2lyY2xlJywge1xuICAgICAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICAgICAgICAgIHI6IHIsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjNjA3ODg5JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudGltZVNlbGVjdFRleHQpIHtcbiAgICAgICAgICAgIHRoaXMudGltZVNlbGVjdFRleHQuYXR0cigneCcsIHgpO1xuICAgICAgICAgICAgdGhpcy50aW1lU2VsZWN0VGV4dC5hdHRyKCd5JywgeSAtIGhlaWdodCAqIDAuMTUgLSAxNCk7XG4gICAgICAgICAgICB0aGlzLnRpbWVTZWxlY3RUZXh0LmF0dHIoJ3RleHQnLCB0aGlzLmN1cnJlbnRUaWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudGltZVNlbGVjdFRleHQgPSBncm91cC5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgICAgICAgICB5OiB5IC0gaGVpZ2h0ICogMC4xNSAtIDE0LFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzLmN1cnJlbnRUaWNrLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICd0b3AnLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzYwNzg4OScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog6L6T5YWl5b2T5YmN5ZyG54K55L2N572u77yM6L6T5Ye656a75ZOq5LiqIHRpY2sg55qE5L2N572u5pyA6L+RICovXG4gICAgVGltZUxpbmUucHJvdG90eXBlLmFkanVzdFRpY2tJbmRleCA9IGZ1bmN0aW9uICh0aW1lU2VsZWN0WCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudGlja1Bvc0xpc3QubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50aWNrUG9zTGlzdFtpXSA8PSB0aW1lU2VsZWN0WCAmJiB0aW1lU2VsZWN0WCA8PSB0aGlzLnRpY2tQb3NMaXN0W2kgKyAxXSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmFicyh0aGlzLnRpY2tQb3NMaXN0W2ldIC0gdGltZVNlbGVjdFgpIDwgTWF0aC5hYnModGltZVNlbGVjdFggLSB0aGlzLnRpY2tQb3NMaXN0W2kgKyAxXSlcbiAgICAgICAgICAgICAgICAgICAgPyBpXG4gICAgICAgICAgICAgICAgICAgIDogaSArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKiDmi5bliqjmiJboh6rliqjmkq3mlL7ov4fnqIvkuK3vvIzorr7nva4gVGltZVNlbGVjdCDnmoTkvY3nva4gKi9cbiAgICBUaW1lTGluZS5wcm90b3R5cGUuc2V0VGltZVNlbGVjdFggPSBmdW5jdGlvbiAob2Zmc2V0WCkge1xuICAgICAgICB2YXIgdGltZVNlbGVjdFggPSB0aGlzLnRpbWVTZWxlY3QuYXR0cigneCcpICsgb2Zmc2V0WDtcbiAgICAgICAgLy8g6Ziy5q2i5bem5Y+z5rqi5Ye6XG4gICAgICAgIGlmICh0aW1lU2VsZWN0WCA8IHRoaXMudGltZUxpbmUueCkge1xuICAgICAgICAgICAgdGltZVNlbGVjdFggPSB0aGlzLnRpbWVMaW5lLng7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbWVTZWxlY3RYID4gdGhpcy50aW1lTGluZS54ICsgdGhpcy50aW1lTGluZS53aWR0aCkge1xuICAgICAgICAgICAgdGltZVNlbGVjdFggPSB0aGlzLnRpbWVMaW5lLnggKyB0aGlzLnRpbWVMaW5lLndpZHRoO1xuICAgICAgICAgICAgLy8g5q2j5Zyo5pKt5pS+5Zy65pmvXG4gICAgICAgICAgICBpZiAodGhpcy5pc1BsYXkpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzmmK/lvqrnjq9cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25maWcubG9vcCkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlvZPliY3mu5Hliqjngrnlt7Lnu4/lpITkuo7mnIDlkI7kuIDkuKogdGljayDkuIrvvIzmiY3og73ph43nva7lm57ljrvvvIznu6fnu63lvqrnjq9cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZVNlbGVjdC5hdHRyKCd4JykgPT09IHRoaXMudGltZUxpbmUueCArIHRoaXMudGltZUxpbmUud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVTZWxlY3RYID0gdGhpcy50aW1lTGluZS54O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUGxheSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZVBsYXlTdGF0dXMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aW1lU2VsZWN0LmF0dHIoJ3gnLCB0aW1lU2VsZWN0WCk7XG4gICAgICAgIHRoaXMudGltZVNlbGVjdFRleHQuYXR0cigneCcsIHRpbWVTZWxlY3RYKTtcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5hZGp1c3RUaWNrSW5kZXgodGltZVNlbGVjdFgpO1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50VGljayAhPT0gdGhpcy5jb25maWcudGlja3NbaW5kZXhdKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRUaWNrID0gdGhpcy5jb25maWcudGlja3NbaW5kZXhdO1xuICAgICAgICAgICAgdGhpcy50aW1lU2VsZWN0VGV4dC5hdHRyKCd0ZXh0JywgdGhpcy5jdXJyZW50VGljayk7XG4gICAgICAgICAgICB0aGlzLmVtaXQoVElNRUxJTkVfQ0hBTkdFLCB0aGlzLmN1cnJlbnRUaWNrKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdldENhbnZhcygpLmRyYXcoKTtcbiAgICB9O1xuICAgIC8qKiDlkIzmraXlnIbngrnliLAgY3Vycm5lbnRUaWNrICovXG4gICAgVGltZUxpbmUucHJvdG90eXBlLnN5bmNDdXJybmVudFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMuY29uZmlnLnRpY2tzO1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSB0aGlzLnRpbWVMaW5lLndpZHRoIC8gKHRpY2tzLmxlbmd0aCAtIDEpO1xuICAgICAgICB2YXIgaW5kZXggPSB1dGlsXzEuZmluZEluZGV4KHRpY2tzLCBmdW5jdGlvbiAodGljaykgeyByZXR1cm4gdGljayA9PT0gX3RoaXMuY3VycmVudFRpY2s7IH0pO1xuICAgICAgICB2YXIgeCA9IHRoaXMudGltZUxpbmUueCArIGluZGV4ICogaW50ZXJ2YWw7XG4gICAgICAgIHRoaXMudGltZVNlbGVjdC5hdHRyKCd4JywgeCk7XG4gICAgICAgIHRoaXMudGltZVNlbGVjdFRleHQuYXR0cigneCcsIHgpO1xuICAgICAgICB0aGlzLmdldENhbnZhcygpLmRyYXcoKTtcbiAgICB9O1xuICAgIFRpbWVMaW5lLnByb3RvdHlwZS5zdGFydFBsYXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IF90aGlzLmNvbmZpZywgc3BlZWQgPSBfYS5zcGVlZCwgdGlja3MgPSBfYS50aWNrcztcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IF90aGlzLnRpbWVMaW5lLndpZHRoO1xuICAgICAgICAgICAgdmFyIHRpY2tJbnRlcnZhbCA9IHdpZHRoIC8gdGlja3MubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIG9mZnNldFggPSB0aWNrSW50ZXJ2YWwgLyAoKHNwZWVkICogMTAwMCkgLyA2MCk7XG4gICAgICAgICAgICBfdGhpcy5zZXRUaW1lU2VsZWN0WChvZmZzZXRYKTtcbiAgICAgICAgICAgIGlmIChfdGhpcy5pc1BsYXkpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5wbGF5SGFuZGxlciA9IF90aGlzLnN0YXJ0UGxheSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRpbWVMaW5lLnByb3RvdHlwZS5jaGFuZ2VQbGF5U3RhdHVzID0gZnVuY3Rpb24gKGlzU3luYykge1xuICAgICAgICBpZiAoaXNTeW5jID09PSB2b2lkIDApIHsgaXNTeW5jID0gdHJ1ZTsgfVxuICAgICAgICB0aGlzLnRpbWVMaW5lQnV0dG9uLnVwZGF0ZSh7XG4gICAgICAgICAgICBpc1BsYXk6IHRoaXMuaXNQbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuaXNQbGF5KSB7XG4gICAgICAgICAgICAvLyDlvIDlp4vmkq3mlL5cbiAgICAgICAgICAgIHRoaXMucGxheUhhbmRsZXIgPSB0aGlzLnN0YXJ0UGxheSgpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KFRJTUVMSU5FX1NUQVJULCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIOe7k+adn+aSreaUvlxuICAgICAgICAgICAgaWYgKHRoaXMucGxheUhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5wbGF5SGFuZGxlcik7XG4gICAgICAgICAgICAgICAgaWYgKGlzU3luYykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN5bmNDdXJybmVudFRpY2soKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFRJTUVMSU5FX0VORCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuZ2V0Q2FudmFzKCkuZHJhdygpO1xuICAgIH07XG4gICAgVGltZUxpbmUucHJvdG90eXBlLmluaXRFdmVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgLyoqIOaSreaUvi/mmoLlgZzkuovku7YgKi9cbiAgICAgICAgdGhpcy50aW1lTGluZUJ1dHRvbi5vZmYoJ2NsaWNrJyk7XG4gICAgICAgIHRoaXMudGltZUxpbmVCdXR0b24ub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuaXNQbGF5ID0gIV90aGlzLmlzUGxheTtcbiAgICAgICAgICAgIF90aGlzLmNoYW5nZVBsYXlTdGF0dXMoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKiDmkq3mlL7ovbTkuIrlnIbngrnmu5Hliqjkuovku7YgKi9cbiAgICAgICAgdGhpcy50aW1lU2VsZWN0Lm9mZignbW91c2Vkb3duJyk7XG4gICAgICAgIHRoaXMudGltZVNlbGVjdC5vbignbW91c2Vkb3duJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBfdGhpcy5vblRpbWVTZWxlY3RNb3VzZURvd24oZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBUaW1lTGluZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRpbWVMaW5lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkVWRU5UUyA9IGV4cG9ydHMuRUxFTUVOVF9OQU1FUyA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2Jhc2VcIikpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi9kZXBlbmRlbnRzXCIpO1xudmFyIGdfdXRpbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvZy11dGlsXCIpO1xudmFyIHRleHRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3RleHRcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3V0aWwvYmJveFwiKSk7XG52YXIgRUxFTUVOVF9OQU1FUztcbihmdW5jdGlvbiAoRUxFTUVOVF9OQU1FUykge1xuICAgIEVMRU1FTlRfTkFNRVNbXCJUT09MVElQX0lORElDQVRPUl9JTk5FUlwiXSA9IFwidG9vbHRpcF9pbmRpY2F0b3ItaW5uZXJcIjtcbiAgICBFTEVNRU5UX05BTUVTW1wiVE9PTFRJUF9JTkRJQ0FUT1JfVElUTEVcIl0gPSBcInRvb2x0aXBfaW5kaWNhdG9yLXRpdGxlXCI7XG4gICAgRUxFTUVOVF9OQU1FU1tcIlRPT0xUSVBfSU5ESUNBVE9SX0JPRFlcIl0gPSBcInRvb2x0aXBfaW5kaWNhdG9yLWJvZHlcIjtcbiAgICBFTEVNRU5UX05BTUVTW1wiVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9HUk9VUFwiXSA9IFwidG9vbHRpcF9pbmRpY2F0b3ItaXRlbS1ncm91cFwiO1xuICAgIEVMRU1FTlRfTkFNRVNbXCJUT09MVElQX0lORElDQVRPUl9JVEVNX0JBQ0tHUk9VTkRcIl0gPSBcInRvb2x0aXBfaW5kaWNhdG9yLWl0ZW0tYmFja2dyb3VuZFwiO1xuICAgIEVMRU1FTlRfTkFNRVNbXCJUT09MVElQX0lORElDQVRPUl9JVEVNX0xJTkVcIl0gPSBcInRvb2x0aXBfaW5kaWNhdG9yLWl0ZW0tbGluZVwiO1xuICAgIEVMRU1FTlRfTkFNRVNbXCJUT09MVElQX0lORElDQVRPUl9JVEVNX1RJVExFXCJdID0gXCJ0b29sdGlwX2luZGljYXRvci1pdGVtLXRpdGxlXCI7XG4gICAgRUxFTUVOVF9OQU1FU1tcIlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fQk9EWVwiXSA9IFwidG9vbHRpcF9pbmRpY2F0b3ItaXRlbS1ib2R5XCI7XG4gICAgRUxFTUVOVF9OQU1FU1tcIlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fVkFMVUVfR1JPVVBcIl0gPSBcInRvb2x0aXBfaW5kaWNhdG9yLWl0ZW0tdmFsdWUtZ3JvdXBcIjtcbiAgICBFTEVNRU5UX05BTUVTW1wiVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9OQU1FXCJdID0gXCJ0b29sdGlwX2luZGljYXRvci1pdGVtLW5hbWVcIjtcbiAgICBFTEVNRU5UX05BTUVTW1wiVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9WQUxVRVwiXSA9IFwidG9vbHRpcF9pbmRpY2F0b3ItaXRlbS12YWx1ZVwiO1xufSkoRUxFTUVOVF9OQU1FUyA9IGV4cG9ydHMuRUxFTUVOVF9OQU1FUyB8fCAoZXhwb3J0cy5FTEVNRU5UX05BTUVTID0ge30pKTtcbnZhciBFVkVOVFM7XG4oZnVuY3Rpb24gKEVWRU5UUykge1xuICAgIEVWRU5UU1tcIk9OX1NFTEVDVF9JVEVNXCJdID0gXCJvblNlbGVjdEl0ZW1cIjtcbn0pKEVWRU5UUyA9IGV4cG9ydHMuRVZFTlRTIHx8IChleHBvcnRzLkVWRU5UUyA9IHt9KSk7XG52YXIgUEFERElORztcbihmdW5jdGlvbiAoUEFERElORykge1xuICAgIFBBRERJTkdbUEFERElOR1tcIkxBUkdFXCJdID0gMTJdID0gXCJMQVJHRVwiO1xuICAgIFBBRERJTkdbUEFERElOR1tcIk5PUk1BTFwiXSA9IDhdID0gXCJOT1JNQUxcIjtcbiAgICBQQURESU5HW1BBRERJTkdbXCJTTUFMTFwiXSA9IDRdID0gXCJTTUFMTFwiO1xufSkoUEFERElORyB8fCAoUEFERElORyA9IHt9KSk7XG52YXIgTUFYX0lURU1fVElUTEVfV0lEVEggPSAxNjA7XG4vKiog5oyH5qCH5Y2h5Zu+5L6L57uE5Lu2ICovXG52YXIgVG9vbHRpcEluZGljYXRvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUb29sdGlwSW5kaWNhdG9yLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRvb2x0aXBJbmRpY2F0b3IoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5jdXJYID0gMDtcbiAgICAgICAgX3RoaXMuY3VyWSA9IDA7XG4gICAgICAgIF90aGlzLm9mZnNldFggPSAwO1xuICAgICAgICBfdGhpcy5zY3JvbGxXaWR0aCA9IDA7XG4gICAgICAgIF90aGlzLm9uQm9keUdyb3VwTW91c2Vtb3ZlID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICAgICAgdmFyIGl0ZW1Hcm91cCA9IGZpbmRUYXJnZXRBbmNlc3RvcihldnQudGFyZ2V0LCBmdW5jdGlvbiAodGFyZ2V0KSB7IHJldHVybiB0YXJnZXQuZ2V0KCduYW1lJykgPT09IEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9HUk9VUDsgfSk7XG4gICAgICAgICAgICBpZiAoaXRlbUdyb3VwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW1EYXRhID0gaXRlbUdyb3VwLmdldCgnZGVsZWdhdGVPYmplY3QnKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5kb1NlbGVjdEl0ZW0oaXRlbURhdGEuaXRlbS5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIF90aGlzLm9uV2hlZWwgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgICAgICB2YXIgX2EgPSBfdGhpcy5jb25maWcud2lkdGgsIHdpZHRoID0gX2EgPT09IHZvaWQgMCA/IDAgOiBfYTtcbiAgICAgICAgICAgIHZhciBkZWx0YVggPSBldnQuZGVsdGFYO1xuICAgICAgICAgICAgdmFyIG9mZnNldE1pbiA9IE1hdGgubWluKF90aGlzLnNjcm9sbFdpZHRoIC0gd2lkdGgsIDApIC0gKF90aGlzLnNjcm9sbFdpZHRoIC8gMiArIE1hdGgubWF4KDAsIChfdGhpcy5zY3JvbGxXaWR0aCAtIHdpZHRoKSAvIDIpKTtcbiAgICAgICAgICAgIHZhciBvZmZzZXRNYXggPSBNYXRoLm1heChfdGhpcy5zY3JvbGxXaWR0aCAtIHdpZHRoLCAwKSArIF90aGlzLnNjcm9sbFdpZHRoIC8gMiArIE1hdGgubWF4KDAsIChfdGhpcy5zY3JvbGxXaWR0aCAtIHdpZHRoKSAvIDIpO1xuICAgICAgICAgICAgdmFyIG5ld09mZnNldFggPSB1dGlsXzEuY2xhbXAoX3RoaXMub2Zmc2V0WCArIGRlbHRhWCwgb2Zmc2V0TWluLCBvZmZzZXRNYXgpO1xuICAgICAgICAgICAgaWYgKG5ld09mZnNldFggIT09IF90aGlzLm9mZnNldFgpIHtcbiAgICAgICAgICAgICAgICBnX3V0aWxfMS50cmFuc2xhdGUoX3RoaXMuYm9keUdyb3VwLCBfdGhpcy5vZmZzZXRYIC0gbmV3T2Zmc2V0WCwgMCk7XG4gICAgICAgICAgICAgICAgX3RoaXMub2Zmc2V0WCA9IG5ld09mZnNldFg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vZmZFdmVudHMoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICAvKiog6YCJ5Lit5p+Q5LiA6aG5ICovXG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUuc2VsZWN0SXRlbSA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICB0aGlzLmRvU2VsZWN0SXRlbShpZCk7XG4gICAgfTtcbiAgICAvKiog6YeN572u6YCJ5Lit54q25oCBICovXG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUucmVzZXRTZWxlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZG9TZWxlY3RJdGVtKHRoaXMuc2VsZWN0ZWRJdGVtSWQpO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUuaW5pdENvbmZpZyA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgX2IgPSBjb25maWcudGhlbWUsIHRoZW1lID0gX2IgPT09IHZvaWQgMCA/IHt9IDogX2I7XG4gICAgICAgIHZhciBkZWZhdWx0Q2ZnID0ge1xuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgICAgIHNwYWNpbmdZOiBQQURESU5HLk5PUk1BTCxcbiAgICAgICAgICAgICAgICBzdHlsZToge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgIHNwYWNpbmdYOiBQQURESU5HLlNNQUxMLFxuICAgICAgICAgICAgICAgIHdpZHRoOiAyLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpdGVtVGl0bGU6IHtcbiAgICAgICAgICAgICAgICBzcGFjaW5nWDogMCxcbiAgICAgICAgICAgICAgICBzcGFjaW5nWTogUEFERElORy5TTUFMTCxcbiAgICAgICAgICAgICAgICBzdHlsZToge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaXRlbU5hbWU6IHtcbiAgICAgICAgICAgICAgICBzcGFjaW5nWDogUEFERElORy5OT1JNQUwsXG4gICAgICAgICAgICAgICAgc3BhY2luZ1k6IFBBRERJTkcuU01BTEwsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGl0ZW1WYWx1ZToge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpdGVtQmFja2dyb3VuZDoge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjMDAwJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGl0ZW1TcGFjaW5nOiBQQURESU5HLkxBUkdFLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCAoX2EgPSB0aGVtZSA9PT0gbnVsbCB8fCB0aGVtZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogdGhlbWUuY29tcG9uZW50cykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLnRvb2x0aXBJbmRpY2F0b3IsIGRlZmF1bHRDZmcsIGNvbmZpZyk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtSWQgPSB0aGlzLmNvbmZpZy5zZWxlY3RlZEl0ZW07XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9yLnByb3RvdHlwZS5yZW5kZXJJbm5lciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLnJlc2V0UmVuZGVyKCk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY29uZmlnLCBpdGVtcyA9IF9hLml0ZW1zLCB4ID0gX2EueCwgeSA9IF9hLnk7XG4gICAgICAgIHZhciBpdGVtR3JvdXBzID0gW107XG4gICAgICAgIHZhciBpbm5lckdyb3VwID0gZ3JvdXAuYWRkR3JvdXAoe1xuICAgICAgICAgICAgbmFtZTogRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9JTk5FUixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVuZGVyVGl0bGUoaW5uZXJHcm91cCk7XG4gICAgICAgIHRoaXMuYm9keUdyb3VwID0gaW5uZXJHcm91cC5hZGRHcm91cCh7XG4gICAgICAgICAgICBuYW1lOiBFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX0JPRFksXG4gICAgICAgIH0pO1xuICAgICAgICBpdGVtcyA9PT0gbnVsbCB8fCBpdGVtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogaXRlbXMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGl0ZW1Hcm91cHMucHVzaChfdGhpcy5yZW5kZXJJdGVtKF90aGlzLmJvZHlHcm91cCwgaXRlbSwgaW5kZXgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubGF5b3V0SXRlbXMoaW5uZXJHcm91cCk7XG4gICAgICAgIGdfdXRpbF8xLm1vdmUoaW5uZXJHcm91cCwgeCwgeSk7XG4gICAgICAgIHRoaXMuYXBwbHlDbGlwKGdyb3VwKTtcbiAgICAgICAgdGhpcy5iaW5kRXZlbnRzKGlubmVyR3JvdXApO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUucmVuZGVyVGl0bGUgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHRpdGxlID0gdGhpcy5jb25maWcudGl0bGU7XG4gICAgICAgIGlmICh0aXRsZSA9PT0gbnVsbCB8fCB0aXRsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogdGl0bGUudGV4dCkge1xuICAgICAgICAgICAgdmFyIHNoYXBlID0gZ3JvdXAuYWRkU2hhcGUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiBFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX1RJVExFLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgdGV4dDogdGl0bGUgPT09IG51bGwgfHwgdGl0bGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHRpdGxlLnRleHQsIHRleHRBbGlnbjogJ2xlZnQnLCB0ZXh0QmFzZWxpbmU6ICd0b3AnIH0sICgodGl0bGUgPT09IG51bGwgfHwgdGl0bGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHRpdGxlLnN0eWxlKSB8fCB7fSkpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgICAgIHRoaXMuY3VyWSArPSBiYm94LmhlaWdodDtcbiAgICAgICAgICAgIHRoaXMuY3VyWSArPSB0aXRsZS5zcGFjaW5nWSB8fCAwO1xuICAgICAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9yLnByb3RvdHlwZS5yZW5kZXJJdGVtID0gZnVuY3Rpb24gKGdyb3VwLCBpdGVtLCBpbmRleCkge1xuICAgICAgICB2YXIgaXRlbUJhY2tncm91bmQgPSB0aGlzLmNvbmZpZy5pdGVtQmFja2dyb3VuZDtcbiAgICAgICAgdmFyIGl0ZW1Hcm91cCA9IGdyb3VwLmFkZEdyb3VwKHtcbiAgICAgICAgICAgIG5hbWU6IEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9HUk9VUCxcbiAgICAgICAgICAgIGRlbGVnYXRlT2JqZWN0OiB7XG4gICAgICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIG9sZFggPSB0aGlzLmN1clg7XG4gICAgICAgIHZhciBvbGRZID0gdGhpcy5jdXJZO1xuICAgICAgICB2YXIgYmFja2dyb3VuZCA9IGl0ZW1Hcm91cC5hZGRTaGFwZSh7XG4gICAgICAgICAgICBuYW1lOiBFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fQkFDS0dST1VORCxcbiAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogdGhpcy5jdXJYLCB5OiB0aGlzLmN1clksIHdpZHRoOiAxLCBoZWlnaHQ6IDEgfSwgKGl0ZW1CYWNrZ3JvdW5kLnN0eWxlIHx8IHt9KSksXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgbGluZSA9IHRoaXMucmVuZGVyTGluZShpdGVtR3JvdXAsIGl0ZW0pO1xuICAgICAgICB0aGlzLnJlbmRlckl0ZW1UaXRsZShpdGVtR3JvdXAsIGl0ZW0pO1xuICAgICAgICB0aGlzLnJlbmRlckl0ZW1WYWx1ZXMoaXRlbUdyb3VwLCBpdGVtKTtcbiAgICAgICAgdmFyIGl0ZW1Hcm91cEJCb3ggPSBpdGVtR3JvdXAuZ2V0QkJveCgpO1xuICAgICAgICAvLyB1cGRhdGUgbGluZSBoZWlnaHRcbiAgICAgICAgbGluZS5hdHRyKHtcbiAgICAgICAgICAgIHkyOiBsaW5lLmF0dHIoJ3kxJykgKyBpdGVtR3JvdXBCQm94LmhlaWdodCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNwYWNpbmdcbiAgICAgICAgdGhpcy5jdXJYID0gb2xkWCArIGl0ZW1Hcm91cEJCb3gud2lkdGg7XG4gICAgICAgIHRoaXMuY3VyWCArPSB0aGlzLmNvbmZpZy5pdGVtU3BhY2luZyB8fCAwO1xuICAgICAgICAvLyB1cGRhdGUgYmFja2dyb3VuZFxuICAgICAgICBiYWNrZ3JvdW5kLmF0dHIoe1xuICAgICAgICAgICAgd2lkdGg6IHRoaXMuY3VyWCAtIG9sZFggLSBiYWNrZ3JvdW5kLmF0dHIoJ2xpbmVXaWR0aCcpICogMixcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5jdXJZIC0gb2xkWSAtIGJhY2tncm91bmQuYXR0cignbGluZVdpZHRoJykgKiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gcmVzZXQgWVxuICAgICAgICB0aGlzLmN1clkgPSBvbGRZO1xuICAgICAgICByZXR1cm4gaXRlbUdyb3VwO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUucmVuZGVyTGluZSA9IGZ1bmN0aW9uIChncm91cCwgaXRlbSkge1xuICAgICAgICB2YXIgbGluZSA9IHRoaXMuY29uZmlnLmxpbmU7XG4gICAgICAgIHZhciB3aWR0aCA9IGxpbmUud2lkdGggfHwgMjtcbiAgICAgICAgdmFyIGF0dHJzID0gdHNsaWJfMS5fX2Fzc2lnbih7IHgxOiB0aGlzLmN1clggKyB3aWR0aCAvIDIsIHkxOiB0aGlzLmN1clksIHgyOiB0aGlzLmN1clggKyB3aWR0aCAvIDIsIHkyOiB0aGlzLmN1clksIGxpbmVXaWR0aDogd2lkdGgsIHN0cm9rZTogaXRlbS5jb2xvciB9LCAoKGxpbmUgPT09IG51bGwgfHwgbGluZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGluZS5zdHlsZSkgfHwge30pKTtcbiAgICAgICAgdmFyIHNoYXBlID0gZ3JvdXAuYWRkU2hhcGUoe1xuICAgICAgICAgICAgbmFtZTogRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9JVEVNX0xJTkUsXG4gICAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgICBhdHRyczogYXR0cnMsXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdGhpcy5jdXJYICs9IGJib3gud2lkdGg7XG4gICAgICAgIHRoaXMuY3VyWCArPSBsaW5lLnNwYWNpbmdYIHx8IDA7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3IucHJvdG90eXBlLnJlbmRlckl0ZW1UaXRsZSA9IGZ1bmN0aW9uIChncm91cCwgaXRlbSkge1xuICAgICAgICB2YXIgaXRlbVRpdGxlID0gdGhpcy5jb25maWcuaXRlbVRpdGxlO1xuICAgICAgICB2YXIgdGV4dCA9IHRleHRfMS5nZXRFbGxpcHNpc1RleHQoaXRlbS50aXRsZSwgTUFYX0lURU1fVElUTEVfV0lEVEgsIGl0ZW1UaXRsZS5zdHlsZSB8fCB7fSk7XG4gICAgICAgIHZhciBzaGFwZSA9IGdyb3VwLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIG5hbWU6IEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9USVRMRSxcbiAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogdGhpcy5jdXJYLCB5OiB0aGlzLmN1clksIHRleHRBbGlnbjogJ2xlZnQnLCB0ZXh0QmFzZWxpbmU6ICd0b3AnLCB0ZXh0OiB0ZXh0IH0sIChpdGVtVGl0bGUuc3R5bGUgfHwge30pKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB0aGlzLmN1clkgKz0gYmJveC5oZWlnaHQ7XG4gICAgICAgIHRoaXMuY3VyWSArPSBpdGVtVGl0bGUuc3BhY2luZ1kgfHwgMDtcbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUucmVuZGVySXRlbVZhbHVlcyA9IGZ1bmN0aW9uIChncm91cCwgaXRlbSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHZhciBpdGVtQm9keUdyb3VwID0gZ3JvdXAuYWRkR3JvdXAoe1xuICAgICAgICAgICAgbmFtZTogRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9JVEVNX0JPRFksXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgb2xkWCA9IHRoaXMuY3VyWDtcbiAgICAgICAgKF9hID0gaXRlbS52YWx1ZXMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwgdmFsdWVJbmRleCkge1xuICAgICAgICAgICAgdmFyIHZhbHVlR3JvdXAgPSBpdGVtQm9keUdyb3VwLmFkZEdyb3VwKHtcbiAgICAgICAgICAgICAgICBuYW1lOiBFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fVkFMVUVfR1JPVVAsXG4gICAgICAgICAgICAgICAgZGVsZWdhdGVPYmplY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVJbmRleDogdmFsdWVJbmRleCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyByZXNldCB4XG4gICAgICAgICAgICBfdGhpcy5jdXJYID0gb2xkWDtcbiAgICAgICAgICAgIF90aGlzLnJlbmRlckl0ZW1WYWx1ZU5hbWUodmFsdWVHcm91cCwgdmFsdWUpO1xuICAgICAgICAgICAgX3RoaXMucmVuZGVySXRlbVZhbHVlVmFsdWUodmFsdWVHcm91cCwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sYXlvdXRJdGVtVmFsdWVzKGl0ZW1Cb2R5R3JvdXApO1xuICAgICAgICByZXR1cm4gaXRlbUJvZHlHcm91cDtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3IucHJvdG90eXBlLnJlbmRlckl0ZW1WYWx1ZU5hbWUgPSBmdW5jdGlvbiAoZ3JvdXAsIHZhbHVlKSB7XG4gICAgICAgIHZhciBpdGVtTmFtZSA9IHRoaXMuY29uZmlnLml0ZW1OYW1lO1xuICAgICAgICBpZiAodmFsdWUubmFtZSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlID0gZ3JvdXAuYWRkU2hhcGUoe1xuICAgICAgICAgICAgICAgIG5hbWU6IEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9OQU1FLFxuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHg6IHRoaXMuY3VyWCwgeTogdGhpcy5jdXJZLCB0ZXh0QWxpZ246ICdsZWZ0JywgdGV4dEJhc2VsaW5lOiAndG9wJywgdGV4dDogdmFsdWUubmFtZSB9LCAoaXRlbU5hbWUuc3R5bGUgfHwge30pKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIGJib3ggPSBzaGFwZS5nZXRCQm94KCk7XG4gICAgICAgICAgICBpZiAodmFsdWUud3JhcExpbmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1clkgKz0gYmJveC5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJZICs9IGl0ZW1OYW1lLnNwYWNpbmdZIHx8IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1clggKz0gYmJveC53aWR0aDtcbiAgICAgICAgICAgICAgICB0aGlzLmN1clggKz0gaXRlbU5hbWUuc3BhY2luZ1ggfHwgMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzaGFwZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUucmVuZGVySXRlbVZhbHVlVmFsdWUgPSBmdW5jdGlvbiAoZ3JvdXAsIHZhbHVlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY29uZmlnLCBpdGVtTmFtZSA9IF9hLml0ZW1OYW1lLCBpdGVtVmFsdWUgPSBfYS5pdGVtVmFsdWU7XG4gICAgICAgIHZhciBzaGFwZSA9IGdyb3VwLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIG5hbWU6IEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9WQUxVRSxcbiAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgeDogdGhpcy5jdXJYLCB5OiB0aGlzLmN1clksIHRleHRBbGlnbjogJ2xlZnQnLCB0ZXh0QmFzZWxpbmU6ICd0b3AnLCB0ZXh0OiB2YWx1ZS52YWx1ZSB9LCAoaXRlbVZhbHVlLnN0eWxlIHx8IHt9KSksXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdGhpcy5jdXJZICs9IGJib3guaGVpZ2h0O1xuICAgICAgICB0aGlzLmN1clkgKz0gaXRlbU5hbWUuc3BhY2luZ1kgfHwgMDtcbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUubGF5b3V0SXRlbXMgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIGJvZHlHcm91cCA9IGdyb3VwLmZpbmRBbGxCeU5hbWUoRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9CT0RZKVswXTtcbiAgICAgICAgdmFyIGl0ZW1Hcm91cHMgPSBncm91cC5maW5kQWxsQnlOYW1lKEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9HUk9VUCk7XG4gICAgICAgIGlmICghYm9keUdyb3VwIHx8IGl0ZW1Hcm91cHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJvZHlHcm91cEJCb3ggPSBib2R5R3JvdXAuZ2V0QkJveCgpO1xuICAgICAgICB0aGlzLnNjcm9sbFdpZHRoID0gYm9keUdyb3VwQkJveC53aWR0aDtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3IucHJvdG90eXBlLmxheW91dEl0ZW1WYWx1ZXMgPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgICAgdmFyIHZhbHVlR3JvdXBzID0gZ3JvdXAuZmluZEFsbEJ5TmFtZShFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fVkFMVUVfR1JPVVApO1xuICAgICAgICB2YXIgdmFsdWVHcm91cEJCb3hlcyA9IHZhbHVlR3JvdXBzLm1hcChmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gYmJveF8xLmRlZmF1bHQuZnJvbUJCb3hPYmplY3QoaXRlbS5nZXRCQm94KCkpOyB9KTtcbiAgICAgICAgdmFyIHZhbHVlU2hhcGVzID0gZ3JvdXAuZmluZEFsbEJ5TmFtZShFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fVkFMVUUpO1xuICAgICAgICB2YXIgdmFsdWVTaGFwZUJCb3hlcyA9IHZhbHVlU2hhcGVzLm1hcChmdW5jdGlvbiAoc2hhcGUpIHsgcmV0dXJuIGJib3hfMS5kZWZhdWx0LmZyb21CQm94T2JqZWN0KHNoYXBlLmdldEJCb3goKSk7IH0pO1xuICAgICAgICB2YXIgbWF4WCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHZhbHVlU2hhcGVCQm94ZXMubWFwKGZ1bmN0aW9uIChiYm94KSB7IHJldHVybiBiYm94Lm1heFg7IH0pKTtcbiAgICAgICAgdmFsdWVHcm91cHMuZm9yRWFjaChmdW5jdGlvbiAodmFsdWVHcm91cCwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gdmFsdWVHcm91cEJCb3hlc1tpbmRleF07XG4gICAgICAgICAgICB2YXIgbmFtZVNoYXBlID0gdmFsdWVHcm91cC5maW5kQWxsQnlOYW1lKEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9OQU1FKVswXTtcbiAgICAgICAgICAgIHZhciB2YWx1ZVNoYXBlID0gdmFsdWVHcm91cC5maW5kQWxsQnlOYW1lKEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9WQUxVRSlbMF07XG4gICAgICAgICAgICBpZiAobmFtZVNoYXBlICYmIHZhbHVlU2hhcGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZVNoYXBlQkJveCA9IGJib3hfMS5kZWZhdWx0LmZyb21CQm94T2JqZWN0KG5hbWVTaGFwZS5nZXRCQm94KCkpO1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZVNoYXBlQkJveCA9IGJib3hfMS5kZWZhdWx0LmZyb21CQm94T2JqZWN0KHZhbHVlU2hhcGUuZ2V0QkJveCgpKTtcbiAgICAgICAgICAgICAgICAvLyBob3Jpem9udGFsIGFsaWduOiBuYW1lICYgdmFsdWVcbiAgICAgICAgICAgICAgICBpZiAobmFtZVNoYXBlQkJveC5oZWlnaHQgPCBiYm94LmhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBuYW1lU2hhcGUuYXR0cigneScsIG5hbWVTaGFwZS5hdHRyKCd5JykgKyAoYmJveC5oZWlnaHQgLSBuYW1lU2hhcGVCQm94LmhlaWdodCkgLyAyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlU2hhcGVCQm94LmhlaWdodCA8IGJib3guaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlU2hhcGUuYXR0cigneScsIHZhbHVlU2hhcGUuYXR0cigneScpICsgKGJib3guaGVpZ2h0IC0gdmFsdWVTaGFwZUJCb3guaGVpZ2h0KSAvIDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyB2ZXJ0aWNhbCBhbGlnbiB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAodmFsdWVTaGFwZUJCb3gubWF4WCA8IG1heFgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVTaGFwZS5hdHRyKCd4JywgdmFsdWVTaGFwZS5hdHRyKCd4JykgKyBtYXhYIC0gdmFsdWVTaGFwZUJCb3gubWF4WCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3IucHJvdG90eXBlLmFwcGx5Q2xpcCA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmNvbmZpZywgeCA9IF9hLngsIHkgPSBfYS55LCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgIHZhciBiYm94ID0gZ3JvdXAuZ2V0QkJveCgpO1xuICAgICAgICBpZiAod2lkdGggfHwgaGVpZ2h0KSB7XG4gICAgICAgICAgICBncm91cC5zZXRDbGlwKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoIHx8IGJib3gud2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0IHx8IGJib3guaGVpZ2h0LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvci5wcm90b3R5cGUuZG9TZWxlY3RJdGVtID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2V0R3JvdXAoKTtcbiAgICAgICAgdmFyIGl0ZW1Hcm91cHMgPSBncm91cC5maW5kQWxsQnlOYW1lKEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfSVRFTV9HUk9VUCk7XG4gICAgICAgIGlmIChpZCAhPT0gdGhpcy5zZWxlY3RlZEl0ZW1JZCkge1xuICAgICAgICAgICAgaXRlbUdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtR3JvdXApIHtcbiAgICAgICAgICAgICAgICB2YXIgY3VySXRlbURhdGEgPSBpdGVtR3JvdXAuZ2V0KCdkZWxlZ2F0ZU9iamVjdCcpO1xuICAgICAgICAgICAgICAgIGlmIChjdXJJdGVtRGF0YSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5hcHBseUl0ZW1TdHlsZShpdGVtR3JvdXAsIGN1ckl0ZW1EYXRhLml0ZW0uaWQgPT09IGlkID8gJ3NlbGVjdGVkJyA6ICdpbmFjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1JZCA9IGlkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5Y+W5raI6YCJ5LitXG4gICAgICAgICAgICBpdGVtR3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGl0ZW1Hcm91cCkge1xuICAgICAgICAgICAgICAgIF90aGlzLmFwcGx5SXRlbVN0eWxlKGl0ZW1Hcm91cCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtSWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbWl0KEVWRU5UUy5PTl9TRUxFQ1RfSVRFTSwgdGhpcy5zZWxlY3RlZEl0ZW1JZCk7XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9yLnByb3RvdHlwZS5hcHBseUl0ZW1TdHlsZSA9IGZ1bmN0aW9uIChpdGVtR3JvdXAsIHN0YXRlKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY29uZmlnLCBsaW5lID0gX2EubGluZSwgaXRlbVRpdGxlID0gX2EuaXRlbVRpdGxlLCBpdGVtTmFtZSA9IF9hLml0ZW1OYW1lLCBpdGVtVmFsdWUgPSBfYS5pdGVtVmFsdWU7XG4gICAgICAgIHZhciBsaW5lU2hhcGUgPSBpdGVtR3JvdXAuZmluZEFsbEJ5TmFtZShFTEVNRU5UX05BTUVTLlRPT0xUSVBfSU5ESUNBVE9SX0lURU1fTElORSlbMF07XG4gICAgICAgIHZhciB0aXRsZVNoYXBlID0gaXRlbUdyb3VwLmZpbmRBbGxCeU5hbWUoRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9JVEVNX1RJVExFKVswXTtcbiAgICAgICAgdmFyIGl0ZW1OYW1lU2hhcGVzID0gaXRlbUdyb3VwLmZpbmRBbGxCeU5hbWUoRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9JVEVNX05BTUUpO1xuICAgICAgICB2YXIgaXRlbVZhbHVlU2hhcGVzID0gaXRlbUdyb3VwLmZpbmRBbGxCeU5hbWUoRUxFTUVOVF9OQU1FUy5UT09MVElQX0lORElDQVRPUl9JVEVNX1ZBTFVFKTtcbiAgICAgICAgdmFyIHN0eWxlTmFtZSA9IHN0YXRlICYmIHN0YXRlICsgXCJTdHlsZVwiO1xuICAgICAgICBpZiAobGluZVNoYXBlKSB7XG4gICAgICAgICAgICBsaW5lU2hhcGUuYXR0cihsaW5lLnN0eWxlKTtcbiAgICAgICAgICAgIGxpbmVTaGFwZS5hdHRyKGxpbmVbc3R5bGVOYW1lXSB8fCB7fSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpdGxlU2hhcGUpIHtcbiAgICAgICAgICAgIHRpdGxlU2hhcGUuYXR0cihpdGVtVGl0bGUuc3R5bGUpO1xuICAgICAgICAgICAgdGl0bGVTaGFwZS5hdHRyKGl0ZW1UaXRsZVtzdHlsZU5hbWVdIHx8IHt9KTtcbiAgICAgICAgfVxuICAgICAgICBpdGVtTmFtZVNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtTmFtZVNoYXBlKSB7XG4gICAgICAgICAgICBpdGVtTmFtZVNoYXBlLmF0dHIoaXRlbU5hbWUuc3R5bGUpO1xuICAgICAgICAgICAgaXRlbU5hbWVTaGFwZS5hdHRyKGl0ZW1OYW1lW3N0eWxlTmFtZV0gfHwge30pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXRlbVZhbHVlU2hhcGVzLmZvckVhY2goZnVuY3Rpb24gKGl0ZW1WYWx1ZVNoYXBlKSB7XG4gICAgICAgICAgICBpdGVtVmFsdWVTaGFwZS5hdHRyKGl0ZW1WYWx1ZS5zdHlsZSk7XG4gICAgICAgICAgICBpdGVtVmFsdWVTaGFwZS5hdHRyKGl0ZW1WYWx1ZVtzdHlsZU5hbWVdIHx8IHt9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9yLnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMub2ZmRXZlbnRzKCk7XG4gICAgICAgIHZhciBib2R5R3JvdXAgPSBncm91cC5maW5kQWxsQnlOYW1lKEVMRU1FTlRfTkFNRVMuVE9PTFRJUF9JTkRJQ0FUT1JfQk9EWSlbMF07XG4gICAgICAgIGJvZHlHcm91cC5vbignbW91c2Vtb3ZlJywgdGhpcy5vbkJvZHlHcm91cE1vdXNlbW92ZSk7XG4gICAgICAgIHRoaXMuYWRkRGlzcG9zYWJsZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBib2R5R3JvdXAub2ZmKCdtb3VzZW1vdmUnLCBfdGhpcy5vbkJvZHlHcm91cE1vdXNlbW92ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdtID0gbmV3IGRlcGVuZGVudHNfMS5HTShib2R5R3JvdXApO1xuICAgICAgICB0aGlzLndoZWVsID0gbmV3IGRlcGVuZGVudHNfMS5XaGVlbChib2R5R3JvdXApO1xuICAgICAgICB0aGlzLndoZWVsLm9uKCd3aGVlbCcsIHRoaXMub25XaGVlbCk7XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9yLnByb3RvdHlwZS5vZmZFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmdtKSB7XG4gICAgICAgICAgICB0aGlzLmdtLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy53aGVlbCkge1xuICAgICAgICAgICAgdGhpcy53aGVlbC5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3IucHJvdG90eXBlLnJlc2V0UmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmN1clggPSAwO1xuICAgICAgICB0aGlzLmN1clkgPSAwO1xuICAgICAgICB0aGlzLm9mZnNldFggPSAwO1xuICAgIH07XG4gICAgcmV0dXJuIFRvb2x0aXBJbmRpY2F0b3I7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUb29sdGlwSW5kaWNhdG9yO1xuZnVuY3Rpb24gZmluZFRhcmdldEFuY2VzdG9yKGVsZW1lbnQsIHByZWRpY2F0ZSkge1xuICAgIHZhciBjdXIgPSBlbGVtZW50O1xuICAgIHdoaWxlIChjdXIpIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShjdXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3VyO1xuICAgICAgICB9XG4gICAgICAgIGN1ciA9IGN1ci5nZXRQYXJlbnQoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD10b29sdGlwLWluZGljYXRvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBzdGF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvY29udHJvbGxlci9zdGF0ZVwiKTtcbnZhciBQT1NJVElPTl9NQVBQRVIgPSBbJ3hGaWVsZCcsICd5RmllbGQnLCAnYW5nbGVGaWVsZCddO1xuZnVuY3Rpb24gb25BY3RpdmUocGxvdCwgY29uZGl0aW9uKSB7XG4gICAgdmFyIHByb3BzID0gcGxvdC5vcHRpb25zO1xuICAgIC8vIOiOt+WPlnN0YXRlIGNvbmRpdGlvbuWvueW6lOWcqOeUu+W4g+eahOS9jee9ru+8jOWPquacieWcqHN0YXRlIGNvbmRpdGlvbuWvueW6lOWtl+auteS4uuS9jee9ruaYoOWwhOWtl+auteaXtu+8jHRvb2x0aXDmiY3kvJrlr7npvZDov5vooYzlk43lupRcbiAgICBpZiAoc2hvdWxkQWN0aXZlKHByb3BzLCBjb25kaXRpb24pKSB7XG4gICAgICAgIHZhciBkYXRhID0gcHJvcHMuZGF0YTtcbiAgICAgICAgdXRpbF8xLmVhY2goZGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIGlmIChzdGF0ZV8xLmNvbXBhcmUoZCwgY29uZGl0aW9uKSkge1xuICAgICAgICAgICAgICAgIHZhciBwb2ludCA9IHBsb3Qudmlldy5nZXRYWShkKTtcbiAgICAgICAgICAgICAgICAvLyDosIPnlKhzaG93VG9vbHRpcOaWueazlVxuICAgICAgICAgICAgICAgIHBsb3Qudmlldy5vbigndG9vbHRpcDpjcmVhdGUnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzU3RhdGUoY29uZGl0aW9uLCBlLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcGxvdC52aWV3LnNob3dUb29sdGlwKHBvaW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuZnVuY3Rpb24gb25EaXNhYmxlKHBsb3QsIGNvbmRpdGlvbikge1xuICAgIHBsb3Qudmlldy5vbigndG9vbHRpcDpjaGFuZ2UnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICBwcm9jZXNzU3RhdGUoY29uZGl0aW9uLCBlLCB0cnVlKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIHByb2Nlc3NTdGF0ZShjb25kaXRpb24sIGUsIGludmVyc2UpIHtcbiAgICB2YXIgZXhwZWN0ZWQgPSBpbnZlcnNlID8gZmFsc2UgOiB0cnVlO1xuICAgIHZhciBvcmlnaW5JdGVtcyA9IHV0aWxfMS5jbG9uZShlLml0ZW1zKTtcbiAgICBlLml0ZW1zLnNwbGljZSgwKTtcbiAgICB1dGlsXzEuZWFjaChvcmlnaW5JdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgdmFyIG9yaWdpbiA9IGl0ZW0ucG9pbnQuX29yaWdpbjtcbiAgICAgICAgaWYgKHN0YXRlXzEuY29tcGFyZShvcmlnaW4sIGNvbmRpdGlvbikgPT09IGV4cGVjdGVkKSB7XG4gICAgICAgICAgICBlLml0ZW1zLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmZ1bmN0aW9uIHNob3VsZEFjdGl2ZShwcm9wcywgY29uZGl0aW9uKSB7XG4gICAgdmFyIGZpZWxkcyA9IGdldFBvc2l0aW9uRmllbGQocHJvcHMpO1xuICAgIHJldHVybiAhdXRpbF8xLmlzRnVuY3Rpb24oY29uZGl0aW9uKSAmJiBmaWVsZHMuaW5kZXhPZihjb25kaXRpb24ubmFtZSk7XG59XG5mdW5jdGlvbiBnZXRQb3NpdGlvbkZpZWxkKHByb3BzKSB7XG4gICAgdmFyIGZpZWxkcyA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKFBPU0lUSU9OX01BUFBFUiwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsIHYpKSB7XG4gICAgICAgICAgICBmaWVsZHMucHVzaCh2KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBmaWVsZHM7XG59XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgYWN0aXZlOiBvbkFjdGl2ZSxcbiAgICBzZWxlY3RlZDogb25BY3RpdmUsXG4gICAgZGlzYWJsZTogb25EaXNhYmxlLFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5fT1JJR0lOID0gZXhwb3J0cy5PUklHSU4gPSBleHBvcnRzLlRvb2x0aXBDc3NDb25zdCA9IGV4cG9ydHMuSHRtbFRvb2x0aXBUaGVtZSA9IGV4cG9ydHMuSHRtbFRvb2x0aXAgPSBleHBvcnRzLkludGVyYWN0aW9uVXRpbHMgPSBleHBvcnRzLkdyYW1tYXJJbnRlcmFjdGlvbiA9IGV4cG9ydHMuR2VzdHVyZUNvbnRyb2xsZXIgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8vIGRlcGVuZGVudHPmmK/ln7rnoYDkvp3otZbvvIzku6Xkvr/mjInpnIDkvb/nlKhwbG90XG52YXIgZ2VzdHVyZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIkBhbnR2L2cyL2xpYi9jaGFydC9jb250cm9sbGVyL2dlc3R1cmVcIikpO1xuZXhwb3J0cy5HZXN0dXJlQ29udHJvbGxlciA9IGdlc3R1cmVfMS5kZWZhdWx0O1xudmFyIGcyXzEgPSByZXF1aXJlKFwiQGFudHYvZzJcIik7XG5nMl8xLnJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlcignZ2VzdHVyZScsIGdlc3R1cmVfMS5kZWZhdWx0KTtcbi8vIEdcbnZhciBnX2Jhc2VfMSA9IHJlcXVpcmUoXCJAYW50di9nLWJhc2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcmFwaGljRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfYmFzZV8xLkV2ZW50OyB9IH0pO1xudmFyIGdfY2FudmFzXzEgPSByZXF1aXJlKFwiQGFudHYvZy1jYW52YXNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDYW52YXNcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfY2FudmFzXzEuQ2FudmFzOyB9IH0pO1xudmFyIGdfc3ZnXzEgPSByZXF1aXJlKFwiQGFudHYvZy1zdmdcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTVkdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfc3ZnXzEuQ2FudmFzOyB9IH0pO1xuLy8gRy1HZXN0dXJlXG52YXIgZ19nZXN0dXJlXzEgPSByZXF1aXJlKFwiQGFudHYvZy1nZXN0dXJlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiR01cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfZ2VzdHVyZV8xLkdNOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiV2hlZWxcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdfZ2VzdHVyZV8xLldoZWVsOyB9IH0pO1xuLy8gRzJcbnZhciBnMl8yID0gcmVxdWlyZShcIkBhbnR2L2cyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVmlld1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZzJfMi5WaWV3OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJBbmltYXRpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGcyXzIucmVnaXN0ZXJBbmltYXRpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3Rlckdlb21ldHJ5XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBnMl8yLnJlZ2lzdGVyR2VvbWV0cnk7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHZW9tZXRyeVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZzJfMi5HZW9tZXRyeTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkludGVyYWN0aW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBnMl8yLkludGVyYWN0aW9uOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiSW50ZXJhY3Rpb25BY3Rpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGcyXzIuSW50ZXJhY3Rpb25BY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckludGVyYWN0aW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBnMl8yLnJlZ2lzdGVySW50ZXJhY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZWdpc3RlckFjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZzJfMi5yZWdpc3RlckFjdGlvbjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyU2hhcGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGcyXzIucmVnaXN0ZXJTaGFwZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFRoZW1lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBnMl8yLmdldFRoZW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVXRpbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZzJfMi5VdGlsOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0U2hhcGVGYWN0b3J5XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBnMl8yLmdldFNoYXBlRmFjdG9yeTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbXBvbmVudENvbnRyb2xsZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGcyXzIuQ29tcG9uZW50Q29udHJvbGxlcjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZzJfMi5yZWdpc3RlckNvbXBvbmVudENvbnRyb2xsZXI7IH0gfSk7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCJAYW50di9nMi9saWIvY29uc3RhbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJWSUVXX0xJRkVfQ0lSQ0xFXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudF8xLlZJRVdfTElGRV9DSVJDTEU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDT01QT05FTlRfVFlQRVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRfMS5DT01QT05FTlRfVFlQRTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkZJRUxEX09SSUdJTlwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRfMS5GSUVMRF9PUklHSU47IH0gfSk7XG52YXIgdG9vbHRpcF8xID0gcmVxdWlyZShcIkBhbnR2L2cyL2xpYi9jaGFydC9jb250cm9sbGVyL3Rvb2x0aXBcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUb29sdGlwQ29udHJvbGxlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdG9vbHRpcF8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgbWFya2VyXzEgPSByZXF1aXJlKFwiQGFudHYvZzIvbGliL3V0aWwvbWFya2VyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWFya2VyU3ltYm9sc1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbWFya2VyXzEuTWFya2VyU3ltYm9sczsgfSB9KTtcbnZhciBncmFtbWFyX2ludGVyYWN0aW9uXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiQGFudHYvZzIvbGliL2ludGVyYWN0aW9uL2dyYW1tYXItaW50ZXJhY3Rpb25cIikpO1xuZXhwb3J0cy5HcmFtbWFySW50ZXJhY3Rpb24gPSBncmFtbWFyX2ludGVyYWN0aW9uXzEuZGVmYXVsdDtcbnZhciBJbnRlcmFjdGlvblV0aWxzID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIkBhbnR2L2cyL2xpYi9pbnRlcmFjdGlvbi9hY3Rpb24vdXRpbFwiKSk7XG5leHBvcnRzLkludGVyYWN0aW9uVXRpbHMgPSBJbnRlcmFjdGlvblV0aWxzO1xudmFyIGFuaW1hdGVfMSA9IHJlcXVpcmUoXCJAYW50di9nMi9saWIvYW5pbWF0ZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkRFRkFVTFRfQU5JTUFURV9DRkdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFuaW1hdGVfMS5ERUZBVUxUX0FOSU1BVEVfQ0ZHOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0RGVmYXVsdEFuaW1hdGVDZmdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFuaW1hdGVfMS5nZXREZWZhdWx0QW5pbWF0ZUNmZzsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImRvQW5pbWF0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYW5pbWF0ZV8xLmRvQW5pbWF0ZTsgfSB9KTtcbnZhciBlbGVtZW50XzEgPSByZXF1aXJlKFwiQGFudHYvZzIvbGliL2dlb21ldHJ5L2VsZW1lbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFbGVtZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBlbGVtZW50XzEuZGVmYXVsdDsgfSB9KTtcbi8vIENvbXBvbmVudFxudmFyIGh0bWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJAYW50di9jb21wb25lbnQvbGliL3Rvb2x0aXAvaHRtbFwiKSk7XG5leHBvcnRzLkh0bWxUb29sdGlwID0gaHRtbF8xLmRlZmF1bHQ7XG52YXIgaHRtbF90aGVtZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIkBhbnR2L2NvbXBvbmVudC9saWIvdG9vbHRpcC9odG1sLXRoZW1lXCIpKTtcbmV4cG9ydHMuSHRtbFRvb2x0aXBUaGVtZSA9IGh0bWxfdGhlbWVfMS5kZWZhdWx0O1xudmFyIFRvb2x0aXBDc3NDb25zdCA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJAYW50di9jb21wb25lbnQvbGliL3Rvb2x0aXAvY3NzLWNvbnN0XCIpKTtcbmV4cG9ydHMuVG9vbHRpcENzc0NvbnN0ID0gVG9vbHRpcENzc0NvbnN0O1xudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIkBhbnR2L2NvbXBvbmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkdyb3VwQ29tcG9uZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb21wb25lbnRfMS5Hcm91cENvbXBvbmVudDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkF4aXNcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbXBvbmVudF8xLkF4aXM7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJMZWdlbmRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbXBvbmVudF8xLkxlZ2VuZDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRvb2x0aXBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbXBvbmVudF8xLlRvb2x0aXA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTbGlkZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbXBvbmVudF8xLlNsaWRlcjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNjcm9sbGJhclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29tcG9uZW50XzEuU2Nyb2xsYmFyOyB9IH0pO1xuLy8gQ29vcmRpbmF0ZVxudmFyIGNvb3JkXzEgPSByZXF1aXJlKFwiQGFudHYvY29vcmRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDb29yZGluYXRlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb29yZF8xLkNvb3JkaW5hdGU7IH0gfSk7XG4vLyBDb21tb25cbmV4cG9ydHMuT1JJR0lOID0gJ29yaWdpbic7XG5leHBvcnRzLl9PUklHSU4gPSAnX29yaWdpbic7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZXBlbmRlbnRzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbWFpbl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbWFpblwiKSk7XG52YXIgbWluaV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbWluaVwiKSk7XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgbWFpbjogbWFpbl8xLmRlZmF1bHQsXG4gICAgbWluaTogbWluaV8xLmRlZmF1bHQsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG52YXIgQXJlYVBhcnNlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhBcmVhUGFyc2VyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEFyZWFQYXJzZXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQXJlYVBhcnNlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgdHlwZTogJ2FyZWEnLFxuICAgICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFtwcm9wcy54RmllbGQsIHByb3BzLnlGaWVsZF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29ubmVjdE51bGxzOiBwcm9wcy5jb25uZWN0TnVsbHMgfHwgZmFsc2UsXG4gICAgICAgIH07XG4gICAgICAgIGlmIChwcm9wcy5zbW9vdGgpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnNoYXBlID0geyB2YWx1ZXM6IFsnc21vb3RoJ10gfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fZ2V0Q29sb3JNYXBwaW5nRmllbGQoKSB8fCBwcm9wcy5jb2xvcikge1xuICAgICAgICAgICAgdGhpcy5wYXJzZUNvbG9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLmFyZWFTdHlsZSB8fCAocHJvcHMuYXJlYSAmJiBwcm9wcy5hcmVhLnN0eWxlKSkge1xuICAgICAgICAgICAgdGhpcy5wYXJzZVN0eWxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEFyZWFQYXJzZXIucHJvdG90eXBlLnBhcnNlQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIHZhciBjb2xvck1hcHBpbmdGaWVsZCA9IHRoaXMuX2dldENvbG9yTWFwcGluZ0ZpZWxkKCk7XG4gICAgICAgIGlmIChjb2xvck1hcHBpbmdGaWVsZCkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IGNvbG9yTWFwcGluZ0ZpZWxkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1dGlsXzEuaGFzKHByb3BzLCAnY29sb3InKSkge1xuICAgICAgICAgICAgdmFyIGNvbG9yID0gcHJvcHMuY29sb3I7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbY29sb3JdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzRnVuY3Rpb24oY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNBcnJheShjb2xvcikpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29sb3JNYXBwaW5nRmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLnZhbHVlcyA9IGNvbG9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbG9yLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbY29sb3JbMF1dO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnLmNvbG9yID0gY29uZmlnO1xuICAgIH07XG4gICAgQXJlYVBhcnNlci5wcm90b3R5cGUucGFyc2VTdHlsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHZhciBzdHlsZVByb3BzID0gcHJvcHMuYXJlYVN0eWxlID8gcHJvcHMuYXJlYVN0eWxlIDogcHJvcHMuYXJlYS5zdHlsZTtcbiAgICAgICAgdmFyIGNvbmZpZyA9IHt9O1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24oc3R5bGVQcm9wcykgJiYgcHJvcHMuc2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5maWVsZHMgPSBbcHJvcHMuc2VyaWVzRmllbGRdO1xuICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gc3R5bGVQcm9wcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5jZmcgPSBzdHlsZVByb3BzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnLnN0eWxlID0gY29uZmlnO1xuICAgIH07XG4gICAgQXJlYVBhcnNlci5wcm90b3R5cGUuX2dldENvbG9yTWFwcGluZ0ZpZWxkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIGNvbG9yTWFwcGVyID0gWydzdGFja0ZpZWxkJywgJ3Nlcmllc0ZpZWxkJ107XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgY29sb3JNYXBwZXJfMSA9IGNvbG9yTWFwcGVyOyBfaSA8IGNvbG9yTWFwcGVyXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgbSA9IGNvbG9yTWFwcGVyXzFbX2ldO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5nZXQocHJvcHMsIG0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtwcm9wc1ttXV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBBcmVhUGFyc2VyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJlYVBhcnNlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1haW4uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKiDnroDljJbmipjnur/ngrkgKi9cbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vLi4vZGVwZW5kZW50c1wiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBtYXRoXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9tYXRoXCIpO1xudmFyIHBhdGhfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3BhdGhcIik7XG52YXIgbWFpbl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbWFpblwiKSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbmRlcGVuZGVudHNfMS5yZWdpc3RlclNoYXBlKCdhcmVhJywgJ21pbmlBcmVhJywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgb3BhY2l0eSA9IGNmZy5zdHlsZSA/IGNmZy5zdHlsZS5vcGFjaXR5IDogbnVsbDtcbiAgICAgICAgdmFyIHBhdGggPSBnZXRQYXRoKGNmZywgdGhpcywgZmFsc2UpO1xuICAgICAgICB2YXIgc3R5bGUgPSB1dGlsXzEuZGVlcE1peCh7fSwge1xuICAgICAgICAgICAgbGluZUpvaW46ICdyb3VuZCcsXG4gICAgICAgICAgICBsaW5lQ2FwOiAncm91bmQnLFxuICAgICAgICB9LCBjZmcuc3R5bGUpO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgZmlsbDogcGFyc2VHcmFkaWVudChjZmcuY29sb3IgfHwgdGhlbWVfMS5nZXRHbG9iYWxUaGVtZSgpLmRlZmF1bHRDb2xvciksXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogb3BhY2l0eSB8fCAwLjQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH0sXG59KTtcbmRlcGVuZGVudHNfMS5yZWdpc3RlclNoYXBlKCdhcmVhJywgJ21pbmlBcmVhU21vb3RoJywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgb3BhY2l0eSA9IGNmZy5zdHlsZSA/IGNmZy5zdHlsZS5vcGFjaXR5IDogbnVsbDtcbiAgICAgICAgdmFyIHBhdGggPSBnZXRQYXRoKGNmZywgdGhpcywgdHJ1ZSk7XG4gICAgICAgIHZhciBzaGFwZSA9IGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICBmaWxsOiBwYXJzZUdyYWRpZW50KGNmZy5jb2xvciB8fCB0aGVtZV8xLmdldEdsb2JhbFRoZW1lKCkuZGVmYXVsdENvbG9yKSxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBvcGFjaXR5IHx8IDAuNSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfSxcbn0pO1xuZnVuY3Rpb24gZ2V0UGF0aChjZmcsIHNoYXBlLCBpc1Ntb290aCkge1xuICAgIHZhciBjb25zdHJhaW50ID0gW1xuICAgICAgICBbMCwgMF0sXG4gICAgICAgIFsxLCAxXSxcbiAgICBdO1xuICAgIHZhciB0b3BMaW5lUG9pbnRzID0gW107XG4gICAgdmFyIGJvdHRvbUxpbmVQb2ludHMgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChjZmcucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgdG9wTGluZVBvaW50cy5wdXNoKHBvaW50WzFdKTtcbiAgICAgICAgYm90dG9tTGluZVBvaW50cy5wdXNoKHBvaW50WzBdKTtcbiAgICB9KTtcbiAgICBib3R0b21MaW5lUG9pbnRzID0gc2hhcGUucGFyc2VQb2ludHMoYm90dG9tTGluZVBvaW50cy5yZXZlcnNlKCkpO1xuICAgIHRvcExpbmVQb2ludHMgPSBtYXRoXzEubGluZVNpbXBsaWZpY2F0aW9uKHNoYXBlLnBhcnNlUG9pbnRzKHRvcExpbmVQb2ludHMpKTtcbiAgICB2YXIgdG9wUGF0aCA9IGlzU21vb3RoID8gcGF0aF8xLmdldFNwbGluZVBhdGgodG9wTGluZVBvaW50cywgZmFsc2UsIGNvbnN0cmFpbnQpIDogZ2V0U3RyYWlnaHRQYXRoKHRvcExpbmVQb2ludHMpO1xuICAgIHZhciBib3R0b21QYXRoID0gZ2V0U3RyYWlnaHRQYXRoKGJvdHRvbUxpbmVQb2ludHMpO1xuICAgIGJvdHRvbVBhdGhbMF1bMF0gPSAnTCc7XG4gICAgdmFyIHBhdGggPSB0b3BQYXRoLmNvbmNhdChib3R0b21QYXRoKTtcbiAgICByZXR1cm4gcGF0aDtcbn1cbmZ1bmN0aW9uIGdldFN0cmFpZ2h0UGF0aChwb2ludHMpIHtcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwID0gcG9pbnRzW2ldO1xuICAgICAgICB2YXIgZmxhZyA9IGkgPT09IDAgPyAnTScgOiAnTCc7XG4gICAgICAgIHBhdGgucHVzaChbZmxhZywgcC54LCBwLnldKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGg7XG59XG5mdW5jdGlvbiBwYXJzZUdyYWRpZW50KGNvbG9yKSB7XG4gICAgcmV0dXJuIFwibCg5MCkgMDpcIiArIGNvbG9yICsgXCIgMTojZmZmZmZmXCI7XG59XG52YXIgTWluaUFyZWFQYXJzZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTWluaUFyZWFQYXJzZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTWluaUFyZWFQYXJzZXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTWluaUFyZWFQYXJzZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLnBhcnNlU2hhcGUoKTtcbiAgICB9O1xuICAgIE1pbmlBcmVhUGFyc2VyLnByb3RvdHlwZS5wYXJzZVNoYXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLnNtb290aCkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuc2hhcGUgPSB7IHZhbHVlczogWydtaW5pQXJlYVNtb290aCddIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5zaGFwZSA9IHsgdmFsdWVzOiBbJ21pbmlBcmVhJ10gfTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIE1pbmlBcmVhUGFyc2VyO1xufShtYWluXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTWluaUFyZWFQYXJzZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW5pLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIEVsZW1lbnRQYXJzZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRWxlbWVudFBhcnNlcihjZmcpIHtcbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLCBjZmcpO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgRWxlbWVudFBhcnNlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogdGhpcy5wb3NpdGlvbkZpZWxkcyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gRWxlbWVudFBhcnNlcjtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBFbGVtZW50UGFyc2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0R2VvbSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGluZGV4XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9hcmVhL2luZGV4XCIpKTtcbnZhciBpbmRleF8yID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vaW50ZXJ2YWwvaW5kZXhcIikpO1xudmFyIGluZGV4XzMgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9saW5lL2luZGV4XCIpKTtcbnZhciBpbmRleF80ID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcG9pbnQvaW5kZXhcIikpO1xuLyoqXG4gKiDlsIZlbGVtZW5055qE6YWN572u6YC76L6R5ouG56a75Ye65p2l77yM5bm25bCG5q+P57G7ZWxlbWVudOe7huWIhuS4uuS4u+S9k+WbvuW9ouOAgei+heWKqeWbvuW9ouOAgW1pbmnlm77lvaLkuInnp41cbiAqIOi/meagt+S5n+aWueS+v+acquadpeabtOeBtea0u+eahOiwg+eUqOWSjOe7hOijhWcy55qEZWxlbWVudOaooeWdl1xuICovXG52YXIgR0VPTUVUUllfTUFQID0ge1xuICAgIGFyZWE6IGluZGV4XzEuZGVmYXVsdCxcbiAgICBsaW5lOiBpbmRleF8zLmRlZmF1bHQsXG4gICAgcG9pbnQ6IGluZGV4XzQuZGVmYXVsdCxcbiAgICBpbnRlcnZhbDogaW5kZXhfMi5kZWZhdWx0LFxufTtcbmZ1bmN0aW9uIGdldEdlb20obmFtZSwgdHlwZSwgY2ZnKSB7XG4gICAgdmFyIEdlb20gPSBHRU9NRVRSWV9NQVBbbmFtZV1bdHlwZV07XG4gICAgcmV0dXJuIG5ldyBHZW9tKGNmZykuY29uZmlnO1xufVxuZXhwb3J0cy5nZXRHZW9tID0gZ2V0R2VvbTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZhY3RvcnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vLi4vZGVwZW5kZW50c1wiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb2xvclV0aWwgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi4vLi4vdXRpbC9jb2xvclwiKSk7XG52YXIgR0FVU1NfQ09FRiA9IDAuMzk4OTQyMjgwNDAxNDMyNztcbnZhciBaRVJPID0gMS4wIC8gMjU1LjAgLyAxNi4wO1xudmFyIE9SSUdJTl9GSUVMRCA9ICdfb3JpZ2luJztcbnZhciBMaW5lYXJIZWF0bWFwID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmVhckhlYXRtYXAsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZWFySGVhdG1hcChjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2hlYXRtYXAnO1xuICAgICAgICBfdGhpcy5wYWxldHRlQ2FjaGUgPSB7fTtcbiAgICAgICAgX3RoaXMuaW50ZW5zaXR5ID0gY2ZnLmludGVuc2l0eTtcbiAgICAgICAgX3RoaXMucmFkaXVzID0gY2ZnLnJhZGl1cztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBMaW5lYXJIZWF0bWFwLnByb3RvdHlwZS5jcmVhdGVFbGVtZW50cyA9IGZ1bmN0aW9uIChtYXBwaW5nRGF0YSAvKmluZGV4OiBudW1iZXIsIGlzVXBkYXRlOiBib29sZWFuID0gZmFsc2UqLykge1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLnByZXBhcmVSYW5nZShtYXBwaW5nRGF0YSk7XG4gICAgICAgIHRoaXMucHJlcGFyZVNpemUoKTtcbiAgICAgICAgdGhpcy5wcmVwYXJlQmx1cigpO1xuICAgICAgICB0aGlzLnByZXBhcmVHcmV5U2NhbGVCbHVycmVkQ2lyY2xlKHRoaXMucmFkaXVzKTtcbiAgICAgICAgdGhpcy5kcmF3V2l0aFJhbmdlKG1hcHBpbmdEYXRhLCByYW5nZSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXJTaGFkb3dDYW52YXNDdHgoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jbGVhci5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUucHJlcGFyZVJhbmdlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIGNvbG9yQXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCdjb2xvcicpO1xuICAgICAgICB2YXIgY29sb3JGaWVsZCA9IGNvbG9yQXR0ci5nZXRGaWVsZHMoKVswXTtcbiAgICAgICAgdmFyIG1pbiA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4ID0gLUluZmluaXR5O1xuICAgICAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKHJvdykge1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gcm93W09SSUdJTl9GSUVMRF1bY29sb3JGaWVsZF07XG4gICAgICAgICAgICBpZiAodmFsdWUgPiBtYXgpIHtcbiAgICAgICAgICAgICAgICBtYXggPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh2YWx1ZSA8IG1pbikge1xuICAgICAgICAgICAgICAgIG1pbiA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG1pbiA9PT0gbWF4KSB7XG4gICAgICAgICAgICBtaW4gPSBtYXggLSAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbbWluLCBtYXhdO1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUucHJlcGFyZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByYWRpdXMgPSB0aGlzLnJhZGl1cztcbiAgICAgICAgaWYgKCF0aGlzLnJhZGl1cykge1xuICAgICAgICAgICAgcmFkaXVzID0gdGhpcy5nZXREZWZhdWx0VmFsdWUoJ3NpemUnKTtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmlzTnVtYmVyKHJhZGl1cykpIHtcbiAgICAgICAgICAgICAgICByYWRpdXMgPSB0aGlzLmdldERlZmF1bHRTaXplKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJhZGl1cyA9IHJhZGl1cztcbiAgICAgICAgfVxuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUucHJlcGFyZUJsdXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBibHVyID0gdXRpbF8xLmdldCh0aGlzLnN0eWxlT3B0aW9uLCBbJ3N0eWxlJywgJ3NoYWRvd0JsdXInXSk7XG4gICAgICAgIGlmICghdXRpbF8xLmlzTnVtYmVyKGJsdXIpKSB7XG4gICAgICAgICAgICBibHVyID0gdGhpcy5yYWRpdXMgLyAyO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYmx1ciA9IGJsdXI7XG4gICAgfTtcbiAgICBMaW5lYXJIZWF0bWFwLnByb3RvdHlwZS5nZXREZWZhdWx0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3Bvc2l0aW9uJyk7XG4gICAgICAgIHZhciBjb29yZCA9IHRoaXMuY29vcmRpbmF0ZTtcbiAgICAgICAgdmFyIHJhZGl1cyA9IE1hdGgubWluKGNvb3JkLmdldFdpZHRoKCkgLyAocG9zaXRpb24uc2NhbGVzWzBdLnRpY2tzLmxlbmd0aCAqIDQpLCBjb29yZC5nZXRIZWlnaHQoKSAvIChwb3NpdGlvbi5zY2FsZXNbMV0udGlja3MubGVuZ3RoICogNCkpO1xuICAgICAgICByZXR1cm4gcmFkaXVzO1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUuY29sb3JpemUgPSBmdW5jdGlvbiAoaW1nKSB7XG4gICAgICAgIHZhciBjb2xvckF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnY29sb3InKTtcbiAgICAgICAgdmFyIHBpeGVscyA9IGltZy5kYXRhO1xuICAgICAgICB2YXIgcGFsZXR0ZUNhY2hlID0gdGhpcy5wYWxldHRlQ2FjaGU7XG4gICAgICAgIGZvciAodmFyIGkgPSAzOyBpIDwgcGl4ZWxzLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICAgICAgICB2YXIgYWxwaGEgPSBwaXhlbHNbaV07IC8vIGdldCBncmFkaWVudCBjb2xvciBmcm9tIG9wYWNpdHkgdmFsdWVcbiAgICAgICAgICAgIGlmIChhbHBoYSkge1xuICAgICAgICAgICAgICAgIHZhciBwYWxldHRlID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgIGlmIChwYWxldHRlQ2FjaGVbYWxwaGFdKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBwYWxldHRlQ2FjaGVbYWxwaGFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGNvbG9yVXRpbC5yZ2IyYXJyKGNvbG9yQXR0ci5ncmFkaWVudChhbHBoYSAvIDI1NikpO1xuICAgICAgICAgICAgICAgICAgICBwYWxldHRlQ2FjaGVbYWxwaGFdID0gcGFsZXR0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gY29uc3QgcGFsZXR0ZSA9IGNvbG9yVXRpbC5yZ2IyYXJyKGNvbG9yQXR0ci5ncmFkaWVudChhbHBoYSAvIDI1NikpO1xuICAgICAgICAgICAgICAgIHBpeGVsc1tpIC0gM10gPSBwYWxldHRlWzBdO1xuICAgICAgICAgICAgICAgIHBpeGVsc1tpIC0gMl0gPSBwYWxldHRlWzFdO1xuICAgICAgICAgICAgICAgIHBpeGVsc1tpIC0gMV0gPSBwYWxldHRlWzJdO1xuICAgICAgICAgICAgICAgIHBpeGVsc1tpXSA9IGFscGhhO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBMaW5lYXJIZWF0bWFwLnByb3RvdHlwZS5wcmVwYXJlR3JleVNjYWxlQmx1cnJlZENpcmNsZSA9IGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIHZhciBjaXJjbGVDYW52YXMgPSB0aGlzLmdyYXlTY2FsZUNhbnZhcztcbiAgICAgICAgaWYgKCFjaXJjbGVDYW52YXMpIHtcbiAgICAgICAgICAgIGNpcmNsZUNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICAgICAgdGhpcy5ncmF5U2NhbGVDYW52YXMgPSBjaXJjbGVDYW52YXM7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGludGVuc2l0eSA9IHRoaXMuaW50ZW5zaXR5ID8gdGhpcy5pbnRlbnNpdHkgOiAyO1xuICAgICAgICB2YXIgY2lyY2xlUmFkaXVzID0gKE1hdGguc3FydCgtMi4wICogTWF0aC5sb2coWkVSTyAvIHIgLyBpbnRlbnNpdHkgLyBHQVVTU19DT0VGKSkgLyAzLjApICogcjtcbiAgICAgICAgdmFyIGJsdXIgPSBjaXJjbGVSYWRpdXMgLSByO1xuICAgICAgICB2YXIgcjIgPSBjaXJjbGVSYWRpdXMgKyBibHVyO1xuICAgICAgICB2YXIgY3R4ID0gY2lyY2xlQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGNpcmNsZUNhbnZhcy53aWR0aCA9IGNpcmNsZUNhbnZhcy5oZWlnaHQgPSByMiAqIDI7XG4gICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgY2lyY2xlQ2FudmFzLndpZHRoLCBjaXJjbGVDYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjdHguc2hhZG93T2Zmc2V0WSA9IHIyICogMjtcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBibHVyO1xuICAgICAgICBjdHguc2hhZG93Q29sb3IgPSAnYmxhY2snO1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5hcmMoLXIyLCAtcjIsIHIsIDAsIE1hdGguUEkgKiAyLCB0cnVlKTtcbiAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICBjdHguZmlsbCgpO1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUuZHJhd0dyYXlTY2FsZUJsdXJyZWRDaXJjbGUgPSBmdW5jdGlvbiAoeCwgeSwgciwgYWxwaGEsIGN0eCkge1xuICAgICAgICB2YXIgY2lyY2xlQ2FudmFzID0gdGhpcy5ncmF5U2NhbGVDYW52YXM7XG4gICAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IGFscGhhO1xuICAgICAgICBjdHguZHJhd0ltYWdlKGNpcmNsZUNhbnZhcywgeCAtIHIsIHkgLSByKTtcbiAgICB9O1xuICAgIExpbmVhckhlYXRtYXAucHJvdG90eXBlLmdldFNoYWRvd0NhbnZhc0N0eCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IHRoaXMuc2hhZG93Q2FudmFzO1xuICAgICAgICBpZiAoIWNhbnZhcykge1xuICAgICAgICAgICAgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgICAgICB0aGlzLnNoYWRvd0NhbnZhcyA9IGNhbnZhcztcbiAgICAgICAgfVxuICAgICAgICBjYW52YXMud2lkdGggPSB0aGlzLmNvb3JkaW5hdGUuZ2V0V2lkdGgoKTtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IHRoaXMuY29vcmRpbmF0ZS5nZXRIZWlnaHQoKTtcbiAgICAgICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY29udGV4dC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnbGlnaHRlcic7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUuY2xlYXJTaGFkb3dDYW52YXNDdHggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjdHggPSB0aGlzLmdldFNoYWRvd0NhbnZhc0N0eCgpO1xuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGN0eC5jYW52YXMud2lkdGgsIGN0eC5jYW52YXMuaGVpZ2h0KTtcbiAgICB9O1xuICAgIExpbmVhckhlYXRtYXAucHJvdG90eXBlLmdldEltYWdlU2hhcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbWFnZVNoYXBlID0gdGhpcy5pbWFnZVNoYXBlO1xuICAgICAgICBpZiAoaW1hZ2VTaGFwZSkge1xuICAgICAgICAgICAgcmV0dXJuIGltYWdlU2hhcGU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICBpbWFnZVNoYXBlID0gY29udGFpbmVyLmFkZFNoYXBlKHtcbiAgICAgICAgICAgIHR5cGU6ICdpbWFnZScsXG4gICAgICAgICAgICBhdHRyczoge30sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmltYWdlU2hhcGUgPSBpbWFnZVNoYXBlO1xuICAgIH07XG4gICAgTGluZWFySGVhdG1hcC5wcm90b3R5cGUuZHJhd1dpdGhSYW5nZSA9IGZ1bmN0aW9uIChkYXRhLCByYW5nZSkge1xuICAgICAgICAvLyBjYW52YXMgc2l6ZVxuICAgICAgICB2YXIgX2EgPSB0aGlzLmNvb3JkaW5hdGUsIHN0YXJ0ID0gX2Euc3RhcnQsIGVuZCA9IF9hLmVuZDtcbiAgICAgICAgdmFyIHdpZHRoID0gdGhpcy5jb29yZGluYXRlLmdldFdpZHRoKCk7XG4gICAgICAgIHZhciBoZWlnaHQgPSB0aGlzLmNvb3JkaW5hdGUuZ2V0SGVpZ2h0KCk7XG4gICAgICAgIC8vIHZhbHVlLCByYW5nZSwgZXRjXG4gICAgICAgIHZhciBjb2xvckF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnY29sb3InKTtcbiAgICAgICAgdmFyIHZhbHVlRmllbGQgPSBjb2xvckF0dHIuZ2V0RmllbGRzKClbMF07XG4gICAgICAgIC8vIHByZXBhcmUgc2hhZG93IGNhbnZhcyBjb250ZXh0XG4gICAgICAgIHRoaXMuY2xlYXJTaGFkb3dDYW52YXNDdHgoKTtcbiAgICAgICAgdmFyIGN0eCA9IHRoaXMuZ2V0U2hhZG93Q2FudmFzQ3R4KCk7XG4gICAgICAgIC8vIGZpbHRlciBkYXRhXG4gICAgICAgIGlmIChyYW5nZSkge1xuICAgICAgICAgICAgZGF0YSA9IGRhdGEuZmlsdGVyKGZ1bmN0aW9uIChyb3cpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcm93W09SSUdJTl9GSUVMRF1bdmFsdWVGaWVsZF0gPD0gcmFuZ2VbMV0gJiYgcm93W09SSUdJTl9GSUVMRF1bdmFsdWVGaWVsZF0gPj0gcmFuZ2VbMF07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzdGVwMS4gZHJhdyBwb2ludHMgd2l0aCBzaGFkb3dcbiAgICAgICAgdmFyIHNjYWxlID0gdGhpcy5zY2FsZXNbdmFsdWVGaWVsZF07XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIG9iaiA9IGRhdGFbaV07XG4gICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5nZXREcmF3Q2ZnKG9iaik7XG4gICAgICAgICAgICB2YXIgYWxwaGEgPSBzY2FsZS5zY2FsZShvYmpbT1JJR0lOX0ZJRUxEXVt2YWx1ZUZpZWxkXSk7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB0aGlzLmRyYXdHcmF5U2NhbGVCbHVycmVkQ2lyY2xlKGNmZy54IC0gc3RhcnQueCwgY2ZnLnkgLSBlbmQueSwgdGhpcy5yYWRpdXMgKyB0aGlzLmJsdXIsIGFscGhhLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHN0ZXAyLiBjb252ZXJ0IHBpeGVsc1xuICAgICAgICB2YXIgY29sb3JlZCA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHRoaXMuY2xlYXJTaGFkb3dDYW52YXNDdHgoKTtcbiAgICAgICAgdGhpcy5jb2xvcml6ZShjb2xvcmVkKTtcbiAgICAgICAgY3R4LnB1dEltYWdlRGF0YShjb2xvcmVkLCAwLCAwKTtcbiAgICAgICAgdmFyIGltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICAgIGltYWdlLnNyYyA9IGN0eC5jYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcbiAgICAgICAgdGhpcy5nZXRJbWFnZVNoYXBlKCk7XG4gICAgICAgIHRoaXMuaW1hZ2VTaGFwZS5hdHRyKCd4Jywgc3RhcnQueCk7XG4gICAgICAgIHRoaXMuaW1hZ2VTaGFwZS5hdHRyKCd5JywgZW5kLnkpO1xuICAgICAgICB0aGlzLmltYWdlU2hhcGUuYXR0cignd2lkdGgnLCB3aWR0aCk7XG4gICAgICAgIHRoaXMuaW1hZ2VTaGFwZS5hdHRyKCdoZWlnaHQnLCBoZWlnaHQpO1xuICAgICAgICB0aGlzLmltYWdlU2hhcGUuYXR0cignaW1nJywgY3R4LmNhbnZhcyk7XG4gICAgICAgIHRoaXMuaW1hZ2VTaGFwZS5zZXQoJ29yaWdpbicsIHRoaXMuZ2V0U2hhcGVJbmZvKGRhdGEpKTsgLy8g5a2Y5YKo57uY5Zu+5L+h5oGv5pWw5o2uXG4gICAgfTtcbiAgICBMaW5lYXJIZWF0bWFwLnByb3RvdHlwZS5nZXRTaGFwZUluZm8gPSBmdW5jdGlvbiAobWFwcGluZ0RhdGEpIHtcbiAgICAgICAgdmFyIHNoYXBlQ2ZnID0gdGhpcy5nZXREcmF3Q2ZnKG1hcHBpbmdEYXRhWzBdKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc2hhcGVDZmcpLCB7IG1hcHBpbmdEYXRhOiBtYXBwaW5nRGF0YSwgZGF0YTogdGhpcy5nZXREYXRhKG1hcHBpbmdEYXRhKSB9KTtcbiAgICB9O1xuICAgIExpbmVhckhlYXRtYXAucHJvdG90eXBlLmdldERhdGEgPSBmdW5jdGlvbiAobWFwcGluZ0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIG1hcHBpbmdEYXRhLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqW09SSUdJTl9GSUVMRF07XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIExpbmVhckhlYXRtYXA7XG59KGRlcGVuZGVudHNfMS5HZW9tZXRyeSkpO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyR2VvbWV0cnkoJ2xpbmVhckhlYXRtYXAnLCBMaW5lYXJIZWF0bWFwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmVhci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIG1haW5fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL21haW5cIikpO1xuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICAgIG1haW46IG1haW5fMS5kZWZhdWx0LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2Jhc2VcIikpO1xudmFyIENPTE9SX01BUFBFUiA9IFsnY29sb3JGaWVsZCcsICdzdGFja0ZpZWxkJywgJ2dyb3VwRmllbGQnXTtcbnZhciBJbnRlcnZhbFBhcnNlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhJbnRlcnZhbFBhcnNlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBJbnRlcnZhbFBhcnNlcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBJbnRlcnZhbFBhcnNlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2ludGVydmFsJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0LmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICBpZiAodGhpcy5fbmVlZFBhcnNlckNvbG9yKCkpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VDb2xvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5jb25maWcuY29sb3IpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmNvbG9yID0geyB2YWx1ZXM6IFsnIzViOGZmOSddIH07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNpemVQcm9wcyA9IHRoaXMuX2dldFNpemVQcm9wcyhwcm9wcyk7XG4gICAgICAgIGlmIChzaXplUHJvcHMpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VTaXplKHNpemVQcm9wcyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHN0eWxlUHJvcHMgPSB0aGlzLl9nZXRTdHlsZVByb3BzKHByb3BzKTtcbiAgICAgICAgaWYgKHN0eWxlUHJvcHMpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VTdHlsZShzdHlsZVByb3BzKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgSW50ZXJ2YWxQYXJzZXIucHJvdG90eXBlLnBhcnNlQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29sb3JGaWVsZCA9IHRoaXMuX2dldENvbG9yTWFwcGluZ0ZpZWxkKHByb3BzKTtcbiAgICAgICAgdmFyIGNvbmZpZyA9IHt9O1xuICAgICAgICBpZiAoY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IGNvbG9yRmllbGQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLmNvbG9yKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHByb3BzLmNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbcHJvcHMuY29sb3JdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzRnVuY3Rpb24ocHJvcHMuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gcHJvcHMuY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNBcnJheShwcm9wcy5jb2xvcikpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcudmFsdWVzID0gcHJvcHMuY29sb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcHMuY29sb3IubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLnZhbHVlcyA9IFtwcm9wcy5jb2xvclswXV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNPYmplY3QocHJvcHMuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IGNvbG9yRmllbGQ7XG4gICAgICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb3BzLmNvbG9yW2RdO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuY29sb3IgPSBjb25maWc7XG4gICAgfTtcbiAgICBJbnRlcnZhbFBhcnNlci5wcm90b3R5cGUucGFyc2VTaXplID0gZnVuY3Rpb24gKHNpemVQcm9wcykge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIGNvbmZpZyA9IHt9O1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24ocHJvcHNbc2l6ZVByb3BzXSkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5maWVsZHMgPSBbdGhpcy5jb25maWcucG9zaXRpb24uZmllbGRzXTtcbiAgICAgICAgICAgIGNvbmZpZy5jYWxsYmFjayA9IHByb3BzW3NpemVQcm9wc107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWcudmFsdWVzID0gW3Byb3BzW3NpemVQcm9wc11dO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnLnNpemUgPSBjb25maWc7XG4gICAgfTtcbiAgICBJbnRlcnZhbFBhcnNlci5wcm90b3R5cGUucGFyc2VTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZVByb3BzKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29sb3IgPSB0aGlzLmNvbmZpZy5jb2xvcjtcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5wbG90Lm9wdGlvbnNbc3R5bGVQcm9wc107XG4gICAgICAgIHZhciBjb25maWcgPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHN0eWxlKSkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IChjb2xvciA9PT0gbnVsbCB8fCBjb2xvciA9PT0gdm9pZCAwID8gdm9pZCAwIDogY29sb3IuZmllbGRzKSB8fCBbcHJvcHMueEZpZWxkLCBwcm9wcy55RmllbGRdO1xuICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gc3R5bGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWcuY2ZnID0gc3R5bGU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuc3R5bGUgPSBjb25maWc7XG4gICAgfTtcbiAgICBJbnRlcnZhbFBhcnNlci5wcm90b3R5cGUuX2dldFNpemVQcm9wcyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgc2l6ZU1hcHBlciA9IFsnY29sdW1uU2l6ZScsICdiYXJTaXplJ107XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgc2l6ZU1hcHBlcl8xID0gc2l6ZU1hcHBlcjsgX2kgPCBzaXplTWFwcGVyXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgbSA9IHNpemVNYXBwZXJfMVtfaV07XG4gICAgICAgICAgICBpZiAodXRpbF8xLmdldChwcm9wcywgbSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgSW50ZXJ2YWxQYXJzZXIucHJvdG90eXBlLl9nZXRTdHlsZVByb3BzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBzaXplTWFwcGVyID0gWydjb2x1bW5TdHlsZScsICdiYXJTdHlsZScsICdwaWVTdHlsZScsICdyaW5nU3R5bGUnXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBzaXplTWFwcGVyXzIgPSBzaXplTWFwcGVyOyBfaSA8IHNpemVNYXBwZXJfMi5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBtID0gc2l6ZU1hcHBlcl8yW19pXTtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuZ2V0KHByb3BzLCBtKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBJbnRlcnZhbFBhcnNlci5wcm90b3R5cGUuX2dldENvbG9yTWFwcGluZ0ZpZWxkID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIC8qKuWmguaenOaciWNvbG9yRmlsZWTmiJZzdGFja0ZpZWxk6YWN572u6aG5KOWQjuiAheS4uuWghuWPoGludGVydmFsKe+8jOWImeWPguS4jmNvbG9yTWFwcGluZ+eahOWtl+auteS4uuWvueW6lOWAvFxuICAgICAgICAgKiDlpoLmsqHmnInnibnliKvorr7lrprvvIzliJnkuIDoiKzmmK9jYWxsYmFja+S4reeahOS8oOWPgu+8jOS8oOWFpeS9jee9ruaYoOWwhOeahOWtl+autVxuICAgICAgICAgKi9cbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBDT0xPUl9NQVBQRVJfMSA9IENPTE9SX01BUFBFUjsgX2kgPCBDT0xPUl9NQVBQRVJfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBtID0gQ09MT1JfTUFQUEVSXzFbX2ldO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5nZXQocHJvcHMsIG0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtwcm9wc1ttXV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEludGVydmFsUGFyc2VyLnByb3RvdHlwZS5fbmVlZFBhcnNlckNvbG9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmNvbG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIENPTE9SX01BUFBFUl8yID0gQ09MT1JfTUFQUEVSOyBfaSA8IENPTE9SX01BUFBFUl8yLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIG0gPSBDT0xPUl9NQVBQRVJfMltfaV07XG4gICAgICAgICAgICBpZiAocHJvcHNbbV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICByZXR1cm4gSW50ZXJ2YWxQYXJzZXI7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBJbnRlcnZhbFBhcnNlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1haW4uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBtYWluXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9tYWluXCIpKTtcbnZhciBHdWlkZUxpbmVQYXJzZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR3VpZGVMaW5lUGFyc2VyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEd1aWRlTGluZVBhcnNlcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBHdWlkZUxpbmVQYXJzZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICBpZiAoIXByb3BzLnhGaWVsZCB8fCAhcHJvcHMueUZpZWxkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW3Byb3BzLnhGaWVsZCwgcHJvcHMueUZpZWxkXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMuX2dldENvbG9yTWFwcGluZ0ZpZWxkKCkgfHwgdGhpcy5fbmVlZFBhcnNlQXR0cmlidXRlKCdjb2xvcicpKSB7XG4gICAgICAgICAgICB0aGlzLnBhcnNlQ29sb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fbmVlZFBhcnNlQXR0cmlidXRlKCdzaXplJykpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VTaXplKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLmxpbmUuc3R5bGUpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VTdHlsZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy5zbW9vdGgpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnNoYXBlID0geyB2YWx1ZXM6IFsnc21vb3RoJ10gfTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgR3VpZGVMaW5lUGFyc2VyLnByb3RvdHlwZS5wYXJzZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIGlmIChwcm9wcy5saW5lLnNpemUpIHtcbiAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbcHJvcHMubGluZS5zaXplXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGxpbmXkvZzkuLrovoXliqnlm77lvaLmsqHmnInlnKhzdHlsZemHjOaMh+WumnNpemXlsZ7mgKfnmoTmg4XlhrXkuIvvvIzorr7nva7pu5jorqTlgLxcbiAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbMl07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuc2l6ZSA9IGNvbmZpZztcbiAgICB9O1xuICAgIEd1aWRlTGluZVBhcnNlci5wcm90b3R5cGUucGFyc2VDb2xvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHZhciBjb25maWcgPSB7fTtcbiAgICAgICAgdmFyIGNvbG9yRmllbGQgPSB0aGlzLl9nZXRDb2xvck1hcHBpbmdGaWVsZCgpO1xuICAgICAgICBpZiAoY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IGNvbG9yRmllbGQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLmxpbmUuY29sb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbcHJvcHMubGluZS5jb2xvcl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBsaW5l5L2c5Li66L6F5Yqp5Zu+5b2i5rKh5pyJ5Zyoc3R5bGXph4zmjIflrppjb2xvcuWxnuaAp+eahOaDheWGteS4i++8jOm7mOiupOaOpeWPl+S4u+S9k+WbvuW9oueahOmAj+S8oFxuICAgICAgICAgICAgaWYgKHV0aWxfMS5pc1N0cmluZyhwcm9wcy5jb2xvcikpIHtcbiAgICAgICAgICAgICAgICBjb25maWcudmFsdWVzID0gW3Byb3BzLmNvbG9yXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHByb3BzLmNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5maWVsZHMgPSBjb2xvckZpZWxkO1xuICAgICAgICAgICAgICAgIGNvbmZpZy5jYWxsYmFjayA9IHByb3BzLmNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzQXJyYXkocHJvcHMuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbG9yRmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLnZhbHVlcyA9IHByb3BzLmNvbG9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BzLmNvbG9yLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbcHJvcHMuY29sb3JbMF1dO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnLmNvbG9yID0gY29uZmlnO1xuICAgIH07XG4gICAgR3VpZGVMaW5lUGFyc2VyLnByb3RvdHlwZS5wYXJzZVN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIHN0eWxlUHJvcHMgPSBwcm9wcy5saW5lLnN0eWxlO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzdHlsZVByb3BzKSkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IHRoaXMuY29uZmlnLnBvc2l0aW9uLmZpZWxkcztcbiAgICAgICAgICAgIGNvbmZpZy5jYWxsYmFjayA9IHN0eWxlUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWcuY2ZnID0gc3R5bGVQcm9wcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbmZpZy5zdHlsZSA9IGNvbmZpZztcbiAgICB9O1xuICAgIEd1aWRlTGluZVBhcnNlci5wcm90b3R5cGUuX25lZWRQYXJzZUF0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICBpZiAocHJvcHNbYXR0cl0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHByb3BzLmxpbmVbYXR0cl0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEd1aWRlTGluZVBhcnNlci5wcm90b3R5cGUuX2dldENvbG9yTWFwcGluZ0ZpZWxkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIGNvbG9yTWFwcGVyID0gWydzdGFja0ZpZWxkJywgJ3Nlcmllc0ZpZWxkJ107XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgY29sb3JNYXBwZXJfMSA9IGNvbG9yTWFwcGVyOyBfaSA8IGNvbG9yTWFwcGVyXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgbSA9IGNvbG9yTWFwcGVyXzFbX2ldO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5nZXQocHJvcHMsIG0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtwcm9wc1ttXV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBHdWlkZUxpbmVQYXJzZXI7XG59KG1haW5fMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBHdWlkZUxpbmVQYXJzZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ndWlkZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGd1aWRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9ndWlkZVwiKSk7XG52YXIgbWFpbl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbWFpblwiKSk7XG52YXIgbWluaV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbWluaVwiKSk7XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgbWFpbjogbWFpbl8xLmRlZmF1bHQsXG4gICAgZ3VpZGU6IGd1aWRlXzEuZGVmYXVsdCxcbiAgICBtaW5pOiBtaW5pXzEuZGVmYXVsdCxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciBMaW5lUGFyc2VyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmVQYXJzZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZVBhcnNlcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBMaW5lUGFyc2VyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW3Byb3BzLnhGaWVsZCwgcHJvcHMueUZpZWxkXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25uZWN0TnVsbHM6IHByb3BzLmNvbm5lY3ROdWxscyxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHByb3BzLmxpbmVTaXplKSB7XG4gICAgICAgICAgICB0aGlzLnBhcnNlU2l6ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy5zbW9vdGgpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnNoYXBlID0geyB2YWx1ZXM6IFsnc21vb3RoJ10gfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMuc3RlcCkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuc2hhcGUgPSB7IHZhbHVlczogW3Byb3BzLnN0ZXBdIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLnNlcmllc0ZpZWxkIHx8IHByb3BzLmNvbG9yKSB7XG4gICAgICAgICAgICB0aGlzLnBhcnNlQ29sb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMubGluZVN0eWxlIHx8IHV0aWxfMS5nZXQocHJvcHMsIFsnbGluZScsICdzdHlsZSddKSkge1xuICAgICAgICAgICAgdGhpcy5wYXJzZVN0eWxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExpbmVQYXJzZXIucHJvdG90eXBlLnBhcnNlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNpemVQcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zLmxpbmVTaXplO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzaXplUHJvcHMpKSB7XG4gICAgICAgICAgICBjb25maWcuY2FsbGJhY2sgPSBzaXplUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWcudmFsdWVzID0gW3NpemVQcm9wc107XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuc2l6ZSA9IGNvbmZpZztcbiAgICB9O1xuICAgIExpbmVQYXJzZXIucHJvdG90eXBlLnBhcnNlQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIGlmIChwcm9wcy5zZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IFtwcm9wcy5zZXJpZXNGaWVsZF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICdjb2xvcicpKSB7XG4gICAgICAgICAgICB2YXIgY29sb3IgPSBwcm9wcy5jb2xvcjtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcoY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLnZhbHVlcyA9IFtjb2xvcl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNGdW5jdGlvbihjb2xvcikpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuY2FsbGJhY2sgPSBjb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc0FycmF5KGNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wcy5zZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcudmFsdWVzID0gY29sb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29sb3IubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLnZhbHVlcyA9IFtjb2xvclswXV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuY29sb3IgPSBjb25maWc7XG4gICAgfTtcbiAgICBMaW5lUGFyc2VyLnByb3RvdHlwZS5wYXJzZVN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIHN0eWxlUHJvcHMgPSBwcm9wcy5saW5lU3R5bGUgfHwgdXRpbF8xLmdldChwcm9wcywgWydsaW5lJywgJ3N0eWxlJ10pO1xuICAgICAgICB2YXIgY29uZmlnID0ge1xuICAgICAgICAgICAgZmllbGRzOiBudWxsLFxuICAgICAgICAgICAgY2FsbGJhY2s6IG51bGwsXG4gICAgICAgICAgICBjZmc6IG51bGwsXG4gICAgICAgIH07XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzdHlsZVByb3BzKSAmJiBwcm9wcy5zZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IFtwcm9wcy5zZXJpZXNGaWVsZF07XG4gICAgICAgICAgICBjb25maWcuY2FsbGJhY2sgPSBzdHlsZVByb3BzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLmNmZyA9IHN0eWxlUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuc3R5bGUgPSBjb25maWc7XG4gICAgfTtcbiAgICByZXR1cm4gTGluZVBhcnNlcjtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmVQYXJzZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYWluLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKiog566A5YyW5oqY57q/54K5ICovXG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbWF0aF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvbWF0aFwiKTtcbnZhciBwYXRoXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9wYXRoXCIpO1xudmFyIG1haW5fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL21haW5cIikpO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vLi4vdGhlbWVcIik7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJTaGFwZSgnbGluZScsICdtaW5pTGluZScsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IG1hdGhfMS5saW5lU2ltcGxpZmljYXRpb24oY2ZnLnBvaW50cyk7XG4gICAgICAgIHZhciBwYXRoID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIHZhciBmbGFnID0gaSA9PT0gMCA/ICdNJyA6ICdMJztcbiAgICAgICAgICAgIHBhdGgucHVzaChbZmxhZywgcC54LCBwLnldKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3R5bGUgPSB1dGlsXzEuZGVlcE1peCh7fSwge1xuICAgICAgICAgICAgbGluZUpvaW46ICdyb3VuZCcsXG4gICAgICAgICAgICBsaW5lQ2FwOiAncm91bmQnLFxuICAgICAgICB9LCBjZmcuc3R5bGUpO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdXRpbF8xLm1peCh7XG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICBzdHJva2U6IGNmZy5jb2xvciB8fCB0aGVtZV8xLmdldEdsb2JhbFRoZW1lKCkuZGVmYXVsdENvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogY2ZnLnNpemUgfHwgMixcbiAgICAgICAgICAgIH0sIHN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzaGFwZTtcbiAgICB9LFxufSk7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJTaGFwZSgnbGluZScsICdtaW5pTGluZVNtb290aCcsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IG1hdGhfMS5saW5lU2ltcGxpZmljYXRpb24oY2ZnLnBvaW50cyk7XG4gICAgICAgIHZhciBjb25zdHJhaW50ID0gW1xuICAgICAgICAgICAgWzAsIDBdLFxuICAgICAgICAgICAgWzEsIDFdLFxuICAgICAgICBdO1xuICAgICAgICB2YXIgcGF0aCA9IHBhdGhfMS5nZXRTcGxpbmVQYXRoKHBvaW50cywgZmFsc2UsIGNvbnN0cmFpbnQpO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdXRpbF8xLm1peCh7XG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICBzdHJva2U6IGNmZy5jb2xvciB8fCB0aGVtZV8xLmdldEdsb2JhbFRoZW1lKCkuZGVmYXVsdENvbG9yLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogY2ZnLnNpemUgfHwgMixcbiAgICAgICAgICAgIH0sIGNmZy5zdHlsZSksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgfSxcbn0pO1xudmFyIE1pbmlMaW5lUGFyc2VyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKE1pbmlMaW5lUGFyc2VyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIE1pbmlMaW5lUGFyc2VyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIE1pbmlMaW5lUGFyc2VyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5wYXJzZVNoYXBlKCk7XG4gICAgfTtcbiAgICBNaW5pTGluZVBhcnNlci5wcm90b3R5cGUucGFyc2VTaGFwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIGlmIChwcm9wcy5zbW9vdGgpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnNoYXBlID0geyB2YWx1ZXM6IFsnbWluaUxpbmVTbW9vdGgnXSB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuc2hhcGUgPSB7IHZhbHVlczogWydtaW5pTGluZSddIH07XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNaW5pTGluZVBhcnNlcjtcbn0obWFpbl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1pbmlMaW5lUGFyc2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlXCIpKTtcbnZhciBDaXJjbGVQYXJzZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2lyY2xlUGFyc2VyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENpcmNsZVBhcnNlcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBDaXJjbGVQYXJzZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB0aGlzLnN0eWxlID0gcHJvcHMucG9pbnRTdHlsZTtcbiAgICAgICAgaWYgKCFwcm9wcy54RmllbGQgfHwgIXByb3BzLnlGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgdHlwZTogJ3BvaW50JyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICAgICAgZmllbGRzOiBbcHJvcHMueEZpZWxkLCBwcm9wcy55RmllbGRdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wYXJzZUNvbG9yKCk7XG4gICAgICAgIHRoaXMucGFyc2VTaXplKCk7XG4gICAgICAgIGlmIChwcm9wcy5zaGFwZSkge1xuICAgICAgICAgICAgdGhpcy5wYXJzZVNoYXBlKHByb3BzLnNoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMucG9pbnRTdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5wYXJzZVN0eWxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENpcmNsZVBhcnNlci5wcm90b3R5cGUucGFyc2VDb2xvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHZhciBjb25maWcgPSB7fTtcbiAgICAgICAgdmFyIGNvbG9yRmllbGQgPSBwcm9wcy5jb2xvckZpZWxkO1xuICAgICAgICBpZiAoY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IHV0aWxfMS5pc0FycmF5KGNvbG9yRmllbGQpID8gY29sb3JGaWVsZCA6IFtjb2xvckZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMuY29sb3IpIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnNlQ29sb3IocHJvcHMsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF1dGlsXzEuaXNFbXB0eShjb25maWcpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5jb2xvciA9IGNvbmZpZztcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ2lyY2xlUGFyc2VyLnByb3RvdHlwZS5wYXJzZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIGlmIChwcm9wcy5zaXplRmllbGQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5maWVsZHMgPSBbcHJvcHMuc2l6ZUZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMucG9pbnRTaXplKSB7XG4gICAgICAgICAgICBjb25maWcudmFsdWVzID0gdXRpbF8xLmlzQXJyYXkocHJvcHMucG9pbnRTaXplKSA/IHByb3BzLnBvaW50U2l6ZSA6IFtwcm9wcy5wb2ludFNpemVdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnLnNpemUgPSBjb25maWc7XG4gICAgfTtcbiAgICBDaXJjbGVQYXJzZXIucHJvdG90eXBlLnBhcnNlU2hhcGUgPSBmdW5jdGlvbiAoc2hhcGVOYW1lKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLnNoYXBlID0gc2hhcGVOYW1lO1xuICAgIH07XG4gICAgQ2lyY2xlUGFyc2VyLnByb3RvdHlwZS5wYXJzZVN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIHN0eWxlUHJvcHMgPSBwcm9wcy5wb2ludFN0eWxlO1xuICAgICAgICB2YXIgY29uZmlnID0ge1xuICAgICAgICAgICAgZmllbGRzOiBudWxsLFxuICAgICAgICAgICAgY2FsbGJhY2s6IG51bGwsXG4gICAgICAgICAgICBjZmc6IG51bGwsXG4gICAgICAgIH07XG4gICAgICAgIHZhciB4RmllbGQgPSBwcm9wcy54RmllbGQsIHlGaWVsZCA9IHByb3BzLnlGaWVsZCwgY29sb3JGaWVsZCA9IHByb3BzLmNvbG9yRmllbGQ7XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzdHlsZVByb3BzKSkge1xuICAgICAgICAgICAgaWYgKGNvbG9yRmllbGQpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuZmllbGRzID0gdXRpbF8xLmlzQXJyYXkoY29sb3JGaWVsZClcbiAgICAgICAgICAgICAgICAgICAgPyBbeEZpZWxkLCB5RmllbGQsIGNvbG9yRmllbGRdLmNvbmNhdChjb2xvckZpZWxkKVxuICAgICAgICAgICAgICAgICAgICA6IFt4RmllbGQsIHlGaWVsZCwgY29sb3JGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25maWcuZmllbGRzID0gW3hGaWVsZCwgeUZpZWxkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZy5jYWxsYmFjayA9IHN0eWxlUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWcuY2ZnID0gc3R5bGVQcm9wcztcbiAgICAgICAgICAgIC8vIG9wYWNpdHkg5LiOIGZpbGxPcGFjaXR5IOWFvOWuuVxuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwoc3R5bGVQcm9wcy5vcGFjaXR5KSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5jZmcuZmlsbE9wYWNpdHkgPSBzdHlsZVByb3BzLm9wYWNpdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuc3R5bGUgPSBjb25maWc7XG4gICAgfTtcbiAgICBDaXJjbGVQYXJzZXIucHJvdG90eXBlLl9wYXJzZUNvbG9yID0gZnVuY3Rpb24gKHByb3BzLCBjb25maWcpIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc1N0cmluZyhwcm9wcy5jb2xvcikpIHtcbiAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbcHJvcHMuY29sb3JdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHByb3BzLmNvbG9yKSkge1xuICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gcHJvcHMuY29sb3I7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzQXJyYXkocHJvcHMuY29sb3IpKSB7XG4gICAgICAgICAgICBjb25maWcudmFsdWVzID0gcHJvcHMuY29sb3I7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBDaXJjbGVQYXJzZXI7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDaXJjbGVQYXJzZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaXJjbGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFzZVwiKSk7XG5mdW5jdGlvbiBnZXRWYWx1ZXNCeUZpZWxkKGZpZWxkLCBkYXRhKSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKGRhdGEsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2ID0gZFtmaWVsZF07XG4gICAgICAgIHZhbHVlcy5wdXNoKHYpO1xuICAgIH0pO1xuICAgIHJldHVybiB1dGlsXzEudW5pcSh2YWx1ZXMpO1xufVxudmFyIENPTE9SX01BUFBFUiA9IFsnc2VyaWVzRmllbGQnLCAnc3RhY2tGaWVsZCddO1xudmFyIEd1aWRlUG9pbnRQYXJzZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR3VpZGVQb2ludFBhcnNlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBHdWlkZVBvaW50UGFyc2VyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEd1aWRlUG9pbnRQYXJzZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB0aGlzLnN0eWxlID0gcHJvcHMucG9pbnQuc3R5bGU7XG4gICAgICAgIGlmICghcHJvcHMueEZpZWxkIHx8ICFwcm9wcy55RmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbmZpZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdwb2ludCcsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW3Byb3BzLnhGaWVsZCwgcHJvcHMueUZpZWxkXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gaWYgKHRoaXMuX25lZWRQYXJzZUF0dHJpYnV0ZSgnY29sb3InKSkge1xuICAgICAgICB0aGlzLnBhcnNlQ29sb3IoKTtcbiAgICAgICAgLy8gfVxuICAgICAgICBpZiAodGhpcy5fbmVlZFBhcnNlQXR0cmlidXRlKCdzaXplJykpIHtcbiAgICAgICAgICAgIHRoaXMucGFyc2VTaXplKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLnBvaW50LnNoYXBlKSB7XG4gICAgICAgICAgICB0aGlzLnBhcnNlU2hhcGUocHJvcHMucG9pbnQuc2hhcGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy5wb2ludC5zdHlsZSkge1xuICAgICAgICAgICAgdGhpcy5wYXJzZVN0eWxlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEd1aWRlUG9pbnRQYXJzZXIucHJvdG90eXBlLnBhcnNlQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIHZhciBtYXBwaW5nRmllbGQgPSB0aGlzLl9nZXRDb2xvck1hcHBpbmdGaWVsZChwcm9wcyk7XG4gICAgICAgIGlmIChtYXBwaW5nRmllbGQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnNlQ29sb3JCeUZpZWxkKHByb3BzLCBjb25maWcsIG1hcHBpbmdGaWVsZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAocHJvcHMucG9pbnQgJiYgcHJvcHMucG9pbnQuY29sb3IpIHtcbiAgICAgICAgICAgICAgICBjb25maWcudmFsdWVzID0gW3Byb3BzLnBvaW50LmNvbG9yXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHByb3BzLmNvbG9yKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyc2VDb2xvcihwcm9wcywgY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB0aGVtZSA9IHRoaXMucGxvdC5nZXRUaGVtZSgpO1xuICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbdGhlbWUuZGVmYXVsdENvbG9yXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmtleXMoY29uZmlnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5jb2xvciA9IGNvbmZpZztcbiAgICAgICAgfVxuICAgIH07XG4gICAgR3VpZGVQb2ludFBhcnNlci5wcm90b3R5cGUucGFyc2VTaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIGNvbmZpZyA9IHt9O1xuICAgICAgICBjb25maWcudmFsdWVzID0gW3Byb3BzLnBvaW50LnNpemVdO1xuICAgICAgICB0aGlzLmNvbmZpZy5zaXplID0gY29uZmlnO1xuICAgIH07XG4gICAgR3VpZGVQb2ludFBhcnNlci5wcm90b3R5cGUucGFyc2VTaGFwZSA9IGZ1bmN0aW9uIChzaGFwZUNmZykge1xuICAgICAgICB2YXIgY29uZmlnID0ge307XG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcoc2hhcGVDZmcpKSB7XG4gICAgICAgICAgICBjb25maWcudmFsdWVzID0gW3NoYXBlQ2ZnXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNPYmplY3Qoc2hhcGVDZmcpKSB7XG4gICAgICAgICAgICBjb25maWcuZmllbGRzID0gc2hhcGVDZmcuZmllbGRzO1xuICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gc2hhcGVDZmcuY2FsbGJhY2s7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcuc2hhcGUgPSBjb25maWc7XG4gICAgfTtcbiAgICBHdWlkZVBvaW50UGFyc2VyLnByb3RvdHlwZS5wYXJzZVN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLnBsb3Qub3B0aW9ucztcbiAgICAgICAgdmFyIHN0eWxlUHJvcHMgPSBwcm9wcy5wb2ludCAmJiBwcm9wcy5wb2ludC5zdHlsZTtcbiAgICAgICAgdmFyIGNvbmZpZyA9IHtcbiAgICAgICAgICAgIGZpZWxkczogbnVsbCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiBudWxsLFxuICAgICAgICAgICAgY2ZnOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgICB2YXIgZmllbGQgPSB0aGlzLl9nZXRDb2xvck1hcHBpbmdGaWVsZChwcm9wcyk7XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzdHlsZVByb3BzKSkge1xuICAgICAgICAgICAgY29uZmlnLmZpZWxkcyA9IFtwcm9wcy54RmllbGQsIHByb3BzLnlGaWVsZF07XG4gICAgICAgICAgICBjb25maWcuY2FsbGJhY2sgPSBzdHlsZVByb3BzO1xuICAgICAgICAgICAgaWYgKGZpZWxkKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLmZpZWxkcy51bnNoaWZ0KGZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5jZmcgPSBzdHlsZVByb3BzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uZmlnLnN0eWxlID0gY29uZmlnO1xuICAgIH07XG4gICAgR3VpZGVQb2ludFBhcnNlci5wcm90b3R5cGUuX3BhcnNlQ29sb3JCeUZpZWxkID0gZnVuY3Rpb24gKHByb3BzLCBjb25maWcsIGZpZWxkKSB7XG4gICAgICAgIGNvbmZpZy5maWVsZHMgPSBbZmllbGRdO1xuICAgICAgICBpZiAocHJvcHMucG9pbnQuY29sb3IpIHtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IGdldFZhbHVlc0J5RmllbGQoZmllbGQsIHByb3BzLmRhdGEpLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHByb3BzLnBvaW50LmNvbG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocHJvcHMuY29sb3IpIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnNlQ29sb3IocHJvcHMsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEd1aWRlUG9pbnRQYXJzZXIucHJvdG90eXBlLl9wYXJzZUNvbG9yID0gZnVuY3Rpb24gKHByb3BzLCBjb25maWcpIHtcbiAgICAgICAgdmFyIGZpZWxkID0gdGhpcy5fZ2V0Q29sb3JNYXBwaW5nRmllbGQocHJvcHMpO1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHByb3BzLmNvbG9yKSkge1xuICAgICAgICAgICAgY29uZmlnLnZhbHVlcyA9IFtwcm9wcy5jb2xvcl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzRnVuY3Rpb24ocHJvcHMuY29sb3IpKSB7XG4gICAgICAgICAgICBjb25maWcuY2FsbGJhY2sgPSBwcm9wcy5jb2xvcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNBcnJheShwcm9wcy5jb2xvcikpIHtcbiAgICAgICAgICAgIGlmIChmaWVsZCkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBwcm9wcy5jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wcy5jb2xvci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy52YWx1ZXMgPSBbcHJvcHMuY29sb3JbMF1dO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgR3VpZGVQb2ludFBhcnNlci5wcm90b3R5cGUuX25lZWRQYXJzZUF0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucGxvdC5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZGl0aW9uID0gcHJvcHMucG9pbnQgJiYgdXRpbF8xLmhhcyhwcm9wcy5wb2ludCwgYXR0cik7XG4gICAgICAgIHJldHVybiBjb25kaXRpb247XG4gICAgICAgIC8vIGNvbnN0IGNvbmRpdGlvbiA9ICF0aGlzLnN0eWxlIHx8IHRoaXMuc3R5bGVbYXR0cl07XG4gICAgICAgIC8vIHJldHVybiBjb25kaXRpb247XG4gICAgfTtcbiAgICBHdWlkZVBvaW50UGFyc2VyLnByb3RvdHlwZS5fZ2V0Q29sb3JNYXBwaW5nRmllbGQgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBDT0xPUl9NQVBQRVJfMSA9IENPTE9SX01BUFBFUjsgX2kgPCBDT0xPUl9NQVBQRVJfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBtID0gQ09MT1JfTUFQUEVSXzFbX2ldO1xuICAgICAgICAgICAgaWYgKHV0aWxfMS5nZXQocHJvcHMsIG0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtwcm9wc1ttXV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBHdWlkZVBvaW50UGFyc2VyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3VpZGVQb2ludFBhcnNlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWd1aWRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY2lyY2xlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jaXJjbGVcIikpO1xudmFyIGd1aWRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9ndWlkZVwiKSk7XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgZ3VpZGU6IGd1aWRlXzEuZGVmYXVsdCxcbiAgICBjaXJjbGU6IGNpcmNsZV8xLmRlZmF1bHQsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb3JlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jb3JlXCIpKTtcbnZhciBCYXNlSW50ZXJhY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQmFzZUludGVyYWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhc2VJbnRlcmFjdGlvbihjZmcsIHZpZXdMYXllciwgaW50ZXJhY3Rpb25SYW5nZSwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy52aWV3TGF5ZXIgPSB2aWV3TGF5ZXI7XG4gICAgICAgIF90aGlzLmludGVyYWN0aW9uUmFuZ2UgPSBpbnRlcmFjdGlvblJhbmdlO1xuICAgICAgICBfdGhpcy5pbnRlcmFjdGlvbkNvbmZpZyA9IGludGVyYWN0aW9uO1xuICAgICAgICBfdGhpcy5kaXNwb3NhYmxlcyA9IFtdO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEJhc2VJbnRlcmFjdGlvbi5yZWdpc3RlckludGVyYWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIGN0b3IpIHtcbiAgICAgICAgQmFzZUludGVyYWN0aW9uLkdMT0JBTF9JTlRFUkFDVElPTl9NQVBbdHlwZV0gPSBjdG9yO1xuICAgIH07XG4gICAgQmFzZUludGVyYWN0aW9uLnJlZ2lzdGVyUGxvdEludGVyYWN0aW9uID0gZnVuY3Rpb24gKHBsb3RUeXBlLCB0eXBlLCBjdG9yKSB7XG4gICAgICAgIGlmICghQmFzZUludGVyYWN0aW9uLlBMT1RfSU5URVJBQ1RJT05fTUFQW3Bsb3RUeXBlXSkge1xuICAgICAgICAgICAgQmFzZUludGVyYWN0aW9uLlBMT1RfSU5URVJBQ1RJT05fTUFQW3Bsb3RUeXBlXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIEJhc2VJbnRlcmFjdGlvbi5QTE9UX0lOVEVSQUNUSU9OX01BUFtwbG90VHlwZV1bdHlwZV0gPSBjdG9yO1xuICAgIH07XG4gICAgQmFzZUludGVyYWN0aW9uLmdldEludGVyYWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIHBsb3RUeXBlKSB7XG4gICAgICAgIGlmIChwbG90VHlwZSAmJiBCYXNlSW50ZXJhY3Rpb24uUExPVF9JTlRFUkFDVElPTl9NQVBbcGxvdFR5cGVdICYmIEJhc2VJbnRlcmFjdGlvbltwbG90VHlwZV1bdHlwZV0pIHtcbiAgICAgICAgICAgIHJldHVybiBCYXNlSW50ZXJhY3Rpb24uUExPVF9JTlRFUkFDVElPTl9NQVBbcGxvdFR5cGVdW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBCYXNlSW50ZXJhY3Rpb24uR0xPQkFMX0lOVEVSQUNUSU9OX01BUFt0eXBlXTtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBCYXNlSW50ZXJhY3Rpb24uZ2V0SW50ZXJhY3Rpb25SYW5nZSA9IGZ1bmN0aW9uIChsYXllclJhbmdlLCBpbnRlcmFjdGlvbikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH07XG4gICAgQmFzZUludGVyYWN0aW9uLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmRpc3Bvc2FibGVzLCBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgICAgIGZuKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRpc3Bvc2FibGVzID0gW107XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBCYXNlSW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldFZpZXdMYXllciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlld0xheWVyO1xuICAgIH07XG4gICAgQmFzZUludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRSYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJhY3Rpb25SYW5nZTtcbiAgICB9O1xuICAgIEJhc2VJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0SW50ZXJhY3Rpb25Db25maWcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmludGVyYWN0aW9uQ29uZmlnO1xuICAgIH07XG4gICAgQmFzZUludGVyYWN0aW9uLnByb3RvdHlwZS5hZGREaXNwb3NhYmxlID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHRoaXMuZGlzcG9zYWJsZXMucHVzaChmbik7XG4gICAgfTtcbiAgICBCYXNlSW50ZXJhY3Rpb24ucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEJhc2VJbnRlcmFjdGlvbi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgQmFzZUludGVyYWN0aW9uLkdMT0JBTF9JTlRFUkFDVElPTl9NQVAgPSB7fTtcbiAgICBCYXNlSW50ZXJhY3Rpb24uUExPVF9JTlRFUkFDVElPTl9NQVAgPSB7fTtcbiAgICByZXR1cm4gQmFzZUludGVyYWN0aW9uO1xufShjb3JlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQmFzZUludGVyYWN0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBFVkVOVF9UWVBFUyA9IFsnc3RhcnQnLCAncHJvY2VzcycsICdlbmQnLCAncmVzZXQnXTtcbnZhciBJbnRlcmFjdGlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBJbnRlcmFjdGlvbihjZmcpIHtcbiAgICAgICAgdmFyIGRlZmF1bHRDZmcgPSB0aGlzLmdldERlZmF1bHRDZmcoKTtcbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLCBkZWZhdWx0Q2ZnLCBjZmcpO1xuICAgICAgICB0aGlzLmNhbnZhcyA9IHRoaXMudmlldy5jYW52YXM7XG4gICAgICAgIHRoaXMuX2V2ZW50SGFuZGxlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5fYmluZEV2ZW50cygpO1xuICAgIH1cbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0RGVmYXVsdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0RXZlbnQ6ICdtb3VzZWRvd24nLFxuICAgICAgICAgICAgcHJvY2Vzc0V2ZW50OiAnbW91c2Vtb3ZlJyxcbiAgICAgICAgICAgIGVuZEV2ZW50OiAnbW91c2V1cCcsXG4gICAgICAgICAgICByZXNldEV2ZW50OiAnZGJsY2xpY2snLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB0aGlzLnByZVN0YXJ0KGV2KTtcbiAgICAgICAgdGhpcy5zdGFydChldik7XG4gICAgICAgIHRoaXMuYWZ0ZXJTdGFydChldik7XG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnByZVN0YXJ0ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuYWZ0ZXJTdGFydCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuX3Byb2Nlc3MgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdGhpcy5wcmVQcm9jZXNzKGV2KTtcbiAgICAgICAgdGhpcy5wcm9jZXNzKGV2KTtcbiAgICAgICAgdGhpcy5hZnRlclByb2Nlc3MoZXYpO1xuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5wcmVQcm9jZXNzID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuYWZ0ZXJQcm9jZXNzID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5fZW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHRoaXMucHJlRW5kKGV2KTtcbiAgICAgICAgdGhpcy5lbmQoZXYpO1xuICAgICAgICB0aGlzLmFmdGVyRW5kKGV2KTtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUucHJlRW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuYWZ0ZXJFbmQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLl9yZXNldCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB0aGlzLnByZVJlc2V0KGV2KTtcbiAgICAgICAgdGhpcy5yZXNldChldik7XG4gICAgICAgIHRoaXMuYWZ0ZXJSZXNldChldik7XG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnByZVJlc2V0ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5hZnRlclJlc2V0ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5fYmluZEV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdXRpbF8xLmVhY2goRVZFTlRfVFlQRVMsIGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgICAgICB2YXIgZXZlbnROYW1lID0gX3RoaXNbdHlwZSArIFwiRXZlbnRcIl07XG4gICAgICAgICAgICB2YXIgaGFuZGxlciA9IHV0aWxfMS53cmFwQmVoYXZpb3IoX3RoaXMsIFwiX1wiICsgdHlwZSk7XG4gICAgICAgICAgICBfdGhpcy52aWV3Lm9uKGV2ZW50TmFtZSwgaGFuZGxlcik7XG4gICAgICAgICAgICBfdGhpcy5fZXZlbnRIYW5kbGVycy5wdXNoKHsgdHlwZTogZXZlbnROYW1lLCBoYW5kbGVyOiBoYW5kbGVyIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEludGVyYWN0aW9uLnByb3RvdHlwZS5fdW5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZXZlbnRIYW5kbGVycyA9IHRoaXMuX2V2ZW50SGFuZGxlcnM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGV2ZW50SGFuZGxlcnMsIGZ1bmN0aW9uIChlaCkge1xuICAgICAgICAgICAgX3RoaXMudmlldy5vZmYoZWgudHlwZSwgZWguaGFuZGxlcik7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50cygpO1xuICAgICAgICB0aGlzLl9yZXNldCgpO1xuICAgIH07XG4gICAgcmV0dXJuIEludGVyYWN0aW9uO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEludGVyYWN0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29yZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0RGF0YUJ5U2NhbGVSYW5nZSA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbi8qKlxuICog5oyJ54Wnc2NhbGXlrZfmrrV2YWx1ZXPkuK3nmoRzdGFydOWSjGVuZOS/oeaBr+S7juWFqOmDqOaVsOaNruS4reWPluWHuuWvueW6lOeahOmDqOWIhlxuICpcbiAqIEBwYXJhbSBmaWVsZCBzY2FsZSBmaWVsZFxuICogQHBhcmFtIHZhbHVlcyBzY2FsZSB2YWx1ZXNcbiAqIEBwYXJhbSBkYXRhIG9yaWdpbmFsIGRhdGFcbiAqIEBwYXJhbSByYW5nZSByYW5nZSBzdGFydCAmIGVuZFxuICovXG5leHBvcnRzLmdldERhdGFCeVNjYWxlUmFuZ2UgPSBmdW5jdGlvbiAoZmllbGQsIHZhbHVlcywgZGF0YSwgX2EsIHZlcnRpY2FsKSB7XG4gICAgdmFyIHN0YXJ0ID0gX2FbMF0sIGVuZCA9IF9hWzFdO1xuICAgIGlmICh2ZXJ0aWNhbCA9PT0gdm9pZCAwKSB7IHZlcnRpY2FsID0gZmFsc2U7IH1cbiAgICB2YXIgZ3JvdXBlZERhdGEgPSB1dGlsXzEuZ3JvdXBCeShkYXRhLCBmaWVsZCk7XG4gICAgdmFyIG5ld1ZhbHVlcyA9IHZlcnRpY2FsID8gdmFsdWVzLnNsaWNlKHZhbHVlcy5sZW5ndGggLSBlbmQsIHZhbHVlcy5sZW5ndGggLSBzdGFydCkgOiB2YWx1ZXMuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgcmV0dXJuIHV0aWxfMS5mbGF0dGVuKHV0aWxfMS5tYXAobmV3VmFsdWVzLCBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIGdyb3VwZWREYXRhW3ZhbHVlXSB8fCBbXTsgfSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGEtcmFuZ2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbnZhciBzY3JvbGxiYXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3Njcm9sbGJhclwiKSk7XG52YXIgc2xpZGVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9zbGlkZXJcIikpO1xudmFyIHRpbWVsaW5lXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi90aW1lbGluZVwiKSk7XG52YXIgdG9vbHRpcF9pbmRpY2F0b3JfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3Rvb2x0aXAtaW5kaWNhdG9yXCIpKTtcbmJhc2VfMS5kZWZhdWx0LnJlZ2lzdGVySW50ZXJhY3Rpb24oJ3NsaWRlcicsIHNsaWRlcl8xLmRlZmF1bHQpO1xuYmFzZV8xLmRlZmF1bHQucmVnaXN0ZXJJbnRlcmFjdGlvbignc2Nyb2xsYmFyJywgc2Nyb2xsYmFyXzEuZGVmYXVsdCk7XG5iYXNlXzEuZGVmYXVsdC5yZWdpc3RlckludGVyYWN0aW9uKCd0aW1lbGluZScsIHRpbWVsaW5lXzEuZGVmYXVsdCk7XG5iYXNlXzEuZGVmYXVsdC5yZWdpc3RlckludGVyYWN0aW9uKCd0b29sdGlwLWluZGljYXRvcicsIHRvb2x0aXBfaW5kaWNhdG9yXzEuZGVmYXVsdCk7XG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiLi9iYXNlXCIpLCBleHBvcnRzKTtcbmV4cG9ydHMuZGVmYXVsdCA9IGJhc2VfMS5kZWZhdWx0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vZGVwZW5kZW50c1wiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vdXRpbC9iYm94XCIpKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbnZhciBkYXRhX3JhbmdlXzEgPSByZXF1aXJlKFwiLi9oZWxwZXIvZGF0YS1yYW5nZVwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIkBhbnR2L2cyL2xpYi9jb25zdGFudFwiKTtcbnZhciBjb25zdGFudHNfMSA9IHJlcXVpcmUoXCIuLi9iYXNlL2NvbnN0YW50c1wiKTtcbnZhciBERUZBVUxUX1BBRERJTkcgPSA0O1xudmFyIERFRkFVTFRfU0laRSA9IDg7XG52YXIgREVGQVVMVF9DQVRFR09SWV9TSVpFID0gMzI7XG52YXIgTUlOX1RIVU1CX0xFTkdUSCA9IDIwO1xudmFyIFNDUk9MTF9CQVJfWl9JTkRFWCA9IDk5OTtcbnZhciBnZXRWYWxpZFNjcm9sbGJhckNvbmZpZyA9IGZ1bmN0aW9uIChjZmcpIHtcbiAgICBpZiAoY2ZnID09PSB2b2lkIDApIHsgY2ZnID0ge307IH1cbiAgICB2YXIgX2NmZyA9IHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAnaG9yaXpvbnRhbCcsIGNhdGVnb3J5U2l6ZTogREVGQVVMVF9DQVRFR09SWV9TSVpFLCB3aWR0aDogREVGQVVMVF9TSVpFLCBoZWlnaHQ6IERFRkFVTFRfU0laRSwgcGFkZGluZzogWzAsIDAsIDAsIDBdIH0sIGNmZyk7XG4gICAgLy8gZGVmYXVsdCBwYWRkaW5nXG4gICAgaWYgKCFjZmcucGFkZGluZykge1xuICAgICAgICBfY2ZnLnBhZGRpbmcgPVxuICAgICAgICAgICAgX2NmZy50eXBlID09PSAnaG9yaXpvbnRhbCcgPyBbREVGQVVMVF9QQURESU5HLCAwLCBERUZBVUxUX1BBRERJTkcsIDBdIDogWzAsIERFRkFVTFRfUEFERElORywgMCwgREVGQVVMVF9QQURESU5HXTtcbiAgICB9XG4gICAgcmV0dXJuIF9jZmc7XG59O1xudmFyIFNjcm9sbGJhckludGVyYWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFNjcm9sbGJhckludGVyYWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNjcm9sbGJhckludGVyYWN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMub25DaGFuZ2VGbiA9IHV0aWxfMS50aHJvdHRsZShfdGhpcy5vbkNoYW5nZS5iaW5kKF90aGlzKSwgMjAsIHtcbiAgICAgICAgICAgIGxlYWRpbmc6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFNjcm9sbGJhckludGVyYWN0aW9uLmdldEludGVyYWN0aW9uUmFuZ2UgPSBmdW5jdGlvbiAobGF5ZXJSYW5nZSwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdmFyIGNvbmZpZyA9IGdldFZhbGlkU2Nyb2xsYmFyQ29uZmlnKGludGVyYWN0aW9uKTtcbiAgICAgICAgdmFyIF9hID0gY29uZmlnLnBhZGRpbmcsIHBhZGRpbmdUb3AgPSBfYVswXSwgcGFkZGluZ1JpZ2h0ID0gX2FbMV0sIHBhZGRpbmdCb3R0b20gPSBfYVsyXSwgcGFkZGluZ0xlZnQgPSBfYVszXTtcbiAgICAgICAgaWYgKGNvbmZpZy50eXBlID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQobGF5ZXJSYW5nZS5taW5YLCBsYXllclJhbmdlLm1heFkgLSBjb25maWcuaGVpZ2h0IC0gcGFkZGluZ1RvcCAtIHBhZGRpbmdCb3R0b20sIGxheWVyUmFuZ2Uud2lkdGgsIGNvbmZpZy5oZWlnaHQgKyBwYWRkaW5nVG9wICsgcGFkZGluZ0JvdHRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGJib3hfMS5kZWZhdWx0KGxheWVyUmFuZ2UubWF4WCAtIGNvbmZpZy53aWR0aCAtIHBhZGRpbmdMZWZ0IC0gcGFkZGluZ1JpZ2h0LCBsYXllclJhbmdlLm1pblksIGNvbmZpZy53aWR0aCArIHBhZGRpbmdMZWZ0ICsgcGFkZGluZ1JpZ2h0LCBsYXllclJhbmdlLmhlaWdodCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNjcm9sbGJhckludGVyYWN0aW9uLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMuZ2V0Vmlld0xheWVyKCk7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy52aWV3O1xuICAgICAgICB0aGlzLnJhdGlvID0gMDtcbiAgICAgICAgdGhpcy50aHVtYk9mZnNldCA9IDA7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBwYWRkaW5nID0gX3RoaXMudmlldy5wYWRkaW5nO1xuICAgICAgICAgICAgLy8gaWYgd2UncmUgbm90IGluIGBhdXRvIHBhZGRpbmdgIHByb2Nlc3NcbiAgICAgICAgICAgIGlmIChwYWRkaW5nID09PSAnYXV0bycgfHwgdXRpbF8xLmlzRXF1YWwocGFkZGluZywgWzAsIDAsIDAsIDFdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghX3RoaXMudHJhY2tMZW4pIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5tZWFzdXJlU2Nyb2xsQmFyKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMuY2hhbmdlVmlld0RhdGEoX3RoaXMuZ2V0U2Nyb2xsUmFuZ2UoKSwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5yZW5kZXJTY3JvbGxiYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGNoYW5nZURhdGFDYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIHJlc2V0XG4gICAgICAgICAgICBfdGhpcy50cmFja0xlbiA9IDA7XG4gICAgICAgIH07XG4gICAgICAgIHZpZXcub24oY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1BBSU5ULCBjYWxsYmFjayk7XG4gICAgICAgIHRoaXMuYWRkRGlzcG9zYWJsZShmdW5jdGlvbiAoKSB7IHJldHVybiB2aWV3Lm9mZihjb25zdGFudF8xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUEFJTlQsIGNhbGxiYWNrKTsgfSk7XG4gICAgICAgIHZpZXcub24oY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1JFTkRFUiwgY2FsbGJhY2spO1xuICAgICAgICB0aGlzLmFkZERpc3Bvc2FibGUoZnVuY3Rpb24gKCkgeyByZXR1cm4gdmlldy5vZmYoY29uc3RhbnRfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1JFTkRFUiwgY2FsbGJhY2spOyB9KTtcbiAgICAgICAgbGF5ZXIub24oY29uc3RhbnRzXzEuVklFV19MQVlFUl9MSUZFX0NZQ0xFLkJFRk9SRV9DSEFOR0VfREFUQSwgY2hhbmdlRGF0YUNhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5hZGREaXNwb3NhYmxlKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxheWVyLm9mZihjb25zdGFudHNfMS5WSUVXX0xBWUVSX0xJRkVfQ1lDTEUuQkVGT1JFX0NIQU5HRV9EQVRBLCBjaGFuZ2VEYXRhQ2FsbGJhY2spOyB9KTtcbiAgICB9O1xuICAgIFNjcm9sbGJhckludGVyYWN0aW9uLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgU2Nyb2xsYmFySW50ZXJhY3Rpb24ucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5zY3JvbGxiYXIpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyYWNrTGVuID0gbnVsbDtcbiAgICAgICAgdGhpcy50aHVtYkxlbiA9IG51bGw7XG4gICAgfTtcbiAgICBTY3JvbGxiYXJJbnRlcmFjdGlvbi5wcm90b3R5cGUucmVuZGVyU2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29uZmlnID0gZ2V0VmFsaWRTY3JvbGxiYXJDb25maWcodGhpcy5nZXRJbnRlcmFjdGlvbkNvbmZpZygpKTtcbiAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xuICAgICAgICB2YXIgaXNIb3Jpem9udGFsID0gY29uZmlnLnR5cGUgIT09ICd2ZXJ0aWNhbCc7XG4gICAgICAgIHZhciBwYW5lbFJhbmdlID0gdGhpcy52aWV3LmNvb3JkaW5hdGVCQm94O1xuICAgICAgICB2YXIgX2EgPSBjb25maWcucGFkZGluZywgcGFkZGluZ1RvcCA9IF9hWzBdLCBwYWRkaW5nTGVmdCA9IF9hWzNdO1xuICAgICAgICB2YXIgcG9zaXRpb24gPSBpc0hvcml6b250YWxcbiAgICAgICAgICAgID8geyB4OiBwYW5lbFJhbmdlLm1pblggKyBwYWRkaW5nTGVmdCwgeTogcmFuZ2UubWluWSArIHBhZGRpbmdUb3AgfVxuICAgICAgICAgICAgOiB7IHg6IHJhbmdlLm1pblggKyBwYWRkaW5nTGVmdCwgeTogcGFuZWxSYW5nZS5taW5ZICsgcGFkZGluZ1RvcCB9O1xuICAgICAgICBpZiAoIXRoaXMuc2Nyb2xsYmFyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuY2FudmFzLmFkZEdyb3VwKCk7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbGJhciA9IG5ldyBkZXBlbmRlbnRzXzEuU2Nyb2xsYmFyKHtcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuICAgICAgICAgICAgICAgIHg6IHBvc2l0aW9uLngsXG4gICAgICAgICAgICAgICAgeTogcG9zaXRpb24ueSxcbiAgICAgICAgICAgICAgICBpc0hvcml6b250YWw6IGlzSG9yaXpvbnRhbCxcbiAgICAgICAgICAgICAgICB0cmFja0xlbjogdGhpcy50cmFja0xlbixcbiAgICAgICAgICAgICAgICB0aHVtYkxlbjogdGhpcy50aHVtYkxlbixcbiAgICAgICAgICAgICAgICB0aHVtYk9mZnNldDogdGhpcy5yYXRpbyAqIHRoaXMudHJhY2tMZW4sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyLmluaXQoKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxiYXIuZ2V0KCdncm91cCcpLnNldCgnekluZGV4JywgU0NST0xMX0JBUl9aX0lOREVYKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyLm9uKCdzY3JvbGxjaGFuZ2UnLCB0aGlzLm9uQ2hhbmdlRm4pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxiYXIudXBkYXRlKHtcbiAgICAgICAgICAgICAgICB0cmFja0xlbjogdGhpcy50cmFja0xlbixcbiAgICAgICAgICAgICAgICB0aHVtYkxlbjogdGhpcy50aHVtYkxlbixcbiAgICAgICAgICAgICAgICB0aHVtYk9mZnNldDogdGhpcy50aHVtYk9mZnNldCxcbiAgICAgICAgICAgICAgICB4OiBwb3NpdGlvbi54LFxuICAgICAgICAgICAgICAgIHk6IHBvc2l0aW9uLnksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTY3JvbGxiYXJJbnRlcmFjdGlvbi5wcm90b3R5cGUubWVhc3VyZVNjcm9sbEJhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbmZpZyA9IGdldFZhbGlkU2Nyb2xsYmFyQ29uZmlnKHRoaXMuZ2V0SW50ZXJhY3Rpb25Db25maWcoKSk7XG4gICAgICAgIHZhciBfYSA9IGNvbmZpZy5wYWRkaW5nLCBwYWRkaW5nVG9wID0gX2FbMF0sIHBhZGRpbmdSaWdodCA9IF9hWzFdLCBwYWRkaW5nQm90dG9tID0gX2FbMl0sIHBhZGRpbmdMZWZ0ID0gX2FbM107XG4gICAgICAgIHZhciBpc0hvcml6b250YWwgPSBjb25maWcudHlwZSAhPT0gJ3ZlcnRpY2FsJztcbiAgICAgICAgdmFyIHBhbmVsUmFuZ2UgPSB0aGlzLnZpZXcuY29vcmRpbmF0ZUJCb3g7XG4gICAgICAgIHZhciB4U2NhbGUgPSB0aGlzLnZpZXcuZ2V0WFNjYWxlKCk7XG4gICAgICAgIHZhciB5U2NhbGVzID0gdGhpcy52aWV3LmdldFlTY2FsZXMoKS5maWx0ZXIoZnVuY3Rpb24gKHNjYWxlKSB7IHJldHVybiBzY2FsZTsgfSk7XG4gICAgICAgIHRoaXMuY250ID0geFNjYWxlLnZhbHVlcy5sZW5ndGg7XG4gICAgICAgIHRoaXMueFNjYWxlQ2ZnID0geyBmaWVsZDogeFNjYWxlLmZpZWxkLCB2YWx1ZXM6IHhTY2FsZS52YWx1ZXMgfHwgW10gfTtcbiAgICAgICAgdGhpcy55U2NhbGVzQ2ZnID0geVNjYWxlcztcbiAgICAgICAgdGhpcy5zdGVwID0gTWF0aC5mbG9vcigoaXNIb3Jpem9udGFsID8gcGFuZWxSYW5nZS53aWR0aCA6IHBhbmVsUmFuZ2UuaGVpZ2h0KSAvIGNvbmZpZy5jYXRlZ29yeVNpemUpO1xuICAgICAgICB0aGlzLnRyYWNrTGVuID0gaXNIb3Jpem9udGFsXG4gICAgICAgICAgICA/IHBhbmVsUmFuZ2Uud2lkdGggLSBwYWRkaW5nTGVmdCAtIHBhZGRpbmdSaWdodFxuICAgICAgICAgICAgOiBwYW5lbFJhbmdlLmhlaWdodCAtIHBhZGRpbmdUb3AgLSBwYWRkaW5nQm90dG9tO1xuICAgICAgICB0aGlzLnRodW1iTGVuID0gTWF0aC5tYXgodGhpcy50cmFja0xlbiAqIHV0aWxfMS5jbGFtcCh0aGlzLnN0ZXAgLyB4U2NhbGUudmFsdWVzLmxlbmd0aCwgMCwgMSksIE1JTl9USFVNQl9MRU5HVEgpO1xuICAgIH07XG4gICAgU2Nyb2xsYmFySW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldFNjcm9sbFJhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RhcnRJZHggPSBNYXRoLmZsb29yKCh0aGlzLmNudCAtIHRoaXMuc3RlcCkgKiB1dGlsXzEuY2xhbXAodGhpcy5yYXRpbywgMCwgMSkpO1xuICAgICAgICB2YXIgZW5kSWR4ID0gTWF0aC5taW4oc3RhcnRJZHggKyB0aGlzLnN0ZXAsIHRoaXMuY250KTtcbiAgICAgICAgcmV0dXJuIFtzdGFydElkeCwgZW5kSWR4XTtcbiAgICB9O1xuICAgIFNjcm9sbGJhckludGVyYWN0aW9uLnByb3RvdHlwZS5jaGFuZ2VWaWV3RGF0YSA9IGZ1bmN0aW9uIChfYSwgcmVuZGVyKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBzdGFydElkeCA9IF9hWzBdLCBlbmRJZHggPSBfYVsxXTtcbiAgICAgICAgdmFyIGNvbmZpZyA9IGdldFZhbGlkU2Nyb2xsYmFyQ29uZmlnKHRoaXMuZ2V0SW50ZXJhY3Rpb25Db25maWcoKSk7XG4gICAgICAgIHZhciB2aWV3TGF5ZXIgPSB0aGlzLmdldFZpZXdMYXllcigpO1xuICAgICAgICB2YXIgbWV0YSA9IHZpZXdMYXllci5vcHRpb25zLm1ldGE7XG4gICAgICAgIHZhciBvcmlnRGF0YSA9IHZpZXdMYXllci5nZXREYXRhKCk7XG4gICAgICAgIHZhciBuZXdEYXRhID0gZGF0YV9yYW5nZV8xLmdldERhdGFCeVNjYWxlUmFuZ2UodGhpcy54U2NhbGVDZmcuZmllbGQsIHRoaXMueFNjYWxlQ2ZnLnZhbHVlcywgb3JpZ0RhdGEsIFtzdGFydElkeCwgZW5kSWR4XSwgY29uZmlnLnR5cGUgPT09ICd2ZXJ0aWNhbCcpO1xuICAgICAgICAvLyBTY3JvbGxCYXLlnKjmu5rliqjov4fnqIvkuK3kv53mjIFcYlxiWei9tOS4inNjYWxl6YWN572uOiBtaW4vbWF4L3RpY2tzXG4gICAgICAgIHRoaXMueVNjYWxlc0NmZy5mb3JFYWNoKGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgICAgIHZhciBtZXRhQ2ZnID0gdXRpbF8xLmdldChtZXRhLCBjZmcuZmllbGQpIHx8IHt9O1xuICAgICAgICAgICAgX3RoaXMudmlldy5zY2FsZShjZmcuZmllbGQsIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IGZvcm1hdHRlcjogY2ZnLmZvcm1hdHRlciB9LCBtZXRhQ2ZnKSwgeyB0eXBlOiBjZmcudHlwZSwgbWluOiBjZmcubWluLCBtYXg6IGNmZy5tYXggfSkpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlbmRlcikge1xuICAgICAgICAgICAgdGhpcy52aWV3LmRhdGEobmV3RGF0YSk7XG4gICAgICAgICAgICB0aGlzLnZpZXcucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZXcuY2hhbmdlRGF0YShuZXdEYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2Nyb2xsYmFySW50ZXJhY3Rpb24ucHJvdG90eXBlLm9uQ2hhbmdlID0gZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgIHZhciByYXRpbyA9IF9hLnJhdGlvLCB0aHVtYk9mZnNldCA9IF9hLnRodW1iT2Zmc2V0O1xuICAgICAgICB0aGlzLnJhdGlvID0gcmF0aW87XG4gICAgICAgIHRoaXMudGh1bWJPZmZzZXQgPSB0aHVtYk9mZnNldDtcbiAgICAgICAgdmFyIG9yaWdBbmltYXRlID0gdGhpcy52aWV3LmdldE9wdGlvbnMoKS5hbmltYXRlO1xuICAgICAgICB0aGlzLnZpZXcuYW5pbWF0ZShmYWxzZSk7XG4gICAgICAgIHRoaXMuY2hhbmdlVmlld0RhdGEodGhpcy5nZXRTY3JvbGxSYW5nZSgpLCB0cnVlKTtcbiAgICAgICAgdGhpcy52aWV3LmFuaW1hdGUob3JpZ0FuaW1hdGUpO1xuICAgICAgICAvLyB1cGRhdGUgc2Nyb2xsYmFyXG4gICAgICAgIHRoaXMucmVuZGVyU2Nyb2xsYmFyKCk7XG4gICAgfTtcbiAgICByZXR1cm4gU2Nyb2xsYmFySW50ZXJhY3Rpb247XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTY3JvbGxiYXJJbnRlcmFjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNjcm9sbGJhci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi9kZXBlbmRlbnRzXCIpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi91dGlsL2Jib3hcIikpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2Jhc2VcIikpO1xudmFyIGRhdGFfcmFuZ2VfMSA9IHJlcXVpcmUoXCIuL2hlbHBlci9kYXRhLXJhbmdlXCIpO1xudmFyIERFRkFVTFRfUEFERElORyA9IDQ7XG52YXIgREVGQVVMVF9TSVpFID0gMTY7XG52YXIgZ2V0VmFsaWRTbGlkZXJDb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgaWYgKGNmZyA9PT0gdm9pZCAwKSB7IGNmZyA9IHt9OyB9XG4gICAgdmFyIF9jZmcgPSB0c2xpYl8xLl9fYXNzaWduKHsgdHlwZTogJ2hvcml6b250YWwnLCBzdGFydDogMCwgZW5kOiAxLCB3aWR0aDogdW5kZWZpbmVkLCBoZWlnaHQ6IHVuZGVmaW5lZCwgcGFkZGluZzogWzAsIDAsIDAsIDBdLCBiYWNrZ3JvdW5kU3R5bGU6IHt9LCBmb3JlZ3JvdW5kU3R5bGU6IHt9LCBoYW5kbGVyU3R5bGU6IHt9LCB0ZXh0U3R5bGU6IHt9LCB0cmVuZENmZzoge30gfSwgY2ZnKTtcbiAgICAvLyBkZWZhdWx0IHBhZGRpbmdcbiAgICBpZiAoIWNmZy5wYWRkaW5nKSB7XG4gICAgICAgIF9jZmcucGFkZGluZyA9XG4gICAgICAgICAgICBfY2ZnLnR5cGUgPT09ICdob3Jpem9udGFsJyA/IFtERUZBVUxUX1BBRERJTkcsIDAsIERFRkFVTFRfUEFERElORywgMF0gOiBbMCwgREVGQVVMVF9QQURESU5HLCAwLCBERUZBVUxUX1BBRERJTkddO1xuICAgIH1cbiAgICAvLyBkZWZhdWx0IHNpemVcbiAgICBpZiAoIWNmZy5oZWlnaHQpIHtcbiAgICAgICAgX2NmZy5oZWlnaHQgPSBERUZBVUxUX1NJWkU7XG4gICAgfVxuICAgIGlmICghY2ZnLndpZHRoKSB7XG4gICAgICAgIF9jZmcud2lkdGggPSBERUZBVUxUX1NJWkU7XG4gICAgfVxuICAgIC8vIHN0YXJ0ICYgZW5kXG4gICAgdmFyIHN0YXJ0ID0gdXRpbF8xLmNsYW1wKE1hdGgubWluKF9jZmcuc3RhcnQsIF9jZmcuZW5kKSwgMCwgMSk7XG4gICAgdmFyIGVuZCA9IHV0aWxfMS5jbGFtcChNYXRoLm1heChfY2ZnLnN0YXJ0LCBfY2ZnLmVuZCksIDAsIDEpO1xuICAgIF9jZmcuc3RhcnQgPSBzdGFydDtcbiAgICBfY2ZnLmVuZCA9IGVuZDtcbiAgICByZXR1cm4gX2NmZztcbn07XG52YXIgU2xpZGVySW50ZXJhY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2xpZGVySW50ZXJhY3Rpb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU2xpZGVySW50ZXJhY3Rpb24oKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5vbkNoYW5nZUZuID0gdXRpbF8xLnRocm90dGxlKF90aGlzLm9uQ2hhbmdlLmJpbmQoX3RoaXMpLCAyMCwgeyBsZWFkaW5nOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFNsaWRlckludGVyYWN0aW9uLmdldEludGVyYWN0aW9uUmFuZ2UgPSBmdW5jdGlvbiAobGF5ZXJSYW5nZSwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdmFyIGNvbmZpZyA9IGdldFZhbGlkU2xpZGVyQ29uZmlnKGludGVyYWN0aW9uKTtcbiAgICAgICAgdmFyIF9hID0gY29uZmlnLnBhZGRpbmcgfHwgWzAsIDAsIDAsIDBdLCBwYWRkaW5nVG9wID0gX2FbMF0sIHBhZGRpbmdSaWdodCA9IF9hWzFdLCBwYWRkaW5nQm90dG9tID0gX2FbMl0sIHBhZGRpbmdMZWZ0ID0gX2FbM107XG4gICAgICAgIGlmIChjb25maWcudHlwZSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgICB2YXIgYmJveCA9IG5ldyBiYm94XzEuZGVmYXVsdChsYXllclJhbmdlLm1pblgsIGxheWVyUmFuZ2UubWF4WSAtIGNvbmZpZy5oZWlnaHQgLSBwYWRkaW5nVG9wIC0gcGFkZGluZ0JvdHRvbSwgbGF5ZXJSYW5nZS53aWR0aCwgY29uZmlnLmhlaWdodCArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tKTtcbiAgICAgICAgICAgIHJldHVybiBiYm94O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBiYm94XzEuZGVmYXVsdChsYXllclJhbmdlLm1heFggLSBjb25maWcud2lkdGggLSBwYWRkaW5nTGVmdCAtIHBhZGRpbmdSaWdodCwgbGF5ZXJSYW5nZS5taW5ZLCBjb25maWcud2lkdGggKyBwYWRkaW5nTGVmdCArIHBhZGRpbmdSaWdodCwgbGF5ZXJSYW5nZS5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTbGlkZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldFZpZXdMYXllcigpO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMudmlldztcbiAgICAgICAgLy8g6K6+572u5Yid5aeL5YyW55qEIHN0YXJ0L2VuZFxuICAgICAgICB2YXIgY29uZmlnID0gZ2V0VmFsaWRTbGlkZXJDb25maWcodGhpcy5nZXRJbnRlcmFjdGlvbkNvbmZpZygpKTtcbiAgICAgICAgdGhpcy5jdXJTdGFydCA9IGNvbmZpZy5zdGFydDtcbiAgICAgICAgdGhpcy5jdXJFbmQgPSBjb25maWcuZW5kO1xuICAgICAgICB0aGlzLnhTY2FsZUNmZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgLy8g562J5b6FIHZpZXcg5q+P5qyhIHJlbmRlciDlrozmiJDlkI7mm7TmlrAgc2xpZGVyIOe7hOS7tlxuICAgICAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgcGFkZGluZyA9IF90aGlzLnZpZXcucGFkZGluZztcbiAgICAgICAgICAgIGlmIChwYWRkaW5nID09PSAnYXV0bycgfHwgdXRpbF8xLmlzRXF1YWwocGFkZGluZywgWzAsIDAsIDAsIDFdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNFbXB0eShsYXllci5vcHRpb25zLmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFfdGhpcy54U2NhbGVDZmcpIHtcbiAgICAgICAgICAgICAgICAvLyDliJ3lp4vljJbphY3nva7lkozmlbDmja5cbiAgICAgICAgICAgICAgICB2YXIgeFNjYWxlID0gdmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgICAgICAgICBfdGhpcy54U2NhbGVDZmcgPSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiB4U2NhbGUuZmllbGQsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczogeFNjYWxlLnZhbHVlcyB8fCBbXSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIC8vIOWIneWni+WMliBkYXRhXG4gICAgICAgICAgICAgICAgdmlldy5kYXRhKF90aGlzLmdldFNsaWRlckRhdGEoX3RoaXMuY3VyU3RhcnQsIF90aGlzLmN1ckVuZCkpO1xuICAgICAgICAgICAgICAgIHZpZXcucmVuZGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5yZW5kZXJTbGlkZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmlldy5vbihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9QQUlOVCwgY2FsbGJhY2spO1xuICAgICAgICB0aGlzLmFkZERpc3Bvc2FibGUoZnVuY3Rpb24gKCkgeyByZXR1cm4gdmlldy5vZmYoZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUEFJTlQsIGNhbGxiYWNrKTsgfSk7XG4gICAgICAgIHZpZXcub24oZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUkVOREVSLCBjYWxsYmFjayk7XG4gICAgICAgIHRoaXMuYWRkRGlzcG9zYWJsZShmdW5jdGlvbiAoKSB7IHJldHVybiB2aWV3Lm9mZihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9SRU5ERVIsIGNhbGxiYWNrKTsgfSk7XG4gICAgfTtcbiAgICBTbGlkZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIFNsaWRlckludGVyYWN0aW9uLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2xpZGVyKSB7XG4gICAgICAgICAgICB0aGlzLnNsaWRlci5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLnNsaWRlciA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNsaWRlckludGVyYWN0aW9uLnByb3RvdHlwZS5yZW5kZXJTbGlkZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5zbGlkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyID0gdGhpcy5jYW52YXMuYWRkR3JvdXAoKTtcbiAgICAgICAgICAgIHRoaXMuc2xpZGVyID0gbmV3IGRlcGVuZGVudHNfMS5TbGlkZXIodHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCB0aGlzLmdldFNsaWRlckNvbmZpZygpKSwgeyBjb250YWluZXI6IHRoaXMuY29udGFpbmVyIH0pKTtcbiAgICAgICAgICAgIHRoaXMuc2xpZGVyLmluaXQoKTtcbiAgICAgICAgICAgIHRoaXMuc2xpZGVyLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5zbGlkZXIub24oJ3NsaWRlcmNoYW5nZScsIHRoaXMub25DaGFuZ2VGbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNsaWRlci51cGRhdGUodGhpcy5nZXRTbGlkZXJDb25maWcoKSk7XG4gICAgICAgICAgICB0aGlzLnNsaWRlci5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2xpZGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldFNsaWRlckNvbmZpZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZhciBwYW5lbFJhbmdlID0gdmlldy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpO1xuICAgICAgICB2YXIgY29uZmlnID0gZ2V0VmFsaWRTbGlkZXJDb25maWcodGhpcy5nZXRJbnRlcmFjdGlvbkNvbmZpZygpKTtcbiAgICAgICAgdmFyIF9hID0gY29uZmlnIHx8IHt9LCBfYiA9IF9hLnBhZGRpbmcsIHBhZGRpbmcgPSBfYiA9PT0gdm9pZCAwID8gWzAsIDAsIDAsIDBdIDogX2IsIGJhY2tncm91bmRTdHlsZSA9IF9hLmJhY2tncm91bmRTdHlsZSwgZm9yZWdyb3VuZFN0eWxlID0gX2EuZm9yZWdyb3VuZFN0eWxlLCBoYW5kbGVyU3R5bGUgPSBfYS5oYW5kbGVyU3R5bGUsIHRleHRTdHlsZSA9IF9hLnRleHRTdHlsZSwgX2MgPSBfYS50cmVuZENmZywgdHJlbmRDZmcgPSBfYyA9PT0gdm9pZCAwID8ge30gOiBfYztcbiAgICAgICAgdmFyIHBhZGRpbmdUb3AgPSBwYWRkaW5nWzBdLCBwYWRkaW5nUmlnaHQgPSBwYWRkaW5nWzFdLCBwYWRkaW5nQm90dG9tID0gcGFkZGluZ1syXSwgcGFkZGluZ0xlZnQgPSBwYWRkaW5nWzNdO1xuICAgICAgICB2YXIgX2QgPSB0aGlzLmdldFNsaWRlck1pbk1heFRleHQodGhpcy5jdXJTdGFydCwgdGhpcy5jdXJFbmQpLCBtaW5UZXh0ID0gX2QubWluVGV4dCwgbWF4VGV4dCA9IF9kLm1heFRleHQ7XG4gICAgICAgIHZhciBjZmcgPSB7XG4gICAgICAgICAgICB4OiBwYW5lbFJhbmdlLm1pblggKyBwYWRkaW5nTGVmdCxcbiAgICAgICAgICAgIHk6IHJhbmdlLm1pblkgKyBwYWRkaW5nVG9wLFxuICAgICAgICAgICAgd2lkdGg6IHBhbmVsUmFuZ2Uud2lkdGggLSBwYWRkaW5nTGVmdCAtIHBhZGRpbmdSaWdodCxcbiAgICAgICAgICAgIGhlaWdodDogcmFuZ2UuaGVpZ2h0IC0gcGFkZGluZ1RvcCAtIHBhZGRpbmdCb3R0b20sXG4gICAgICAgICAgICBzdGFydDogdGhpcy5jdXJTdGFydCxcbiAgICAgICAgICAgIGVuZDogdGhpcy5jdXJFbmQsXG4gICAgICAgICAgICBtaW5UZXh0OiBtaW5UZXh0LFxuICAgICAgICAgICAgbWF4VGV4dDogbWF4VGV4dCxcbiAgICAgICAgICAgIGJhY2tncm91bmRTdHlsZTogYmFja2dyb3VuZFN0eWxlLFxuICAgICAgICAgICAgZm9yZWdyb3VuZFN0eWxlOiBmb3JlZ3JvdW5kU3R5bGUsXG4gICAgICAgICAgICBoYW5kbGVyU3R5bGU6IGhhbmRsZXJTdHlsZSxcbiAgICAgICAgICAgIHRleHRTdHlsZTogdGV4dFN0eWxlLFxuICAgICAgICAgICAgdHJlbmRDZmc6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IGlzQXJlYTogZmFsc2UsIHNtb290aDogZmFsc2UgfSwgdHJlbmRDZmcpLCB7IGRhdGE6IHRoaXMuZ2V0U2xpZGVyVHJlbmREYXRhKCkgfSksXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBjZmc7XG4gICAgfTtcbiAgICBTbGlkZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0U2xpZGVyVHJlbmREYXRhID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldFZpZXdMYXllcigpLm9wdGlvbnMsIGRhdGEgPSBfYS5kYXRhLCB5RmllbGQgPSBfYS55RmllbGQ7XG4gICAgICAgIHJldHVybiB1dGlsXzEubWFwKGRhdGEsIGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtW3lGaWVsZF07IH0pO1xuICAgIH07XG4gICAgU2xpZGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldFNsaWRlckRhdGEgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICAgICAgICB2YXIgb3JpZ0RhdGEgPSB0aGlzLmdldFZpZXdMYXllcigpLmdldERhdGEoKTtcbiAgICAgICAgdmFyIGxlbmd0aCA9IHV0aWxfMS5zaXplKHRoaXMueFNjYWxlQ2ZnLnZhbHVlcyk7XG4gICAgICAgIHZhciBzdGFydElkeCA9IE1hdGgucm91bmQoc3RhcnQgKiBsZW5ndGgpO1xuICAgICAgICB2YXIgZW5kSWR4ID0gTWF0aC5tYXgoc3RhcnRJZHggKyAxLCBNYXRoLnJvdW5kKGVuZCAqIGxlbmd0aCkpO1xuICAgICAgICByZXR1cm4gZGF0YV9yYW5nZV8xLmdldERhdGFCeVNjYWxlUmFuZ2UodGhpcy54U2NhbGVDZmcuZmllbGQsIHRoaXMueFNjYWxlQ2ZnLnZhbHVlcywgb3JpZ0RhdGEsIFtzdGFydElkeCwgZW5kSWR4XSk7XG4gICAgfTtcbiAgICBTbGlkZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0U2xpZGVyTWluTWF4VGV4dCA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0Vmlld0xheWVyKCkub3B0aW9ucywgX2IgPSBfYS5kYXRhLCBkYXRhID0gX2IgPT09IHZvaWQgMCA/IFtdIDogX2IsIHhGaWVsZCA9IF9hLnhGaWVsZDtcbiAgICAgICAgdmFyIGxlbmd0aCA9IHV0aWxfMS5zaXplKGRhdGEpO1xuICAgICAgICB2YXIgc3RhcnRJZHggPSBNYXRoLnJvdW5kKHN0YXJ0ICogbGVuZ3RoKTtcbiAgICAgICAgdmFyIGVuZElkeCA9IE1hdGgubWF4KHN0YXJ0SWR4ICsgMSwgTWF0aC5yb3VuZChlbmQgKiBsZW5ndGgpKTtcbiAgICAgICAgdmFyIG5ld0RhdGEgPSBkYXRhLnNsaWNlKHN0YXJ0SWR4LCBlbmRJZHgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluVGV4dDogbmV3RGF0YS5sZW5ndGggPiAwID8gdXRpbF8xLmhlYWQobmV3RGF0YSlbeEZpZWxkXSA6ICcnLFxuICAgICAgICAgICAgbWF4VGV4dDogbmV3RGF0YS5sZW5ndGggPiAwID8gdXRpbF8xLmxhc3QobmV3RGF0YSlbeEZpZWxkXSA6ICcnLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgU2xpZGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLm9uQ2hhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy52aWV3O1xuICAgICAgICB2YXIgc3RhcnQgPSB1dGlsXzEuY2xhbXAoTWF0aC5taW4ocmFuZ2VbMF0sIHJhbmdlWzFdKSwgMCwgMSk7XG4gICAgICAgIHZhciBlbmQgPSB1dGlsXzEuY2xhbXAoTWF0aC5tYXgocmFuZ2VbMF0sIHJhbmdlWzFdKSwgMCwgMSk7XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5nZXRTbGlkZXJEYXRhKHN0YXJ0LCBlbmQpO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldFNsaWRlck1pbk1heFRleHQoc3RhcnQsIGVuZCksIG1pblRleHQgPSBfYS5taW5UZXh0LCBtYXhUZXh0ID0gX2EubWF4VGV4dDtcbiAgICAgICAgdGhpcy5jdXJTdGFydCA9IHN0YXJ0O1xuICAgICAgICB0aGlzLmN1ckVuZCA9IGVuZDtcbiAgICAgICAgdGhpcy5zbGlkZXIudXBkYXRlKHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgICAgIGVuZDogZW5kLFxuICAgICAgICAgICAgbWluVGV4dDogbWluVGV4dCxcbiAgICAgICAgICAgIG1heFRleHQ6IG1heFRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNsaWRlci5yZW5kZXIoKTtcbiAgICAgICAgdmFyIG9yaWdBbmltYXRlID0gdmlldy5nZXRPcHRpb25zKCkuYW5pbWF0ZTtcbiAgICAgICAgdmlldy5hbmltYXRlKGZhbHNlKTtcbiAgICAgICAgdmlldy5kYXRhKGRhdGEpO1xuICAgICAgICB2aWV3LnJlbmRlcigpO1xuICAgICAgICB2aWV3LmFuaW1hdGUob3JpZ0FuaW1hdGUpO1xuICAgIH07XG4gICAgcmV0dXJuIFNsaWRlckludGVyYWN0aW9uO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU2xpZGVySW50ZXJhY3Rpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zbGlkZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vZGVwZW5kZW50c1wiKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vdXRpbC9iYm94XCIpKTtcbnZhciB0aW1lbGluZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2NvbXBvbmVudHMvdGltZWxpbmVcIikpO1xudmFyIERFRkFVTFRfSEVJR0hUID0gNDA7XG5mdW5jdGlvbiBnZXRWYWxpZFRpbWVMaW5lQ29uZmlnKGludGVyYWN0aW9uKSB7XG4gICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24oeyBsb29wOiBmYWxzZSwgYXV0bzogdHJ1ZSwgaGVpZ2h0OiBERUZBVUxUX0hFSUdIVCwgcGFkZGluZzogWzAsIDIwLCAwLCAwXSwgc3BlZWQ6IDIgfSwgaW50ZXJhY3Rpb24pO1xufVxudmFyIFRpbWVMaW5lSW50ZXJhY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVGltZUxpbmVJbnRlcmFjdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUaW1lTGluZUludGVyYWN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMub25DaGFuZ2VGbiA9IHV0aWxfMS50aHJvdHRsZShfdGhpcy5vbkNoYW5nZS5iaW5kKF90aGlzKSwgMjAsIHsgbGVhZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKiogVGltZUxpbmVJbnRlcmFjdGlvbiBuZXcg5pe255qE6IyD5Zu05Y+C5pWwIGludGVyYWN0aW9uUmFuZ2UgKi9cbiAgICBUaW1lTGluZUludGVyYWN0aW9uLmdldEludGVyYWN0aW9uUmFuZ2UgPSBmdW5jdGlvbiAobGF5ZXJSYW5nZSwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdmFyIGNvbmZpZyA9IGdldFZhbGlkVGltZUxpbmVDb25maWcoaW50ZXJhY3Rpb24pO1xuICAgICAgICB2YXIgcGFkZGluZ1RvcCA9IGNvbmZpZy5wYWRkaW5nWzBdO1xuICAgICAgICB2YXIgcGFkZGluZ0JvdHRvbSA9IGNvbmZpZy5wYWRkaW5nWzJdO1xuICAgICAgICByZXR1cm4gbmV3IGJib3hfMS5kZWZhdWx0KGxheWVyUmFuZ2UubWluWCwgbGF5ZXJSYW5nZS5tYXhZIC0gY29uZmlnLmhlaWdodCAtIHBhZGRpbmdUb3AgLSBwYWRkaW5nQm90dG9tLCBsYXllclJhbmdlLndpZHRoLCBjb25maWcuaGVpZ2h0ICsgcGFkZGluZ1RvcCArIHBhZGRpbmdCb3R0b20pO1xuICAgIH07XG4gICAgVGltZUxpbmVJbnRlcmFjdGlvbi5wcm90b3R5cGUuc2V0QW5pbWF0ZSA9IGZ1bmN0aW9uIChpc0FuaW1hdGUpIHtcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLnZpZXcuZ2VvbWV0cmllcztcbiAgICAgICAgdGhpcy52aWV3LmFuaW1hdGUoaXNBbmltYXRlKTtcbiAgICAgICAgZ2VvbWV0cmllcy5mb3JFYWNoKGZ1bmN0aW9uIChnZW9tKSB7XG4gICAgICAgICAgICBnZW9tLmFuaW1hdGUoaXNBbmltYXRlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBUaW1lTGluZUludGVyYWN0aW9uLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgVGltZUxpbmVJbnRlcmFjdGlvbi5wcm90b3R5cGUucmVuZGVyVGltZUxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuY29uZmlnID0gZ2V0VmFsaWRUaW1lTGluZUNvbmZpZyh0aGlzLmdldEludGVyYWN0aW9uQ29uZmlnKCkpO1xuICAgICAgICB2YXIgdmlld1JhbmdlID0gdGhpcy52aWV3LnZpZXdCQm94O1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmNvbmZpZywgbG9vcCA9IF9hLmxvb3AsIHBhZGRpbmcgPSBfYS5wYWRkaW5nLCBzcGVlZCA9IF9hLnNwZWVkO1xuICAgICAgICB2YXIgcGFkZGluZ1RvcCA9IHBhZGRpbmdbMF0sIHBhZGRpbmdSaWdodCA9IHBhZGRpbmdbMV0sIHBhZGRpbmdCb3R0b20gPSBwYWRkaW5nWzJdLCBwYWRkaW5nTGVmdCA9IHBhZGRpbmdbM107XG4gICAgICAgIHZhciByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTtcbiAgICAgICAgdmFyIHRpY2tzID0gdGhpcy5nZXRUaWNrcygpO1xuICAgICAgICB2YXIgd2lkdGggPSB2aWV3UmFuZ2Uud2lkdGggLSBwYWRkaW5nTGVmdCAtIHBhZGRpbmdSaWdodDtcbiAgICAgICAgdmFyIHRpbWVMaW5lQ29uZmlnID0ge1xuICAgICAgICAgICAgeDogdmlld1JhbmdlLm1pblggKyBwYWRkaW5nTGVmdCxcbiAgICAgICAgICAgIHk6IHJhbmdlLnRsLnkgKyBwYWRkaW5nVG9wLFxuICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiByYW5nZS5oZWlnaHQgLSBwYWRkaW5nVG9wIC0gcGFkZGluZ0JvdHRvbSxcbiAgICAgICAgICAgIGxvb3A6IGxvb3AsXG4gICAgICAgICAgICB0aWNrczogdGlja3MsXG4gICAgICAgICAgICBzcGVlZDogc3BlZWQsXG4gICAgICAgICAgICBkZWZhdWx0Q3VycmVudFRpY2s6IHRpY2tzWzBdLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy50aW1lbGluZSkge1xuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNFcXVhbCh0aW1lTGluZUNvbmZpZywgdGhpcy50aW1lTGluZUNvbmZpZykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVMaW5lQ29uZmlnID0gdGltZUxpbmVDb25maWc7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lbGluZS51cGRhdGUodGltZUxpbmVDb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLmNhbnZhcy5hZGRHcm91cCgpO1xuICAgICAgICAgICAgdGhpcy50aW1lbGluZSA9IG5ldyB0aW1lbGluZV8xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IGNvbnRhaW5lcjogdGhpcy5jb250YWluZXIgfSwgdGltZUxpbmVDb25maWcpKTtcbiAgICAgICAgICAgIHRoaXMudGltZWxpbmUuaW5pdCgpO1xuICAgICAgICAgICAgdGhpcy50aW1lbGluZS5yZW5kZXIoKTtcbiAgICAgICAgICAgIHRoaXMudGltZWxpbmUub24oJ3RpbWVsaW5lc3RhcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMub3JpZ2luQW5pbWF0aW9uID0gX3RoaXMudmlldy5nZXRPcHRpb25zKCkuYW5pbWF0ZTtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRBbmltYXRlKHRydWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnRpbWVsaW5lLm9uKCd0aW1lbGluZWVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRBbmltYXRlKF90aGlzLm9yaWdpbkFuaW1hdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMudGltZWxpbmUub24oJ3RpbWVsaW5lY2hhbmdlJywgdGhpcy5vbkNoYW5nZUZuKTtcbiAgICAgICAgICAgIHRoaXMudGltZWxpbmUub24oJ3RpbWVsaW5ldXBkYXRlJywgdGhpcy5vbkNoYW5nZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMudmlldy5kYXRhKHRoaXMuZ2V0RmlsdGVyRGF0YSh0aWNrc1swXSkpO1xuICAgICAgICAgICAgdGhpcy50aW1lTGluZUNvbmZpZyA9IHRpbWVMaW5lQ29uZmlnO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUaW1lTGluZUludGVyYWN0aW9uLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uICh0aWNrKSB7XG4gICAgICAgIHZhciBmaWx0ZXJEYXRhID0gdGhpcy5nZXRGaWx0ZXJEYXRhKHRpY2spO1xuICAgICAgICB0aGlzLnZpZXcuY2hhbmdlRGF0YShmaWx0ZXJEYXRhKTtcbiAgICB9O1xuICAgIFRpbWVMaW5lSW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldEZpbHRlckRhdGEgPSBmdW5jdGlvbiAodGljaykge1xuICAgICAgICB2YXIgZmllbGQgPSB0aGlzLmNvbmZpZy5maWVsZDtcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLmdldFZpZXdMYXllcigpLm9wdGlvbnMuZGF0YTtcbiAgICAgICAgcmV0dXJuIGRhdGEuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBpdGVtW2ZpZWxkXSA9PT0gdGljazsgfSk7XG4gICAgfTtcbiAgICBUaW1lTGluZUludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRUaWNrcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZpZWxkID0gdGhpcy5jb25maWcuZmllbGQ7XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5nZXRWaWV3TGF5ZXIoKS5vcHRpb25zLmRhdGE7XG4gICAgICAgIHJldHVybiB1dGlsXzEudW5pcShkYXRhLm1hcChmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbVtmaWVsZF07IH0pKTtcbiAgICB9O1xuICAgIC8qKiDmuLLmn5MgdGltZWxpbmUgKi9cbiAgICBUaW1lTGluZUludGVyYWN0aW9uLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuZmlyc3RSZW5kZXIgPSB0cnVlO1xuICAgICAgICB0aGlzLnZpZXcub24oZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQkVGT1JFX1JFTkRFUiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMucmVuZGVyVGltZUxpbmUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlldy5vbihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5CRUZPUkVfUEFJTlQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLnJlbmRlclRpbWVMaW5lKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpZXcub24oZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUEFJTlQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5jb25maWcuYXV0byAmJiBfdGhpcy5maXJzdFJlbmRlcikge1xuICAgICAgICAgICAgICAgIF90aGlzLnRpbWVsaW5lLmlzUGxheSA9IHRydWU7XG4gICAgICAgICAgICAgICAgX3RoaXMudGltZWxpbmUuY2hhbmdlUGxheVN0YXR1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMuZmlyc3RSZW5kZXIgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlldy5vbihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9SRU5ERVIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5jb25maWcuYXV0byAmJiBfdGhpcy5maXJzdFJlbmRlcikge1xuICAgICAgICAgICAgICAgIF90aGlzLnRpbWVsaW5lLmlzUGxheSA9IHRydWU7XG4gICAgICAgICAgICAgICAgX3RoaXMudGltZWxpbmUuY2hhbmdlUGxheVN0YXR1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMuZmlyc3RSZW5kZXIgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBUaW1lTGluZUludGVyYWN0aW9uLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMudGltZWxpbmUpIHtcbiAgICAgICAgICAgIHRoaXMudGltZWxpbmUuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy50aW1lbGluZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBUaW1lTGluZUludGVyYWN0aW9uO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGltZUxpbmVJbnRlcmFjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRpbWVsaW5lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5Ub29sdGlwSW5kaWNhdGlvbkFjdGlvbiA9IGV4cG9ydHMuVE9PTFRJUF9JTkRJQ0FUT1JfRVZFTlRTID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uL2RlcGVuZGVudHNcIik7XG52YXIgdG9vbHRpcF9pbmRpY2F0b3JfMSA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuLi9jb21wb25lbnRzL3Rvb2x0aXAtaW5kaWNhdG9yXCIpKTtcbnZhciB2aWV3XzEgPSByZXF1aXJlKFwiLi4vdXRpbC92aWV3XCIpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi91dGlsL2Jib3hcIikpO1xudmFyIERFRkFVTFRfUEFERElORyA9IDg7XG52YXIgZ2V0VmFsaWRUb29sdGlwSW5kaWNhdG9yQ29uZmlnID0gZnVuY3Rpb24gKGNmZykge1xuICAgIGlmIChjZmcgPT09IHZvaWQgMCkgeyBjZmcgPSB7fTsgfVxuICAgIHZhciBuZXdDZmcgPSB0c2xpYl8xLl9fYXNzaWduKHsgc2hvd1RvdGFsOiBmYWxzZSwgc2hvd1BlcmNlbnQ6IGZhbHNlLCBwYWRkaW5nOiBbREVGQVVMVF9QQURESU5HLCAyNCwgREVGQVVMVF9QQURESU5HLCAyNF0sIGhlaWdodDogY2ZnLnNob3dQZXJjZW50ID8gNzIgOiA1NCB9LCBjZmcpO1xuICAgIHJldHVybiBuZXdDZmc7XG59O1xudmFyIFRPT0xUSVBfSU5ESUNBVE9SX0VWRU5UUztcbihmdW5jdGlvbiAoVE9PTFRJUF9JTkRJQ0FUT1JfRVZFTlRTKSB7XG4gICAgVE9PTFRJUF9JTkRJQ0FUT1JfRVZFTlRTW1wiQUNUSVZFX0VMRU1FTlRcIl0gPSBcInRvb2x0aXBfaW5kaWNhdG9yX2FjdGl2ZV9lbGVtZW50XCI7XG4gICAgVE9PTFRJUF9JTkRJQ0FUT1JfRVZFTlRTW1wiQUNUSVZFX0VMRU1FTlRfQllfWFwiXSA9IFwidG9vbHRpcF9pbmRpY2F0b3JfYWN0aXZlX2VsZW1lbnRfYnlfeFwiO1xufSkoVE9PTFRJUF9JTkRJQ0FUT1JfRVZFTlRTID0gZXhwb3J0cy5UT09MVElQX0lORElDQVRPUl9FVkVOVFMgfHwgKGV4cG9ydHMuVE9PTFRJUF9JTkRJQ0FUT1JfRVZFTlRTID0ge30pKTtcbi8qKlxuICogVG9vbHRpcCBJbmRpY2F0b3IgQWN0aW9uIOWunueOsFxuICovXG52YXIgVG9vbHRpcEluZGljYXRpb25BY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVG9vbHRpcEluZGljYXRpb25BY3Rpb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVG9vbHRpcEluZGljYXRpb25BY3Rpb24oKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5zdGF0ZSA9ICdzZWxlY3RlZCc7XG4gICAgICAgIF90aGlzLmlzU2luZ2xlID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqIOS6pOS6kuivreazleinpuWPkeeCuSAqL1xuICAgIFRvb2x0aXBJbmRpY2F0aW9uQWN0aW9uLnByb3RvdHlwZS5hY3RpdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50ID0gZGVwZW5kZW50c18xLkludGVyYWN0aW9uVXRpbHMuZ2V0Q3VycmVudEVsZW1lbnQodGhpcy5jb250ZXh0KTtcbiAgICAgICAgaWYgKGVsZW1lbnQuaGFzU3RhdGUoJ3NlbGVjdGVkJykpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzU2luZ2xlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZUJ5WChlbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlQnlYKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog5Y2V5Liq5YWD57Sg55qEIGVuYWJsZSAqL1xuICAgIFRvb2x0aXBJbmRpY2F0aW9uQWN0aW9uLnByb3RvdHlwZS5zZXRTdGF0ZSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZpZXdfMS5mb3JFYWNoRWxlbWVudCh0aGlzLmdldFZpZXcoKSwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIGlmIChpdGVtID09PSBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtLmhhc1N0YXRlKF90aGlzLnN0YXRlKSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLnNldFN0YXRlKF90aGlzLnN0YXRlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdGVtLnNldFN0YXRlKF90aGlzLnN0YXRlLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlzU2luZ2xlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5nZXRWaWV3KCkuZW1pdChUT09MVElQX0lORElDQVRPUl9FVkVOVFMuQUNUSVZFX0VMRU1FTlQsIHsgZWxlbWVudDogZWxlbWVudCwgaXNTaW5nbGU6IHRydWUgfSk7XG4gICAgfTtcbiAgICAvKiog5ZCMIFgg55qE5YWD57Sg55qEIGVuYWJsZSAqL1xuICAgIFRvb2x0aXBJbmRpY2F0aW9uQWN0aW9uLnByb3RvdHlwZS5zZXRTdGF0ZUJ5WCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB4RmllbGQgPSB0aGlzLmdldFhGaWVsZCgpO1xuICAgICAgICB2YXIgeFZhbHVlID0gZWxlbWVudC5nZXREYXRhKClbeEZpZWxkXTtcbiAgICAgICAgdmlld18xLmZvckVhY2hFbGVtZW50KHRoaXMuZ2V0VmlldygpLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgaWYgKGl0ZW0uZ2V0RGF0YSgpW3hGaWVsZF0gPT09IHhWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICghaXRlbS5oYXNTdGF0ZShfdGhpcy5zdGF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5zZXRTdGF0ZShfdGhpcy5zdGF0ZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaXRlbS5zZXRTdGF0ZShfdGhpcy5zdGF0ZSwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pc1NpbmdsZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmdldFZpZXcoKS5lbWl0KFRPT0xUSVBfSU5ESUNBVE9SX0VWRU5UUy5BQ1RJVkVfRUxFTUVOVF9CWV9YLCB7IGVsZW1lbnQ6IGVsZW1lbnQsIGlzU2luZ2xlOiBmYWxzZSB9KTtcbiAgICB9O1xuICAgIC8qKiDpgJrov4flrZfmrrXlgLzmnaUgZW5hYmxlICovXG4gICAgVG9vbHRpcEluZGljYXRpb25BY3Rpb24ucHJvdG90eXBlLnNldFN0YXRlQnlGaWVsZCA9IGZ1bmN0aW9uICh4RmllbGRWYWx1ZSwgZ3JvdXBGaWVsZFZhbHVlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB4RmllbGQgPSB0aGlzLmdldFZpZXcoKS5nZXRYU2NhbGUoKS5maWVsZDtcbiAgICAgICAgdmFyIGdyb3VwRmllbGQgPSB0aGlzLmdldFZpZXcoKS5nZXRHcm91cFNjYWxlcygpWzBdLmZpZWxkO1xuICAgICAgICB2aWV3XzEuZm9yRWFjaEVsZW1lbnQodGhpcy5nZXRWaWV3KCksIGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IGVsZW1lbnQuZ2V0RGF0YSgpO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRTdGF0ZShfdGhpcy5zdGF0ZSwgZGF0YVt4RmllbGRdID09PSB4RmllbGRWYWx1ZSAmJiAoZ3JvdXBGaWVsZFZhbHVlID09PSB1bmRlZmluZWQgfHwgZGF0YVtncm91cEZpZWxkXSA9PT0gZ3JvdXBGaWVsZFZhbHVlKSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRpb25BY3Rpb24ucHJvdG90eXBlLmdldFZpZXcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudmlldztcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0aW9uQWN0aW9uLnByb3RvdHlwZS5nZXRYRmllbGQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5jb250ZXh0LnZpZXc7XG4gICAgICAgIHJldHVybiB2aWV3LmdldFhTY2FsZSgpLmZpZWxkO1xuICAgIH07XG4gICAgcmV0dXJuIFRvb2x0aXBJbmRpY2F0aW9uQWN0aW9uO1xufShkZXBlbmRlbnRzXzEuSW50ZXJhY3Rpb25BY3Rpb24pKTtcbmV4cG9ydHMuVG9vbHRpcEluZGljYXRpb25BY3Rpb24gPSBUb29sdGlwSW5kaWNhdGlvbkFjdGlvbjtcbmRlcGVuZGVudHNfMS5yZWdpc3RlckFjdGlvbigndG9vbHRpcC1pbmRpY2F0b3InLCBUb29sdGlwSW5kaWNhdGlvbkFjdGlvbik7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJJbnRlcmFjdGlvbignZWxlbWVudC10b29sdGlwLWluZGljYXRvcicsIHtcbiAgICBzdGFydDogW1xuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAnZWxlbWVudDptb3VzZW1vdmUnLFxuICAgICAgICAgICAgYWN0aW9uOiAndG9vbHRpcC1pbmRpY2F0b3I6YWN0aXZlJyxcbiAgICAgICAgICAgIHRocm90dGxlOiB7IHdhaXQ6IDUwLCBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2UgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ2VsZW1lbnQ6dG91Y2htb3ZlJyxcbiAgICAgICAgICAgIGFjdGlvbjogJ3Rvb2x0aXAtaW5kaWNhdG9yOmFjdGl2ZScsXG4gICAgICAgICAgICB0aHJvdHRsZTogeyB3YWl0OiA1MCwgbGVhZGluZzogdHJ1ZSwgdHJhaWxpbmc6IGZhbHNlIH0sXG4gICAgICAgIH0sXG4gICAgXSxcbn0pO1xuLyoqXG4gKiDnu4Tku7YgSW50ZXJhY3Rpb24g5a6e546wXG4gKi9cbnZhciBUb29sdGlwSW5kaWNhdG9ySW50ZXJhY3Rpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVG9vbHRpcEluZGljYXRvckludGVyYWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRvb2x0aXBJbmRpY2F0b3JJbnRlcmFjdGlvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLm9uRWxlbWVudEFjdGl2ZSA9IGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBfYS5lbGVtZW50LCBpc1NpbmdsZSA9IF9hLmlzU2luZ2xlO1xuICAgICAgICAgICAgdmFyIHhTY2FsZSA9IF90aGlzLnZpZXcuZ2V0WFNjYWxlKCk7XG4gICAgICAgICAgICB2YXIgeEZpZWxkID0gX3RoaXMudmlldy5nZXRYU2NhbGUoKS5maWVsZDtcbiAgICAgICAgICAgIHZhciBncm91cEZpZWxkID0gX3RoaXMudmlldy5nZXRHcm91cFNjYWxlcygpWzBdLmZpZWxkO1xuICAgICAgICAgICAgdmFyIGRhdGEgPSBlbGVtZW50LmdldERhdGEoKTtcbiAgICAgICAgICAgIHZhciB4VmFsdWUgPSBkYXRhW3hGaWVsZF07XG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBfdGhpcy5nZXRMZWdlbmRJdGVtcyh4VmFsdWUpO1xuICAgICAgICAgICAgX3RoaXMuY29tcG9uZW50LnVwZGF0ZSh7IGl0ZW1zOiBpdGVtcywgdGl0bGU6IHsgdGV4dDogeFNjYWxlLmdldFRleHQoeFZhbHVlKSB9IH0pO1xuICAgICAgICAgICAgX3RoaXMuY29tcG9uZW50LnJlbmRlcigpO1xuICAgICAgICAgICAgaWYgKGlzU2luZ2xlKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuY29tcG9uZW50LnNlbGVjdEl0ZW0oZGF0YVtncm91cEZpZWxkXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5jdXJYID0geFZhbHVlO1xuICAgICAgICB9O1xuICAgICAgICBfdGhpcy5vblNlbGVjdFRvb2x0aXBJbmRpY2F0b3JJdGVtID0gZnVuY3Rpb24gKGl0ZW1JZCkge1xuICAgICAgICAgICAgaWYgKF90aGlzLmNvbXBvbmVudCAmJiBpdGVtSWQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXRJbnRlcmFjdGlvbkFjdGlvbigpLnNldFN0YXRlQnlGaWVsZChfdGhpcy5jdXJYLCBpdGVtSWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRvb2x0aXBJbmRpY2F0b3JJbnRlcmFjdGlvbi5nZXRJbnRlcmFjdGlvblJhbmdlID0gZnVuY3Rpb24gKGxheWVyUmFuZ2UsIGludGVyYWN0aW9uKSB7XG4gICAgICAgIHZhciBjb25maWcgPSBnZXRWYWxpZFRvb2x0aXBJbmRpY2F0b3JDb25maWcoaW50ZXJhY3Rpb24pO1xuICAgICAgICB2YXIgX2EgPSBjb25maWcucGFkZGluZywgcGFkZGluZ1RvcCA9IF9hWzBdLCBwYWRkaW5nQm90dG9tID0gX2FbMl07XG4gICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQobGF5ZXJSYW5nZS5taW5YLCBsYXllclJhbmdlLm1pblksIGxheWVyUmFuZ2Uud2lkdGgsIGNvbmZpZy5oZWlnaHQgKyBwYWRkaW5nVG9wICsgcGFkZGluZ0JvdHRvbSk7XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9ySW50ZXJhY3Rpb24ucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb21wb25lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50LmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbXBvbmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3JJbnRlcmFjdGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMudmlldztcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHhTY2FsZSA9IF90aGlzLnZpZXcuZ2V0WFNjYWxlKCk7XG4gICAgICAgICAgICB2YXIgbGFzdFggPSB1dGlsXzEubGFzdCh4U2NhbGUuZ2V0VGlja3MoKSkudGlja1ZhbHVlO1xuICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSBfdGhpcy52aWV3LnBhZGRpbmc7XG4gICAgICAgICAgICBpZiAoIXV0aWxfMS5pc0VxdWFsKFswLCAwLCAwLCAwXSwgcGFkZGluZykpIHtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnVwZGF0ZUNvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuY3JlYXRlQ29tcG9uZW50KCk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNvbXBvbmVudC5vbih0b29sdGlwX2luZGljYXRvcl8xLkVWRU5UUy5PTl9TRUxFQ1RfSVRFTSwgX3RoaXMub25TZWxlY3RUb29sdGlwSW5kaWNhdG9ySXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOm7mOiupOmAieS4reacgOWQjueahCBYXG4gICAgICAgICAgICAgICAgX3RoaXMuY3VyWCA9IGxhc3RYO1xuICAgICAgICAgICAgICAgIF90aGlzLmNvbXBvbmVudC51cGRhdGUoe1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogeyB0ZXh0OiB4U2NhbGUuZ2V0VGV4dChfdGhpcy5jdXJYKSB9LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIF90aGlzLmNvbXBvbmVudC5yZW5kZXIoKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXRJbnRlcmFjdGlvbkFjdGlvbigpLnNldFN0YXRlQnlGaWVsZChsYXN0WCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8vIOenu+mZpOWGsueqgS/ph43lpI3nmoTnu4Tku7blkozkuqTkupJcbiAgICAgICAgdmlldy5sZWdlbmQoZmFsc2UpO1xuICAgICAgICB2aWV3LnJlbW92ZUludGVyYWN0aW9uKCdhY3RpdmUtcmVnaW9uJyk7XG4gICAgICAgIHZpZXcucmVtb3ZlSW50ZXJhY3Rpb24oJ3Rvb2x0aXAnKTtcbiAgICAgICAgdmlldy5pbnRlcmFjdGlvbignZWxlbWVudC10b29sdGlwLWluZGljYXRvcicpO1xuICAgICAgICAvLyDnm5HlkKwgVmlld++8jCDliJvlu7ov5pu05paw57uE5Lu2XG4gICAgICAgIHZpZXcub24oZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUEFJTlQsIGNhbGxiYWNrKTtcbiAgICAgICAgdmlldy5vbihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9SRU5ERVIsIGNhbGxiYWNrKTtcbiAgICAgICAgLy8g55uR5ZCs57uE5Lu25LqL5Lu277yM5pu05pawIGFjdGlvblxuICAgICAgICB2aWV3Lm9uKFRPT0xUSVBfSU5ESUNBVE9SX0VWRU5UUy5BQ1RJVkVfRUxFTUVOVCwgdGhpcy5vbkVsZW1lbnRBY3RpdmUpO1xuICAgICAgICB2aWV3Lm9uKFRPT0xUSVBfSU5ESUNBVE9SX0VWRU5UUy5BQ1RJVkVfRUxFTUVOVF9CWV9YLCB0aGlzLm9uRWxlbWVudEFjdGl2ZSk7XG4gICAgfTtcbiAgICBUb29sdGlwSW5kaWNhdG9ySW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldEludGVyYWN0aW9uQWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSB0aGlzLnZpZXcuaW50ZXJhY3Rpb25zWydlbGVtZW50LXRvb2x0aXAtaW5kaWNhdG9yJ107XG4gICAgICAgIHJldHVybiBpbnRlcmFjdGlvbiAmJiBpbnRlcmFjdGlvbi5jb250ZXh0LmdldEFjdGlvbigndG9vbHRpcC1pbmRpY2F0b3InKTtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3JJbnRlcmFjdGlvbi5wcm90b3R5cGUuY3JlYXRlQ29tcG9uZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcGFkZGluZyA9IGdldFZhbGlkVG9vbHRpcEluZGljYXRvckNvbmZpZyh0aGlzLmdldEludGVyYWN0aW9uQ29uZmlnKCkpLnBhZGRpbmc7XG4gICAgICAgIHZhciBwYWRkaW5nVG9wID0gcGFkZGluZ1swXSwgcGFkZGluZ1JpZ2h0ID0gcGFkZGluZ1sxXSwgcGFkZGluZ0JvdHRvbSA9IHBhZGRpbmdbMl0sIHBhZGRpbmdMZWZ0ID0gcGFkZGluZ1szXTtcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5nZXRMZWdlbmRJdGVtcygpO1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7XG4gICAgICAgIHZhciB4U2NhbGUgPSB0aGlzLnZpZXcuZ2V0WFNjYWxlKCk7XG4gICAgICAgIHZhciBsYXN0WCA9IHV0aWxfMS5sYXN0KHhTY2FsZS5nZXRUaWNrcygpKS50aWNrVmFsdWU7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gdGhpcy5jYW52YXMuYWRkR3JvdXAoKTtcbiAgICAgICAgdGhpcy5jb21wb25lbnQgPSBuZXcgdG9vbHRpcF9pbmRpY2F0b3JfMS5kZWZhdWx0KHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5jb250YWluZXIsXG4gICAgICAgICAgICB4OiByYW5nZS54ICsgcGFkZGluZ0xlZnQsXG4gICAgICAgICAgICB5OiByYW5nZS55ICsgcGFkZGluZ1RvcCxcbiAgICAgICAgICAgIHdpZHRoOiByYW5nZS53aWR0aCAtIHBhZGRpbmdMZWZ0IC0gcGFkZGluZ1JpZ2h0LFxuICAgICAgICAgICAgaGVpZ2h0OiByYW5nZS5oZWlnaHQgLSBwYWRkaW5nVG9wIC0gcGFkZGluZ0JvdHRvbSxcbiAgICAgICAgICAgIHRoZW1lOiB0aGlzLmdldFZpZXdMYXllcigpLmdldFBsb3RUaGVtZSgpLFxuICAgICAgICAgICAgaXRlbXM6IGl0ZW1zLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jb21wb25lbnQuaW5pdCgpO1xuICAgICAgICB0aGlzLmdldEludGVyYWN0aW9uQWN0aW9uKCkuc2V0U3RhdGVCeUZpZWxkKGxhc3RYKTtcbiAgICB9O1xuICAgIFRvb2x0aXBJbmRpY2F0b3JJbnRlcmFjdGlvbi5wcm90b3R5cGUudXBkYXRlQ29tcG9uZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLmdldExlZ2VuZEl0ZW1zKCk7XG4gICAgICAgIHRoaXMuY29tcG9uZW50LnVwZGF0ZSh7XG4gICAgICAgICAgICBpdGVtczogaXRlbXMsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVG9vbHRpcEluZGljYXRvckludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRMZWdlbmRJdGVtcyA9IGZ1bmN0aW9uICh4VmFsdWUpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZhciBkYXRhID0gdmlldy5nZXREYXRhKCk7XG4gICAgICAgIHZhciBkZWZhdWx0Q29sb3IgPSB2aWV3LmdldFRoZW1lKCkuZGVmYXVsdENvbG9yO1xuICAgICAgICB2YXIgeFNjYWxlID0gdmlldy5nZXRYU2NhbGUoKTtcbiAgICAgICAgdmFyIHlTY2FsZSA9IHZpZXcuZ2V0WVNjYWxlcygpWzBdO1xuICAgICAgICB2YXIgY3VyWCA9IHhWYWx1ZSB8fCB1dGlsXzEubGFzdCh4U2NhbGUuZ2V0VGlja3MoKSkudGlja1ZhbHVlO1xuICAgICAgICB2YXIgZ3JvdXBBdHRycyA9IHZpZXcuZ2V0TGVnZW5kQXR0cmlidXRlcygpO1xuICAgICAgICB2YXIgY29sb3JBdHRyID0gZ3JvdXBBdHRycy5maW5kKGZ1bmN0aW9uIChhdHRyKSB7IHJldHVybiBhdHRyLnR5cGUgPT09ICdjb2xvcic7IH0pO1xuICAgICAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICAgICAgLy8g5Y+W56ys5LiA5Liq5YiG57uEc2NhbGXvvIzmmoLkuI3ogIPomZHlpJrkuKrliIbnu4Tmg4XlhrVcbiAgICAgICAgdmFyIGdyb3VwU2NhbGUgPSB2aWV3LmdldEdyb3VwU2NhbGVzKClbMF07XG4gICAgICAgIHZhciBncm91cEZpZWxkID0gZ3JvdXBTY2FsZS5maWVsZDtcbiAgICAgICAgaWYgKGdyb3VwU2NhbGUgJiYgZ3JvdXBTY2FsZS5pc0NhdGVnb3J5KSB7XG4gICAgICAgICAgICAvLyDlj6rlpITnkIbnprvmlaPmg4XlhrVcbiAgICAgICAgICAgIGdyb3VwU2NhbGUuZ2V0VGlja3MoKS5mb3JFYWNoKGZ1bmN0aW9uICh0aWNrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5hbWUgPSB0aWNrLnRleHQsIHZhbHVlID0gdGljay50aWNrVmFsdWU7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9yID0gY29sb3JBdHRyLm1hcHBpbmcodmFsdWUpLmpvaW4oJycpIHx8IGRlZmF1bHRDb2xvcjtcbiAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgY29sb3I6IGNvbG9yLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNlbGVjdGVkRGF0YSA9IChkYXRhID09PSBudWxsIHx8IGRhdGEgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRhdGEuZmlsdGVyKGZ1bmN0aW9uIChkYXR1bSkgeyByZXR1cm4gZGF0dW1beFNjYWxlLmZpZWxkXSA9PT0gY3VyWDsgfSkpIHx8IFtdO1xuICAgICAgICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgZGF0dW0gPSBzZWxlY3RlZERhdGEuZmluZChmdW5jdGlvbiAoY3VyRGF0dW0pIHsgcmV0dXJuIGN1ckRhdHVtW2dyb3VwRmllbGRdID09PSBpdGVtLmlkOyB9KTtcbiAgICAgICAgICAgIGl0ZW0udmFsdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIHZhbHVlOiB5U2NhbGUuZm9ybWF0dGVyID8geVNjYWxlLmZvcm1hdHRlcihkYXR1bVt5U2NhbGUuZmllbGRdKSA6IGRhdHVtW3lTY2FsZS5maWVsZF0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBpdGVtcztcbiAgICB9O1xuICAgIHJldHVybiBUb29sdGlwSW5kaWNhdG9ySW50ZXJhY3Rpb247XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUb29sdGlwSW5kaWNhdG9ySW50ZXJhY3Rpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD10b29sdGlwLWluZGljYXRvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMudGltZUludGVydmFscyA9IHZvaWQgMDtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vZGVwZW5kZW50c1wiKTtcbnZhciBTRUNPTkQgPSAxMDAwO1xudmFyIE1JTlVURSA9IDYwICogU0VDT05EO1xudmFyIEhPVVIgPSA2MCAqIE1JTlVURTtcbnZhciBEQVkgPSAyNCAqIEhPVVI7XG52YXIgV0VFSyA9IERBWSAqIDc7XG52YXIgTU9OVEggPSBEQVkgKiAzMDtcbnZhciBZRUFSID0gREFZICogMzY1O1xuZXhwb3J0cy50aW1lSW50ZXJ2YWxzID0ge1xuICAgIHNlY29uZDogeyB2YWx1ZTogU0VDT05ELCBmb3JtYXQ6ICdISDptbTpzcycgfSxcbiAgICBtaW5pdXRlOiB7IHZhbHVlOiBNSU5VVEUsIGZvcm1hdDogJ0hIOm1tJyB9LFxuICAgIGhvdXI6IHsgdmFsdWU6IEhPVVIsIGZvcm1hdDogJ0hIJyB9LFxuICAgIGRheTogeyB2YWx1ZTogREFZLCBmb3JtYXQ6ICdZWVlZLU1NLUREJyB9LFxuICAgIHdlZWs6IHsgdmFsdWU6IFdFRUssIGZvcm1hdDogJ1lZWVktTU0tREQnIH0sXG4gICAgbW9udGg6IHsgdmFsdWU6IE1PTlRILCBmb3JtYXQ6ICdZWVlZLU1NJyB9LFxuICAgIHllYXI6IHsgdmFsdWU6IFlFQVIsIGZvcm1hdDogJ1lZWVknIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uZmlnLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYXhpc18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvcmVzcG9uc2l2ZS9hcHBseS9heGlzXCIpKTtcbmZ1bmN0aW9uIHJlc3BvbnNpdmVBeGlzKGxheWVyKSB7XG4gICAgdmFyIHJlc3BvbnNpdmVUaGVtZSA9IGxheWVyLmdldFJlc3BvbnNpdmVUaGVtZSgpO1xuICAgIHZhciBjYW52YXMgPSBsYXllci5jYW52YXM7XG4gICAgLy8geC1heGlzXG4gICAgbmV3IGF4aXNfMS5kZWZhdWx0KHtcbiAgICAgICAgcGxvdDogbGF5ZXIsXG4gICAgICAgIHJlc3BvbnNpdmVUaGVtZTogcmVzcG9uc2l2ZVRoZW1lLFxuICAgICAgICBkaW06ICd4JyxcbiAgICB9KTtcbiAgICAvLyB5LWF4aXNcbiAgICBuZXcgYXhpc18xLmRlZmF1bHQoe1xuICAgICAgICBwbG90OiBsYXllcixcbiAgICAgICAgcmVzcG9uc2l2ZVRoZW1lOiByZXNwb25zaXZlVGhlbWUsXG4gICAgICAgIGRpbTogJ3knLFxuICAgIH0pO1xuICAgIGNhbnZhcy5kcmF3KCk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSByZXNwb25zaXZlQXhpcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF4aXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBheGlzXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9heGlzXCIpKTtcbnZhciBwcmVSZW5kZXJSZXNwb25zaXZlID0gW107XG52YXIgYWZ0ZXJSZW5kZXJSZXNwb25zaXZlID0gW3sgbmFtZTogJ3Jlc3BvbnNpdmVBeGlzJywgbWV0aG9kOiBheGlzXzEuZGVmYXVsdCB9XTtcbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICBwcmVSZW5kZXI6IHByZVJlbmRlclJlc3BvbnNpdmUsXG4gICAgYWZ0ZXJSZW5kZXI6IGFmdGVyUmVuZGVyUmVzcG9uc2l2ZSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgcG9pbnRfYXV0b18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uLy4uL2NvbXBvbmVudHMvbGFiZWwvcG9pbnQtYXV0b1wiKSk7XG52YXIgdmlld18xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL3V0aWwvdmlld1wiKTtcbnZhciBtYXRoXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vLi4vdXRpbC9tYXRoXCIpO1xudmFyIGNvbG9yXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vLi4vdXRpbC9jb2xvclwiKTtcbnZhciBBcmVhUG9pbnRBdXRvTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQXJlYVBvaW50QXV0b0xhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEFyZWFQb2ludEF1dG9MYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBBcmVhUG9pbnRBdXRvTGFiZWwucHJvdG90eXBlLmxheW91dExhYmVscyA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgbGFiZWxzKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUubGF5b3V0TGFiZWxzLmNhbGwodGhpcywgZ2VvbWV0cnksIGxhYmVscyk7XG4gICAgICAgIHRoaXMuYWRqdXN0QXJlYUxhYmVsc1N0eWxlKGxhYmVscyk7XG4gICAgfTtcbiAgICBBcmVhUG9pbnRBdXRvTGFiZWwucHJvdG90eXBlLmFkanVzdEFyZWFMYWJlbHNTdHlsZSA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgZGFya1N0eWxlID0gX2EuZGFya1N0eWxlLCBsaWdodFN0eWxlID0gX2EubGlnaHRTdHlsZTtcbiAgICAgICAgdmFyIGFyZWFHZW9tZXRyeSA9IHZpZXdfMS5nZXRHZW9tZXRyeUJ5VHlwZSh2aWV3LCAnYXJlYScpO1xuICAgICAgICB2YXIgYXJlYXMgPSB2aWV3XzEuZ2V0R2VvbWV0cnlTaGFwZXMoYXJlYUdlb21ldHJ5KS5zb3J0KGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xuICAgICAgICAgICAgcmV0dXJuIHJpZ2h0LmdldEJCb3goKS5oZWlnaHQgLSBsZWZ0LmdldEJCb3goKS5oZWlnaHQ7XG4gICAgICAgIH0pO1xuICAgICAgICB1dGlsXzEuZWFjaChsYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICAgICAgdmFyIGxhYmVsQkJveCA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciBwb2ludHMgPSBtYXRoXzEuZ2V0U3Ryb2tlUG9pbnRzKGxhYmVsQkJveC54LCBsYWJlbEJCb3gueSwgbGFiZWxCQm94LndpZHRoLCBsYWJlbEJCb3guaGVpZ2h0KTtcbiAgICAgICAgICAgIHZhciBtYXRjaCA9IHV0aWxfMS5tYXAoYXJlYXMsIGZ1bmN0aW9uIChhcmVhKSB7IHJldHVybiAoe1xuICAgICAgICAgICAgICAgIGFyZWE6IGFyZWEsXG4gICAgICAgICAgICAgICAgbWF0Y2hlczogdXRpbF8xLmZpbHRlcihwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkgeyByZXR1cm4gISFhcmVhLmlzSGl0KHBvaW50WzBdLCBwb2ludFsxXSk7IH0pLmxlbmd0aCxcbiAgICAgICAgICAgIH0pOyB9KS5zb3J0KGZ1bmN0aW9uIChsZWZ0LCByaWdodCkgeyByZXR1cm4gbGVmdC5tYXRjaGVzIC0gcmlnaHQubWF0Y2hlczsgfSk7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmxhc3QobWF0Y2gpLm1hdGNoZXMgPiAwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJnQ29sb3IgPSB1dGlsXzEubGFzdChtYXRjaCkuYXJlYS5hdHRyKCdmaWxsJyk7XG4gICAgICAgICAgICAgICAgdmFyIGZpbGxXaGl0ZSA9IGNvbG9yXzEuaXNDb250cmFzdENvbG9yV2hpdGUoYmdDb2xvcik7XG4gICAgICAgICAgICAgICAgbGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IGZpbGxXaGl0ZSA/IGxpZ2h0U3R5bGUgPT09IG51bGwgfHwgbGlnaHRTdHlsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGlnaHRTdHlsZS5maWxsIDogZGFya1N0eWxlID09PSBudWxsIHx8IGRhcmtTdHlsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogZGFya1N0eWxlLmZpbGwsXG4gICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBmaWxsV2hpdGUgPyBsaWdodFN0eWxlLmZpbGxPcGFjaXR5IDogZGFya1N0eWxlLmZpbGxPcGFjaXR5LFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6IGZpbGxXaGl0ZSA/IGxpZ2h0U3R5bGUgPT09IG51bGwgfHwgbGlnaHRTdHlsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGlnaHRTdHlsZS5zdHJva2UgOiBkYXJrU3R5bGUgPT09IG51bGwgfHwgZGFya1N0eWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkYXJrU3R5bGUuc3Ryb2tlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBBcmVhUG9pbnRBdXRvTGFiZWw7XG59KHBvaW50X2F1dG9fMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBcmVhUG9pbnRBdXRvTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnYXJlYS1wb2ludC1hdXRvJywgQXJlYVBvaW50QXV0b0xhYmVsKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFyZWEtcG9pbnQtYXV0by5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgcG9pbnRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL3BvaW50XCIpKTtcbnZhciBBcmVhUG9pbnRMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhBcmVhUG9pbnRMYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBcmVhUG9pbnRMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICByZXR1cm4gQXJlYVBvaW50TGFiZWw7XG59KHBvaW50XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJlYVBvaW50TGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnYXJlYS1wb2ludCcsIEFyZWFQb2ludExhYmVsKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFyZWEtcG9pbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBhcmVhOiAnYXJlYScsXG4gICAgbGluZTogJ2xpbmUnLFxuICAgIHBvaW50OiAncG9pbnQnLFxufTtcbnZhciBTSEFQRV9FVkVOVF9NQVAgPSBldmVudF8xLmdldEV2ZW50TWFwKGNvbXBvbmVudE1hcCk7XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIEFyZWEgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQXJlYSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBcmVhKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEFyZWEucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdhcmVhJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEFyZWEuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIEFyZWE7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBcmVhO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbC9hcmVhLXBvaW50XCIpO1xucmVxdWlyZShcIi4vY29tcG9uZW50L2xhYmVsL2FyZWEtcG9pbnQtYXV0b1wiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvc2NhbGVcIik7XG52YXIgYXBwbHlfcmVzcG9uc2l2ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYXBwbHktcmVzcG9uc2l2ZVwiKSk7XG52YXIgRXZlbnRQYXJzZXIgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi9ldmVudFwiKSk7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnZhciB2aWV3XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC92aWV3XCIpO1xudmFyIEdFT01fTUFQID0ge1xuICAgIGFyZWE6ICdhcmVhJyxcbiAgICBsaW5lOiAnbGluZScsXG4gICAgcG9pbnQ6ICdwb2ludCcsXG59O1xudmFyIEFyZWFMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhBcmVhTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQXJlYUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdhcmVhJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBBcmVhTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHNtb290aDogZmFsc2UsXG4gICAgICAgICAgICBhcmVhU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjI1LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNpemU6IDIsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMSxcbiAgICAgICAgICAgICAgICAgICAgbGluZUpvaW46ICdyb3VuZCcsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVDYXA6ICdyb3VuZCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwb2ludDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNpemU6IDQsXG4gICAgICAgICAgICAgICAgc2hhcGU6ICdwb2ludCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiAncG9pbnQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICd0b3AtbGVmdCcsXG4gICAgICAgICAgICAgICAgd29yZFNwYWNpbmc6IDQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hhcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNob3dDcm9zc2hhaXJzOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNyb3NzaGFpcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3gnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAyMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQXJlYUxheWVyLnByb3RvdHlwZS5iZWZvcmVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmJlZm9yZUluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgLyoqIOWTjeW6lOW8j+WbvuW9oiAqL1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUgJiYgdGhpcy5vcHRpb25zLnBhZGRpbmcgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5hcHBseVJlc3BvbnNpdmUoJ3ByZVJlbmRlcicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBcmVhTGF5ZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlbmRlckxhYmVsKCk7XG4gICAgICAgIC8qKiDlk43lupTlvI8gKi9cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZXNwb25zaXZlICYmIHRoaXMub3B0aW9ucy5wYWRkaW5nICE9PSAnYXV0bycpIHtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlSZXNwb25zaXZlKCdhZnRlclJlbmRlcicpO1xuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoZGltLCB0eXBlKSB7XG4gICAgICAgIHJldHVybiBHRU9NX01BUFt0eXBlXTtcbiAgICB9O1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHNjYWxlcyA9IHt9O1xuICAgICAgICAvKiog6YWN572ueC1zY2FsZSAqL1xuICAgICAgICBzY2FsZXNbcHJvcHMueEZpZWxkXSA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdjYXQnLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhwcm9wcywgJ3hBeGlzJykpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlc1twcm9wcy54RmllbGRdLCBwcm9wcy54QXhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rnktc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW3Byb3BzLnlGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICd5QXhpcycpKSB7XG4gICAgICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXNbcHJvcHMueUZpZWxkXSwgcHJvcHMueUF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBBcmVhTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGFyZWEgPSBmYWN0b3J5XzEuZ2V0R2VvbSgnYXJlYScsICdtYWluJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXJlYSA9IGFyZWE7XG4gICAgICAgIGlmIChwcm9wcy5sYWJlbCkge1xuICAgICAgICAgICAgdGhpcy5sYWJlbCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy50b29sdGlwICYmIChwcm9wcy50b29sdGlwLmZpZWxkcyB8fCBwcm9wcy50b29sdGlwLmZvcm1hdHRlcikpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VvbWV0cnlUb29sdGlwKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGp1c3RBcmVhKGFyZWEpO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBhcmVhKTtcbiAgICAgICAgdGhpcy5hZGRMaW5lKCk7XG4gICAgICAgIHRoaXMuYWRkUG9pbnQoKTtcbiAgICB9O1xuICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUuYWRqdXN0QXJlYSA9IGZ1bmN0aW9uIChhcmVhKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUuYWRqdXN0TGluZSA9IGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUuYWRqdXN0UG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgQXJlYUxheWVyLnByb3RvdHlwZS5hZGRMaW5lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBsaW5lQ29uZmlnID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzLmxpbmUpO1xuICAgICAgICBpZiAobGluZUNvbmZpZy52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgbGluZSA9IGZhY3RvcnlfMS5nZXRHZW9tKCdsaW5lJywgJ2d1aWRlJywge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgICAgIGxpbmU6IGxpbmVDb25maWcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuYWRqdXN0TGluZShsaW5lKTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIGxpbmUpO1xuICAgICAgICAgICAgdGhpcy5saW5lID0gbGluZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQXJlYUxheWVyLnByb3RvdHlwZS5hZGRQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgcG9pbnRDb25maWcgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMucG9pbnQpO1xuICAgICAgICBpZiAocG9pbnRDb25maWcudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIHBvaW50ID0gZmFjdG9yeV8xLmdldEdlb20oJ3BvaW50JywgJ2d1aWRlJywge1xuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuYWRqdXN0UG9pbnQocG9pbnQpO1xuICAgICAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5JywgcG9pbnQpO1xuICAgICAgICAgICAgdGhpcy5wb2ludCA9IHBvaW50O1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBcmVhTGF5ZXIucHJvdG90eXBlLnJlbmRlckxhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2NhbGVzID0gdGhpcy5jb25maWcuc2NhbGVzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIGxhYmVsID0gX2EubGFiZWwsIHlGaWVsZCA9IF9hLnlGaWVsZDtcbiAgICAgICAgdmFyIHNjYWxlID0gc2NhbGVzW3lGaWVsZF07XG4gICAgICAgIGlmIChsYWJlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnkgPSB2aWV3XzEuZ2V0R2VvbWV0cnlCeVR5cGUodGhpcy52aWV3LCAnYXJlYScpO1xuICAgICAgICAgICAgdGhpcy5kb1JlbmRlckxhYmVsKGdlb21ldHJ5LCB0c2xpYl8xLl9fYXNzaWduKHsgdHlwZTogJ2FyZWEtcG9pbnQnLCBmb3JtYXR0ZXI6IHNjYWxlLmZvcm1hdHRlciAmJiAoZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBzY2FsZS5mb3JtYXR0ZXIodmFsdWUpOyB9KSB9LCB0aGlzLm9wdGlvbnMubGFiZWwpKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQXJlYUxheWVyLnByb3RvdHlwZS5hbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYW5pbWF0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8vIOWFs+mXreWKqOeUu1xuICAgICAgICAgICAgdGhpcy5hcmVhLmFuaW1hdGUgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxpbmUpXG4gICAgICAgICAgICAgICAgdGhpcy5saW5lLmFuaW1hdGUgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh0aGlzLnBvaW50KVxuICAgICAgICAgICAgICAgIHRoaXMucG9pbnQuYW5pbWF0ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBcmVhTGF5ZXIucHJvdG90eXBlLmxhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBBcmVhTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hcmVhLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIHRoaXMuYXJlYS50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLmFyZWEudG9vbHRpcC5jYWxsYmFjayA9IHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgIGlmICghdG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmVhLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2VyaWVzRmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcmVhLnRvb2x0aXAuZmllbGRzLnB1c2godGhpcy5vcHRpb25zLnNlcmllc0ZpZWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEFyZWFMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBFdmVudFBhcnNlcik7XG4gICAgfTtcbiAgICBBcmVhTGF5ZXIucHJvdG90eXBlLmFwcGx5UmVzcG9uc2l2ZSA9IGZ1bmN0aW9uIChzdGFnZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbWV0aG9kcyA9IGFwcGx5X3Jlc3BvbnNpdmVfMS5kZWZhdWx0W3N0YWdlXTtcbiAgICAgICAgdXRpbF8xLmVhY2gobWV0aG9kcywgZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgIHZhciByZXNwb25zaXZlID0gcjtcbiAgICAgICAgICAgIHJlc3BvbnNpdmUubWV0aG9kKF90aGlzKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQXJlYUxheWVyO1xufSh2aWV3X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJlYUxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnYXJlYScsIEFyZWFMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuREVGQVVMVF9BUkVBX1RIRU1FID0gdm9pZCAwO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vLi4vdGhlbWVcIik7XG52YXIgQVJFQV9BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5IH07XG59O1xudmFyIEFSRUFfRElTQUJMRV9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IG9wYWNpdHk6IG9wYWNpdHkgKiAwLjUgfTtcbn07XG52YXIgTElORV9BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5IH07XG59O1xudmFyIExJTkVfRElTQUJMRV9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IG9wYWNpdHk6IG9wYWNpdHkgKiAwLjUgfTtcbn07XG52YXIgTElORV9TRUxFQ1RFRF9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBsaW5lV2lkdGggPSBzdHlsZS5saW5lV2lkdGggfHwgMTtcbiAgICByZXR1cm4geyBsaW5lV2lkdGg6IGxpbmVXaWR0aCArIDIgfTtcbn07XG52YXIgUE9JTlRfQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIGNvbG9yID0gc3R5bGUuZmlsbCB8fCBzdHlsZS5maWxsU3R5bGU7XG4gICAgdmFyIHJhZGl1cyA9IHN0eWxlLnNpemUgfHwgc3R5bGUucmFkaXVzO1xuICAgIHJldHVybiB7XG4gICAgICAgIHJhZGl1czogcmFkaXVzICsgMSxcbiAgICAgICAgc2hhZG93Qmx1cjogcmFkaXVzLFxuICAgICAgICBzaGFkb3dDb2xvcjogY29sb3IsXG4gICAgICAgIHN0cm9rZTogY29sb3IsXG4gICAgICAgIHN0cm9rZU9wYWNpdHk6IDEsXG4gICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICB9O1xufTtcbnZhciBQT0lOVF9TRUxFQ1RFRF9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBjb2xvciA9IHN0eWxlLmZpbGwgfHwgc3R5bGUuZmlsbFN0eWxlO1xuICAgIHZhciByYWRpdXMgPSBzdHlsZS5zaXplIHx8IHN0eWxlLnJhZGl1cztcbiAgICByZXR1cm4ge1xuICAgICAgICByYWRpdXM6IHJhZGl1cyArIDIsXG4gICAgICAgIHNoYWRvd0JsdXI6IHJhZGl1cyxcbiAgICAgICAgc2hhZG93Q29sb3I6IGNvbG9yLFxuICAgICAgICBzdHJva2U6IGNvbG9yLFxuICAgICAgICBzdHJva2VPcGFjaXR5OiAxLFxuICAgICAgICBsaW5lV2lkdGg6IDIsXG4gICAgfTtcbn07XG52YXIgUE9JTlRfRElTQUJMRURfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgc3R5bGUuZmlsbE9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5ICogMC41IH07XG59O1xuZXhwb3J0cy5ERUZBVUxUX0FSRUFfVEhFTUUgPSB7XG4gICAgYXJlYVN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogQVJFQV9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IEFSRUFfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IHsgbGluZVdpZHRoOiAxLCBzdHJva2U6ICcjMzMzMzMzJyB9LFxuICAgIH0sXG4gICAgbGluZVN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogTElORV9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IExJTkVfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IExJTkVfU0VMRUNURURfU1RZTEUsXG4gICAgfSxcbiAgICBwb2ludFN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogUE9JTlRfQUNUSVZFX1NUWUxFLFxuICAgICAgICBkaXNhYmxlOiBQT0lOVF9ESVNBQkxFRF9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IFBPSU5UX1NFTEVDVEVEX1NUWUxFLFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgZGFya1N0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAnIzJjMzU0MicsXG4gICAgICAgICAgICBzdHJva2U6ICcjZmZmZmZmJyxcbiAgICAgICAgICAgIGZpbGxPcGFjaXR5OiAwLjg1LFxuICAgICAgICB9LFxuICAgICAgICBsaWdodFN0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAnI2ZmZmZmZicsXG4gICAgICAgICAgICBmaWxsT3BhY2l0eTogMSxcbiAgICAgICAgICAgIHN0cm9rZTogJyMyYzM1NDInLFxuICAgICAgICB9LFxuICAgIH0sXG59O1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdhcmVhJywgZXhwb3J0cy5ERUZBVUxUX0FSRUFfVEhFTUUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vY29tcG9uZW50cy9sYWJlbC9iYXNlXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIGxhYmVsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYWJlbFwiKSk7XG52YXIgdmlld18xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvdmlld1wiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9iYm94XCIpKTtcbnZhciBjb2xvcl8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvY29sb3JcIik7XG4vKiog6Ieq5Yqo5qih5byP55qEIENvbHVtbiDmlbDmja7moIfnrb7vvIzkvJrmoLnmja7lm77lvaLlkozmlbDmja7moIfnrb7oh6rliqjkvJjljJbmlbDmja7moIfnrb7luIPlsYDlkozmoLflvI/nrYkgKi9cbnZhciBCYXJBdXRvTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQmFyQXV0b0xhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhckF1dG9MYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBCYXJBdXRvTGFiZWwucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMuZ2V0RGVmYXVsdE9mZnNldCgpO1xuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKGVsZW1lbnQpO1xuICAgICAgICB2YXIgYmJveCA9IHRoaXMuZ2V0RWxlbWVudFNoYXBlQkJveChlbGVtZW50KTtcbiAgICAgICAgdmFyIG1pblggPSBiYm94Lm1pblgsIG1heFggPSBiYm94Lm1heFgsIG1pblkgPSBiYm94Lm1pblksIGhlaWdodCA9IGJib3guaGVpZ2h0O1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIG9mZnNldFggPSBfYS5vZmZzZXRYLCBvZmZzZXRZID0gX2Eub2Zmc2V0WTtcbiAgICAgICAgdmFyIHkgPSBtaW5ZICsgaGVpZ2h0IC8gMiArIG9mZnNldFk7XG4gICAgICAgIHZhciBkaXIgPSB2YWx1ZSA8IDAgPyAtMSA6IDE7XG4gICAgICAgIHZhciByb290ID0gdmFsdWUgPiAwID8gbWF4WCA6IG1pblg7XG4gICAgICAgIHZhciB4ID0gcm9vdCArIG9mZnNldCAqIGRpciArIG9mZnNldFg7XG4gICAgICAgIC8vIOe7n+S4gOWFiOiuvue9ruS4uiByaWdodFxuICAgICAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG4gICAgfTtcbiAgICBCYXJBdXRvTGFiZWwucHJvdG90eXBlLmdldFRleHRBbGlnbiA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiB2YWx1ZSA+IDAgPyAnbGVmdCcgOiAncmlnaHQnO1xuICAgIH07XG4gICAgLyoqIOm7mOiupOeahCBmaWxsIOWPluiHqueUqOaIt+mFjee9ruaIluS4u+mimOmFjee9riAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBCYXJBdXRvTGFiZWwucHJvdG90eXBlLmdldFRleHRGaWxsID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5vcHRpb25zLnN0eWxlO1xuICAgICAgICByZXR1cm4gc3R5bGUuZmlsbDtcbiAgICB9O1xuICAgIC8qKiDpu5jorqTkuI3mj4/ovrkgKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgQmFyQXV0b0xhYmVsLnByb3RvdHlwZS5nZXRUZXh0U3Ryb2tlID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9O1xuICAgIC8qKiDpu5jorqTml6DlpITnkIbvvJrlnKggbGF5b3V0IOmYtuauteWkhOeQhiAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBCYXJBdXRvTGFiZWwucHJvdG90eXBlLmFkanVzdExhYmVsID0gZnVuY3Rpb24gKGxhYmVsLCBlbGVtZW50KSB7XG4gICAgICAgIC8vIGVtcHR5XG4gICAgfTtcbiAgICAvKiog6Ieq5Yqo5biD5bGA5omA5pyJ55qE5pWw5o2u5qCH562+ICovXG4gICAgQmFyQXV0b0xhYmVsLnByb3RvdHlwZS5sYXlvdXRMYWJlbHMgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGxhYmVscykge1xuICAgICAgICBpZiAodGhpcy5zaG91bGRJblNoYXBlTGFiZWxzKGxhYmVscykpIHtcbiAgICAgICAgICAgIHRoaXMuaW5TaGFwZUxhYmVscyhnZW9tZXRyeSwgbGFiZWxzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmF1dG9IaWRlTGFiZWxzKGdlb21ldHJ5LCBsYWJlbHMpO1xuICAgIH07XG4gICAgLyoqIOWIpOaWreaYr+WQpuWPr+S7peaKiuaVsOaNruagh+etvuaUvue9ruWcqOafseWtkOWGhemDqCAqL1xuICAgIEJhckF1dG9MYWJlbC5wcm90b3R5cGUuc2hvdWxkSW5TaGFwZUxhYmVscyA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5ldmVyeShsYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICAgICAgdmFyIGxhYmVsQkJveCA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciBlbGVtZW50ID0gbGFiZWwuZ2V0KCdlbGVtZW50Jyk7XG4gICAgICAgICAgICB2YXIgYmJveCA9IF90aGlzLmdldEVsZW1lbnRTaGFwZUJCb3goZWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm4gYmJveC5oZWlnaHQgPj0gbGFiZWxCQm94LmhlaWdodDtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKiog5YaF572u5pWw5o2u5qCH562+77yM5bm26Ieq5Yqo6K6+572u6aKc6Imy5o+P6L65562J5bGe5oCnICovXG4gICAgQmFyQXV0b0xhYmVsLnByb3RvdHlwZS5pblNoYXBlTGFiZWxzID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBsYWJlbHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNvb3JkaW5hdGVCQm94ID0gdGhpcy5nZXRDb29yZGluYXRlQkJveCgpO1xuICAgICAgICB2YXIgeEZpZWxkID0gZ2VvbWV0cnkuZ2V0WFlGaWVsZHMoKVswXTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBkYXJrU3R5bGUgPSBfYS5kYXJrU3R5bGUsIGxpZ2h0U3R5bGUgPSBfYS5saWdodFN0eWxlO1xuICAgICAgICB2YXIgZ3JvdXBlZExhYmVscyA9IHV0aWxfMS5ncm91cEJ5KGxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7IHJldHVybiBsYWJlbC5nZXQoZGVwZW5kZW50c18xLk9SSUdJTilbZGVwZW5kZW50c18xLkZJRUxEX09SSUdJTl1beEZpZWxkXTsgfSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICB2YXIgY3VyR3JvdXAgPSBncm91cGVkTGFiZWxzW2xhYmVsLmdldChkZXBlbmRlbnRzXzEuT1JJR0lOKVtkZXBlbmRlbnRzXzEuRklFTERfT1JJR0lOXVt4RmllbGRdXSB8fCBbXTtcbiAgICAgICAgICAgIHZhciBlbGVtZW50ID0gbGFiZWwuZ2V0KCdlbGVtZW50Jyk7XG4gICAgICAgICAgICB2YXIgc2hhcGUgPSBlbGVtZW50LnNoYXBlO1xuICAgICAgICAgICAgdmFyIGZpbGxXaGl0ZSA9IGNvbG9yXzEuaXNDb250cmFzdENvbG9yV2hpdGUoc2hhcGUuYXR0cignZmlsbCcpKTtcbiAgICAgICAgICAgIHZhciBzaGFwZUJCb3ggPSBfdGhpcy5nZXRFbGVtZW50U2hhcGVCQm94KGVsZW1lbnQpO1xuICAgICAgICAgICAgdmFyIGxhYmVsQkJveCA9IGJib3hfMS5kZWZhdWx0LmZyb21CQm94T2JqZWN0KGxhYmVsLmdldEJCb3goKSk7XG4gICAgICAgICAgICAvLyDlpoLmnpwgQ29sdW1uIOacrOi6q+WwseS4jeWPr+inge+8jOebtOaOpemakOiXj+WvueW6lOeahCBsYWJlbFxuICAgICAgICAgICAgaWYgKHZpZXdfMS5nZXRPdmVybGFwQXJlYShjb29yZGluYXRlQkJveCwgc2hhcGVCQm94KSA8PSAwKSB7XG4gICAgICAgICAgICAgICAgbGFiZWwuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhYmVsQkJveC53aWR0aCA+IHNoYXBlQkJveC53aWR0aCkge1xuICAgICAgICAgICAgICAgIC8vIOWkhOeQhuaUvuS4jeS4i+eahOaDheWGtVxuICAgICAgICAgICAgICAgIHZhciBpZHggPSB1dGlsXzEuZmluZEluZGV4KGN1ckdyb3VwLCBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbSA9PT0gbGFiZWw7IH0pO1xuICAgICAgICAgICAgICAgIGlmIChpZHggIT09IGN1ckdyb3VwLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOaVsOaNruagh+etvuWxleekuuWcqOWbvuW9ouS4reWkrlxuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgICAgICB4OiBzaGFwZUJCb3gueCArIHNoYXBlQkJveC53aWR0aCAvIDIsXG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93ID0gbGFiZWxCQm94LndpZHRoID4gc2hhcGVCQm94LndpZHRoIHx8IGxhYmVsQkJveC5oZWlnaHQgPiBzaGFwZUJCb3guaGVpZ2h0O1xuICAgICAgICAgICAgICAgIGlmIChvdmVyZmxvdykge1xuICAgICAgICAgICAgICAgICAgICAvLyDlh7rnjrDkuobmuqLlh7rmg4XlhrXvvIzmt7vliqDmj4/ovrlcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IGxpZ2h0U3R5bGUgPT09IG51bGwgfHwgbGlnaHRTdHlsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGlnaHRTdHlsZS5zdHJva2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5pS+572u5Zyo5p+x5b2i5YaF6YOo77yM6aKc6Imy5Y+W5Y+NXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogZmlsbFdoaXRlID8gbGlnaHRTdHlsZSA9PT0gbnVsbCB8fCBsaWdodFN0eWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsaWdodFN0eWxlLmZpbGwgOiBkYXJrU3R5bGUgPT09IG51bGwgfHwgZGFya1N0eWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkYXJrU3R5bGUuZmlsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiBmaWxsV2hpdGUgPyBsaWdodFN0eWxlID09PSBudWxsIHx8IGxpZ2h0U3R5bGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGxpZ2h0U3R5bGUuZmlsbE9wYWNpdHkgOiBkYXJrU3R5bGUgPT09IG51bGwgfHwgZGFya1N0eWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkYXJrU3R5bGUuZmlsbE9wYWNpdHksXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDmlbDmja7moIfnrb7pmLLph43lj6Dmir3moLcgKi9cbiAgICBCYXJBdXRvTGFiZWwucHJvdG90eXBlLmF1dG9IaWRlTGFiZWxzID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBsYWJlbHMpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGVCQm94ID0gdGhpcy5nZXRDb29yZGluYXRlQkJveCgpO1xuICAgICAgICB2YXIgZmlsdGVyZWRMYWJlbHMgPSB0aGlzLmZpbHRlckxhYmVscyhsYWJlbHMpO1xuICAgICAgICB2YXIgeEZpZWxkID0gZ2VvbWV0cnkuZ2V0WFlGaWVsZHMoKVswXTtcbiAgICAgICAgdmFyIGRvbmVzID0gW107XG4gICAgICAgIHZhciB0b2RvID0gW107XG4gICAgICAgIHZhciBncm91cGVkTGFiZWxzID0gdXRpbF8xLmdyb3VwQnkoZmlsdGVyZWRMYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCkgeyByZXR1cm4gbGFiZWwuZ2V0KGRlcGVuZGVudHNfMS5PUklHSU4pW2RlcGVuZGVudHNfMS5GSUVMRF9PUklHSU5dW3hGaWVsZF07IH0pO1xuICAgICAgICB2YXIgeFZhbHVlcyA9IHV0aWxfMS51bmlxKHV0aWxfMS5tYXAoZmlsdGVyZWRMYWJlbHMsIGZ1bmN0aW9uIChsYWJlbCkgeyByZXR1cm4gbGFiZWwuZ2V0KGRlcGVuZGVudHNfMS5PUklHSU4pW2RlcGVuZGVudHNfMS5GSUVMRF9PUklHSU5dW3hGaWVsZF07IH0pKTtcbiAgICAgICAgdmFyIHhWYWx1ZTtcbiAgICAgICAgaWYgKHV0aWxfMS5zaXplKHhWYWx1ZXMpID4gMCkge1xuICAgICAgICAgICAgLy8g56ys5LiA57uEXG4gICAgICAgICAgICB4VmFsdWUgPSB4VmFsdWVzLnNoaWZ0KCk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChncm91cGVkTGFiZWxzW3hWYWx1ZV0sIGZ1bmN0aW9uIChsYWJlbCkgeyByZXR1cm4gdG9kby5wdXNoKGxhYmVsKTsgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHV0aWxfMS5zaXplKHhWYWx1ZXMpID4gMCkge1xuICAgICAgICAgICAgLy8g5pyA5ZCO5LiA57uEXG4gICAgICAgICAgICB4VmFsdWUgPSB4VmFsdWVzLnBvcCgpO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goZ3JvdXBlZExhYmVsc1t4VmFsdWVdLCBmdW5jdGlvbiAobGFiZWwpIHsgcmV0dXJuIHRvZG8ucHVzaChsYWJlbCk7IH0pO1xuICAgICAgICB9XG4gICAgICAgIHV0aWxfMS5lYWNoKHhWYWx1ZXMucmV2ZXJzZSgpLCBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICAvLyDlhbbku5bnu4RcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGdyb3VwZWRMYWJlbHNbdmFsXSwgZnVuY3Rpb24gKGxhYmVsKSB7IHJldHVybiB0b2RvLnB1c2gobGFiZWwpOyB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHdoaWxlICh0b2RvLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHZhciBjdXIgPSB0b2RvLnNoaWZ0KCk7XG4gICAgICAgICAgICBpZiAoY3VyLmdldCgndmlzaWJsZScpKSB7XG4gICAgICAgICAgICAgICAgdmlld18xLm1vdmVJblBhbmVsKGN1ciwgY29vcmRpbmF0ZUJCb3gpO1xuICAgICAgICAgICAgICAgIGlmICh2aWV3XzEuY2hlY2tTaGFwZU92ZXJsYXAoY3VyLCBkb25lcykpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VyLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmVzLnB1c2goY3VyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKiDmir3moLfmlbDmja7moIfnrb7vvIzorr7nva7mnIDlpKfmlbDph4/nmoTmlbDmja7moIfnrb7vvIzlhbbku5bnmoTnu5/kuIDpmpDol48gKi9cbiAgICBCYXJBdXRvTGFiZWwucHJvdG90eXBlLmZpbHRlckxhYmVscyA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgdmFyIE1BWF9DTlQgPSA1MDA7IC8vIOacgOWkmuaYvuekuiA1MDAg5Liq5pWw5o2u5qCH562+XG4gICAgICAgIHZhciBmaWx0ZXJlZExhYmVscyA9IFtdO1xuICAgICAgICB2YXIgcGFnZXMgPSBNYXRoLm1heChNYXRoLmZsb29yKGxhYmVscy5sZW5ndGggLyBNQVhfQ05UKSwgMSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGxhYmVscywgZnVuY3Rpb24gKGxhYmVsLCBpZHgpIHtcbiAgICAgICAgICAgIGlmIChpZHggJSBwYWdlcyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGZpbHRlcmVkTGFiZWxzLnB1c2gobGFiZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGFiZWwuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZpbHRlcmVkTGFiZWxzO1xuICAgIH07XG4gICAgcmV0dXJuIEJhckF1dG9MYWJlbDtcbn0obGFiZWxfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCYXJBdXRvTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnYmFyLWF1dG8nLCBCYXJBdXRvTGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwtYXV0by5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIikpO1xudmFyIGNvbG9yXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9jb2xvclwiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9iYm94XCIpKTtcbnZhciBCYXJMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhCYXJMYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCYXJMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBCYXJMYWJlbC5wcm90b3R5cGUuZ2V0TGFiZWxJdGVtQXR0cnMgPSBmdW5jdGlvbiAoZWxlbWVudCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgX2IgPSB0aGlzLm9wdGlvbnMsIHN0eWxlID0gX2Iuc3R5bGUsIGZvcm1hdHRlciA9IF9iLmZvcm1hdHRlcjtcbiAgICAgICAgdmFyIG1hcHBpbmdEYXRhID0gW10uY29uY2F0KGVsZW1lbnQuZ2V0TW9kZWwoKS5tYXBwaW5nRGF0YSk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoZWxlbWVudCk7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgc3R5bGUsIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgdGhpcy5nZXRQb3NpdGlvbihlbGVtZW50KSksIHsgdGV4dDogZm9ybWF0dGVyXG4gICAgICAgICAgICAgICAgPyBmb3JtYXR0ZXIodmFsdWUsIChfYSA9IHt9LFxuICAgICAgICAgICAgICAgICAgICBfYVtkZXBlbmRlbnRzXzEuX09SSUdJTl0gPSBtYXBwaW5nRGF0YVswXS5fb3JpZ2luLFxuICAgICAgICAgICAgICAgICAgICBfYS5tYXBwaW5nRGF0dW0gPSBtYXBwaW5nRGF0YVswXSxcbiAgICAgICAgICAgICAgICAgICAgX2EubWFwcGluZ0RhdHVtSW5kZXggPSAwLFxuICAgICAgICAgICAgICAgICAgICBfYS5lbGVtZW50ID0gZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgX2EuZWxlbWVudEluZGV4ID0gaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIF9hKSwgaW5kZXgpXG4gICAgICAgICAgICAgICAgOiB2YWx1ZSwgZmlsbDogdGhpcy5nZXRUZXh0RmlsbChlbGVtZW50KSwgc3Ryb2tlOiB0aGlzLmdldFRleHRTdHJva2UoZWxlbWVudCksIHRleHRBbGlnbjogdGhpcy5nZXRUZXh0QWxpZ24oZWxlbWVudCksIHRleHRCYXNlbGluZTogdGhpcy5nZXRUZXh0QmFzZWxpbmUoKSB9KSk7XG4gICAgfTtcbiAgICBCYXJMYWJlbC5wcm90b3R5cGUuYWRqdXN0TGFiZWwgPSBmdW5jdGlvbiAobGFiZWwsIGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBhZGp1c3RQb3NpdGlvbiA9IF9hLmFkanVzdFBvc2l0aW9uLCBzdHlsZSA9IF9hLnN0eWxlO1xuICAgICAgICBpZiAoYWRqdXN0UG9zaXRpb24pIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLmdldERlZmF1bHRPZmZzZXQoKTtcbiAgICAgICAgICAgIHZhciBsYWJlbFJhbmdlID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHNoYXBlUmFuZ2UgPSB0aGlzLmdldEVsZW1lbnRTaGFwZUJCb3goZWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoc2hhcGVSYW5nZS53aWR0aCA8PSBsYWJlbFJhbmdlLndpZHRoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHhQb3NpdGlvbiA9IHNoYXBlUmFuZ2UubWF4WCArIHRoaXMub3B0aW9ucy5vZmZzZXRYICsgb2Zmc2V0O1xuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3gnLCB4UG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ2ZpbGwnLCBzdHlsZS5maWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgQmFyTGFiZWwucHJvdG90eXBlLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLmxheWVyLnRoZW1lO1xuICAgICAgICB2YXIgX2EgPSB0aGVtZS5sYWJlbCwgbGFiZWwgPSBfYSA9PT0gdm9pZCAwID8ge30gOiBfYTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24oeyBvZmZzZXRYOiAwLCBvZmZzZXRZOiAwLCBhZGp1c3RQb3NpdGlvbjogdHJ1ZSB9LCBsYWJlbCk7XG4gICAgfTtcbiAgICBCYXJMYWJlbC5wcm90b3R5cGUuZ2V0VmFsdWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldChlbGVtZW50LmdldERhdGEoKSwgdGhpcy5sYXllci5vcHRpb25zLnhGaWVsZCk7XG4gICAgfTtcbiAgICBCYXJMYWJlbC5wcm90b3R5cGUuZ2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KCk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoZWxlbWVudCk7XG4gICAgICAgIHZhciBiYm94ID0gdGhpcy5nZXRFbGVtZW50U2hhcGVCQm94KGVsZW1lbnQpO1xuICAgICAgICB2YXIgbWluWCA9IGJib3gubWluWCwgbWF4WCA9IGJib3gubWF4WCwgbWluWSA9IGJib3gubWluWSwgaGVpZ2h0ID0gYmJveC5oZWlnaHQsIHdpZHRoID0gYmJveC53aWR0aDtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFksIHBvc2l0aW9uID0gX2EucG9zaXRpb247XG4gICAgICAgIHZhciB5ID0gbWluWSArIGhlaWdodCAvIDIgKyBvZmZzZXRZO1xuICAgICAgICB2YXIgZGlyID0gdmFsdWUgPCAwID8gLTEgOiAxO1xuICAgICAgICB2YXIgeDtcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIHZhciByb290ID0gdmFsdWUgPiAwID8gbWluWCA6IG1heFg7XG4gICAgICAgICAgICB4ID0gcm9vdCArIG9mZnNldCAqIGRpciArIG9mZnNldFg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocG9zaXRpb24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHZhciByb290ID0gdmFsdWUgPiAwID8gbWF4WCA6IG1pblg7XG4gICAgICAgICAgICB4ID0gcm9vdCArIG9mZnNldCAqIGRpciArIG9mZnNldFg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB4ID0gbWluWCArIHdpZHRoIC8gMiArIG9mZnNldFg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xuICAgIH07XG4gICAgQmFyTGFiZWwucHJvdG90eXBlLmdldFRleHRGaWxsID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHNoYXBlID0gZWxlbWVudC5zaGFwZTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hZGp1c3RDb2xvciAmJiB0aGlzLm9wdGlvbnMucG9zaXRpb24gIT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZUNvbG9yID0gc2hhcGUuYXR0cignZmlsbCcpO1xuICAgICAgICAgICAgdmFyIHNoYXBlT3BhY2l0eSA9IHNoYXBlLmF0dHIoJ29wYWNpdHknKSA/IHNoYXBlLmF0dHIoJ29wYWNpdHknKSA6IDE7XG4gICAgICAgICAgICB2YXIgcmdiID0gY29sb3JfMS5yZ2IyYXJyKHNoYXBlQ29sb3IpO1xuICAgICAgICAgICAgdmFyIGdyYXkgPSBNYXRoLnJvdW5kKHJnYlswXSAqIDAuMjk5ICsgcmdiWzFdICogMC41ODcgKyByZ2JbMl0gKiAwLjExNCkgLyBzaGFwZU9wYWNpdHk7XG4gICAgICAgICAgICB2YXIgY29sb3JCYW5kID0gW1xuICAgICAgICAgICAgICAgIHsgZnJvbTogMCwgdG86IDg1LCBjb2xvcjogJ3doaXRlJyB9LFxuICAgICAgICAgICAgICAgIHsgZnJvbTogODUsIHRvOiAxNzAsIGNvbG9yOiAnI0Y2RjZGNicgfSxcbiAgICAgICAgICAgICAgICB7IGZyb206IDE3MCwgdG86IDI1NSwgY29sb3I6ICdibGFjaycgfSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICB2YXIgcmVmbGVjdCA9IGNvbG9yXzEubWFwcGluZ0NvbG9yKGNvbG9yQmFuZCwgZ3JheSk7XG4gICAgICAgICAgICByZXR1cm4gcmVmbGVjdDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVmYXVsdENvbG9yID0gdGhpcy5vcHRpb25zLnN0eWxlLmZpbGw7XG4gICAgICAgIHJldHVybiBkZWZhdWx0Q29sb3I7XG4gICAgfTtcbiAgICBCYXJMYWJlbC5wcm90b3R5cGUuZ2V0VGV4dFN0cm9rZSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBmaWxsID0gdGhpcy5nZXRUZXh0RmlsbChlbGVtZW50KTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBwb3NpdGlvbiA9IF9hLnBvc2l0aW9uLCBhZGp1c3RDb2xvciA9IF9hLmFkanVzdENvbG9yO1xuICAgICAgICByZXR1cm4gcG9zaXRpb24gIT09ICdyaWdodCcgJiYgYWRqdXN0Q29sb3IgJiYgZmlsbCAhPT0gJ2JsYWNrJyA/IG51bGwgOiB1bmRlZmluZWQ7XG4gICAgfTtcbiAgICBCYXJMYWJlbC5wcm90b3R5cGUuZ2V0VGV4dEFsaWduID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5nZXRWYWx1ZShlbGVtZW50KTtcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uO1xuICAgICAgICB2YXIgYWxpZ25PcHRpb25zID0ge1xuICAgICAgICAgICAgcmlnaHQ6ICdsZWZ0JyxcbiAgICAgICAgICAgIGxlZnQ6ICdsZWZ0JyxcbiAgICAgICAgICAgIG1pZGRsZTogJ2NlbnRlcicsXG4gICAgICAgIH07XG4gICAgICAgIHZhciBhbGlnbk9wdGlvbnNSZXZlcnNlID0ge1xuICAgICAgICAgICAgcmlnaHQ6ICdyaWdodCcsXG4gICAgICAgICAgICBsZWZ0OiAncmlnaHQnLFxuICAgICAgICAgICAgbWlkZGxlOiAnY2VudGVyJyxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGFsaWduT3B0aW9uc1JldmVyc2VbcG9zaXRpb25dO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbGlnbk9wdGlvbnNbcG9zaXRpb25dO1xuICAgIH07XG4gICAgQmFyTGFiZWwucHJvdG90eXBlLmdldFRleHRCYXNlbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICdtaWRkbGUnO1xuICAgIH07XG4gICAgQmFyTGFiZWwucHJvdG90eXBlLmdldEVsZW1lbnRTaGFwZUJCb3ggPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2hhcGUgPSBlbGVtZW50LnNoYXBlO1xuICAgICAgICB2YXIgcG9pbnRzID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlLmdldCgnb3JpZ2luJykucG9pbnRzLCBmdW5jdGlvbiAocCkge1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goX3RoaXMuY29vcmQuY29udmVydFBvaW50KHApKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB4VmFsdWVzID0gcG9pbnRzLm1hcChmdW5jdGlvbiAocG9pbnQpIHsgcmV0dXJuIHBvaW50Lng7IH0pO1xuICAgICAgICB2YXIgeFZhbHVlc01pbiA9IE1hdGgubWluLmFwcGx5KE1hdGgsIHhWYWx1ZXMpO1xuICAgICAgICB2YXIgeFZhbHVlTWF4ID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgeFZhbHVlcyk7XG4gICAgICAgIHZhciB5VmFsdWVzID0gcG9pbnRzLm1hcChmdW5jdGlvbiAocG9pbnQpIHsgcmV0dXJuIHBvaW50Lnk7IH0pO1xuICAgICAgICB2YXIgeVZhbHVlc01pbiA9IE1hdGgubWluLmFwcGx5KE1hdGgsIHlWYWx1ZXMpO1xuICAgICAgICB2YXIgeVZhbHVlc01heCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHlWYWx1ZXMpO1xuICAgICAgICB2YXIgYmJveCA9IG5ldyBiYm94XzEuZGVmYXVsdCh4VmFsdWVzTWluLCB5VmFsdWVzTWluLCB4VmFsdWVNYXggLSB4VmFsdWVzTWluLCB5VmFsdWVzTWF4IC0geVZhbHVlc01pbik7XG4gICAgICAgIHJldHVybiBiYm94O1xuICAgIH07XG4gICAgQmFyTGFiZWwucHJvdG90eXBlLmdldExhYmVsT2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBDb2x1bW4g55qEIG9mZnNldCDlnKggZ2V0UG9zaXRpb24g5Lit5ZugIHBvc2l0aW9uIOS4jeWQjOWNleeLrOWkhOeQhlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gQmFyTGFiZWw7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCYXJMYWJlbDtcbmJhc2VfMS5yZWdpc3RlckxhYmVsQ29tcG9uZW50KCdiYXInLCBCYXJMYWJlbCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYWJlbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVWRU5UX01BUFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5FVkVOVF9NQVA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvbkV2ZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLm9uRXZlbnQ7IH0gfSk7XG52YXIgY29tcG9uZW50TWFwID0ge1xuICAgIGJhcjogJ2ludGVydmFsJyxcbn07XG52YXIgU0hBUEVfRVZFTlRfTUFQID0gZXZlbnRfMS5nZXRFdmVudE1hcChjb21wb25lbnRNYXApO1xudXRpbF8xLmFzc2lnbihldmVudF8xLkVWRU5UX01BUCwgU0hBUEVfRVZFTlRfTUFQKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBCYXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQmFyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJhcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBCYXIucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdiYXInO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgQmFyLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBCYXI7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIHZpZXdfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3ZpZXctbGF5ZXJcIikpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnRzL2ZhY3RvcnlcIik7XG52YXIgY29udmVyc2lvbl90YWdfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnRzL2NvbnZlcnNpb24tdGFnXCIpKTtcbnZhciBmYWN0b3J5XzIgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvc2NhbGVcIik7XG52YXIgYXBwbHlfcmVzcG9uc2l2ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYXBwbHktcmVzcG9uc2l2ZVwiKSk7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbFwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbC1hdXRvXCIpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIHZpZXdfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3ZpZXdcIik7XG52YXIgRzJfR0VPTV9NQVAgPSB7XG4gICAgYmFyOiAnaW50ZXJ2YWwnLFxufTtcbnZhciBQTE9UX0dFT01fTUFQID0ge1xuICAgIGludGVydmFsOiAnYmFyJyxcbn07XG52YXIgQmFzZUJhckxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJhc2VCYXJMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCYXNlQmFyTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2Jhcic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQmFzZUJhckxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2ZnID0ge1xuICAgICAgICAgICAgeEF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hhcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNob3dDcm9zc2hhaXJzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzaG93TWFya2VyczogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnbGVmdCcsXG4gICAgICAgICAgICAgICAgYWRqdXN0Q29sb3I6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICd0b3AtbGVmdCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW50ZXJhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgeyB0eXBlOiAndG9vbHRpcCcgfSxcbiAgICAgICAgICAgICAgICB7IHR5cGU6ICdhY3RpdmUtcmVnaW9uJyB9LFxuICAgICAgICAgICAgICAgIHsgdHlwZTogJ2xlZ2VuZC1hY3RpdmUnIH0sXG4gICAgICAgICAgICAgICAgeyB0eXBlOiAnbGVnZW5kLWZpbHRlcicgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb252ZXJzaW9uVGFnOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCBjZmcpO1xuICAgIH07XG4gICAgQmFzZUJhckxheWVyLnByb3RvdHlwZS5iZWZvcmVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmJlZm9yZUluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICAvKiog5ZON5bqU5byP5Zu+5b2iICovXG4gICAgICAgIGlmIChwcm9wcy5yZXNwb25zaXZlICYmIHByb3BzLnBhZGRpbmcgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5hcHBseVJlc3BvbnNpdmUoJ3ByZVJlbmRlcicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHRoaXMucmVuZGVyTGFiZWwoKTtcbiAgICAgICAgLyoqIOWTjeW6lOW8jyAqL1xuICAgICAgICBpZiAocHJvcHMucmVzcG9uc2l2ZSAmJiBwcm9wcy5wYWRkaW5nICE9PSAnYXV0bycpIHtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlSZXNwb25zaXZlKCdhZnRlclJlbmRlcicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy5jb252ZXJzaW9uVGFnLnZpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMuY29udmVyc2lvblRhZyA9IG5ldyBjb252ZXJzaW9uX3RhZ18xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IHZpZXc6IHRoaXMudmlldywgZmllbGQ6IHByb3BzLnhGaWVsZCwgYW5pbWF0aW9uOiBwcm9wcy5hbmltYXRpb24gPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlIH0sIHByb3BzLmNvbnZlcnNpb25UYWcpKTtcbiAgICAgICAgfVxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKGRpbSwgdHlwZSkge1xuICAgICAgICBpZiAoZGltID09PSAnZzInKSB7XG4gICAgICAgICAgICByZXR1cm4gRzJfR0VPTV9NQVBbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBMT1RfR0VPTV9NQVBbdHlwZV07XG4gICAgfTtcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLnByb2Nlc3NEYXRhID0gZnVuY3Rpb24gKG9yaWdpbkRhdGEpIHtcbiAgICAgICAgdmFyIGlucHV0RGF0YSA9IG9yaWdpbkRhdGEgPyBvcmlnaW5EYXRhLnNsaWNlKCkucmV2ZXJzZSgpIDogb3JpZ2luRGF0YTtcbiAgICAgICAgdmFyIHlGaWVsZCA9IHRoaXMub3B0aW9ucy55RmllbGQ7XG4gICAgICAgIHZhciBwcm9jZXNzZWREYXRhID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKGlucHV0RGF0YSwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIHZhciBkID0gdXRpbF8xLmNsb25lKGRhdGEpO1xuICAgICAgICAgICAgZFt5RmllbGRdID0gZFt5RmllbGRdLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBwcm9jZXNzZWREYXRhLnB1c2goZCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcHJvY2Vzc2VkRGF0YTtcbiAgICB9O1xuICAgIEJhc2VCYXJMYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHNjYWxlcyA9IHt9O1xuICAgICAgICAvKiog6YWN572ueC1zY2FsZSAqL1xuICAgICAgICBzY2FsZXNbcHJvcHMueUZpZWxkXSA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdjYXQnLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhwcm9wcywgJ3lBeGlzJykpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlc1twcm9wcy55RmllbGRdLCBwcm9wcy55QXhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rnktc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW3Byb3BzLnhGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICd4QXhpcycpKSB7XG4gICAgICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXNbcHJvcHMueEZpZWxkXSwgcHJvcHMueEF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldENvbmZpZygnY29vcmRpbmF0ZScsIHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtbJ3RyYW5zcG9zZSddXSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLmF4aXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4QXhpc19wYXJzZXIgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdheGlzJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgICAgIGRpbTogJ3gnLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHlBeGlzX3BhcnNlciA9IGZhY3RvcnlfMS5nZXRDb21wb25lbnQoJ2F4aXMnLCB7XG4gICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgZGltOiAneScsXG4gICAgICAgIH0pO1xuICAgICAgICAvKiog6L2s572u5Z2Q5qCH57O754m55q6K6YWN572uICovXG4gICAgICAgIGlmICh4QXhpc19wYXJzZXIpIHtcbiAgICAgICAgICAgIHhBeGlzX3BhcnNlci5wb3NpdGlvbiA9ICdsZWZ0JztcbiAgICAgICAgfVxuICAgICAgICBpZiAoeUF4aXNfcGFyc2VyKSB7XG4gICAgICAgICAgICB5QXhpc19wYXJzZXIucG9zaXRpb24gPSAnYm90dG9tJztcbiAgICAgICAgfVxuICAgICAgICB2YXIgYXhlc0NvbmZpZyA9IHt9O1xuICAgICAgICBheGVzQ29uZmlnW3RoaXMub3B0aW9ucy54RmllbGRdID0geEF4aXNfcGFyc2VyO1xuICAgICAgICBheGVzQ29uZmlnW3RoaXMub3B0aW9ucy55RmllbGRdID0geUF4aXNfcGFyc2VyO1xuICAgICAgICAvKiog5a2Y5YKo5Z2Q5qCH6L206YWN572u6aG55YiwY29uZmlnICovXG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdheGVzJywgYXhlc0NvbmZpZyk7XG4gICAgfTtcbiAgICAvL2VzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLmFkanVzdEJhciA9IGZ1bmN0aW9uIChiYXIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICBCYXNlQmFyTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBiYXIgPSBmYWN0b3J5XzIuZ2V0R2VvbSgnaW50ZXJ2YWwnLCAnbWFpbicsIHtcbiAgICAgICAgICAgIHBvc2l0aW9uRmllbGRzOiBbcHJvcHMueUZpZWxkLCBwcm9wcy54RmllbGRdLFxuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwcm9wcy5jb252ZXJzaW9uVGFnLnZpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29uZmlnKCd0aGVtZScsIHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLmdldFRoZW1lKCksIHtcbiAgICAgICAgICAgICAgICBjb2x1bW5XaWR0aFJhdGlvOiAxIC8gMyxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkanVzdEJhcihiYXIpO1xuICAgICAgICB0aGlzLmJhciA9IGJhcjtcbiAgICAgICAgaWYgKHByb3BzLnRvb2x0aXAgJiYgKHByb3BzLnRvb2x0aXAuZmllbGRzIHx8IHByb3BzLnRvb2x0aXAuZm9ybWF0dGVyKSkge1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeVRvb2x0aXAoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBiYXIpO1xuICAgIH07XG4gICAgQmFzZUJhckxheWVyLnByb3RvdHlwZS5hbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYW5pbWF0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8qKiDlhbPpl63liqjnlLsgKi9cbiAgICAgICAgICAgIHRoaXMuYmFyLmFuaW1hdGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQmFzZUJhckxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIEJhc2VCYXJMYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmNvbmZpZy5zY2FsZXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgbGFiZWwgPSBfYS5sYWJlbCwgeEZpZWxkID0gX2EueEZpZWxkO1xuICAgICAgICB2YXIgc2NhbGUgPSBzY2FsZXNbeEZpZWxkXTtcbiAgICAgICAgaWYgKGxhYmVsID09PSBudWxsIHx8IGxhYmVsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsYWJlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnkgPSB2aWV3XzEuZ2V0R2VvbWV0cnlCeVR5cGUodGhpcy52aWV3LCAnaW50ZXJ2YWwnKTtcbiAgICAgICAgICAgIHRoaXMuZG9SZW5kZXJMYWJlbChnZW9tZXRyeSwgdHNsaWJfMS5fX2Fzc2lnbih7IHR5cGU6ICdiYXInLCBmb3JtYXR0ZXI6IHNjYWxlLmZvcm1hdHRlciAmJiAoZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBzY2FsZS5mb3JtYXR0ZXIodmFsdWUpOyB9KSB9LCB0aGlzLm9wdGlvbnMubGFiZWwpKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQmFzZUJhckxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYmFyLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIHRoaXMuYmFyLnRvb2x0aXAuZmllbGRzID0gdG9vbHRpcE9wdGlvbnMuZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuYmFyLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAoIXRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIHRoaXMuYmFyLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJhci50b29sdGlwLmZpZWxkcy5wdXNoKHRoaXMub3B0aW9ucy5jb2xvckZpZWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJhc2VCYXJMYXllci5wcm90b3R5cGUuYXBwbHlSZXNwb25zaXZlID0gZnVuY3Rpb24gKHN0YWdlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBtZXRob2RzID0gYXBwbHlfcmVzcG9uc2l2ZV8xLmRlZmF1bHRbc3RhZ2VdO1xuICAgICAgICB1dGlsXzEuZWFjaChtZXRob2RzLCBmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgdmFyIHJlc3BvbnNpdmUgPSByO1xuICAgICAgICAgICAgcmVzcG9uc2l2ZS5tZXRob2QoX3RoaXMpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJhc2VCYXJMYXllci5wcm90b3R5cGUuZ2V0TGFiZWxPcHRpb25zQnlQb3NpdGlvbiA9IGZ1bmN0aW9uIChwb3NpdGlvbikge1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICdtaWRkbGUnKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0OiA3LFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDQsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gQmFzZUJhckxheWVyO1xufSh2aWV3X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQmFzZUJhckxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnYmFyJywgQmFzZUJhckxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5ERUZBVUxUX0JBUl9USEVNRSA9IHZvaWQgMDtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIEJBUl9BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5ICogMC41IH07XG59O1xudmFyIEJBUl9ESVNBQkxFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSAqIDAuNSB9O1xufTtcbmV4cG9ydHMuREVGQVVMVF9CQVJfVEhFTUUgPSB7XG4gICAgbGFiZWw6IHtcbiAgICAgICAgZGFya1N0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAnIzJjMzU0MicsXG4gICAgICAgICAgICBzdHJva2U6ICcjZmZmZmZmJyxcbiAgICAgICAgICAgIGZpbGxPcGFjaXR5OiAwLjg1LFxuICAgICAgICB9LFxuICAgICAgICBsaWdodFN0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAnI2ZmZmZmZicsXG4gICAgICAgICAgICBzdHJva2U6ICcjZmZmZmZmJyxcbiAgICAgICAgICAgIGZpbGxPcGFjaXR5OiAxLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgY29sdW1uU3R5bGU6IHtcbiAgICAgICAgbm9ybWFsOiB7fSxcbiAgICAgICAgYWN0aXZlOiBCQVJfQUNUSVZFX1NUWUxFLFxuICAgICAgICBkaXNhYmxlOiBCQVJfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IHsgbGluZVdpZHRoOiAxLCBzdHJva2U6ICdibGFjaycgfSxcbiAgICB9LFxufTtcbnRoZW1lXzEucmVnaXN0ZXJUaGVtZSgnYmFyJywgZXhwb3J0cy5ERUZBVUxUX0JBUl9USEVNRSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgQnViYmxlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJ1YmJsZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCdWJibGUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQnViYmxlLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnYnViYmxlJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEJ1YmJsZS5wcm90b3R5cGUuZ2V0U2l6ZVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgcmV0dXJuIGxheWVyLmdldFNpemVTY2FsZSgpO1xuICAgIH07XG4gICAgQnViYmxlLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBCdWJibGU7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCdWJibGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4uL3NjYXR0ZXIvZXZlbnRcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vc2NhdHRlci9sYXllclwiKSk7XG5yZXF1aXJlKFwiLi9zaGFwZVwiKTtcbnJlcXVpcmUoXCIuL3RoZW1lXCIpO1xudmFyIEJ1YmJsZUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJ1YmJsZUxheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJ1YmJsZUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdidWJibGUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEJ1YmJsZUxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICAvLyDnm7TlvoQgbWluIDRweO+8m21heCA2NHB4XG4gICAgICAgICAgICBwb2ludFNpemU6IFsyLCAzMl0sXG4gICAgICAgICAgICBwb2ludFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBudWxsLFxuICAgICAgICAgICAgICAgIHN0cm9rZU9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDAuNSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2hhcGU6ICdidWJibGUtcG9pbnQnLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJ1YmJsZUxheWVyLnByb3RvdHlwZS5nZXRTaXplU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzaXplRmllbGQgPSB0aGlzLm9wdGlvbnMuc2l6ZUZpZWxkO1xuICAgICAgICBpZiAoc2l6ZUZpZWxkKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKHNpemVGaWVsZCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJ1YmJsZUxheWVyLnByb3RvdHlwZS5sZWdlbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5sZWdlbmQuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sZWdlbmQgJiYgdGhpcy5vcHRpb25zLmxlZ2VuZC52aXNpYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdsZWdlbmRzJywgKF9hID0ge30sXG4gICAgICAgICAgICBfYVt0aGlzLm9wdGlvbnMuc2l6ZUZpZWxkXSA9IGZhbHNlLFxuICAgICAgICAgICAgX2EpKTtcbiAgICB9O1xuICAgIEJ1YmJsZUxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIHJldHVybiBCdWJibGVMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCdWJibGVMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ2J1YmJsZScsIEJ1YmJsZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGcyXzEgPSByZXF1aXJlKFwiQGFudHYvZzJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS9wb2ludC91dGlsXCIpO1xuZzJfMS5yZWdpc3RlclNoYXBlKCdwb2ludCcsICdidWJibGUtcG9pbnQnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHV0aWxfMS5kcmF3UG9pbnRzKHRoaXMsIGNmZywgY29udGFpbmVyLCAnY2lyY2xlJywgZmFsc2UpO1xuICAgICAgICAvLyDlpoLmnpznlKjmiLfmnKrphY3nva4gc3Ryb2tl77yM5rCU5rOh5Zu+IHN0cm9rZSDpu5jorqTnlKggZmlsbCDpopzoibJcbiAgICAgICAgaWYgKCFjZmcuc3R5bGUuc3Ryb2tlKSB7XG4gICAgICAgICAgICB2YXIgZmlsbCA9IHBvaW50LmF0dHIoJ2ZpbGwnKTtcbiAgICAgICAgICAgIHBvaW50LmF0dHIoJ3N0cm9rZScsIGZpbGwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb2ludDtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA0LjUsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYXBlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vLi4vdGhlbWVcIik7XG52YXIgUE9JTlRfQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIHN0cm9rZSA9IHN0eWxlLnN0cm9rZSB8fCAnIzAwMCc7XG4gICAgdmFyIGZpbGxPcGFjaXR5ID0gc3R5bGUuZmlsbE9wYWNpdHkgfHwgc3R5bGUub3BhY2l0eSB8fCAwLjk1O1xuICAgIHJldHVybiB7XG4gICAgICAgIHN0cm9rZTogc3Ryb2tlLFxuICAgICAgICBmaWxsT3BhY2l0eTogZmlsbE9wYWNpdHksXG4gICAgfTtcbn07XG52YXIgUE9JTlRfU0VMRUNURURfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgc3Ryb2tlID0gc3R5bGUuc3Ryb2tlIHx8ICcjMDAwJztcbiAgICB2YXIgbGluZVdpZHRoID0gc3R5bGUubGluZVdpZHRoIHx8IDI7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3Ryb2tlOiBzdHJva2UsXG4gICAgICAgIGxpbmVXaWR0aDogbGluZVdpZHRoLFxuICAgIH07XG59O1xudmFyIFBPSU5UX0lOQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIGZpbGxPcGFjaXR5ID0gc3R5bGUuZmlsbE9wYWNpdHkgfHwgc3R5bGUub3BhY2l0eSB8fCAwLjM7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZmlsbE9wYWNpdHk6IGZpbGxPcGFjaXR5LFxuICAgIH07XG59O1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdidWJibGUnLCB7XG4gICAgcG9pbnRTdHlsZToge1xuICAgICAgICBub3JtYWw6IHt9LFxuICAgICAgICBhY3RpdmU6IFBPSU5UX0FDVElWRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IFBPSU5UX1NFTEVDVEVEX1NUWUxFLFxuICAgICAgICBpbmFjdGl2ZTogUE9JTlRfSU5BQ1RJVkVfU1RZTEUsXG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9iYm94XCIpKTtcbnZhciBCdWxsZXRSZWN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJ1bGxldFJlY3QodmlldywgY2ZnKSB7XG4gICAgICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgICAgIHRoaXMuY2ZnID0gY2ZnO1xuICAgICAgICB0aGlzLl9pbml0KCk7XG4gICAgfVxuICAgIC8qKiDnu5jliLbovoXliqlsYWJlbHMgKi9cbiAgICBCdWxsZXRSZWN0LnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMudmlldyB8fCB0aGlzLnZpZXcuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLnZpZXcubWlkZGxlR3JvdXAuYWRkR3JvdXAoKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCduYW1lJywgJ3JlY3RHcm91cHMnKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0WkluZGV4KC0xMDApO1xuICAgICAgICB2YXIgZ2VvbWV0cnkgPSB0aGlzLmdldEdlb21ldHJ5KCk7XG4gICAgICAgIHZhciBzaGFwZXMgPSB1dGlsXzEubWFwKGdlb21ldHJ5ID09PSBudWxsIHx8IGdlb21ldHJ5ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBnZW9tZXRyeS5lbGVtZW50cywgZnVuY3Rpb24gKGVsZW1lbnQpIHsgcmV0dXJuIGVsZW1lbnQuc2hhcGU7IH0pO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2ZnLnJhbmdlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlQm94ID0gc2hhcGVzW2ldLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciB3aWR0aFJhdGlvID0gc2hhcGVCb3gud2lkdGggLyBzaGFwZXNbaV0uZ2V0KCdvcmlnaW4nKS5kYXRhW3RoaXMuY2ZnLnlGaWVsZF07XG4gICAgICAgICAgICB0aGlzLmRyYXdSZWN0KHNoYXBlQm94LCB0aGlzLmNmZy5yYW5nZXNbaV0gfHwgWzAsIDFdLCB3aWR0aFJhdGlvKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXcuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIEJ1bGxldFJlY3QucHJvdG90eXBlLmRyYXdSZWN0ID0gZnVuY3Rpb24gKGJveCwgcmFuZ2VzLCB3aWR0aFJhdGlvKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5jZmc7XG4gICAgICAgIHZhciByYW5nZUNvbG9ycyA9IG9wdGlvbnMucmFuZ2VDb2xvcnM7XG4gICAgICAgIHZhciB4UG9zID0gYm94Lm1pblg7XG4gICAgICAgIHZhciB5UG9zID0gYm94Lm1pblkgLSAoYm94LmhlaWdodCAqIChvcHRpb25zLnJhbmdlU2l6ZSAtIDEpKSAvIDI7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB2YXIgd2lkdGggPSAocmFuZ2VzW2ldIC0gcmFuZ2VzW2kgLSAxXSkgKiBvcHRpb25zLnJhbmdlTWF4ICogd2lkdGhSYXRpbztcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyXG4gICAgICAgICAgICAgICAgLmFkZFNoYXBlKCdyZWN0Jywge1xuICAgICAgICAgICAgICAgIG5hbWU6ICdidWxsZXQtcmVjdCcsXG4gICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGJveC5oZWlnaHQgKiBvcHRpb25zLnJhbmdlU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgeDogeFBvcyxcbiAgICAgICAgICAgICAgICAgICAgeTogeVBvcyxcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogcmFuZ2VDb2xvcnNbKGkgLSAxKSAlIHJhbmdlQ29sb3JzLmxlbmd0aF0sXG4gICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiAwLjI1LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5zZXQoJ3pJbmRleCcsIC0xKTtcbiAgICAgICAgICAgIHhQb3MgKz0gd2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuYXhpcyAmJiBvcHRpb25zLmF4aXMudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIHRpY2tJbnRlcnZhbCA9IG9wdGlvbnMucmFuZ2VNYXggLyAob3B0aW9ucy5heGlzLnRpY2tDb3VudCAtIDEpO1xuICAgICAgICAgICAgdmFyIHJhbmdlQm94ID0gbmV3IGJib3hfMS5kZWZhdWx0KGJveC54LCB5UG9zLCB4UG9zLCBib3guaGVpZ2h0ICogb3B0aW9ucy5yYW5nZVNpemUpO1xuICAgICAgICAgICAgdGhpcy5kcmF3QnVsbGV0VGlja3MocmFuZ2VCb3gsIHRpY2tJbnRlcnZhbCwgd2lkdGhSYXRpbyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qKiDmt7vliqAgdGlja3MgICovXG4gICAgQnVsbGV0UmVjdC5wcm90b3R5cGUuZHJhd0J1bGxldFRpY2tzID0gZnVuY3Rpb24gKGJveCwgdGlja0ludGVydmFsLCB3aWR0aFJhdGlvKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5jZmc7XG4gICAgICAgIHZhciB0aWNrc1N0eWxlID0gb3B0aW9ucy5heGlzLnN0eWxlO1xuICAgICAgICB2YXIgdGlja0NvdW50ID0gb3B0aW9ucy5heGlzLnRpY2tDb3VudDtcbiAgICAgICAgdmFyIHRpY2tQb3NpdGlvbiA9IG9wdGlvbnMuYXhpcy5wb3NpdGlvbjtcbiAgICAgICAgdmFyIHRpY2tPZmZzZXQgPSB1dGlsXzEuZ2V0KHRpY2tzU3R5bGUsICdsaW5lSGVpZ2h0JywgMCkgLSB0aWNrc1N0eWxlLmZvbnRTaXplIC8gMjtcbiAgICAgICAgZm9yICh2YXIgdGlja0lkeCA9IDA7IHRpY2tJZHggPCB0aWNrQ291bnQ7IHRpY2tJZHggKz0gMSkge1xuICAgICAgICAgICAgdmFyIHggPSBib3gubWluWCArIHRpY2tJbnRlcnZhbCAqIHRpY2tJZHggKiB3aWR0aFJhdGlvO1xuICAgICAgICAgICAgdmFyIHRpY2tUZXh0ID0gXCJcIiArIHRpY2tJbnRlcnZhbCAqIHRpY2tJZHg7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5heGlzLmZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgIHRpY2tUZXh0ID0gb3B0aW9ucy5heGlzLmZvcm1hdHRlcih0aWNrVGV4dCwgdGlja0lkeCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgICAgICBuYW1lOiAndGljaycsXG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB4OiB4LCB5OiB0aWNrUG9zaXRpb24gPT09ICdiZWZvcmUnID8gYm94Lm1pblkgLSB0aWNrT2Zmc2V0IDogYm94Lm1heFkgKyB0aWNrT2Zmc2V0LCB0ZXh0OiBcIlwiICsgdGlja1RleHQgfSwgdGlja3NTdHlsZSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmF4aXMudGlja0xpbmUgJiYgb3B0aW9ucy5heGlzLnRpY2tMaW5lLnZpc2libGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGlja0xpbmVDZmcgPSBvcHRpb25zLmF4aXMudGlja0xpbmU7XG4gICAgICAgICAgICAgICAgaWYgKHRpY2tJZHggPiAwICYmIHRpY2tJZHggIT09IHRpY2tDb3VudCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCB4LCBib3gubWluWV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIHgsIGJveC5tYXhZXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdIH0sIHRpY2tMaW5lQ2ZnKSxcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zZXQoJ3pJbmRleCcsIC0xKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJ1bGxldFJlY3QucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJ1bGxldFJlY3QucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJ1bGxldFJlY3QucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLnZpZXcub24oJ2JlZm9yZXJlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmNsZWFyKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpZXcub24oJ2FmdGVycmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuZHJhdygpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJ1bGxldFJlY3QucHJvdG90eXBlLmdldEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmZpbmQodGhpcy52aWV3Lmdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tZXRyeSkgeyByZXR1cm4gZ2VvbWV0cnkudHlwZSA9PT0gJ2ludGVydmFsJzsgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQnVsbGV0UmVjdDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCdWxsZXRSZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YnVsbGV0UmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIEJ1bGxldFRhcmdldCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCdWxsZXRUYXJnZXQodmlldywgY2ZnKSB7XG4gICAgICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgICAgIHRoaXMuY2ZnID0gY2ZnO1xuICAgICAgICB0aGlzLl9pbml0KCk7XG4gICAgfVxuICAgIC8qKiDnu5jliLbovoXliqlsYWJlbHMgKi9cbiAgICBCdWxsZXRUYXJnZXQucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy52aWV3IHx8IHRoaXMudmlldy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMudmlldy5mb3JlZ3JvdW5kR3JvdXAuYWRkR3JvdXAoKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCduYW1lJywgJ3RhcmdldEdyb3VwcycpO1xuICAgICAgICB2YXIgc2hhcGVzID0gdXRpbF8xLm1hcCh0aGlzLmdldEdlb21ldHJ5KCkuZWxlbWVudHMsIGZ1bmN0aW9uIChlbGVtZW50KSB7IHJldHVybiBlbGVtZW50LnNoYXBlOyB9KTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmNmZy50YXJnZXRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB2YXIgc2hhcGVCb3ggPSBzaGFwZXNbaV0uZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHdpZHRoUmF0aW8gPSBzaGFwZUJveC53aWR0aCAvIHNoYXBlc1tpXS5nZXQoJ29yaWdpbicpLmRhdGFbdGhpcy5jZmcueUZpZWxkXTtcbiAgICAgICAgICAgIHRoaXMuZHJhd1RhcmdldChzaGFwZUJveCwgdGhpcy5jZmcudGFyZ2V0c1tpXSwgd2lkdGhSYXRpbyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52aWV3LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBCdWxsZXRUYXJnZXQucHJvdG90eXBlLmRyYXdUYXJnZXQgPSBmdW5jdGlvbiAoYm94LCB0YXJnZXRzLCB3aWR0aFJhdGlvKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5jZmc7XG4gICAgICAgIHZhciBjb2xvcnMgPSBvcHRpb25zLm1hcmtlckNvbG9ycztcbiAgICAgICAgLyoqIOa3u+WKoOebruagh+WAvCAqL1xuICAgICAgICB0YXJnZXRzLmZvckVhY2goZnVuY3Rpb24gKHRhcmdldCwgaSkge1xuICAgICAgICAgICAgdmFyIG1hcmtlclN0eWxlID0gb3B0aW9ucy5tYXJrZXJTdHlsZTtcbiAgICAgICAgICAgIF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnYnVsbGV0LXRhcmdldCcsXG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IHdpZHRoOiBtYXJrZXJTdHlsZS53aWR0aCwgaGVpZ2h0OiBib3guaGVpZ2h0ICogb3B0aW9ucy5tYXJrZXJTaXplIC0gbWFya2VyU3R5bGUud2lkdGggLyAyLCB4OiBib3gubWluWCArIHRhcmdldCAqIHdpZHRoUmF0aW8sIHk6IGJveC5taW5ZIC0gKGJveC5oZWlnaHQgKiAob3B0aW9ucy5tYXJrZXJTaXplIC0gMSkpIC8gMiB9LCBtYXJrZXJTdHlsZSksIHsgZmlsbDogY29sb3JzW2kgJSBjb2xvcnMubGVuZ3RoXSB8fCBtYXJrZXJTdHlsZS5maWxsIH0pLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQnVsbGV0VGFyZ2V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBCdWxsZXRUYXJnZXQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJ1bGxldFRhcmdldC5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMudmlldy5vbignYmVmb3JlcmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlldy5vbignYWZ0ZXJyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5kcmF3KCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQnVsbGV0VGFyZ2V0LnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5maW5kKHRoaXMudmlldy5nZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbWV0cnkpIHsgcmV0dXJuIGdlb21ldHJ5LnR5cGUgPT09ICdpbnRlcnZhbCc7IH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEJ1bGxldFRhcmdldDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBCdWxsZXRUYXJnZXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1idWxsZXRUYXJnZXQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBidWxsZXQ6ICdpbnRlcnZhbCcsXG4gICAgYnVsbGV0VGFyZ2V0OiAnYnVsbGV0LXRhcmdldCcsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgQnVsbGV0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJ1bGxldCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCdWxsZXQoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQnVsbGV0LnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnYnVsbGV0JztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEJ1bGxldC5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gQnVsbGV0O1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQnVsbGV0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLllfRklFTEQgPSBleHBvcnRzLlhfRklFTEQgPSBleHBvcnRzLlNUQUNLX0ZJRUxEID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgRXZlbnRQYXJzZXIgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi9ldmVudFwiKSk7XG52YXIgdmlld19sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2Uvdmlldy1sYXllclwiKSk7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3NjYWxlXCIpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnRzL2ZhY3RvcnlcIik7XG52YXIgZmFjdG9yeV8yID0gcmVxdWlyZShcIi4uLy4uL2dlb21zL2ZhY3RvcnlcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgYnVsbGV0UmVjdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50L2J1bGxldFJlY3RcIikpO1xudmFyIGJ1bGxldFRhcmdldF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50L2J1bGxldFRhcmdldFwiKSk7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnZhciBHMl9HRU9NX01BUCA9IHtcbiAgICBidWxsZXQ6ICdpbnRlcnZhbCcsXG59O1xudmFyIFBMT1RfR0VPTV9NQVAgPSB7XG4gICAgaW50ZXJ2YWw6ICdidWxsZXQnLFxufTtcbmV4cG9ydHMuU1RBQ0tfRklFTEQgPSAnJCRzdGFja0ZpZWxkJCQnO1xuZXhwb3J0cy5YX0ZJRUxEID0gJyQkeEZpZWxkJCQnO1xuZXhwb3J0cy5ZX0ZJRUxEID0gJyQkeUZpZWxkJCQnO1xudmFyIEJ1bGxldExheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJ1bGxldExheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEJ1bGxldExheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdidWxsZXQnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEJ1bGxldExheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgICAgIHN0YWNrRmllbGQ6IGV4cG9ydHMuU1RBQ0tfRklFTEQsXG4gICAgICAgICAgICB4RmllbGQ6IGV4cG9ydHMuWF9GSUVMRCxcbiAgICAgICAgICAgIHlGaWVsZDogZXhwb3J0cy5ZX0ZJRUxELFxuICAgICAgICAgICAgcmFuZ2VDb2xvcnM6IFsncmdiYSg5MSwgMTQzLCAyNDksIDAuNDUpJ10sXG4gICAgICAgICAgICBtZWFzdXJlU2l6ZTogMTIsXG4gICAgICAgICAgICByYW5nZVNpemU6IDIsXG4gICAgICAgICAgICBtYXJrZXJTaXplOiAyLFxuICAgICAgICAgICAgbWFya2VyQ29sb3JzOiBbXSxcbiAgICAgICAgICAgIG1hcmtlclN0eWxlOiB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDIsXG4gICAgICAgICAgICAgICAgZmlsbDogJyM1QjhGRjknLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBheGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdiZWZvcmUnLFxuICAgICAgICAgICAgICAgIHRpY2tDb3VudDogNixcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGZ1bmN0aW9uICh0ZXh0LCBpZHgpIHsgcmV0dXJuIFwiXCIgKyBpZHg7IH0sXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC4yNSknLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IDE2LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjRkZGJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZURhc2g6IFs0LCAyXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuaWNlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogJ2l0ZW0nLFxuICAgICAgICAgICAgICAgIGNyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDQsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC40NSknLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEJ1bGxldExheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLnZpZXcucmVtb3ZlSW50ZXJhY3Rpb24oJ2xlZ2VuZC1maWx0ZXInKTtcbiAgICB9O1xuICAgIEJ1bGxldExheWVyLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgLyoqIOmFjee9rnktc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW29wdGlvbnMueUZpZWxkXSA9IHt9O1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhvcHRpb25zLCAneUF4aXMnKSkge1xuICAgICAgICAgICAgc2NhbGVfMS5leHRyYWN0U2NhbGUoc2NhbGVzW29wdGlvbnMueUZpZWxkXSwgb3B0aW9ucy55QXhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rngtc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW29wdGlvbnMueEZpZWxkXSA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdjYXQnLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhvcHRpb25zLCAneEF4aXMnKSkge1xuICAgICAgICAgICAgc2NhbGVfMS5leHRyYWN0U2NhbGUoc2NhbGVzW29wdGlvbnMueEZpZWxkXSwgb3B0aW9ucy54QXhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ3NjYWxlcycsIHNjYWxlcyk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2NhbGUuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIEJ1bGxldExheWVyLnByb3RvdHlwZS5nZXRPcHRpb25zID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gX3N1cGVyLnByb3RvdHlwZS5nZXRPcHRpb25zLmNhbGwodGhpcywgcHJvcHMpO1xuICAgICAgICB0aGlzLmFkanVzdE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH07XG4gICAgQnVsbGV0TGF5ZXIucHJvdG90eXBlLmFmdGVySW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlckluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciByYW5nZXMgPSBvcHRpb25zLmRhdGEubWFwKGZ1bmN0aW9uIChkKSB7IHJldHVybiBkLnJhbmdlczsgfSk7XG4gICAgICAgIHZhciB0YXJnZXRzID0gb3B0aW9ucy5kYXRhLm1hcChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZC50YXJnZXRzOyB9KTtcbiAgICAgICAgdGhpcy5idWxsZXRSZWN0ID0gbmV3IGJ1bGxldFJlY3RfMS5kZWZhdWx0KHRoaXMudmlldywge1xuICAgICAgICAgICAgcmFuZ2VzOiByYW5nZXMsXG4gICAgICAgICAgICByYW5nZU1heDogb3B0aW9ucy5yYW5nZU1heCxcbiAgICAgICAgICAgIHlGaWVsZDogb3B0aW9ucy55RmllbGQsXG4gICAgICAgICAgICByYW5nZVNpemU6IG9wdGlvbnMucmFuZ2VTaXplLFxuICAgICAgICAgICAgcmFuZ2VDb2xvcnM6IG9wdGlvbnMucmFuZ2VDb2xvcnMgfHwgW10sXG4gICAgICAgICAgICBheGlzOiBvcHRpb25zLmF4aXMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmJ1bGxldFRhcmdldCA9IG5ldyBidWxsZXRUYXJnZXRfMS5kZWZhdWx0KHRoaXMudmlldywge1xuICAgICAgICAgICAgdGFyZ2V0czogdGFyZ2V0cyxcbiAgICAgICAgICAgIHlGaWVsZDogb3B0aW9ucy55RmllbGQsXG4gICAgICAgICAgICBtYXJrZXJTaXplOiBvcHRpb25zLm1hcmtlclNpemUsXG4gICAgICAgICAgICBtYXJrZXJDb2xvcnM6IG9wdGlvbnMubWFya2VyQ29sb3JzIHx8IFtdLFxuICAgICAgICAgICAgbWFya2VyU3R5bGU6IG9wdGlvbnMubWFya2VyU3R5bGUsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQnVsbGV0TGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKGRpbSwgdHlwZSkge1xuICAgICAgICBpZiAoZGltID09PSAnZzInKSB7XG4gICAgICAgICAgICByZXR1cm4gRzJfR0VPTV9NQVBbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBMT1RfR0VPTV9NQVBbdHlwZV07XG4gICAgfTtcbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUuY29vcmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdjb29yZGluYXRlJywge1xuICAgICAgICAgICAgYWN0aW9uczogW1sndHJhbnNwb3NlJ11dLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDoh6rlrprkuYnlrZDlvLnlm77lm77kvosgKi9cbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUubGVnZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIG1hcmtlckNvbG9yID0gb3B0aW9ucy5tYXJrZXJTdHlsZS5maWxsO1xuICAgICAgICB2YXIgbWVhc3VyZUNvbG9ycyA9IG9wdGlvbnMubWVhc3VyZUNvbG9ycyB8fCB0aGlzLnRoZW1lLmNvbG9ycztcbiAgICAgICAgdmFyIGl0ZW1zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG5hbWU6ICflrp7pmYXov5vluqYnLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAn5a6e6ZmF6L+b5bqmJyxcbiAgICAgICAgICAgICAgICBtYXJrZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc3ltYm9sOiAnc3F1YXJlJyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6IG1lYXN1cmVDb2xvcnNbMF0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbmFtZTogJ+ebruagh+WAvCcsXG4gICAgICAgICAgICAgICAgdmFsdWU6ICfnm67moIflgLwnLFxuICAgICAgICAgICAgICAgIG1hcmtlcjoge1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2w6ICdsaW5lJyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogbWFya2VyQ29sb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDIsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgICAgIHZhciBsZWdlbmRPcHRpb25zID0gdHNsaWJfMS5fX2Fzc2lnbih7IGN1c3RvbTogdHJ1ZSwgcG9zaXRpb246ICdib3R0b20nLCBpdGVtczogaXRlbXMgfSwgb3B0aW9ucy5sZWdlbmQpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdsZWdlbmRzJywgbGVnZW5kT3B0aW9ucyk7XG4gICAgfTtcbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgYnVsbGV0ID0gZmFjdG9yeV8yLmdldEdlb20oJ2ludGVydmFsJywgJ21haW4nLCB7XG4gICAgICAgICAgICBwb3NpdGlvbkZpZWxkczogW29wdGlvbnMueEZpZWxkLCBvcHRpb25zLnlGaWVsZF0sXG4gICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICB9KTtcbiAgICAgICAgYnVsbGV0LmFkanVzdCA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKG9wdGlvbnMubGFiZWwpIHtcbiAgICAgICAgICAgIGJ1bGxldC5sYWJlbCA9IHRoaXMuZXh0cmFjdExhYmVsKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWxsZXQgPSBidWxsZXQ7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIGJ1bGxldCk7XG4gICAgfTtcbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBFdmVudFBhcnNlcik7XG4gICAgfTtcbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUuZXh0cmFjdExhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGxhYmVsID0gdXRpbF8xLmRlZXBNaXgoe30sIG9wdGlvbnMubGFiZWwpO1xuICAgICAgICBpZiAobGFiZWwudmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFiZWxDb25maWcgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdsYWJlbCcsIHRzbGliXzEuX19hc3NpZ24oeyBwbG90OiB0aGlzLCBsYWJlbFR5cGU6ICdiYXJMYWJlbCcsIGZpZWxkczogW29wdGlvbnMueUZpZWxkXSB9LCBsYWJlbCkpO1xuICAgICAgICByZXR1cm4gbGFiZWxDb25maWc7XG4gICAgfTtcbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUuYWRqdXN0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIG9wdGlvbnMuYmFyU2l6ZSA9IG9wdGlvbnMubWVhc3VyZVNpemUgfHwgMTI7XG4gICAgICAgIHRoaXMuYWRqdXN0WUF4aXNPcHRpb25zKG9wdGlvbnMpO1xuICAgIH07XG4gICAgQnVsbGV0TGF5ZXIucHJvdG90eXBlLmFkanVzdFlBeGlzT3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgICAgb3B0aW9ucy5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHsgcmV0dXJuIHZhbHVlcy5wdXNoKGQubWVhc3VyZXMucmVkdWNlKGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhICsgYjsgfSwgMCkpOyB9KTtcbiAgICAgICAgdmFsdWVzLnB1c2gob3B0aW9ucy5yYW5nZU1heCk7XG4gICAgICAgIG9wdGlvbnMueUF4aXMubWF4ID0gTWF0aC5tYXguYXBwbHkoW10sIHZhbHVlcyk7XG4gICAgfTtcbiAgICBCdWxsZXRMYXllci5wcm90b3R5cGUucHJvY2Vzc0RhdGEgPSBmdW5jdGlvbiAoZGF0YU9wdGlvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBkYXRhID0gW107XG4gICAgICAgIGRhdGFPcHRpb25zLmZvckVhY2goZnVuY3Rpb24gKGRhdGFJdGVtLCBkYXRhSWR4KSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICBmb3IgKHZhciB2YWx1ZUlkeCA9IDA7IHZhbHVlSWR4IDwgZGF0YUl0ZW0ubWVhc3VyZXMubGVuZ3RoOyB2YWx1ZUlkeCArPSAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gZGF0YUl0ZW0ubWVhc3VyZXNbdmFsdWVJZHhdO1xuICAgICAgICAgICAgICAgIHZhciB4RmllbGQgPSBkYXRhSXRlbS50aXRsZSB8fCBcIlwiICsgZGF0YUlkeDtcbiAgICAgICAgICAgICAgICBkYXRhLnB1c2goKF9hID0ge30sXG4gICAgICAgICAgICAgICAgICAgIF9hW29wdGlvbnMueEZpZWxkXSA9IHhGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgX2Fbb3B0aW9ucy55RmllbGRdID0gdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIF9hW29wdGlvbnMuc3RhY2tGaWVsZF0gPSBcIlwiICsgdmFsdWVJZHgsXG4gICAgICAgICAgICAgICAgICAgIF9hKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9O1xuICAgIHJldHVybiBCdWxsZXRMYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJ1bGxldExheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnYnVsbGV0JywgQnVsbGV0TGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciBCVUxMRVRfQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSAqIDAuNSwgbGluZVdpZHRoOiAwIH07XG59O1xudmFyIEJVTExFVF9ESVNBQkxFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSAqIDAuNSB9O1xufTtcbnRoZW1lXzEucmVnaXN0ZXJUaGVtZSgnYnVsbGV0Jywge1xuICAgIGNvbHVtblN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogQlVMTEVUX0FDVElWRV9TVFlMRSxcbiAgICAgICAgZGlzYWJsZTogQlVMTEVUX0RJU0FCTEVfU1RZTEUsXG4gICAgICAgIHNlbGVjdGVkOiB7fSxcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuV0VFS1MgPSBleHBvcnRzLk1PTlRIUyA9IGV4cG9ydHMuRk9STUFUVEVSID0gZXhwb3J0cy5JU19NT05USF9DRU5URVJfRklFTEQgPSBleHBvcnRzLkRBVEVfRklFTEQgPSBleHBvcnRzLldFRUtfRklFTEQgPSBleHBvcnRzLkRBWV9GSUVMRCA9IHZvaWQgMDtcbi8qKlxuICog5b2T5YmN5LiA5ZGo5Lit55qE56ys5Yeg5aSp77yI5ZGo5pelID0gMO+8iVxuICovXG5leHBvcnRzLkRBWV9GSUVMRCA9ICckJGRheSQkJztcbi8qKlxuICog5b2T5YmN5piv5LiA5bm05Lit55qE56ys5Yeg5ZGoXG4gKi9cbmV4cG9ydHMuV0VFS19GSUVMRCA9ICckJHdlZWskJCc7XG4vKipcbiAqIOaXpeacn+Wtl+aute+8jERhdGUg57G75Z6LXG4gKi9cbmV4cG9ydHMuREFURV9GSUVMRCA9ICckJGRhdGUkJCc7XG4vKipcbiAqIOaVsOaNruWkhOeQhumYtuaute+8jOagh+iusOi/meWRqOaYr+WQpuaYr+W9k+aciOS4remXtFxuICovXG5leHBvcnRzLklTX01PTlRIX0NFTlRFUl9GSUVMRCA9ICckJGlzX21vbnRoX2NlbnRlciQkJztcbi8qKlxuICog5qC85byP5YyW5pel5pyfXG4gKi9cbmV4cG9ydHMuRk9STUFUVEVSID0gJ1lZWVktTU0tREQnO1xuLyoqXG4gKiDmnIjku73mnprkuL5cbiAqL1xuZXhwb3J0cy5NT05USFMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ107XG4vKipcbiAqIOWRqOaemuS4vlxuICovXG5leHBvcnRzLldFRUtTID0gWydTJywgJ00nLCAnVCcsICdXJywgJ1QnLCAnRicsICdTJ107XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVWRU5UX01BUFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5FVkVOVF9NQVA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvbkV2ZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLm9uRXZlbnQ7IH0gfSk7XG52YXIgY29tcG9uZW50TWFwID0ge1xuICAgIHJlY3Q6ICdwb2x5Z29uJyxcbn07XG52YXIgU0hBUEVfRVZFTlRfTUFQID0gZXZlbnRfMS5nZXRFdmVudE1hcChjb21wb25lbnRNYXApO1xudXRpbF8xLmFzc2lnbihldmVudF8xLkVWRU5UX01BUCwgU0hBUEVfRVZFTlRfTUFQKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbi8vIOazqOWGjOaXpeWOhuWbvueahOiHquWumuS5iSBzaGFwZVxucmVxdWlyZShcIi4vc2hhcGVcIik7XG4vKipcbiAqIOaXpeWOhuWbvlxuICovXG52YXIgQ2FsZW5kYXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2FsZW5kYXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ2FsZW5kYXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICog5aSN5YaZ54i257G75pa55rOVXG4gICAgICogQHBhcmFtIHByb3BzXG4gICAgICovXG4gICAgQ2FsZW5kYXIucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdjYWxlbmRhcic7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBDYWxlbmRhci5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gQ2FsZW5kYXI7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBDYWxlbmRhcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZmVjaGFfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJmZWNoYVwiKSk7XG52YXIgdmlld19sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2Uvdmlldy1sYXllclwiKSk7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50XCIpO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgZGF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZGF0ZVwiKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9mYWN0b3J5XCIpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xuLyoqXG4gKiDml6Xljoblm75cbiAqL1xudmFyIENhbGVuZGFyTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQ2FsZW5kYXJMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDYWxlbmRhckxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdjYWxlbmRhcic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQ2FsZW5kYXJMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB4QXhpczoge1xuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9IaWRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZ2VuZDogeyB2aXNpYmxlOiBmYWxzZSB9LFxuICAgICAgICAgICAgbWV0YTogKF9hID0ge30sXG4gICAgICAgICAgICAgICAgX2FbY29uc3RhbnRfMS5EQVlfRklFTERdID0ge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnY2F0JyxcbiAgICAgICAgICAgICAgICAgICAgYWxpYXM6ICdEYXknLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IFswLCAxLCAyLCAzLCA0LCA1LCA2XSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF9hW2NvbnN0YW50XzEuV0VFS19GSUVMRF0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjYXQnLFxuICAgICAgICAgICAgICAgICAgICBhbGlhczogJ01vbnRoJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF9hKSxcbiAgICAgICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNob3dUaXRsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzaG93Q3Jvc3NoYWlyczogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnZGF0ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOWkjeWGmeeItuexu+eahOaVsOaNruWkhOeQhuexu++8jOS4u+imgeWujOaIkO+8mlxuICAgICAqIDEuIOeUn+aIkCBwb2x5Z29uIOeahCB4IHkgZmllbGTvvIjomZrmi5/nmoTvvIzml6DpnIDnlKjmiLfkvKDlhaXvvIlcbiAgICAgKlxuICAgICAqIEBwYXJhbSBkYXRhXG4gICAgICovXG4gICAgQ2FsZW5kYXJMYXllci5wcm90b3R5cGUucHJvY2Vzc0RhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgZGF0ZUZpZWxkID0gdGhpcy5vcHRpb25zLmRhdGVGaWVsZDtcbiAgICAgICAgdmFyIGRhdGVSYW5nZSA9IHRoaXMub3B0aW9ucy5kYXRlUmFuZ2U7XG4gICAgICAgIC8vIOe7meS4jum7mOiupOWAvOaYr+W9k+WJjei/meS4gOW5tFxuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKGRhdGVSYW5nZSkpIHtcbiAgICAgICAgICAgIHZhciBkYXRlcyA9IHV0aWxfMS5tYXAoZGF0YSwgZnVuY3Rpb24gKGRhdHVtKSB7IHJldHVybiBmZWNoYV8xLmRlZmF1bHQucGFyc2UoXCJcIiArIGRhdHVtW2RhdGVGaWVsZF0sIGNvbnN0YW50XzEuRk9STUFUVEVSKTsgfSk7XG4gICAgICAgICAgICBkYXRlUmFuZ2UgPSBkYXRlXzEuZ2V0RGF0ZVJhbmdlKGRhdGVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXRpbF8yLmdlbmVyYXRlQ2FsZW5kYXJEYXRhKGRhdGEsIGRhdGVSYW5nZSwgZGF0ZUZpZWxkKTtcbiAgICB9O1xuICAgIENhbGVuZGFyTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHZhbHVlRmllbGQgPSBfYS52YWx1ZUZpZWxkLCBjb2xvcnMgPSBfYS5jb2xvcnMsIHRvb2x0aXAgPSBfYS50b29sdGlwO1xuICAgICAgICB2YXIgcG9seWdvbkNvbmZpZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdwb2x5Z29uJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICAgICAgZmllbGRzOiBbY29uc3RhbnRfMS5XRUVLX0ZJRUxELCBjb25zdGFudF8xLkRBWV9GSUVMRF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2hhcGU6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IFsnY2FsZW5kYXItcG9seWdvbiddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgICAgICAgZmllbGRzOiBbdmFsdWVGaWVsZF0sXG4gICAgICAgICAgICAgICAgdmFsdWVzOiBjb2xvcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHRoaXMuZXh0cmFjdExhYmVsKCksXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0b29sdGlwICYmICh0b29sdGlwLmZpZWxkcyB8fCB0b29sdGlwLmZvcm1hdHRlcikpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VvbWV0cnlUb29sdGlwKHBvbHlnb25Db25maWcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIHBvbHlnb25Db25maWcpO1xuICAgIH07XG4gICAgQ2FsZW5kYXJMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKGdlb21Db25maWcpIHtcbiAgICAgICAgZ2VvbUNvbmZpZy50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICBnZW9tQ29uZmlnLnRvb2x0aXAuZmllbGRzID0gdG9vbHRpcE9wdGlvbnMuZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIGdlb21Db25maWcudG9vbHRpcC5jYWxsYmFjayA9IHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgIGlmICghdG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgZ2VvbUNvbmZpZy50b29sdGlwLmZpZWxkcyA9IFtjb25zdGFudF8xLldFRUtfRklFTEQsIGNvbnN0YW50XzEuREFZX0ZJRUxEXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgQ2FsZW5kYXJMYXllci5wcm90b3R5cGUuZXh0cmFjdExhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBsYWJlbCA9IHByb3BzLmxhYmVsO1xuICAgICAgICBpZiAobGFiZWwgJiYgbGFiZWwudmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdmFsdWVGaWVsZCA9IHRoaXMub3B0aW9ucy52YWx1ZUZpZWxkO1xuICAgICAgICByZXR1cm4gZmFjdG9yeV8xLmdldENvbXBvbmVudCgnbGFiZWwnLCB0c2xpYl8xLl9fYXNzaWduKHsgcGxvdDogdGhpcywgZmllbGRzOiBbdmFsdWVGaWVsZF0sIHBvc2l0aW9uOiAndG9wJywgb2Zmc2V0OiAwIH0sIGxhYmVsKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlhpnlhaXlnZDmoIfns7vphY3nva7vvIzpu5jorqTlop7liqDplZzlg49cbiAgICAgKi9cbiAgICBDYWxlbmRhckxheWVyLnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g6buY6K6k5YGa6ZWc5YOP5aSE55CGXG4gICAgICAgIHZhciBjb29yZGluYXRlQ29uZmlnID0ge1xuICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICAgICAgY2ZnOiB7fSxcbiAgICAgICAgICAgIGFjdGlvbnM6IFtbJ3JlZmxlY3QnLCAneSddXSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2Nvb3JkaW5hdGUnLCBjb29yZGluYXRlQ29uZmlnKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOaXoOmcgCBnZW9tZXRyeSBwYXJzZXLvvIznm7TmjqXkvb/nlKggcG9seWdvbiDljbPlj69cbiAgICAgKi9cbiAgICBDYWxlbmRhckxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH07XG4gICAgQ2FsZW5kYXJMYXllci5wcm90b3R5cGUuYXhpcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHhBeGlzX3BhcnNlciA9IGZhY3RvcnlfMS5nZXRDb21wb25lbnQoJ2F4aXMnLCB7XG4gICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgZGltOiAneCcsXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgeUF4aXNfcGFyc2VyID0gZmFjdG9yeV8xLmdldENvbXBvbmVudCgnYXhpcycsIHtcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICBkaW06ICd5JyxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBheGVzQ29uZmlnID0ge307XG4gICAgICAgIGF4ZXNDb25maWdbY29uc3RhbnRfMS5XRUVLX0ZJRUxEXSA9IHhBeGlzX3BhcnNlcjtcbiAgICAgICAgYXhlc0NvbmZpZ1tjb25zdGFudF8xLkRBWV9GSUVMRF0gPSB5QXhpc19wYXJzZXI7XG4gICAgICAgIC8qKiDlrZjlgqjlnZDmoIfovbTphY3nva7pobnliLBjb25maWcgKi9cbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2F4ZXMnLCBheGVzQ29uZmlnKTtcbiAgICB9O1xuICAgIENhbGVuZGFyTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBtb250aFdlZWsgPSB1dGlsXzIuZ2V0TW9udGhDZW50ZXJXZWVrKHRoaXMub3B0aW9ucy5kYXRlUmFuZ2UpO1xuICAgICAgICAvLyDmi7/lh7ogc2NhbGUg5LqM5qyh5Yqg5bel77yM5Li76KaB5piv6YWN572uIHggeSDkuK3nmoTmoIfpopjmmL7npLpcbiAgICAgICAgdmFyIHNjYWxlcyA9IHRoaXMuY29uZmlnLnNjYWxlcztcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBfYiA9IF9hLndlZWtzLCB3ZWVrcyA9IF9iID09PSB2b2lkIDAgPyBjb25zdGFudF8xLldFRUtTIDogX2IsIF9jID0gX2EubW9udGhzLCBtb250aHMgPSBfYyA9PT0gdm9pZCAwID8gY29uc3RhbnRfMS5NT05USFMgOiBfYztcbiAgICAgICAgdmFyIHggPSBzY2FsZXNbY29uc3RhbnRfMS5XRUVLX0ZJRUxEXTtcbiAgICAgICAgdmFyIHkgPSBzY2FsZXNbY29uc3RhbnRfMS5EQVlfRklFTERdO1xuICAgICAgICAvLyAxLiDorr7nva4gZm9ybWF0dGVyXG4gICAgICAgIHguZm9ybWF0dGVyID0gZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgIHZhciBtID0gbW9udGhXZWVrW3ZdO1xuICAgICAgICAgICAgcmV0dXJuIG0gIT09IHVuZGVmaW5lZCA/IG1vbnRoc1ttXSA6ICcnO1xuICAgICAgICB9O1xuICAgICAgICB5LmZvcm1hdHRlciA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiB3ZWVrc1t2XSB8fCAnJzsgfTtcbiAgICAgICAgLy8gMi4g6K6+572uIGFsaWFzXG4gICAgICAgIHZhciBfZCA9IHRoaXMub3B0aW9ucywgeEF4aXMgPSBfZC54QXhpcywgeUF4aXMgPSBfZC55QXhpcztcbiAgICAgICAgeC5hbGlhcyA9IHV0aWxfMS5nZXQoeEF4aXMsIFsndGl0bGUnLCAndGV4dCddLCB4LmFsaWFzKTtcbiAgICAgICAgeS5hbGlhcyA9IHV0aWxfMS5nZXQoeUF4aXMsIFsndGl0bGUnLCAndGV4dCddLCB5LmFsaWFzKTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ3NjYWxlcycsIHNjYWxlcyk7XG4gICAgfTtcbiAgICBDYWxlbmRhckxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIHJldHVybiBDYWxlbmRhckxheWVyO1xufSh2aWV3X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2FsZW5kYXJMYXllcjtcbi8vIOazqOWGjOWIsOaxoOWtkOS4rVxuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnY2FsZW5kYXInLCBDYWxlbmRhckxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZzJfMSA9IHJlcXVpcmUoXCJAYW50di9nMlwiKTtcbnZhciBjb25zdGFudF8xID0gcmVxdWlyZShcIi4vY29uc3RhbnRcIik7XG52YXIgZGF0ZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZGF0ZVwiKTtcbi8qKlxuICog5rOo5YaM6Ieq5a6a5LmJ5pel5Y6G5Zu+55qEIHNoYXBlXG4gKiBjb2RlIGZyb20gaHR0cHM6Ly9nMi5hbnR2LnZpc2lvbi96aC9leGFtcGxlcy9oZWF0bWFwL2hlYXRtYXAjY2FsZW5kYXItaG9yaXpvbnRhbFxuICovXG5nMl8xLnJlZ2lzdGVyU2hhcGUoJ3BvbHlnb24nLCAnY2FsZW5kYXItcG9seWdvbicsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNFbXB0eShjZmcucG9pbnRzKSkge1xuICAgICAgICAgICAgdmFyIHBvaW50cyA9IGNmZy5wb2ludHM7XG4gICAgICAgICAgICAvLyByZWN0IHBhdGhcbiAgICAgICAgICAgIHZhciBwYXRoID0gW1xuICAgICAgICAgICAgICAgIFsnTScsIHBvaW50c1swXS54LCBwb2ludHNbMF0ueV0sXG4gICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzFdLngsIHBvaW50c1sxXS55XSxcbiAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldLFxuICAgICAgICAgICAgICAgIFsnTCcsIHBvaW50c1szXS54LCBwb2ludHNbM10ueV0sXG4gICAgICAgICAgICAgICAgWydaJ10sXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgcGF0aCA9IHRoaXMucGFyc2VQYXRoKHBhdGgpO1xuICAgICAgICAgICAgdmFyIGF0dHJzID0gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHsgc3Ryb2tlOiAnI2ZmZicsIGxpbmVXaWR0aDogMSwgZmlsbDogY2ZnLmNvbG9yIH0sIGNmZy5zdHlsZSksIHsgcGF0aDogcGF0aCB9KTtcbiAgICAgICAgICAgIHZhciBwb2x5Z29uID0gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgICAgIGF0dHJzOiBhdHRycyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBjZmcuZGF0YVtjb25zdGFudF8xLkRBVEVfRklFTERdO1xuICAgICAgICAgICAgaWYgKGRhdGVfMS5pc0xhc3RXZWVrT2ZNb250aChkYXRlKSkge1xuICAgICAgICAgICAgICAgIHZhciBsaW5lUGF0aCA9IFtcbiAgICAgICAgICAgICAgICAgICAgWydNJywgcG9pbnRzWzJdLngsIHBvaW50c1syXS55XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgcG9pbnRzWzNdLngsIHBvaW50c1szXS55XSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIC8vIOacgOWQjuS4gOWRqOeahOWkmui+ueW9oua3u+WKoOWPs+S+p+i+ueahhlxuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICAgICAgekluZGV4OiAxLFxuICAgICAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogdGhpcy5wYXJzZVBhdGgobGluZVBhdGgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAnIzQwNDA0MCcsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGVfMS5pc0xhc3REYXlPZk1vbnRoKGRhdGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHpJbmRleDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogdGhpcy5wYXJzZVBhdGgoW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCBwb2ludHNbMV0ueCwgcG9pbnRzWzFdLnldLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjNDA0MDQwJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRhaW5lci5zb3J0KCk7XG4gICAgICAgICAgICByZXR1cm4gcG9seWdvbjtcbiAgICAgICAgfVxuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYXBlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRNb250aENlbnRlcldlZWsgPSBleHBvcnRzLmdlbmVyYXRlQ2FsZW5kYXJEYXRhID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZmVjaGFfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJmZWNoYVwiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50XCIpO1xudmFyIGRhdGVfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2RhdGVcIik7XG4vKipcbiAqIOino+aekOaXpeacn1xuICogQHBhcmFtIGRhdGVSYW5nZVxuICovXG5mdW5jdGlvbiBwYXJzZURhdGVSYW5nZShkYXRlUmFuZ2UpIHtcbiAgICB2YXIgX2E7XG4gICAgdmFyIGZyb20gPSBkYXRlUmFuZ2VbMF0sIHRvID0gZGF0ZVJhbmdlWzFdO1xuICAgIHZhciBmcm9tRGF0ZSA9IGZlY2hhXzEuZGVmYXVsdC5wYXJzZShmcm9tLCBjb25zdGFudF8xLkZPUk1BVFRFUik7XG4gICAgdmFyIHRvRGF0ZSA9IGZlY2hhXzEuZGVmYXVsdC5wYXJzZSh0bywgY29uc3RhbnRfMS5GT1JNQVRURVIpO1xuICAgIC8vIOS6pOaNoumhuuW6j1xuICAgIGlmIChmcm9tRGF0ZSA+IHRvRGF0ZSkge1xuICAgICAgICBfYSA9IFtmcm9tRGF0ZSwgdG9EYXRlXSwgdG9EYXRlID0gX2FbMF0sIGZyb21EYXRlID0gX2FbMV07XG4gICAgfVxuICAgIHJldHVybiBbZnJvbURhdGUsIHRvRGF0ZV07XG59XG4vKipcbiAqIOagueaNriByYW5nZSDooaXpvZDml6Xljoblm77nmoTmlbDmja5cbiAqIEBwYXJhbSBkYXRhIOS8oOWFpeaVsOaNrlxuICogQHBhcmFtIGRhdGVSYW5nZSDml6XmnJ/ljLrpl7RcbiAqIEBwYXJhbSBkYXRlRmllbGQg5pel5pyf5a2X5q61XG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlQ2FsZW5kYXJEYXRhKGRhdGEsIGRhdGVSYW5nZSwgZGF0ZUZpZWxkKSB7XG4gICAgdmFyIGFsbCA9IFtdO1xuICAgIHZhciBfYSA9IHBhcnNlRGF0ZVJhbmdlKGRhdGVSYW5nZSksIGZyb21EYXRlID0gX2FbMF0sIHRvRGF0ZSA9IF9hWzFdO1xuICAgIC8vIGNvcHkg5LiA5Lu9XG4gICAgdmFyIGN1cnIgPSBuZXcgRGF0ZShmcm9tRGF0ZSk7XG4gICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIGRhdGVTdHJpbmcgPSBmZWNoYV8xLmRlZmF1bHQuZm9ybWF0KGN1cnIsIGNvbnN0YW50XzEuRk9STUFUVEVSKTtcbiAgICAgICAgLy8g5om+5Yiw5a+55bqU55qE5pWw5o2uXG4gICAgICAgIHZhciBkYXR1bSA9IHV0aWxfMS5maW5kKGRhdGEsIGZ1bmN0aW9uIChkYXR1bSkgeyByZXR1cm4gZGF0dW1bZGF0ZUZpZWxkXSA9PT0gZGF0ZVN0cmluZzsgfSk7XG4gICAgICAgIGFsbC5wdXNoKHRzbGliXzEuX19hc3NpZ24oKF9hID0ge30sIF9hW2NvbnN0YW50XzEuREFZX0ZJRUxEXSA9IGRhdGVfMS5nZXREYXkoY3VyciksIF9hW2NvbnN0YW50XzEuV0VFS19GSUVMRF0gPSBcIlwiICsgZGF0ZV8xLmdldFdlZWsoY3VyciksIF9hW2RhdGVGaWVsZF0gPSBkYXRlU3RyaW5nLCBfYVtjb25zdGFudF8xLkRBVEVfRklFTERdID0gbmV3IERhdGUoY3VyciksIF9hKSwgZGF0dW0pKTtcbiAgICAgICAgLy8g5ZCR5YmN56e75Yqo5LiA5aSpXG4gICAgICAgIGRhdGVfMS5hZHZhbmNlQnkoY3VyciwgZGF0ZV8xLkRBWV9NUyk7XG4gICAgfTtcbiAgICB3aGlsZSAoY3VyciA8PSB0b0RhdGUpIHtcbiAgICAgICAgX2xvb3BfMSgpO1xuICAgIH1cbiAgICByZXR1cm4gYWxsO1xufVxuZXhwb3J0cy5nZW5lcmF0ZUNhbGVuZGFyRGF0YSA9IGdlbmVyYXRlQ2FsZW5kYXJEYXRhO1xuLyoqXG4gKiDorqHnrpfmr4/kuKrmnIjnmoTkuK3pl7TlkajjgIJcbiAqL1xuZnVuY3Rpb24gZ2V0TW9udGhDZW50ZXJXZWVrKGRhdGVSYW5nZSkge1xuICAgIHZhciBfYSA9IHBhcnNlRGF0ZVJhbmdlKGRhdGVSYW5nZSksIGZyb21EYXRlID0gX2FbMF0sIHRvRGF0ZSA9IF9hWzFdO1xuICAgIHZhciBtb250aFdlZWtNYXAgPSBuZXcgTWFwKCk7XG4gICAgZnVuY3Rpb24gYXBwZW5kKGN1cnJlbnQpIHtcbiAgICAgICAgdmFyIG1vbnRoID0gY3VycmVudC5nZXRNb250aCgpOyAvLyDku44gMCDlvIDlp4tcbiAgICAgICAgdmFyIHdlZWsgPSBkYXRlXzEuZ2V0V2VlayhjdXJyZW50KTtcbiAgICAgICAgaWYgKCFtb250aFdlZWtNYXAuaGFzKG1vbnRoKSkge1xuICAgICAgICAgICAgbW9udGhXZWVrTWFwLnNldChtb250aCwgW10pO1xuICAgICAgICB9XG4gICAgICAgIG1vbnRoV2Vla01hcC5nZXQobW9udGgpLnB1c2god2Vlayk7XG4gICAgfVxuICAgIC8vIGNvcHkg5LiA5Lu9XG4gICAgdmFyIGN1cnIgPSBuZXcgRGF0ZShmcm9tRGF0ZSk7XG4gICAgd2hpbGUgKGN1cnIgPD0gdG9EYXRlKSB7XG4gICAgICAgIC8vIOiuvue9ruWIsCBtYXAg5LitXG4gICAgICAgIGFwcGVuZChjdXJyKTtcbiAgICAgICAgLy8g5ZCR5YmN56e75YqoIDcg5aSp77yI5LiA5ZGo77yJXG4gICAgICAgIGRhdGVfMS5hZHZhbmNlQnkoY3VyciwgZGF0ZV8xLkRBWV9NUyAqIDcpO1xuICAgIH1cbiAgICAvLyDlop7liqDmnIDlkI7kuIDkuKrml6XmnJ/nmoTorqHnrpdcbiAgICBpZiAodG9EYXRlIDwgY3Vycikge1xuICAgICAgICBhcHBlbmQodG9EYXRlKTtcbiAgICB9XG4gICAgLy8g5aSE55CG5pWw5o2u77yM6L+U5Zue57uT5p6cXG4gICAgdmFyIHJlc3VsdCA9IHt9OyAvLyB3ZWVrIC0+IG1vbnRoXG4gICAgbW9udGhXZWVrTWFwLmZvckVhY2goZnVuY3Rpb24gKHYsIGspIHtcbiAgICAgICAgdmFyIHcgPSBNYXRoLmNlaWwoKHV0aWxfMS5oZWFkKHYpICsgdXRpbF8xLmxhc3QodikpIC8gMik7IC8vIOWPluW5s+Wdh+WAvFxuICAgICAgICByZXN1bHRbd10gPSBrO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnRzLmdldE1vbnRoQ2VudGVyV2VlayA9IGdldE1vbnRoQ2VudGVyV2Vlaztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBheGlzXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9heGlzXCIpKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGFiZWxcIikpO1xudmFyIHByZVJlbmRlclJlc3BvbnNpdmUgPSBbXTtcbnZhciBhZnRlclJlbmRlclJlc3BvbnNpdmUgPSBbXG4gICAgeyBuYW1lOiAncmVzcG9uc2l2ZUF4aXMnLCBtZXRob2Q6IGF4aXNfMS5kZWZhdWx0IH0sXG4gICAgeyBuYW1lOiAncmVzcG9uc2l2ZUxhYmVsJywgbWV0aG9kOiBsYWJlbF8xLmRlZmF1bHQgfSxcbl07XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgcHJlUmVuZGVyOiBwcmVSZW5kZXJSZXNwb25zaXZlLFxuICAgIGFmdGVyUmVuZGVyOiBhZnRlclJlbmRlclJlc3BvbnNpdmUsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvcmVzcG9uc2l2ZS9hcHBseS9sYWJlbFwiKSk7XG52YXIgQXBwbHlSZXNwb25zaXZlQ29sdW1uTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQXBwbHlSZXNwb25zaXZlQ29sdW1uTGFiZWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQXBwbHlSZXNwb25zaXZlQ29sdW1uTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQXBwbHlSZXNwb25zaXZlQ29sdW1uTGFiZWwucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZ2V0KHRoaXMucGxvdC5vcHRpb25zLCBbJ2xhYmVsJywgJ3Bvc2l0aW9uJ10sICdpbm5lcicpO1xuICAgIH07XG4gICAgcmV0dXJuIEFwcGx5UmVzcG9uc2l2ZUNvbHVtbkxhYmVsO1xufShsYWJlbF8xLmRlZmF1bHQpKTtcbmZ1bmN0aW9uIHJlc3BvbnNpdmVQb2ludExhYmVsKGxheWVyKSB7XG4gICAgdmFyIHJlc3BvbnNpdmVUaGVtZSA9IGxheWVyLmdldFJlc3BvbnNpdmVUaGVtZSgpO1xuICAgIG5ldyBBcHBseVJlc3BvbnNpdmVDb2x1bW5MYWJlbCh7XG4gICAgICAgIHBsb3Q6IGxheWVyLFxuICAgICAgICByZXNwb25zaXZlVGhlbWU6IHJlc3BvbnNpdmVUaGVtZSxcbiAgICB9KTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHJlc3BvbnNpdmVQb2ludExhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL3Jlc3BvbnNpdmUvdGhlbWVcIik7XG4vKiog57uE6KOFdGhlbWUgKi9cbnZhciBjb2x1bW5UaGVtZSA9IHtcbiAgICBsYWJlbDoge1xuICAgICAgICB0b3A6IHtcbiAgICAgICAgICAgIGNvbnN0cmFpbnRzOiBbeyBuYW1lOiAnZWxlbWVudENvbGxpc2lvbicgfV0sXG4gICAgICAgICAgICBydWxlczoge1xuICAgICAgICAgICAgICAgIGVsZW1lbnRDb2xsaXNpb246IFtcbiAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnbm9kZUppdHRlclVwd2FyZCcgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ25vZGVzUmVzYW1wbGluZ0J5U3RhdGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcDogWydtaW4nLCAnbWF4JywgJ21lZGlhbiddLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3RleHRIaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9LFxufTtcbnRoZW1lXzEucmVnaXN0ZXJSZXNwb25zaXZlVGhlbWUoJ2NvbHVtbicsIGNvbHVtblRoZW1lKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRoZW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uLy4uLy4uL2NvbXBvbmVudHMvbGFiZWwvYmFzZVwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vZGVwZW5kZW50c1wiKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGFiZWxcIikpO1xudmFyIHZpZXdfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL3ZpZXdcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgY29sb3JfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL2NvbG9yXCIpO1xuLyoqIOiHquWKqOaooeW8j+eahCBDb2x1bW4g5pWw5o2u5qCH562+77yM5Lya5qC55o2u5Zu+5b2i5ZKM5pWw5o2u5qCH562+6Ieq5Yqo5LyY5YyW5pWw5o2u5qCH562+5biD5bGA5ZKM5qC35byP562JICovXG52YXIgQ29sdW1uQXV0b0xhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbHVtbkF1dG9MYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDb2x1bW5BdXRvTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQ29sdW1uQXV0b0xhYmVsLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLmdldERlZmF1bHRPZmZzZXQoKTtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5nZXRWYWx1ZShlbGVtZW50KTtcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldEVsZW1lbnRTaGFwZUJCb3goZWxlbWVudCk7XG4gICAgICAgIHZhciBtaW5YID0gYmJveC5taW5YLCBtaW5ZID0gYmJveC5taW5ZLCBtYXhZID0gYmJveC5tYXhZLCB3aWR0aCA9IGJib3gud2lkdGg7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgb2Zmc2V0WCA9IF9hLm9mZnNldFgsIG9mZnNldFkgPSBfYS5vZmZzZXRZO1xuICAgICAgICB2YXIgeCA9IG1pblggKyB3aWR0aCAvIDIgKyBvZmZzZXRYO1xuICAgICAgICB2YXIgZGlyID0gdmFsdWUgPiAwID8gLTEgOiAxO1xuICAgICAgICB2YXIgcm9vdCA9IHZhbHVlID4gMCA/IG1pblkgOiBtYXhZO1xuICAgICAgICB2YXIgeSA9IHJvb3QgKyBvZmZzZXQgKiBkaXIgKyBvZmZzZXRZO1xuICAgICAgICAvLyDpu5jorqTlhajpg6jlhYjorr7nva7kuLogdG9wXG4gICAgICAgIHJldHVybiB7IHg6IHgsIHk6IHkgfTtcbiAgICB9O1xuICAgIC8qKiDpu5jorqTnmoQgZmlsbCDlj5boh6rnlKjmiLfphY3nva7miJbkuLvpopjphY3nva4gKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgQ29sdW1uQXV0b0xhYmVsLnByb3RvdHlwZS5nZXRUZXh0RmlsbCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHZhciBzdHlsZSA9IHRoaXMub3B0aW9ucy5zdHlsZTtcbiAgICAgICAgcmV0dXJuIHN0eWxlLmZpbGw7XG4gICAgfTtcbiAgICAvKiog6buY6K6k5LiN5o+P6L65ICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIENvbHVtbkF1dG9MYWJlbC5wcm90b3R5cGUuZ2V0VGV4dFN0cm9rZSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfTtcbiAgICAvKiog6buY6K6k5peg5aSE55CG77ya5ZyoIGxheW91dCDpmLbmrrXlpITnkIYgKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgQ29sdW1uQXV0b0xhYmVsLnByb3RvdHlwZS5hZGp1c3RMYWJlbCA9IGZ1bmN0aW9uIChsYWJlbCwgZWxlbWVudCkge1xuICAgICAgICAvLyBlbXB0eVxuICAgIH07XG4gICAgLyoqIOiHquWKqOW4g+WxgOaJgOacieeahOaVsOaNruagh+etviAqL1xuICAgIENvbHVtbkF1dG9MYWJlbC5wcm90b3R5cGUubGF5b3V0TGFiZWxzID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBsYWJlbHMpIHtcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkSW5TaGFwZUxhYmVscyhsYWJlbHMpKSB7XG4gICAgICAgICAgICB0aGlzLmluU2hhcGVMYWJlbHMoZ2VvbWV0cnksIGxhYmVscyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hdXRvSGlkZUxhYmVscyhnZW9tZXRyeSwgbGFiZWxzKTtcbiAgICB9O1xuICAgIC8qKiDliKTmlq3mmK/lkKblj6/ku6XmiormlbDmja7moIfnrb7mlL7nva7lnKjmn7HlrZDlhoXpg6ggKi9cbiAgICBDb2x1bW5BdXRvTGFiZWwucHJvdG90eXBlLnNob3VsZEluU2hhcGVMYWJlbHMgPSBmdW5jdGlvbiAobGFiZWxzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZXZlcnkobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbEJCb3ggPSBsYWJlbC5nZXRCQm94KCk7XG4gICAgICAgICAgICB2YXIgZWxlbWVudCA9IGxhYmVsLmdldCgnZWxlbWVudCcpO1xuICAgICAgICAgICAgdmFyIGJib3ggPSBfdGhpcy5nZXRFbGVtZW50U2hhcGVCQm94KGVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGJib3gud2lkdGggPj0gbGFiZWxCQm94LndpZHRoO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDlhoXnva7mlbDmja7moIfnrb7vvIzlubboh6rliqjorr7nva7popzoibLmj4/ovrnnrYnlsZ7mgKcgKi9cbiAgICBDb2x1bW5BdXRvTGFiZWwucHJvdG90eXBlLmluU2hhcGVMYWJlbHMgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGxhYmVscykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgY29vcmRpbmF0ZUJCb3ggPSB0aGlzLmdldENvb3JkaW5hdGVCQm94KCk7XG4gICAgICAgIHZhciB4RmllbGQgPSBnZW9tZXRyeS5nZXRYWUZpZWxkcygpWzBdO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIGRhcmtTdHlsZSA9IF9hLmRhcmtTdHlsZSwgbGlnaHRTdHlsZSA9IF9hLmxpZ2h0U3R5bGU7XG4gICAgICAgIHZhciBncm91cGVkTGFiZWxzID0gdXRpbF8xLmdyb3VwQnkobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHsgcmV0dXJuIGxhYmVsLmdldChkZXBlbmRlbnRzXzEuT1JJR0lOKVtkZXBlbmRlbnRzXzEuRklFTERfT1JJR0lOXVt4RmllbGRdOyB9KTtcbiAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgIHZhciBjdXJHcm91cCA9IGdyb3VwZWRMYWJlbHNbbGFiZWwuZ2V0KGRlcGVuZGVudHNfMS5PUklHSU4pW2RlcGVuZGVudHNfMS5GSUVMRF9PUklHSU5dW3hGaWVsZF1dIHx8IFtdO1xuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBsYWJlbC5nZXQoJ2VsZW1lbnQnKTtcbiAgICAgICAgICAgIHZhciBzaGFwZSA9IGVsZW1lbnQuc2hhcGU7XG4gICAgICAgICAgICB2YXIgZmlsbFdoaXRlID0gY29sb3JfMS5pc0NvbnRyYXN0Q29sb3JXaGl0ZShzaGFwZS5hdHRyKCdmaWxsJykpO1xuICAgICAgICAgICAgdmFyIHNoYXBlQkJveCA9IF90aGlzLmdldEVsZW1lbnRTaGFwZUJCb3goZWxlbWVudCk7XG4gICAgICAgICAgICB2YXIgbGFiZWxCQm94ID0gYmJveF8xLmRlZmF1bHQuZnJvbUJCb3hPYmplY3QobGFiZWwuZ2V0QkJveCgpKTtcbiAgICAgICAgICAgIC8vIOWmguaenCBDb2x1bW4g5pys6Lqr5bCx5LiN5Y+v6KeB77yM55u05o6l6ZqQ6JeP5a+55bqU55qEIGxhYmVsXG4gICAgICAgICAgICBpZiAodmlld18xLmdldE92ZXJsYXBBcmVhKGNvb3JkaW5hdGVCQm94LCBzaGFwZUJCb3gpIDw9IDApIHtcbiAgICAgICAgICAgICAgICBsYWJlbC5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFiZWxCQm94LmhlaWdodCA+IHNoYXBlQkJveC5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAvLyDlpITnkIbmlL7kuI3kuIvnmoTmg4XlhrVcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gdXRpbF8xLmZpbmRJbmRleChjdXJHcm91cCwgZnVuY3Rpb24gKGl0ZW0pIHsgcmV0dXJuIGl0ZW0gPT09IGxhYmVsOyB9KTtcbiAgICAgICAgICAgICAgICBpZiAoaWR4ICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyDmlbDmja7moIfnrb7lsZXnpLrlnKjlm77lvaLkuK3lpK5cbiAgICAgICAgICAgICAgICBsYWJlbC5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgeTogc2hhcGVCQm94LnkgKyBzaGFwZUJCb3guaGVpZ2h0IC8gMixcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3cgPSBsYWJlbEJCb3gud2lkdGggPiBzaGFwZUJCb3gud2lkdGggfHwgbGFiZWxCQm94LmhlaWdodCA+IHNoYXBlQkJveC5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgaWYgKG92ZXJmbG93KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOWHuueOsOS6hua6ouWHuuaDheWGte+8jOa3u+WKoOaPj+i+uVxuICAgICAgICAgICAgICAgICAgICBsYWJlbC5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogbGlnaHRTdHlsZSA9PT0gbnVsbCB8fCBsaWdodFN0eWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsaWdodFN0eWxlLnN0cm9rZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyDmlL7nva7lnKjmn7HlvaLlhoXpg6jvvIzpopzoibLlj5blj41cbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBmaWxsV2hpdGUgPyBsaWdodFN0eWxlID09PSBudWxsIHx8IGxpZ2h0U3R5bGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGxpZ2h0U3R5bGUuZmlsbCA6IGRhcmtTdHlsZSA9PT0gbnVsbCB8fCBkYXJrU3R5bGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRhcmtTdHlsZS5maWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IGZpbGxXaGl0ZSA/IGxpZ2h0U3R5bGUgPT09IG51bGwgfHwgbGlnaHRTdHlsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGlnaHRTdHlsZS5maWxsT3BhY2l0eSA6IGRhcmtTdHlsZSA9PT0gbnVsbCB8fCBkYXJrU3R5bGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRhcmtTdHlsZS5maWxsT3BhY2l0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqIOaVsOaNruagh+etvumYsumHjeWPoOaKveagtyAqL1xuICAgIENvbHVtbkF1dG9MYWJlbC5wcm90b3R5cGUuYXV0b0hpZGVMYWJlbHMgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGxhYmVscykge1xuICAgICAgICB2YXIgY29vcmRpbmF0ZUJCb3ggPSB0aGlzLmdldENvb3JkaW5hdGVCQm94KCk7XG4gICAgICAgIHZhciBmaWx0ZXJlZExhYmVscyA9IHRoaXMuZmlsdGVyTGFiZWxzKGxhYmVscyk7XG4gICAgICAgIHZhciB4RmllbGQgPSBnZW9tZXRyeS5nZXRYWUZpZWxkcygpWzBdO1xuICAgICAgICB2YXIgZG9uZXMgPSBbXTtcbiAgICAgICAgdmFyIHRvZG8gPSBbXTtcbiAgICAgICAgdmFyIGdyb3VwZWRMYWJlbHMgPSB1dGlsXzEuZ3JvdXBCeShmaWx0ZXJlZExhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7IHJldHVybiBsYWJlbC5nZXQoZGVwZW5kZW50c18xLk9SSUdJTilbZGVwZW5kZW50c18xLkZJRUxEX09SSUdJTl1beEZpZWxkXTsgfSk7XG4gICAgICAgIHZhciB4VmFsdWVzID0gdXRpbF8xLnVuaXEodXRpbF8xLm1hcChmaWx0ZXJlZExhYmVscywgZnVuY3Rpb24gKGxhYmVsKSB7IHJldHVybiBsYWJlbC5nZXQoZGVwZW5kZW50c18xLk9SSUdJTilbZGVwZW5kZW50c18xLkZJRUxEX09SSUdJTl1beEZpZWxkXTsgfSkpO1xuICAgICAgICB2YXIgeFZhbHVlO1xuICAgICAgICBpZiAodXRpbF8xLnNpemUoeFZhbHVlcykgPiAwKSB7XG4gICAgICAgICAgICAvLyDnrKzkuIDnu4RcbiAgICAgICAgICAgIHhWYWx1ZSA9IHhWYWx1ZXMuc2hpZnQoKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGdyb3VwZWRMYWJlbHNbeFZhbHVlXSwgZnVuY3Rpb24gKGxhYmVsKSB7IHJldHVybiB0b2RvLnB1c2gobGFiZWwpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLnNpemUoeFZhbHVlcykgPiAwKSB7XG4gICAgICAgICAgICAvLyDmnIDlkI7kuIDnu4RcbiAgICAgICAgICAgIHhWYWx1ZSA9IHhWYWx1ZXMucG9wKCk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChncm91cGVkTGFiZWxzW3hWYWx1ZV0sIGZ1bmN0aW9uIChsYWJlbCkgeyByZXR1cm4gdG9kby5wdXNoKGxhYmVsKTsgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdXRpbF8xLmVhY2goeFZhbHVlcy5yZXZlcnNlKCksIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIC8vIOWFtuS7lue7hFxuICAgICAgICAgICAgdXRpbF8xLmVhY2goZ3JvdXBlZExhYmVsc1t2YWxdLCBmdW5jdGlvbiAobGFiZWwpIHsgcmV0dXJuIHRvZG8ucHVzaChsYWJlbCk7IH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgd2hpbGUgKHRvZG8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdmFyIGN1ciA9IHRvZG8uc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChjdXIuZ2V0KCd2aXNpYmxlJykpIHtcbiAgICAgICAgICAgICAgICB2aWV3XzEubW92ZUluUGFuZWwoY3VyLCBjb29yZGluYXRlQkJveCk7XG4gICAgICAgICAgICAgICAgaWYgKHZpZXdfMS5jaGVja1NoYXBlT3ZlcmxhcChjdXIsIGRvbmVzKSkge1xuICAgICAgICAgICAgICAgICAgICBjdXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZXMucHVzaChjdXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqIOaKveagt+aVsOaNruagh+etvu+8jOiuvue9ruacgOWkp+aVsOmHj+eahOaVsOaNruagh+etvu+8jOWFtuS7lueahOe7n+S4gOmakOiXjyAqL1xuICAgIENvbHVtbkF1dG9MYWJlbC5wcm90b3R5cGUuZmlsdGVyTGFiZWxzID0gZnVuY3Rpb24gKGxhYmVscykge1xuICAgICAgICB2YXIgTUFYX0NOVCA9IDUwMDsgLy8g5pyA5aSa5pi+56S6IDUwMCDkuKrmlbDmja7moIfnrb5cbiAgICAgICAgdmFyIGZpbHRlcmVkTGFiZWxzID0gW107XG4gICAgICAgIHZhciBwYWdlcyA9IE1hdGgubWF4KE1hdGguZmxvb3IobGFiZWxzLmxlbmd0aCAvIE1BWF9DTlQpLCAxKTtcbiAgICAgICAgdXRpbF8xLmVhY2gobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwsIGlkeCkge1xuICAgICAgICAgICAgaWYgKGlkeCAlIHBhZ2VzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZmlsdGVyZWRMYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsYWJlbC5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmlsdGVyZWRMYWJlbHM7XG4gICAgfTtcbiAgICByZXR1cm4gQ29sdW1uQXV0b0xhYmVsO1xufShsYWJlbF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IENvbHVtbkF1dG9MYWJlbDtcbmJhc2VfMS5yZWdpc3RlckxhYmVsQ29tcG9uZW50KCdjb2x1bW4tYXV0bycsIENvbHVtbkF1dG9MYWJlbCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYWJlbC1hdXRvLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4uLy4uLy4uL2NvbXBvbmVudHMvbGFiZWwvYmFzZVwiKSk7XG52YXIgY29sb3JfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL2NvbG9yXCIpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL2Jib3hcIikpO1xudmFyIENvbHVtbkxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbHVtbkxhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENvbHVtbkxhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIENvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbEl0ZW1BdHRycyA9IGZ1bmN0aW9uIChlbGVtZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHZhciBfYjtcbiAgICAgICAgdmFyIF9jID0gdGhpcy5vcHRpb25zLCBzdHlsZSA9IF9jLnN0eWxlLCBmb3JtYXR0ZXIgPSBfYy5mb3JtYXR0ZXI7XG4gICAgICAgIHZhciBtYXBwaW5nRGF0YSA9IFtdLmNvbmNhdChlbGVtZW50LmdldE1vZGVsKCkubWFwcGluZ0RhdGEpO1xuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKGVsZW1lbnQpO1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIHN0eWxlLCB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMuZ2V0UG9zaXRpb24oZWxlbWVudCkpLCB7IHRleHQ6IGZvcm1hdHRlclxuICAgICAgICAgICAgICAgID8gZm9ybWF0dGVyKHZhbHVlLCAoX2EgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgX2FbZGVwZW5kZW50c18xLl9PUklHSU5dID0gKF9iID0gbWFwcGluZ0RhdGFbMF0pID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5fb3JpZ2luLFxuICAgICAgICAgICAgICAgICAgICBfYS5tYXBwaW5nRGF0dW0gPSBtYXBwaW5nRGF0YVswXSxcbiAgICAgICAgICAgICAgICAgICAgX2EubWFwcGluZ0RhdHVtSW5kZXggPSAwLFxuICAgICAgICAgICAgICAgICAgICBfYS5lbGVtZW50ID0gZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgX2EuZWxlbWVudEluZGV4ID0gaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIF9hKSwgaW5kZXgpXG4gICAgICAgICAgICAgICAgOiB2YWx1ZSwgZmlsbDogdGhpcy5nZXRUZXh0RmlsbChlbGVtZW50KSwgc3Ryb2tlOiB0aGlzLmdldFRleHRTdHJva2UoZWxlbWVudCksIHRleHRBbGlnbjogdGhpcy5nZXRUZXh0QWxpZ24oKSwgdGV4dEJhc2VsaW5lOiB0aGlzLmdldFRleHRCYXNlTGluZSgpIH0pKTtcbiAgICB9O1xuICAgIENvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRoZW1lID0gdGhpcy5sYXllci50aGVtZTtcbiAgICAgICAgdmFyIF9hID0gdGhlbWUubGFiZWwsIGxhYmVsID0gX2EgPT09IHZvaWQgMCA/IHt9IDogX2E7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHsgb2Zmc2V0WDogMCwgb2Zmc2V0WTogMCwgYWRqdXN0UG9zaXRpb246IHRydWUgfSwgbGFiZWwpO1xuICAgIH07XG4gICAgQ29sdW1uTGFiZWwucHJvdG90eXBlLmFkanVzdExhYmVsID0gZnVuY3Rpb24gKGxhYmVsLCBlbGVtZW50KSB7XG4gICAgICAgIHZhciBhZGp1c3RQb3NpdGlvbiA9IHRoaXMub3B0aW9ucy5hZGp1c3RQb3NpdGlvbjtcbiAgICAgICAgaWYgKGFkanVzdFBvc2l0aW9uKSB7XG4gICAgICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KCk7XG4gICAgICAgICAgICB2YXIgbGFiZWxSYW5nZSA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciBzaGFwZVJhbmdlID0gdGhpcy5nZXRFbGVtZW50U2hhcGVCQm94KGVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKHNoYXBlUmFuZ2UuaGVpZ2h0IDw9IGxhYmVsUmFuZ2UuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHlQb3NpdGlvbiA9IHNoYXBlUmFuZ2UubWluWSArIHRoaXMub3B0aW9ucy5vZmZzZXRZIC0gb2Zmc2V0O1xuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3knLCB5UG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3RleHRCYXNlbGluZScsICdib3R0b20nKTtcbiAgICAgICAgICAgICAgICBsYWJlbC5hdHRyKCdmaWxsJywgdGhpcy5vcHRpb25zLnN0eWxlLmZpbGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBDb2x1bW5MYWJlbC5wcm90b3R5cGUuZ2V0VmFsdWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldChlbGVtZW50LmdldERhdGEoKSwgdGhpcy5sYXllci5vcHRpb25zLnlGaWVsZCk7XG4gICAgfTtcbiAgICBDb2x1bW5MYWJlbC5wcm90b3R5cGUuZ2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXREZWZhdWx0T2Zmc2V0KCk7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoZWxlbWVudCk7XG4gICAgICAgIHZhciBiYm94ID0gdGhpcy5nZXRFbGVtZW50U2hhcGVCQm94KGVsZW1lbnQpO1xuICAgICAgICB2YXIgbWluWCA9IGJib3gubWluWCwgbWluWSA9IGJib3gubWluWSwgbWF4WSA9IGJib3gubWF4WSwgaGVpZ2h0ID0gYmJveC5oZWlnaHQsIHdpZHRoID0gYmJveC53aWR0aDtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFksIHBvc2l0aW9uID0gX2EucG9zaXRpb247XG4gICAgICAgIHZhciB4ID0gbWluWCArIHdpZHRoIC8gMiArIG9mZnNldFg7XG4gICAgICAgIHZhciBkaXIgPSB2YWx1ZSA+IDAgPyAtMSA6IDE7XG4gICAgICAgIHZhciB5O1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICB2YXIgcm9vdCA9IHZhbHVlID4gMCA/IG1pblkgOiBtYXhZO1xuICAgICAgICAgICAgeSA9IHJvb3QgKyBvZmZzZXQgKiBkaXIgKyBvZmZzZXRZO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgdmFyIHJvb3QgPSB2YWx1ZSA+IDAgPyBtYXhZIDogbWluWTtcbiAgICAgICAgICAgIHkgPSByb290ICsgb2Zmc2V0ICogZGlyICsgb2Zmc2V0WTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHkgPSBtaW5ZICsgaGVpZ2h0IC8gMiArIG9mZnNldFk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xuICAgIH07XG4gICAgQ29sdW1uTGFiZWwucHJvdG90eXBlLmdldFRleHRGaWxsID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHNoYXBlID0gZWxlbWVudC5zaGFwZTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hZGp1c3RDb2xvciAmJiB0aGlzLm9wdGlvbnMucG9zaXRpb24gIT09ICd0b3AnKSB7XG4gICAgICAgICAgICB2YXIgc2hhcGVDb2xvciA9IHNoYXBlLmF0dHIoJ2ZpbGwnKTtcbiAgICAgICAgICAgIHZhciBzaGFwZU9wYWNpdHkgPSBzaGFwZS5hdHRyKCdvcGFjaXR5JykgPyBzaGFwZS5hdHRyKCdvcGFjaXR5JykgOiAxO1xuICAgICAgICAgICAgdmFyIHJnYiA9IGNvbG9yXzEucmdiMmFycihzaGFwZUNvbG9yKTtcbiAgICAgICAgICAgIHZhciBncmF5ID0gTWF0aC5yb3VuZChyZ2JbMF0gKiAwLjI5OSArIHJnYlsxXSAqIDAuNTg3ICsgcmdiWzJdICogMC4xMTQpIC8gc2hhcGVPcGFjaXR5O1xuICAgICAgICAgICAgdmFyIGNvbG9yQmFuZCA9IFtcbiAgICAgICAgICAgICAgICB7IGZyb206IDAsIHRvOiA4NSwgY29sb3I6ICd3aGl0ZScgfSxcbiAgICAgICAgICAgICAgICB7IGZyb206IDg1LCB0bzogMTcwLCBjb2xvcjogJyNGNkY2RjYnIH0sXG4gICAgICAgICAgICAgICAgeyBmcm9tOiAxNzAsIHRvOiAyNTUsIGNvbG9yOiAnYmxhY2snIH0sXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgdmFyIHJlZmxlY3QgPSBjb2xvcl8xLm1hcHBpbmdDb2xvcihjb2xvckJhbmQsIGdyYXkpO1xuICAgICAgICAgICAgcmV0dXJuIHJlZmxlY3Q7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRlZmF1bHRDb2xvciA9IHRoaXMub3B0aW9ucy5zdHlsZS5maWxsO1xuICAgICAgICByZXR1cm4gZGVmYXVsdENvbG9yO1xuICAgIH07XG4gICAgQ29sdW1uTGFiZWwucHJvdG90eXBlLmdldFRleHRTdHJva2UgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICB2YXIgZmlsbCA9IHRoaXMuZ2V0VGV4dEZpbGwoZWxlbWVudCk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgcG9zaXRpb24gPSBfYS5wb3NpdGlvbiwgYWRqdXN0Q29sb3IgPSBfYS5hZGp1c3RDb2xvcjtcbiAgICAgICAgcmV0dXJuIHBvc2l0aW9uICE9PSAndG9wJyAmJiBhZGp1c3RDb2xvciAmJiBmaWxsICE9PSAnYmxhY2snID8gbnVsbCA6IHVuZGVmaW5lZDtcbiAgICB9O1xuICAgIENvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRFbGVtZW50U2hhcGVCQm94ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHNoYXBlID0gZWxlbWVudC5zaGFwZTtcbiAgICAgICAgdmFyIHBvaW50cyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChzaGFwZS5nZXQoJ29yaWdpbicpLnBvaW50cywgZnVuY3Rpb24gKHApIHtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKF90aGlzLmNvb3JkLmNvbnZlcnRQb2ludChwKSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgeFZhbHVlcyA9IHBvaW50cy5tYXAoZnVuY3Rpb24gKHBvaW50KSB7IHJldHVybiBwb2ludC54OyB9KTtcbiAgICAgICAgdmFyIHhWYWx1ZXNNaW4gPSBNYXRoLm1pbi5hcHBseShNYXRoLCB4VmFsdWVzKTtcbiAgICAgICAgdmFyIHhWYWx1ZU1heCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHhWYWx1ZXMpO1xuICAgICAgICB2YXIgeVZhbHVlcyA9IHBvaW50cy5tYXAoZnVuY3Rpb24gKHBvaW50KSB7IHJldHVybiBwb2ludC55OyB9KTtcbiAgICAgICAgdmFyIHlWYWx1ZXNNaW4gPSBNYXRoLm1pbi5hcHBseShNYXRoLCB5VmFsdWVzKTtcbiAgICAgICAgdmFyIHlWYWx1ZXNNYXggPSBNYXRoLm1heC5hcHBseShNYXRoLCB5VmFsdWVzKTtcbiAgICAgICAgdmFyIGJib3ggPSBuZXcgYmJveF8xLmRlZmF1bHQoeFZhbHVlc01pbiwgeVZhbHVlc01pbiwgeFZhbHVlTWF4IC0geFZhbHVlc01pbiwgeVZhbHVlc01heCAtIHlWYWx1ZXNNaW4pO1xuICAgICAgICByZXR1cm4gYmJveDtcbiAgICB9O1xuICAgIENvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRUZXh0QWxpZ24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnY2VudGVyJztcbiAgICB9O1xuICAgIENvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRUZXh0QmFzZUxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnbWlkZGxlJztcbiAgICB9O1xuICAgIENvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbE9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQ29sdW1uIOeahCBvZmZzZXQg5ZyoIGdldFBvc2l0aW9uIOS4reWboCBwb3NpdGlvbiDkuI3lkIzljZXni6zlpITnkIZcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIENvbHVtbkxhYmVsO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sdW1uTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnY29sdW1uJywgQ29sdW1uTGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBjb2x1bW46ICdpbnRlcnZhbCcsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgQ29sdW1uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbHVtbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDb2x1bW4oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQ29sdW1uLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnY29sdW1uJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIENvbHVtbi5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gQ29sdW1uO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sdW1uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnZhciBjb252ZXJzaW9uX3RhZ18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2NvbXBvbmVudHMvY29udmVyc2lvbi10YWdcIikpO1xudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9zY2FsZVwiKTtcbnZhciBhcHBseV9yZXNwb25zaXZlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9hcHBseS1yZXNwb25zaXZlXCIpKTtcbnJlcXVpcmUoXCIuL2FwcGx5LXJlc3BvbnNpdmUvdGhlbWVcIik7XG5yZXF1aXJlKFwiLi9jb21wb25lbnQvbGFiZWxcIik7XG5yZXF1aXJlKFwiLi9jb21wb25lbnQvbGFiZWwtYXV0b1wiKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnJlcXVpcmUoXCIuL3RoZW1lXCIpO1xudmFyIHZpZXdfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3ZpZXdcIik7XG52YXIgRzJfR0VPTV9NQVAgPSB7XG4gICAgY29sdW1uOiAnaW50ZXJ2YWwnLFxufTtcbnZhciBQTE9UX0dFT01fTUFQID0ge1xuICAgIGludGVydmFsOiAnY29sdW1uJyxcbn07XG52YXIgQmFzZUNvbHVtbkxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEJhc2VDb2x1bW5MYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCYXNlQ29sdW1uTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2NvbHVtbic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQmFzZUNvbHVtbkxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB4QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hhcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNob3dDcm9zc2hhaXJzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzaG93TWFya2VyczogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ3RvcCcsXG4gICAgICAgICAgICAgICAgYWRqdXN0Q29sb3I6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ3RvcC1sZWZ0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbnRlcmFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICB7IHR5cGU6ICd0b29sdGlwJyB9LFxuICAgICAgICAgICAgICAgIHsgdHlwZTogJ2FjdGl2ZS1yZWdpb24nIH0sXG4gICAgICAgICAgICAgICAgeyB0eXBlOiAnbGVnZW5kLWFjdGl2ZScgfSxcbiAgICAgICAgICAgICAgICB7IHR5cGU6ICdsZWdlbmQtZmlsdGVyJyB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNvbnZlcnNpb25UYWc6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5iZWZvcmVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmJlZm9yZUluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgLyoqIOWTjeW6lOW8j+WbvuW9oiAqL1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUgJiYgdGhpcy5vcHRpb25zLnBhZGRpbmcgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5hcHBseVJlc3BvbnNpdmUoJ3ByZVJlbmRlcicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBCYXNlQ29sdW1uTGF5ZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHRoaXMucmVuZGVyTGFiZWwoKTtcbiAgICAgICAgLyoqIOWTjeW6lOW8jyAqL1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUgJiYgdGhpcy5vcHRpb25zLnBhZGRpbmcgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5hcHBseVJlc3BvbnNpdmUoJ2FmdGVyUmVuZGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLmNvbnZlcnNpb25UYWcudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5jb252ZXJzaW9uVGFnID0gbmV3IGNvbnZlcnNpb25fdGFnXzEuZGVmYXVsdCh0c2xpYl8xLl9fYXNzaWduKHsgdmlldzogdGhpcy52aWV3LCBmaWVsZDogcHJvcHMueUZpZWxkLCB0cmFuc3Bvc2U6IHRydWUsIGFuaW1hdGlvbjogcHJvcHMuYW5pbWF0aW9uID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZSB9LCBwcm9wcy5jb252ZXJzaW9uVGFnKSk7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgaWYgKGRpbSA9PT0gJ2cyJykge1xuICAgICAgICAgICAgcmV0dXJuIEcyX0dFT01fTUFQW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQTE9UX0dFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uIChvcmlnaW5EYXRhKSB7XG4gICAgICAgIHZhciB4RmllbGQgPSB0aGlzLm9wdGlvbnMueEZpZWxkO1xuICAgICAgICB2YXIgcHJvY2Vzc2VkRGF0YSA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChvcmlnaW5EYXRhLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgdmFyIGQgPSB1dGlsXzEuY2xvbmUoZGF0YSk7XG4gICAgICAgICAgICBkW3hGaWVsZF0gPSBkW3hGaWVsZF0udG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHByb2Nlc3NlZERhdGEucHVzaChkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwcm9jZXNzZWREYXRhO1xuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgLyoqIOmFjee9rngtc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW29wdGlvbnMueEZpZWxkXSA9IHsgdHlwZTogJ2NhdCcgfTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMob3B0aW9ucywgJ3hBeGlzJykpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlc1tvcHRpb25zLnhGaWVsZF0sIG9wdGlvbnMueEF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIC8qKiDphY3nva55LXNjYWxlICovXG4gICAgICAgIHNjYWxlc1tvcHRpb25zLnlGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMob3B0aW9ucywgJ3lBeGlzJykpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlc1tvcHRpb25zLnlGaWVsZF0sIG9wdGlvbnMueUF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBCYXNlQ29sdW1uTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICAvL2VzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBCYXNlQ29sdW1uTGF5ZXIucHJvdG90eXBlLmFkanVzdENvbHVtbiA9IGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBjb2x1bW4gPSBmYWN0b3J5XzEuZ2V0R2VvbSgnaW50ZXJ2YWwnLCAnbWFpbicsIHtcbiAgICAgICAgICAgIHBvc2l0aW9uRmllbGRzOiBbb3B0aW9ucy54RmllbGQsIG9wdGlvbnMueUZpZWxkXSxcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAob3B0aW9ucy5jb252ZXJzaW9uVGFnLnZpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29uZmlnKCd0aGVtZScsIHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLmdldFRoZW1lKCksIHtcbiAgICAgICAgICAgICAgICBjb2x1bW5XaWR0aFJhdGlvOiAxIC8gMyxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkanVzdENvbHVtbihjb2x1bW4pO1xuICAgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjtcbiAgICAgICAgaWYgKG9wdGlvbnMudG9vbHRpcCAmJiAob3B0aW9ucy50b29sdGlwLmZpZWxkcyB8fCBvcHRpb25zLnRvb2x0aXAuZm9ybWF0dGVyKSkge1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeVRvb2x0aXAoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBjb2x1bW4pO1xuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29sdW1uLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uLnRvb2x0aXAuZmllbGRzID0gdG9vbHRpcE9wdGlvbnMuZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAoIXRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmZpZWxkcy5wdXNoKHRoaXMub3B0aW9ucy5jb2xvckZpZWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEJhc2VDb2x1bW5MYXllci5wcm90b3R5cGUuYW5pbWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFuaW1hdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8qKiDlhbPpl63liqjnlLsgKi9cbiAgICAgICAgICAgIHRoaXMuY29sdW1uLmFuaW1hdGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIEJhc2VDb2x1bW5MYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmNvbmZpZy5zY2FsZXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgbGFiZWwgPSBfYS5sYWJlbCwgeUZpZWxkID0gX2EueUZpZWxkO1xuICAgICAgICB2YXIgc2NhbGUgPSBzY2FsZXNbeUZpZWxkXTtcbiAgICAgICAgaWYgKGxhYmVsID09PSBudWxsIHx8IGxhYmVsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsYWJlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnkgPSB2aWV3XzEuZ2V0R2VvbWV0cnlCeVR5cGUodGhpcy52aWV3LCAnaW50ZXJ2YWwnKTtcbiAgICAgICAgICAgIHRoaXMuZG9SZW5kZXJMYWJlbChnZW9tZXRyeSwgdHNsaWJfMS5fX2Fzc2lnbih7IHR5cGU6ICdjb2x1bW4nLCBmb3JtYXR0ZXI6IHNjYWxlLmZvcm1hdHRlciAmJiAoZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBzY2FsZS5mb3JtYXR0ZXIodmFsdWUpOyB9KSB9LCB0aGlzLm9wdGlvbnMubGFiZWwpKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQmFzZUNvbHVtbkxheWVyLnByb3RvdHlwZS5hcHBseVJlc3BvbnNpdmUgPSBmdW5jdGlvbiAoc3RhZ2UpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1ldGhvZHMgPSBhcHBseV9yZXNwb25zaXZlXzEuZGVmYXVsdFtzdGFnZV07XG4gICAgICAgIHV0aWxfMS5lYWNoKG1ldGhvZHMsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICB2YXIgcmVzcG9uc2l2ZSA9IHI7XG4gICAgICAgICAgICByZXNwb25zaXZlLm1ldGhvZChfdGhpcyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEJhc2VDb2x1bW5MYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJhc2VDb2x1bW5MYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ2NvbHVtbicsIEJhc2VDb2x1bW5MYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuREVGQVVMVF9DT0xVTU5fVEhFTUUgPSB2b2lkIDA7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciBDT0xVTU5fQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSAqIDAuNSB9O1xufTtcbnZhciBDT0xVTU5fRElTQUJMRV9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IG9wYWNpdHk6IG9wYWNpdHkgKiAwLjUsIGZpbGxPcGFjaXR5OiBvcGFjaXR5ICogMC41IH07XG59O1xuZXhwb3J0cy5ERUZBVUxUX0NPTFVNTl9USEVNRSA9IHtcbiAgICBsYWJlbDoge1xuICAgICAgICBkYXJrU3R5bGU6IHtcbiAgICAgICAgICAgIGZpbGw6ICcjMmMzNTQyJyxcbiAgICAgICAgICAgIHN0cm9rZTogJyNmZmZmZmYnLFxuICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDAuODUsXG4gICAgICAgIH0sXG4gICAgICAgIGxpZ2h0U3R5bGU6IHtcbiAgICAgICAgICAgIGZpbGw6ICcjZmZmZmZmJyxcbiAgICAgICAgICAgIHN0cm9rZTogJyNmZmZmZmYnLFxuICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDEsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBjb2x1bW5TdHlsZToge1xuICAgICAgICBub3JtYWw6IHt9LFxuICAgICAgICBhY3RpdmU6IENPTFVNTl9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IENPTFVNTl9ESVNBQkxFX1NUWUxFLFxuICAgICAgICBzZWxlY3RlZDogeyBsaW5lV2lkdGg6IDEsIHN0cm9rZTogJ2JsYWNrJyB9LFxuICAgIH0sXG59O1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdjb2x1bW4nLCBleHBvcnRzLkRFRkFVTFRfQ09MVU1OX1RIRU1FKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRoZW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgd2FybmluZ18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIndhcm5pbmdcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vZ3JvdXBlZC1iYXIvbGF5ZXJcIikpO1xudmFyIEdyb3VwQmFyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEdyb3VwQmFyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyb3VwQmFyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEdyb3VwQmFyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnZ3JvdXBlZEJhcic7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgICAgIHdhcm5pbmdfMS5kZWZhdWx0KGZhbHNlLCAnUGxlYXNlIHVzZSBcIkdyb3VwZWRCYXJcIiBpbnN0ZWFkIG9mIFwiR3JvdXBCYXJcIiB3aGljaCB3YXMgbm90IHJlY29tbWVuZGVkLicpO1xuICAgIH07XG4gICAgR3JvdXBCYXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIEdyb3VwQmFyO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JvdXBCYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIHdhcm5pbmdfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJ3YXJuaW5nXCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2dyb3VwZWQtY29sdW1uL2xheWVyXCIpKTtcbnZhciBHcm91cENvbHVtbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cENvbHVtbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBHcm91cENvbHVtbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBHcm91cENvbHVtbi5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2dyb3VwZWRDb2x1bW4nO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgICAgICB3YXJuaW5nXzEuZGVmYXVsdChmYWxzZSwgJ1BsZWFzZSB1c2UgXCJHcm91cGVkQ29sdW1uXCIgaW5zdGVhZCBvZiBcIkdyb3VwQ29sdW1uXCIgd2hpY2ggd2FzIG5vdCByZWNvbW1lbmRlZC4nKTtcbiAgICB9O1xuICAgIEdyb3VwQ29sdW1uLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBHcm91cENvbHVtbjtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdyb3VwQ29sdW1uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vLyDlhbzlrrkgMC5455qE5Zu+6KGo57G75Z6LXG52YXIgcmluZ18xID0gcmVxdWlyZShcIi4vcmluZ1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlJpbmdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJpbmdfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGdyb3VwX2NvbHVtbl8xID0gcmVxdWlyZShcIi4vZ3JvdXAtY29sdW1uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiR3JvdXBDb2x1bW5cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdyb3VwX2NvbHVtbl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZ3JvdXBfYmFyXzEgPSByZXF1aXJlKFwiLi9ncm91cC1iYXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcm91cEJhclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZ3JvdXBfYmFyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBwZXJjZW50YWdlX3N0YWNrX2FyZWFfMSA9IHJlcXVpcmUoXCIuL3BlcmNlbnRhZ2Utc3RhY2stYXJlYVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBlcmNlbnRhZ2VTdGFja0FyZWFcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHBlcmNlbnRhZ2Vfc3RhY2tfYXJlYV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcGVyY2VudGFnZV9zdGFja19iYXJfMSA9IHJlcXVpcmUoXCIuL3BlcmNlbnRhZ2Utc3RhY2stYmFyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUGVyY2VudGFnZVN0YWNrQmFyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBwZXJjZW50YWdlX3N0YWNrX2Jhcl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcGVyY2VudGFnZV9zdGFja19jb2x1bW5fMSA9IHJlcXVpcmUoXCIuL3BlcmNlbnRhZ2Utc3RhY2stY29sdW1uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUGVyY2VudGFnZVN0YWNrQ29sdW1uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBwZXJjZW50YWdlX3N0YWNrX2NvbHVtbl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgc3RhY2tfYXJlYV8xID0gcmVxdWlyZShcIi4vc3RhY2stYXJlYVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0YWNrQXJlYVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc3RhY2tfYXJlYV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgc3RhY2tfYmFyXzEgPSByZXF1aXJlKFwiLi9zdGFjay1iYXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTdGFja0JhclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc3RhY2tfYmFyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBzdGFja19jb2x1bW5fMSA9IHJlcXVpcmUoXCIuL3N0YWNrLWNvbHVtblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0YWNrQ29sdW1uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzdGFja19jb2x1bW5fMS5kZWZhdWx0OyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciB3YXJuaW5nXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwid2FybmluZ1wiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9wZXJjZW50LXN0YWNrZWQtYXJlYS9sYXllclwiKSk7XG52YXIgUGVyY2VudGFnZVN0YWNrQXJlYSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQZXJjZW50YWdlU3RhY2tBcmVhLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBlcmNlbnRhZ2VTdGFja0FyZWEoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUGVyY2VudGFnZVN0YWNrQXJlYS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3BlcmNlbnRTdGFja2VkQXJlYSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgICAgIHdhcm5pbmdfMS5kZWZhdWx0KGZhbHNlLCAnUGxlYXNlIHVzZSBcIlBlcmNlbnRTdGFja2VkQXJlYVwiIGluc3RlYWQgb2YgXCJQZXJjZW50YWdlU3RhY2tBcmVhXCIgd2hpY2ggd2FzIG5vdCByZWNvbW1lbmRlZC4nKTtcbiAgICB9O1xuICAgIFBlcmNlbnRhZ2VTdGFja0FyZWEuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFBlcmNlbnRhZ2VTdGFja0FyZWE7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQZXJjZW50YWdlU3RhY2tBcmVhO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciB3YXJuaW5nXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwid2FybmluZ1wiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9wZXJjZW50LXN0YWNrZWQtYmFyL2xheWVyXCIpKTtcbnZhciBQZXJjZW50YWdlU3RhY2tCYXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGVyY2VudGFnZVN0YWNrQmFyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBlcmNlbnRhZ2VTdGFja0JhcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBQZXJjZW50YWdlU3RhY2tCYXIucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdwZXJjZW50U3RhY2tlZEJhcic7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgICAgIHdhcm5pbmdfMS5kZWZhdWx0KGZhbHNlLCAnUGxlYXNlIHVzZSBcIlBlcmNlbnRTdGFja2VkQmFyXCIgaW5zdGVhZCBvZiBcIlBlcmNlbnRhZ2VTdGFja0JhclwiIHdoaWNoIHdhcyBub3QgcmVjb21tZW5kZWQuJyk7XG4gICAgfTtcbiAgICBQZXJjZW50YWdlU3RhY2tCYXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFBlcmNlbnRhZ2VTdGFja0Jhcjtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBlcmNlbnRhZ2VTdGFja0Jhcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgd2FybmluZ18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIndhcm5pbmdcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vcGVyY2VudC1zdGFja2VkLWNvbHVtbi9sYXllclwiKSk7XG52YXIgUGVyY2VudGFnZVN0YWNrQ29sdW1uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBlcmNlbnRhZ2VTdGFja0NvbHVtbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQZXJjZW50YWdlU3RhY2tDb2x1bW4oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUGVyY2VudGFnZVN0YWNrQ29sdW1uLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAncGVyY2VudFN0YWNrZWRDb2x1bW4nO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgICAgICB3YXJuaW5nXzEuZGVmYXVsdChmYWxzZSwgJ1BsZWFzZSB1c2UgXCJQZXJjZW50U3RhY2tlZENvbHVtblwiIGluc3RlYWQgb2YgXCJQZXJjZW50YWdlU3RhY2tDb2x1bW5cIiB3aGljaCB3YXMgbm90IHJlY29tbWVuZGVkLicpO1xuICAgIH07XG4gICAgUGVyY2VudGFnZVN0YWNrQ29sdW1uLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBQZXJjZW50YWdlU3RhY2tDb2x1bW47XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQZXJjZW50YWdlU3RhY2tDb2x1bW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIHdhcm5pbmdfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJ3YXJuaW5nXCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2RvbnV0L2xheWVyXCIpKTtcbnZhciBSaW5nID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJpbmcsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmluZygpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBSaW5nLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnZG9udXQnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgICAgICB3YXJuaW5nXzEuZGVmYXVsdChmYWxzZSwgJ1BsZWFzZSB1c2UgXCJEb251dFwiIGluc3RlYWQgb2YgXCJSaW5nXCIgd2hpY2ggd2FzIG5vdCByZWNvbW1lbmRlZC4nKTtcbiAgICB9O1xuICAgIFJpbmcuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFJpbmc7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSaW5nO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciB3YXJuaW5nXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwid2FybmluZ1wiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9zdGFja2VkLWFyZWEvbGF5ZXJcIikpO1xudmFyIFN0YWNrQXJlYSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTdGFja0FyZWEsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tBcmVhKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFN0YWNrQXJlYS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3N0YWNrZWRBcmVhJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICAgICAgd2FybmluZ18xLmRlZmF1bHQoZmFsc2UsICdQbGVhc2UgdXNlIFwiU3RhY2tlZEFyZWFcIiBpbnN0ZWFkIG9mIFwiU3RhY2tBcmVhXCIgd2hpY2ggd2FzIG5vdCByZWNvbW1lbmRlZC4nKTtcbiAgICB9O1xuICAgIFN0YWNrQXJlYS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gU3RhY2tBcmVhO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tBcmVhO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciB3YXJuaW5nXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwid2FybmluZ1wiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9zdGFja2VkLWJhci9sYXllclwiKSk7XG52YXIgU3RhY2tCYXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tCYXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tCYXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgU3RhY2tCYXIucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdzdGFja2VkQmFyJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICAgICAgd2FybmluZ18xLmRlZmF1bHQoZmFsc2UsICdQbGVhc2UgdXNlIFwiU3RhY2tlZEJhclwiIGluc3RlYWQgb2YgXCJTdGFja0JhclwiIHdoaWNoIHdhcyBub3QgcmVjb21tZW5kZWQuJyk7XG4gICAgfTtcbiAgICBTdGFja0Jhci5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gU3RhY2tCYXI7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGFja0Jhcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgd2FybmluZ18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIndhcm5pbmdcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vc3RhY2tlZC1jb2x1bW4vbGF5ZXJcIikpO1xudmFyIFN0YWNrQ29sdW1uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrQ29sdW1uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFN0YWNrQ29sdW1uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFN0YWNrQ29sdW1uLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnc3RhY2tlZENvbHVtbic7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgICAgIHdhcm5pbmdfMS5kZWZhdWx0KGZhbHNlLCAnUGxlYXNlIHVzZSBcIlN0YWNrZWRDb2x1bW5cIiBpbnN0ZWFkIG9mIFwiU3RhY2tDb2x1bW5cIiB3aGljaCB3YXMgbm90IHJlY29tbWVuZGVkLicpO1xuICAgIH07XG4gICAgU3RhY2tDb2x1bW4uZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFN0YWNrQ29sdW1uO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tDb2x1bW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50X2VtaXR0ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJAYW50di9ldmVudC1lbWl0dGVyXCIpKTtcbnZhciBIZWF0bWFwQmFja2dyb3VuZCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhIZWF0bWFwQmFja2dyb3VuZCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIZWF0bWFwQmFja2dyb3VuZChjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMub3B0aW9ucyA9IGNmZztcbiAgICAgICAgX3RoaXMudmlldyA9IF90aGlzLm9wdGlvbnMudmlldztcbiAgICAgICAgX3RoaXMuaW5pdCgpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEhlYXRtYXBCYWNrZ3JvdW5kLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29vcmQgPSB0aGlzLmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdGhpcy53aWR0aCA9IGNvb3JkLmdldFdpZHRoKCk7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gY29vcmQuZ2V0SGVpZ2h0KCk7XG4gICAgICAgIHRoaXMueCA9IGNvb3JkLnN0YXJ0Lng7XG4gICAgICAgIHRoaXMueSA9IGNvb3JkLmVuZC55O1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMudmlldy5iYWNrZ3JvdW5kR3JvdXAuYWRkR3JvdXAoe30pO1xuICAgIH07XG4gICAgSGVhdG1hcEJhY2tncm91bmQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50eXBlID09PSAnY29sb3InKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckNvbG9yQmFja2dyb3VuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMub3B0aW9ucy50eXBlID09PSAnaW1hZ2UnKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckltYWdlQmFja2dyb3VuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMub3B0aW9ucy5jYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIGNhbGxiYWNrQ2ZnID0ge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMueCxcbiAgICAgICAgICAgICAgICB5OiB0aGlzLnksXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5jYWxsYmFjayhjYWxsYmFja0NmZyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEhlYXRtYXBCYWNrZ3JvdW5kLnByb3RvdHlwZS5yZW5kZXJDb2xvckJhY2tncm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFkZFNoYXBlKCdyZWN0Jywge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLngsXG4gICAgICAgICAgICAgICAgeTogdGhpcy55LFxuICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQsXG4gICAgICAgICAgICAgICAgZmlsbDogdGhpcy5vcHRpb25zLnZhbHVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5hbWU6ICdoZWF0bWFwLWJhY2tncm91bmQnLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhlYXRtYXBCYWNrZ3JvdW5kLnByb3RvdHlwZS5yZW5kZXJJbWFnZUJhY2tncm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFkZFNoYXBlKCdpbWFnZScsIHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogdGhpcy54LFxuICAgICAgICAgICAgICAgIHk6IHRoaXMueSxcbiAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy53aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0LFxuICAgICAgICAgICAgICAgIGltZzogdGhpcy5vcHRpb25zLnNyYyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuYW1lOiAnaGVhdG1hcC1iYWNrZ3JvdW5kJyxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBIZWF0bWFwQmFja2dyb3VuZC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnYmFja2dyb3VuZDpjbGVhcicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBIZWF0bWFwQmFja2dyb3VuZC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgICAgIC8vIOS9v+eUqGNhbGxiYWNr5a6a5Yi255qEaHRtbCBiYWNrZ3JvdW5k6ZyA6KaB6Ieq5bex55uR5ZCs6ZSA5q+B5LqL5Lu26Ieq6KGM6ZSA5q+BXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2JhY2tncm91bmQ6ZGVzdHJveScpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBIZWF0bWFwQmFja2dyb3VuZC5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvb3JkaW5hdGU7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMudmlldy5nZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbSkge1xuICAgICAgICAgICAgaWYgKGdlb20udHlwZSA9PT0gJ2hlYXRtYXAnKSB7XG4gICAgICAgICAgICAgICAgY29vcmRpbmF0ZSA9IGdlb20uY29vcmRpbmF0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb29yZGluYXRlO1xuICAgIH07XG4gICAgcmV0dXJuIEhlYXRtYXBCYWNrZ3JvdW5kO1xufShldmVudF9lbWl0dGVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSGVhdG1hcEJhY2tncm91bmQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYWNrZ3JvdW5kLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRQbG90Q29tcG9uZW50cyA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhY2tncm91bmRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2JhY2tncm91bmRcIikpO1xudmFyIGxlZ2VuZF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGVnZW5kXCIpKTtcbnZhciBDb21wb25lbnRzSW5mbyA9IHtcbiAgICBiYWNrZ3JvdW5kOiB7IEN0cjogYmFja2dyb3VuZF8xLmRlZmF1bHQgfSxcbiAgICBsZWdlbmQ6IHsgQ3RyOiBsZWdlbmRfMS5kZWZhdWx0LCBwYWRkaW5nOiAnb3V0ZXInIH0sXG59O1xuZnVuY3Rpb24gZ2V0UGxvdENvbXBvbmVudHMocGxvdCwgdHlwZSwgY2ZnKSB7XG4gICAgaWYgKHBsb3Qub3B0aW9uc1t0eXBlXSAmJiBwbG90Lm9wdGlvbnNbdHlwZV0udmlzaWJsZSkge1xuICAgICAgICB2YXIgY29tcG9uZW50SW5mbyA9IENvbXBvbmVudHNJbmZvW3R5cGVdO1xuICAgICAgICB2YXIgY29tcG9uZW50ID0gbmV3IGNvbXBvbmVudEluZm8uQ3RyKGNmZyk7XG4gICAgICAgIGlmIChjb21wb25lbnRJbmZvLnBhZGRpbmcpIHtcbiAgICAgICAgICAgIHBsb3QucGFkZGluZ0NvbnRyb2xsZXIucmVnaXN0ZXJQYWRkaW5nKGNvbXBvbmVudCwgY29tcG9uZW50SW5mby5wYWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tcG9uZW50O1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0UGxvdENvbXBvbmVudHMgPSBnZXRQbG90Q29tcG9uZW50cztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgTEFCRUxfTUFSR0lOID0gNDtcbnZhciBBQ1RJVkVfT1BBQ0lUWSA9IDE7XG52YXIgREVBQ1RJVkVfT1BBQ0lUWSA9IDAuMTtcbnZhciBIZWF0bWFwTGVnZW5kID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEhlYXRtYXBMZWdlbmQoY2ZnKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZGF0YVNsaWRlcyA9IHt9O1xuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmdldERlZmF1bHRPcHRpb25zKCk7XG4gICAgICAgIGlmIChjZmcucGxvdC5vcHRpb25zLnRoZW1lICYmIGNmZy5wbG90Lm9wdGlvbnMudGhlbWUgPT09ICdkYXJrJykge1xuICAgICAgICAgICAgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmdldERhcmtPcHRpb25zKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRPcHRpb25zLCBjZmcpO1xuICAgICAgICB0aGlzLnZpZXcgPSB0aGlzLm9wdGlvbnMudmlldztcbiAgICAgICAgdGhpcy5hZnRlclJlbmRlciA9IHRydWU7XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmxheW91dCA9IHRoaXMuZ2V0TGF5b3V0KCk7XG4gICAgICAgIHRoaXMud2lkdGggPSB0aGlzLm9wdGlvbnMud2lkdGggPyB0aGlzLm9wdGlvbnMud2lkdGggOiB0aGlzLmdldERlZmF1bHRXaWR0aCgpO1xuICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQgPyB0aGlzLm9wdGlvbnMuaGVpZ2h0IDogdGhpcy5nZXREZWZhdWx0SGVpZ2h0KCk7XG4gICAgICAgIHZhciBwbG90Q29udGFpbmVyID0gdGhpcy5vcHRpb25zLnBsb3QuY29udGFpbmVyO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHBsb3RDb250YWluZXIuYWRkR3JvdXAoKTtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNjYWxlcyA9IHRoaXMuZ2V0U2NhbGVzKCk7XG4gICAgICAgIHZhciBjb2xvckZpZWxkID0gdGhpcy5vcHRpb25zLnBsb3Qub3B0aW9ucy5jb2xvckZpZWxkO1xuICAgICAgICB0aGlzLmNvbG9yU2NhbGUgPSBzY2FsZXNbY29sb3JGaWVsZF07XG4gICAgICAgIHZhciBfYSA9IHRoaXMuY29sb3JTY2FsZSwgbWluID0gX2EubWluLCBtYXggPSBfYS5tYXg7XG4gICAgICAgIHZhciBjb2xvciA9IHRoaXMub3B0aW9ucy5wbG90Lm9wdGlvbnMuY29sb3I7XG4gICAgICAgIGlmICh0aGlzLmxheW91dCA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckhvcml6b250YWwobWluLCBtYXgsIGNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyVmVydGljYWwobWluLCBtYXgsIGNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxlZ2VuZExheW91dCgpO1xuICAgICAgICB0aGlzLmFkZEludGVyYWN0aW9uKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMub3B0aW9ucy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgSGVhdG1hcExlZ2VuZC5wcm90b3R5cGUuZ2V0QkJveCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9yaWdpbl9iYm94ID0gdGhpcy5jb250YWluZXIuZ2V0QkJveCgpO1xuICAgICAgICByZXR1cm4gbmV3IGJib3hfMS5kZWZhdWx0KHRoaXMueCwgdGhpcy55LCBvcmlnaW5fYmJveC53aWR0aCwgb3JpZ2luX2Jib3guaGVpZ2h0KTtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLnJlbmRlclZlcnRpY2FsID0gZnVuY3Rpb24gKG1pbiwgbWF4LCBjb2xvcnMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGdyaWRXaWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgIHZhciBncmlkSGVpZ2h0ID0gdGhpcy5oZWlnaHQgLyBjb2xvcnMubGVuZ3RoO1xuICAgICAgICB2YXIgZ3JpZExpbmVDb250YWluZXIgPSB0aGlzLmNvbnRhaW5lci5hZGRHcm91cCgpO1xuICAgICAgICB2YXIgZ3JpZENvbG9ycyA9IHV0aWxfMS5jbG9uZShjb2xvcnMpLnJldmVyc2UoKTtcbiAgICAgICAgdmFyIHZhbHVlU3RlcCA9IChtYXggLSBtaW4pIC8gY29sb3JzLmxlbmd0aDtcbiAgICAgICAgLy8g57uY5Yi26Imy5b2p5qC85a2QXG4gICAgICAgIHV0aWxfMS5lYWNoKGdyaWRDb2xvcnMsIGZ1bmN0aW9uIChjLCBpKSB7XG4gICAgICAgICAgICB2YXIgeSA9IGdyaWRIZWlnaHQgKiBpO1xuICAgICAgICAgICAgLy8g6K6w5b2V5q+P5LiqZ3JpZOS7o+ihqOeahOWMuumXtOS/oeaBr+eUqOS6jmxlZ2VuZOS6pOS6klxuICAgICAgICAgICAgdmFyIGFwcGVuZEluZm8gPSB7IHRvOiBtYXggLSB2YWx1ZVN0ZXAgKiBpLCBmcm9tOiBtYXggLSB2YWx1ZVN0ZXAgKiAoaSArIDEpIH07XG4gICAgICAgICAgICB2YXIgcmVjdCA9IF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogZ3JpZFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGdyaWRIZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IGMsXG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IEFDVElWRV9PUEFDSVRZLFxuICAgICAgICAgICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWN0LnNldCgnaW5mbycsIGFwcGVuZEluZm8pO1xuICAgICAgICAgICAgdmFyIGRhdGFTbGlkZSA9IF90aGlzLmdldERhdGFTbGlkZShhcHBlbmRJbmZvKTtcbiAgICAgICAgICAgIF90aGlzLmRhdGFTbGlkZXNbYXBwZW5kSW5mby5mcm9tICsgXCItXCIgKyBhcHBlbmRJbmZvLnRvXSA9IHsgbW9kZTogJ2FjdGl2ZScsIGRhdGE6IGRhdGFTbGlkZSB9O1xuICAgICAgICAgICAgZ3JpZExpbmVDb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCAwLCB5ICsgZ3JpZEhlaWdodF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBncmlkV2lkdGgsIHkgKyBncmlkSGVpZ2h0XSxcbiAgICAgICAgICAgICAgICAgICAgXSB9LCBfdGhpcy5vcHRpb25zLmdyaWRsaW5lU3R5bGUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDnu5jliLbkuKTovrnnmoRsYWJlbFxuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgdGV4dDogbWF4LCB4OiBncmlkV2lkdGggLyAyLCB5OiAtTEFCRUxfTUFSR0lOLCB0ZXh0QWxpZ246ICdjZW50ZXInLCB0ZXh0QmFzZWxpbmU6ICdib3R0b20nIH0sIHRoaXMub3B0aW9ucy50ZXh0LnN0eWxlKSxcbiAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtbGFiZWwnLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHsgdGV4dDogbWluLCB4OiBncmlkV2lkdGggLyAyLCB5OiB0aGlzLmhlaWdodCArIExBQkVMX01BUkdJTiwgdGV4dEFsaWduOiAnY2VudGVyJywgdGV4dEJhc2VsaW5lOiAndG9wJyB9LCB0aGlzLm9wdGlvbnMudGV4dC5zdHlsZSksIHsgbmFtZTogJ2xlZ2VuZC1sYWJlbCcgfSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyDnu5jliLbljIXlm7Tnur9cbiAgICAgICAgZ3JpZExpbmVDb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgWydNJywgMCwgMF0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIHRoaXMud2lkdGgsIDBdLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodF0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIDAsIHRoaXMuaGVpZ2h0XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgMCwgMF0sXG4gICAgICAgICAgICAgICAgXSB9LCB0aGlzLm9wdGlvbnMuZ3JpZGxpbmVTdHlsZSksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgSGVhdG1hcExlZ2VuZC5wcm90b3R5cGUucmVuZGVySG9yaXpvbnRhbCA9IGZ1bmN0aW9uIChtaW4sIG1heCwgY29sb3JzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBncmlkV2lkdGggPSB0aGlzLndpZHRoIC8gY29sb3JzLmxlbmd0aDtcbiAgICAgICAgdmFyIGdyaWRIZWlnaHQgPSB0aGlzLmhlaWdodDtcbiAgICAgICAgdmFyIGdyaWRMaW5lQ29udGFpbmVyID0gdGhpcy5jb250YWluZXIuYWRkR3JvdXAoKTtcbiAgICAgICAgdmFyIHZhbHVlU3RlcCA9IChtYXggLSBtaW4pIC8gY29sb3JzLmxlbmd0aDtcbiAgICAgICAgLy8g57uY5Yi26Imy5b2p5qC85a2QXG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbG9ycywgZnVuY3Rpb24gKGMsIGkpIHtcbiAgICAgICAgICAgIHZhciB4ID0gZ3JpZFdpZHRoICogaTtcbiAgICAgICAgICAgIC8vIOiusOW9leavj+S4qmdyaWTku6PooajnmoTljLrpl7Tkv6Hmga/nlKjkuo5sZWdlbmTkuqTkupJcbiAgICAgICAgICAgIHZhciBhcHBlbmRJbmZvID0geyBmcm9tOiB2YWx1ZVN0ZXAgKiBpLCB0bzogdmFsdWVTdGVwICogKGkgKyAxKSB9O1xuICAgICAgICAgICAgdmFyIHJlY3QgPSBfdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3JlY3QnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGdyaWRXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBncmlkSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiBjLFxuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjgsXG4gICAgICAgICAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbmFtZTogJ2xlZ2VuZCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlY3Quc2V0KCdpbmZvJywgYXBwZW5kSW5mbyk7XG4gICAgICAgICAgICBncmlkTGluZUNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTScsIHggKyBncmlkV2lkdGgsIDBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgWydMJywgeCArIGdyaWRXaWR0aCwgZ3JpZEhlaWdodF0sXG4gICAgICAgICAgICAgICAgICAgIF0gfSwgX3RoaXMub3B0aW9ucy5ncmlkbGluZVN0eWxlKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8g57uY5Yi25Lik6L6555qEbGFiZWxcbiAgICAgICAgdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHsgdGV4dDogbWluLCB4OiAtTEFCRUxfTUFSR0lOLCB5OiBncmlkSGVpZ2h0IC8gMiB9LCB0aGlzLm9wdGlvbnMudGV4dC5zdHlsZSksIHsgdGV4dEFsaWduOiAncmlnaHQnLCB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnIH0pLFxuICAgICAgICAgICAgbmFtZTogJ2xlZ2VuZC1sYWJlbCcsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgdGV4dDogbWF4LCB4OiB0aGlzLndpZHRoICsgTEFCRUxfTUFSR0lOLCB5OiBncmlkSGVpZ2h0IC8gMiwgdGV4dEFsaWduOiAnbGVmdCcsIHRleHRCYXNlbGluZTogJ21pZGRsZScgfSwgdGhpcy5vcHRpb25zLnRleHQuc3R5bGUpLFxuICAgICAgICAgICAgbmFtZTogJ2xlZ2VuZC1sYWJlbCcsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyDnu5jliLbljIXlm7Tnur9cbiAgICAgICAgZ3JpZExpbmVDb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgWydNJywgMCwgMF0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIHRoaXMud2lkdGgsIDBdLFxuICAgICAgICAgICAgICAgICAgICBbJ0wnLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodF0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIDAsIHRoaXMuaGVpZ2h0XSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgMCwgMF0sXG4gICAgICAgICAgICAgICAgXSB9LCB0aGlzLm9wdGlvbnMuZ3JpZGxpbmVTdHlsZSksXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgSGVhdG1hcExlZ2VuZC5wcm90b3R5cGUuZ2V0TGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9zaXRpb25zID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uLnNwbGl0KCctJyk7XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbnNbMF07XG4gICAgICAgIGlmIChwb3NpdGlvbnNbMF0gPT09ICdsZWZ0JyB8fCBwb3NpdGlvbnNbMF0gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHJldHVybiAndmVydGljYWwnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnaG9yaXpvbnRhbCc7XG4gICAgfTtcbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5nZXREZWZhdWx0V2lkdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmxheW91dCA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgICB2YXIgd2lkdGggPSB0aGlzLm9wdGlvbnMucGxvdC5vcHRpb25zLndpZHRoO1xuICAgICAgICAgICAgcmV0dXJuIHdpZHRoICogMC41O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAxMDtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLmdldERlZmF1bHRIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmxheW91dCA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgICAgdmFyIGhlaWdodCA9IHRoaXMub3B0aW9ucy5wbG90Lm9wdGlvbnMuaGVpZ2h0O1xuICAgICAgICAgICAgcmV0dXJuIGhlaWdodCAqIDAuNTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMTA7XG4gICAgfTtcbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5sZWdlbmRMYXlvdXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBibGVlZGluZyA9IHRoaXMub3B0aW9ucy5wbG90LmdldFBsb3RUaGVtZSgpLmJsZWVkaW5nO1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoYmxlZWRpbmcpKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChibGVlZGluZywgZnVuY3Rpb24gKGl0LCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYmxlZWRpbmdbaW5kZXhdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGJsZWVkaW5nW2luZGV4XSA9IGJsZWVkaW5nW2luZGV4XShfdGhpcy5vcHRpb25zLnBsb3Qub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmNvbnRhaW5lci5nZXRCQm94KCk7XG4gICAgICAgIHZhciB4ID0gMDtcbiAgICAgICAgdmFyIHkgPSAwO1xuICAgICAgICB2YXIgcG9zaXRpb25zID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uLnNwbGl0KCctJyk7XG4gICAgICAgIHZhciBwbG90V2lkdGggPSB0aGlzLm9wdGlvbnMucGxvdC53aWR0aDtcbiAgICAgICAgdmFyIHBsb3RIZWlnaHQgPSB0aGlzLm9wdGlvbnMucGxvdC5oZWlnaHQ7XG4gICAgICAgIC8vIOWFiOehruWumnhcbiAgICAgICAgaWYgKHBvc2l0aW9uc1swXSA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICB4ID0gYmxlZWRpbmdbM107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocG9zaXRpb25zWzBdID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICB4ID0gcGxvdFdpZHRoIC0gYmxlZWRpbmdbMV0gLSBiYm94LndpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uc1sxXSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIHggPSAocGxvdFdpZHRoIC0gYmJveC53aWR0aCkgLyAyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uc1sxXSA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICB4ID0gYmxlZWRpbmdbM107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocG9zaXRpb25zWzFdID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICB4ID0gdGhpcy5vcHRpb25zLnBsb3Qud2lkdGggLSBibGVlZGluZ1sxXSAtIGJib3gud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5YaN56Gu5a6aeVxuICAgICAgICBpZiAocG9zaXRpb25zWzBdID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgeSA9IHBsb3RIZWlnaHQgLSBibGVlZGluZ1syXSAtIGJib3guaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uc1swXSA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgIHkgPSB0aGlzLmdldFRvcFBvc2l0aW9uKGJsZWVkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbnNbMV0gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICB5ID0gKHBsb3RIZWlnaHQgLSBiYm94LmhlaWdodCkgLyAyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uc1sxXSA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgIHkgPSBibGVlZGluZ1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbnNbMV0gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICB5ID0gcGxvdEhlaWdodCAtIGJsZWVkaW5nWzJdIC0gYmJveC5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54ID0geDtcbiAgICAgICAgdGhpcy55ID0geTtcbiAgICAgICAgdGhpcy5jb250YWluZXIudHJhbnNsYXRlKHgsIHkpO1xuICAgIH07XG4gICAgSGVhdG1hcExlZ2VuZC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgwLCAwLCAwLCAwLjQ1KScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBncmlkbGluZVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogJ3JnYmEoMCwgMCwgMCwgMC40NSknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLmdldERhcmtPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGV4dDoge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMjU1LCAyNTUsIDI1NSwgMC40NSknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ3JpZGxpbmVTdHlsZToge1xuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMjUpJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5hZGRJbnRlcmFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNvbG9yRmllbGQgPSB0aGlzLm9wdGlvbnMucGxvdC5vcHRpb25zLmNvbG9yRmllbGQ7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLm9uKCdjbGljaycsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2LnRhcmdldDtcbiAgICAgICAgICAgIGlmICh0YXJnZXQuZ2V0KCduYW1lJykgPT09ICdsZWdlbmQnKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFwcGVuZEluZm8gPSB0YXJnZXQuZ2V0KCdpbmZvJyk7XG4gICAgICAgICAgICAgICAgdmFyIHRhcmdldEluZm8gPSBhcHBlbmRJbmZvLmZyb20gKyBcIi1cIiArIGFwcGVuZEluZm8udG87XG4gICAgICAgICAgICAgICAgdmFyIHJlbGF0aXZlRGF0YSA9IF90aGlzLmRhdGFTbGlkZXNbdGFyZ2V0SW5mb107XG4gICAgICAgICAgICAgICAgaWYgKHJlbGF0aXZlRGF0YS5tb2RlID09PSAnYWN0aXZlJykge1xuICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZURhdGEubW9kZSA9ICdkZWFjdGl2ZSc7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiBERUFDVElWRV9PUEFDSVRZLFxuICAgICAgICAgICAgICAgICAgICB9LCAyMDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVEYXRhLm1vZGUgPSAnYWN0aXZlJztcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IEFDVElWRV9PUEFDSVRZLFxuICAgICAgICAgICAgICAgICAgICB9LCAyMDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZmlsdGVyZWREYXRhID0gX3RoaXMuZ2V0RmlsdGVyZWREYXRhKCk7XG4gICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnZpZXcuY2hhbmdlRGF0YShmaWx0ZXJlZERhdGEpO1xuICAgICAgICAgICAgICAgICAgICAvL3RoaXMudmlldy5zZXQoJ2RhdGEnLCBmaWx0ZXJlZERhdGEpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy52aWV3LnNjYWxlKGNvbG9yRmllbGQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbjogX3RoaXMuY29sb3JTY2FsZS5taW4sXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXg6IF90aGlzLmNvbG9yU2NhbGUubWF4LFxuICAgICAgICAgICAgICAgICAgICAgICAgbmljZTogX3RoaXMuY29sb3JTY2FsZS5uaWNlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudmlldy5yZW5kZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgSGVhdG1hcExlZ2VuZC5wcm90b3R5cGUuZ2V0RmlsdGVyZWREYXRhID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmlsdGVyZWREYXRhID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuZGF0YVNsaWRlcywgZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgICAgIGlmIChzLm1vZGUgPT0gJ2FjdGl2ZScpIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJlZERhdGEucHVzaC5hcHBseShmaWx0ZXJlZERhdGEsIHMuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmlsdGVyZWREYXRhO1xuICAgIH07XG4gICAgLy/pooTlhYjlr7nmlbDmja7ov5vooYzliIbnu4RcbiAgICBIZWF0bWFwTGVnZW5kLnByb3RvdHlwZS5nZXREYXRhU2xpZGUgPSBmdW5jdGlvbiAocmFuZ2UpIHtcbiAgICAgICAgdmFyIHNsaWRlID0gW107XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucy5wbG90Lm9wdGlvbnMsIGNvbG9yRmllbGQgPSBfYS5jb2xvckZpZWxkLCBkYXRhID0gX2EuZGF0YTtcbiAgICAgICAgdXRpbF8xLmVhY2goZGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGRbY29sb3JGaWVsZF07XG4gICAgICAgICAgICBpZiAodmFsdWUgPj0gcmFuZ2UuZnJvbSAmJiB2YWx1ZSA8IHJhbmdlLnRvKSB7XG4gICAgICAgICAgICAgICAgc2xpZGUucHVzaChkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzbGlkZTtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLmdldFRvcFBvc2l0aW9uID0gZnVuY3Rpb24gKGJsZWVkaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucGxvdC5kZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgdmFyIGJib3ggPSB0aGlzLm9wdGlvbnMucGxvdC5kZXNjcmlwdGlvbi5nZXRCQm94KCk7XG4gICAgICAgICAgICByZXR1cm4gYmJveC5tYXhZICsgMTA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5vcHRpb25zLnBsb3QudGl0bGUpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gdGhpcy5vcHRpb25zLnBsb3QudGl0bGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgcmV0dXJuIGJib3gubWF4WSArIDEwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBibGVlZGluZ1swXTtcbiAgICB9O1xuICAgIEhlYXRtYXBMZWdlbmQucHJvdG90eXBlLmdldFNjYWxlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNjYWxlcztcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy52aWV3Lmdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tKSB7XG4gICAgICAgICAgICBpZiAoZ2VvbS50eXBlID09PSAnaGVhdG1hcCcpIHtcbiAgICAgICAgICAgICAgICBzY2FsZXMgPSBnZW9tLnNjYWxlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgfTtcbiAgICByZXR1cm4gSGVhdG1hcExlZ2VuZDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIZWF0bWFwTGVnZW5kO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGVnZW5kLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5vbkV2ZW50ID0gZXhwb3J0cy5FVkVOVF9NQVAgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2V2ZW50XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRVZFTlRfTUFQXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLkVWRU5UX01BUDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9uRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEub25FdmVudDsgfSB9KTtcbnZhciBjb21wb25lbnRNYXAgPSB7XG4gICAgaGVhdG1hcDogJ2hlYXRtYXAnLFxuICAgIGxlZ2VuZExhYmVsOiAnbGVnZW5kLWxhYmVsJyxcbiAgICBoZWF0bWFwQmFja2dyb3VuZDogJ2hlYXRtYXAtYmFja2dyb3VuZCcsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgRGVuc2l0eUhlYXRtYXAgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRGVuc2l0eUhlYXRtYXAsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRGVuc2l0eUhlYXRtYXAoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgRGVuc2l0eUhlYXRtYXAucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdkZW5zaXR5SGVhdG1hcCc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBEZW5zaXR5SGVhdG1hcC5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gRGVuc2l0eUhlYXRtYXA7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEZW5zaXR5SGVhdG1hcDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgdmlld19sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2Uvdmlldy1sYXllclwiKSk7XG52YXIgZmFjdG9yeV8xID0gcmVxdWlyZShcIi4uLy4uL2NvbXBvbmVudHMvZmFjdG9yeVwiKTtcbnZhciBmYWN0b3J5XzIgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvc2NhbGVcIik7XG5yZXF1aXJlKFwiLi4vLi4vZ2VvbXMvaGVhdG1hcC9saW5lYXJcIik7XG52YXIgY29tcG9uZW50c18xID0gcmVxdWlyZShcIi4vY29tcG9uZW50c1wiKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnZhciBEZW5zaXR5SGVhdG1hcExheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERlbnNpdHlIZWF0bWFwTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRGVuc2l0eUhlYXRtYXBMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnZGVuc2l0eUhlYXRtYXAnO1xuICAgICAgICBfdGhpcy5wbG90Q29tcG9uZW50cyA9IFtdO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIERlbnNpdHlIZWF0bWFwTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlVGl0bGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogMTIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZVRpdGxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IHRydWUsXG4gICAgICAgICAgICAgICAgY3Jvc3NoYWlyczoge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAneHknLFxuICAgICAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJyMwMDAwMDAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjUsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdib3R0b20tY2VudGVyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xvcjogW1xuICAgICAgICAgICAgICAgICdyZ2JhKDMzLDEwMiwxNzIsMCknLFxuICAgICAgICAgICAgICAgICdyZ2IoMTAzLDE2OSwyMDcpJyxcbiAgICAgICAgICAgICAgICAncmdiKDIwOSwyMjksMjQwKScsXG4gICAgICAgICAgICAgICAgJ3JnYigyNTMsMjE5LDE5OSknLFxuICAgICAgICAgICAgICAgICdyZ2IoMjM5LDEzOCw5OCknLFxuICAgICAgICAgICAgICAgICdyZ2IoMTc4LDI0LDQzKScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgaW50ZXJhY3Rpb25zOiBbeyB0eXBlOiAndG9vbHRpcCcgfV0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRGVuc2l0eUhlYXRtYXBMYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyUGxvdENvbXBvbmVudHMoKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgRGVuc2l0eUhlYXRtYXBMYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5wbG90Q29tcG9uZW50cywgZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgY29tcG9uZW50LmRlc3Ryb3koKTtcbiAgICAgICAgfSk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgRGVuc2l0eUhlYXRtYXBMYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHNjYWxlcyA9IHt9O1xuICAgICAgICAvKiog6YWN572ueC1zY2FsZSAqL1xuICAgICAgICBzY2FsZXNbcHJvcHMueEZpZWxkXSA9IHt9O1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhwcm9wcywgJ3hBeGlzJykpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlc1twcm9wcy54RmllbGRdLCBwcm9wcy54QXhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rnktc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW3Byb3BzLnlGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICd5QXhpcycpKSB7XG4gICAgICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXNbcHJvcHMueUZpZWxkXSwgcHJvcHMueUF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBEZW5zaXR5SGVhdG1hcExheWVyLnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgRGVuc2l0eUhlYXRtYXBMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnaGVhdG1hcCc7XG4gICAgfTtcbiAgICBEZW5zaXR5SGVhdG1hcExheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5kYXRhLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHZhciBjb25maWcgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcmhlYXRtYXAnLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkczogW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICAgICAgICAgICAgZmllbGRzOiBbdGhpcy5vcHRpb25zLmNvbG9yRmllbGRdLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IHRoaXMub3B0aW9ucy5jb2xvcixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNmZzoge1xuICAgICAgICAgICAgICAgICAgICBpbnRlbnNpdHk6IHRoaXMub3B0aW9ucy5pbnRlbnNpdHksXG4gICAgICAgICAgICAgICAgICAgIHJhZGl1czogdGhpcy5vcHRpb25zLnJhZGl1cyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmFkaXVzKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLnJhZGl1cyA9IHRoaXMub3B0aW9ucy5yYWRpdXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmludGVuc2l0eSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5pbnRlbnNpdHkgPSB0aGlzLm9wdGlvbnMuaW50ZW5zaXR5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50b29sdGlwICYmICh0aGlzLm9wdGlvbnMudG9vbHRpcC5maWVsZHMgfHwgdGhpcy5vcHRpb25zLnRvb2x0aXAuZm9ybWF0dGVyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2VvbWV0cnlUb29sdGlwKGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBjb25maWcpO1xuICAgICAgICAgICAgdGhpcy5hZGRQb2ludCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBEZW5zaXR5SGVhdG1hcExheWVyLnByb3RvdHlwZS5hZGRQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgZGVmYXVsdENvbmZpZyA9IHsgdmlzaWJsZTogZmFsc2UsIHNpemU6IDAgfTtcbiAgICAgICAgaWYgKHByb3BzLnBvaW50ICYmIHByb3BzLnBvaW50LnZpc2libGUpIHtcbiAgICAgICAgICAgIHByb3BzLnBvaW50ID0gdXRpbF8xLmRlZXBNaXgoZGVmYXVsdENvbmZpZywgcHJvcHMucG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHJvcHMucG9pbnQgPSBkZWZhdWx0Q29uZmlnO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwb2ludCA9IGZhY3RvcnlfMi5nZXRHZW9tKCdwb2ludCcsICdndWlkZScsIHtcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICBwb2ludC5hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgLy8gcG9pbnQubGFiZWwgPSB0aGlzLmV4dHJhY3RMYWJlbCgpO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBwb2ludCk7XG4gICAgfTtcbiAgICBEZW5zaXR5SGVhdG1hcExheWVyLnByb3RvdHlwZS5leHRyYWN0TGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGxhYmVsID0gcHJvcHMubGFiZWw7XG4gICAgICAgIGlmIChsYWJlbCAmJiBsYWJlbC52aXNpYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsYWJlbENvbmZpZyA9IGZhY3RvcnlfMS5nZXRDb21wb25lbnQoJ2xhYmVsJywgdHNsaWJfMS5fX2Fzc2lnbih7IHBsb3Q6IHRoaXMsIGxhYmVsVHlwZTogJ3NjYXR0ZXJMYWJlbCcsIGZpZWxkczogW3Byb3BzLnhGaWVsZCwgcHJvcHMueUZpZWxkXSwgcG9zaXRpb246ICdtaWRkbGUnLCBvZmZzZXQ6IDAgfSwgbGFiZWwpKTtcbiAgICAgICAgcmV0dXJuIGxhYmVsQ29uZmlnO1xuICAgIH07XG4gICAgRGVuc2l0eUhlYXRtYXBMYXllci5wcm90b3R5cGUubGVnZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldENvbmZpZygnbGVnZW5kcycsIGZhbHNlKTtcbiAgICB9O1xuICAgIERlbnNpdHlIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgY29uZmlnLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIGNvbmZpZy50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICBjb25maWcudG9vbHRpcC5jYWxsYmFjayA9IHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgIGlmICghdG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY29sb3JGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcudG9vbHRpcC5maWVsZHMucHVzaCh0aGlzLm9wdGlvbnMuY29sb3JGaWVsZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBEZW5zaXR5SGVhdG1hcExheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIERlbnNpdHlIZWF0bWFwTGF5ZXIucHJvdG90eXBlLnJlbmRlclBsb3RDb21wb25lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLnBsb3RDb21wb25lbnRzLCBmdW5jdGlvbiAoY29tcG9uZW50KSB7XG4gICAgICAgICAgICBjb21wb25lbnQuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGNvbXBvbmVudHNUeXBlID0gWydsZWdlbmQnLCAnYmFja2dyb3VuZCddO1xuICAgICAgICB1dGlsXzEuZWFjaChjb21wb25lbnRzVHlwZSwgZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHZhciBjZmcgPSB0c2xpYl8xLl9fYXNzaWduKHsgdmlldzogX3RoaXMudmlldywgcGxvdDogX3RoaXMgfSwgX3RoaXMub3B0aW9uc1t0XSk7XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gY29tcG9uZW50c18xLmdldFBsb3RDb21wb25lbnRzKF90aGlzLCB0LCBjZmcpO1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5yZW5kZXIoKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5wbG90Q29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIERlbnNpdHlIZWF0bWFwTGF5ZXI7XG59KHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEZW5zaXR5SGVhdG1hcExheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZGVuc2l0eUhlYXRtYXAnLCBEZW5zaXR5SGVhdG1hcExheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBEZW5zaXR5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERlbnNpdHksIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRGVuc2l0eSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBEZW5zaXR5LnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnZGVuc2l0eSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBEZW5zaXR5LmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBEZW5zaXR5O1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRGVuc2l0eTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCJAYW50di9zY2FsZVwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBtYXRoXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9tYXRoXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYXJlYS9sYXllclwiKSk7XG52YXIga2VybmVscyA9IHtcbiAgICBlcGFuZWNobmlrb3Y6IGZ1bmN0aW9uIChkaXN0KSB7XG4gICAgICAgIHJldHVybiBNYXRoLmFicyhkaXN0KSA8PSAxID8gMC43NSAqICgxIC0gZGlzdCAqIGRpc3QpIDogMDtcbiAgICB9LFxuICAgIGdhdXNzaWFuOiBmdW5jdGlvbiAoZGlzdCkge1xuICAgICAgICByZXR1cm4gKDEgLyBNYXRoLnNxcnQoTWF0aC5QSSAqIDIpKSAqIE1hdGguZXhwKC0wLjUgKiBNYXRoLnBvdyhkaXN0LCAyKSk7XG4gICAgfSxcbiAgICB1bmlmb3JtOiBmdW5jdGlvbiAoZGlzdCkge1xuICAgICAgICByZXR1cm4gTWF0aC5hYnMoZGlzdCkgPD0gMSA/IDAuNSA6IDA7XG4gICAgfSxcbiAgICB0cmlhbmdsZTogZnVuY3Rpb24gKGRpc3QpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKGRpc3QpIDw9IDEgPyAxIC0gTWF0aC5hYnMoZGlzdCkgOiAwO1xuICAgIH0sXG4gICAgcXVhcnRpYzogZnVuY3Rpb24gKGRpc3QpIHtcbiAgICAgICAgdmFyIHYgPSAxIC0gZGlzdCAqIGRpc3Q7XG4gICAgICAgIHJldHVybiBNYXRoLmFicyhkaXN0KSA8PSAxID8gKDE1IC8gMTYpICogdiAqIHYgOiAwO1xuICAgIH0sXG4gICAgdHJpd2VpZ2h0OiBmdW5jdGlvbiAoZGlzdCkge1xuICAgICAgICB2YXIgdiA9IDEgLSBkaXN0ICogZGlzdDtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKGRpc3QpIDw9IDEgPyAoMTUgLyAxNikgKiBNYXRoLnBvdyh2LCAzKSA6IDA7XG4gICAgfSxcbiAgICBjb3NpbnVzOiBmdW5jdGlvbiAoZGlzdCkge1xuICAgICAgICB2YXIgdiA9IChNYXRoLlBJIC8gNCkgKiBNYXRoLmNvcygwLjUgKiBNYXRoLlBJICogZGlzdCk7XG4gICAgICAgIHJldHVybiBNYXRoLmFicyhkaXN0KSA8PSAxID8gdiA6IDA7XG4gICAgfSxcbn07XG52YXIgRGVuc2l0eUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERlbnNpdHlMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBEZW5zaXR5TGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2RlbnNpdHknO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIERlbnNpdHlMYXllci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9yaWdpblhBeGlzQ29uZmlnID0gdGhpcy5vcHRpb25zLnhBeGlzID8gdXRpbF8xLmNsb25lKHRoaXMub3B0aW9ucy54QXhpcykgOiB7fTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnhGaWVsZCA9ICd2YWx1ZSc7XG4gICAgICAgIHRoaXMub3B0aW9ucy55RmllbGQgPSAnZGVuc2l0eSc7XG4gICAgICAgIHRoaXMub3B0aW9ucy54QXhpcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBvcmlnaW5YQXhpc0NvbmZpZywgeyB0eXBlOiAnbGluZWFyJyB9KTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnNtb290aCA9IHRydWU7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgRGVuc2l0eUxheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uIChvcmlnaW5EYXRhKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgYmluRmllbGQgPSBfYS5iaW5GaWVsZCwgYmluV2lkdGggPSBfYS5iaW5XaWR0aCwgYmluTnVtYmVyID0gX2EuYmluTnVtYmVyLCBrZXJuZWwgPSBfYS5rZXJuZWw7XG4gICAgICAgIHZhciBfa2VybmVsID0ga2VybmVsID8ga2VybmVsIDogJ2VwYW5lY2huaWtvdic7XG4gICAgICAgIHZhciBrZXJuZWxGdW5jID0ga2VybmVsc1tfa2VybmVsXTtcbiAgICAgICAgdmFyIG9yaWdpbkRhdGFDb3B5ID0gdXRpbF8xLmNsb25lKG9yaWdpbkRhdGEpO1xuICAgICAgICB1dGlsXzEuc29ydEJ5KG9yaWdpbkRhdGFDb3B5LCBiaW5GaWVsZCk7XG4gICAgICAgIC8vIOiuoeeul+WIhueuse+8jOebtOaWueWbvuWIhueuseeahOiuoeeul+WfuuS6jmJpbldpZHRo77yM5aaC6YWN572u5LqGYmluTnVtYmVy5YiZ5bCG5YW26L2s5Li6YmluV2lkdGjov5vooYzorqHnrpdcbiAgICAgICAgdmFyIHZhbHVlcyA9IHV0aWxfMS52YWx1ZXNPZktleShvcmlnaW5EYXRhQ29weSwgYmluRmllbGQpO1xuICAgICAgICB2YXIgcmFuZ2UgPSB1dGlsXzEuZ2V0UmFuZ2UodmFsdWVzKTtcbiAgICAgICAgdmFyIHJhbmdlV2lkdGggPSByYW5nZS5tYXggLSByYW5nZS5taW47XG4gICAgICAgIHZhciBfYmluTnVtYmVyID0gYmluTnVtYmVyO1xuICAgICAgICB2YXIgX2JpbldpZHRoID0gYmluV2lkdGg7XG4gICAgICAgIGlmICghYmluTnVtYmVyICYmIGJpbldpZHRoKSB7XG4gICAgICAgICAgICBfYmluTnVtYmVyID0gTWF0aC5mbG9vcihyYW5nZVdpZHRoIC8gYmluV2lkdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYmluV2lkdGggJiYgYmluTnVtYmVyKSB7XG4gICAgICAgICAgICBfYmluV2lkdGggPSByYW5nZVdpZHRoIC8gYmluTnVtYmVyO1xuICAgICAgICB9XG4gICAgICAgIC8vIOW9k2JpbldpZHRo5ZKMYmluTnVtYmVy6YO95rKh5pyJ5oyH5a6a55qE5oOF5Ya177yM6YeH55SoU3R1cmdlcyBmb3JtdWxh6Ieq5Yqo55Sf5oiQYmluV2lkdGhcbiAgICAgICAgaWYgKCFiaW5OdW1iZXIgJiYgIWJpbldpZHRoKSB7XG4gICAgICAgICAgICBfYmluTnVtYmVyID0gbWF0aF8xLnN0dXJnZXModmFsdWVzKTtcbiAgICAgICAgICAgIF9iaW5XaWR0aCA9IHJhbmdlV2lkdGggLyBiaW5OdW1iZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5qC55o2uYmluTnVtYmVy6I635Y+Wc2FtcGxlc1xuICAgICAgICB2YXIgTGluZWFyU2NhbGUgPSBzY2FsZV8xLmdldFNjYWxlKCdsaW5lYXInKTtcbiAgICAgICAgdmFyIHNjYWxlID0gbmV3IExpbmVhclNjYWxlKHtcbiAgICAgICAgICAgIG1pbjogcmFuZ2UubWluLFxuICAgICAgICAgICAgbWF4OiByYW5nZS5tYXgsXG4gICAgICAgICAgICB0aWNrQ291bnQ6IF9iaW5OdW1iZXIsXG4gICAgICAgICAgICBuaWNlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBzYW1wbGVzID0gc2NhbGUuZ2V0VGlja3MoKTtcbiAgICAgICAgLy8g6K6h566XS0RFXG4gICAgICAgIHZhciBkZW5zaXRpZXMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2FtcGxlcywgZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgICAgIHZhciBkZW5zaXR5ID0gX3RoaXMua2VybmVsRGVuc2l0eUVzdGltYXRvcihfYmluV2lkdGgsIGtlcm5lbEZ1bmMsIHMsIHZhbHVlcyk7XG4gICAgICAgICAgICBkZW5zaXRpZXMucHVzaCh7IHZhbHVlOiBzLnRleHQsIGRlbnNpdHk6IGRlbnNpdHkgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZGVuc2l0aWVzO1xuICAgIH07XG4gICAgRGVuc2l0eUxheWVyLnByb3RvdHlwZS5rZXJuZWxEZW5zaXR5RXN0aW1hdG9yID0gZnVuY3Rpb24gKGJpbldpZHRoLCBrZXJuZWxGdW5jLCB4LCB2YWx1ZXMpIHtcbiAgICAgICAgdmFyIHN1bSA9IDA7XG4gICAgICAgIHV0aWxfMS5lYWNoKHZhbHVlcywgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgIHZhciBkaXN0ID0gKHgudGlja1ZhbHVlIC0gdikgLyBiaW5XaWR0aDtcbiAgICAgICAgICAgIHN1bSArPSBrZXJuZWxGdW5jKGRpc3QpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5sZW5ndGggPT09IDAgPyAwIDogc3VtIC8gdmFsdWVzLmxlbmd0aDtcbiAgICB9O1xuICAgIHJldHVybiBEZW5zaXR5TGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRGVuc2l0eUxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZGVuc2l0eScsIERlbnNpdHlMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHN0YXRpc3RpY18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2NvbXBvbmVudHMvc3RhdGlzdGljXCIpKTtcbnZhciBzdGF0aXN0aWNfdGVtcGxhdGVfMSA9IHJlcXVpcmUoXCIuL3N0YXRpc3RpYy10ZW1wbGF0ZVwiKTtcbnZhciB1dGlsXzIgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBSaW5nU3RhdGlzdGljID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJpbmdTdGF0aXN0aWMsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmluZ1N0YXRpc3RpYyhjZmcpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY2ZnKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy52aWV3ID0gY2ZnLnZpZXc7XG4gICAgICAgIF90aGlzLnBsb3QgPSBjZmcucGxvdDtcbiAgICAgICAgX3RoaXMuc3RhdGlzdGljQ2xhc3MgPSBjZmcuc3RhdGlzdGljQ2xhc3M7XG4gICAgICAgIF90aGlzLmFkanVzdE9wdGlvbnMoKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBSaW5nU3RhdGlzdGljLnByb3RvdHlwZS50cmlnZ2VyT24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0cmlnZ2VyT25FdmVudCA9IHRoaXMub3B0aW9ucy50cmlnZ2VyT247XG4gICAgICAgIHRoaXMudmlldy5vbihcImludGVydmFsOlwiICsgdHJpZ2dlck9uRXZlbnQsIHV0aWxfMi5kZWJvdW5jZShmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIGRpc3BsYXlEYXRhID0gX3RoaXMucGFyc2VTdGF0aXN0aWNEYXRhKCdpdGVtJywgZS5kYXRhLmRhdGEsIGUuZGF0YS5jb2xvcik7XG4gICAgICAgICAgICB2YXIgaHRtbFN0cmluZyA9IF90aGlzLmdldFN0YXRpc3RpY0h0bWxTdHJpbmcoZGlzcGxheURhdGEpO1xuICAgICAgICAgICAgX3RoaXMudXBkYXRlSHRtbChodG1sU3RyaW5nKTtcbiAgICAgICAgfSwgMTUwKSk7XG4gICAgICAgIHZhciB0cmlnZ2VyT2ZmRXZlbnQgPSB0aGlzLm9wdGlvbnMudHJpZ2dlck9mZiA/IHRoaXMub3B0aW9ucy50cmlnZ2VyT2ZmIDogJ21vdXNlbGVhdmUnO1xuICAgICAgICB0aGlzLnZpZXcub24oXCJpbnRlcnZhbDpcIiArIHRyaWdnZXJPZmZFdmVudCwgdXRpbF8yLmRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBodG1sU3RyaW5nID0gX3RoaXMuZ2V0VG90YWxIdG1sU3RyaW5nKCk7XG4gICAgICAgICAgICBfdGhpcy51cGRhdGVIdG1sKGh0bWxTdHJpbmcpO1xuICAgICAgICB9LCAxNTApKTtcbiAgICB9O1xuICAgIFJpbmdTdGF0aXN0aWMucHJvdG90eXBlLmdldFRvdGFsSHRtbFN0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRpc3BsYXlEYXRhO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNvbnRlbnQpIHtcbiAgICAgICAgICAgIGRpc3BsYXlEYXRhID0gdGhpcy5vcHRpb25zLmNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvKiog55So5oi35rKh5pyJ5oyH5a6a5paH5pys5YaF5a655pe277yM6buY6K6k5pi+56S65oC76K6hICovXG4gICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZ2V0VG90YWxWYWx1ZSgpO1xuICAgICAgICAgICAgZGlzcGxheURhdGEgPSB0aGlzLnBhcnNlU3RhdGlzdGljRGF0YSgndG90YWwnLCBkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICAvKiog5Lit5b+D5paH5pys5pi+56S6ICovXG4gICAgICAgIHZhciBodG1sQ29udGVudDtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5odG1sQ29udGVudCkge1xuICAgICAgICAgICAgaHRtbENvbnRlbnQgPSB0aGlzLm9wdGlvbnMuaHRtbENvbnRlbnQoZGlzcGxheURhdGEsIHRoaXMuZ2V0U3RhdGlzdGljU2l6ZSgpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGh0bWxDb250ZW50ID0gdGhpcy5nZXRTdGF0aXN0aWNUZW1wbGF0ZShkaXNwbGF5RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHN0YXRpc3RpY0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBpZiAodXRpbF8xLmlzVHlwZShodG1sQ29udGVudCwgJ0hUTUxEaXZFbGVtZW50JykpIHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIHN0YXRpc3RpY0NvbnRhaW5lci5hcHBlbmRDaGlsZChodG1sQ29udGVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGF0aXN0aWNDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbENvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0YXRpc3RpY0NvbnRhaW5lcjtcbiAgICB9O1xuICAgIFJpbmdTdGF0aXN0aWMucHJvdG90eXBlLmFkanVzdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaHRtbCA9IHRoaXMuZ2V0VG90YWxIdG1sU3RyaW5nKCk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMudmlldy5jb29yZGluYXRlQkJveCwgbWluWCA9IF9hLm1pblgsIG1pblkgPSBfYS5taW5ZLCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XG4gICAgICAgIHRoaXMueCA9IG1pblggKyB3aWR0aCAvIDI7XG4gICAgICAgIHRoaXMueSA9IG1pblkgKyBoZWlnaHQgLyAyO1xuICAgIH07XG4gICAgUmluZ1N0YXRpc3RpYy5wcm90b3R5cGUuZ2V0VG90YWxWYWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgdG90YWwgPSAwO1xuICAgICAgICB2YXIgX2IgPSB0aGlzLnBsb3Qub3B0aW9ucywgYW5nbGVGaWVsZCA9IF9iLmFuZ2xlRmllbGQsIGNvbG9yRmllbGQgPSBfYi5jb2xvckZpZWxkO1xuICAgICAgICB2YXIgdG90YWxMYWJlbCA9IHRoaXMub3B0aW9ucy50b3RhbExhYmVsO1xuICAgICAgICB1dGlsXzIuZWFjaCh0aGlzLnBsb3Qub3B0aW9ucy5kYXRhLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtW2FuZ2xlRmllbGRdID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIHRvdGFsICs9IGl0ZW1bYW5nbGVGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgZGF0YSA9IChfYSA9IHt9LFxuICAgICAgICAgICAgX2FbYW5nbGVGaWVsZF0gPSB0b3RhbCxcbiAgICAgICAgICAgIF9hW2NvbG9yRmllbGRdID0gdG90YWxMYWJlbCxcbiAgICAgICAgICAgIF9hKTtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfTtcbiAgICBSaW5nU3RhdGlzdGljLnByb3RvdHlwZS5wYXJzZVN0YXRpc3RpY0RhdGEgPSBmdW5jdGlvbiAodHlwZSwgZGF0YSwgY29sb3IpIHtcbiAgICAgICAgdmFyIHBsb3QgPSB0aGlzLnBsb3Q7XG4gICAgICAgIHZhciBfYSA9IHBsb3Qub3B0aW9ucywgYW5nbGVGaWVsZCA9IF9hLmFuZ2xlRmllbGQsIGNvbG9yRmllbGQgPSBfYS5jb2xvckZpZWxkO1xuICAgICAgICB2YXIgYW5nbGVTY2FsZSA9IHBsb3QuZ2V0U2NhbGVCeUZpZWxkKGFuZ2xlRmllbGQpO1xuICAgICAgICB2YXIgY29sb3JTY2FsZSA9IHBsb3QuZ2V0U2NhbGVCeUZpZWxkKGNvbG9yRmllbGQpO1xuICAgICAgICB2YXIgc3RhdGlzdGljRGF0YSA9IHtcbiAgICAgICAgICAgIG5hbWU6IGNvbG9yU2NhbGUgPyBjb2xvclNjYWxlLmdldFRleHQoZGF0YVtjb2xvckZpZWxkXSkgOiBudWxsLFxuICAgICAgICAgICAgdmFsdWU6IGFuZ2xlU2NhbGUuZ2V0VGV4dChkYXRhW2FuZ2xlRmllbGRdKSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdpdGVtJykge1xuICAgICAgICAgICAgLy8g5q+P5LiA5Liq5omH5b2i5Yy65Z+f55qE5pWw5o2uXG4gICAgICAgICAgICBzdGF0aXN0aWNEYXRhLml0ZW1EYXRhID0gZGF0YTtcbiAgICAgICAgICAgIHN0YXRpc3RpY0RhdGEuY29sb3IgPSBjb2xvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RhdGlzdGljRGF0YTtcbiAgICB9O1xuICAgIFJpbmdTdGF0aXN0aWMucHJvdG90eXBlLmdldFN0YXRpc3RpY1RlbXBsYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIHNpemUgPSB0aGlzLmdldFN0YXRpc3RpY1NpemUoKTtcbiAgICAgICAgdmFyIGh0bWxTdHJpbmcgPSBzdGF0aXN0aWNfdGVtcGxhdGVfMS5nZXRUZW1wbGF0ZShkYXRhLm5hbWUsIGRhdGEudmFsdWUsIHRoaXMuc3RhdGlzdGljQ2xhc3MsIHNpemUpO1xuICAgICAgICAvKiog5pu05Li65aSN5p2C55qE5paH5pys6KaB5rGC55So5oi36Ieq6KGM5Yi25a6aaHRtbOaooeadvyAqL1xuICAgICAgICByZXR1cm4gaHRtbFN0cmluZztcbiAgICB9O1xuICAgIFJpbmdTdGF0aXN0aWMucHJvdG90eXBlLmdldFN0YXRpc3RpY1NpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2aWV3UmFuZ2UgPSB0aGlzLnBsb3Qudmlldy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5wbG90Lm9wdGlvbnMsIHJhZGl1cyA9IF9hLnJhZGl1cywgaW5uZXJSYWRpdXMgPSBfYS5pbm5lclJhZGl1cztcbiAgICAgICAgdmFyIG1pbkNvbnRhaW5lclNpemUgPSBNYXRoLm1pbih2aWV3UmFuZ2Uud2lkdGgsIHZpZXdSYW5nZS5oZWlnaHQpO1xuICAgICAgICB2YXIgc2l6ZSA9IG1pbkNvbnRhaW5lclNpemUgKiByYWRpdXMgKiBpbm5lclJhZGl1cztcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgfTtcbiAgICBSaW5nU3RhdGlzdGljLnByb3RvdHlwZS5nZXRTdGF0aXN0aWNIdG1sU3RyaW5nID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIGh0bWxDb250ZW50ID0gdGhpcy5vcHRpb25zLmh0bWxDb250ZW50O1xuICAgICAgICB2YXIgaHRtbFN0cmluZztcbiAgICAgICAgaWYgKGh0bWxDb250ZW50KSB7XG4gICAgICAgICAgICBodG1sU3RyaW5nID0gaHRtbENvbnRlbnQoZGF0YSwgdGhpcy5nZXRTdGF0aXN0aWNTaXplKCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaHRtbFN0cmluZyA9IHRoaXMuZ2V0U3RhdGlzdGljVGVtcGxhdGUoZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGh0bWxTdHJpbmc7XG4gICAgfTtcbiAgICByZXR1cm4gUmluZ1N0YXRpc3RpYztcbn0oc3RhdGlzdGljXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmluZ1N0YXRpc3RpYztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJpbmctc3RhdGlzdGljLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRUZW1wbGF0ZSA9IHZvaWQgMDtcbi8qdHNsaW50OmRpc2FibGUqL1xudmFyIGNvbnRhaW5lclN0eWxlID0gXCJjb2xvcjojNGQ0ZDRkO2ZvbnQtc2l6ZToxNHB4O3RleHQtYWxpZ246Y2VudGVyO2xpbmUtaGVpZ2h0OjI7Zm9udC1mYW1pbHk6Jy1hcHBsZS1zeXN0ZW0nLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2VVSScsUm9ib3RvLCdIZWx2ZXRpY2FOZXVlJyxIZWx2ZXRpY2EsJ1BpbmdGYW5nU0MnLCdIaXJhZ2lub1NhbnNHQicsJ01pY3Jvc29mdFlhSGVpJyxTaW1TdW4sJ3NhbnMtc2VyaWYnO3BvaW50ZXItZXZlbnRzOm5vbmU7XCI7XG52YXIgbmFtZVN0eWxlID0gJ2ZvbnQtd2VpZ2h0OjMwMDt3aGl0ZS1zcGFjZTogbm93cmFwO3RleHQtb3ZlcmZsb3c6IGVsbGlwc2lzOyc7XG52YXIgdmFsdWVTdHlsZSA9ICdmb250LXNpemU6MzJweDtmb250LXdlaWdodDpib2xkO2NvbG9yOiM0RDRENEQnO1xuZnVuY3Rpb24gZ2V0VGVtcGxhdGUobmFtZSwgdmFsdWUsIGNsYXNzSWQsIHNpemUpIHtcbiAgICB2YXIgZG9tU3R5bGUgPSBjb250YWluZXJTdHlsZSArIFwid2lkdGg6XCIgKyBzaXplICsgXCJweDtcIjtcbiAgICB2YXIgbmFtZURvbVN0ciA9IG5hbWUgPyBcIjxzcGFuIGNsYXNzPVxcXCJyaW5nLWd1aWRlLW5hbWVcXFwiIHN0eWxlPVwiICsgbmFtZVN0eWxlICsgXCI+XCIgKyBuYW1lICsgXCI8L3NwYW4+PGJyLz5cIiA6ICcnO1xuICAgIHZhciB2YWx1ZURvbVN0ciA9IFwiPHNwYW4gY2xhc3M9XFxcInJpbmctZ3VpZGUtdmFsdWVcXFwiIHN0eWxlPVwiICsgdmFsdWVTdHlsZSArIFwiPlwiICsgdmFsdWUgKyBcIjwvc3Bhbj5cIjtcbiAgICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJyaW5nLWd1aWRlLWh0bWwgXCIgKyBjbGFzc0lkICsgXCJcXFwiIHN0eWxlPVwiICsgZG9tU3R5bGUgKyBcIj5cIiArIG5hbWVEb21TdHIgKyB2YWx1ZURvbVN0ciArIFwiPC9kaXY+XCI7XG59XG5leHBvcnRzLmdldFRlbXBsYXRlID0gZ2V0VGVtcGxhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGF0aXN0aWMtdGVtcGxhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICByaW5nOiAnaW50ZXJ2YWwnLFxufTtcbnZhciBTSEFQRV9FVkVOVF9NQVAgPSBldmVudF8xLmdldEV2ZW50TWFwKGNvbXBvbmVudE1hcCk7XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIERvbnV0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERvbnV0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERvbnV0KCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIERvbnV0LnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnZG9udXQnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgRG9udXQucHJvdG90eXBlLmdldEFuZ2xlU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0QW5nbGVTY2FsZSgpO1xuICAgIH07XG4gICAgRG9udXQuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIERvbnV0O1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRG9udXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRvbV91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvZG9tLXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9waWUvbGF5ZXJcIikpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIHJpbmdfc3RhdGlzdGljXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jb21wb25lbnQvcmluZy1zdGF0aXN0aWNcIikpO1xudmFyIEcyX0dFT01fTUFQID0ge1xuICAgIHJpbmc6ICdpbnRlcnZhbCcsXG59O1xudmFyIFBMT1RfR0VPTV9NQVAgPSB7XG4gICAgaW50ZXJ2YWw6ICdyaW5nJyxcbn07XG52YXIgRG9udXRMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhEb251dExheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERvbnV0TGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2RvbnV0JztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBEb251dExheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICByYWRpdXM6IDAuOCxcbiAgICAgICAgICAgIGlubmVyUmFkaXVzOiAwLjY0LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0YXRpc3RpYzoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdG90YWxMYWJlbDogJ+aAu+iuoScsXG4gICAgICAgICAgICAgICAgdHJpZ2dlck9uOiAnbW91c2VlbnRlcicsXG4gICAgICAgICAgICAgICAgdHJpZ2dlck9mZjogJ21vdXNlbGVhdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBEb251dExheWVyLnByb3RvdHlwZS5iZWZvcmVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmJlZm9yZUluaXQuY2FsbCh0aGlzKTtcbiAgICAgICAgRG9udXRMYXllci5jZW50cmFsSWQrKztcbiAgICAgICAgdGhpcy5zdGF0aXN0aWNDbGFzcyA9IFwic3RhdGlzdGljQ2xhc3NJZFwiICsgRG9udXRMYXllci5jZW50cmFsSWQ7XG4gICAgICAgIHRoaXMuYWRqdXN0TGFiZWxEZWZhdWx0T3B0aW9ucygpO1xuICAgICAgICAvLyBpZiAodGhpcy5vcHRpb25zLnN0YXRpc3RpYy52aXNpYmxlICYmIHRoaXMub3B0aW9ucy5zdGF0aXN0aWMudHJpZ2dlck9uKSB7XG4gICAgICAgIC8vICAgdGhpcy5vcHRpb25zLnRvb2x0aXAudmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICAvLyB9XG4gICAgfTtcbiAgICBEb251dExheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY2FudmFzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRpc3RpYykge1xuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMuc3RhdGlzdGljLndyYXBwZXJOb2RlKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGlzdGljID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICAvKirnjq/lm77kuK3lv4PmlofmnKwgKi9cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zdGF0aXN0aWMgJiYgdGhpcy5vcHRpb25zLnN0YXRpc3RpYy52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyXzEgPSB0aGlzLmNhbnZhcy5nZXQoJ2NvbnRhaW5lcicpO1xuICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoY29udGFpbmVyXzEsIHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfSk7XG4gICAgICAgICAgICB0aGlzLnN0YXRpc3RpYyA9IG5ldyByaW5nX3N0YXRpc3RpY18xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IGNvbnRhaW5lcjogY29udGFpbmVyXzEsIHZpZXc6IHRoaXMudmlldywgcGxvdDogdGhpcywgc3RhdGlzdGljQ2xhc3M6IHRoaXMuc3RhdGlzdGljQ2xhc3MgfSwgdGhpcy5vcHRpb25zLnN0YXRpc3RpYykpO1xuICAgICAgICAgICAgdGhpcy5zdGF0aXN0aWMucmVuZGVyKCk7XG4gICAgICAgICAgICAvKirlk43lupTkuqTkupIgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3RhdGlzdGljLnRyaWdnZXJPbikge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGlzdGljLnRyaWdnZXJPbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIERvbnV0TGF5ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRpc3RpYykge1xuICAgICAgICAgICAgdGhpcy5zdGF0aXN0aWMuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgRG9udXRMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoZGltLCB0eXBlKSB7XG4gICAgICAgIGlmIChkaW0gPT09ICdnMicpIHtcbiAgICAgICAgICAgIHJldHVybiBHMl9HRU9NX01BUFt0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUExPVF9HRU9NX01BUFt0eXBlXTtcbiAgICB9O1xuICAgIERvbnV0TGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBjb29yZENvbmZpZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICd0aGV0YScsXG4gICAgICAgICAgICBjZmc6IHtcbiAgICAgICAgICAgICAgICByYWRpdXM6IHByb3BzLnJhZGl1cyxcbiAgICAgICAgICAgICAgICBpbm5lclJhZGl1czogcHJvcHMuaW5uZXJSYWRpdXMsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldENvbmZpZygnY29vcmRpbmF0ZScsIGNvb3JkQ29uZmlnKTtcbiAgICB9O1xuICAgIERvbnV0TGF5ZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgRXZlbnRQYXJzZXIpO1xuICAgIH07XG4gICAgLyoqIEBvdmVycmlkZSDosIPmlbQgbGFiZWwg6buY6K6kIG9wdGlvbnMgKi9cbiAgICBEb251dExheWVyLnByb3RvdHlwZS5hZGp1c3RMYWJlbERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGFiZWxDb25maWcgPSB0aGlzLm9wdGlvbnMubGFiZWw7XG4gICAgICAgIGlmIChsYWJlbENvbmZpZyAmJiBsYWJlbENvbmZpZy50eXBlID09PSAnaW5uZXInKSB7XG4gICAgICAgICAgICB2YXIgbGFiZWxTdHlsZUNvbmZpZyA9IChsYWJlbENvbmZpZy5zdHlsZSB8fCB7fSk7XG4gICAgICAgICAgICBpZiAoIWxhYmVsU3R5bGVDb25maWcudGV4dEFsaWduKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxTdHlsZUNvbmZpZy50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhYmVsQ29uZmlnLnN0eWxlID0gbGFiZWxTdHlsZUNvbmZpZztcbiAgICAgICAgICAgIGlmICghbGFiZWxDb25maWcub2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgbGFiZWxDb25maWcub2Zmc2V0ID0gKCh0aGlzLm9wdGlvbnMuaW5uZXJSYWRpdXMgLSAxKSAvIDIpICogMTAwICsgXCIlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERvbnV0TGF5ZXIuY2VudHJhbElkID0gMDtcbiAgICByZXR1cm4gRG9udXRMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBEb251dExheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZG9udXQnLCBEb251dExheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBGYW5HYXVnZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhGYW5HYXVnZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBGYW5HYXVnZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBGYW5HYXVnZS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2ZhbkdhdWdlJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEZhbkdhdWdlLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBGYW5HYXVnZTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEZhbkdhdWdlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2dhdWdlL2xheWVyXCIpKTtcbnZhciBnYXVnZV9zaGFwZV8xID0gcmVxdWlyZShcIi4uL2dhdWdlL2dlb21ldHJ5L3NoYXBlL2dhdWdlLXNoYXBlXCIpO1xudmFyIEZhbkdhdWdlTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRmFuR2F1Z2VMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBGYW5HYXVnZUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdmYW5HYXVnZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgRmFuR2F1Z2VMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgcmFuZ2VDb2xvcjogJyNGNjQ0NUEnLFxuICAgICAgICAgICAgcmFuZ2VTaXplOiA3MCxcbiAgICAgICAgICAgIGF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9mZnNldDogNSxcbiAgICAgICAgICAgICAgICB0aWNrQ291bnQ6IDEwLFxuICAgICAgICAgICAgICAgIHN1YlRpY2tDb3VudDogNCxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBsZW5ndGg6IDMsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjYWFhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiAnI2FhYScsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTYsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBGYW5HYXVnZUxheWVyLnByb3RvdHlwZS5pbml0RzJTaGFwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nYXVnZVNoYXBlID0gbmV3IGdhdWdlX3NoYXBlXzEuR2F1Z2VTaGFwZSh1dGlsXzEudW5pcXVlSWQoKSk7XG4gICAgICAgIHRoaXMuZ2F1Z2VTaGFwZS5zZXRPcHRpb24odGhpcy50eXBlLCB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5vcHRpb25zLCB7XG4gICAgICAgICAgICByYWRpdXM6IDEsXG4gICAgICAgICAgICBhbmdsZTogMTIwLFxuICAgICAgICAgICAgdGV4dFBvc2l0aW9uOiAnMTI1JScsXG4gICAgICAgICAgICBib3R0b21SYXRpbzogMy41LFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuZ2F1Z2VTaGFwZS5yZW5kZXIoKTtcbiAgICB9O1xuICAgIEZhbkdhdWdlTGF5ZXIucHJvdG90eXBlLmF4aXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBheGVzQ29uZmlnID0ge1xuICAgICAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICAgICAgMTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdheGVzJywgYXhlc0NvbmZpZyk7XG4gICAgfTtcbiAgICBGYW5HYXVnZUxheWVyLnByb3RvdHlwZS5hbm5vdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RhdGlzdGljID0gdGhpcy5vcHRpb25zLnN0YXRpc3RpYztcbiAgICAgICAgdmFyIGFubm90YXRpb25Db25maWdzID0gW107XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgaWYgKHN0YXRpc3RpYyAmJiBzdGF0aXN0aWMudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIHN0YXRpc3RpY3MgPSB0aGlzLnJlbmRlclN0YXRpc3RpYygpO1xuICAgICAgICAgICAgYW5ub3RhdGlvbkNvbmZpZ3MucHVzaChzdGF0aXN0aWNzKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2lkZXJUZXh0cyA9IHRoaXMucmVuZGVyU2lkZVRleHQoKTtcbiAgICAgICAgdmFyIGFsbEFubm90YXRpb25zID0gYW5ub3RhdGlvbkNvbmZpZ3MuY29uY2F0KHNpZGVyVGV4dHMpO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnYW5ub3RhdGlvbnMnLCBhbGxBbm5vdGF0aW9ucyk7XG4gICAgfTtcbiAgICBGYW5HYXVnZUxheWVyLnByb3RvdHlwZS5yZW5kZXJTaWRlVGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBtYXggPSBfYS5tYXgsIG1pbiA9IF9hLm1pbiwgZm9ybWF0ID0gX2EuZm9ybWF0LCByYW5nZVNpemUgPSBfYS5yYW5nZVNpemUsIGF4aXMgPSBfYS5heGlzO1xuICAgICAgICB2YXIgT0ZGU0VUX1kgPSAxMjtcbiAgICAgICAgcmV0dXJuIFttaW4sIG1heF0ubWFwKGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgICAgIHRvcDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogWyc1MCUnLCAnNTAlJ10sXG4gICAgICAgICAgICAgICAgY29udGVudDogZm9ybWF0KHZhbHVlKSxcbiAgICAgICAgICAgICAgICBzdHlsZTogdXRpbF8xLmRlZXBNaXgoe30sIGF4aXMubGFiZWwuc3R5bGUsIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBvZmZzZXRYOiAhaW5kZXggPyAtcmFuZ2VTaXplIDogcmFuZ2VTaXplLFxuICAgICAgICAgICAgICAgIG9mZnNldFk6IE9GRlNFVF9ZLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gRmFuR2F1Z2VMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBGYW5HYXVnZUxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZmFuR2F1Z2UnLCBGYW5HYXVnZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgZzJfMSA9IHJlcXVpcmUoXCJAYW50di9nMlwiKTtcbmZ1bmN0aW9uIGZ1bm5lbFNjYWxlSW5YKHNoYXBlLCBhbmltYXRlQ2ZnKSB7XG4gICAgdmFyIF9hID0gYW5pbWF0ZUNmZyB8fCB7fSwgX2IgPSBfYS5kdXJhdGlvbiwgZHVyYXRpb24gPSBfYiA9PT0gdm9pZCAwID8gMjAwIDogX2IsIGRlbGF5ID0gX2EuZGVsYXksIGVhc2luZyA9IF9hLmVhc2luZywgY2FsbGJhY2sgPSBfYS5jYWxsYmFjaywgcmV2ZXJzZSA9IF9hLnJldmVyc2U7XG4gICAgdmFyIGJib3ggPSBzaGFwZS5nZXRCQm94KCk7XG4gICAgdmFyIG9yaWdpblggPSByZXZlcnNlID8gYmJveC5tYXhYIDogYmJveC5taW5YO1xuICAgIHZhciBvcmlnaW5ZID0gKGJib3gubWluWSArIGJib3gubWF4WSkgLyAyO1xuICAgIHZhciBjbGlwID0gc2hhcGUuc2V0Q2xpcCh7XG4gICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgIHg6IGJib3gueCxcbiAgICAgICAgICAgIHk6IGJib3gueSxcbiAgICAgICAgICAgIHdpZHRoOiBiYm94LndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBiYm94LmhlaWdodCxcbiAgICAgICAgfSxcbiAgICB9KTtcbiAgICB2YXIgY2xpcFRhcmdldEF0dHJzID0ge1xuICAgICAgICBtYXRyaXg6IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXSxcbiAgICB9O1xuICAgIGNsaXAuc2V0TWF0cml4KG1hdHJpeF91dGlsXzEuZXh0LnRyYW5zZm9ybShjbGlwLmdldE1hdHJpeCgpLCBbXG4gICAgICAgIFsndCcsIC1vcmlnaW5YLCAtb3JpZ2luWV0sXG4gICAgICAgIFsncycsIDAsIDFdLFxuICAgICAgICBbJ3QnLCBvcmlnaW5YLCBvcmlnaW5ZXSxcbiAgICBdKSk7XG4gICAgdmFyIHNoYXBlVGFyZ2V0QXR0cnMgPSB7XG4gICAgICAgIGZpbGxPcGFjaXR5OiBzaGFwZS5hdHRyKCdmaWxsT3BhY2l0eScpLFxuICAgICAgICBzdHJva2VPcGFjaXR5OiBzaGFwZS5hdHRyKCdzdHJva2VPcGFjaXR5JyksXG4gICAgICAgIG9wYWNpdHk6IHNoYXBlLmF0dHIoJ29wYWNpdHknKSxcbiAgICB9O1xuICAgIHNoYXBlLmF0dHIoe1xuICAgICAgICBmaWxsT3BhY2l0eTogMCxcbiAgICAgICAgc3Ryb2tlT3BhY2l0eTogMCxcbiAgICAgICAgb3BhY2l0eTogMCxcbiAgICB9KTtcbiAgICBjbGlwLmFuaW1hdGUoY2xpcFRhcmdldEF0dHJzLCB7XG4gICAgICAgIGR1cmF0aW9uOiAyMDAsXG4gICAgICAgIGVhc2luZzogZWFzaW5nLFxuICAgICAgICBjYWxsYmFjazogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2hhcGUuc2V0Q2xpcChudWxsKTtcbiAgICAgICAgICAgIGNsaXAucmVtb3ZlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGRlbGF5OiBkZWxheSxcbiAgICB9KTtcbiAgICBzaGFwZS5hbmltYXRlKHNoYXBlVGFyZ2V0QXR0cnMsIHsgZHVyYXRpb246IGR1cmF0aW9uLCBlYXNpbmc6IGVhc2luZywgZGVsYXk6IGRlbGF5IH0pO1xuICAgIGNhbGxiYWNrICYmIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyByZXR1cm4gY2FsbGJhY2soc2hhcGUpOyB9LCBkdXJhdGlvbiArIGRlbGF5KTtcbn1cbmZ1bm5lbFNjYWxlSW5YLmFuaW1hdGlvbk5hbWUgPSAnZnVubmVsU2NhbGVJblgnO1xuZzJfMS5yZWdpc3RlckFuaW1hdGlvbignZnVubmVsU2NhbGVJblgnLCBmdW5uZWxTY2FsZUluWCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mdW5uZWwtc2NhbGUtaW4teC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIGcyXzEgPSByZXF1aXJlKFwiQGFudHYvZzJcIik7XG5mdW5jdGlvbiBmdW5uZWxTY2FsZUluWShzaGFwZSwgYW5pbWF0ZUNmZykge1xuICAgIHZhciBfYSA9IGFuaW1hdGVDZmcgfHwge30sIF9iID0gX2EuZHVyYXRpb24sIGR1cmF0aW9uID0gX2IgPT09IHZvaWQgMCA/IDIwMCA6IF9iLCBkZWxheSA9IF9hLmRlbGF5LCBlYXNpbmcgPSBfYS5lYXNpbmcsIGNhbGxiYWNrID0gX2EuY2FsbGJhY2ssIHJldmVyc2UgPSBfYS5yZXZlcnNlO1xuICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgIHZhciBvcmlnaW5YID0gKGJib3gubWluWCArIGJib3gubWF4WCkgLyAyO1xuICAgIHZhciBvcmlnaW5ZID0gcmV2ZXJzZSA/IGJib3gubWF4WSA6IGJib3gubWluWTtcbiAgICB2YXIgY2xpcCA9IHNoYXBlLnNldENsaXAoe1xuICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB4OiBiYm94LngsXG4gICAgICAgICAgICB5OiBiYm94LnksXG4gICAgICAgICAgICB3aWR0aDogYmJveC53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogYmJveC5oZWlnaHQsXG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgdmFyIGNsaXBUYXJnZXRBdHRycyA9IHtcbiAgICAgICAgbWF0cml4OiBbMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMV0sXG4gICAgfTtcbiAgICBjbGlwLnNldE1hdHJpeChtYXRyaXhfdXRpbF8xLmV4dC50cmFuc2Zvcm0oY2xpcC5nZXRNYXRyaXgoKSwgW1xuICAgICAgICBbJ3QnLCAtb3JpZ2luWCwgLW9yaWdpblldLFxuICAgICAgICBbJ3MnLCAxLCAwXSxcbiAgICAgICAgWyd0Jywgb3JpZ2luWCwgb3JpZ2luWV0sXG4gICAgXSkpO1xuICAgIHZhciBzaGFwZVRhcmdldEF0dHJzID0ge1xuICAgICAgICBmaWxsT3BhY2l0eTogc2hhcGUuYXR0cignZmlsbE9wYWNpdHknKSxcbiAgICAgICAgc3Ryb2tlT3BhY2l0eTogc2hhcGUuYXR0cignc3Ryb2tlT3BhY2l0eScpLFxuICAgICAgICBvcGFjaXR5OiBzaGFwZS5hdHRyKCdvcGFjaXR5JyksXG4gICAgfTtcbiAgICBzaGFwZS5hdHRyKHtcbiAgICAgICAgZmlsbE9wYWNpdHk6IDAsXG4gICAgICAgIHN0cm9rZU9wYWNpdHk6IDAsXG4gICAgICAgIG9wYWNpdHk6IDAsXG4gICAgfSk7XG4gICAgY2xpcC5hbmltYXRlKGNsaXBUYXJnZXRBdHRycywge1xuICAgICAgICBkdXJhdGlvbjogMjAwLFxuICAgICAgICBlYXNpbmc6IGVhc2luZyxcbiAgICAgICAgY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNoYXBlLnNldENsaXAobnVsbCk7XG4gICAgICAgICAgICBjbGlwLnJlbW92ZSgpO1xuICAgICAgICB9LFxuICAgICAgICBkZWxheTogZGVsYXksXG4gICAgfSk7XG4gICAgc2hhcGUuYW5pbWF0ZShzaGFwZVRhcmdldEF0dHJzLCB7IGR1cmF0aW9uOiBkdXJhdGlvbiwgZWFzaW5nOiBlYXNpbmcsIGRlbGF5OiBkZWxheSB9KTtcbiAgICBjYWxsYmFjayAmJiBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNhbGxiYWNrKHNoYXBlKTsgfSwgZHVyYXRpb24gKyBkZWxheSk7XG59XG5mdW5uZWxTY2FsZUluWS5hbmltYXRpb25OYW1lID0gJ2Z1bm5lbFNjYWxlSW5ZJztcbmcyXzEucmVnaXN0ZXJBbmltYXRpb24oJ2Z1bm5lbFNjYWxlSW5ZJywgZnVubmVsU2NhbGVJblkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZnVubmVsLXNjYWxlLWluLXkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnMl8xID0gcmVxdWlyZShcIkBhbnR2L2cyXCIpO1xudmFyIGdldF9zdHlsZV8xID0gcmVxdWlyZShcIkBhbnR2L2cyL2xpYi9nZW9tZXRyeS9zaGFwZS91dGlsL2dldC1zdHlsZVwiKTtcbi8vIOagueaNruaVsOaNrueCueeUn+aIkOefqeW9oueahOWbm+S4quWFs+mUrueCuVxuZnVuY3Rpb24gX2dldFJlY3RQb2ludHMoY2ZnLCBpc1B5cmFtaWQpIHtcbiAgICBpZiAoaXNQeXJhbWlkID09PSB2b2lkIDApIHsgaXNQeXJhbWlkID0gZmFsc2U7IH1cbiAgICB2YXIgeCA9IGNmZy54LCB5ID0gY2ZnLnksIHkwID0gY2ZnLnkwLCBzaXplID0gY2ZnLnNpemU7XG4gICAgLy8g5pyJIDQg56eN5oOF5Ya177yMXG4gICAgLy8gMS4geCwgeSDpg73kuI3mmK/mlbDnu4RcbiAgICAvLyAyLiB55piv5pWw57uE77yMeOS4jeaYr1xuICAgIC8vIDMuIHjmmK/mlbDnu4TvvIx55LiN5pivXG4gICAgLy8gNC4geCwgeSDpg73mmK/mlbDnu4RcbiAgICB2YXIgeU1pbjtcbiAgICB2YXIgeU1heDtcbiAgICBpZiAodXRpbF8xLmlzQXJyYXkoeSkpIHtcbiAgICAgICAgeU1pbiA9IHlbMF07XG4gICAgICAgIHlNYXggPSB5WzFdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgeU1pbiA9IHkwO1xuICAgICAgICB5TWF4ID0geTtcbiAgICB9XG4gICAgdmFyIHhNaW47XG4gICAgdmFyIHhNYXg7XG4gICAgaWYgKHV0aWxfMS5pc0FycmF5KHgpKSB7XG4gICAgICAgIHhNaW4gPSB4WzBdO1xuICAgICAgICB4TWF4ID0geFsxXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHhNaW4gPSB4IC0gc2l6ZSAvIDI7XG4gICAgICAgIHhNYXggPSB4ICsgc2l6ZSAvIDI7XG4gICAgfVxuICAgIHZhciBwb2ludHMgPSBbXG4gICAgICAgIHsgeDogeE1pbiwgeTogeU1pbiB9LFxuICAgICAgICB7IHg6IHhNaW4sIHk6IHlNYXggfSxcbiAgICBdO1xuICAgIGlmIChpc1B5cmFtaWQpIHtcbiAgICAgICAgLy8g57uY5Yi25bCW5bqV5ryP5paX5Zu+XG4gICAgICAgIC8vIOmHkeWtl+WhlOa8j+aWl+WbvueahOWFs+mUrueCuVxuICAgICAgICAvLyAxXG4gICAgICAgIC8vIHwgICAyXG4gICAgICAgIC8vIDBcbiAgICAgICAgcG9pbnRzLnB1c2goe1xuICAgICAgICAgICAgeDogeE1heCxcbiAgICAgICAgICAgIHk6ICh5TWF4ICsgeU1pbikgLyAyLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIOefqeW9oueahOWbm+S4quWFs+mUrueCue+8jOe7k+aehOWmguS4i++8iOW3puS4i+inkumhuuaXtumSiOi/nuaOpe+8iVxuICAgICAgICAvLyAxIC0tLS0gMlxuICAgICAgICAvLyB8ICAgICAgfFxuICAgICAgICAvLyAwIC0tLS0gM1xuICAgICAgICBwb2ludHMucHVzaCh7IHg6IHhNYXgsIHk6IHlNYXggfSwgeyB4OiB4TWF4LCB5OiB5TWluIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcG9pbnRzO1xufVxuLy8g5qC55o2u5YWz6ZSu54K557uY5Yi25ryP5paX5Zu+55qEIHBhdGhcbmZ1bmN0aW9uIF9nZXRGdW5uZWxQYXRoKGNmZywgY29tcGFyZSkge1xuICAgIHZhciBwYXRoID0gW107XG4gICAgdmFyIHBvaW50cyA9IGNmZy5wb2ludHMsIG5leHRQb2ludHMgPSBjZmcubmV4dFBvaW50cztcbiAgICBpZiAoY29tcGFyZSkge1xuICAgICAgICAvLyDlr7nmr5TmvI/mlpdcbiAgICAgICAgdmFyIHlWYWx1ZXMgPSBjb21wYXJlLnlWYWx1ZXMsIHlWYWx1ZXNNYXggPSBjb21wYXJlLnlWYWx1ZXNNYXgsIHlWYWx1ZXNOZXh0ID0gY29tcGFyZS55VmFsdWVzTmV4dDtcbiAgICAgICAgdmFyIG9yaWdpblkgPSAocG9pbnRzWzBdLnkgKyBwb2ludHNbMV0ueSkgLyAyO1xuICAgICAgICB2YXIgeVZhbHVlVG90YWxfMSA9IHlWYWx1ZXNbMF0gKyB5VmFsdWVzWzFdO1xuICAgICAgICB2YXIgeVJhdGlvcyA9IHlWYWx1ZXMubWFwKGZ1bmN0aW9uICh5VmFsdWUpIHsgcmV0dXJuIHlWYWx1ZSAvIHlWYWx1ZVRvdGFsXzEgLyAwLjU7IH0pO1xuICAgICAgICB2YXIgeU9mZnNldCA9ICh5VmFsdWVzTWF4WzBdIC8gKHlWYWx1ZXNNYXhbMF0gKyB5VmFsdWVzTWF4WzFdKSAtIDAuNSkgKiAwLjk7XG4gICAgICAgIHZhciBzcGFjaW5nID0gMC4wMDE7XG4gICAgICAgIGlmICghdXRpbF8xLmlzTmlsKG5leHRQb2ludHMpKSB7XG4gICAgICAgICAgICB2YXIgeVZhbHVlVG90YWxOZXh0XzEgPSB5VmFsdWVzTmV4dFswXSArIHlWYWx1ZXNOZXh0WzFdO1xuICAgICAgICAgICAgdmFyIHlSYXRpb3NOZXh0ID0geVZhbHVlc05leHQubWFwKGZ1bmN0aW9uICh5VmFsdWVOZXh0KSB7IHJldHVybiB5VmFsdWVOZXh0IC8geVZhbHVlVG90YWxOZXh0XzEgLyAwLjU7IH0pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50c1swXS54LCB5T2Zmc2V0ICsgKHBvaW50c1swXS55IC0gb3JpZ2luWSkgKiB5UmF0aW9zWzBdICsgb3JpZ2luWSAtIHNwYWNpbmddLCBbJ0wnLCBwb2ludHNbMV0ueCwgeU9mZnNldCArIG9yaWdpblkgLSBzcGFjaW5nXSwgWydMJywgbmV4dFBvaW50c1sxXS54LCB5T2Zmc2V0ICsgb3JpZ2luWSAtIHNwYWNpbmddLCBbJ0wnLCBuZXh0UG9pbnRzWzBdLngsIHlPZmZzZXQgKyAobmV4dFBvaW50c1szXS55IC0gb3JpZ2luWSkgKiB5UmF0aW9zTmV4dFswXSArIG9yaWdpblkgLSBzcGFjaW5nXSwgWydaJ10pO1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50c1swXS54LCB5T2Zmc2V0ICsgb3JpZ2luWSArIHNwYWNpbmddLCBbJ0wnLCBwb2ludHNbMV0ueCwgeU9mZnNldCArIChwb2ludHNbMV0ueSAtIG9yaWdpblkpICogeVJhdGlvc1sxXSArIG9yaWdpblkgKyBzcGFjaW5nXSwgWydMJywgbmV4dFBvaW50c1sxXS54LCB5T2Zmc2V0ICsgKG5leHRQb2ludHNbMl0ueSAtIG9yaWdpblkpICogeVJhdGlvc05leHRbMV0gKyBvcmlnaW5ZICsgc3BhY2luZ10sIFsnTCcsIG5leHRQb2ludHNbMF0ueCwgeU9mZnNldCArIG9yaWdpblkgKyBzcGFjaW5nXSwgWydaJ10pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnTScsIHBvaW50c1swXS54LCB5T2Zmc2V0ICsgKHBvaW50c1swXS55IC0gb3JpZ2luWSkgKiB5UmF0aW9zWzBdICsgb3JpZ2luWV0sIFsnTCcsIHBvaW50c1sxXS54LCB5T2Zmc2V0ICsgb3JpZ2luWV0sIFsnTCcsIHBvaW50c1syXS54LCB5T2Zmc2V0ICsgb3JpZ2luWV0sIFsnTCcsIHBvaW50c1szXS54LCB5T2Zmc2V0ICsgKHBvaW50c1szXS55IC0gb3JpZ2luWSkgKiB5UmF0aW9zWzBdICsgb3JpZ2luWV0sIFsnWiddKTtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCBwb2ludHNbMF0ueCwgeU9mZnNldCArIDAuMDAyICsgb3JpZ2luWV0sIFsnTCcsIHBvaW50c1sxXS54LCB5T2Zmc2V0ICsgMC4wMDIgKyAocG9pbnRzWzFdLnkgLSBvcmlnaW5ZKSAqIHlSYXRpb3NbMV0gKyBvcmlnaW5ZXSwgWydMJywgcG9pbnRzWzJdLngsIHlPZmZzZXQgKyAwLjAwMiArIChwb2ludHNbMl0ueSAtIG9yaWdpblkpICogeVJhdGlvc1sxXSArIG9yaWdpblldLCBbJ0wnLCBwb2ludHNbM10ueCwgeU9mZnNldCArIDAuMDAyICsgb3JpZ2luWV0sIFsnWiddKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g5qCH5YeG5ryP5paXXG4gICAgICAgIGlmICghdXRpbF8xLmlzTmlsKG5leHRQb2ludHMpKSB7XG4gICAgICAgICAgICBwYXRoLnB1c2goWydNJywgcG9pbnRzWzBdLngsIHBvaW50c1swXS55XSwgWydMJywgcG9pbnRzWzFdLngsIHBvaW50c1sxXS55XSwgWydMJywgbmV4dFBvaW50c1sxXS54LCBuZXh0UG9pbnRzWzFdLnldLCBbJ0wnLCBuZXh0UG9pbnRzWzBdLngsIG5leHRQb2ludHNbMF0ueV0sIFsnWiddKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHBhdGgucHVzaChbJ00nLCBwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnldLCBbJ0wnLCBwb2ludHNbMV0ueCwgcG9pbnRzWzFdLnldLCBbJ0wnLCBwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnldLCBbJ0wnLCBwb2ludHNbM10ueCwgcG9pbnRzWzNdLnldLCBbJ1onXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBhdGg7XG59XG5nMl8xLnJlZ2lzdGVyU2hhcGUoJ2ludGVydmFsJywgJ2Z1bm5lbC1iYXNpYy1yZWN0Jywge1xuICAgIGdldFBvaW50czogZnVuY3Rpb24gKHBvaW50SW5mbykge1xuICAgICAgICBwb2ludEluZm8uc2l6ZSA9IHBvaW50SW5mby5zaXplICogMS44OyAvLyDosIPmlbTpnaLnp69cbiAgICAgICAgcmV0dXJuIF9nZXRSZWN0UG9pbnRzKHBvaW50SW5mbyk7XG4gICAgfSxcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgdmFyIGNvbXBhcmUgPSB1dGlsXzEuZ2V0KGNmZywgJ2RhdGEuX19jb21wYXJlX18nKTtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLnBhcnNlUGF0aChfZ2V0RnVubmVsUGF0aChjZmcsIGNvbXBhcmUpKTtcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIChfYSA9IHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnaW50ZXJ2YWwnLFxuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHN0eWxlKSwgeyBwYXRoOiBwYXRoIH0pXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgX2FbJ19fY29tcGFyZV9fJ10gPSBjb21wYXJlLFxuICAgICAgICAgICAgX2EpKTtcbiAgICB9LFxuICAgIGdldE1hcmtlcjogZnVuY3Rpb24gKG1hcmtlckNmZykge1xuICAgICAgICB2YXIgY29sb3IgPSBtYXJrZXJDZmcuY29sb3I7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzeW1ib2w6ICdzcXVhcmUnLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICByOiA0LFxuICAgICAgICAgICAgICAgIGZpbGw6IGNvbG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mdW5uZWwtYmFzaWMtcmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGcyXzEgPSByZXF1aXJlKFwiQGFudHYvZzJcIik7XG52YXIgZ2V0X3N0eWxlXzEgPSByZXF1aXJlKFwiQGFudHYvZzIvbGliL2dlb21ldHJ5L3NoYXBlL3V0aWwvZ2V0LXN0eWxlXCIpO1xuZnVuY3Rpb24gbGVycChhLCBiLCBmYWN0b3IpIHtcbiAgICByZXR1cm4gKDEgLSBmYWN0b3IpICogYSArIGZhY3RvciAqIGI7XG59XG4vLyDmoLnmja7nn6nlvaLlhbPplK7ngrnnu5jliLYgcGF0aFxuZnVuY3Rpb24gX2dldFJlY3RQYXRoKHBvaW50cywgX2EpIHtcbiAgICB2YXIgcmV2ZXJzZSA9IF9hLnJldmVyc2UsIHJhdGlvVXBwZXIgPSBfYS5yYXRpb1VwcGVyLCByYXRpb0xvd2VyID0gX2EucmF0aW9Mb3dlcjtcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIHZhciBmaXJzdFBvaW50ID0gcG9pbnRzWzBdO1xuICAgIHZhciBvcmlnaW5YID0gKHBvaW50c1sxXS54ICsgcG9pbnRzWzJdLngpIC8gMjtcbiAgICB2YXIgZmFjdG9yVG9wID0gMS4yO1xuICAgIHZhciBmYWN0b3JCb3R0b20gPSAwLjY7XG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgdmFyIHRtcCA9IHJhdGlvTG93ZXI7XG4gICAgICAgIHJhdGlvTG93ZXIgPSByYXRpb1VwcGVyO1xuICAgICAgICByYXRpb1VwcGVyID0gdG1wO1xuICAgIH1cbiAgICB2YXIgZmlyc3RQb2ludFggPSAoZmlyc3RQb2ludC54IC0gb3JpZ2luWCkgKiBsZXJwKGZhY3RvckJvdHRvbSwgZmFjdG9yVG9wLCByYXRpb0xvd2VyKSArIG9yaWdpblg7XG4gICAgcGF0aC5wdXNoKFsnTScsIGZpcnN0UG9pbnRYLCBmaXJzdFBvaW50LnldKTtcbiAgICBmb3IgKHZhciBpID0gMSwgbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludFggPSBwb2ludHNbaV0ueDtcbiAgICAgICAgc3dpdGNoIChpKSB7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgcG9pbnRYID0gKHBvaW50WCAtIG9yaWdpblgpICogbGVycChmYWN0b3JCb3R0b20sIGZhY3RvclRvcCwgcmF0aW9VcHBlcikgKyBvcmlnaW5YO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBvaW50WCA9IChwb2ludFggLSBvcmlnaW5YKSAqIGxlcnAoZmFjdG9yQm90dG9tLCBmYWN0b3JUb3AsIHJhdGlvTG93ZXIpICsgb3JpZ2luWDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBwYXRoLnB1c2goWydMJywgcG9pbnRYLCBwb2ludHNbaV0ueV0pO1xuICAgIH1cbiAgICBwYXRoLnB1c2goWydMJywgZmlyc3RQb2ludFgsIGZpcnN0UG9pbnQueV0pOyAvLyDpnIDopoHpl63lkIhcbiAgICBwYXRoLnB1c2goWyd6J10pO1xuICAgIHJldHVybiBwYXRoO1xufVxuZzJfMS5yZWdpc3RlclNoYXBlKCdpbnRlcnZhbCcsICdmdW5uZWwtZHluYW1pYy1yZWN0Jywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgc3R5bGUgPSBnZXRfc3R5bGVfMS5nZXRTdHlsZShjZmcsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgdmFyIGN1c3RvbSA9IHV0aWxfMS5nZXQoY2ZnLCAnZGF0YS5fX2N1c3RvbV9fJyk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5wYXJzZVBhdGgoX2dldFJlY3RQYXRoKGNmZy5wb2ludHMsIGN1c3RvbSkpO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgc3R5bGUpLCB7IHBhdGg6IHBhdGggfSksXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgZ2V0TWFya2VyOiBmdW5jdGlvbiAobWFya2VyQ2ZnKSB7XG4gICAgICAgIHZhciBjb2xvciA9IG1hcmtlckNmZy5jb2xvciwgaXNJblBvbGFyID0gbWFya2VyQ2ZnLmlzSW5Qb2xhcjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN5bWJvbDogaXNJblBvbGFyID8gJ2NpcmNsZScgOiAnc3F1YXJlJyxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgcjogaXNJblBvbGFyID8gNC41IDogNCxcbiAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZnVubmVsLWR5bmFtaWMtcmVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgRnVubmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEZ1bm5lbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBGdW5uZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgRnVubmVsLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnZnVubmVsJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEZ1bm5lbC5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gRnVubmVsO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRnVubmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkb21fdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L2RvbS11dGlsXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIHZpZXdfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3ZpZXctbGF5ZXJcIikpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xucmVxdWlyZShcIi4vdGhlbWVcIik7XG5yZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9mdW5uZWwtYmFzaWMtcmVjdFwiKTtcbnJlcXVpcmUoXCIuL2dlb21ldHJ5L3NoYXBlL2Z1bm5lbC1keW5hbWljLXJlY3RcIik7XG5yZXF1aXJlKFwiLi9hbmltYXRpb24vZnVubmVsLXNjYWxlLWluLXhcIik7XG5yZXF1aXJlKFwiLi9hbmltYXRpb24vZnVubmVsLXNjYWxlLWluLXlcIik7XG52YXIgY29sb3JfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2NvbG9yXCIpO1xuZnVuY3Rpb24gbGVycChhLCBiLCBmYWN0b3IpIHtcbiAgICByZXR1cm4gKDEgLSBmYWN0b3IpICogYSArIGZhY3RvciAqIGI7XG59XG52YXIgRzJfR0VPTV9NQVAgPSB7XG4gICAgY29sdW1uOiAnaW50ZXJ2YWwnLFxufTtcbnZhciBQTE9UX0dFT01fTUFQID0ge1xuICAgIGludGVydmFsOiAnZnVubmVsJyxcbn07XG52YXIgRnVubmVsTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoRnVubmVsTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gRnVubmVsTGF5ZXIocHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgcHJvcHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnZnVubmVsJztcbiAgICAgICAgX3RoaXMuX3Nob3VsZFJlc2V0UGVyY2VudGFnZXMgPSB0cnVlO1xuICAgICAgICBfdGhpcy5fc2hvdWxkUmVzZXRMYWJlbHMgPSB0cnVlO1xuICAgICAgICBfdGhpcy5fc2hvdWxkUmVzZXRDb21wYXJlVGV4dHMgPSB0cnVlO1xuICAgICAgICBfdGhpcy5fbGVnZW5kc0xpc3RlbmVyQXR0YWNoZWQgPSBmYWxzZTtcbiAgICAgICAgX3RoaXMuX29uTGVnZW5kQ29udGFpbmVyTW91c2VEb3duID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciBwcm9wcyA9IF90aGlzLm9wdGlvbnM7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0TmFtZSA9IGUudGFyZ2V0LmdldCgnbmFtZScpO1xuICAgICAgICAgICAgaWYgKHRhcmdldE5hbWUuc3RhcnRzV2l0aCgnbGVnZW5kLWl0ZW0nKSkge1xuICAgICAgICAgICAgICAgIHZhciBsZWdlbmRJdGVtID0gZS50YXJnZXQuZ2V0KCdwYXJlbnQnKTtcbiAgICAgICAgICAgICAgICBsZWdlbmRJdGVtLnNldCgndW5jaGVja2VkJywgIWxlZ2VuZEl0ZW0uZ2V0KCd1bmNoZWNrZWQnKSk7XG4gICAgICAgICAgICAgICAgX3RoaXMucmVmcmVzaFBlcmNlbnRhZ2VzKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMucmVmcmVzaExhYmVscygpO1xuICAgICAgICAgICAgICAgIGlmIChwcm9wcy5keW5hbWljSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBkYXRhID0gX3RoaXMuX2ZpbmRDaGVja2VkRGF0YUJ5TW91c2VEb3duTGVnZW5kSXRlbShsZWdlbmRJdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2dlbkN1c3RvbUZpZWxkRm9yRHluYW1pY0hlaWdodChkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHByb3BzLmNvbXBhcmVGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IF90aGlzLl9maW5kQ2hlY2tlZERhdGFCeU1vdXNlRG93bkxlZ2VuZEl0ZW0obGVnZW5kSXRlbSk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl91cGRhdGVEYXRhRm9yQ29tcGFyZShkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucmVmcmVzaENvbXBhcmVUZXh0cygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgX3RoaXMuYWRqdXN0UHJvcHMoX3RoaXMub3B0aW9ucyk7XG4gICAgICAgIGlmIChwcm9wcy5keW5hbWljSGVpZ2h0KSB7XG4gICAgICAgICAgICBfdGhpcy5fZ2VuQ3VzdG9tRmllbGRGb3JEeW5hbWljSGVpZ2h0KF90aGlzLmdldERhdGEoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLmNvbXBhcmVGaWVsZCkge1xuICAgICAgICAgICAgX3RoaXMub3B0aW9ucy5kYXRhID0gX3RoaXMuX3JlZHVjZURhdGFGb3JDb21wYXJlKF90aGlzLmdldERhdGEoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBGdW5uZWxMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgY2ZnID0ge1xuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGFkanVzdENvbG9yOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBlcmNlbnRhZ2U6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9mZnNldFg6IHByb3BzLnRyYW5zcG9zZSA/IDAgOiA0MCxcbiAgICAgICAgICAgICAgICBvZmZzZXRZOiBwcm9wcy50cmFuc3Bvc2UgPyA0MCA6IDAsXG4gICAgICAgICAgICAgICAgc3BhY2luZzogNCxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsIDAsIDAsIDAuMTUpJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogJ+i9rOWMlueOhycsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgwLCAwLCAwLCAwLjY1KScsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogJ2JsYWNrJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVyOiBmdW5jdGlvbiAoeVZhbHVlVXBwZXIsIHlWYWx1ZUxvd2VyKSB7IHJldHVybiAoKDEwMCAqIHlWYWx1ZUxvd2VyKSAvIHlWYWx1ZVVwcGVyKS50b0ZpeGVkKDIpICsgXCIlXCI7IH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzaGFyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hvd1RpdGxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzaG93Q3Jvc3NoYWlyczogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFuaW1hdGlvbjogdXRpbF8xLmRlZXBNaXgoe30sIGRlcGVuZGVudHNfMS5ERUZBVUxUX0FOSU1BVEVfQ0ZHLCB7XG4gICAgICAgICAgICAgICAgYXBwZWFyOiB7XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiA4MDAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZHluYW1pY0hlaWdodDogZmFsc2UsXG4gICAgICAgICAgICBjb21wYXJlVGV4dDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgb2Zmc2V0WDogLTE2LFxuICAgICAgICAgICAgICAgIG9mZnNldFk6IC0xNixcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnYmxhY2snLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdib3R0b20tY2VudGVyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbnRlcmFjdGlvbnM6IFt7IHR5cGU6ICd0b29sdGlwJyB9LCB7IHR5cGU6ICdsZWdlbmQtZmlsdGVyJyB9XSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwgY2ZnKTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5nZXRDb2xvclNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeEZpZWxkID0gdGhpcy5vcHRpb25zLnhGaWVsZDtcbiAgICAgICAgaWYgKHhGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoeEZpZWxkKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBjb29yZENvbmZpZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgICAgIGFjdGlvbnM6IHByb3BzLnRyYW5zcG9zZVxuICAgICAgICAgICAgICAgID8gcHJvcHMuZHluYW1pY0hlaWdodFxuICAgICAgICAgICAgICAgICAgICA/IFtbJ3RyYW5zcG9zZSddLCBbJ3NjYWxlJywgMSwgLTFdXVxuICAgICAgICAgICAgICAgICAgICA6IFtbJ3NjYWxlJywgMSwgLTFdXVxuICAgICAgICAgICAgICAgIDogcHJvcHMuZHluYW1pY0hlaWdodFxuICAgICAgICAgICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICAgICAgICAgIDogW1sndHJhbnNwb3NlJ10sIFsnc2NhbGUnLCAxLCAtMV1dLFxuICAgICAgICB9O1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdjb29yZGluYXRlJywgY29vcmRDb25maWcpO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmF4aXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdheGVzJywgZmFsc2UpO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmFkanVzdEZ1bm5lbCA9IGZ1bmN0aW9uIChmdW5uZWwpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGZ1bm5lbC5zaGFwZSA9IHByb3BzLmR5bmFtaWNIZWlnaHQgPyAnZnVubmVsLWR5bmFtaWMtcmVjdCcgOiAnZnVubmVsLWJhc2ljLXJlY3QnO1xuICAgICAgICBmdW5uZWwuY29sb3IgPSB7XG4gICAgICAgICAgICBmaWVsZHM6IFtwcm9wcy54RmllbGRdLFxuICAgICAgICAgICAgdmFsdWVzOiBwcm9wcy5jb2xvciAmJiAoQXJyYXkuaXNBcnJheShwcm9wcy5jb2xvcikgPyBwcm9wcy5jb2xvciA6IFtwcm9wcy5jb2xvcl0pLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24ocHJvcHMuZnVubmVsU3R5bGUpKSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBmdW5uZWwuc3R5bGUgPSB7IGNhbGxiYWNrOiBwcm9wcy5mdW5uZWxTdHlsZSB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgZnVubmVsLnN0eWxlID0geyBjZmc6IHByb3BzLmZ1bm5lbFN0eWxlIH07XG4gICAgICAgIH1cbiAgICAgICAgZnVubmVsLmFkanVzdCA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBwcm9wcy5keW5hbWljSGVpZ2h0ID8gJ3N0YWNrJyA6ICdzeW1tZXRyaWMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS50b29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmIChwcm9wcy5jb21wYXJlRmllbGQpIHtcbiAgICAgICAgICAgIHV0aWxfMS5kZWVwTWl4KHByb3BzLnRvb2x0aXAsIHtcbiAgICAgICAgICAgICAgICBodG1sQ29udGVudDogZnVuY3Rpb24gKHRpdGxlLCBpdGVtcykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY2xzcywgZWwsIGNvbG9yLCBlbE1hcmtlcjtcbiAgICAgICAgICAgICAgICAgICAgY2xzcyA9IGRlcGVuZGVudHNfMS5Ub29sdGlwQ3NzQ29uc3QuQ09OVEFJTkVSX0NMQVNTO1xuICAgICAgICAgICAgICAgICAgICBlbCA9IGRvbV91dGlsXzEuY3JlYXRlRG9tKFwiPGRpdiBjbGFzcz1cXFwiXCIgKyBjbHNzICsgXCJcXFwiPjwvZGl2PlwiKTtcbiAgICAgICAgICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoZWwsIGRlcGVuZGVudHNfMS5IdG1sVG9vbHRpcFRoZW1lW2Nsc3NdKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsUm9vdCA9IGVsO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGl0bGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsc3MgPSBkZXBlbmRlbnRzXzEuVG9vbHRpcENzc0NvbnN0LlRJVExFX0NMQVNTO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBkb21fdXRpbF8xLmNyZWF0ZURvbShcIjxkaXYgY2xhc3M9XFxcIlwiICsgY2xzcyArIFwiXFxcIj48L2Rpdj5cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb21fdXRpbF8xLm1vZGlmeUNTUyhlbCwgZGVwZW5kZW50c18xLkh0bWxUb29sdGlwVGhlbWVbY2xzc10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxSb290LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbFRpdGxlID0gZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbHNzID0gZGVwZW5kZW50c18xLlRvb2x0aXBDc3NDb25zdC5NQVJLRVJfQ0xBU1M7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IGRvbV91dGlsXzEuY3JlYXRlRG9tKFwiPHNwYW4gY2xhc3M9XFxcIlwiICsgY2xzcyArIFwiXFxcIj48L3NwYW4+XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoZWwsIGRlcGVuZGVudHNfMS5IdG1sVG9vbHRpcFRoZW1lW2Nsc3NdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGVsLCB7IHdpZHRoOiAnMTBweCcsIGhlaWdodDogJzEwcHgnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxUaXRsZS5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbE1hcmtlciA9IGVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBkb21fdXRpbF8xLmNyZWF0ZURvbShcIjxzcGFuPlwiICsgdGl0bGUgKyBcIjwvc3Bhbj5cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbFRpdGxlLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsc3MgPSBkZXBlbmRlbnRzXzEuVG9vbHRpcENzc0NvbnN0LkxJU1RfQ0xBU1M7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IGRvbV91dGlsXzEuY3JlYXRlRG9tKFwiPHVsIGNsYXNzPVxcXCJcIiArIGNsc3MgKyBcIlxcXCI+PC91bD5cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb21fdXRpbF8xLm1vZGlmeUNTUyhlbCwgZGVwZW5kZW50c18xLkh0bWxUb29sdGlwVGhlbWVbY2xzc10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxSb290LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbExpc3RfMSA9IGVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVkdWNlKGZ1bmN0aW9uIChwYWlycywgaXRlbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29sb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBpdGVtLmNvbG9yO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29tcGFyZVZhbHVlcyA9IHV0aWxfMS5nZXQoaXRlbSwgJ3BvaW50Ll9vcmlnaW4uX19jb21wYXJlX18uY29tcGFyZVZhbHVlcycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB5VmFsdWVzID0gdXRpbF8xLmdldChpdGVtLCAncG9pbnQuX29yaWdpbi5fX2NvbXBhcmVfXy55VmFsdWVzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeVZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uICh5VmFsdWUsIGkpIHsgcmV0dXJuIHBhaXJzLnB1c2goW2NvbXBhcmVWYWx1ZXNbaV0sIHlWYWx1ZV0pOyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFpcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBbXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaChmdW5jdGlvbiAoX2EsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbXBhcmVWYWx1ZSA9IF9hWzBdLCB5VmFsdWUgPSBfYVsxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbHNzID0gZGVwZW5kZW50c18xLlRvb2x0aXBDc3NDb25zdC5MSVNUX0lURU1fQ0xBU1M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBkb21fdXRpbF8xLmNyZWF0ZURvbShcIjxsaSBjbGFzcz1cXFwiXCIgKyBjbHNzICsgXCJcXFwiIGRhdGEtaW5kZXg9XCIgKyBpbmRleCArIFwiPjwvbGk+XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGVsLCBkZXBlbmRlbnRzXzEuSHRtbFRvb2x0aXBUaGVtZVtjbHNzXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxMaXN0XzEuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbExpc3RJdGVtID0gZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xzcyA9IGRlcGVuZGVudHNfMS5Ub29sdGlwQ3NzQ29uc3QuTkFNRV9DTEFTUztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbCA9IGRvbV91dGlsXzEuY3JlYXRlRG9tKFwiPHNwYW4gY2xhc3M9XFxcIlwiICsgY2xzcyArIFwiXFxcIj5cIiArIGNvbXBhcmVWYWx1ZSArIFwiPC9zcGFuPlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21fdXRpbF8xLm1vZGlmeUNTUyhlbCwgZGVwZW5kZW50c18xLkh0bWxUb29sdGlwVGhlbWVbY2xzc10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsTGlzdEl0ZW0uYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsc3MgPSBkZXBlbmRlbnRzXzEuVG9vbHRpcENzc0NvbnN0LlZBTFVFX0NMQVNTO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gZG9tX3V0aWxfMS5jcmVhdGVEb20oXCI8c3BhbiBjbGFzcz1cXFwiXCIgKyBjbHNzICsgXCJcXFwiPlwiICsgeVZhbHVlICsgXCI8L3NwYW4+XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGVsLCBkZXBlbmRlbnRzXzEuSHRtbFRvb2x0aXBUaGVtZVtjbHNzXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxMaXN0SXRlbS5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sb3IgJiYgZWxNYXJrZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbV91dGlsXzEubW9kaWZ5Q1NTKGVsTWFya2VyLCB7IGJhY2tncm91bmRDb2xvcjogY29sb3IgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsUm9vdDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS50b29sdGlwLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGZ1bm5lbCA9IGZhY3RvcnlfMS5nZXRHZW9tKCdpbnRlcnZhbCcsICdtYWluJywge1xuICAgICAgICAgICAgcG9zaXRpb25GaWVsZHM6IFtwcm9wcy5keW5hbWljSGVpZ2h0ID8gJ18nIDogcHJvcHMueEZpZWxkLCBwcm9wcy55RmllbGRdLFxuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWRqdXN0RnVubmVsKGZ1bm5lbCk7XG4gICAgICAgIHRoaXMuZnVubmVsID0gZnVubmVsO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBmdW5uZWwpO1xuICAgICAgICBpZiAoIXByb3BzLmNvbXBhcmVGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeVRvb2x0aXAoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5mdW5uZWwudG9vbHRpcCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZnVubmVsLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZnVubmVsLnRvb2x0aXAuZmllbGRzID0gdG9vbHRpcE9wdGlvbnMuZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5mdW5uZWwudG9vbHRpcCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZnVubmVsLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZnVubmVsLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAoIXRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIHRoaXMuZnVubmVsLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUuYW5pbWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFuaW1hdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmIChwcm9wcy5hbmltYXRpb24gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAvKiog5YWz6Zet5Yqo55S7ICovXG4gICAgICAgICAgICB0aGlzLmZ1bm5lbC5hbmltYXRlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgZGF0YV8xID0gdGhpcy5nZXREYXRhKCk7XG4gICAgICAgICAgICB2YXIgYXBwZWFyRHVyYXRpb24gPSB1dGlsXzEuZ2V0KHByb3BzLCAnYW5pbWF0aW9uLmFwcGVhci5kdXJhdGlvbicpO1xuICAgICAgICAgICAgdmFyIGFwcGVhckR1cmF0aW9uRWFjaF8xID0gYXBwZWFyRHVyYXRpb24gLyAoZGF0YV8xLmxlbmd0aCB8fCAxKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hbmltYXRpb25BcHBlYXJUaW1lb3V0SGFuZGxlcikge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9hbmltYXRpb25BcHBlYXJUaW1lb3V0SGFuZGxlcik7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2FuaW1hdGlvbkFwcGVhclRpbWVvdXRIYW5kbGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYW5pbWF0aW9uQXBwZWFyVGltZW91dEhhbmRsZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5mYWRlSW5QZXJjZW50YWdlcyhhcHBlYXJEdXJhdGlvbkVhY2hfMSk7XG4gICAgICAgICAgICAgICAgaWYgKHByb3BzLmNvbXBhcmVGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5mYWRlSW5Db21wYXJlVGV4dHMoYXBwZWFyRHVyYXRpb25FYWNoXzEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgX3RoaXMuX2FuaW1hdGlvbkFwcGVhclRpbWVvdXRIYW5kbGVyO1xuICAgICAgICAgICAgfSwgYXBwZWFyRHVyYXRpb24pO1xuICAgICAgICAgICAgdGhpcy5mdW5uZWwuYW5pbWF0ZSA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcy5hbmltYXRpb24sIHtcbiAgICAgICAgICAgICAgICBhcHBlYXI6IHtcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBwcm9wcy50cmFuc3Bvc2UgPyAnZnVubmVsU2NhbGVJblgnIDogJ2Z1bm5lbFNjYWxlSW5ZJyxcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IGFwcGVhckR1cmF0aW9uRWFjaF8xLFxuICAgICAgICAgICAgICAgICAgICBkZWxheTogZnVuY3Rpb24gKGRhdHVtKSB7IHJldHVybiB1dGlsXzEuZmluZEluZGV4KGRhdGFfMSwgZnVuY3Rpb24gKG8pIHsgcmV0dXJuIHV0aWxfMS5pc0VxdWFsKG8sIGRhdHVtKTsgfSkgKiBhcHBlYXJEdXJhdGlvbkVhY2hfMTsgfSxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuZmFkZUluTGFiZWxzKHNoYXBlLCAwLjUgKiBhcHBlYXJEdXJhdGlvbkVhY2hfMSk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnRlcjoge1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb246ICdmYWRlLWluJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB0aGlzLnJlc2V0TGFiZWxzKCk7XG4gICAgICAgIHRoaXMucmVzZXRQZXJjZW50YWdlcygpO1xuICAgICAgICBpZiAocHJvcHMuY29tcGFyZUZpZWxkKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0Q29tcGFyZVRleHRzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLnBhZGRpbmcgPT0gJ2F1dG8nKSB7XG4gICAgICAgICAgICB2YXIgcGVyY2VudGFnZUNvbnRhaW5lciA9IHRoaXMuX2ZpbmRQZXJjZW50YWdlQ29udGFpbmVyKCk7XG4gICAgICAgICAgICBpZiAocGVyY2VudGFnZUNvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMucGFkZGluZ0NvbnRyb2xsZXIucmVnaXN0ZXJQYWRkaW5nKHBlcmNlbnRhZ2VDb250YWluZXIsICdpbm5lcicsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNvbXBhcmVUZXh0Q29udGFpbmVyID0gdGhpcy5fZmluZENvbXBhcmVUZXh0Q29udGFpbmVyKCk7XG4gICAgICAgICAgICBpZiAoY29tcGFyZVRleHRDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhZGRpbmdDb250cm9sbGVyLnJlZ2lzdGVyUGFkZGluZyhjb21wYXJlVGV4dENvbnRhaW5lciwgJ2lubmVyJywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAocHJvcHMuYW5pbWF0aW9uID09PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5mYWRlSW5MYWJlbHMoKTtcbiAgICAgICAgICAgIHRoaXMuZmFkZUluUGVyY2VudGFnZXMoKTtcbiAgICAgICAgICAgIGlmIChwcm9wcy5jb21wYXJlRmllbGQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZhZGVJbkNvbXBhcmVUZXh0cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fbGVnZW5kc0xpc3RlbmVyQXR0YWNoZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xlZ2VuZHNMaXN0ZW5lckF0dGFjaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIHZhciBsZWdlbmRDb250YWluZXIgPSB0aGlzLnZpZXcuZ2V0Q29udHJvbGxlcignbGVnZW5kJykuY29udGFpbmVyO1xuICAgICAgICAgICAgbGVnZW5kQ29udGFpbmVyLm9uKCdtb3VzZWRvd24nLCB0aGlzLl9vbkxlZ2VuZENvbnRhaW5lck1vdXNlRG93bik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS51cGRhdGVDb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIGNmZyA9IHRoaXMuYWRqdXN0UHJvcHMoY2ZnKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS51cGRhdGVDb25maWcuY2FsbCh0aGlzLCBjZmcpO1xuICAgICAgICB0aGlzLl9sZWdlbmRzTGlzdGVuZXJBdHRhY2hlZCA9IGZhbHNlO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmNoYW5nZURhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmIChwcm9wcy5hbmltYXRpb24gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zaG91bGRSZXNldFBlcmNlbnRhZ2VzID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9zaG91bGRSZXNldExhYmVscyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy5keW5hbWljSGVpZ2h0KSB7XG4gICAgICAgICAgICB2YXIgY2hlY2tlZERhdGEgPSB0aGlzLl9maW5kQ2hlY2tlZERhdGFJbk5ld0RhdGEoZGF0YSk7XG4gICAgICAgICAgICB0aGlzLl9nZW5DdXN0b21GaWVsZEZvckR5bmFtaWNIZWlnaHQoY2hlY2tlZERhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wcy5jb21wYXJlRmllbGQpIHtcbiAgICAgICAgICAgIGRhdGEgPSB0aGlzLl9yZWR1Y2VEYXRhRm9yQ29tcGFyZShkYXRhKTtcbiAgICAgICAgICAgIHZhciBjaGVja2VkRGF0YSA9IHRoaXMuX2ZpbmRDaGVja2VkRGF0YUluTmV3RGF0YShkYXRhKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZURhdGFGb3JDb21wYXJlKGNoZWNrZWREYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNoYW5nZURhdGEuY2FsbCh0aGlzLCBkYXRhKTtcbiAgICAgICAgdGhpcy5yZWZyZXNoUGVyY2VudGFnZXMoKTtcbiAgICAgICAgdGhpcy5yZWZyZXNoTGFiZWxzKCk7XG4gICAgICAgIGlmIChwcm9wcy5jb21wYXJlRmllbGQpIHtcbiAgICAgICAgICAgIHRoaXMuZmFkZUluQ29tcGFyZVRleHRzKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgaWYgKGRpbSA9PT0gJ2cyJykge1xuICAgICAgICAgICAgcmV0dXJuIEcyX0dFT01fTUFQW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQTE9UX0dFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmFkanVzdFByb3BzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIGlmIChwcm9wcy5jb21wYXJlRmllbGQpIHtcbiAgICAgICAgICAgIHByb3BzLmR5bmFtaWNIZWlnaHQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMuZHluYW1pY0hlaWdodCkge1xuICAgICAgICAgICAgdXRpbF8xLnNldChwcm9wcywgXCJtZXRhLlwiICsgcHJvcHMueUZpZWxkICsgXCIubmljZVwiLCBmYWxzZSk7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KHByb3BzLCAndG9vbHRpcC5zaGFyZWQnLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb3BzO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLnJlc2V0UGVyY2VudGFnZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmICghdGhpcy5fc2hvdWxkUmVzZXRQZXJjZW50YWdlcylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgX2EgPSBwcm9wcy5wZXJjZW50YWdlIHx8IHt9LCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFksIHNwYWNpbmcgPSBfYS5zcGFjaW5nLCBfYiA9IF9hLmxpbmUsIHBlcmNlbnRhZ2VMaW5lID0gX2IgPT09IHZvaWQgMCA/IHt9IDogX2IsIF9jID0gX2EudGV4dCwgcGVyY2VudGFnZVRleHQgPSBfYyA9PT0gdm9pZCAwID8ge30gOiBfYywgX2QgPSBfYS52YWx1ZSwgcGVyY2VudGFnZVZhbHVlID0gX2QgPT09IHZvaWQgMCA/IHt9IDogX2Q7XG4gICAgICAgIHZhciBhZGp1c3RUaW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5fZmluZFBlcmNlbnRhZ2VDb250YWluZXIodHJ1ZSk7XG4gICAgICAgIHRoaXMuX2VhY2hTaGFwZShmdW5jdGlvbiAoc2hhcGUsIGluZGV4LCBkYXR1bUxvd2VyLCBkYXR1bVVwcGVyKSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hID0gc2hhcGUuZ2V0QkJveCgpLCBtaW5YID0gX2EubWluWCwgbWF4WCA9IF9hLm1heFgsIG1heFkgPSBfYS5tYXhZLCBtaW5ZID0gX2EubWluWTtcbiAgICAgICAgICAgICAgICB2YXIgeDEgPSBwcm9wcy50cmFuc3Bvc2UgPyBtaW5YIDogbWF4WDtcbiAgICAgICAgICAgICAgICB2YXIgeTEgPSBwcm9wcy50cmFuc3Bvc2UgPyAocHJvcHMuY29tcGFyZUZpZWxkID8gbWF4WSA6IG1pblkpIDogbWluWTtcbiAgICAgICAgICAgICAgICB2YXIgX2IgPSBfdGhpcy5fZmluZFBlcmNlbnRhZ2VNZW1iZXJzSW5Db250YWluZXJCeUluZGV4KGNvbnRhaW5lciwgaW5kZXgsIHRydWUpLCBsaW5lXzEgPSBfYi5saW5lLCB0ZXh0XzEgPSBfYi50ZXh0LCB2YWx1ZV8xID0gX2IudmFsdWU7XG4gICAgICAgICAgICAgICAgdmFyIGVhY2hQcm9jc18xID0gW1xuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoeCwgeSwgbGluZSwgdGV4dCwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZS5hdHRyKHV0aWxfMS5kZWVwTWl4KHt9LCBwZXJjZW50YWdlTGluZS5zdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4MTogeCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTE6IHksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgyOiBwcm9wcy50cmFuc3Bvc2UgPyB4ICsgb2Zmc2V0WCA6IHggLSBvZmZzZXRYLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MjogcHJvcHMudHJhbnNwb3NlID8geSAtIG9mZnNldFkgOiB5ICsgb2Zmc2V0WSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZS5zZXQoJ2FkanVzdFRpbWVzdGFtcCcsIGFkanVzdFRpbWVzdGFtcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dFdpZHRoID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZVdpZHRoID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0UHJvYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LmF0dHIodXRpbF8xLmRlZXBNaXgoe30sIHBlcmNlbnRhZ2VUZXh0LnN0eWxlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBwcm9wcy50cmFuc3Bvc2UgPyB4ICsgb2Zmc2V0WCA6IHggLSBvZmZzZXRYIC0gc3BhY2luZyAtIHZhbHVlV2lkdGggLSBzcGFjaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogcHJvcHMudHJhbnNwb3NlID8geSAtIG9mZnNldFkgLSBzcGFjaW5nIDogeSArIG9mZnNldFksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogcGVyY2VudGFnZVRleHQuY29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogcHJvcHMudHJhbnNwb3NlID8gJ2xlZnQnIDogJ3JpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogcHJvcHMudHJhbnNwb3NlID8gJ2JvdHRvbScgOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LnNldCgnYWRqdXN0VGltZXN0YW1wJywgYWRqdXN0VGltZXN0YW1wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFdpZHRoID0gdGV4dC5nZXRCQm94KCkud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZVByb2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmF0dHIodXRpbF8xLmRlZXBNaXgoe30sIHBlcmNlbnRhZ2VWYWx1ZS5zdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogcHJvcHMudHJhbnNwb3NlID8geCArIG9mZnNldFggKyB0ZXh0V2lkdGggKyBzcGFjaW5nIDogeCAtIG9mZnNldFggLSBzcGFjaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogcHJvcHMudHJhbnNwb3NlID8geSAtIG9mZnNldFkgLSBzcGFjaW5nIDogeSArIG9mZnNldFksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogdXRpbF8xLmlzRnVuY3Rpb24ocGVyY2VudGFnZVZhbHVlLmZvcm1hdHRlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHByb3BzLmNvbXBhcmVGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHBlcmNlbnRhZ2VWYWx1ZS5mb3JtYXR0ZXIodXRpbF8xLmdldChkYXR1bVVwcGVyLCAnX19jb21wYXJlX18ueVZhbHVlcy4wJyksIHV0aWxfMS5nZXQoZGF0dW1Mb3dlciwgJ19fY29tcGFyZV9fLnlWYWx1ZXMuMCcpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHBlcmNlbnRhZ2VWYWx1ZS5mb3JtYXR0ZXIoZGF0dW1VcHBlcltwcm9wcy55RmllbGRdLCBkYXR1bUxvd2VyW3Byb3BzLnlGaWVsZF0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogcHJvcHMudHJhbnNwb3NlID8gJ2xlZnQnIDogJ3JpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogcHJvcHMudHJhbnNwb3NlID8gJ2JvdHRvbScgOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5zZXQoJ2FkanVzdFRpbWVzdGFtcCcsIGFkanVzdFRpbWVzdGFtcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlV2lkdGggPSB2YWx1ZS5nZXRCQm94KCkud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wcy50cmFuc3Bvc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0UHJvYygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlUHJvYygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVQcm9jKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFByb2MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHgsIHksIGxpbmUsIHRleHQsIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuYXR0cih1dGlsXzEuZGVlcE1peCh7fSwgcGVyY2VudGFnZUxpbmUuc3R5bGUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDE6IHgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkxOiB5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4MjogeCArIG9mZnNldFgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkyOiBwcm9wcy50cmFuc3Bvc2UgPyAocHJvcHMuY29tcGFyZUZpZWxkID8geSArIG9mZnNldFkgOiB5IC0gb2Zmc2V0WSkgOiB5ICsgb2Zmc2V0WSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZS5zZXQoJ2FkanVzdFRpbWVzdGFtcCcsIGFkanVzdFRpbWVzdGFtcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dFdpZHRoID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dC5hdHRyKHV0aWxfMS5kZWVwTWl4KHt9LCBwZXJjZW50YWdlVGV4dC5zdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBwcm9wcy50cmFuc3Bvc2UgPyB4ICsgb2Zmc2V0WCA6IHggKyBvZmZzZXRYICsgc3BhY2luZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogcHJvcHMudHJhbnNwb3NlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHByb3BzLmNvbXBhcmVGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8geSArIG9mZnNldFkgKyBzcGFjaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB5IC0gb2Zmc2V0WSAtIHNwYWNpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogeSArIG9mZnNldFksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IHBlcmNlbnRhZ2VUZXh0LmNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6IHByb3BzLnRyYW5zcG9zZSA/IChwcm9wcy5jb21wYXJlRmllbGQgPyAndG9wJyA6ICdib3R0b20nKSA6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LnNldCgnYWRqdXN0VGltZXN0YW1wJywgYWRqdXN0VGltZXN0YW1wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0V2lkdGggPSB0ZXh0LmdldEJCb3goKS53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmF0dHIodXRpbF8xLmRlZXBNaXgoe30sIHBlcmNlbnRhZ2VWYWx1ZS5zdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBwcm9wcy50cmFuc3Bvc2UgPyB4ICsgb2Zmc2V0WCArIHRleHRXaWR0aCArIHNwYWNpbmcgOiB4ICsgb2Zmc2V0WCArIHNwYWNpbmcgKyB0ZXh0V2lkdGggKyBzcGFjaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBwcm9wcy50cmFuc3Bvc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcHMuY29tcGFyZUZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB5ICsgb2Zmc2V0WSArIHNwYWNpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHkgLSBvZmZzZXRZIC0gc3BhY2luZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB5ICsgb2Zmc2V0WSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogdXRpbF8xLmlzRnVuY3Rpb24ocGVyY2VudGFnZVZhbHVlLmZvcm1hdHRlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcHMuY29tcGFyZUZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBwZXJjZW50YWdlVmFsdWUuZm9ybWF0dGVyKHV0aWxfMS5nZXQoZGF0dW1VcHBlciwgXCJfX2NvbXBhcmVfXy55VmFsdWVzLjFcIiksIHV0aWxfMS5nZXQoZGF0dW1Mb3dlciwgXCJfX2NvbXBhcmVfXy55VmFsdWVzLjFcIikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwZXJjZW50YWdlVmFsdWUuZm9ybWF0dGVyKGRhdHVtVXBwZXJbcHJvcHMueUZpZWxkXSwgZGF0dW1Mb3dlcltwcm9wcy55RmllbGRdKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnbGVmdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogcHJvcHMudHJhbnNwb3NlID8gKHByb3BzLmNvbXBhcmVGaWVsZCA/ICd0b3AnIDogJ2JvdHRvbScpIDogJ21pZGRsZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnNldCgnYWRqdXN0VGltZXN0YW1wJywgYWRqdXN0VGltZXN0YW1wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIGlmIChwcm9wcy5jb21wYXJlRmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9jID0gW21pblgsIG1pblldLCB4MCA9IF9jWzBdLCB5MCA9IF9jWzFdO1xuICAgICAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICAgICBbeDAsIHkwXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFt4MSwgeTFdLFxuICAgICAgICAgICAgICAgICAgICBdLmZvckVhY2goZnVuY3Rpb24gKF9hLCBpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgeCA9IF9hWzBdLCB5ID0gX2FbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWFjaFByb2NzXzFbaV0oeCwgeSwgbGluZV8xICYmIGxpbmVfMVtpXSwgdGV4dF8xICYmIHRleHRfMVtpXSwgdmFsdWVfMSAmJiB2YWx1ZV8xW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlYWNoUHJvY3NfMVsxXSh4MSwgeTEsIGxpbmVfMSwgdGV4dF8xLCB2YWx1ZV8xKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkYXR1bVVwcGVyID0gZGF0dW1Mb3dlcjtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH0pO1xuICAgICAgICBjb250YWluZXIuZ2V0KCdjaGlsZHJlbicpLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGQuZ2V0KCdhZGp1c3RUaW1lc3RhbXAnKSAhPSBhZGp1c3RUaW1lc3RhbXApIHtcbiAgICAgICAgICAgICAgICBjaGlsZC5hdHRyKHsgb3BhY2l0eTogMCB9KTtcbiAgICAgICAgICAgICAgICBjb250YWluZXIuc2V0KGNoaWxkLmdldCgnaWQnKSwgbnVsbCk7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7IHJldHVybiBjaGlsZC5yZW1vdmUoKTsgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmZhZGVJblBlcmNlbnRhZ2VzID0gZnVuY3Rpb24gKGR1cmF0aW9uLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9maW5kUGVyY2VudGFnZUNvbnRhaW5lcigpO1xuICAgICAgICB2YXIgZWFjaFByb2MgPSBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgdmFyIGxhc3RCQm94ID0geyBtaW5YOiBJbmZpbml0eSwgbWF4WDogLUluZmluaXR5LCBtaW5ZOiBJbmZpbml0eSwgbWF4WTogLUluZmluaXR5IH07XG4gICAgICAgICAgICBfdGhpcy5fZWFjaFNoYXBlKGZ1bmN0aW9uIChzaGFwZSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICB2YXIgbWVtYmVycyA9IF90aGlzLl9maW5kUGVyY2VudGFnZU1lbWJlcnNJbkNvbnRhaW5lckJ5SW5kZXgoY29udGFpbmVyLCBpbmRleCk7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJCQm94ID0geyBtaW5YOiBJbmZpbml0eSwgbWF4WDogLUluZmluaXR5LCBtaW5ZOiBJbmZpbml0eSwgbWF4WTogLUluZmluaXR5IH07XG4gICAgICAgICAgICAgICAgdmFyIGVhY2hDYWxjID0gZnVuY3Rpb24gKG1lbWJlcikge1xuICAgICAgICAgICAgICAgICAgICBpZiAobWVtYmVyICYmIG1lbWJlci5nZXQoJ3R5cGUnKSA9PSAndGV4dCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfYSA9IG1lbWJlci5nZXRCQm94KCksIG1pblggPSBfYS5taW5YLCBtYXhYID0gX2EubWF4WCwgbWluWSA9IF9hLm1pblksIG1heFkgPSBfYS5tYXhZO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pblggPCBjdXJyQkJveC5taW5YKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1pblggPSBtaW5YO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1heFggPiBjdXJyQkJveC5tYXhYKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1heFggPSBtYXhYO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pblkgPCBjdXJyQkJveC5taW5ZKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1pblkgPSBtaW5ZO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1heFkgPiBjdXJyQkJveC5tYXhZKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1heFkgPSBtYXhZO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChtZW1iZXJzLCBmdW5jdGlvbiAobWVtYmVyKSB7IHJldHVybiAodXRpbF8xLmlzQXJyYXkobWVtYmVyKSA/IGVhY2hDYWxjKG1lbWJlcltpXSkgOiBlYWNoQ2FsYyhtZW1iZXIpKTsgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGN1cnJCQm94Lm1pblggPiBsYXN0QkJveC5tYXhYIHx8XG4gICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1heFggPCBsYXN0QkJveC5taW5YIHx8XG4gICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1pblkgPiBsYXN0QkJveC5tYXhZIHx8XG4gICAgICAgICAgICAgICAgICAgIGN1cnJCQm94Lm1heFkgPCBsYXN0QkJveC5taW5ZKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlYWNoU2hvd18xID0gZnVuY3Rpb24gKG1lbWJlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1lbWJlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID8gbWVtYmVyLmFuaW1hdGUoYXR0cnMsIGR1cmF0aW9uKSA6IG1lbWJlci5hdHRyKGF0dHJzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gobWVtYmVycywgZnVuY3Rpb24gKG1lbWJlcikgeyByZXR1cm4gKHV0aWxfMS5pc0FycmF5KG1lbWJlcikgPyBlYWNoU2hvd18xKG1lbWJlcltpXSkgOiBlYWNoU2hvd18xKG1lbWJlcikpOyB9KTtcbiAgICAgICAgICAgICAgICAgICAgdXRpbF8xLmFzc2lnbihsYXN0QkJveCwgY3VyckJCb3gpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBwcm9wcy5jb21wYXJlRmllbGQgPyBbMCwgMV0uZm9yRWFjaChlYWNoUHJvYykgOiBlYWNoUHJvYygpO1xuICAgICAgICBkdXJhdGlvbiAmJiBjYWxsYmFjayAmJiBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkdXJhdGlvbik7XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUuZmFkZU91dFBlcmNlbnRhZ2VzID0gZnVuY3Rpb24gKGR1cmF0aW9uLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5fZmluZFBlcmNlbnRhZ2VDb250YWluZXIoKTtcbiAgICAgICAgdGhpcy5fZWFjaFNoYXBlKGZ1bmN0aW9uIChzaGFwZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBtZW1iZXJzID0gX3RoaXMuX2ZpbmRQZXJjZW50YWdlTWVtYmVyc0luQ29udGFpbmVyQnlJbmRleChjb250YWluZXIsIGluZGV4KTtcbiAgICAgICAgICAgIHZhciBlYWNoUHJvYyA9IGZ1bmN0aW9uIChtZW1iZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWVtYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID8gbWVtYmVyLmFuaW1hdGUoYXR0cnMsIGR1cmF0aW9uKSA6IG1lbWJlci5hdHRyKGF0dHJzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobWVtYmVycywgZnVuY3Rpb24gKG1lbWJlcikgeyByZXR1cm4gKHV0aWxfMS5pc0FycmF5KG1lbWJlcikgPyBtZW1iZXIuZm9yRWFjaChlYWNoUHJvYykgOiBlYWNoUHJvYyhtZW1iZXIpKTsgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBkdXJhdGlvbiAmJiBjYWxsYmFjayAmJiBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkdXJhdGlvbik7XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUucmVmcmVzaFBlcmNlbnRhZ2VzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuX2NhbGNSZWZyZXNoRmFkZUR1cmF0aW9ucygpLCBmYWRlT3V0RHVyYXRpb24gPSBfYS5mYWRlT3V0RHVyYXRpb24sIGZhZGVJbkR1cmF0aW9uXzEgPSBfYS5mYWRlSW5EdXJhdGlvbjtcbiAgICAgICAgICAgIHRoaXMuX3Nob3VsZFJlc2V0UGVyY2VudGFnZXMgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZmFkZU91dFBlcmNlbnRhZ2VzKGZhZGVPdXREdXJhdGlvbiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLl9zaG91bGRSZXNldFBlcmNlbnRhZ2VzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfdGhpcy5yZXNldFBlcmNlbnRhZ2VzKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMuZmFkZUluUGVyY2VudGFnZXMoZmFkZUluRHVyYXRpb25fMSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5fZmluZFBlcmNlbnRhZ2VDb250YWluZXIgPSBmdW5jdGlvbiAoY3JlYXRlSWZOb3RGb3VuZCkge1xuICAgICAgICBpZiAoY3JlYXRlSWZOb3RGb3VuZCA9PT0gdm9pZCAwKSB7IGNyZWF0ZUlmTm90Rm91bmQgPSBmYWxzZTsgfVxuICAgICAgICB2YXIgbWlkZGxlR3JvdXAgPSB0aGlzLnZpZXcubWlkZGxlR3JvdXA7XG4gICAgICAgIHZhciBwZXJjZW50YWdlQ29udGFpbmVyID0gbWlkZGxlR3JvdXAuZ2V0KCdwZXJjZW50YWdlQ29udGFpbmVyJyk7XG4gICAgICAgIGlmICghcGVyY2VudGFnZUNvbnRhaW5lciAmJiBjcmVhdGVJZk5vdEZvdW5kKSB7XG4gICAgICAgICAgICBwZXJjZW50YWdlQ29udGFpbmVyID0gbWlkZGxlR3JvdXAuYWRkR3JvdXAoKTtcbiAgICAgICAgICAgIG1pZGRsZUdyb3VwLnNldCgncGVyY2VudGFnZUNvbnRhaW5lcicsIHBlcmNlbnRhZ2VDb250YWluZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwZXJjZW50YWdlQ29udGFpbmVyO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLl9maW5kUGVyY2VudGFnZU1lbWJlcnNJbkNvbnRhaW5lckJ5SW5kZXggPSBmdW5jdGlvbiAoY29udGFpbmVyLCBpbmRleCwgY3JlYXRlSWZOb3RGb3VuZCkge1xuICAgICAgICBpZiAoY3JlYXRlSWZOb3RGb3VuZCA9PT0gdm9pZCAwKSB7IGNyZWF0ZUlmTm90Rm91bmQgPSBmYWxzZTsgfVxuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBfYSA9IHByb3BzLnBlcmNlbnRhZ2UgfHwge30sIHZpc2libGUgPSBfYS52aXNpYmxlLCBfYiA9IF9hLmxpbmUsIHBlcmNlbnRhZ2VMaW5lID0gX2IgPT09IHZvaWQgMCA/IHt9IDogX2IsIF9jID0gX2EudGV4dCwgcGVyY2VudGFnZVRleHQgPSBfYyA9PT0gdm9pZCAwID8ge30gOiBfYywgX2QgPSBfYS52YWx1ZSwgcGVyY2VudGFnZVZhbHVlID0gX2QgPT09IHZvaWQgMCA/IHt9IDogX2Q7XG4gICAgICAgIHZhciBtZW1iZXJzID0ge1xuICAgICAgICAgICAgbGluZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdGV4dDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHZpc2libGUgPT09IGZhbHNlIHx8ICFjb250YWluZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBtZW1iZXJzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwZXJjZW50YWdlTGluZS52aXNpYmxlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdmFyIGZpbmQgPSBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHZhciBsaW5lSWQgPSBcIl9wZXJjZW50YWdlLWxpbmUtXCIgKyBpbmRleCArIFwiLVwiICsgaTtcbiAgICAgICAgICAgICAgICB2YXIgbGluZSA9IGNvbnRhaW5lci5nZXQobGluZUlkKTtcbiAgICAgICAgICAgICAgICBpZiAoIWxpbmUgJiYgY3JlYXRlSWZOb3RGb3VuZCkge1xuICAgICAgICAgICAgICAgICAgICBsaW5lID0gY29udGFpbmVyLmFkZFNoYXBlKHsgaWQ6IGxpbmVJZCwgdHlwZTogJ2xpbmUnLCBhdHRyczoge30gfSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci5zZXQobGluZUlkLCBsaW5lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxpbmU7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIGxpbmUgPSBwcm9wcy5jb21wYXJlRmllbGQgPyBbMCwgMV0ubWFwKGZpbmQpIDogZmluZCgwKTtcbiAgICAgICAgICAgIG1lbWJlcnMubGluZSA9IGxpbmU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBlcmNlbnRhZ2VUZXh0LnZpc2libGUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB2YXIgZmluZCA9IGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRleHRJZCA9IFwiX3BlcmNlbnRhZ2UtdGV4dC1cIiArIGluZGV4ICsgXCItXCIgKyBpO1xuICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0gY29udGFpbmVyLmdldCh0ZXh0SWQpO1xuICAgICAgICAgICAgICAgIGlmICghdGV4dCAmJiBjcmVhdGVJZk5vdEZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQgPSBjb250YWluZXIuYWRkU2hhcGUoeyBpZDogdGV4dElkLCB0eXBlOiAndGV4dCcsIGF0dHJzOiB7fSB9KTtcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnNldCh0ZXh0SWQsIHRleHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB2YXIgdGV4dCA9IHByb3BzLmNvbXBhcmVGaWVsZCA/IFswLCAxXS5tYXAoZmluZCkgOiBmaW5kKDApO1xuICAgICAgICAgICAgbWVtYmVycy50ZXh0ID0gdGV4dDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGVyY2VudGFnZVZhbHVlLnZpc2libGUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB2YXIgZmluZCA9IGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlSWQgPSBcIl9wZXJjZW50YWdlLXZhbHVlLVwiICsgaW5kZXggKyBcIi1cIiArIGk7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gY29udGFpbmVyLmdldCh2YWx1ZUlkKTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlICYmIGNyZWF0ZUlmTm90Rm91bmQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBjb250YWluZXIuYWRkU2hhcGUoeyBpZDogdmFsdWVJZCwgdHlwZTogJ3RleHQnLCBhdHRyczoge30gfSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci5zZXQodmFsdWVJZCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gcHJvcHMuY29tcGFyZUZpZWxkID8gWzAsIDFdLm1hcChmaW5kKSA6IGZpbmQoMCk7XG4gICAgICAgICAgICBtZW1iZXJzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbWJlcnM7XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUuX2NhbGNSZWZyZXNoRmFkZUR1cmF0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgdXBkYXRlRHVyYXRpb24gPSB1dGlsXzEuZ2V0KHByb3BzLCAnYW5pbWF0aW9uLnVwZGF0ZS5kdXJhdGlvbicpO1xuICAgICAgICB2YXIgZW50ZXJEdXJhdGlvbiA9IHV0aWxfMS5nZXQocHJvcHMsICdhbmltYXRpb24uZW50ZXIuZHVyYXRpb24nKTtcbiAgICAgICAgdmFyIGZhZGVJbkR1cmF0aW9uID0gTWF0aC5taW4oZW50ZXJEdXJhdGlvbiwgdXBkYXRlRHVyYXRpb24pICogMC42O1xuICAgICAgICB2YXIgZmFkZU91dER1cmF0aW9uID0gTWF0aC5tYXgoZW50ZXJEdXJhdGlvbiwgdXBkYXRlRHVyYXRpb24pICogMS4yO1xuICAgICAgICByZXR1cm4geyBmYWRlSW5EdXJhdGlvbjogZmFkZUluRHVyYXRpb24sIGZhZGVPdXREdXJhdGlvbjogZmFkZU91dER1cmF0aW9uIH07XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUucmVzZXRMYWJlbHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmICghdGhpcy5fc2hvdWxkUmVzZXRMYWJlbHMpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHhGaWVsZCA9IHByb3BzLnhGaWVsZCwgeUZpZWxkID0gcHJvcHMueUZpZWxkO1xuICAgICAgICB2YXIgYWRqdXN0VGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdmFyIGxhYmVsc0NvbnRhaW5lciA9IHRoaXMuX2dldEdlb21ldHJ5KCkubGFiZWxzQ29udGFpbmVyO1xuICAgICAgICB2YXIgbGFiZWxQcm9wcyA9IHByb3BzLmxhYmVsIHx8IHt9O1xuICAgICAgICB2YXIgbGFiZWxTdHlsZSA9IHV0aWxfMS5kZWVwTWl4KHRzbGliXzEuX19hc3NpZ24oe30sIHRoaXMudGhlbWUubGFiZWwpLCBwcm9wcy5sYWJlbC5zdHlsZSwge1xuICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGRhdHVtVG9wO1xuICAgICAgICB0aGlzLl9lYWNoU2hhcGUoZnVuY3Rpb24gKHNoYXBlLCBpbmRleCwgZGF0dW0sIGVsZW1lbnRJbmRleCkge1xuICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBzaGFwZS5nZXQoJ2VsZW1lbnQnKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA9PSAwKSB7XG4gICAgICAgICAgICAgICAgZGF0dW1Ub3AgPSBkYXR1bTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBfYiA9IHNoYXBlLmdldEJCb3goKSwgbWluWCA9IF9iLm1pblgsIG1heFggPSBfYi5tYXhYLCBtaW5ZID0gX2IubWluWSwgbWF4WSA9IF9iLm1heFk7XG4gICAgICAgICAgICB2YXIgeFZhbHVlID0gZGF0dW1beEZpZWxkXTtcbiAgICAgICAgICAgIHZhciB5VmFsdWUgPSBkYXR1bVt5RmllbGRdO1xuICAgICAgICAgICAgaWYgKGxhYmVsUHJvcHMuYWRqdXN0Q29sb3IpIHtcbiAgICAgICAgICAgICAgICBsYWJlbFN0eWxlLmZpbGwgPSBfdGhpcy5fZ2V0QWRqdXN0ZWRUZXh0RmlsbEJ5U2hhcGUoc2hhcGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNvbXBhcmUgPSBkYXR1bS5fX2NvbXBhcmVfXztcbiAgICAgICAgICAgIHZhciBjb250ZW50O1xuICAgICAgICAgICAgdmFyIGZvcm1hdEFyZ3MgPSAoX2EgPSB7fSxcbiAgICAgICAgICAgICAgICBfYVtkZXBlbmRlbnRzXzEuX09SSUdJTl0gPSBkYXR1bSxcbiAgICAgICAgICAgICAgICBfYS5lbGVtZW50ID0gZWxlbWVudCxcbiAgICAgICAgICAgICAgICBfYS5lbGVtZW50SW5kZXggPSBlbGVtZW50SW5kZXgsXG4gICAgICAgICAgICAgICAgX2EubWFwcGluZ0RhdHVtID0gW10uY29uY2F0KGVsZW1lbnQuZ2V0TW9kZWwoKS5tYXBwaW5nRGF0YSlbMF0sXG4gICAgICAgICAgICAgICAgX2EubWFwcGluZ0RhdHVtSW5kZXggPSAwLFxuICAgICAgICAgICAgICAgIF9hKTtcbiAgICAgICAgICAgIGlmIChsYWJlbFByb3BzLmZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBsYWJlbFByb3BzLmZvcm1hdHRlcih4VmFsdWUsIGZvcm1hdEFyZ3MsIGluZGV4LCB5VmFsdWUsIGRhdHVtVG9wW3lGaWVsZF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBhcmUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IFswLCAxXS5tYXAoZnVuY3Rpb24gKCkgeyByZXR1cm4gXCJcIiArIHlWYWx1ZTsgfSkuam9pbihwcm9wcy50cmFuc3Bvc2UgPyAnXFxuXFxuJyA6ICcgICAgJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0geFZhbHVlICsgXCIgXCIgKyB5VmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGxhYmVsID0gX3RoaXMuX2ZpbmRMYWJlbEluQ29udGFpbmVyQnlJbmRleChsYWJlbHNDb250YWluZXIsIGluZGV4LCB0cnVlKTtcbiAgICAgICAgICAgIHZhciByYXRpbyA9IGNvbXBhcmUgPyBjb21wYXJlLnlWYWx1ZXNbMF0gLyAoY29tcGFyZS55VmFsdWVzWzBdICsgY29tcGFyZS55VmFsdWVzWzFdKSA6IDAuNTtcbiAgICAgICAgICAgIGlmIChsYWJlbCkge1xuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIodHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBsYWJlbFN0eWxlKSwgeyB4OiBsZXJwKG1pblgsIG1heFgsICFwcm9wcy50cmFuc3Bvc2UgPyByYXRpbyA6IDAuNSksIHk6IGxlcnAobWluWSwgbWF4WSwgcHJvcHMudHJhbnNwb3NlID8gcmF0aW8gOiAwLjUpLCB0ZXh0OiBjb250ZW50IH0pKTtcbiAgICAgICAgICAgICAgICBsYWJlbC5zZXQoJ2FkanVzdFRpbWVzdGFtcCcsIGFkanVzdFRpbWVzdGFtcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBsYWJlbHNDb250YWluZXIuZ2V0KCdjaGlsZHJlbicpLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICBpZiAobGFiZWwuZ2V0KCdhZGp1c3RUaW1lc3RhbXAnKSAhPSBhZGp1c3RUaW1lc3RhbXApIHtcbiAgICAgICAgICAgICAgICBsYWJlbC5hdHRyKHsgb3BhY2l0eTogMCB9KTtcbiAgICAgICAgICAgICAgICBsYWJlbHNDb250YWluZXIuc2V0KGxhYmVsLmdldCgnaWQnKSwgbnVsbCk7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7IHJldHVybiBsYWJlbC5yZW1vdmUoKTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmZhZGVJbkxhYmVscyA9IGZ1bmN0aW9uICh0YXJnZXRTaGFwZSwgZHVyYXRpb24sIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBsYWJlbHNDb250YWluZXIgPSB0aGlzLl9nZXRHZW9tZXRyeSgpLmxhYmVsc0NvbnRhaW5lcjtcbiAgICAgICAgdGhpcy5fZWFjaFNoYXBlKGZ1bmN0aW9uIChzaGFwZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmICghdGFyZ2V0U2hhcGUgfHwgdGFyZ2V0U2hhcGUgPT0gc2hhcGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBfdGhpcy5fZmluZExhYmVsSW5Db250YWluZXJCeUluZGV4KGxhYmVsc0NvbnRhaW5lciwgaW5kZXgpO1xuICAgICAgICAgICAgICAgIGlmIChsYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc2hhcGVCQm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxCQm94ID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobGFiZWxCQm94Lm1pblggPj0gc2hhcGVCQm94Lm1pblggJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsQkJveC5tYXhYIDw9IHNoYXBlQkJveC5tYXhYICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbEJCb3gubWluWSA+PSBzaGFwZUJCb3gubWluWSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxCQm94Lm1heFkgPD0gc2hhcGVCQm94Lm1heFkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID8gbGFiZWwuYW5pbWF0ZShhdHRycywgZHVyYXRpb24pIDogbGFiZWwuYXR0cihhdHRycyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkdXJhdGlvbiAmJiBjYWxsYmFjayAmJiBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkdXJhdGlvbik7XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUuZmFkZU91dExhYmVscyA9IGZ1bmN0aW9uICh0YXJnZXRTaGFwZSwgZHVyYXRpb24sIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBsYWJlbHNDb250YWluZXIgPSB0aGlzLl9nZXRHZW9tZXRyeSgpLmxhYmVsc0NvbnRhaW5lcjtcbiAgICAgICAgdGhpcy5fZWFjaFNoYXBlKGZ1bmN0aW9uIChzaGFwZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmICghdGFyZ2V0U2hhcGUgfHwgdGFyZ2V0U2hhcGUgPT0gc2hhcGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBfdGhpcy5fZmluZExhYmVsSW5Db250YWluZXJCeUluZGV4KGxhYmVsc0NvbnRhaW5lciwgaW5kZXgpO1xuICAgICAgICAgICAgICAgIGlmIChsYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA/IGxhYmVsLmFuaW1hdGUoYXR0cnMsIGR1cmF0aW9uKSA6IGxhYmVsLmF0dHIoYXR0cnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGR1cmF0aW9uICYmIGNhbGxiYWNrICYmIHNldFRpbWVvdXQoY2FsbGJhY2ssIGR1cmF0aW9uKTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5yZWZyZXNoTGFiZWxzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuX2NhbGNSZWZyZXNoRmFkZUR1cmF0aW9ucygpLCBmYWRlT3V0RHVyYXRpb24gPSBfYS5mYWRlT3V0RHVyYXRpb24sIGZhZGVJbkR1cmF0aW9uXzIgPSBfYS5mYWRlSW5EdXJhdGlvbjtcbiAgICAgICAgICAgIHRoaXMuX3Nob3VsZFJlc2V0TGFiZWxzID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmZhZGVPdXRMYWJlbHMobnVsbCwgZmFkZU91dER1cmF0aW9uLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX3Nob3VsZFJlc2V0TGFiZWxzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfdGhpcy5yZXNldExhYmVscygpO1xuICAgICAgICAgICAgICAgIF90aGlzLmZhZGVJbkxhYmVscyhudWxsLCBmYWRlSW5EdXJhdGlvbl8yLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLl9maW5kTGFiZWxJbkNvbnRhaW5lckJ5SW5kZXggPSBmdW5jdGlvbiAoY29udGFpbmVyLCBpbmRleCwgY3JlYXRlSWZOb3RGb3VuZCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGlmIChjcmVhdGVJZk5vdEZvdW5kID09PSB2b2lkIDApIHsgY3JlYXRlSWZOb3RGb3VuZCA9IGZhbHNlOyB9XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGxhYmVsO1xuICAgICAgICBpZiAoKChfYSA9IHByb3BzLmxhYmVsKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EudmlzaWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gbGFiZWw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGxhYmVsSWQgPSBcIl9sYWJlbC1cIiArIGluZGV4O1xuICAgICAgICBsYWJlbCA9IGNvbnRhaW5lci5nZXQobGFiZWxJZCk7XG4gICAgICAgIGlmICghbGFiZWwgJiYgY3JlYXRlSWZOb3RGb3VuZCkge1xuICAgICAgICAgICAgbGFiZWwgPSBjb250YWluZXIuYWRkU2hhcGUoe1xuICAgICAgICAgICAgICAgIGlkOiBsYWJlbElkLFxuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICBhdHRyczoge30sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5zZXQobGFiZWxJZCwgbGFiZWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYWJlbDtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5yZXNldENvbXBhcmVUZXh0cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9zaG91bGRSZXNldENvbXBhcmVUZXh0cylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgc2hhcGVQYXJlbnRCQm94O1xuICAgICAgICB2YXIgY29tcGFyZTtcbiAgICAgICAgdGhpcy5fZWFjaFNoYXBlKGZ1bmN0aW9uIChzaGFwZSwgaW5kZXgsIGRhdHVtKSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkge1xuICAgICAgICAgICAgICAgIHNoYXBlUGFyZW50QkJveCA9IHNoYXBlLmdldCgncGFyZW50JykuZ2V0QkJveCgpO1xuICAgICAgICAgICAgICAgIGNvbXBhcmUgPSB1dGlsXzEuZ2V0KGRhdHVtLCAnX19jb21wYXJlX18nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChzaGFwZVBhcmVudEJCb3ggJiYgY29tcGFyZSAmJiB1dGlsXzEuZ2V0KHByb3BzLCAnY29tcGFyZVRleHQudmlzaWJsZScpICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lcl8xID0gdGhpcy5fZmluZENvbXBhcmVUZXh0Q29udGFpbmVyKHRydWUpO1xuICAgICAgICAgICAgdmFyIHlWYWx1ZXNNYXhfMSA9IGNvbXBhcmUueVZhbHVlc01heCwgY29tcGFyZVZhbHVlc18xID0gY29tcGFyZS5jb21wYXJlVmFsdWVzO1xuICAgICAgICAgICAgdmFyIG1pblhfMSA9IHNoYXBlUGFyZW50QkJveC5taW5YLCBtYXhYXzEgPSBzaGFwZVBhcmVudEJCb3gubWF4WCwgbWluWV8xID0gc2hhcGVQYXJlbnRCQm94Lm1pblksIG1heFlfMSA9IHNoYXBlUGFyZW50QkJveC5tYXhZO1xuICAgICAgICAgICAgdmFyIGNvbXBhcmVUZXh0c18xID0gY29udGFpbmVyXzEuZ2V0KCdjaGlsZHJlbicpO1xuICAgICAgICAgICAgWzAsIDFdLmZvckVhY2goZnVuY3Rpb24gKGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgY29tcGFyZVRleHQgPSBjb21wYXJlVGV4dHNfMVtpXTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbXBhcmVUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBhcmVUZXh0ID0gY29udGFpbmVyXzEuYWRkU2hhcGUoeyB0eXBlOiAndGV4dCcgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbXBhcmVUZXh0LmF0dHIodXRpbF8xLmRlZXBNaXgoe30sIHV0aWxfMS5nZXQocHJvcHMsICdjb21wYXJlVGV4dC5zdHlsZScpLCB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IHByb3BzLnRyYW5zcG9zZSA/IGNvbXBhcmVWYWx1ZXNfMVtpXSA6IGkgPyBcIiAgXCIgKyBjb21wYXJlVmFsdWVzXzFbaV0gOiBjb21wYXJlVmFsdWVzXzFbaV0gKyBcIiAgXCIsXG4gICAgICAgICAgICAgICAgICAgIHg6IHByb3BzLnRyYW5zcG9zZVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBtaW5YXzEgKyB1dGlsXzEuZ2V0KHByb3BzLCAnY29tcGFyZVRleHQub2Zmc2V0WCcpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGxlcnAobWluWF8xLCBtYXhYXzEsIHlWYWx1ZXNNYXhfMVswXSAvICh5VmFsdWVzTWF4XzFbMF0gKyB5VmFsdWVzTWF4XzFbMV0pKSxcbiAgICAgICAgICAgICAgICAgICAgeTogcHJvcHMudHJhbnNwb3NlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGxlcnAobWluWV8xLCBtYXhZXzEsIHlWYWx1ZXNNYXhfMVswXSAvICh5VmFsdWVzTWF4XzFbMF0gKyB5VmFsdWVzTWF4XzFbMV0pKSArIChpID8gOCA6IC04KVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBtaW5ZXzEgKyB1dGlsXzEuZ2V0KHByb3BzLCAnY29tcGFyZVRleHQub2Zmc2V0WScpLFxuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246IHByb3BzLnRyYW5zcG9zZSA/ICdyaWdodCcgOiBpID8gJ2xlZnQnIDogJ3JpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiBwcm9wcy50cmFuc3Bvc2UgPyAoaSA/ICd0b3AnIDogJ2JvdHRvbScpIDogJ2JvdHRvbScsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5mYWRlSW5Db21wYXJlVGV4dHMgPSBmdW5jdGlvbiAoZHVyYXRpb24sIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9maW5kQ29tcGFyZVRleHRDb250YWluZXIoKTtcbiAgICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICAgICAgdmFyIGNvbXBhcmVUZXh0c18yID0gY29udGFpbmVyLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIFswLCAxXS5mb3JFYWNoKGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbXBhcmVUZXh0ID0gY29tcGFyZVRleHRzXzJbaV07XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID8gY29tcGFyZVRleHQuYW5pbWF0ZShhdHRycywgZHVyYXRpb24pIDogY29tcGFyZVRleHQuYXR0cihhdHRycyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZHVyYXRpb24gJiYgY2FsbGJhY2sgJiYgc2V0VGltZW91dChjYWxsYmFjaywgZHVyYXRpb24pO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLmZhZGVPdXRDb21wYXJlVGV4dHMgPSBmdW5jdGlvbiAoZHVyYXRpb24sIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9maW5kQ29tcGFyZVRleHRDb250YWluZXIoKTtcbiAgICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICAgICAgdmFyIGNvbXBhcmVUZXh0c18zID0gY29udGFpbmVyLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIFswLCAxXS5mb3JFYWNoKGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbXBhcmVUZXh0ID0gY29tcGFyZVRleHRzXzNbaV07XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID8gY29tcGFyZVRleHQuYW5pbWF0ZShhdHRycywgZHVyYXRpb24pIDogY29tcGFyZVRleHQuYXR0cihhdHRycyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZHVyYXRpb24gJiYgY2FsbGJhY2sgJiYgc2V0VGltZW91dChjYWxsYmFjaywgZHVyYXRpb24pO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLnJlZnJlc2hDb21wYXJlVGV4dHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAocHJvcHMuYW5pbWF0aW9uICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdmFyIF9hID0gdGhpcy5fY2FsY1JlZnJlc2hGYWRlRHVyYXRpb25zKCksIGZhZGVJbkR1cmF0aW9uXzMgPSBfYS5mYWRlSW5EdXJhdGlvbiwgZmFkZU91dER1cmF0aW9uID0gX2EuZmFkZU91dER1cmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5fc2hvdWxkUmVzZXRDb21wYXJlVGV4dHMgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZmFkZU91dENvbXBhcmVUZXh0cyhmYWRlT3V0RHVyYXRpb24sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5fc2hvdWxkUmVzZXRDb21wYXJlVGV4dHMgPSB0cnVlO1xuICAgICAgICAgICAgICAgIF90aGlzLnJlc2V0Q29tcGFyZVRleHRzKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMuZmFkZUluQ29tcGFyZVRleHRzKGZhZGVJbkR1cmF0aW9uXzMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBGdW5uZWxMYXllci5wcm90b3R5cGUuX2ZpbmRDb21wYXJlVGV4dENvbnRhaW5lciA9IGZ1bmN0aW9uIChjcmVhdGVJZk5vdEZvdW5kKSB7XG4gICAgICAgIGlmIChjcmVhdGVJZk5vdEZvdW5kID09PSB2b2lkIDApIHsgY3JlYXRlSWZOb3RGb3VuZCA9IGZhbHNlOyB9XG4gICAgICAgIHZhciBtaWRkbGVHcm91cCA9IHRoaXMudmlldy5taWRkbGVHcm91cDtcbiAgICAgICAgdmFyIGNvbXBhcmVUZXh0Q29udGFpbmVyID0gbWlkZGxlR3JvdXAuZ2V0KCdjb21wYXJlVGV4dENvbnRhaW5lcicpO1xuICAgICAgICBpZiAoIWNvbXBhcmVUZXh0Q29udGFpbmVyICYmIGNyZWF0ZUlmTm90Rm91bmQpIHtcbiAgICAgICAgICAgIGNvbXBhcmVUZXh0Q29udGFpbmVyID0gbWlkZGxlR3JvdXAuYWRkR3JvdXAoKTtcbiAgICAgICAgICAgIG1pZGRsZUdyb3VwLnNldCgnY29tcGFyZVRleHRDb250YWluZXInLCBjb21wYXJlVGV4dENvbnRhaW5lcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbXBhcmVUZXh0Q29udGFpbmVyO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLl9lYWNoU2hhcGUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2ZpbmRDaGVja2VkRGF0YSh0aGlzLmdldERhdGEoKSk7XG4gICAgICAgIHZhciBkYXRhTGVuID0gZGF0YS5sZW5ndGg7XG4gICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgIHZhciBkYXR1bVVwcGVyO1xuICAgICAgICAoX2EgPSB0aGlzLl9nZXRHZW9tZXRyeSgpKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCwgZWxlbWVudEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc2hhcGUgPSBlbGVtZW50LnNoYXBlO1xuICAgICAgICAgICAgdmFyIGRhdHVtTG93ZXIgPSBkYXRhW2luZGV4XTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8IGRhdGFMZW4pIHtcbiAgICAgICAgICAgICAgICBmbihzaGFwZSwgaW5kZXgsIGRhdHVtTG93ZXIsIGRhdHVtVXBwZXIsIGVsZW1lbnRJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkYXR1bVVwcGVyID0gZGF0dW1Mb3dlcjtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLl9nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZW9tZXRyaWVzWzBdO1xuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLl9nZXRBZGp1c3RlZFRleHRGaWxsQnlTaGFwZSA9IGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICB2YXIgc2hhcGVDb2xvciA9IHNoYXBlLmF0dHIoJ2ZpbGwnKTtcbiAgICAgICAgdmFyIHNoYXBlT3BhY2l0eSA9IHNoYXBlLmF0dHIoJ29wYWNpdHknKSA/IHNoYXBlLmF0dHIoJ29wYWNpdHknKSA6IDE7XG4gICAgICAgIHZhciByZ2IgPSBjb2xvcl8xLnJnYjJhcnIoc2hhcGVDb2xvcik7XG4gICAgICAgIHZhciBncmF5ID0gTWF0aC5yb3VuZChyZ2JbMF0gKiAwLjI5OSArIHJnYlsxXSAqIDAuNTg3ICsgcmdiWzJdICogMC4xMTQpIC8gc2hhcGVPcGFjaXR5O1xuICAgICAgICB2YXIgY29sb3JCYW5kID0gW1xuICAgICAgICAgICAgeyBmcm9tOiAwLCB0bzogODUsIGNvbG9yOiAnd2hpdGUnIH0sXG4gICAgICAgICAgICB7IGZyb206IDg1LCB0bzogMTcwLCBjb2xvcjogJyNGNkY2RjYnIH0sXG4gICAgICAgICAgICB7IGZyb206IDE3MCwgdG86IDI1NSwgY29sb3I6ICdibGFjaycgfSxcbiAgICAgICAgXTtcbiAgICAgICAgdmFyIHJlZmxlY3QgPSBjb2xvcl8xLm1hcHBpbmdDb2xvcihjb2xvckJhbmQsIGdyYXkpO1xuICAgICAgICByZXR1cm4gcmVmbGVjdDtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5fZ2VuQ3VzdG9tRmllbGRGb3JEeW5hbWljSGVpZ2h0ID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgdG90YWwgPSBkYXRhLnJlZHVjZShmdW5jdGlvbiAodG90YWwsIGRhdHVtKSB7IHJldHVybiB0b3RhbCArIGRhdHVtW3Byb3BzLnlGaWVsZF07IH0sIDApO1xuICAgICAgICB2YXIgcmF0aW9VcHBlciA9IDE7XG4gICAgICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0dW0sIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBkYXR1bVtwcm9wcy55RmllbGRdO1xuICAgICAgICAgICAgdmFyIHNoYXJlID0gdmFsdWUgLyB0b3RhbDtcbiAgICAgICAgICAgIHZhciByYXRpb0xvd2VyID0gcmF0aW9VcHBlciAtIHNoYXJlO1xuICAgICAgICAgICAgZGF0dW1bJ19fY3VzdG9tX18nXSA9IHtcbiAgICAgICAgICAgICAgICBkYXR1bUluZGV4OiBpbmRleCxcbiAgICAgICAgICAgICAgICBkYXRhTGVuZ3RoOiBkYXRhLmxlbmd0aCxcbiAgICAgICAgICAgICAgICByYXRpb1VwcGVyOiByYXRpb1VwcGVyLFxuICAgICAgICAgICAgICAgIHJhdGlvTG93ZXI6IHJhdGlvTG93ZXIsXG4gICAgICAgICAgICAgICAgcmV2ZXJzZTogcHJvcHMudHJhbnNwb3NlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJhdGlvVXBwZXIgPSByYXRpb0xvd2VyO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5fZmluZENoZWNrZWREYXRhQnlNb3VzZURvd25MZWdlbmRJdGVtID0gZnVuY3Rpb24gKGxlZ2VuZEl0ZW0pIHtcbiAgICAgICAgdmFyIGZsYWdzID0gbGVnZW5kSXRlbVxuICAgICAgICAgICAgLmdldCgncGFyZW50JylcbiAgICAgICAgICAgIC5nZXQoJ2NoaWxkcmVuJylcbiAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKGxlZ2VuZEl0ZW0pIHsgcmV0dXJuICFsZWdlbmRJdGVtLmdldCgndW5jaGVja2VkJyk7IH0pO1xuICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZ2V0RGF0YSgpLmZpbHRlcihmdW5jdGlvbiAoZGF0dW0sIGluZGV4KSB7IHJldHVybiBmbGFnc1tpbmRleF07IH0pO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5fZmluZENoZWNrZWREYXRhSW5OZXdEYXRhID0gZnVuY3Rpb24gKG5ld0RhdGEpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHZhciBsZWdlbmRDb250YWluZXIgPSB0aGlzLnZpZXcuZ2V0Q29udHJvbGxlcignbGVnZW5kJykuY29udGFpbmVyO1xuICAgICAgICB2YXIgdW5jaGVja2VkWFZhbHVlcyA9IGxlZ2VuZENvbnRhaW5lclxuICAgICAgICAgICAgLmZpbmRBbGwoZnVuY3Rpb24gKHNoYXBlKSB7IHJldHVybiBzaGFwZS5nZXQoJ25hbWUnKSA9PSAnbGVnZW5kLWl0ZW0nOyB9KVxuICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobGVnZW5kSXRlbSkgeyByZXR1cm4gbGVnZW5kSXRlbS5nZXQoJ3VuY2hlY2tlZCcpOyB9KVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGVnZW5kSXRlbSkgeyByZXR1cm4gbGVnZW5kSXRlbS5nZXQoJ2lkJykucmVwbGFjZSgnLWxlZ2VuZC1pdGVtLScsICcnKTsgfSk7XG4gICAgICAgIHZhciBjaGVja2VkRGF0YSA9IG5ld0RhdGEuZmlsdGVyKGZ1bmN0aW9uIChkYXR1bSkgeyByZXR1cm4gIXV0aWxfMS5jb250YWlucyh1bmNoZWNrZWRYVmFsdWVzLCBkYXR1bVtwcm9wcy54RmllbGRdKTsgfSk7XG4gICAgICAgIHJldHVybiBjaGVja2VkRGF0YTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5fZmluZENoZWNrZWREYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmICgoX2EgPSBwcm9wcy5sZWdlbmQpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS52aXNpYmxlKSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB2YXIgbGVnZW5kQ29udGFpbmVyID0gdGhpcy52aWV3LmdldENvbnRyb2xsZXIoJ2xlZ2VuZCcpLmNvbnRhaW5lcjtcbiAgICAgICAgICAgIHZhciBjaGVja2VkWFZhbHVlc18xID0gbGVnZW5kQ29udGFpbmVyXG4gICAgICAgICAgICAgICAgLmZpbmRBbGwoZnVuY3Rpb24gKHNoYXBlKSB7IHJldHVybiBzaGFwZS5nZXQoJ25hbWUnKSA9PSAnbGVnZW5kLWl0ZW0nOyB9KVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGxlZ2VuZEl0ZW0pIHsgcmV0dXJuICFsZWdlbmRJdGVtLmdldCgndW5jaGVja2VkJyk7IH0pXG4gICAgICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGVnZW5kSXRlbSkgeyByZXR1cm4gbGVnZW5kSXRlbS5nZXQoJ2lkJykucmVwbGFjZSgnLWxlZ2VuZC1pdGVtLScsICcnKTsgfSk7XG4gICAgICAgICAgICB2YXIgY2hlY2tlZERhdGEgPSBkYXRhLmZpbHRlcihmdW5jdGlvbiAoZGF0dW0pIHsgcmV0dXJuIHV0aWxfMS5jb250YWlucyhjaGVja2VkWFZhbHVlc18xLCBkYXR1bVtwcm9wcy54RmllbGRdKTsgfSk7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2tlZERhdGE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzRGF0YShwcm9wcy5kYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRnVubmVsTGF5ZXIucHJvdG90eXBlLl9yZWR1Y2VEYXRhRm9yQ29tcGFyZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGNvbXBhcmVWYWx1ZUZpcnN0VmlzaXRlZDtcbiAgICAgICAgdmFyIHlWYWx1ZXNNYXggPSBbLUluZmluaXR5LCAtSW5maW5pdHldO1xuICAgICAgICBkYXRhID0gZGF0YS5yZWR1Y2UoZnVuY3Rpb24gKG5ld0RhdGEsIGRhdHVtKSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICB2YXIgeFZhbHVlID0gZGF0dW1bcHJvcHMueEZpZWxkXTtcbiAgICAgICAgICAgIHZhciB5VmFsdWUgPSBkYXR1bVtwcm9wcy55RmllbGRdO1xuICAgICAgICAgICAgdmFyIGNvbXBhcmVWYWx1ZSA9IGRhdHVtW3Byb3BzLmNvbXBhcmVGaWVsZF07XG4gICAgICAgICAgICBpZiAoIWNvbXBhcmVWYWx1ZUZpcnN0VmlzaXRlZClcbiAgICAgICAgICAgICAgICBjb21wYXJlVmFsdWVGaXJzdFZpc2l0ZWQgPSBjb21wYXJlVmFsdWU7XG4gICAgICAgICAgICB2YXIgbmV3RGF0dW0gPSBuZXdEYXRhLmZpbmQoZnVuY3Rpb24gKG5ld0RhdHVtKSB7IHJldHVybiBuZXdEYXR1bVtwcm9wcy54RmllbGRdID09IHhWYWx1ZTsgfSk7XG4gICAgICAgICAgICBpZiAoIW5ld0RhdHVtKSB7XG4gICAgICAgICAgICAgICAgbmV3RGF0dW0gPSAoX2EgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgX2FbcHJvcHMueEZpZWxkXSA9IHhWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgX2FbcHJvcHMueUZpZWxkXSA9IDAsXG4gICAgICAgICAgICAgICAgICAgIF9hWydfX2NvbXBhcmVfXyddID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGFyZVZhbHVlczogW10sXG4gICAgICAgICAgICAgICAgICAgICAgICB5VmFsdWVzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHlWYWx1ZXNNYXg6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgeVZhbHVlc05leHQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9zZTogcHJvcHMudHJhbnNwb3NlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBfYSk7XG4gICAgICAgICAgICAgICAgbmV3RGF0YS5wdXNoKG5ld0RhdHVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpZHggPSBjb21wYXJlVmFsdWUgPT0gY29tcGFyZVZhbHVlRmlyc3RWaXNpdGVkID8gMCA6IDE7XG4gICAgICAgICAgICBuZXdEYXR1bVsnX19jb21wYXJlX18nXS55VmFsdWVzW2lkeF0gPSB5VmFsdWU7XG4gICAgICAgICAgICBpZiAoeVZhbHVlc01heFtpZHhdIDwgeVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgeVZhbHVlc01heFtpZHhdID0geVZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3RGF0dW1bJ19fY29tcGFyZV9fJ10uY29tcGFyZVZhbHVlc1tpZHhdID0gY29tcGFyZVZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgICAgIH0sIFtdKTtcbiAgICAgICAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChkYXR1bSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGRhdHVtW3Byb3BzLnlGaWVsZF0gPSB1dGlsXzEuZ2V0KGRhdHVtLCAnX19jb21wYXJlX18ueVZhbHVlcycsIFtdKS5yZWR1Y2UoZnVuY3Rpb24gKHlUb3RhbCwgeVZhbHVlKSB7IHJldHVybiAoeVRvdGFsICs9IHlWYWx1ZSk7IH0sIDApO1xuICAgICAgICAgICAgdXRpbF8xLnNldChkYXR1bSwgJ19fY29tcGFyZV9fLnlWYWx1ZXNNYXgnLCB5VmFsdWVzTWF4KTtcbiAgICAgICAgICAgIHV0aWxfMS5zZXQoZGF0dW0sICdfX2NvbXBhcmVfXy55VmFsdWVzTmV4dCcsIHV0aWxfMS5nZXQoZGF0YSwgaW5kZXggKyAxICsgXCIuX19jb21wYXJlX18ueVZhbHVlc1wiKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9O1xuICAgIEZ1bm5lbExheWVyLnByb3RvdHlwZS5fdXBkYXRlRGF0YUZvckNvbXBhcmUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgeVZhbHVlc01heCA9IFstSW5maW5pdHksIC1JbmZpbml0eV07XG4gICAgICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0dW0pIHtcbiAgICAgICAgICAgIHZhciB5VmFsdWVzID0gdXRpbF8xLmdldChkYXR1bSwgJ19fY29tcGFyZV9fLnlWYWx1ZXMnKTtcbiAgICAgICAgICAgIFswLCAxXS5mb3JFYWNoKGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHlWYWx1ZXNbaV0gPiB5VmFsdWVzTWF4W2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIHlWYWx1ZXNNYXhbaV0gPSB5VmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChkYXR1bSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHV0aWxfMS5zZXQoZGF0dW0sICdfX2NvbXBhcmVfXy55VmFsdWVzTWF4JywgeVZhbHVlc01heCk7XG4gICAgICAgICAgICB1dGlsXzEuc2V0KGRhdHVtLCAnX19jb21wYXJlX18ueVZhbHVlc05leHQnLCB1dGlsXzEuZ2V0KGRhdGEsIGluZGV4ICsgMSArIFwiLl9fY29tcGFyZV9fLnlWYWx1ZXNcIikpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBGdW5uZWxMYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEZ1bm5lbExheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZnVubmVsJywgRnVubmVsTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciBCQVJfQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSAqIDAuNSB9O1xufTtcbnZhciBCQVJfRElTQUJMRV9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IG9wYWNpdHk6IG9wYWNpdHkgKiAwLjUgfTtcbn07XG50aGVtZV8xLnJlZ2lzdGVyVGhlbWUoJ2Z1bm5lbCcsIHtcbiAgICBjb2x1bW5TdHlsZToge1xuICAgICAgICBub3JtYWw6IHt9LFxuICAgICAgICBhY3RpdmU6IEJBUl9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IEJBUl9ESVNBQkxFX1NUWUxFLFxuICAgICAgICBzZWxlY3RlZDogeyBsaW5lV2lkdGg6IDEsIHN0cm9rZTogJ2JsYWNrJyB9LFxuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRoZW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5vbkV2ZW50ID0gZXhwb3J0cy5FVkVOVF9NQVAgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2V2ZW50XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRVZFTlRfTUFQXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLkVWRU5UX01BUDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9uRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEub25FdmVudDsgfSB9KTtcbnZhciBjb21wb25lbnRNYXAgPSB7XG4gICAgcmFuZ2U6ICdwb2ludCcsXG4gICAgc3RhdGlzdGljOiAnYW5ub3RhdGlvbi10ZXh0Jyxcbn07XG52YXIgU0hBUEVfRVZFTlRfTUFQID0gZXZlbnRfMS5nZXRFdmVudE1hcChjb21wb25lbnRNYXApO1xudXRpbF8xLmFzc2lnbihldmVudF8xLkVWRU5UX01BUCwgU0hBUEVfRVZFTlRfTUFQKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5HYXVnZVNoYXBlID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKipcbiAqIEBhdXRob3IgbGluaHVpd1xuICogQGRlc2NyaXB0aW9uIOS7quihqOebmOW9oueKtlxuICovXG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZzJfMSA9IHJlcXVpcmUoXCJAYW50di9nMlwiKTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL3RoZW1lXCIpO1xudmFyIGNvbW1vbl8xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL3V0aWwvY29tbW9uXCIpO1xuLyoqXG4gKiDku6rooajnm5jmjIfpkojlm77lvaJcbiAqIOaMh+mSiOS4u+S9k+eUseair+W9ouWSjOS4gOWkp+S4gOWwj+WchuW9oue7hOaIkO+8jFxuICog5Lit5b+D5aSE55Sx54Gw6Imy5ZyG5bqV5ZKM5bCP55m95ZyG5Yqg5Lul6KOF6aWwXG4gKi9cbnZhciBHYXVnZVNoYXBlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdhdWdlU2hhcGUodWlkKSB7XG4gICAgICAgIHRoaXMudWlkID0gdWlkO1xuICAgIH1cbiAgICBHYXVnZVNoYXBlLnByb3RvdHlwZS5zZXRPcHRpb24gPSBmdW5jdGlvbiAodHlwZSwgb3B0aW9ucykge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLmF4aXMgPSBvcHRpb25zLmF4aXM7XG4gICAgICAgIHRoaXMucGl2b3QgPSBvcHRpb25zLnBpdm90O1xuICAgIH07XG4gICAgR2F1Z2VTaGFwZS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgR2F1Z2UgPSB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgICAgIGcyXzEucmVnaXN0ZXJTaGFwZSgncG9pbnQnLCAnZ2F1Z2UnLCB7XG4gICAgICAgICAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBncm91cCkge1xuICAgICAgICAgICAgICAgIHZhciBfYSwgX2IsIF9jO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F1Z2UgPSB7fTtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdWdlLm9wdGlvbnMgPSBHYXVnZS5vcHRpb25zO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F1Z2UuYXhpcyA9IEdhdWdlLmF4aXM7XG4gICAgICAgICAgICAgICAgdGhpcy5nYXVnZS5waXZvdCA9IEdhdWdlLnBpdm90O1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F1Z2UudHlwZSA9IEdhdWdlLnR5cGU7XG4gICAgICAgICAgICAgICAgdmFyIGdhdWdlID0gdGhpcy5nYXVnZTtcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IHRoaXMuZ2F1Z2UudHlwZTtcbiAgICAgICAgICAgICAgICB2YXIgcG9pbnQgPSBjZmcucG9pbnRzWzBdO1xuICAgICAgICAgICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLnBhcnNlUG9pbnQoe1xuICAgICAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSB0aGlzLnBhcnNlUG9pbnQoe1xuICAgICAgICAgICAgICAgICAgICB4OiBwb2ludC54IHx8IDAsXG4gICAgICAgICAgICAgICAgICAgIHk6IDEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgZ2F1Z2UuY2VudGVyID0gY2VudGVyO1xuICAgICAgICAgICAgICAgIGdhdWdlLmdyb3VwID0gZ3JvdXA7XG4gICAgICAgICAgICAgICAgdmFyIHIgPSB7IHg6IGNlbnRlci54IC0gdGFyZ2V0LngsIHk6IGNlbnRlci55IC0gdGFyZ2V0LnkgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdWdlLnJpbmdSYWRpdXMgPSBNYXRoLnNxcnQoci54ICogci54ICsgci55ICogci55KTtcbiAgICAgICAgICAgICAgICB2YXIgX2QgPSB0aGlzLmdldEFuZ2xlUmFuZ2UoKSwgc3RhckFuZ2xlID0gX2Quc3RhckFuZ2xlLCBlbmRBbmdsZSA9IF9kLmVuZEFuZ2xlO1xuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50QW5nbGUgPSBwb2ludC54ICogKGVuZEFuZ2xlIC0gc3RhckFuZ2xlKSArIHN0YXJBbmdsZTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbWV0ZXJHYXVnZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdCYXJHYXVnZShjdXJyZW50QW5nbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2F1Z2UuYXhpcy52aXNpYmxlICYmICgoX2EgPSB0aGlzLmdhdWdlLmF4aXMudGlja0xpbmUpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS52aXNpYmxlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd0luU2lkZUF4aXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdmYW5HYXVnZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdHYXVnZShjdXJyZW50QW5nbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2F1Z2UuYXhpcy52aXNpYmxlICYmICgoX2IgPSB0aGlzLmdhdWdlLmF4aXMudGlja0xpbmUpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi52aXNpYmxlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd091dFNpZGVBeGlzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnc3RhbmRhcmRHYXVnZSc6XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdHYXVnZShjdXJyZW50QW5nbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2F1Z2UuYXhpcy52aXNpYmxlICYmICgoX2MgPSB0aGlzLmdhdWdlLmF4aXMudGlja0xpbmUpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy52aXNpYmxlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd0F4aXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyDnu5jliLbmjIfpkohcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nYXVnZS5waXZvdC52aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd1Bpdm90KGNmZywgZ3JvdXApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmF3R2F1Z2U6IGZ1bmN0aW9uIChjdXJyZW50QW5nbGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdhdWdlLm9wdGlvbnMucmFuZ2U7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmF3Qm90dG9tUmluZygpOyAvLyDnu5jliLbngbDlupXoibJcbiAgICAgICAgICAgICAgICBpZiAocmFuZ2UgJiYgcmFuZ2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd1JhbmdlQ29sb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd0N1cnJlbnRSaW5nKGN1cnJlbnRBbmdsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRyYXdSYW5nZUNvbG9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hID0gdGhpcy5nYXVnZS5vcHRpb25zLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heCwgcmFuZ2UgPSBfYS5yYW5nZSwgY29sb3IgPSBfYS5jb2xvciwgcmFuZ2VTdHlsZSA9IF9hLnJhbmdlU3R5bGU7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9ycyA9IGNvbG9yIHx8IHRoZW1lXzEuZ2V0R2xvYmFsVGhlbWUoKS5jb2xvcnM7XG4gICAgICAgICAgICAgICAgdmFyIF9iID0gdGhpcy5nZXRBbmdsZVJhbmdlKCksIHN0YXJBbmdsZSA9IF9iLnN0YXJBbmdsZSwgZW5kQW5nbGUgPSBfYi5lbmRBbmdsZTtcbiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0ge1xuICAgICAgICAgICAgICAgICAgICBtaW46IG1pbixcbiAgICAgICAgICAgICAgICAgICAgbWF4OiBtYXgsXG4gICAgICAgICAgICAgICAgICAgIHN0YXJBbmdsZTogc3RhckFuZ2xlLFxuICAgICAgICAgICAgICAgICAgICBlbmRBbmdsZTogZW5kQW5nbGUsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGFydCA9IHRoaXMudmFsdWVUb0FuZ2xlKHJhbmdlW2ldLCBjb25maWcpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZW5kID0gdGhpcy52YWx1ZVRvQW5nbGUocmFuZ2VbaSArIDFdLCBjb25maWcpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZW5kID49IHN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGF0aDIgPSB0aGlzLmdldFBhdGgoc3RhcnQsIGVuZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3R5bGUgPSB1dGlsXzEuZGVlcE1peCh7IGZpbGw6IGNvbG9yc1tpXSB9LCByYW5nZVN0eWxlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd1JpbmcocGF0aDIsIHN0eWxlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmF3Qm90dG9tUmluZzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0QW5nbGVSYW5nZSgpLCBzdGFyQW5nbGUgPSBfYS5zdGFyQW5nbGUsIGVuZEFuZ2xlID0gX2EuZW5kQW5nbGU7XG4gICAgICAgICAgICAgICAgdmFyIGJhY2tncm91bmRTdHlsZSA9IHRoaXMuZ2F1Z2Uub3B0aW9ucy5yYW5nZUJhY2tncm91bmRTdHlsZTtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aCA9IHRoaXMuZ2V0UGF0aChzdGFyQW5nbGUsIGVuZEFuZ2xlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYXdSaW5nKHBhdGgsIGJhY2tncm91bmRTdHlsZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZHJhd0N1cnJlbnRSaW5nOiBmdW5jdGlvbiAoY3VycmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBzdGFyQW5nbGUgPSB0aGlzLmdldEFuZ2xlUmFuZ2UoKS5zdGFyQW5nbGU7XG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlU3R5bGUgPSB0aGlzLmdhdWdlLnJhbmdlU3R5bGU7XG4gICAgICAgICAgICAgICAgdmFyIHBhdGgzID0gdGhpcy5nZXRQYXRoKHN0YXJBbmdsZSwgY3VycmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmF3UmluZyhwYXRoMywgcmFuZ2VTdHlsZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZHJhd0luU2lkZUF4aXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2EgPSB0aGlzLmdhdWdlLm9wdGlvbnMsIG1pbiA9IF9hLm1pbiwgbWF4ID0gX2EubWF4LCBheGlzID0gX2EuYXhpcztcbiAgICAgICAgICAgICAgICB2YXIgX2IgPSB0aGlzLmdldEFuZ2xlUmFuZ2UoKSwgc3RhckFuZ2xlID0gX2Iuc3RhckFuZ2xlLCBlbmRBbmdsZSA9IF9iLmVuZEFuZ2xlO1xuICAgICAgICAgICAgICAgIHZhciBjb25maWcgPSB7XG4gICAgICAgICAgICAgICAgICAgIG1pbjogbWluLFxuICAgICAgICAgICAgICAgICAgICBtYXg6IG1heCxcbiAgICAgICAgICAgICAgICAgICAgc3RhckFuZ2xlOiBzdGFyQW5nbGUsXG4gICAgICAgICAgICAgICAgICAgIGVuZEFuZ2xlOiBlbmRBbmdsZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHZhciBpbnRlcnZhbCA9IChtYXggLSBtaW4pIC8gYXhpcy50aWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBheGlzLnRpY2tDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGFydFZhbHVlID0gbWluICsgaSAqIGludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYW5nbGUgPSB0aGlzLnZhbHVlVG9BbmdsZShzdGFydFZhbHVlICsgaW50ZXJ2YWwgLyAyLCBjb25maWcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdSZWN0KGFuZ2xlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGg6IGF4aXMudGlja0xpbmUubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IGF4aXMudGlja0xpbmUuc3R5bGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmF3QXhpczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBheGlzID0gdGhpcy5nYXVnZS5heGlzO1xuICAgICAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuZ2F1Z2Uub3B0aW9ucywgbWluID0gX2EubWluLCBtYXggPSBfYS5tYXg7XG4gICAgICAgICAgICAgICAgdmFyIF9iID0gdGhpcy5nZXRBbmdsZVJhbmdlKCksIHN0YXJBbmdsZSA9IF9iLnN0YXJBbmdsZSwgZW5kQW5nbGUgPSBfYi5lbmRBbmdsZTtcbiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0ge1xuICAgICAgICAgICAgICAgICAgICBtaW46IG1pbixcbiAgICAgICAgICAgICAgICAgICAgbWF4OiBtYXgsXG4gICAgICAgICAgICAgICAgICAgIHN0YXJBbmdsZTogc3RhckFuZ2xlLFxuICAgICAgICAgICAgICAgICAgICBlbmRBbmdsZTogZW5kQW5nbGUsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwgPSAobWF4IC0gbWluKSAvIChheGlzLnRpY2tDb3VudCAtIDEpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXhpcy50aWNrQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc3RhcnRWYWx1ZSA9IG1pbiArIGkgKiBpbnRlcnZhbDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFuZ2xlID0gdGhpcy52YWx1ZVRvQW5nbGUoc3RhcnRWYWx1ZSwgY29uZmlnKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRpY2tMaW5lU3R5bGUgPSB1dGlsXzEuY2xvbmUoYXhpcy50aWNrTGluZS5zdHlsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpICUgNSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGlja0xpbmVTdHlsZS5saW5lV2lkdGggPSB0aWNrTGluZVN0eWxlLmxpbmVXaWR0aCAvIDI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3UmVjdChhbmdsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiBpICUgNSA9PT0gMCA/IGF4aXMudGlja0xpbmUubGVuZ3RoIDogYXhpcy50aWNrTGluZS5sZW5ndGggLyAyLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHRpY2tMaW5lU3R5bGUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmF3T3V0U2lkZUF4aXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXhpcyA9IHRoaXMuZ2F1Z2UuYXhpcztcbiAgICAgICAgICAgICAgICB2YXIgX2EgPSB0aGlzLmdhdWdlLm9wdGlvbnMsIG1pbiA9IF9hLm1pbiwgbWF4ID0gX2EubWF4O1xuICAgICAgICAgICAgICAgIHZhciBfYiA9IHRoaXMuZ2V0QW5nbGVSYW5nZSgpLCBzdGFyQW5nbGUgPSBfYi5zdGFyQW5nbGUsIGVuZEFuZ2xlID0gX2IuZW5kQW5nbGU7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICAgICAgbWluOiBtaW4sXG4gICAgICAgICAgICAgICAgICAgIG1heDogbWF4LFxuICAgICAgICAgICAgICAgICAgICBzdGFyQW5nbGU6IHN0YXJBbmdsZSxcbiAgICAgICAgICAgICAgICAgICAgZW5kQW5nbGU6IGVuZEFuZ2xlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdmFyIGludGVydmFsID0gKG1heCAtIG1pbikgLyAoYXhpcy50aWNrQ291bnQgLSAxKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF4aXMudGlja0NvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXJ0VmFsdWUgPSBtaW4gKyBpICogaW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhbmdsZSA9IHRoaXMudmFsdWVUb0FuZ2xlKHN0YXJ0VmFsdWUsIGNvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd1JlY3QoYW5nbGUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aDogYXhpcy50aWNrTGluZS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogYXhpcy50aWNrTGluZS5zdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRyYXdCYXJHYXVnZTogZnVuY3Rpb24gKGN1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuZ2F1Z2Uub3B0aW9ucywgbWluID0gX2EubWluLCBtYXggPSBfYS5tYXgsIHJhbmdlID0gX2EucmFuZ2UsIGNvbG9yID0gX2EuY29sb3IsIHJhbmdlU3R5bGUgPSBfYS5yYW5nZVN0eWxlLCByYW5nZUJhY2tncm91bmRTdHlsZSA9IF9hLnJhbmdlQmFja2dyb3VuZFN0eWxlO1xuICAgICAgICAgICAgICAgIHZhciBjb2xvcnMgPSBjb2xvciB8fCB0aGVtZV8xLmdldEdsb2JhbFRoZW1lKCkuY29sb3JzO1xuICAgICAgICAgICAgICAgIHZhciBfYiA9IHRoaXMuZ2V0QW5nbGVSYW5nZSgpLCBzdGFyQW5nbGUgPSBfYi5zdGFyQW5nbGUsIGVuZEFuZ2xlID0gX2IuZW5kQW5nbGU7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICAgICAgbWluOiBtaW4sXG4gICAgICAgICAgICAgICAgICAgIG1heDogbWF4LFxuICAgICAgICAgICAgICAgICAgICBzdGFyQW5nbGU6IHN0YXJBbmdsZSxcbiAgICAgICAgICAgICAgICAgICAgZW5kQW5nbGU6IGVuZEFuZ2xlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdmFyIGludGVydmFsID0gKGVuZEFuZ2xlIC0gc3RhckFuZ2xlKSAvICg1MCAtIDEpO1xuICAgICAgICAgICAgICAgIHZhciBvZmZzZXQgPSBpbnRlcnZhbCAvIDM7XG4gICAgICAgICAgICAgICAgLy8g55SxNTDkuKrmn7HlrZDnu4TmiJBcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDUwOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gc3RhckFuZ2xlICsgaSAqIGludGVydmFsO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGF0aDIgPSB0aGlzLmdldFBhdGgoc3RhcnQgLSBvZmZzZXQgLyAyLCBzdGFydCArIG9mZnNldCAtIG9mZnNldCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgc3R5bGUgPSByYW5nZUJhY2tncm91bmRTdHlsZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlICYmIHJhbmdlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdDEgPSByYW5nZS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMudmFsdWVUb0FuZ2xlKGl0ZW0sIGNvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGNvbW1vbl8xLnNvcnRlZExhc3RJbmRleChyZXN1bHQxLCBzdGFydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvKiog5pyA5ZCO5LiA5Liq5YC85Lmf5Zyo5pyA5ZCO5LiA5Liq5Yy66Ze05YaFICovXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3JJbmRleCA9IE1hdGgubWluKGluZGV4LCByYW5nZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gdXRpbF8xLmRlZXBNaXgoe30sIHsgZmlsbDogY29sb3JzW2NvbG9ySW5kZXggLSAxXSB9LCByYW5nZVN0eWxlKSB8fCByYW5nZUJhY2tncm91bmRTdHlsZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gY3VycmVudCA+PSBzdGFydCA/IHV0aWxfMS5kZWVwTWl4KHt9LCB7IGZpbGw6IGNvbG9yIH0sIHJhbmdlU3R5bGUpIDogcmFuZ2VCYWNrZ3JvdW5kU3R5bGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3UmluZyhwYXRoMiwgc3R5bGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRBbmdsZVJhbmdlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFuZ2xlID0gdGhpcy5nYXVnZS5vcHRpb25zLmFuZ2xlO1xuICAgICAgICAgICAgICAgIHZhciBhbmdsZVZhbHVlID0gOTAgLSAoMzYwIC0gYW5nbGUpICogMC41O1xuICAgICAgICAgICAgICAgIHZhciBzdGFyQW5nbGUgPSAoKDI3MCAtIDkwIC0gYW5nbGVWYWx1ZSkgKiBNYXRoLlBJKSAvIDE4MDtcbiAgICAgICAgICAgICAgICB2YXIgZW5kQW5nbGUgPSAoKDI3MCArIDkwICsgYW5nbGVWYWx1ZSkgKiBNYXRoLlBJKSAvIDE4MDtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBzdGFyQW5nbGU6IHN0YXJBbmdsZSwgZW5kQW5nbGU6IGVuZEFuZ2xlIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmFsdWVUb0FuZ2xlOiBmdW5jdGlvbiAodmFsdWUsIGNvbmZpZykge1xuICAgICAgICAgICAgICAgIHZhciBtaW4gPSBjb25maWcubWluLCBtYXggPSBjb25maWcubWF4LCBzdGFyQW5nbGUgPSBjb25maWcuc3RhckFuZ2xlLCBlbmRBbmdsZSA9IGNvbmZpZy5lbmRBbmdsZTtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IG1heCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5kQW5nbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbWluKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGFyQW5nbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciByYXRpbyA9ICh2YWx1ZSAtIG1pbikgLyAobWF4IC0gbWluKTtcbiAgICAgICAgICAgICAgICBpZiAobWF4ID09PSBtaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgcmF0aW8gPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgYW5nbGUgPSByYXRpbyAqIChlbmRBbmdsZSAtIHN0YXJBbmdsZSkgKyBzdGFyQW5nbGU7XG4gICAgICAgICAgICAgICAgYW5nbGUgPSBNYXRoLm1heChhbmdsZSwgc3RhckFuZ2xlKTtcbiAgICAgICAgICAgICAgICBhbmdsZSA9IE1hdGgubWluKGFuZ2xlLCBlbmRBbmdsZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFuZ2xlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRyYXdSaW5nOiBmdW5jdGlvbiAocGF0aCwgc3R5bGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmdhdWdlLmdyb3VwLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgICAgICAgICBhdHRyczogdXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICAgIH0sIHN0eWxlKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmF3UmVjdDogZnVuY3Rpb24gKGFuZ2xlLCBwYXJhbSkge1xuICAgICAgICAgICAgICAgIHZhciBheGlzID0gdGhpcy5nYXVnZS5heGlzO1xuICAgICAgICAgICAgICAgIHZhciBjb25maWcgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGF4aXMpLCBwYXJhbSk7XG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IGNvbmZpZy5vZmZzZXQsIGxlbmd0aCA9IGNvbmZpZy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIGNlbnRlciA9IHRoaXMuZ2F1Z2UuY2VudGVyO1xuICAgICAgICAgICAgICAgIHZhciByYWRpdXM7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmFkaXVzID0gdGhpcy5nYXVnZS5yaW5nUmFkaXVzIC0gdGhpcy5nYXVnZS5vcHRpb25zLnJhbmdlU2l6ZSArIG9mZnNldDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IHRoaXMuZ2F1Z2UucmluZ1JhZGl1cyArIG9mZnNldDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHhBMSA9IHJhZGl1cyAqIE1hdGguY29zKGFuZ2xlKSArIGNlbnRlci54O1xuICAgICAgICAgICAgICAgIHZhciB5QTEgPSByYWRpdXMgKiBNYXRoLnNpbihhbmdsZSkgKyBjZW50ZXIueTtcbiAgICAgICAgICAgICAgICB2YXIgeEIxID0gKHJhZGl1cyArIGxlbmd0aCkgKiBNYXRoLmNvcyhhbmdsZSkgKyBjZW50ZXIueDtcbiAgICAgICAgICAgICAgICB2YXIgeUIxID0gKHJhZGl1cyArIGxlbmd0aCkgKiBNYXRoLnNpbihhbmdsZSkgKyBjZW50ZXIueTtcbiAgICAgICAgICAgICAgICB2YXIgbGluZSA9IHRoaXMuZ2F1Z2UuZ3JvdXAuYWRkU2hhcGUoJ2xpbmUnLCB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEuZGVlcE1peCh7fSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgeDE6IHhBMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHkxOiB5QTEsXG4gICAgICAgICAgICAgICAgICAgICAgICB4MjogeEIxLFxuICAgICAgICAgICAgICAgICAgICAgICAgeTI6IHlCMSxcbiAgICAgICAgICAgICAgICAgICAgfSwgcGFyYW0uc3R5bGUpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGxpbmUuc2V0KCduYW1lJywgJ2F4aXMtdGlja0xpbmUnKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRQYXRoOiBmdW5jdGlvbiAoc3RhckFuZ2xlLCBlbmRBbmdsZSkge1xuICAgICAgICAgICAgICAgIC8qIGNvbnN0IHR5cGUgPSB0aGlzLmdhdWdlLnR5cGU7XG4gICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gZ2V0KGdhdWdlLCAnb3B0aW9ucy5oZWlnaHQnKTtcbiAgICAgICAgICAgICAgICBjb25zdCB3aWR0aCA9IGdldChnYXVnZSwgJ29wdGlvbnMud2lkdGgnKTsqL1xuICAgICAgICAgICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLmdhdWdlLmNlbnRlcjtcbiAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gdGhpcy5nYXVnZS5yaW5nUmFkaXVzO1xuICAgICAgICAgICAgICAgIC8qbGV0IHRoaWNrO1xuICAgICAgICAgICAgICAgICBjb25zdCB7IG1pblRoaWNrbmVzcywgbWluVGhpY2tDYW52c1NpemUgfSA9IHRoaXMuZ2F1Z2UucmluZ1N0eWxlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNpemUgPSBNYXRoLm1pbih3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2ZhbicgJiYgc2l6ZSA8IG1pblRoaWNrQ2FudnNTaXplKSB7XG4gICAgICAgICAgICAgICAgICB0aGljayA9IGxlbmd0aCAtIG1pblRoaWNrbmVzcztcbiAgICAgICAgICAgICAgICB9IGVsc2UgeyovXG4gICAgICAgICAgICAgICAgdmFyIHRoaWNrID0gdGhpcy5nYXVnZS5vcHRpb25zLnJhbmdlU2l6ZTtcbiAgICAgICAgICAgICAgICAvL31cbiAgICAgICAgICAgICAgICB2YXIgeEExID0gbGVuZ3RoICogTWF0aC5jb3Moc3RhckFuZ2xlKSArIGNlbnRlci54O1xuICAgICAgICAgICAgICAgIHZhciB5QTEgPSBsZW5ndGggKiBNYXRoLnNpbihzdGFyQW5nbGUpICsgY2VudGVyLnk7XG4gICAgICAgICAgICAgICAgdmFyIHhBMiA9IChsZW5ndGggLSB0aGljaykgKiBNYXRoLmNvcyhzdGFyQW5nbGUpICsgY2VudGVyLng7XG4gICAgICAgICAgICAgICAgdmFyIHlBMiA9IChsZW5ndGggLSB0aGljaykgKiBNYXRoLnNpbihzdGFyQW5nbGUpICsgY2VudGVyLnk7XG4gICAgICAgICAgICAgICAgdmFyIHhCMSA9IGxlbmd0aCAqIE1hdGguY29zKGVuZEFuZ2xlKSArIGNlbnRlci54O1xuICAgICAgICAgICAgICAgIHZhciB5QjEgPSBsZW5ndGggKiBNYXRoLnNpbihlbmRBbmdsZSkgKyBjZW50ZXIueTtcbiAgICAgICAgICAgICAgICB2YXIgeEIyID0gKGxlbmd0aCAtIHRoaWNrKSAqIE1hdGguY29zKGVuZEFuZ2xlKSArIGNlbnRlci54O1xuICAgICAgICAgICAgICAgIHZhciB5QjIgPSAobGVuZ3RoIC0gdGhpY2spICogTWF0aC5zaW4oZW5kQW5nbGUpICsgY2VudGVyLnk7XG4gICAgICAgICAgICAgICAgdmFyIGxhcmdlQXJjRmxhZyA9IE1hdGguYWJzKHN0YXJBbmdsZSAtIGVuZEFuZ2xlKSA+IE1hdGguUEkgPyAxIDogMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgICAgICBbJ00nLCB4QTEsIHlBMV0sXG4gICAgICAgICAgICAgICAgICAgIFsnQScsIGxlbmd0aCwgbGVuZ3RoLCAwLCBsYXJnZUFyY0ZsYWcsIDEsIHhCMSwgeUIxXSxcbiAgICAgICAgICAgICAgICAgICAgWydMJywgeEIyLCB5QjJdLFxuICAgICAgICAgICAgICAgICAgICBbJ0EnLCBsZW5ndGggLSB0aGljaywgbGVuZ3RoIC0gdGhpY2ssIDAsIGxhcmdlQXJjRmxhZywgMCwgeEEyLCB5QTJdLFxuICAgICAgICAgICAgICAgICAgICBbJ1onXSxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRyYXdQaXZvdDogZnVuY3Rpb24gKGNmZykge1xuICAgICAgICAgICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0QW5nbGVSYW5nZSgpLCBzdGFyQW5nbGUgPSBfYS5zdGFyQW5nbGUsIGVuZEFuZ2xlID0gX2EuZW5kQW5nbGU7XG4gICAgICAgICAgICAgICAgdmFyIF9iID0gdGhpcy5nYXVnZS5vcHRpb25zLCByYWRpdXMgPSBfYi5yYWRpdXMsIHJhbmdlU2l6ZSA9IF9iLnJhbmdlU2l6ZTtcbiAgICAgICAgICAgICAgICB2YXIgcGl2b3RDb25maWcgPSB0aGlzLmdhdWdlLnBpdm90O1xuICAgICAgICAgICAgICAgIHZhciBiaWdDaXJjbGUgPSBwaXZvdENvbmZpZy50aGlja25lc3M7XG4gICAgICAgICAgICAgICAgdmFyIHNtQ2lyY2xlID0gcGl2b3RDb25maWcudGhpY2tuZXNzIC8gMi41O1xuICAgICAgICAgICAgICAgIHZhciBncm91cCA9IHRoaXMuZ2F1Z2UuZ3JvdXA7XG4gICAgICAgICAgICAgICAgdmFyIHBvaW50ID0gY2ZnLnBvaW50c1swXTtcbiAgICAgICAgICAgICAgICB2YXIgY2VudGVyID0gdGhpcy5wYXJzZVBvaW50KHtcbiAgICAgICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvLyByYWRpdXNcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IHBvaW50LnggKiAoZW5kQW5nbGUgLSBzdGFyQW5nbGUpICsgc3RhckFuZ2xlO1xuICAgICAgICAgICAgICAgIHZhciB4ID0gKHRoaXMuZ2F1Z2UucmluZ1JhZGl1cyAtIHJhbmdlU2l6ZSkgKiByYWRpdXMgKiBNYXRoLmNvcyhjdXJyZW50KSArIHRoaXMuZ2F1Z2UuY2VudGVyLng7XG4gICAgICAgICAgICAgICAgdmFyIHkgPSAodGhpcy5nYXVnZS5yaW5nUmFkaXVzIC0gcmFuZ2VTaXplKSAqIHJhZGl1cyAqIE1hdGguc2luKGN1cnJlbnQpICsgdGhpcy5nYXVnZS5jZW50ZXIueTtcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgLy8g5aSW5bqV6Imy54Gw5ZyGXG4gICAgICAgICAgICAgICAgaWYgKHBpdm90Q29uZmlnLmJhc2UudmlzaWJsZSkge1xuICAgICAgICAgICAgICAgICAgICBncm91cC5hZGRTaGFwZSgnY2lyY2xlJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogY2VudGVyLngsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogY2VudGVyLnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcjogcGl2b3RDb25maWcuYmFzZS5zaXplID8gcGl2b3RDb25maWcuYmFzZS5zaXplIC8gMiA6IGJpZ0NpcmNsZSAqIDIuMixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHBpdm90Q29uZmlnLmJhc2Uuc3R5bGUpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g5oyH6ZKIXG4gICAgICAgICAgICAgICAgaWYgKHBpdm90Q29uZmlnLnBvaW50ZXIudmlzaWJsZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGlyVmVjID0geyB4OiBjZW50ZXIueCAtIHRhcmdldC54LCB5OiBjZW50ZXIueSAtIHRhcmdldC55IH07XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGhfMSA9IE1hdGguc3FydChkaXJWZWMueCAqIGRpclZlYy54ICsgZGlyVmVjLnkgKiBkaXJWZWMueSk7XG4gICAgICAgICAgICAgICAgICAgIGRpclZlYy54ICo9IDEgLyBsZW5ndGhfMTtcbiAgICAgICAgICAgICAgICAgICAgZGlyVmVjLnkgKj0gMSAvIGxlbmd0aF8xO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYW5nbGUxID0gLU1hdGguUEkgLyAyO1xuICAgICAgICAgICAgICAgICAgICB2YXIgeDEgPSBNYXRoLmNvcyhhbmdsZTEpICogZGlyVmVjLnggLSBNYXRoLnNpbihhbmdsZTEpICogZGlyVmVjLnk7XG4gICAgICAgICAgICAgICAgICAgIHZhciB5MSA9IE1hdGguc2luKGFuZ2xlMSkgKiBkaXJWZWMueCArIE1hdGguY29zKGFuZ2xlMSkgKiBkaXJWZWMueTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFuZ2xlMiA9IE1hdGguUEkgLyAyO1xuICAgICAgICAgICAgICAgICAgICB2YXIgeDIgPSBNYXRoLmNvcyhhbmdsZTIpICogZGlyVmVjLnggLSBNYXRoLnNpbihhbmdsZTIpICogZGlyVmVjLnk7XG4gICAgICAgICAgICAgICAgICAgIHZhciB5MiA9IE1hdGguc2luKGFuZ2xlMikgKiBkaXJWZWMueCArIE1hdGguY29zKGFuZ2xlMikgKiBkaXJWZWMueTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhdGggPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCB0YXJnZXQueCArIHgxICogc21DaXJjbGUsIHRhcmdldC55ICsgeTEgKiBzbUNpcmNsZV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBjZW50ZXIueCArIHgxICogYmlnQ2lyY2xlLCBjZW50ZXIueSArIHkxICogYmlnQ2lyY2xlXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIGNlbnRlci54ICsgeDIgKiBiaWdDaXJjbGUsIGNlbnRlci55ICsgeTIgKiBiaWdDaXJjbGVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgWydMJywgdGFyZ2V0LnggKyB4MiAqIHNtQ2lyY2xlLCB0YXJnZXQueSArIHkyICogc21DaXJjbGVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgWydaJ10sXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHBpdm90Q29uZmlnLnBvaW50ZXIuc3R5bGUpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuYWRkU2hhcGUoJ2NpcmNsZScsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogdGFyZ2V0LngsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogdGFyZ2V0LnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcjogc21DaXJjbGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogcGl2b3RDb25maWcucG9pbnRlci5zdHlsZS5maWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLmFkZFNoYXBlKCdjaXJjbGUnLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGNlbnRlci54LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGNlbnRlci55LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHI6IGJpZ0NpcmNsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBwaXZvdENvbmZpZy5wb2ludGVyLnN0eWxlLmZpbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHBpdm90Q29uZmlnLnBpbi52aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOWGhemDqOeZveiJsuWwj+WchlxuICAgICAgICAgICAgICAgICAgICBncm91cC5hZGRTaGFwZSgnY2lyY2xlJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogY2VudGVyLngsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogY2VudGVyLnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcjogc21DaXJjbGUgLyAxLjIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBwaXZvdENvbmZpZy5waW4uc3R5bGUpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBHYXVnZVNoYXBlO1xufSgpKTtcbmV4cG9ydHMuR2F1Z2VTaGFwZSA9IEdhdWdlU2hhcGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYXVnZS1zaGFwZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgR2F1Z2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR2F1Z2UsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR2F1Z2UoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgR2F1Z2UucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdnYXVnZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBHYXVnZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gR2F1Z2U7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBHYXVnZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKipcbiAqIEBhdXRob3IgbGluaHVpd1xuICogQGRlc2NyaXB0aW9uIOS7quihqOebmCBsYXllclxuICovXG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgdmlld19sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2Uvdmlldy1sYXllclwiKSk7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3NjYWxlXCIpO1xudmFyIGdhdWdlX3NoYXBlXzEgPSByZXF1aXJlKFwiLi9nZW9tZXRyeS9zaGFwZS9nYXVnZS1zaGFwZVwiKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnZhciBHYXVnZUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEdhdWdlTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR2F1Z2VMYXllcihwcm9wcykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBwcm9wcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdnYXVnZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgR2F1Z2VMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgc3RhcnRBbmdsZTogLTcgLyA2LFxuICAgICAgICAgICAgZW5kQW5nbGU6IDEgLyA2LFxuICAgICAgICAgICAgcmFuZ2VCYWNrZ3JvdW5kU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiAnI2YwZjBmMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmFuZ2VTaXplOiAyNCxcbiAgICAgICAgICAgIHN0YXRpc3RpYzoge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBbJzUwJScsICc4MCUnXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBheGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IC0xMCxcbiAgICAgICAgICAgICAgICB0aWNrQ291bnQ6IDIxLFxuICAgICAgICAgICAgICAgIHN1YlRpY2tDb3VudDogNCxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBsZW5ndGg6IDUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjYWFhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogOCxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjYWFhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxNixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGl2b3Q6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHRoaWNrbmVzczogNixcbiAgICAgICAgICAgICAgICBwaW46IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgc2l6ZTogMixcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjMkUzNjRCJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGJhc2U6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjRUVFRUVFJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBvaW50ZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjQ0ZDRkNGJyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBHYXVnZUxheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHZhbHVlID0gX2EudmFsdWUsIHJhbmdlID0gX2EucmFuZ2U7XG4gICAgICAgIHZhciByYW5nZVNvcnRlZCA9IChyYW5nZSB8fCBbXSkubWFwKGZ1bmN0aW9uIChkKSB7IHJldHVybiArZDsgfSkuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSAtIGI7IH0pO1xuICAgICAgICB2YXIgX2IgPSB0aGlzLm9wdGlvbnMsIF9jID0gX2IubWluLCBtaW4gPSBfYyA9PT0gdm9pZCAwID8gcmFuZ2VTb3J0ZWRbMF0gOiBfYywgX2QgPSBfYi5tYXgsIG1heCA9IF9kID09PSB2b2lkIDAgPyByYW5nZVNvcnRlZFtyYW5nZVNvcnRlZC5sZW5ndGggLSAxXSA6IF9kLCBfZSA9IF9iLmZvcm1hdCwgZm9ybWF0ID0gX2UgPT09IHZvaWQgMCA/IGZ1bmN0aW9uIChkKSB7IHJldHVybiBcIlwiICsgZDsgfSA6IF9lO1xuICAgICAgICB2YXIgdmFsdWVUZXh0ID0gZm9ybWF0KHZhbHVlKTtcbiAgICAgICAgLy9jb25zdCBzdHlsZU1peCA9IHRoaXMuZ2V0U3R5bGVNaXgoKTtcbiAgICAgICAgLy90aGlzLm9wdGlvbnMuc3R5bGVNaXggPSBzdHlsZU1peDtcbiAgICAgICAgdGhpcy5vcHRpb25zLmRhdGEgPSBbeyB2YWx1ZTogdmFsdWUgfHwgMCB9XTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnZhbHVlVGV4dCA9IHZhbHVlVGV4dDtcbiAgICAgICAgdGhpcy5vcHRpb25zLm1pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5vcHRpb25zLm1heCA9IG1heDtcbiAgICAgICAgdGhpcy5vcHRpb25zLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgICAgdGhpcy5pbml0RzJTaGFwZSgpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIOe7mOWItuaMh+mSiFxuICAgICAqL1xuICAgIEdhdWdlTGF5ZXIucHJvdG90eXBlLmluaXRHMlNoYXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmdhdWdlU2hhcGUgPSBuZXcgZ2F1Z2Vfc2hhcGVfMS5HYXVnZVNoYXBlKHV0aWxfMS51bmlxdWVJZCgpKTtcbiAgICAgICAgdGhpcy5nYXVnZVNoYXBlLnNldE9wdGlvbih0aGlzLnR5cGUsIHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLm9wdGlvbnMsIHtcbiAgICAgICAgICAgIHJhZGl1czogMC42LFxuICAgICAgICAgICAgYW5nbGU6IDI0MCxcbiAgICAgICAgICAgIHRleHRQb3NpdGlvbjogJzEwMCUnLFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuZ2F1Z2VTaGFwZS5yZW5kZXIoKTtcbiAgICB9O1xuICAgIEdhdWdlTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJ2dhdWdlJztcbiAgICB9O1xuICAgIEdhdWdlTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIG1pbiA9IF9hLm1pbiwgbWF4ID0gX2EubWF4LCBmb3JtYXQgPSBfYS5mb3JtYXQ7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7XG4gICAgICAgICAgICB2YWx1ZToge30sXG4gICAgICAgIH07XG4gICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlcy52YWx1ZSwge1xuICAgICAgICAgICAgbWluOiBtaW4sXG4gICAgICAgICAgICBtYXg6IG1heCxcbiAgICAgICAgICAgIG1pbkxpbWl0OiBtaW4sXG4gICAgICAgICAgICBtYXhMaW1pdDogbWF4LFxuICAgICAgICAgICAgbmljZTogdHJ1ZSxcbiAgICAgICAgICAgIGZvcm1hdHRlcjogZm9ybWF0LFxuICAgICAgICAgICAgLy8g6Ieq5a6a5LmJIHRpY2sgc3RlcFxuICAgICAgICAgICAgdGlja0ludGVydmFsOiAyMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ3NjYWxlcycsIHNjYWxlcyk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2NhbGUuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIEdhdWdlTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29vcmRDb25maWcgPSB7XG4gICAgICAgICAgICB0eXBlOiAncG9sYXInLFxuICAgICAgICAgICAgY2ZnOiB7XG4gICAgICAgICAgICAgICAgcmFkaXVzOiAxLFxuICAgICAgICAgICAgICAgIHN0YXJ0QW5nbGU6IHRoaXMub3B0aW9ucy5zdGFydEFuZ2xlICogTWF0aC5QSSxcbiAgICAgICAgICAgICAgICBlbmRBbmdsZTogdGhpcy5vcHRpb25zLmVuZEFuZ2xlICogTWF0aC5QSSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdjb29yZGluYXRlJywgY29vcmRDb25maWcpO1xuICAgIH07XG4gICAgR2F1Z2VMYXllci5wcm90b3R5cGUuYXhpcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGF4aXMgPSB0aGlzLm9wdGlvbnMuYXhpcztcbiAgICAgICAgdmFyIGF4ZXNDb25maWcgPSB7XG4gICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICAgIGxpbmU6IG51bGwsXG4gICAgICAgICAgICAgICAgZ3JpZDogbnVsbCxcbiAgICAgICAgICAgICAgICB0aWNrTGluZTogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHZhciBvZmZzZXRWYWx1ZTtcbiAgICAgICAgaWYgKGF4aXMub2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgb2Zmc2V0VmFsdWUgPSBheGlzLm9mZnNldCAtIHRoaXMub3B0aW9ucy5yYW5nZVNpemUgLSBheGlzLnRpY2tMaW5lLmxlbmd0aCAtIGF4aXMubGFiZWwub2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgb2Zmc2V0VmFsdWUgPSBheGlzLm9mZnNldCArIGF4aXMudGlja0xpbmUubGVuZ3RoICsgYXhpcy5sYWJlbC5vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF4aXMubGFiZWwudmlzaWJsZSkge1xuICAgICAgICAgICAgYXhlc0NvbmZpZy52YWx1ZS5sYWJlbCA9IHtcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IG9mZnNldFZhbHVlLFxuICAgICAgICAgICAgICAgIHRleHRTdHlsZTogYXhpcy5sYWJlbC5zdHlsZSxcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGF4ZXNDb25maWcudmFsdWUubGFiZWwgPSB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBheGVzQ29uZmlnWycxJ10gPSBmYWxzZTtcbiAgICAgICAgYXhlc0NvbmZpZ1sndmFsdWUnXSA9IGF4aXMudmlzaWJsZSA/IGF4ZXNDb25maWdbJ3ZhbHVlJ10gOiBmYWxzZTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2F4ZXMnLCBheGVzQ29uZmlnKTtcbiAgICB9O1xuICAgIEdhdWdlTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9pbnRlckNvbG9yID0gdGhpcy5vcHRpb25zLnBpdm90LnBvaW50ZXIuc3R5bGUuZmlsbCB8fCB0aGlzLnRoZW1lLmRlZmF1bHRDb2xvcjtcbiAgICAgICAgdmFyIHBvaW50ZXIgPSB7XG4gICAgICAgICAgICB0eXBlOiAncG9pbnQnLFxuICAgICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFsndmFsdWUnLCAnMSddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNoYXBlOiB7XG4gICAgICAgICAgICAgICAgdmFsdWVzOiBbJ2dhdWdlJ10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IFtwb2ludGVyQ29sb3JdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5JywgcG9pbnRlcik7XG4gICAgfTtcbiAgICBHYXVnZUxheWVyLnByb3RvdHlwZS5hbm5vdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RhdGlzdGljID0gdGhpcy5vcHRpb25zLnN0YXRpc3RpYztcbiAgICAgICAgdmFyIGFubm90YXRpb25Db25maWdzID0gW107XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgaWYgKHN0YXRpc3RpYyAmJiBzdGF0aXN0aWMudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIHN0YXRpc3RpY3MgPSB0aGlzLnJlbmRlclN0YXRpc3RpYygpO1xuICAgICAgICAgICAgYW5ub3RhdGlvbkNvbmZpZ3MucHVzaChzdGF0aXN0aWNzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnYW5ub3RhdGlvbnMnLCBhbm5vdGF0aW9uQ29uZmlncyk7XG4gICAgfTtcbiAgICBHYXVnZUxheWVyLnByb3RvdHlwZS5yZW5kZXJTdGF0aXN0aWMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb250YWluZXJTaXplID0gTWF0aC5tYXgodGhpcy5vcHRpb25zLndpZHRoLCB0aGlzLm9wdGlvbnMuaGVpZ2h0KSAvIDIwO1xuICAgICAgICB2YXIgc3RhdGlzdGljID0gdGhpcy5vcHRpb25zLnN0YXRpc3RpYztcbiAgICAgICAgdmFyIHRleHQgPSB7XG4gICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICBjb250ZW50OiBzdGF0aXN0aWMudGV4dCxcbiAgICAgICAgICAgIHRvcDogdHJ1ZSxcbiAgICAgICAgICAgIHBvc2l0aW9uOiBzdGF0aXN0aWMucG9zaXRpb24sXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIGZpbGw6IHN0YXRpc3RpYy5jb2xvcixcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogc3RhdGlzdGljLnNpemUgPyBzdGF0aXN0aWMuc2l6ZSA6IGNvbnRhaW5lclNpemUgKiAxLjIsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfTtcbiAgICBHYXVnZUxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIHJldHVybiBHYXVnZUxheWVyO1xufSh2aWV3X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR2F1Z2VMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ2dhdWdlJywgR2F1Z2VMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgR3JvdXBlZEJhciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cGVkQmFyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyb3VwZWRCYXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgR3JvdXBlZEJhci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2dyb3VwZWRCYXInO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgR3JvdXBlZEJhci5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gR3JvdXBlZEJhcjtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdyb3VwZWRCYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFyL2xheWVyXCIpKTtcbnJlcXVpcmUoXCIuL3RoZW1lXCIpO1xudmFyIEdyb3VwZWRCYXJMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cGVkQmFyTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR3JvdXBlZEJhckxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdncm91cGVkQmFyJztcbiAgICAgICAgX3RoaXMuYmFzZVR5cGUgPSAnYmFyJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBHcm91cGVkQmFyTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdyaWdodCcsXG4gICAgICAgICAgICAgICAgYWRqdXN0Q29sb3I6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ3JpZ2h0LXRvcCcsXG4gICAgICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgR3JvdXBlZEJhckxheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICB2YXIgbmFtZXMgPSB1dGlsXzEudmFsdWVzT2ZLZXkodGhpcy5vcHRpb25zLmRhdGEsIHRoaXMub3B0aW9ucy5ncm91cEZpZWxkKSB8fCBbXTtcbiAgICAgICAgdGhpcy52aWV3Lm9uKCd0b29sdGlwOmNoYW5nZScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB2YXIgX2EgPSBlLml0ZW1zLCBpdGVtcyA9IF9hID09PSB2b2lkIDAgPyBbXSA6IF9hO1xuICAgICAgICAgICAgdmFyIGZpeGVkSXRlbXMgPSB1dGlsXzEuc29ydEJ5KGl0ZW1zLnNsaWNlKCksIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzLmluZGV4T2YoaXRlbS5uYW1lKTtcbiAgICAgICAgICAgIH0pLnJldmVyc2UoKTtcbiAgICAgICAgICAgIGZpeGVkSXRlbXMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaWR4KSB7XG4gICAgICAgICAgICAgICAgZS5pdGVtc1tpZHhdID0gaXRlbTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEdyb3VwZWRCYXJMYXllci5wcm90b3R5cGUuZ2V0Q29sb3JTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdyb3VwRmllbGQgPSB0aGlzLm9wdGlvbnMuZ3JvdXBGaWVsZDtcbiAgICAgICAgaWYgKGdyb3VwRmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKGdyb3VwRmllbGQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBHcm91cGVkQmFyTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZGVmYXVsdE1ldGEgPSB7fTtcbiAgICAgICAgZGVmYXVsdE1ldGFbdGhpcy5vcHRpb25zLmdyb3VwRmllbGRdID0ge1xuICAgICAgICAgICAgdmFsdWVzOiB1dGlsXzEudmFsdWVzT2ZLZXkodGhpcy5vcHRpb25zLmRhdGEsIHRoaXMub3B0aW9ucy5ncm91cEZpZWxkKSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubWV0YSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLm1ldGEgPSBkZWZhdWx0TWV0YTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5tZXRhID0gdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMub3B0aW9ucy5tZXRhLCBkZWZhdWx0TWV0YSk7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5zY2FsZS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgR3JvdXBlZEJhckxheWVyLnByb3RvdHlwZS5hZGp1c3RCYXIgPSBmdW5jdGlvbiAoYmFyKSB7XG4gICAgICAgIGJhci5hZGp1c3QgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2RvZGdlJyxcbiAgICAgICAgICAgICAgICBtYXJnaW5SYXRpbzogMC4xLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIEdyb3VwZWRCYXJMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmJhci50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLmJhci50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLmJhci50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJhci50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMueEZpZWxkLCB0aGlzLm9wdGlvbnMueUZpZWxkLCB0aGlzLm9wdGlvbnMuZ3JvdXBGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBHcm91cGVkQmFyTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JvdXBlZEJhckxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZ3JvdXBlZEJhcicsIEdyb3VwZWRCYXJMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIHRoZW1lXzIgPSByZXF1aXJlKFwiLi4vYmFyL3RoZW1lXCIpO1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdncm91cGVkQmFyJywgdGhlbWVfMi5ERUZBVUxUX0JBUl9USEVNRSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgR3JvdXBlZENvbHVtbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cGVkQ29sdW1uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEdyb3VwZWRDb2x1bW4oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgR3JvdXBlZENvbHVtbi5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2dyb3VwZWRDb2x1bW4nO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgR3JvdXBlZENvbHVtbi5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gR3JvdXBlZENvbHVtbjtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdyb3VwZWRDb2x1bW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vY29sdW1uL2xheWVyXCIpKTtcbnJlcXVpcmUoXCIuL3RoZW1lXCIpO1xudmFyIEdyb3VwZWRDb2x1bW5MYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhHcm91cGVkQ29sdW1uTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR3JvdXBlZENvbHVtbkxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuYmFzZVR5cGUgPSAnY29sdW1uJztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdncm91cGVkQ29sdW1uJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBHcm91cGVkQ29sdW1uTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBHcm91cGVkQ29sdW1uTGF5ZXIucHJvdG90eXBlLmdldFJlc3BvbnNpdmVUaGVtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGhlbWVDb250cm9sbGVyLmdldFJlc3BvbnNpdmVUaGVtZSgnY29sdW1uJyk7XG4gICAgfTtcbiAgICBHcm91cGVkQ29sdW1uTGF5ZXIucHJvdG90eXBlLmdldENvbG9yU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cEZpZWxkID0gdGhpcy5vcHRpb25zLmdyb3VwRmllbGQ7XG4gICAgICAgIGlmIChncm91cEZpZWxkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZChncm91cEZpZWxkKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgR3JvdXBlZENvbHVtbkxheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgR3JvdXBlZENvbHVtbkxheWVyLnByb3RvdHlwZS5hZGp1c3RDb2x1bW4gPSBmdW5jdGlvbiAoY29sdW1uKSB7XG4gICAgICAgIGNvbHVtbi5hZGp1c3QgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2RvZGdlJyxcbiAgICAgICAgICAgICAgICBtYXJnaW5SYXRpbzogMC4xLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIEdyb3VwZWRDb2x1bW5MYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMueEZpZWxkLCB0aGlzLm9wdGlvbnMueUZpZWxkLCB0aGlzLm9wdGlvbnMuZ3JvdXBGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBHcm91cGVkQ29sdW1uTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gR3JvdXBlZENvbHVtbkxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnZ3JvdXBlZENvbHVtbicsIEdyb3VwZWRDb2x1bW5MYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIHRoZW1lXzIgPSByZXF1aXJlKFwiLi4vY29sdW1uL3RoZW1lXCIpO1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdncm91cGVkQ29sdW1uJywgdGhlbWVfMi5ERUZBVUxUX0NPTFVNTl9USEVNRSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgR3JvdXBlZFJvc2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoR3JvdXBlZFJvc2UsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR3JvdXBlZFJvc2UoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgR3JvdXBlZFJvc2UucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdncm91cGVkUm9zZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBHcm91cGVkUm9zZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gR3JvdXBlZFJvc2U7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBHcm91cGVkUm9zZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9yb3NlL2xheWVyXCIpKTtcbnZhciBHcm91cGVkUm9zZUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEdyb3VwZWRSb3NlTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gR3JvdXBlZFJvc2VMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnZ3JvdXBlZFJvc2UnO1xuICAgICAgICBfdGhpcy5iYXNlVHlwZSA9ICdyb3NlJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBHcm91cGVkUm9zZUxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICB4QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhbGlnblRpY2s6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLjUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IDUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBHcm91cGVkUm9zZUxheWVyLnByb3RvdHlwZS5nZXRDb2xvclNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ3JvdXBGaWVsZCA9IHRoaXMub3B0aW9ucy5ncm91cEZpZWxkO1xuICAgICAgICBpZiAoZ3JvdXBGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoZ3JvdXBGaWVsZCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEdyb3VwZWRSb3NlTGF5ZXIucHJvdG90eXBlLmFkanVzdFJvc2VBZGp1c3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2RvZGdlJyxcbiAgICAgICAgICAgICAgICBtYXJnaW5SYXRpbzogMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgfTtcbiAgICBHcm91cGVkUm9zZUxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucm9zZS50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLnJvc2UudG9vbHRpcC5maWVsZHMgPSB0b29sdGlwT3B0aW9ucy5maWVsZHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcikge1xuICAgICAgICAgICAgdGhpcy5yb3NlLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAoIXRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIHRoaXMucm9zZS50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMucmFkaXVzRmllbGQsIHRoaXMub3B0aW9ucy5jYXRlZ29yeUZpZWxkLCB0aGlzLm9wdGlvbnMuZ3JvdXBGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBHcm91cGVkUm9zZUxheWVyO1xufShsYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEdyb3VwZWRSb3NlTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdncm91cGVkUm9zZScsIEdyb3VwZWRSb3NlTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFBsb3RDb21wb25lbnRzID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xhYmVsXCIpKTtcbnZhciBsZWdlbmRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xlZ2VuZFwiKSk7XG52YXIgQ29tcG9uZW50c0luZm8gPSB7XG4gICAgbGFiZWw6IHsgQ3RyOiBsYWJlbF8xLmRlZmF1bHQgfSxcbiAgICBsZWdlbmQ6IHsgQ3RyOiBsZWdlbmRfMS5kZWZhdWx0LCBwYWRkaW5nOiAnb3V0ZXInIH0sXG59O1xuZnVuY3Rpb24gZ2V0UGxvdENvbXBvbmVudHMocGxvdCwgdHlwZSwgY2ZnKSB7XG4gICAgaWYgKHBsb3Qub3B0aW9uc1t0eXBlXSAmJiBwbG90Lm9wdGlvbnNbdHlwZV0udmlzaWJsZSkge1xuICAgICAgICB2YXIgY29tcG9uZW50SW5mbyA9IENvbXBvbmVudHNJbmZvW3R5cGVdO1xuICAgICAgICB2YXIgY29tcG9uZW50ID0gbmV3IGNvbXBvbmVudEluZm8uQ3RyKGNmZyk7XG4gICAgICAgIGlmIChjb21wb25lbnRJbmZvLnBhZGRpbmcpIHtcbiAgICAgICAgICAgIHBsb3QucGFkZGluZ0NvbnRyb2xsZXIucmVnaXN0ZXJQYWRkaW5nKGNvbXBvbmVudCwgY29tcG9uZW50SW5mby5wYWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tcG9uZW50O1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0UGxvdENvbXBvbmVudHMgPSBnZXRQbG90Q29tcG9uZW50cztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbG9yXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9jb2xvclwiKTtcbnZhciBNYXRyaXhMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNYXRyaXhMYWJlbChjZmcpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52aWV3ID0gY2ZnLnZpZXc7XG4gICAgICAgIHRoaXMucGxvdCA9IGNmZy5wbG90O1xuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmdldERlZmF1bHRPcHRpb25zKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KGRlZmF1bHRPcHRpb25zLCBjZmcsIHt9KTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIE1hdHJpeExhYmVsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmxhYmVsc0NvbnRhaW5lcjtcbiAgICAgICAgdGhpcy52aWV3Lm9uKCdiZWZvcmVyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5jbGVhcigpO1xuICAgICAgICAgICAgX3RoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIE1hdHJpeExhYmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmVsZW1lbnRzO1xuICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlID0gZWxlLnNoYXBlO1xuICAgICAgICAgICAgdmFyIF9hID0gX3RoaXMub3B0aW9ucywgc3R5bGUgPSBfYS5zdHlsZSwgb2Zmc2V0WCA9IF9hLm9mZnNldFgsIG9mZnNldFkgPSBfYS5vZmZzZXRZO1xuICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IF90aGlzLm9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIoX3RoaXMuZ2V0Q29udGVudChzaGFwZSkpIDogX3RoaXMuZ2V0Q29udGVudChzaGFwZSk7XG4gICAgICAgICAgICB2YXIgcG9zaXRpb24gPSBfdGhpcy5nZXRQb3NpdGlvbihzaGFwZSk7XG4gICAgICAgICAgICB2YXIgY29sb3IgPSBfdGhpcy5nZXRUZXh0Q29sb3Ioc2hhcGUpO1xuICAgICAgICAgICAgdmFyIGxhYmVsID0gX3RoaXMuY29udGFpbmVyLmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEuZGVlcE1peCh7fSwgc3R5bGUsIHtcbiAgICAgICAgICAgICAgICAgICAgeDogcG9zaXRpb24ueCArIG9mZnNldFgsXG4gICAgICAgICAgICAgICAgICAgIHk6IHBvc2l0aW9uLnkgKyBvZmZzZXRZLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBjb250ZW50LFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBuYW1lOiAnbGFiZWwnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5hZGp1c3RQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIF90aGlzLmFkanVzdExhYmVsKGxhYmVsLCBzaGFwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgTWF0cml4TGFiZWwucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIE1hdHJpeExhYmVsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgTWF0cml4TGFiZWwucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnNldCgndmlzaWJsZScsIHRydWUpO1xuICAgICAgICB0aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIE1hdHJpeExhYmVsLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9O1xuICAgIE1hdHJpeExhYmVsLnByb3RvdHlwZS5nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXIuZ2V0QkJveCgpO1xuICAgIH07XG4gICAgTWF0cml4TGFiZWwucHJvdG90eXBlLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnBsb3QudGhlbWU7XG4gICAgICAgIHZhciBsYWJlbFN0eWxlID0gdGhlbWUubGFiZWwuc3R5bGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvZmZzZXRYOiAwLFxuICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIHN0eWxlOiB1dGlsXzEuY2xvbmUobGFiZWxTdHlsZSksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBNYXRyaXhMYWJlbC5wcm90b3R5cGUuZ2V0Q29udGVudCA9IGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICB2YXIgZGF0YSA9IHNoYXBlLmdldCgnb3JpZ2luJykuZGF0YTtcbiAgICAgICAgdmFyIGZpZWxkID0gdGhpcy5wbG90Lm9wdGlvbnMuY29sb3JGaWVsZDtcbiAgICAgICAgcmV0dXJuIGRhdGFbZmllbGRdO1xuICAgIH07XG4gICAgTWF0cml4TGFiZWwucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogYmJveC5taW5YICsgYmJveC53aWR0aCAvIDIsXG4gICAgICAgICAgICB5OiBiYm94Lm1pblkgKyBiYm94LmhlaWdodCAvIDIsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBNYXRyaXhMYWJlbC5wcm90b3R5cGUuZ2V0VGV4dENvbG9yID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWRqdXN0Q29sb3IpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZUNvbG9yID0gc2hhcGUuYXR0cignZmlsbCcpO1xuICAgICAgICAgICAgdmFyIHNoYXBlT3BhY2l0eSA9IHNoYXBlLmF0dHIoJ29wYWNpdHknKSA/IHNoYXBlLmF0dHIoJ29wYWNpdHknKSA6IDE7XG4gICAgICAgICAgICB2YXIgcmdiID0gY29sb3JfMS5yZ2IyYXJyKHNoYXBlQ29sb3IpO1xuICAgICAgICAgICAgdmFyIGdyYXkgPSBNYXRoLnJvdW5kKHJnYlswXSAqIDAuMjk5ICsgcmdiWzFdICogMC41ODcgKyByZ2JbMl0gKiAwLjExNCkgLyBzaGFwZU9wYWNpdHk7XG4gICAgICAgICAgICB2YXIgY29sb3JCYW5kID0gW1xuICAgICAgICAgICAgICAgIHsgZnJvbTogMCwgdG86IDg1LCBjb2xvcjogJ3doaXRlJyB9LFxuICAgICAgICAgICAgICAgIHsgZnJvbTogODUsIHRvOiAxNzAsIGNvbG9yOiAnI0Y2RjZGNicgfSxcbiAgICAgICAgICAgICAgICB7IGZyb206IDE3MCwgdG86IDI1NSwgY29sb3I6ICdibGFjaycgfSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICB2YXIgcmVmbGVjdCA9IGNvbG9yXzEubWFwcGluZ0NvbG9yKGNvbG9yQmFuZCwgZ3JheSk7XG4gICAgICAgICAgICByZXR1cm4gcmVmbGVjdDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVmYXVsdENvbG9yID0gdGhpcy5vcHRpb25zLnN0eWxlLmZpbGw7XG4gICAgICAgIHJldHVybiBkZWZhdWx0Q29sb3I7XG4gICAgfTtcbiAgICBNYXRyaXhMYWJlbC5wcm90b3R5cGUuYWRqdXN0TGFiZWwgPSBmdW5jdGlvbiAobGFiZWwsIHNoYXBlKSB7XG4gICAgICAgIHZhciBsYWJlbFJhbmdlID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgc2hhcGVSYW5nZSA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgaWYgKGxhYmVsUmFuZ2Uud2lkdGggPiBzaGFwZVJhbmdlLndpZHRoIHx8IGxhYmVsUmFuZ2UuaGVpZ2h0ID4gc2hhcGVSYW5nZS5oZWlnaHQpIHtcbiAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3RleHQnLCAnJyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNYXRyaXhMYWJlbDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBNYXRyaXhMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgTEFCRUxfTUFSR0lOID0gNDtcbnZhciBNYXRyaXhMZWdlbmQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWF0cml4TGVnZW5kKGNmZykge1xuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRhdGFTbGlkZXMgPSB7fTtcbiAgICAgICAgdGhpcy5pbnRlcmFjdGl2ZUV2ZW50cyA9IHt9O1xuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmdldERlZmF1bHRPcHRpb25zKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBkZWZhdWx0T3B0aW9ucywgY2ZnKTtcbiAgICAgICAgdGhpcy52aWV3ID0gdGhpcy5vcHRpb25zLnZpZXc7XG4gICAgICAgIHRoaXMuYWZ0ZXJSZW5kZXIgPSB0cnVlO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmxheW91dCA9IHRoaXMuZ2V0TGF5b3V0KCk7XG4gICAgICAgIHRoaXMud2lkdGggPSB0aGlzLm9wdGlvbnMud2lkdGggPyB0aGlzLm9wdGlvbnMud2lkdGggOiB0aGlzLmdldERlZmF1bHRXaWR0aCgpO1xuICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQgPyB0aGlzLm9wdGlvbnMuaGVpZ2h0IDogdGhpcy5nZXREZWZhdWx0SGVpZ2h0KCk7XG4gICAgICAgIHZhciBwbG90Q29udGFpbmVyID0gdGhpcy5vcHRpb25zLnBsb3QuY29udGFpbmVyO1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gcGxvdENvbnRhaW5lci5hZGRHcm91cCgpO1xuICAgICAgICB0aGlzLnZpZXcub24oJ2JlZm9yZXJlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmNsZWFyKCk7XG4gICAgICAgICAgICBfdGhpcy5vcHRpb25zLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBNYXRyaXhMZWdlbmQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNjYWxlcyA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLnNjYWxlcztcbiAgICAgICAgdmFyIGNvbG9yRmllbGQgPSB0aGlzLm9wdGlvbnMucGxvdC5vcHRpb25zLmNvbG9yRmllbGQ7XG4gICAgICAgIHRoaXMuY29sb3JTY2FsZSA9IHNjYWxlc1tjb2xvckZpZWxkXTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb2xvclNjYWxlLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heDtcbiAgICAgICAgdmFyIGNvbG9yID0gdGhpcy5vcHRpb25zLnBsb3Qub3B0aW9ucy5jb2xvcjtcbiAgICAgICAgaWYgKHRoaXMubGF5b3V0ID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVySG9yaXpvbnRhbChtaW4sIG1heCwgY29sb3IpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJWZXJ0aWNhbChtaW4sIG1heCwgY29sb3IpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGVnZW5kTGF5b3V0KCk7XG4gICAgICAgIHRoaXMuYWRkSW50ZXJhY3Rpb24oKTtcbiAgICB9O1xuICAgIE1hdHJpeExlZ2VuZC5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICB0aGlzLm9wdGlvbnMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIE1hdHJpeExlZ2VuZC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2ZmRXZlbnQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb3JpZ2luX2Jib3ggPSB0aGlzLmNvbnRhaW5lci5nZXRCQm94KCk7XG4gICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQodGhpcy54LCB0aGlzLnksIG9yaWdpbl9iYm94LndpZHRoLCBvcmlnaW5fYmJveC5oZWlnaHQpO1xuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5yZW5kZXJWZXJ0aWNhbCA9IGZ1bmN0aW9uIChtaW4sIG1heCwgY29sb3JzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB2YWx1ZVN0ZXAgPSAobWF4IC0gbWluKSAvIChjb2xvcnMubGVuZ3RoIC0gMSk7XG4gICAgICAgIHZhciBjb2xvclN0ZXAgPSAxIC8gKGNvbG9ycy5sZW5ndGggLSAxKTtcbiAgICAgICAgdmFyIHRpY2tTdGVwID0gdGhpcy5oZWlnaHQgLyAoY29sb3JzLmxlbmd0aCAtIDEpO1xuICAgICAgICB2YXIgZ3JhZGllbnRDb2xvciA9ICdsKDkwKSc7XG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbG9ycywgZnVuY3Rpb24gKGMsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc3RlcE51bSA9IGNvbG9yU3RlcCAqIGluZGV4O1xuICAgICAgICAgICAgZ3JhZGllbnRDb2xvciArPSBzdGVwTnVtICsgXCI6XCIgKyBjICsgXCIgXCI7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQsXG4gICAgICAgICAgICAgICAgZmlsbDogZ3JhZGllbnRDb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuYW1lOiAnbGVnZW5kJyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGRyYXcgdGljayBhbmQgbGFiZWxcbiAgICAgICAgdXRpbF8xLmVhY2goY29sb3JzLCBmdW5jdGlvbiAoYywgaW5kZXgpIHtcbiAgICAgICAgICAgIC8vIHRpY2tcbiAgICAgICAgICAgIHZhciBzdGVwID0gdGlja1N0ZXAgKiBpbmRleDtcbiAgICAgICAgICAgIF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTScsIDAsIHN0ZXBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgWydMJywgX3RoaXMud2lkdGgsIHN0ZXBdLFxuICAgICAgICAgICAgICAgICAgICBdIH0sIF90aGlzLm9wdGlvbnMudGlja2xpbmVTdHlsZSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHZhbHVlXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBNYXRoLnJvdW5kKHZhbHVlU3RlcCAqIGluZGV4KTtcbiAgICAgICAgICAgIF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHRleHQ6IHZhbHVlLCB0ZXh0QWxpZ246ICdsZWZ0JywgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJywgeDogX3RoaXMud2lkdGggKyBMQUJFTF9NQVJHSU4sIHk6IHN0ZXAgfSwgX3RoaXMub3B0aW9ucy50ZXh0LnN0eWxlKSxcbiAgICAgICAgICAgICAgICBuYW1lOiAnbGVnZW5kLWxhYmVsJyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy9hbmNob3JcbiAgICAgICAgdmFyIHRyaV93aWR0aCA9IDEwO1xuICAgICAgICB2YXIgdHJpX2hlaWdodCA9IDE0O1xuICAgICAgICB2YXIgdHJpX3BhdGggPSBbWydNJywgLXRyaV93aWR0aCwgLXRyaV9oZWlnaHQgLyAyXSwgWydMJywgMCwgMF0sIFsnTCcsIC10cmlfd2lkdGgsIHRyaV9oZWlnaHQgLyAyXSwgWydaJ11dO1xuICAgICAgICB0aGlzLmFuY2hvciA9IHRoaXMuY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBwYXRoOiB0cmlfcGF0aCB9LCB0aGlzLm9wdGlvbnMuYW5jaG9yU3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hbmNob3Iuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5yZW5kZXJIb3Jpem9udGFsID0gZnVuY3Rpb24gKG1pbiwgbWF4LCBjb2xvcnMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHZhbHVlU3RlcCA9IChtYXggLSBtaW4pIC8gKGNvbG9ycy5sZW5ndGggLSAxKTtcbiAgICAgICAgdmFyIGNvbG9yU3RlcCA9IDEgLyAoY29sb3JzLmxlbmd0aCAtIDEpO1xuICAgICAgICB2YXIgdGlja1N0ZXAgPSB0aGlzLndpZHRoIC8gKGNvbG9ycy5sZW5ndGggLSAxKTtcbiAgICAgICAgdmFyIGdyYWRpZW50Q29sb3IgPSAnbCgwKSc7XG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbG9ycywgZnVuY3Rpb24gKGMsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc3RlcE51bSA9IGNvbG9yU3RlcCAqIGluZGV4O1xuICAgICAgICAgICAgZ3JhZGllbnRDb2xvciArPSBzdGVwTnVtICsgXCI6XCIgKyBjICsgXCIgXCI7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncmVjdCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQsXG4gICAgICAgICAgICAgICAgZmlsbDogZ3JhZGllbnRDb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuYW1lOiAnbGVnZW5kJyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGRyYXcgdGljayBhbmQgbGFiZWxcbiAgICAgICAgdXRpbF8xLmVhY2goY29sb3JzLCBmdW5jdGlvbiAoYywgaW5kZXgpIHtcbiAgICAgICAgICAgIC8vIHRpY2tcbiAgICAgICAgICAgIHZhciBzdGVwID0gdGlja1N0ZXAgKiBpbmRleDtcbiAgICAgICAgICAgIF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTScsIHN0ZXAsIDBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgWydMJywgc3RlcCwgX3RoaXMuaGVpZ2h0XSxcbiAgICAgICAgICAgICAgICAgICAgXSB9LCBfdGhpcy5vcHRpb25zLnRpY2tsaW5lU3R5bGUpLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdsZWdlbmQtbGFiZWwnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyB2YWx1ZVxuICAgICAgICAgICAgdmFyIHZhbHVlID0gTWF0aC5yb3VuZCh2YWx1ZVN0ZXAgKiBpbmRleCk7XG4gICAgICAgICAgICBfdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB0ZXh0OiB2YWx1ZSwgdGV4dEFsaWduOiAnY2VudGVyJywgdGV4dEJhc2VsaW5lOiAndG9wJywgeDogc3RlcCwgeTogX3RoaXMuaGVpZ2h0ICsgTEFCRUxfTUFSR0lOIH0sIF90aGlzLm9wdGlvbnMudGV4dC5zdHlsZSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vYW5jaG9yXG4gICAgICAgIHZhciB0cmlfd2lkdGggPSAxNDtcbiAgICAgICAgdmFyIHRyaV9oZWlnaHQgPSAxMDtcbiAgICAgICAgdmFyIHRyaV9wYXRoID0gW1snTScsIDAsIDBdLCBbJ0wnLCAtdHJpX3dpZHRoIC8gMiwgLXRyaV9oZWlnaHRdLCBbJ0wnLCB0cmlfd2lkdGggLyAyLCAtdHJpX2hlaWdodF0sIFsnWiddXTtcbiAgICAgICAgdGhpcy5hbmNob3IgPSB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgcGF0aDogdHJpX3BhdGggfSwgdGhpcy5vcHRpb25zLmFuY2hvclN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYW5jaG9yLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICB9O1xuICAgIE1hdHJpeExlZ2VuZC5wcm90b3R5cGUuZ2V0TGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9zaXRpb25zID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uLnNwbGl0KCctJyk7XG4gICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbnNbMF07XG4gICAgICAgIGlmIChwb3NpdGlvbnNbMF0gPT09ICdsZWZ0JyB8fCBwb3NpdGlvbnNbMF0gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHJldHVybiAndmVydGljYWwnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnaG9yaXpvbnRhbCc7XG4gICAgfTtcbiAgICBNYXRyaXhMZWdlbmQucHJvdG90eXBlLmdldERlZmF1bHRXaWR0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMubGF5b3V0ID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IHRoaXMudmlldy5jb29yZGluYXRlQkJveC53aWR0aDtcbiAgICAgICAgICAgIHJldHVybiB3aWR0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMTA7XG4gICAgfTtcbiAgICBNYXRyaXhMZWdlbmQucHJvdG90eXBlLmdldERlZmF1bHRIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmxheW91dCA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgICAgdmFyIGhlaWdodCA9IHRoaXMudmlldy5jb29yZGluYXRlQkJveC5oZWlnaHQ7XG4gICAgICAgICAgICByZXR1cm4gaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAxMDtcbiAgICB9O1xuICAgIE1hdHJpeExlZ2VuZC5wcm90b3R5cGUubGVnZW5kTGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgcGFuZWxSYW5nZSA9IHRoaXMudmlldy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgdmFyIGJsZWVkaW5nID0gdGhpcy5vcHRpb25zLnBsb3QuZ2V0UGxvdFRoZW1lKCkuYmxlZWRpbmc7XG4gICAgICAgIGlmICh1dGlsXzEuaXNBcnJheShibGVlZGluZykpIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGJsZWVkaW5nLCBmdW5jdGlvbiAoaXQsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBibGVlZGluZ1tpbmRleF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgYmxlZWRpbmdbaW5kZXhdID0gYmxlZWRpbmdbaW5kZXhdKF90aGlzLm9wdGlvbnMucGxvdC5vcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYmJveCA9IHRoaXMuY29udGFpbmVyLmdldEJCb3goKTtcbiAgICAgICAgdmFyIHggPSAwO1xuICAgICAgICB2YXIgeSA9IDA7XG4gICAgICAgIHZhciBwb3NpdGlvbnMgPSB0aGlzLm9wdGlvbnMucG9zaXRpb24uc3BsaXQoJy0nKTtcbiAgICAgICAgdmFyIHBsb3RXaWR0aCA9IHRoaXMub3B0aW9ucy5wbG90LndpZHRoO1xuICAgICAgICB2YXIgcGxvdEhlaWdodCA9IHRoaXMub3B0aW9ucy5wbG90LmhlaWdodDtcbiAgICAgICAgLy8g5YWI56Gu5a6aeFxuICAgICAgICBpZiAocG9zaXRpb25zWzBdID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIHggPSBibGVlZGluZ1szXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbnNbMF0gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHggPSBwbG90V2lkdGggLSBibGVlZGluZ1sxXSAtIGJib3gud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocG9zaXRpb25zWzFdID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgLy8gZGVmYXVsdFxuICAgICAgICAgICAgaWYgKHRoaXMud2lkdGggPT09IHBhbmVsUmFuZ2Uud2lkdGgpIHtcbiAgICAgICAgICAgICAgICB4ID0gcGFuZWxSYW5nZS54O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgeCA9IChwbG90V2lkdGggLSBiYm94LndpZHRoKSAvIDI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocG9zaXRpb25zWzFdID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIHggPSBibGVlZGluZ1szXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbnNbMV0gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHggPSB0aGlzLm9wdGlvbnMucGxvdC53aWR0aCAtIGJsZWVkaW5nWzFdIC0gYmJveC53aWR0aDtcbiAgICAgICAgfVxuICAgICAgICAvLyDlho3noa7lrpp5XG4gICAgICAgIGlmIChwb3NpdGlvbnNbMF0gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICB5ID0gcGxvdEhlaWdodCAtIGJsZWVkaW5nWzJdIC0gYmJveC5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocG9zaXRpb25zWzBdID09PSAndG9wJykge1xuICAgICAgICAgICAgeSA9IHRoaXMuZ2V0VG9wUG9zaXRpb24oYmxlZWRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uc1sxXSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIC8vIGRlZmF1bHRcbiAgICAgICAgICAgIGlmICh0aGlzLmhlaWdodCA9PT0gcGFuZWxSYW5nZS5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICB5ID0gcGFuZWxSYW5nZS55O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy/nlKjmiLfoh6rooYzorr7lrppcbiAgICAgICAgICAgICAgICB5ID0gKHBsb3RIZWlnaHQgLSBiYm94LmhlaWdodCkgLyAyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uc1sxXSA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgIHkgPSBibGVlZGluZ1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwb3NpdGlvbnNbMV0gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICB5ID0gcGxvdEhlaWdodCAtIGJsZWVkaW5nWzJdIC0gYmJveC5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54ID0geDtcbiAgICAgICAgdGhpcy55ID0geTtcbiAgICAgICAgdGhpcy5jb250YWluZXIudHJhbnNsYXRlKHgsIHkpO1xuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRleHQ6IHtcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICdyZ2JhKDAsIDAsIDAsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpY2tsaW5lU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgwLCAwLCAwLCAwLjgpJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhbmNob3JTdHlsZToge1xuICAgICAgICAgICAgICAgIGZpbGw6ICdyZ2JhKDAsMCwwLDAuNSknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyaWdnZXJPbjogJ21vdXNlbW92ZScsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBNYXRyaXhMZWdlbmQucHJvdG90eXBlLmFkZEludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZ2VvbVR5cGU7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucGxvdC5vcHRpb25zLnNoYXBlVHlwZSA9PT0gJ3JlY3QnKSB7XG4gICAgICAgICAgICBnZW9tVHlwZSA9ICdwb2x5Z29uJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdlb21UeXBlID0gJ3BvaW50JztcbiAgICAgICAgfVxuICAgICAgICB2YXIgZXZlbnROYW1lID0gZ2VvbVR5cGUgKyBcIjpcIiArIHRoaXMub3B0aW9ucy50cmlnZ2VyT247XG4gICAgICAgIC8vY29uc3QgbGFiZWxFdmVudE5hbWUgPSBgbGFiZWw6JHt0aGlzLm9wdGlvbnMudHJpZ2dlck9ufWA7XG4gICAgICAgIHZhciBmaWVsZCA9IHRoaXMub3B0aW9ucy5wbG90Lm9wdGlvbnMuY29sb3JGaWVsZDtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5jb2xvclNjYWxlLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heDtcbiAgICAgICAgdmFyIGdlb21FdmVudEhhbmRsZXIgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGV2LmRhdGEuZGF0YVtmaWVsZF07XG4gICAgICAgICAgICB2YXIgcmF0aW8gPSAodmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gICAgICAgICAgICBfdGhpcy5tb3ZlQW5jaG9yKHJhdGlvKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy52aWV3Lm9uKGV2ZW50TmFtZSwgZ2VvbUV2ZW50SGFuZGxlcik7XG4gICAgICAgIHRoaXMuaW50ZXJhY3RpdmVFdmVudHNbZXZlbnROYW1lXSA9IHtcbiAgICAgICAgICAgIHRhcmdldDogdGhpcy52aWV3LFxuICAgICAgICAgICAgaGFuZGxlcjogZ2VvbUV2ZW50SGFuZGxlcixcbiAgICAgICAgfTtcbiAgICAgICAgLyp0aGlzLnZpZXcub24obGFiZWxFdmVudE5hbWUsIChldikgPT4ge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXYuZGF0YVtmaWVsZF07XG4gICAgICAgICAgY29uc3QgcmF0aW8gPSAodmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gICAgICAgICAgdGhpcy5tb3ZlQW5jaG9yKHJhdGlvKTtcbiAgICAgICAgfSk7Ki9cbiAgICAgICAgdmFyIG1vdXNlbGVhdmVIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuYW5jaG9yLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnBsb3QuY2FudmFzLm9uKCdtb3VzZWxlYXZlJywgbW91c2VsZWF2ZUhhbmRsZXIpO1xuICAgICAgICB0aGlzLmludGVyYWN0aXZlRXZlbnRzLm1vdXNlbGVhdmUgPSB7XG4gICAgICAgICAgICB0YXJnZXQ6IHRoaXMub3B0aW9ucy5wbG90LmNhbnZhcyxcbiAgICAgICAgICAgIGhhbmRsZXI6IG1vdXNlbGVhdmVIYW5kbGVyLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgTWF0cml4TGVnZW5kLnByb3RvdHlwZS5tb3ZlQW5jaG9yID0gZnVuY3Rpb24gKHJhdGlvKSB7XG4gICAgICAgIHRoaXMuYW5jaG9yLnNldCgndmlzaWJsZScsIHRydWUpO1xuICAgICAgICBpZiAodGhpcy5sYXlvdXQgPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmhlaWdodCAqIHJhdGlvO1xuICAgICAgICAgICAgdmFyIHVsTWF0cml4ID0gWzEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDFdO1xuICAgICAgICAgICAgdWxNYXRyaXhbN10gPSBwb3M7XG4gICAgICAgICAgICB0aGlzLmFuY2hvci5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5hbmNob3IuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgbWF0cml4OiB1bE1hdHJpeCxcbiAgICAgICAgICAgIH0sIDQwMCwgJ2Vhc2VMaW5lYXInKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLndpZHRoICogcmF0aW87XG4gICAgICAgICAgICB2YXIgdWxNYXRyaXggPSBbMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMV07XG4gICAgICAgICAgICB1bE1hdHJpeFs2XSA9IHBvcztcbiAgICAgICAgICAgIHRoaXMuYW5jaG9yLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICB0aGlzLmFuY2hvci5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICBtYXRyaXg6IHVsTWF0cml4LFxuICAgICAgICAgICAgfSwgNDAwLCAnZWFzZUxpbmVhcicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNYXRyaXhMZWdlbmQucHJvdG90eXBlLmdldFRvcFBvc2l0aW9uID0gZnVuY3Rpb24gKGJsZWVkaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucGxvdC5kZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgdmFyIGJib3ggPSB0aGlzLm9wdGlvbnMucGxvdC5kZXNjcmlwdGlvbi5nZXRCQm94KCk7XG4gICAgICAgICAgICByZXR1cm4gYmJveC5tYXhZICsgMTA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5vcHRpb25zLnBsb3QudGl0bGUpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gdGhpcy5vcHRpb25zLnBsb3QudGl0bGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgcmV0dXJuIGJib3gubWF4WSArIDEwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBibGVlZGluZ1swXTtcbiAgICB9O1xuICAgIE1hdHJpeExlZ2VuZC5wcm90b3R5cGUub2ZmRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuaW50ZXJhY3RpdmVFdmVudHMsIGZ1bmN0aW9uIChldmVudCwga2V5KSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0LCBoYW5kbGVyID0gZXZlbnQuaGFuZGxlcjtcbiAgICAgICAgICAgIHRhcmdldC5vZmYoa2V5LCBoYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gTWF0cml4TGVnZW5kO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1hdHJpeExlZ2VuZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxlZ2VuZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgSGVhdG1hcCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhIZWF0bWFwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEhlYXRtYXAoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2hlYXRtYXAnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuY2hhbmdlU2hhcGUgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgbGF5ZXIuY2hhbmdlU2hhcGUodHlwZSk7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5tYXBwaW5nU2l6ZSA9IGZ1bmN0aW9uIChmaWVsZCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgbGF5ZXIubWFwcGluZ1NpemUoZmllbGQpO1xuICAgIH07XG4gICAgSGVhdG1hcC5wcm90b3R5cGUuZGlzYWJsZU1hcHBpbmdTaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgbGF5ZXIuZGlzYWJsZU1hcHBpbmdTaXplKCk7XG4gICAgfTtcbiAgICBIZWF0bWFwLnByb3RvdHlwZS5nZXRTaXplU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0U2l6ZVNjYWxlKCk7XG4gICAgfTtcbiAgICBIZWF0bWFwLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBIZWF0bWFwO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSGVhdG1hcDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCJAYW50di9zY2FsZVwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBzaGFwZV8xID0gcmVxdWlyZShcIi4vc2hhcGVcIik7XG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XG52YXIgSGVhdG1hcExheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEhlYXRtYXBMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIZWF0bWFwTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2hlYXRtYXAnO1xuICAgICAgICBfdGhpcy5ncmlkU2l6ZSA9IFtdO1xuICAgICAgICBfdGhpcy5wbG90Q29tcG9uZW50cyA9IFtdO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEhlYXRtYXBMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgc2hhcGVUeXBlOiAncmVjdCcsXG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAncmlnaHQtY2VudGVyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgc2hhcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzaG93Q3Jvc3NoYWlyczogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2hvd01hcmtlcnM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkQWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ3JpZEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xvcjogWycjOWFlM2Q1JywgJyM2NmNkYmInLCAnI2U3YTc0NCcsICcjZjFlMDY2JywgJyNmMjc2NjQnLCAnI2U3YzFhMiddLFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGFkanVzdENvbG9yOiB0cnVlLFxuICAgICAgICAgICAgICAgIGFkanVzdFBvc2l0aW9uOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDI1NSwyNTUsMjU1LDApJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW50ZXJhY3Rpb25zOiBbeyB0eXBlOiAndG9vbHRpcCcgfV0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgSGVhdG1hcExheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJQbG90Q29tcG9uZW50cygpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmNoYW5nZVNoYXBlID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaGFwZVR5cGUgPT09IHR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMuc2hhcGVUeXBlID0gdHlwZTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdyZWN0Jykge1xuICAgICAgICAgICAgdmFyIHNoYXBlcyA9IHRoaXMuZ2V0U2hhcGUoKTtcbiAgICAgICAgICAgIHRoaXMuY2lyY2xlVG9SZWN0KHNoYXBlcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2NpcmNsZScpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZXMgPSB0aGlzLmdldFNoYXBlKCk7XG4gICAgICAgICAgICB0aGlzLnJlY3RUb0NpcmNsZShzaGFwZXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLm1hcHBpbmdTaXplID0gZnVuY3Rpb24gKGZpZWxkKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2l6ZUZpZWxkICYmIHRoaXMub3B0aW9ucy5zaXplRmllbGQgPT09IGZpZWxkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zLnNpemVGaWVsZCA9IGZpZWxkO1xuICAgICAgICAvLyDliJvlu7pzY2FsZVxuICAgICAgICB2YXIgdmFsdWVzID0gdXRpbF8xLnZhbHVlc09mS2V5KHRoaXMub3B0aW9ucy5kYXRhLCBmaWVsZCk7XG4gICAgICAgIHZhciBtaW4gPSBNYXRoLm1pbi5hcHBseShNYXRoLCB2YWx1ZXMpO1xuICAgICAgICB2YXIgbWF4ID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgdmFsdWVzKTtcbiAgICAgICAgdmFyIExpbmVhclNjYWxlID0gc2NhbGVfMS5nZXRTY2FsZSgnbGluZWFyJyk7XG4gICAgICAgIHZhciBzY2FsZSA9IG5ldyBMaW5lYXJTY2FsZSh7XG4gICAgICAgICAgICBtaW46IG1pbixcbiAgICAgICAgICAgIG1heDogbWF4LFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHNoYXBlcyA9IHRoaXMuZ2V0U2hhcGUoKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaGFwZVR5cGUgPT09ICdyZWN0Jykge1xuICAgICAgICAgICAgdGhpcy5yZWN0U2l6ZU1hcHBpbmcoc2hhcGVzLCBzY2FsZSwgZmllbGQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMub3B0aW9ucy5zaGFwZVR5cGUgPT09ICdjaXJjbGUnKSB7XG4gICAgICAgICAgICB0aGlzLmNpcmNsZVNpemVNYXBwaW5nKHNoYXBlcywgc2NhbGUsIGZpZWxkKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgSGVhdG1hcExheWVyLnByb3RvdHlwZS5kaXNhYmxlTWFwcGluZ1NpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzaGFwZXMgPSB0aGlzLmdldFNoYXBlKCk7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hhcGVUeXBlID09PSAncmVjdCcpIHtcbiAgICAgICAgICAgIHRoaXMucmVjdERpc2FibGVTaXplTWFwcGluZyhzaGFwZXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMub3B0aW9ucy5zaGFwZVR5cGUgPT09ICdjaXJjbGUnKSB7XG4gICAgICAgICAgICB0aGlzLmNpcmNsZURpc2FibGVTaXplTWFwcGluZyhzaGFwZXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMucGxvdENvbXBvbmVudHMsIGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgIH0pO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUuZ2V0U2l6ZVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2l6ZUZpZWxkID0gdGhpcy5vcHRpb25zLnNpemVGaWVsZDtcbiAgICAgICAgaWYgKHNpemVGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZChzaXplRmllbGQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmxlZ2VuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2xlZ2VuZHMnLCBmYWxzZSk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmdyaWRTaXplID0gdGhpcy5nZXRHcmlkU2l6ZSgpO1xuICAgICAgICB2YXIgZ2VvbUNvbmZpZztcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaGFwZVR5cGUgPT09ICdyZWN0Jykge1xuICAgICAgICAgICAgZ2VvbUNvbmZpZyA9IHRoaXMuYWRkUmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGNpcmNsZSA9IHRoaXMuYWRkQ2lyY2xlKCk7XG4gICAgICAgICAgICBnZW9tQ29uZmlnID0gY2lyY2xlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hhcGVTdHlsZSkge1xuICAgICAgICAgICAgdmFyIHN0eWxlQ29uZmlnID0ge307XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24odGhpcy5vcHRpb25zLnNoYXBlU3R5bGUpKSB7XG4gICAgICAgICAgICAgICAgc3R5bGVDb25maWcuZmllbGRzID0gW1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuY29sb3JGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnhGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnlGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnNpemVGaWVsZCxcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIHN0eWxlQ29uZmlnLmNhbGxiYWNrID0gdGhpcy5vcHRpb25zLnNoYXBlU3R5bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNPYmplY3QodGhpcy5vcHRpb25zLnNoYXBlU3R5bGUpKSB7XG4gICAgICAgICAgICAgICAgc3R5bGVDb25maWcuY2ZnID0gdGhpcy5vcHRpb25zLnNoYXBlU3R5bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBnZW9tQ29uZmlnLnN0eWxlID0gc3R5bGVDb25maWc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50b29sdGlwICYmICh0aGlzLm9wdGlvbnMudG9vbHRpcC5maWVsZHMgfHwgdGhpcy5vcHRpb25zLnRvb2x0aXAuZm9ybWF0dGVyKSkge1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeVRvb2x0aXAoZ2VvbUNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5JywgZ2VvbUNvbmZpZyk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmFkZFJlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOWmguaenOeUqOaIt+iuvue9ruS6hnNpemXvvIzlsIZzaXpl5pWw5YC86L2s5o2i5Li6WzAsMV3ljLrpl7RcbiAgICAgICAgdmFyIHNpemUgPSBbMC4zLCAwLjldO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNoYXBlU2l6ZSkge1xuICAgICAgICAgICAgc2l6ZVswXSA9IHRoaXMub3B0aW9ucy5zaGFwZVNpemVbMF0gLyB0aGlzLmdyaWRTaXplWzBdO1xuICAgICAgICAgICAgc2l6ZVsxXSA9IHRoaXMub3B0aW9ucy5zaGFwZVNpemVbMV0gLyB0aGlzLmdyaWRTaXplWzFdO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZWN0ID0ge1xuICAgICAgICAgICAgdHlwZTogJ3BvbHlnb24nLFxuICAgICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFt0aGlzLm9wdGlvbnMueEZpZWxkLCB0aGlzLm9wdGlvbnMueUZpZWxkXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xvcjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW3RoaXMub3B0aW9ucy5jb2xvckZpZWxkXSxcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IHRoaXMub3B0aW9ucy5jb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaGFwZToge1xuICAgICAgICAgICAgICAgIHZhbHVlczogWydyZWN0J10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNpemVGaWVsZCkge1xuICAgICAgICAgICAgcmVjdC5zaXplID0ge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW3RoaXMub3B0aW9ucy5zaXplRmllbGRdLFxuICAgICAgICAgICAgICAgIHZhbHVlczogc2l6ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZWN0LnNpemUgPSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzOiBbMV0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWN0O1xuICAgIH07XG4gICAgSGVhdG1hcExheWVyLnByb3RvdHlwZS5hZGRDaXJjbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzaXplID0gWzAuMywgMC45XTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaGFwZVNpemUpIHtcbiAgICAgICAgICAgIHNpemUgPSB0aGlzLm9wdGlvbnMuc2hhcGVTaXplO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc2l6ZVswXSA9IHRoaXMuZ3JpZFNpemVbMF0gKiBzaXplWzBdICogMC41O1xuICAgICAgICAgICAgc2l6ZVsxXSA9IHRoaXMuZ3JpZFNpemVbMV0gKiBzaXplWzFdICogMC41O1xuICAgICAgICB9XG4gICAgICAgIHZhciBjaXJjbGUgPSB7XG4gICAgICAgICAgICB0eXBlOiAncG9pbnQnLFxuICAgICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFt0aGlzLm9wdGlvbnMueEZpZWxkLCB0aGlzLm9wdGlvbnMueUZpZWxkXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xvcjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW3RoaXMub3B0aW9ucy5jb2xvckZpZWxkXSxcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IHRoaXMub3B0aW9ucy5jb2xvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaGFwZToge1xuICAgICAgICAgICAgICAgIHZhbHVlczogWydjdXJ2ZVBvaW50J10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNpemVGaWVsZCkge1xuICAgICAgICAgICAgY2lyY2xlLnNpemUgPSB7XG4gICAgICAgICAgICAgICAgZmllbGRzOiBbdGhpcy5vcHRpb25zLnNpemVGaWVsZF0sXG4gICAgICAgICAgICAgICAgdmFsdWVzOiBzaXplLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNpcmNsZS5zaXplID0ge1xuICAgICAgICAgICAgICAgIHZhbHVlczogW01hdGgubWluKHRoaXMuZ3JpZFNpemVbMF0sIHRoaXMuZ3JpZFNpemVbMV0pICogMC41ICogMC45XSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNpcmNsZTtcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICBjb25maWcudG9vbHRpcCA9IHt9O1xuICAgICAgICB2YXIgdG9vbHRpcE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMudG9vbHRpcDtcbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgY29uZmlnLnRvb2x0aXAuZmllbGRzID0gdG9vbHRpcE9wdGlvbnMuZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIGNvbmZpZy50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICBjb25maWcudG9vbHRpcC5maWVsZHMgPSBbdGhpcy5vcHRpb25zLnhGaWVsZCwgdGhpcy5vcHRpb25zLnlGaWVsZF07XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jb2xvckZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy50b29sdGlwLmZpZWxkcy5wdXNoKHRoaXMub3B0aW9ucy5jb2xvckZpZWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUuZ2V0R3JpZFNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucGFkZGluZyA9PT0gJ2F1dG8nKSB7XG4gICAgICAgICAgICByZXR1cm4gWzAsIDBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHZpZXdSYW5nZSA9IHRoaXMuZ2V0Vmlld1JhbmdlKCk7XG4gICAgICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHBhZGRpbmcgPSBfYS5wYWRkaW5nLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZCwgZGF0YSA9IF9hLmRhdGE7XG4gICAgICAgICAgICB2YXIgd2lkdGggPSB2aWV3UmFuZ2Uud2lkdGggLSBwYWRkaW5nWzFdIC0gcGFkZGluZ1szXTtcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSB2aWV3UmFuZ2UuaGVpZ2h0IC0gcGFkZGluZ1swXSAtIHBhZGRpbmdbMl07XG4gICAgICAgICAgICB2YXIgeENvdW50ID0gdXRpbF8xLnZhbHVlc09mS2V5KGRhdGEsIHhGaWVsZCkubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIHlDb3VudCA9IHV0aWxfMS52YWx1ZXNPZktleShkYXRhLCB5RmllbGQpLmxlbmd0aDtcbiAgICAgICAgICAgIHJldHVybiBbd2lkdGggLyB4Q291bnQsIGhlaWdodCAvIHlDb3VudF07XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUuY2lyY2xlVG9SZWN0ID0gZnVuY3Rpb24gKHNoYXBlcykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgZ3JpZFNpemUgPSB0aGlzLmdyaWRTaXplO1xuICAgICAgICB1dGlsXzEuZWFjaChzaGFwZXMsIGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICAgICAgdmFyIF9hID0gc2hhcGUuZ2V0KCdvcmlnaW4nKSwgeCA9IF9hLngsIHkgPSBfYS55LCBzaXplID0gX2Euc2l6ZTtcbiAgICAgICAgICAgIHZhciBzaXplUmF0aW8gPSAoc2l6ZSAqIDIpIC8gTWF0aC5taW4oZ3JpZFNpemVbMF0sIGdyaWRTaXplWzFdKTtcbiAgICAgICAgICAgIGlmICghX3RoaXMub3B0aW9ucy5zaXplRmllbGQpIHtcbiAgICAgICAgICAgICAgICBzaXplUmF0aW8gPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGN1cnZlUGF0aCA9IHNoYXBlXzEuZ2V0Q2lyY2xlQ3VydmUoeCwgeSwgc2l6ZSk7XG4gICAgICAgICAgICB2YXIgcmVjdFBhdGggPSBzaGFwZV8xLmdldFJlY3RQYXRoKHgsIHksIGdyaWRTaXplWzBdLCBncmlkU2l6ZVsxXSwgc2l6ZVJhdGlvKTtcbiAgICAgICAgICAgIHNoYXBlLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICBzaGFwZS5hdHRyKCdwYXRoJywgY3VydmVQYXRoKTtcbiAgICAgICAgICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgIHBhdGg6IHJlY3RQYXRoLFxuICAgICAgICAgICAgfSwgNTAwLCAnZWFzZUxpbmVhcicpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUucmVjdFRvQ2lyY2xlID0gZnVuY3Rpb24gKHNoYXBlcykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB1dGlsXzEuZWFjaChzaGFwZXMsIGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICAgICAgdmFyIGNvb3JkID0gc2hhcGUuZ2V0KCdjb29yZCcpO1xuICAgICAgICAgICAgdmFyIHBvaW50cyA9IHNoYXBlLmdldCgnb3JpZ2luJykucG9pbnRzO1xuICAgICAgICAgICAgdmFyIHBzID0gW107XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICAgICAgcHMucHVzaChjb29yZC5jb252ZXJ0UG9pbnQocCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IGJib3gud2lkdGg7XG4gICAgICAgICAgICB2YXIgaGVpZ2h0ID0gYmJveC5oZWlnaHQ7XG4gICAgICAgICAgICB2YXIgY2VudGVyWCA9IGJib3gubWluWCArIHdpZHRoIC8gMjtcbiAgICAgICAgICAgIHZhciBjZW50ZXJZID0gYmJveC5taW5ZICsgaGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIHZhciBvZmZzZXRSYXRpbyA9IF90aGlzLm9wdGlvbnMuc2l6ZUZpZWxkID8gMSA6IDAuOTtcbiAgICAgICAgICAgIHZhciBjdXJ2ZVBhdGggPSBzaGFwZV8xLmdldENpcmNsZUN1cnZlKGNlbnRlclgsIGNlbnRlclksIChNYXRoLm1pbih3aWR0aCwgaGVpZ2h0KSAvIDIpICogb2Zmc2V0UmF0aW8pO1xuICAgICAgICAgICAgdmFyIGNpcmNsZVBhdGggPSBzaGFwZV8xLmdldENpcmNsZVBhdGgoY2VudGVyWCwgY2VudGVyWSwgKE1hdGgubWluKHdpZHRoLCBoZWlnaHQpIC8gMikgKiBvZmZzZXRSYXRpbyk7XG4gICAgICAgICAgICBzaGFwZS5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgc2hhcGUuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgcGF0aDogY3VydmVQYXRoLFxuICAgICAgICAgICAgfSwgNTAwLCAnZWFzZUxpbmVhcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzaGFwZS5hdHRyKCdwYXRoJywgY2lyY2xlUGF0aCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLnJlY3RTaXplTWFwcGluZyA9IGZ1bmN0aW9uIChzaGFwZXMsIHNjYWxlLCBmaWVsZCkge1xuICAgICAgICB1dGlsXzEuZWFjaChzaGFwZXMsIGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICAgICAgdmFyIGRhdGEgPSBzaGFwZS5nZXQoJ29yaWdpbicpLmRhdGE7XG4gICAgICAgICAgICB2YXIgcmF0aW8gPSAwLjMgKyBzY2FsZS5zY2FsZShkYXRhW2ZpZWxkXSkgKiAwLjY7XG4gICAgICAgICAgICBzaGFwZS5nZXQoJ29yaWdpbicpLnNpemUgPSByYXRpbztcbiAgICAgICAgICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHdpZHRoID0gYmJveC53aWR0aDtcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSBiYm94LmhlaWdodDtcbiAgICAgICAgICAgIHZhciBjZW50ZXJYID0gYmJveC5taW5YICsgd2lkdGggLyAyO1xuICAgICAgICAgICAgdmFyIGNlbnRlclkgPSBiYm94Lm1pblkgKyBoZWlnaHQgLyAyO1xuICAgICAgICAgICAgdmFyIHBhdGggPSBzaGFwZV8xLmdldFJlY3RQYXRoKGNlbnRlclgsIGNlbnRlclksIHdpZHRoLCBoZWlnaHQsIHJhdGlvKTtcbiAgICAgICAgICAgIHNoYXBlLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICBzaGFwZS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgfSwgNTAwLCAnZWFzZUxpbmVhcicpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUuY2lyY2xlU2l6ZU1hcHBpbmcgPSBmdW5jdGlvbiAoc2hhcGVzLCBzY2FsZSwgZmllbGQpIHtcbiAgICAgICAgdXRpbF8xLmVhY2goc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgICAgIHZhciBkYXRhID0gc2hhcGUuZ2V0KCdvcmlnaW4nKS5kYXRhO1xuICAgICAgICAgICAgdmFyIHJhdGlvID0gMC4zICsgc2NhbGUuc2NhbGUoZGF0YVtmaWVsZF0pICogMC42O1xuICAgICAgICAgICAgdmFyIF9hID0gc2hhcGUuZ2V0KCdvcmlnaW4nKSwgeCA9IF9hLngsIHkgPSBfYS55LCBzaXplID0gX2Euc2l6ZTtcbiAgICAgICAgICAgIHZhciBwYXRoID0gc2hhcGVfMS5nZXRDaXJjbGVQYXRoKHgsIHksIHNpemUgKiByYXRpbyk7XG4gICAgICAgICAgICBzaGFwZS5nZXQoJ29yaWdpbicpLnNpemUgPSBzaXplICogcmF0aW87XG4gICAgICAgICAgICBzaGFwZS5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICAgICAgc2hhcGUuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgIH0sIDUwMCwgJ2Vhc2VMaW5lYXInKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBIZWF0bWFwTGF5ZXIucHJvdG90eXBlLmNpcmNsZURpc2FibGVTaXplTWFwcGluZyA9IGZ1bmN0aW9uIChzaGFwZXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5vcHRpb25zLnNpemVGaWVsZCA9IG51bGw7XG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlcywgZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgICAgICB2YXIgX2EgPSBzaGFwZS5nZXQoJ29yaWdpbicpLCB4ID0gX2EueCwgeSA9IF9hLnk7XG4gICAgICAgICAgICB2YXIgc2l6ZSA9IE1hdGgubWluKF90aGlzLmdyaWRTaXplWzBdLCBfdGhpcy5ncmlkU2l6ZVsxXSkgKiAwLjk7XG4gICAgICAgICAgICBzaGFwZS5nZXQoJ29yaWdpbicpLnNpemUgPSBzaXplIC8gMjtcbiAgICAgICAgICAgIHZhciBwYXRoID0gc2hhcGVfMS5nZXRDaXJjbGVQYXRoKHgsIHksIHNpemUgLyAyKTtcbiAgICAgICAgICAgIHNoYXBlLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICBzaGFwZS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgfSwgNTAwLCAnZWFzZUxpbmVhcicpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUucmVjdERpc2FibGVTaXplTWFwcGluZyA9IGZ1bmN0aW9uIChzaGFwZXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5vcHRpb25zLnNpemVGaWVsZCA9IG51bGw7XG4gICAgICAgIHV0aWxfMS5lYWNoKHNoYXBlcywgZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgICAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IGJib3gud2lkdGg7XG4gICAgICAgICAgICB2YXIgaGVpZ2h0ID0gYmJveC5oZWlnaHQ7XG4gICAgICAgICAgICB2YXIgY2VudGVyWCA9IGJib3gubWluWCArIHdpZHRoIC8gMjtcbiAgICAgICAgICAgIHZhciBjZW50ZXJZID0gYmJveC5taW5ZICsgaGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIHZhciBwYXRoID0gc2hhcGVfMS5nZXRSZWN0UGF0aChjZW50ZXJYLCBjZW50ZXJZLCBfdGhpcy5ncmlkU2l6ZVswXSwgX3RoaXMuZ3JpZFNpemVbMV0sIDEpO1xuICAgICAgICAgICAgc2hhcGUuZ2V0KCdvcmlnaW4nKS5zaXplID0gMTtcbiAgICAgICAgICAgIHNoYXBlLnN0b3BBbmltYXRlKCk7XG4gICAgICAgICAgICBzaGFwZS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgfSwgNTAwLCAnZWFzZUxpbmVhcicpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUuZ2V0U2hhcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmVsZW1lbnRzO1xuICAgICAgICB2YXIgc2hhcGVzID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWxlKSB7XG4gICAgICAgICAgICBzaGFwZXMucHVzaChlbGUuc2hhcGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHNoYXBlcztcbiAgICB9O1xuICAgIEhlYXRtYXBMYXllci5wcm90b3R5cGUucmVuZGVyUGxvdENvbXBvbmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMucGxvdENvbXBvbmVudHMsIGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBsb3RDb21wb25lbnRzID0gW107XG4gICAgICAgIHZhciBjb21wb25lbnRzVHlwZSA9IFsnbGFiZWwnLCAnbGVnZW5kJ107XG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbXBvbmVudHNUeXBlLCBmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgdmFyIGNmZyA9IHRzbGliXzEuX19hc3NpZ24oeyB2aWV3OiBfdGhpcy52aWV3LCBwbG90OiBfdGhpcyB9LCBfdGhpcy5vcHRpb25zW3RdKTtcbiAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBjb21wb25lbnRfMS5nZXRQbG90Q29tcG9uZW50cyhfdGhpcywgdCwgY2ZnKTtcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICBjb21wb25lbnQucmVuZGVyKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMucGxvdENvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBIZWF0bWFwTGF5ZXI7XG59KHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIZWF0bWFwTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdoZWF0bWFwJywgSGVhdG1hcExheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRDaXJjbGVDdXJ2ZSA9IGV4cG9ydHMuZ2V0Q2lyY2xlUGF0aCA9IGV4cG9ydHMuZ2V0UmVjdFBhdGggPSB2b2lkIDA7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG5mdW5jdGlvbiBnZXRSZWN0UGF0aChjeCwgY3ksIHdpZHRoLCBoZWlnaHQsIHNpemUpIHtcbiAgICB2YXIgdyA9IHdpZHRoICogc2l6ZTtcbiAgICB2YXIgaCA9IGhlaWdodCAqIHNpemU7XG4gICAgdmFyIHBhdGggPSBbXG4gICAgICAgIFsnTScsIGN4IC0gdyAvIDIsIGN5ICsgaCAvIDJdLFxuICAgICAgICBbJ1EnLCBjeCAtIHcgLyAyLCBjeSwgY3ggLSB3IC8gMiwgY3kgLSBoIC8gMl0sXG4gICAgICAgIFsnUScsIGN4LCBjeSAtIGggLyAyLCBjeCArIHcgLyAyLCBjeSAtIGggLyAyXSxcbiAgICAgICAgWydRJywgY3ggKyB3IC8gMiwgY3ksIGN4ICsgdyAvIDIsIGN5ICsgaCAvIDJdLFxuICAgICAgICBbJ1EnLCBjeCwgY3kgKyBoIC8gMiwgY3ggLSB3IC8gMiwgY3kgKyBoIC8gMl0sXG4gICAgICAgIFsnWiddLFxuICAgIF07XG4gICAgcmV0dXJuIHBhdGg7XG59XG5leHBvcnRzLmdldFJlY3RQYXRoID0gZ2V0UmVjdFBhdGg7XG5mdW5jdGlvbiBnZXRDaXJjbGVQYXRoKHgsIHksIHNpemUpIHtcbiAgICB2YXIgcGF0aCA9IFtcbiAgICAgICAgWydNJywgeCwgeV0sXG4gICAgICAgIFsnbCcsIC1zaXplLCAwXSxcbiAgICAgICAgWydhJywgc2l6ZSwgc2l6ZSwgMCwgMSwgMCwgc2l6ZSAqIDIsIDBdLFxuICAgICAgICBbJ2EnLCBzaXplLCBzaXplLCAwLCAxLCAwLCAtKHNpemUgKiAyKSwgMF0sXG4gICAgICAgIFsnWiddLFxuICAgIF07XG4gICAgcmV0dXJuIHBhdGg7XG59XG5leHBvcnRzLmdldENpcmNsZVBhdGggPSBnZXRDaXJjbGVQYXRoO1xuZnVuY3Rpb24gZ2V0Q2lyY2xlQ3VydmUoeCwgeSwgc2l6ZSkge1xuICAgIC8vIOiuoeeul+Wbm+S4quinkuWSjOS4reeCuVxuICAgIHZhciBwYXRoID0gW1xuICAgICAgICBbJ00nLCB4IC0gc2l6ZSwgeV0sXG4gICAgICAgIFsnUScsIHggLSBzaXplLCB5IC0gc2l6ZSwgeCwgeSAtIHNpemVdLFxuICAgICAgICBbJ1EnLCB4ICsgc2l6ZSwgeSAtIHNpemUsIHggKyBzaXplLCB5XSxcbiAgICAgICAgWydRJywgeCArIHNpemUsIHkgKyBzaXplLCB4LCB5ICsgc2l6ZV0sXG4gICAgICAgIFsnUScsIHggLSBzaXplLCB5ICsgc2l6ZSwgeCAtIHNpemUsIHldLFxuICAgICAgICBbJ1onXSxcbiAgICBdO1xuICAgIHJldHVybiBwYXRoO1xufVxuZXhwb3J0cy5nZXRDaXJjbGVDdXJ2ZSA9IGdldENpcmNsZUN1cnZlO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyU2hhcGUoJ3BvbHlnb24nLCAncmVjdCcsIHtcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IHRoaXMucGFyc2VQb2ludHMoY2ZnLnBvaW50cyk7XG4gICAgICAgIHZhciB3aWR0aCA9IHBvaW50c1syXS54IC0gcG9pbnRzWzBdLng7XG4gICAgICAgIHZhciBoZWlnaHQgPSBwb2ludHNbMF0ueSAtIHBvaW50c1sxXS55O1xuICAgICAgICB2YXIgY2VudGVyWCA9IHBvaW50c1swXS54ICsgd2lkdGggLyAyO1xuICAgICAgICB2YXIgY2VudGVyWSA9IHBvaW50c1sxXS55ICsgaGVpZ2h0IC8gMjtcbiAgICAgICAgLypcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBbXG4gICAgICAgICAgICAgIFsnTScsIGNlbnRlclggLSB3IC8gMiwgY2VudGVyWSArIGggLyAyXSxcbiAgICAgICAgICAgICAgWydMJywgY2VudGVyWCAtIHcgLyAyLCBjZW50ZXJZIC0gaCAvIDJdLFxuICAgICAgICAgICAgICBbJ0wnLCBjZW50ZXJYICsgdyAvIDIsIGNlbnRlclkgLSBoIC8gMl0sXG4gICAgICAgICAgICAgIFsnTCcsIGNlbnRlclggKyB3IC8gMiwgY2VudGVyWSArIGggLyAyXSxcbiAgICAgICAgICAgICAgWydaJ10sXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgKi9cbiAgICAgICAgdmFyIHBhdGggPSBnZXRSZWN0UGF0aChjZW50ZXJYLCBjZW50ZXJZLCB3aWR0aCwgaGVpZ2h0LCBjZmcuc2l6ZSk7XG4gICAgICAgIHJldHVybiBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgIGZpbGw6IGNmZy5jb2xvcixcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgfSwgY2ZnLnN0eWxlKSxcbiAgICAgICAgfSk7XG4gICAgfSxcbn0pO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyU2hhcGUoJ3BvaW50JywgJ2N1cnZlUG9pbnQnLCB7XG4gICAgZHJhdzogZnVuY3Rpb24gKGNmZywgY29udGFpbmVyKSB7XG4gICAgICAgIHZhciBwYXRoID0gZ2V0Q2lyY2xlUGF0aChjZmcueCwgY2ZnLnksIGNmZy5zaXplKTtcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEuZGVlcE1peCh7fSwge1xuICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgZmlsbDogY2ZnLmNvbG9yLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICB9LCBjZmcuc3R5bGUpLFxuICAgICAgICB9KTtcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zaGFwZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgSGlzdG9ncmFtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEhpc3RvZ3JhbSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIaXN0b2dyYW0oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgSGlzdG9ncmFtLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnaGlzdG9ncmFtJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIEhpc3RvZ3JhbS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gSGlzdG9ncmFtO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSGlzdG9ncmFtO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBtYXRoXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9tYXRoXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vY29sdW1uL2xheWVyXCIpKTtcbnZhciBIaXN0b2dyYW1MYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhIaXN0b2dyYW1MYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIaXN0b2dyYW1MYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnaGlzdG9ncmFtJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBIaXN0b2dyYW1MYXllci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zLnhGaWVsZCA9ICdyYW5nZSc7XG4gICAgICAgIHRoaXMub3B0aW9ucy55RmllbGQgPSAnY291bnQnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIEhpc3RvZ3JhbUxheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uIChvcmlnaW5EYXRhKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgYmluRmllbGQgPSBfYS5iaW5GaWVsZCwgYmluV2lkdGggPSBfYS5iaW5XaWR0aCwgYmluTnVtYmVyID0gX2EuYmluTnVtYmVyO1xuICAgICAgICB2YXIgb3JpZ2luRGF0YV9jb3B5ID0gdXRpbF8xLmNsb25lKG9yaWdpbkRhdGEpO1xuICAgICAgICAvLyDmoLnmja5iaW5GaWVsZCB2YWx1ZeWvuea6kOaVsOaNrui/m+ihjOaOkuW6j1xuICAgICAgICB1dGlsXzEuc29ydEJ5KG9yaWdpbkRhdGFfY29weSwgYmluRmllbGQpO1xuICAgICAgICAvLyDojrflj5bmupDmlbDmja5iaW5GaWVsZCB2YWx1ZXPnmoRyYW5nZVxuICAgICAgICB2YXIgdmFsdWVzID0gdXRpbF8xLnZhbHVlc09mS2V5KG9yaWdpbkRhdGFfY29weSwgYmluRmllbGQpO1xuICAgICAgICB2YXIgcmFuZ2UgPSB1dGlsXzEuZ2V0UmFuZ2UodmFsdWVzKTtcbiAgICAgICAgdmFyIHJhbmdlV2lkdGggPSByYW5nZS5tYXggLSByYW5nZS5taW47XG4gICAgICAgIC8vIOiuoeeul+WIhueuse+8jOebtOaWueWbvuWIhueuseeahOiuoeeul+WfuuS6jmJpbldpZHRo77yM5aaC6YWN572u5LqGYmluTnVtYmVy5YiZ5bCG5YW26L2s5Li6YmluV2lkdGjov5vooYzorqHnrpdcbiAgICAgICAgdmFyIF9iaW5XaWR0aCA9IGJpbldpZHRoO1xuICAgICAgICBpZiAoIWJpbldpZHRoICYmIGJpbk51bWJlcikge1xuICAgICAgICAgICAgX2JpbldpZHRoID0gcmFuZ2VXaWR0aCAvIGJpbk51bWJlcjtcbiAgICAgICAgfVxuICAgICAgICAvLyDlvZNiaW5XaWR0aOWSjGJpbk51bWJlcumDveayoeacieaMh+WumueahOaDheWGte+8jOmHh+eUqFN0dXJnZXMgZm9ybXVsYeiHquWKqOeUn+aIkGJpbldpZHRoXG4gICAgICAgIGlmICghYmluV2lkdGggJiYgIWJpbk51bWJlcikge1xuICAgICAgICAgICAgdmFyIF9kZWZhdWx0QmluTnVtYmVyID0gbWF0aF8xLnN0dXJnZXModmFsdWVzKTtcbiAgICAgICAgICAgIF9iaW5XaWR0aCA9IHJhbmdlV2lkdGggLyBfZGVmYXVsdEJpbk51bWJlcjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYmlucyA9IHt9O1xuICAgICAgICB1dGlsXzEuZWFjaChvcmlnaW5EYXRhX2NvcHksIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBkYXRhW2JpbkZpZWxkXTtcbiAgICAgICAgICAgIHZhciBiaW4gPSBfdGhpcy5nZXRCaW4odmFsdWUsIF9iaW5XaWR0aCk7XG4gICAgICAgICAgICB2YXIgYmluTmFtZSA9IGJpblswXSArIFwiLVwiICsgYmluWzFdO1xuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaGFzS2V5KGJpbnMsIGJpbk5hbWUpKSB7XG4gICAgICAgICAgICAgICAgYmluc1tiaW5OYW1lXSA9IHsgbmFtZTogYmluTmFtZSwgcmFuZ2U6IGJpbiwgY291bnQ6IDAsIGRhdGE6IFtdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBiaW5zW2Jpbk5hbWVdLmRhdGEucHVzaChkYXRhKTtcbiAgICAgICAgICAgIGJpbnNbYmluTmFtZV0uY291bnQgKz0gMTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOWwhuWIhueuseaVsOaNrui9rOaNouS4unBsb3REYXRhXG4gICAgICAgIHZhciBwbG90RGF0YSA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChiaW5zLCBmdW5jdGlvbiAoYmluKSB7XG4gICAgICAgICAgICBwbG90RGF0YS5wdXNoKGJpbik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGxvdERhdGE7XG4gICAgfTtcbiAgICBIaXN0b2dyYW1MYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2NhbGUuY2FsbCh0aGlzKTtcbiAgICAgICAgLy8gZml4bWU6IOexu+Wei+WumuS5iVxuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmNvbmZpZy5zY2FsZXMucmFuZ2U7XG4gICAgICAgIHJhbmdlLm5pY2UgPSBmYWxzZTtcbiAgICAgICAgcmFuZ2UudHlwZSA9ICdsaW5lYXInO1xuICAgIH07XG4gICAgSGlzdG9ncmFtTGF5ZXIucHJvdG90eXBlLmdldEJpbiA9IGZ1bmN0aW9uICh2YWx1ZSwgYmluV2lkdGgpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gTWF0aC5mbG9vcih2YWx1ZSAvIGJpbldpZHRoKTtcbiAgICAgICAgcmV0dXJuIFtiaW5XaWR0aCAqIGluZGV4LCBiaW5XaWR0aCAqIChpbmRleCArIDEpXTtcbiAgICB9O1xuICAgIHJldHVybiBIaXN0b2dyYW1MYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBIaXN0b2dyYW1MYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ2hpc3RvZ3JhbScsIEhpc3RvZ3JhbUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbGluZV8xID0gcmVxdWlyZShcIi4vbGluZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxpbmVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxpbmVfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHRyZWVtYXBfMSA9IHJlcXVpcmUoXCIuL3RyZWVtYXBcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUcmVlbWFwXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cmVlbWFwXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBzdGVwX2xpbmVfMSA9IHJlcXVpcmUoXCIuL3N0ZXAtbGluZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0ZXBMaW5lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzdGVwX2xpbmVfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGJhcl8xID0gcmVxdWlyZShcIi4vYmFyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQmFyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBiYXJfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHN0YWNrZWRfYmFyXzEgPSByZXF1aXJlKFwiLi9zdGFja2VkLWJhclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0YWNrZWRCYXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHN0YWNrZWRfYmFyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBncm91cGVkX2Jhcl8xID0gcmVxdWlyZShcIi4vZ3JvdXBlZC1iYXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcm91cGVkQmFyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBncm91cGVkX2Jhcl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcGVyY2VudF9zdGFja2VkX2Jhcl8xID0gcmVxdWlyZShcIi4vcGVyY2VudC1zdGFja2VkLWJhclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBlcmNlbnRTdGFja2VkQmFyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBwZXJjZW50X3N0YWNrZWRfYmFyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciByYW5nZV9iYXJfMSA9IHJlcXVpcmUoXCIuL3JhbmdlLWJhclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlJhbmdlQmFyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiByYW5nZV9iYXJfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGFyZWFfMSA9IHJlcXVpcmUoXCIuL2FyZWFcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBcmVhXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBhcmVhXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBzdGFja2VkX2FyZWFfMSA9IHJlcXVpcmUoXCIuL3N0YWNrZWQtYXJlYVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlN0YWNrZWRBcmVhXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzdGFja2VkX2FyZWFfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHBlcmNlbnRfc3RhY2tlZF9hcmVhXzEgPSByZXF1aXJlKFwiLi9wZXJjZW50LXN0YWNrZWQtYXJlYVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBlcmNlbnRTdGFja2VkQXJlYVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcGVyY2VudF9zdGFja2VkX2FyZWFfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGNvbHVtbl8xID0gcmVxdWlyZShcIi4vY29sdW1uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29sdW1uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb2x1bW5fMS5kZWZhdWx0OyB9IH0pO1xudmFyIGxhYmVsXzEgPSByZXF1aXJlKFwiLi9jb2x1bW4vY29tcG9uZW50L2xhYmVsXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29sdW1uTGFiZWxcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxhYmVsXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBncm91cGVkX2NvbHVtbl8xID0gcmVxdWlyZShcIi4vZ3JvdXBlZC1jb2x1bW5cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcm91cGVkQ29sdW1uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBncm91cGVkX2NvbHVtbl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgc3RhY2tlZF9jb2x1bW5fMSA9IHJlcXVpcmUoXCIuL3N0YWNrZWQtY29sdW1uXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU3RhY2tlZENvbHVtblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc3RhY2tlZF9jb2x1bW5fMS5kZWZhdWx0OyB9IH0pO1xudmFyIGxhYmVsXzIgPSByZXF1aXJlKFwiLi9zdGFja2VkLWNvbHVtbi9jb21wb25lbnQvbGFiZWxcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTdGFja2VkQ29sdW1uTGFiZWxcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxhYmVsXzIuZGVmYXVsdDsgfSB9KTtcbnZhciByYW5nZV9jb2x1bW5fMSA9IHJlcXVpcmUoXCIuL3JhbmdlLWNvbHVtblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlJhbmdlQ29sdW1uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiByYW5nZV9jb2x1bW5fMS5kZWZhdWx0OyB9IH0pO1xudmFyIHBlcmNlbnRfc3RhY2tlZF9jb2x1bW5fMSA9IHJlcXVpcmUoXCIuL3BlcmNlbnQtc3RhY2tlZC1jb2x1bW5cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJQZXJjZW50U3RhY2tlZENvbHVtblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcGVyY2VudF9zdGFja2VkX2NvbHVtbl8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcGllXzEgPSByZXF1aXJlKFwiLi9waWVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJQaWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHBpZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZGVuc2l0eV9oZWF0bWFwXzEgPSByZXF1aXJlKFwiLi9kZW5zaXR5LWhlYXRtYXBcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJEZW5zaXR5SGVhdG1hcFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVuc2l0eV9oZWF0bWFwXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBoZWF0bWFwXzEgPSByZXF1aXJlKFwiLi9oZWF0bWFwXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiSGVhdG1hcFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaGVhdG1hcF8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgd29yZF9jbG91ZF8xID0gcmVxdWlyZShcIi4vd29yZC1jbG91ZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIldvcmRDbG91ZFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gd29yZF9jbG91ZF8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgcm9zZV8xID0gcmVxdWlyZShcIi4vcm9zZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlJvc2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJvc2VfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGZ1bm5lbF8xID0gcmVxdWlyZShcIi4vZnVubmVsXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRnVubmVsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBmdW5uZWxfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHN0YWNrZWRfcm9zZV8xID0gcmVxdWlyZShcIi4vc3RhY2tlZC1yb3NlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU3RhY2tlZFJvc2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHN0YWNrZWRfcm9zZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZ3JvdXBlZF9yb3NlXzEgPSByZXF1aXJlKFwiLi9ncm91cGVkLXJvc2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHcm91cGVkUm9zZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZ3JvdXBlZF9yb3NlXzEuZGVmYXVsdDsgfSB9KTtcbnZhciByYWRhcl8xID0gcmVxdWlyZShcIi4vcmFkYXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJSYWRhclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmFkYXJfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGxpcXVpZF8xID0gcmVxdWlyZShcIi4vbGlxdWlkXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTGlxdWlkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXF1aWRfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGhpc3RvZ3JhbV8xID0gcmVxdWlyZShcIi4vaGlzdG9ncmFtXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiSGlzdG9ncmFtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBoaXN0b2dyYW1fMS5kZWZhdWx0OyB9IH0pO1xudmFyIGRlbnNpdHlfMSA9IHJlcXVpcmUoXCIuL2RlbnNpdHlcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJEZW5zaXR5XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBkZW5zaXR5XzEuZGVmYXVsdDsgfSB9KTtcbnZhciBkb251dF8xID0gcmVxdWlyZShcIi4vZG9udXRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJEb251dFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZG9udXRfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHdhdGVyZmFsbF8xID0gcmVxdWlyZShcIi4vd2F0ZXJmYWxsXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiV2F0ZXJmYWxsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB3YXRlcmZhbGxfMS5kZWZhdWx0OyB9IH0pO1xudmFyIHNjYXR0ZXJfMSA9IHJlcXVpcmUoXCIuL3NjYXR0ZXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTY2F0dGVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzY2F0dGVyXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBidWJibGVfMSA9IHJlcXVpcmUoXCIuL2J1YmJsZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJ1YmJsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnViYmxlXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBidWxsZXRfMSA9IHJlcXVpcmUoXCIuL2J1bGxldFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJ1bGxldFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnVsbGV0XzEuZGVmYXVsdDsgfSB9KTtcbnZhciBjYWxlbmRhcl8xID0gcmVxdWlyZShcIi4vY2FsZW5kYXJcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDYWxlbmRhclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY2FsZW5kYXJfMS5kZWZhdWx0OyB9IH0pO1xudmFyIGdhdWdlXzEgPSByZXF1aXJlKFwiLi9nYXVnZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkdhdWdlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBnYXVnZV8xLmRlZmF1bHQ7IH0gfSk7XG52YXIgZmFuX2dhdWdlXzEgPSByZXF1aXJlKFwiLi9mYW4tZ2F1Z2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJGYW5HYXVnZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFuX2dhdWdlXzEuZGVmYXVsdDsgfSB9KTtcbnZhciBtZXRlcl9nYXVnZV8xID0gcmVxdWlyZShcIi4vbWV0ZXItZ2F1Z2VcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJNZXRlckdhdWdlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBtZXRlcl9nYXVnZV8xLmRlZmF1bHQ7IH0gfSk7XG50c2xpYl8xLl9fZXhwb3J0U3RhcihyZXF1aXJlKFwiLi9jb21wYXRpYmxlUGxvdHNcIiksIGV4cG9ydHMpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFBsb3RPcHRpb24gPSB2b2lkIDA7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdEluZm87XG5mdW5jdGlvbiBjbGlwaW5nV2l0aERhdGEoc2hhcGUsIGFuaW1hdGVDZmcpIHtcbiAgICB2YXIgZGVmYXVsdENmZyA9IHtcbiAgICAgICAgZWFzaW5nOiAnZWFzZUxpbmVhcicsXG4gICAgICAgIGR1cmF0aW9uOiAxMDAwMCxcbiAgICB9O1xuICAgIHZhciBhbmltYXRpb25Db25maWcgPSB1dGlsXzEuZGVlcE1peCh7fSwgYW5pbWF0ZUNmZywgZGVmYXVsdENmZyk7XG4gICAgdmFyIGdlb21ldHJ5ID0gc2hhcGUuZ2V0KCdlbGVtZW50JykuZ2VvbWV0cnk7XG4gICAgZ2VvbWV0cnkubGFiZWxzQ29udGFpbmVyLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAvKiog5Yqo55S75Yid5aeL54q25oCBICovXG4gICAgdmFyIGluZGV4ID0gc2hhcGUuZ2V0KCdpbmRleCcpO1xuICAgIHZhciBjb29yZCA9IGdlb21ldHJ5LmNvb3JkaW5hdGU7XG4gICAgdmFyIHNjYWxlcyA9IGdlb21ldHJ5LnNjYWxlcztcbiAgICB2YXIgeVNjYWxlID0gc2NhbGVzW3Bsb3RJbmZvLm9wdGlvbnMueUZpZWxkXTtcbiAgICB2YXIgc2hhcGVEYXRhID0gdXRpbF8xLmNsb25lKHNoYXBlLmdldCgnb3JpZ2luJykpO1xuICAgIHNldENsaXAoc2hhcGUsIGNvb3JkKTtcbiAgICB2YXIgY2xpcCA9IHNoYXBlLmdldCgnY2xpcFNoYXBlJyk7XG4gICAgdmFyIHBhcmVudCA9IHNoYXBlLmdldCgncGFyZW50Jyk7XG4gICAgdmFyIG9mZnNldFggPSAxMjtcbiAgICB2YXIgdGl0bGUgPSBudWxsO1xuICAgIHZhciBzZXJpZXNGaWVsZCA9IHBsb3RJbmZvLm9wdGlvbnMuc2VyaWVzRmllbGQ7XG4gICAgaWYgKHNlcmllc0ZpZWxkKSB7XG4gICAgICAgIHRpdGxlID0gcGFyZW50LmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4OiBjb29yZC5zdGFydC54ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgIHRleHQ6IHNoYXBlRGF0YS5kYXRhWzBdW3Nlcmllc0ZpZWxkXSxcbiAgICAgICAgICAgICAgICBmaWxsOiBzaGFwZS5hdHRyKCdzdHJva2UnKSxcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdmFyIG9mZnNldFkgPSB0aXRsZSA/IDE2IDogMDtcbiAgICB2YXIgbWFya2VyID0gcGFyZW50LmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgeDogY29vcmQuc3RhcnQueCArIG9mZnNldFgsXG4gICAgICAgICAgICB5OiBvZmZzZXRZLFxuICAgICAgICAgICAgdGV4dDogXCJ0ZXN0XCIgKyBpbmRleCxcbiAgICAgICAgICAgIGZpbGw6IHNoYXBlLmF0dHIoJ3N0cm9rZScpLFxuICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgdGV4dEFsaWduOiAnc3RhcnQnLFxuICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgfSxcbiAgICB9KTtcbiAgICAvKiog5Yqo55S75omn6KGM5LmL5ZCOICovXG4gICAgYW5pbWF0aW9uQ29uZmlnLmNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoc2hhcGUgJiYgIXNoYXBlLmdldCgnZGVzdHJveWVkJykpIHtcbiAgICAgICAgICAgIHNoYXBlLnNldENsaXAobnVsbCk7XG4gICAgICAgICAgICBjbGlwLnJlbW92ZSgpO1xuICAgICAgICAgICAgbWFya2VyLmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICB9LCAzMDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBtYXJrZXIucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOaWwodGl0bGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgbGFiZWxzQ29udGFpbmVyID0gZ2VvbWV0cnkubGFiZWxzQ29udGFpbmVyO1xuICAgICAgICAgICAgICAgIGlmICghbGFiZWxzQ29udGFpbmVyLmdldCgndmlzaWJsZScpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsc0NvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqIOaJp+ihjOWKqOeUuyAqL1xuICAgIC8qKiDlh4blpIfliqjnlLvlj4LmlbAgKi9cbiAgICB2YXIgZGVsYXkgPSBhbmltYXRpb25Db25maWcuZGVsYXk7XG4gICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGRlbGF5KSkge1xuICAgICAgICBkZWxheSA9IGFuaW1hdGlvbkNvbmZpZy5kZWxheShpbmRleCk7XG4gICAgfVxuICAgIHZhciBlYXNpbmcgPSBhbmltYXRpb25Db25maWcuZWFzaW5nO1xuICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihlYXNpbmcpKSB7XG4gICAgICAgIGVhc2luZyA9IGFuaW1hdGlvbkNvbmZpZy5lYXNpbmcoaW5kZXgpO1xuICAgIH1cbiAgICAvKiog5Yqo6LW35p2lICovXG4gICAgY2xpcC5hbmltYXRlKHtcbiAgICAgICAgd2lkdGg6IGNvb3JkLmdldFdpZHRoKCksXG4gICAgfSwgYW5pbWF0aW9uQ29uZmlnLmR1cmF0aW9uLCBlYXNpbmcsIGFuaW1hdGlvbkNvbmZpZy5jYWxsYmFjaywgZGVsYXkpO1xuICAgIChhbmltYXRpb25Db25maWcub25GcmFtZSA9IGZ1bmN0aW9uIChyYXRpbykge1xuICAgICAgICB2YXIgcG9zaXRpb24gPSBnZXRQb3NpdGlvbkJ5UmF0aW8ocmF0aW8sIHNoYXBlRGF0YSwgY29vcmQpO1xuICAgICAgICBpZiAoIXBvc2l0aW9uKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBtYXJrZXIuYXR0cigneCcsIHBvc2l0aW9uWzBdICsgb2Zmc2V0WCk7XG4gICAgICAgIG1hcmtlci5hdHRyKCd5JywgcG9zaXRpb25bMV0gKyBvZmZzZXRZKTtcbiAgICAgICAgdmFyIHlUZXh0ID0gZ2V0RGF0YUJ5UG9zaXRpb24oeVNjYWxlLCBwb3NpdGlvblsxXSwgY29vcmQpO1xuICAgICAgICAvLyB1c2UgZm9ybWF0dGVyXG4gICAgICAgIGlmICh5U2NhbGUuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB5VGV4dCA9IHlTY2FsZS5mb3JtYXR0ZXIoeVRleHQpO1xuICAgICAgICB9XG4gICAgICAgIG1hcmtlci5hdHRyKCd0ZXh0JywgeVRleHQpO1xuICAgIH0pLFxuICAgICAgICBtYXJrZXIuYW5pbWF0ZShhbmltYXRpb25Db25maWcub25GcmFtZSwge1xuICAgICAgICAgICAgZHVyYXRpb246IGFuaW1hdGlvbkNvbmZpZy5kdXJhdGlvbixcbiAgICAgICAgICAgIGVhc2luZzogZWFzaW5nLFxuICAgICAgICAgICAgY2FsbGJhY2s6IGFuaW1hdGlvbkNvbmZpZy5jYWxsYmFjayxcbiAgICAgICAgICAgIGRlbGF5OiBkZWxheSxcbiAgICAgICAgfSk7XG4gICAgaWYgKHRpdGxlKSB7XG4gICAgICAgIHRpdGxlLmFuaW1hdGUoe1xuICAgICAgICAgICAgb25GcmFtZTogZnVuY3Rpb24gKHJhdGlvKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gZ2V0UG9zaXRpb25CeVJhdGlvKHJhdGlvLCBzaGFwZURhdGEsIGNvb3JkKTtcbiAgICAgICAgICAgICAgICBpZiAoIXBvc2l0aW9uKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgdGl0bGUuYXR0cigneCcsIHBvc2l0aW9uWzBdICsgb2Zmc2V0WCk7XG4gICAgICAgICAgICAgICAgdGl0bGUuYXR0cigneScsIHBvc2l0aW9uWzFdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sIGFuaW1hdGlvbkNvbmZpZy5kdXJhdGlvbiwgZWFzaW5nLCBhbmltYXRpb25Db25maWcuY2FsbGJhY2ssIGRlbGF5KTtcbiAgICB9XG59XG5mdW5jdGlvbiBzZXRDbGlwKHNoYXBlLCBjb29yZCkge1xuICAgIHZhciBzdGFydCA9IGNvb3JkLnN0YXJ0LCBlbmQgPSBjb29yZC5lbmQsIGhlaWdodCA9IGNvb3JkLmhlaWdodDtcbiAgICBzaGFwZS5zZXRDbGlwKHtcbiAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgeDogc3RhcnQueCxcbiAgICAgICAgICAgIHk6IGVuZC55LFxuICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgfSxcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGdldFBvc2l0aW9uQnlSYXRpbyhyYXRpbywgZGF0YVBvaW50cywgY29vcmQpIHtcbiAgICB2YXIgcG9pbnRzID0gZGF0YVBvaW50cy5wb2ludHM7XG4gICAgdmFyIGN1cnJlbnRYID0gY29vcmQuc3RhcnQueCArIGNvb3JkLmdldFdpZHRoKCkgKiByYXRpbztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgdmFyIGN1cnJlbnQgPSBwb2ludHNbaV07XG4gICAgICAgIHZhciBuZXh0ID0gcG9pbnRzW2kgKyAxXTtcbiAgICAgICAgaWYgKGN1cnJlbnRYID49IGN1cnJlbnQueCAmJiBjdXJyZW50WCA8PSBuZXh0LngpIHtcbiAgICAgICAgICAgIHZhciBtID0gKG5leHQueSAtIGN1cnJlbnQueSkgLyAobmV4dC54IC0gY3VycmVudC54KTsgLy8g5pac546HXG4gICAgICAgICAgICB2YXIgeSA9IGN1cnJlbnQueSArIG0gKiAoY3VycmVudFggLSBjdXJyZW50LngpO1xuICAgICAgICAgICAgcmV0dXJuIFtjdXJyZW50WCwgeV07XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBnZXREYXRhQnlQb3NpdGlvbihzY2FsZSwgeSwgY29vcmQpIHtcbiAgICB2YXIgeVJhdGlvID0gKHkgLSBjb29yZC5zdGFydC55KSAvIChjb29yZC5lbmQueSAtIGNvb3JkLnN0YXJ0LnkpO1xuICAgIHJldHVybiBzY2FsZS5pbnZlcnQoeVJhdGlvKS50b0ZpeGVkKDIpO1xufVxuZnVuY3Rpb24gZ2V0UGxvdE9wdGlvbihvcHRpb24pIHtcbiAgICBwbG90SW5mbyA9IG9wdGlvbjtcbn1cbmV4cG9ydHMuZ2V0UGxvdE9wdGlvbiA9IGdldFBsb3RPcHRpb247XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJBbmltYXRpb24oJ2NsaXBpbmdXaXRoRGF0YScsIGNsaXBpbmdXaXRoRGF0YSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jbGlwSW4td2l0aC1kYXRhLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYXhpc18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYXhpc1wiKSk7XG52YXIgbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xhYmVsXCIpKTtcbnZhciBwcmVSZW5kZXJSZXNwb25zaXZlID0gW107XG52YXIgYWZ0ZXJSZW5kZXJSZXNwb25zaXZlID0gW1xuICAgIHsgbmFtZTogJ3Jlc3BvbnNpdmVBeGlzJywgbWV0aG9kOiBheGlzXzEuZGVmYXVsdCB9LFxuICAgIHsgbmFtZTogJ3Jlc3BvbnNpdmVQb2ludExhYmVsJywgbWV0aG9kOiBsYWJlbF8xLmRlZmF1bHQgfSxcbl07XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgcHJlUmVuZGVyOiBwcmVSZW5kZXJSZXNwb25zaXZlLFxuICAgIGFmdGVyUmVuZGVyOiBhZnRlclJlbmRlclJlc3BvbnNpdmUsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvcmVzcG9uc2l2ZS9hcHBseS9sYWJlbFwiKSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgQXBwbHlSZXNwb25zaXZlTGluZUxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEFwcGx5UmVzcG9uc2l2ZUxpbmVMYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBBcHBseVJlc3BvbnNpdmVMaW5lTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgQXBwbHlSZXNwb25zaXZlTGluZUxhYmVsLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmdldCh0aGlzLnBsb3Qub3B0aW9ucywgWydsYWJlbCcsICd0eXBlJ10sICdwb2ludCcpO1xuICAgIH07XG4gICAgcmV0dXJuIEFwcGx5UmVzcG9uc2l2ZUxpbmVMYWJlbDtcbn0obGFiZWxfMS5kZWZhdWx0KSk7XG5mdW5jdGlvbiByZXNwb25zaXZlUG9pbnRMYWJlbChsYXllcikge1xuICAgIHZhciByZXNwb25zaXZlVGhlbWUgPSBsYXllci5nZXRSZXNwb25zaXZlVGhlbWUoKTtcbiAgICBuZXcgQXBwbHlSZXNwb25zaXZlTGluZUxhYmVsKHtcbiAgICAgICAgcGxvdDogbGF5ZXIsXG4gICAgICAgIHJlc3BvbnNpdmVUaGVtZTogcmVzcG9uc2l2ZVRoZW1lLFxuICAgIH0pO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gcmVzcG9uc2l2ZVBvaW50TGFiZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYWJlbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvcmVzcG9uc2l2ZS90aGVtZVwiKTtcbi8qKiDnu4Too4V0aGVtZSAqL1xudmFyIGxpbmVUaGVtZSA9IHtcbiAgICBsYWJlbDoge1xuICAgICAgICBwb2ludDoge1xuICAgICAgICAgICAgY29uc3RyYWludHM6IFt7IG5hbWU6ICdlbGVtZW50Q29sbGlzaW9uJyB9XSxcbiAgICAgICAgICAgIHJ1bGVzOiB7XG4gICAgICAgICAgICAgICAgZWxlbWVudENvbGxpc2lvbjogW3sgbmFtZTogJ25vZGVzUmVzYW1wbGluZ0J5Q2hhbmdlJyB9LCB7IG5hbWU6ICdjbGVhck92ZXJsYXBwaW5nJyB9XSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgfSxcbn07XG50aGVtZV8xLnJlZ2lzdGVyUmVzcG9uc2l2ZVRoZW1lKCdsaW5lJywgbGluZVRoZW1lKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRoZW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIERFRkFVTFRfT0ZGU0VUID0gODtcbnZhciBMaW5lTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTGluZUxhYmVsKGNmZykge1xuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnZpZXcgPSBjZmcudmlldztcbiAgICAgICAgdGhpcy5wbG90ID0gY2ZnLnBsb3Q7XG4gICAgICAgIHZhciBkZWZhdWx0T3B0aW9ucyA9IHRoaXMuZ2V0RGVmYXVsdE9wdGlvbnMoKTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoZGVmYXVsdE9wdGlvbnMsIGNmZywge30pO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgTGluZUxhYmVsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5sYWJlbHNDb250YWluZXI7XG4gICAgICAgIHRoaXMudmlldy5vbignYmVmb3JlcmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuY2xlYXIoKTtcbiAgICAgICAgICAgIF90aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBMaW5lTGFiZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy5nZXRHZW9tZXRyeSgpLmVsZW1lbnRzO1xuICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlSW5mbyA9IF90aGlzLmdldFNoYXBlSW5mbyhlbGUuc2hhcGUpO1xuICAgICAgICAgICAgdmFyIF9hID0gX3RoaXMub3B0aW9ucywgc3R5bGUgPSBfYS5zdHlsZSwgb2Zmc2V0WCA9IF9hLm9mZnNldFgsIG9mZnNldFkgPSBfYS5vZmZzZXRZO1xuICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IF90aGlzLm9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIoc2hhcGVJbmZvLm5hbWUpIDogc2hhcGVJbmZvLm5hbWU7XG4gICAgICAgICAgICBfdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHNoYXBlSW5mby54ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgICAgICAgICAgeTogc2hhcGVJbmZvLnkgKyBvZmZzZXRZLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBjb250ZW50LFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiBzaGFwZUluZm8uY29sb3IsXG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgIH0sIHN0eWxlKSxcbiAgICAgICAgICAgICAgICBuYW1lOiAnbGFiZWwnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgTGluZUxhYmVsLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMaW5lTGFiZWwucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBMaW5lTGFiZWwucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnNldCgndmlzaWJsZScsIHRydWUpO1xuICAgICAgICB0aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIExpbmVMYWJlbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgfTtcbiAgICBMaW5lTGFiZWwucHJvdG90eXBlLmdldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5nZXRCQm94KCk7XG4gICAgfTtcbiAgICBMaW5lTGFiZWwucHJvdG90eXBlLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnBsb3QudGhlbWU7XG4gICAgICAgIHZhciBsYWJlbFN0eWxlID0gdXRpbF8xLmNsb25lKHRoZW1lLmxhYmVsLnN0eWxlKTtcbiAgICAgICAgZGVsZXRlIGxhYmVsU3R5bGUuZmlsbDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9mZnNldFg6IERFRkFVTFRfT0ZGU0VULFxuICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIHN0eWxlOiBsYWJlbFN0eWxlLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgTGluZUxhYmVsLnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5maW5kKHRoaXMudmlldy5nZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbSkgeyByZXR1cm4gZ2VvbS50eXBlID09PSAnbGluZSc7IH0pO1xuICAgIH07XG4gICAgTGluZUxhYmVsLnByb3RvdHlwZS5nZXRTaGFwZUluZm8gPSBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgdmFyIG9yaWdpblBvaW50cyA9IHNoYXBlLmdldCgnb3JpZ2luJykucG9pbnRzO1xuICAgICAgICB2YXIgbGFzdFBvaW50ID0gb3JpZ2luUG9pbnRzW29yaWdpblBvaW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgdmFyIGNvbG9yID0gc2hhcGUuYXR0cignc3Ryb2tlJyk7XG4gICAgICAgIHZhciBzZXJpZXNGaWVsZCA9IHRoaXMucGxvdC5vcHRpb25zLnNlcmllc0ZpZWxkO1xuICAgICAgICB2YXIgbmFtZSA9IHNoYXBlLmdldCgnb3JpZ2luJykuZGF0YVswXVtzZXJpZXNGaWVsZF07XG4gICAgICAgIHJldHVybiB7IHg6IGxhc3RQb2ludC54LCB5OiBsYXN0UG9pbnQueSwgY29sb3I6IGNvbG9yLCBuYW1lOiBuYW1lIH07XG4gICAgfTtcbiAgICByZXR1cm4gTGluZUxhYmVsO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmVMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUtbGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBsaW5lOiAnbGluZScsXG4gICAgcG9pbnQ6ICdwb2ludCcsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgTGluZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaW5lLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIExpbmUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTGluZS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ2xpbmUnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgTGluZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gTGluZTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTGluZVNlbGVjdCA9IGV4cG9ydHMuTGluZUFjdGl2ZSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGxpbmVfYWN0aXZlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9saW5lLWFjdGl2ZVwiKSk7XG5leHBvcnRzLkxpbmVBY3RpdmUgPSBsaW5lX2FjdGl2ZV8xLmRlZmF1bHQ7XG52YXIgbGluZV9zZWxlY3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xpbmUtc2VsZWN0XCIpKTtcbmV4cG9ydHMuTGluZVNlbGVjdCA9IGxpbmVfc2VsZWN0XzEuZGVmYXVsdDtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vZGVwZW5kZW50c1wiKTtcbnZhciBzZWxlY3RlZF90b29sdGlwXzEgPSByZXF1aXJlKFwiLi9zZWxlY3RlZC10b29sdGlwXCIpO1xudmFyIG1hcmtlcl9hY3RpdmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL21hcmtlci1hY3RpdmVcIikpO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyQWN0aW9uKCdzZWxlY3RlZC10b29sdGlwJywgc2VsZWN0ZWRfdG9vbHRpcF8xLlNlbGVjdGVkVG9vbHRpcEFjdGlvbik7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJJbnRlcmFjdGlvbignc2VsZWN0ZWQtdG9vbHRpcCcsIHtcbiAgICBzdGFydDogW1xuICAgICAgICB7IHRyaWdnZXI6IGRlcGVuZGVudHNfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1BBSU5ULCBhY3Rpb246ICdzZWxlY3RlZC10b29sdGlwOnNob3cnIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUkVOREVSLCBhY3Rpb246ICdzZWxlY3RlZC10b29sdGlwOnNob3cnIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyaWdnZXI6ICdwbG90Om1vdXNlbW92ZScsXG4gICAgICAgICAgICBhY3Rpb246ICdzZWxlY3RlZC10b29sdGlwOnNob3cnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAncGxvdDp0b3VjaG1vdmUnLFxuICAgICAgICAgICAgYWN0aW9uOiAnc2VsZWN0ZWQtdG9vbHRpcDpzaG93JyxcbiAgICAgICAgICAgIHRocm90dGxlOiB7IHdhaXQ6IDUwLCBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2UgfSxcbiAgICAgICAgfSxcbiAgICBdLFxufSk7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJBY3Rpb24oJ21hcmtlci1hY3RpdmUnLCBtYXJrZXJfYWN0aXZlXzEuZGVmYXVsdCk7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJJbnRlcmFjdGlvbignbWFya2VyLWFjdGl2ZScsIHtcbiAgICBzdGFydDogW1xuICAgICAgICB7IHRyaWdnZXI6IGRlcGVuZGVudHNfMS5WSUVXX0xJRkVfQ0lSQ0xFLkFGVEVSX1BBSU5ULCBhY3Rpb246ICdtYXJrZXItYWN0aXZlOnNob3cnIH0sXG4gICAgICAgIHsgdHJpZ2dlcjogZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQUZURVJfUkVOREVSLCBhY3Rpb246ICdtYXJrZXItYWN0aXZlOnNob3cnIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRyaWdnZXI6ICdwbG90Om1vdXNlbW92ZScsXG4gICAgICAgICAgICBhY3Rpb246ICdtYXJrZXItYWN0aXZlOnNob3cnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAncGxvdDp0b3VjaG1vdmUnLFxuICAgICAgICAgICAgYWN0aW9uOiAnbWFya2VyLWFjdGl2ZTpzaG93JyxcbiAgICAgICAgICAgIHRocm90dGxlOiB7IHdhaXQ6IDUwLCBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2UgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ3Bsb3Q6bW91c2VsZWF2ZScsXG4gICAgICAgICAgICBhY3Rpb246ICdtYXJrZXItYWN0aXZlOmhpZGUnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0cmlnZ2VyOiAncGxvdDp0b3VjaGVuZCcsXG4gICAgICAgICAgICBhY3Rpb246ICdtYXJrZXItYWN0aXZlOmhpZGUnLFxuICAgICAgICAgICAgdGhyb3R0bGU6IHsgd2FpdDogNTAsIGxlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiBmYWxzZSB9LFxuICAgICAgICB9LFxuICAgIF0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29yZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2ludGVyYWN0aW9uL2NvcmVcIikpO1xudmFyIExpbmVBY3RpdmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTGluZUFjdGl2ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaW5lQWN0aXZlKGNmZykge1xuICAgICAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgdHNsaWJfMS5fX2Fzc2lnbih7IFxuICAgICAgICAgICAgLyoqIOayoeacieeUqCBsaW5lOm1vdXNlZW50ZXIg5ZKMIGxpbmU6bW91c2VsZWF2ZSDkuovku7bvvIzmmK/lm6DkuLrlj6/og73lnKjlpJrmnaHmipjnur/nmoTmg4XlhrXkuIvvvIzku47kuIDmnaHnur/mu5HliqjliLDlj6bkuIDmnaHkvJrlkIzml7bop6blj5Fwcm9jZXNz5ZKMcmVzZXTvvIzkvb/nlLvpnaLlh7rnjrDpl6rliqggKi9cbiAgICAgICAgICAgIHByb2Nlc3NFdmVudDogJ21vdXNlbW92ZScgfSwgY2ZnKSkgfHwgdGhpcztcbiAgICB9XG4gICAgTGluZUFjdGl2ZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIExpbmVBY3RpdmUucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdmFyIGxpbmVzID0gdXRpbF8xLmZpbHRlcih0aGlzLnZpZXcuZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb20pIHsgcmV0dXJuIGdlb20udHlwZSA9PSAnbGluZSc7IH0pO1xuICAgICAgICB2YXIgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBpZiAodGFyZ2V0LmdldCgnbmFtZScpID09PSAnbGluZScpIHtcbiAgICAgICAgICAgIHZhciBkYXRhXzEgPSB1dGlsXzEuZ2V0KGV2LCAnZGF0YS5kYXRhJyk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChsaW5lcywgZnVuY3Rpb24gKGxpbmUpIHtcbiAgICAgICAgICAgICAgICB1dGlsXzEuZWFjaChsaW5lLmVsZW1lbnRzLCBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldFN0YXRlKCdhY3RpdmUnLCBlbGVtZW50LmRhdGEgPT09IGRhdGFfMSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGxpbmVzLCBmdW5jdGlvbiAobGluZSkge1xuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGxpbmUuZWxlbWVudHMsIGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0U3RhdGUoJ2FjdGl2ZScsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gTGluZUFjdGl2ZTtcbn0oY29yZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpbmVBY3RpdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLWFjdGl2ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvcmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi9pbnRlcmFjdGlvbi9jb3JlXCIpKTtcbnZhciBMaW5lU2VsZWN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmVTZWxlY3QsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZVNlbGVjdChjZmcpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIHRzbGliXzEuX19hc3NpZ24oeyBlbmRFdmVudDogJ2NsaWNrJyB9LCBjZmcpKSB8fCB0aGlzO1xuICAgIH1cbiAgICBMaW5lU2VsZWN0LnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgTGluZVNlbGVjdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSBldi50YXJnZXQ7XG4gICAgICAgIHZhciBsaW5lcyA9IHV0aWxfMS5maWx0ZXIodGhpcy52aWV3Lmdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tKSB7IHJldHVybiBnZW9tLnR5cGUgPT0gJ2xpbmUnOyB9KTtcbiAgICAgICAgaWYgKHRhcmdldC5nZXQoJ25hbWUnKSA9PT0gJ2xpbmUnKSB7XG4gICAgICAgICAgICB2YXIgZGF0YV8xID0gdXRpbF8xLmdldChldiwgJ2RhdGEuZGF0YScpO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobGluZXMsIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gobGluZS5lbGVtZW50cywgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRTdGF0ZSgnaW5hY3RpdmUnLCBlbGVtZW50LmRhdGEgIT09IGRhdGFfMSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIFRPRE/vvJog6K6+572uei1pbmRleFxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2gobGluZXMsIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gobGluZS5lbGVtZW50cywgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRTdGF0ZSgnaW5hY3RpdmUnLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIFRPRE86IOmHjee9rnotaW5kZXhcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIExpbmVTZWxlY3Q7XG59KGNvcmVfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMaW5lU2VsZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGluZS1zZWxlY3QuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkFjdGl2ZVRvb2x0aXBDb250cm9sbGVyID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG4vLyBAdHMtaWdub3JlXG52YXIgQWN0aXZlVG9vbHRpcENvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQWN0aXZlVG9vbHRpcENvbnRyb2xsZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQWN0aXZlVG9vbHRpcENvbnRyb2xsZXIoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFjdGl2ZVRvb2x0aXBDb250cm9sbGVyLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3Rvb2x0aXAtYWN0aXZlJztcbiAgICAgICAgfSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuICAgIEFjdGl2ZVRvb2x0aXBDb250cm9sbGVyLnByb3RvdHlwZS5nZXRUb29sdGlwQ2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHZhciBjZmcgPSBfc3VwZXIucHJvdG90eXBlLmdldFRvb2x0aXBDZmcuY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7fSwgY2ZnKSwgeyBzaG93Q3Jvc3NoYWlyczogdHJ1ZSwgc2hvd01hcmtlcnM6IGZhbHNlLCBzaGFyZWQ6IHRydWUgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQWN0aXZlVG9vbHRpcENvbnRyb2xsZXI7XG59KGRlcGVuZGVudHNfMS5Ub29sdGlwQ29udHJvbGxlcikpO1xuZXhwb3J0cy5BY3RpdmVUb29sdGlwQ29udHJvbGxlciA9IEFjdGl2ZVRvb2x0aXBDb250cm9sbGVyO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyQ29tcG9uZW50Q29udHJvbGxlcigndG9vbHRpcC1hY3RpdmUnLCBBY3RpdmVUb29sdGlwQ29udHJvbGxlcik7XG52YXIgTWFya2VyQWN0aXZlQWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKE1hcmtlckFjdGl2ZUFjdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBNYXJrZXJBY3RpdmVBY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTWFya2VyQWN0aXZlQWN0aW9uLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDnp7vpmaTpu5jorqTnmoR0b29sdGlw5Lqk5LqSXG4gICAgICAgIHRoaXMuZ2V0VmlldygpLnJlbW92ZUludGVyYWN0aW9uKCd0b29sdGlwJyk7XG4gICAgfTtcbiAgICBNYXJrZXJBY3RpdmVBY3Rpb24ucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjdXJMb2NhdGlvbiA9IHRoaXMuZ2V0UG9pbnQoKTtcbiAgICAgICAgaWYgKGN1ckxvY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnNob3dUb29sdGlwKGN1ckxvY2F0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTWFya2VyQWN0aXZlQWN0aW9uLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMuZ2V0VmlldygpO1xuICAgICAgICB2YXIgY29udHJvbGxlciA9IHRoaXMuZ2V0VG9vbHRpcENvbnRyb2xsZXIoKTtcbiAgICAgICAgY29udHJvbGxlci5oaWRlVG9vbHRpcCgpO1xuICAgICAgICB2YXIgcG9pbnRzID0gdXRpbF8xLmZpbHRlcih2aWV3Lmdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tKSB7IHJldHVybiBnZW9tLnR5cGUgPT0gJ3BvaW50JzsgfSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwb2ludC5lbGVtZW50cywgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNldFN0YXRlKCdhY3RpdmUnLCBmYWxzZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBNYXJrZXJBY3RpdmVBY3Rpb24ucHJvdG90eXBlLnNob3dUb29sdGlwID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5nZXRWaWV3KCk7XG4gICAgICAgIHZhciBjb250cm9sbGVyID0gdGhpcy5nZXRUb29sdGlwQ29udHJvbGxlcigpO1xuICAgICAgICBjb250cm9sbGVyLnNob3dUb29sdGlwKHBvaW50KTtcbiAgICAgICAgdmFyIGl0ZW1zID0gY29udHJvbGxlci5nZXRUb29sdGlwSXRlbXMocG9pbnQpO1xuICAgICAgICB2YXIgcG9pbnRzID0gdXRpbF8xLmZpbHRlcih2aWV3Lmdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tKSB7IHJldHVybiBnZW9tLnR5cGUgPT0gJ3BvaW50JzsgfSk7XG4gICAgICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwb2ludC5lbGVtZW50cywgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnNldFN0YXRlKCdhY3RpdmUnLCB1dGlsXzEuZmluZEluZGV4KGl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbS5kYXRhID09PSBlbGVtZW50LmRhdGE7IH0pICE9PSAtMSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBNYXJrZXJBY3RpdmVBY3Rpb24ucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZXYgPSB0aGlzLmNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHJldHVybiBldiA/IHsgeDogZXYueCwgeTogZXYueSB9IDogbnVsbDtcbiAgICB9O1xuICAgIE1hcmtlckFjdGl2ZUFjdGlvbi5wcm90b3R5cGUuZ2V0VmlldyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC52aWV3O1xuICAgIH07XG4gICAgTWFya2VyQWN0aXZlQWN0aW9uLnByb3RvdHlwZS5nZXRUb29sdGlwQ29udHJvbGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmlldygpLmdldENvbnRyb2xsZXIoJ3Rvb2x0aXAtYWN0aXZlJyk7XG4gICAgfTtcbiAgICByZXR1cm4gTWFya2VyQWN0aXZlQWN0aW9uO1xufShkZXBlbmRlbnRzXzEuSW50ZXJhY3Rpb25BY3Rpb24pKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1hcmtlckFjdGl2ZUFjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1hcmtlci1hY3RpdmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlNlbGVjdGVkVG9vbHRpcEFjdGlvbiA9IGV4cG9ydHMuU2VsZWN0ZWRUb29sdGlwQ29udHJvbGxlciA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi9kZXBlbmRlbnRzXCIpO1xuLy8gQHRzLWlnbm9yZVxudmFyIFNlbGVjdGVkVG9vbHRpcENvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2VsZWN0ZWRUb29sdGlwQ29udHJvbGxlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTZWxlY3RlZFRvb2x0aXBDb250cm9sbGVyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTZWxlY3RlZFRvb2x0aXBDb250cm9sbGVyLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3NlbGVjdGVkLXRvb2x0aXAnO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgU2VsZWN0ZWRUb29sdGlwQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0VG9vbHRpcENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB2YXIgY2ZnID0gX3N1cGVyLnByb3RvdHlwZS5nZXRUb29sdGlwQ2ZnLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGNmZyksIHsgc2hvd0NvbnRlbnQ6IGZhbHNlLCBzaG93Q3Jvc3NoYWlyczogdHJ1ZSwgc2hvd01hcmtlcnM6IHRydWUsIHNoYXJlZDogdHJ1ZSB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTZWxlY3RlZFRvb2x0aXBDb250cm9sbGVyO1xufShkZXBlbmRlbnRzXzEuVG9vbHRpcENvbnRyb2xsZXIpKTtcbmV4cG9ydHMuU2VsZWN0ZWRUb29sdGlwQ29udHJvbGxlciA9IFNlbGVjdGVkVG9vbHRpcENvbnRyb2xsZXI7XG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJDb21wb25lbnRDb250cm9sbGVyKCdzZWxlY3RlZC10b29sdGlwJywgU2VsZWN0ZWRUb29sdGlwQ29udHJvbGxlcik7XG52YXIgU2VsZWN0ZWRUb29sdGlwQWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFNlbGVjdGVkVG9vbHRpcEFjdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTZWxlY3RlZFRvb2x0aXBBY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgU2VsZWN0ZWRUb29sdGlwQWN0aW9uLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3VyTG9jYXRpb24gPSB0aGlzLmdldFBvaW50KCk7XG4gICAgICAgIGlmICghdXRpbF8xLmlzRXF1YWwoY3VyTG9jYXRpb24sIHRoaXMubG9jYXRpb24pKSB7XG4gICAgICAgICAgICB0aGlzLmxvY2F0aW9uID0gY3VyTG9jYXRpb247XG4gICAgICAgICAgICB0aGlzLnNob3dUb29sdGlwKGN1ckxvY2F0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2VsZWN0ZWRUb29sdGlwQWN0aW9uLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udHJvbGxlciA9IHRoaXMuZ2V0VG9vbHRpcENvbnRyb2xsZXIoKTtcbiAgICAgICAgY29udHJvbGxlci5oaWRlVG9vbHRpcCgpO1xuICAgIH07XG4gICAgU2VsZWN0ZWRUb29sdGlwQWN0aW9uLnByb3RvdHlwZS5zaG93VG9vbHRpcCA9IGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICB2YXIgY29udHJvbGxlciA9IHRoaXMuZ2V0VG9vbHRpcENvbnRyb2xsZXIoKTtcbiAgICAgICAgY29udHJvbGxlci5zaG93VG9vbHRpcChwb2ludCk7XG4gICAgfTtcbiAgICBTZWxlY3RlZFRvb2x0aXBBY3Rpb24ucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZXYgPSB0aGlzLmNvbnRleHQuZXZlbnQ7XG4gICAgICAgIHJldHVybiBldiA/IHsgeDogZXYueCwgeTogZXYueSB9IDogdGhpcy5nZXRMYXN0WFBvaW50KCk7XG4gICAgfTtcbiAgICBTZWxlY3RlZFRvb2x0aXBBY3Rpb24ucHJvdG90eXBlLmdldExhc3RYUG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy5nZXRWaWV3KCk7XG4gICAgICAgIHZhciB4U2NhbGUgPSB2aWV3LmdldFhTY2FsZSgpO1xuICAgICAgICB2YXIgeVNjYWxlID0gdmlldy5nZXRZU2NhbGVzKClbMF07XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdmlldy5nZXRDb29yZGluYXRlKCk7XG4gICAgICAgIHZhciBsYXN0WCA9IHV0aWxfMS5sYXN0KHhTY2FsZS5nZXRUaWNrcygpKS52YWx1ZTtcbiAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGUuY29udmVydCh7IHg6IGxhc3RYLCB5OiAoeVNjYWxlLnJhbmdlWzBdICsgeVNjYWxlLnJhbmdlWzFdKSAvIDIgfSk7XG4gICAgfTtcbiAgICBTZWxlY3RlZFRvb2x0aXBBY3Rpb24ucHJvdG90eXBlLmdldFZpZXcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudmlldztcbiAgICB9O1xuICAgIFNlbGVjdGVkVG9vbHRpcEFjdGlvbi5wcm90b3R5cGUuZ2V0VG9vbHRpcENvbnRyb2xsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKCdzZWxlY3RlZC10b29sdGlwJyk7XG4gICAgfTtcbiAgICByZXR1cm4gU2VsZWN0ZWRUb29sdGlwQWN0aW9uO1xufShkZXBlbmRlbnRzXzEuSW50ZXJhY3Rpb25BY3Rpb24pKTtcbmV4cG9ydHMuU2VsZWN0ZWRUb29sdGlwQWN0aW9uID0gU2VsZWN0ZWRUb29sdGlwQWN0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0ZWQtdG9vbHRpcC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIHZpZXdfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3ZpZXctbGF5ZXJcIikpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9zY2FsZVwiKTtcbnZhciBjbGlwSW5fd2l0aF9kYXRhXzEgPSByZXF1aXJlKFwiLi9hbmltYXRpb24vY2xpcEluLXdpdGgtZGF0YVwiKTtcbnZhciBhcHBseV9yZXNwb25zaXZlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9hcHBseS1yZXNwb25zaXZlXCIpKTtcbnJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnRzL2xhYmVsL3BvaW50XCIpO1xucmVxdWlyZShcIi4uLy4uL2NvbXBvbmVudHMvbGFiZWwvcG9pbnQtYXV0b1wiKTtcbnZhciBsaW5lX2xhYmVsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jb21wb25lbnQvbGFiZWwvbGluZS1sYWJlbFwiKSk7XG52YXIgRXZlbnRQYXJzZXIgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi9ldmVudFwiKSk7XG52YXIgbWFya2VyX3BvaW50XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9tYXJrZXItcG9pbnRcIikpO1xucmVxdWlyZShcIi4vdGhlbWVcIik7XG5yZXF1aXJlKFwiLi9hcHBseS1yZXNwb25zaXZlL3RoZW1lXCIpO1xudmFyIGluZGV4XzEgPSByZXF1aXJlKFwiLi9pbnRlcmFjdGlvbi9pbmRleFwiKTtcbnZhciB2aWV3XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC92aWV3XCIpO1xudmFyIEdFT01fTUFQID0ge1xuICAgIGxpbmU6ICdsaW5lJyxcbiAgICBwb2ludDogJ3BvaW50Jyxcbn07XG52YXIgTGluZUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpbmVMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaW5lTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ2xpbmUnO1xuICAgICAgICBfdGhpcy5tYXJrZXJQb2ludHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBMaW5lTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIGNvbm5lY3ROdWxsczogZmFsc2UsXG4gICAgICAgICAgICBzbW9vdGg6IGZhbHNlLFxuICAgICAgICAgICAgbGluZVNpemU6IDIsXG4gICAgICAgICAgICBsaW5lU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBsaW5lSm9pbjogJ3JvdW5kJyxcbiAgICAgICAgICAgICAgICBsaW5lQ2FwOiAncm91bmQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvaW50OiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2l6ZTogMyxcbiAgICAgICAgICAgICAgICBzaGFwZTogJ2NpcmNsZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiAncG9pbnQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICd0b3AtbGVmdCcsXG4gICAgICAgICAgICAgICAgd29yZFNwYWNpbmc6IDQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHNob3dDb250ZW50OiB0cnVlLFxuICAgICAgICAgICAgICAgIGNyb3NzaGFpcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsMCwwLDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtYXJrZXJQb2ludHM6IFtdLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB0aGlzLnJlbmRlckxhYmVsKCk7XG4gICAgICAgIGlmIChvcHRpb25zLm1hcmtlclBvaW50cykge1xuICAgICAgICAgICAgLy8g5riF56m6XG4gICAgICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLm1hcmtlclBvaW50cywgZnVuY3Rpb24gKG1hcmtlclBvaW50KSB7IHJldHVybiBtYXJrZXJQb2ludC5kZXN0cm95KCk7IH0pO1xuICAgICAgICAgICAgdGhpcy5tYXJrZXJQb2ludHMgPSBbXTtcbiAgICAgICAgICAgIG9wdGlvbnMubWFya2VyUG9pbnRzLmZvckVhY2goZnVuY3Rpb24gKG1hcmtlclBvaW50T3B0KSB7XG4gICAgICAgICAgICAgICAgaWYgKG1hcmtlclBvaW50T3B0LnZpc2libGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmtlclBvaW50ID0gbmV3IG1hcmtlcl9wb2ludF8xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBtYXJrZXJQb2ludE9wdCksIHsgdmlldzogX3RoaXMudmlldyB9KSk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm1hcmtlclBvaW50cy5wdXNoKG1hcmtlclBvaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyDlk43lupTlvI9cbiAgICAgICAgaWYgKG9wdGlvbnMucmVzcG9uc2l2ZSAmJiBvcHRpb25zLnBhZGRpbmcgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5hcHBseVJlc3BvbnNpdmUoJ2FmdGVyUmVuZGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgTGluZUxheWVyLnByb3RvdHlwZS5nZXRDb2xvclNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VyaWVzRmllbGQgPSB0aGlzLm9wdGlvbnMuc2VyaWVzRmllbGQ7XG4gICAgICAgIGlmIChzZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoc2VyaWVzRmllbGQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMaW5lTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKGRpbSwgdHlwZSkge1xuICAgICAgICByZXR1cm4gR0VPTV9NQVBbdHlwZV07XG4gICAgfTtcbiAgICBMaW5lTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgLyoqIOmFjee9rngtc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW3Byb3BzLnhGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICd4QXhpcycpKSB7XG4gICAgICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXNbcHJvcHMueEZpZWxkXSwgcHJvcHMueEF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIC8qKiDphY3nva55LXNjYWxlICovXG4gICAgICAgIHNjYWxlc1twcm9wcy55RmllbGRdID0ge307XG4gICAgICAgIGlmICh1dGlsXzEuaGFzKHByb3BzLCAneUF4aXMnKSkge1xuICAgICAgICAgICAgc2NhbGVfMS5leHRyYWN0U2NhbGUoc2NhbGVzW3Byb3BzLnlGaWVsZF0sIHByb3BzLnlBeGlzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnc2NhbGVzJywgc2NhbGVzKTtcbiAgICAgICAgc2NhbGVfMS50cnlTZXRTY2FsZU1pblRvWmVybyhzY2FsZXNbcHJvcHMueUZpZWxkXSwgdXRpbF8xLm1hcChwcm9wcy5kYXRhIHx8IFtdLCBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbVtwcm9wcy55RmllbGRdOyB9KSk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2NhbGUuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUuY29vcmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUudG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g5aaC5p6c5pyJ5qCH5rOo54K577yM5YiZ5LiN5bGV56S6bWFya2Vyc1xuICAgICAgICBpZiAodXRpbF8xLnNvbWUodGhpcy5vcHRpb25zLm1hcmtlclBvaW50cywgZnVuY3Rpb24gKG1hcmtlclBvaW50T3B0KSB7IHJldHVybiBtYXJrZXJQb2ludE9wdC52aXNpYmxlOyB9KSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnRvb2x0aXAuc2hvd01hcmtlcnMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnRvb2x0aXAuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOmFjee9rue6v1xuICAgICAgICB0aGlzLmFkZExpbmUoKTtcbiAgICAgICAgLy8g6YWN572u5pWw5o2u54K5XG4gICAgICAgIHRoaXMuYWRkUG9pbnQoKTtcbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUuYWRkTGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB0aGlzLmxpbmUgPSBmYWN0b3J5XzEuZ2V0R2VvbSgnbGluZScsICdtYWluJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwcm9wcy50b29sdGlwICYmIChwcm9wcy50b29sdGlwLmZpZWxkcyB8fCBwcm9wcy50b29sdGlwLmZvcm1hdHRlcikpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VvbWV0cnlUb29sdGlwKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5JywgdGhpcy5saW5lKTtcbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUuYWRkUG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGRlZmF1bHRDb25maWcgPSB7IHZpc2libGU6IGZhbHNlIH07XG4gICAgICAgIGlmIChwcm9wcy5wb2ludCkge1xuICAgICAgICAgICAgcHJvcHMucG9pbnQgPSB1dGlsXzEuZGVlcE1peChkZWZhdWx0Q29uZmlnLCBwcm9wcy5wb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLnBvaW50ICYmIHByb3BzLnBvaW50LnZpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMucG9pbnQgPSBmYWN0b3J5XzEuZ2V0R2VvbSgncG9pbnQnLCAnZ3VpZGUnLCB7XG4gICAgICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5JywgdGhpcy5wb2ludCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmNvbmZpZy5zY2FsZXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgbGFiZWwgPSBfYS5sYWJlbCwgeUZpZWxkID0gX2EueUZpZWxkO1xuICAgICAgICB2YXIgc2NhbGUgPSBzY2FsZXNbeUZpZWxkXTtcbiAgICAgICAgaWYgKGxhYmVsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IHZpZXdfMS5nZXRHZW9tZXRyeUJ5VHlwZSh0aGlzLnZpZXcsICdsaW5lJyk7XG4gICAgICAgICAgICBpZiAobGFiZWwudHlwZSA9PT0gJ2xpbmUnKSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogTGluZSBMYWJlbCDov4Hnp7tcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWxfMSA9IG5ldyBsaW5lX2xhYmVsXzEuZGVmYXVsdCh0c2xpYl8xLl9fYXNzaWduKHsgdmlldzogdGhpcy52aWV3LCBwbG90OiB0aGlzIH0sIHRoaXMub3B0aW9ucy5sYWJlbCkpO1xuICAgICAgICAgICAgICAgIGxhYmVsXzEucmVuZGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvUmVuZGVyTGFiZWwoZ2VvbWV0cnksIHRzbGliXzEuX19hc3NpZ24oeyB0eXBlOiAncG9pbnQnLCBmb3JtYXR0ZXI6IHNjYWxlLmZvcm1hdHRlciAmJiAoZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBzY2FsZS5mb3JtYXR0ZXIodmFsdWUpOyB9KSB9LCB0aGlzLm9wdGlvbnMubGFiZWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgTGluZUxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMubGluZS50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLmxpbmUudG9vbHRpcC5maWVsZHMgPSB0b29sdGlwT3B0aW9ucy5maWVsZHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcikge1xuICAgICAgICAgICAgdGhpcy5saW5lLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAoIXRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIHRoaXMubGluZS50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMueEZpZWxkLCB0aGlzLm9wdGlvbnMueUZpZWxkXTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNlcmllc0ZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGluZS50b29sdGlwLmZpZWxkcy5wdXNoKHRoaXMub3B0aW9ucy5zZXJpZXNGaWVsZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBMaW5lTGF5ZXIucHJvdG90eXBlLmFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hbmltYXRpb24uY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAoIXByb3BzLmFuaW1hdGlvbikge1xuICAgICAgICAgICAgLy8g5YWz6Zet5Yqo55S7XG4gICAgICAgICAgICB0aGlzLmxpbmUuYW5pbWF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHRoaXMucG9pbnQpXG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludC5hbmltYXRlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjbGlwSW5fd2l0aF9kYXRhXzEuZ2V0UGxvdE9wdGlvbih7XG4gICAgICAgICAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgICAgICAgICAgIHZpZXc6IHRoaXMudmlldyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5saW5lLmFuaW1hdGUgPSBwcm9wcy5hbmltYXRpb247XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExpbmVMYXllci5wcm90b3R5cGUuYXBwbHlJbnRlcmFjdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYXBwbHlJbnRlcmFjdGlvbnMuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnMucHVzaChuZXcgaW5kZXhfMS5MaW5lQWN0aXZlKHtcbiAgICAgICAgICAgIHZpZXc6IHRoaXMudmlldyxcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLmludGVyYWN0aW9ucy5wdXNoKG5ldyBpbmRleF8xLkxpbmVTZWxlY3Qoe1xuICAgICAgICAgICAgdmlldzogdGhpcy52aWV3LFxuICAgICAgICB9KSk7XG4gICAgfTtcbiAgICBMaW5lTGF5ZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgRXZlbnRQYXJzZXIpO1xuICAgIH07XG4gICAgTGluZUxheWVyLnByb3RvdHlwZS5hcHBseVJlc3BvbnNpdmUgPSBmdW5jdGlvbiAoc3RhZ2UpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1ldGhvZHMgPSBhcHBseV9yZXNwb25zaXZlXzEuZGVmYXVsdFtzdGFnZV07XG4gICAgICAgIHV0aWxfMS5lYWNoKG1ldGhvZHMsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICB2YXIgcmVzcG9uc2l2ZSA9IHI7XG4gICAgICAgICAgICByZXNwb25zaXZlLm1ldGhvZChfdGhpcyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgTGluZUxheWVyLnByb3RvdHlwZS5zaW5nbGVMaW5lTGFiZWxDaGVjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g5LiN5YWB6K645Y2V5oqY57q/6K6+572u5bC+6YOo6Lef6ZqPbGFiZWxcbiAgICAgICAgcmV0dXJuICF0aGlzLm9wdGlvbnMuc2VyaWVzRmllbGQgJiYgdGhpcy5vcHRpb25zLmxhYmVsLnR5cGUgJiYgdGhpcy5vcHRpb25zLmxhYmVsLnR5cGUgPT09ICdsaW5lJztcbiAgICB9O1xuICAgIHJldHVybiBMaW5lTGF5ZXI7XG59KHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBMaW5lTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdsaW5lJywgTGluZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi4vLi4vdGhlbWVcIik7XG52YXIgTElORV9BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoX2EpIHtcbiAgICB2YXIgc2hhcGUgPSBfYS5zaGFwZTtcbiAgICB2YXIgbGluZVdpZHRoID0gc2hhcGUuYXR0cignbGluZVdpZHRoJykgfHwgMTtcbiAgICByZXR1cm4geyBsaW5lV2lkdGg6IGxpbmVXaWR0aCArIDEgfTtcbn07XG52YXIgTElORV9ESVNBQkxFX1NUWUxFID0gZnVuY3Rpb24gKF9hKSB7XG4gICAgdmFyIHNoYXBlID0gX2Euc2hhcGU7XG4gICAgdmFyIG9wYWNpdHkgPSBzaGFwZS5hdHRyKCdvcGFjaXR5JykgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5ICogMC4yIH07XG59O1xudmFyIExJTkVfU0VMRUNURURfU1RZTEUgPSBmdW5jdGlvbiAoX2EpIHtcbiAgICB2YXIgc2hhcGUgPSBfYS5zaGFwZTtcbiAgICB2YXIgbGluZVdpZHRoID0gc2hhcGUuYXR0cignbGluZVdpZHRoJykgfHwgMTtcbiAgICByZXR1cm4geyBsaW5lV2lkdGg6IGxpbmVXaWR0aCArIDIgfTtcbn07XG50aGVtZV8xLnJlZ2lzdGVyVGhlbWUoJ2xpbmUnLCB7XG4gICAgbGluZVN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogTElORV9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IExJTkVfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IExJTkVfU0VMRUNURURfU1RZTEUsXG4gICAgfSxcbiAgICBwb2ludFN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZToge30sXG4gICAgICAgIGRpc2FibGU6IHt9LFxuICAgICAgICBzZWxlY3RlZDoge30sXG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ191dGlsXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9nLXV0aWxcIik7XG5mdW5jdGlvbiBsaXF1aWRNb3ZlSW4oc2hhcGUsIGFuaW1hdGVDZmcpIHtcbiAgICB2YXIgY29udGFpbmVyID0gc2hhcGUuZ2V0KCdwYXJlbnQnKTtcbiAgICB2YXIgYm94ID0gY29udGFpbmVyLmdldEJCb3goKTtcbiAgICB2YXIgZmFjdG9yID0gTWF0aC5taW4oTWF0aC5tYXgoMCwgdXRpbF8xLmdldChhbmltYXRlQ2ZnLCAnZmFjdG9yJywgMC41KSksIDEpO1xuICAgIHZhciBkZWxheSA9IHV0aWxfMS5nZXQoYW5pbWF0ZUNmZywgJ2RlbGF5JywgMCk7XG4gICAgdmFyIGR1cmF0aW9uID0gdXRpbF8xLmdldChhbmltYXRlQ2ZnLCAnZHVyYXRpb24nLCA4MDApO1xuICAgIHZhciBjYWxsYmFjayA9IGFuaW1hdGVDZmcuY2FsbGJhY2s7XG4gICAgdmFyIG9yaWdpblggPSAoYm94Lm1pblggKyBib3gubWF4WCkgLyAyO1xuICAgIHZhciBvcmlnaW5ZID0gYm94Lm1heFk7XG4gICAgdmFyIHdyYXAgPSBjb250YWluZXIuZmluZChmdW5jdGlvbiAoc2hhcGUpIHsgcmV0dXJuIHNoYXBlLmdldCgnbmFtZScpID09ICd3cmFwJzsgfSk7XG4gICAgdmFyIHdyYXBUYXJnZXRPcGFjaXR5ID0gd3JhcC5hdHRyKCdvcGFjaXR5Jyk7XG4gICAgd3JhcC5hdHRyKCdvcGFjaXR5JywgMCk7XG4gICAgd3JhcC5hbmltYXRlKHsgb3BhY2l0eTogd3JhcFRhcmdldE9wYWNpdHkgfSwgZHVyYXRpb24gKiBmYWN0b3IsICdlYXNlTGluZWFyJywgbnVsbCwgZGVsYXkpO1xuICAgIHZhciB3YXZlcyA9IGNvbnRhaW5lci5maW5kKGZ1bmN0aW9uIChzaGFwZSkgeyByZXR1cm4gc2hhcGUuZ2V0KCduYW1lJykgPT0gJ3dhdmVzJzsgfSk7XG4gICAgdmFyIHdhdmVzVGFyZ2V0TWF0cml4ID0gdXRpbF8xLmNsb25lKHdhdmVzLmF0dHIoJ21hdHJpeCcpKSB8fCBbMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMV07XG4gICAgdmFyIHRyYW5zZm9ybU1hdHJpeCA9IGdfdXRpbF8xLnRyYW5zZm9ybSh3YXZlc1RhcmdldE1hdHJpeCwgW1xuICAgICAgICBbJ3QnLCAtb3JpZ2luWCwgLW9yaWdpblldLFxuICAgICAgICBbJ3MnLCAxLCAwXSxcbiAgICAgICAgWyd0Jywgb3JpZ2luWCwgb3JpZ2luWV0sXG4gICAgXSk7XG4gICAgd2F2ZXMuc2V0TWF0cml4KHRyYW5zZm9ybU1hdHJpeCk7XG4gICAgd2F2ZXMuYW5pbWF0ZSh7IG1hdHJpeDogd2F2ZXNUYXJnZXRNYXRyaXggfSwgZHVyYXRpb24sIGFuaW1hdGVDZmcuZWFzaW5nLCBmdW5jdGlvbiAoKSB7IHJldHVybiBjYWxsYmFjayAmJiBjYWxsYmFjayhjb250YWluZXIsIHdyYXAsIHdhdmVzKTsgfSwgZGVsYXkpO1xufVxubGlxdWlkTW92ZUluLmFuaW1hdGlvbk5hbWUgPSAnbGlxdWlkTW92ZUluJztcbmRlcGVuZGVudHNfMS5yZWdpc3RlckFuaW1hdGlvbignbGlxdWlkTW92ZUluJywgbGlxdWlkTW92ZUluKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpcXVpZC1tb3ZlLWluLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgc3RhdGlzdGljXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vY29tcG9uZW50cy9zdGF0aXN0aWNcIikpO1xudmFyIHN0YXRpc3RpY190ZW1wbGF0ZV8xID0gcmVxdWlyZShcIi4vc3RhdGlzdGljLXRlbXBsYXRlXCIpO1xudmFyIFJpbmdTdGF0aXN0aWMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUmluZ1N0YXRpc3RpYywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSaW5nU3RhdGlzdGljKGNmZykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjZmcpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnZpZXcgPSBjZmcudmlldztcbiAgICAgICAgX3RoaXMucGxvdCA9IGNmZy5wbG90O1xuICAgICAgICBfdGhpcy5zdGF0aXN0aWNDbGFzcyA9IGNmZy5zdGF0aXN0aWNDbGFzcztcbiAgICAgICAgX3RoaXMuYWRqdXN0T3B0aW9ucygpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKiDkuK3lv4PmlofmnKzmmL7npLogKi9cbiAgICBSaW5nU3RhdGlzdGljLnByb3RvdHlwZS5nZXRUb3RhbEh0bWxTdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGF0aXN0aWNDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5wbG90Lm9wdGlvbnMsIF9iID0gX2EudmFsdWUsIHZhbHVlID0gX2IgPT09IHZvaWQgMCA/IDAgOiBfYiwgc3RhdGlzdGljID0gX2Euc3RhdGlzdGljO1xuICAgICAgICBpZiAoc3RhdGlzdGljICYmICFzdGF0aXN0aWMudmlzaWJsZSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YXRpc3RpY0NvbnRhaW5lcjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaHRtbENvbnRlbnQgPSB0aGlzLm9wdGlvbnMuaHRtbENvbnRlbnQodmFsdWUpO1xuICAgICAgICBpZiAodXRpbF8xLmlzVHlwZShodG1sQ29udGVudCwgJ0hUTUxEaXZFbGVtZW50JykpIHtcbiAgICAgICAgICAgIHN0YXRpc3RpY0NvbnRhaW5lci5hcHBlbmRDaGlsZChodG1sQ29udGVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGF0aXN0aWNDb250YWluZXIuaW5uZXJIVE1MID0gc3RhdGlzdGljX3RlbXBsYXRlXzEuZ2V0VGVtcGxhdGUoaHRtbENvbnRlbnQsIHRoaXMuc3RhdGlzdGljQ2xhc3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGF0aXN0aWNDb250YWluZXI7XG4gICAgfTtcbiAgICBSaW5nU3RhdGlzdGljLnByb3RvdHlwZS5hZGp1c3RPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmh0bWwgPSB0aGlzLmdldFRvdGFsSHRtbFN0cmluZygpO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLnZpZXcuY29vcmRpbmF0ZUJCb3gsIG1pblggPSBfYS5taW5YLCBtaW5ZID0gX2EubWluWSwgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICAgICAgICB0aGlzLnggPSBtaW5YICsgd2lkdGggLyAyO1xuICAgICAgICB0aGlzLnkgPSBtaW5ZICsgaGVpZ2h0IC8gMjtcbiAgICB9O1xuICAgIHJldHVybiBSaW5nU3RhdGlzdGljO1xufShzdGF0aXN0aWNfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSaW5nU3RhdGlzdGljO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGlxdWlkLXN0YXRpc3RpYy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0VGVtcGxhdGUgPSB2b2lkIDA7XG4vKnRzbGludDpkaXNhYmxlKi9cbnZhciBjb250YWluZXJTdHlsZSA9IFwiY29sb3I6IzRkNGQ0ZDtmb250LXNpemU6MTRweDt0ZXh0LWFsaWduOmNlbnRlcjtsaW5lLWhlaWdodDoyO2ZvbnQtZmFtaWx5OictYXBwbGUtc3lzdGVtJyxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lVUknLFJvYm90bywnSGVsdmV0aWNhTmV1ZScsSGVsdmV0aWNhLCdQaW5nRmFuZ1NDJywnSGlyYWdpbm9TYW5zR0InLCdNaWNyb3NvZnRZYUhlaScsU2ltU3VuLCdzYW5zLXNlcmlmJztwb2ludGVyLWV2ZW50czpub25lO1wiO1xudmFyIHZhbHVlU3R5bGUgPSAnZm9udC1zaXplOjMycHg7Zm9udC13ZWlnaHQ6Ym9sZDtjb2xvcjojNEQ0RDREJztcbmZ1bmN0aW9uIGdldFRlbXBsYXRlKHZhbHVlLCBjbGFzc05hbWUpIHtcbiAgICB2YXIgdmFsdWVEb21TdHIgPSBcIjxzcGFuIGNsYXNzPVxcXCJsaXF1aWQtZ3VpZGUtdmFsdWVcXFwiIHN0eWxlPVwiICsgdmFsdWVTdHlsZSArIFwiPlwiICsgdmFsdWUgKyBcIjwvc3Bhbj5cIjtcbiAgICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJsaXF1aWQtZ3VpZGUtaHRtbCBcIiArIGNsYXNzTmFtZSArIFwiXFxcIiBzdHlsZT1cIiArIGNvbnRhaW5lclN0eWxlICsgXCI+XCIgKyB2YWx1ZURvbVN0ciArIFwiPC9kaXY+XCI7XG59XG5leHBvcnRzLmdldFRlbXBsYXRlID0gZ2V0VGVtcGxhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGF0aXN0aWMtdGVtcGxhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBsaXF1aWQ6ICdpbnRlcnZsJyxcbiAgICBzdGF0aXN0aWM6ICdhbm5vdGF0aW9uLXRleHQnLFxufTtcbnZhciBTSEFQRV9FVkVOVF9NQVAgPSBldmVudF8xLmdldEV2ZW50TWFwKGNvbXBvbmVudE1hcCk7XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi90aGVtZVwiKTtcbnZhciBnX3V0aWxfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi91dGlsL2ctdXRpbFwiKTtcbnZhciBnbG9iYWxUaGVtZSA9IHRoZW1lXzEuZ2V0R2xvYmFsVGhlbWUoKTtcbnZhciBTaGFwZVV0aWwgPSB7XG4gICAgc3BsaXRQb2ludHM6IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IFtdO1xuICAgICAgICB2YXIgeCA9IG9iai54O1xuICAgICAgICB2YXIgeSA9IG9iai55O1xuICAgICAgICB5ID0gdXRpbF8xLmlzQXJyYXkoeSkgPyB5IDogW3ldO1xuICAgICAgICB1dGlsXzEuZWFjaCh5LCBmdW5jdGlvbiAoeUl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSB7XG4gICAgICAgICAgICAgICAgeDogdXRpbF8xLmlzQXJyYXkoeCkgPyB4W2luZGV4XSA6IHgsXG4gICAgICAgICAgICAgICAgeTogeUl0ZW0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcG9pbnRzLnB1c2gocG9pbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBvaW50cztcbiAgICB9LFxuICAgIGFkZEZpbGxBdHRyczogZnVuY3Rpb24gKGF0dHJzLCBjZmcpIHtcbiAgICAgICAgaWYgKGNmZy5jb2xvciAmJiAhYXR0cnMuZmlsbCkge1xuICAgICAgICAgICAgYXR0cnMuZmlsbCA9IGNmZy5jb2xvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKGNmZy5vcGFjaXR5KSkge1xuICAgICAgICAgICAgYXR0cnMub3BhY2l0eSA9IGF0dHJzLmZpbGxPcGFjaXR5ID0gY2ZnLm9wYWNpdHk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFkZFN0cm9rZUF0dHJzOiBmdW5jdGlvbiAoYXR0cnMsIGNmZykge1xuICAgICAgICBpZiAoY2ZnLmNvbG9yICYmICFhdHRycy5zdHJva2UpIHtcbiAgICAgICAgICAgIGF0dHJzLnN0cm9rZSA9IGNmZy5jb2xvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKGNmZy5vcGFjaXR5KSkge1xuICAgICAgICAgICAgYXR0cnMub3BhY2l0eSA9IGF0dHJzLnN0cm9rZU9wYWNpdHkgPSBjZmcub3BhY2l0eTtcbiAgICAgICAgfVxuICAgIH0sXG59O1xudmFyIFZhbHVlVXRpbCA9IHtcbiAgICBsZXJwOiBmdW5jdGlvbiAoYSwgYiwgZmFjdG9yKSB7XG4gICAgICAgIHJldHVybiAoMSAtIGZhY3RvcikgKiBhICsgZmFjdG9yICogYjtcbiAgICB9LFxufTtcbnZhciBnZXRGaWxsQXR0cnMgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgdmFyIGRlZmF1bHRBdHRycyA9IHtcbiAgICAgICAgbGluZVdpZHRoOiAwLFxuICAgICAgICBmaWxsOiBnbG9iYWxUaGVtZS5jb2xvcixcbiAgICAgICAgZmlsbE9wYWNpdHk6IDAuODUsXG4gICAgfTtcbiAgICB2YXIgYXR0cnMgPSB1dGlsXzEubWl4KHt9LCBkZWZhdWx0QXR0cnMsIGNmZy5zdHlsZSk7XG4gICAgU2hhcGVVdGlsLmFkZEZpbGxBdHRycyhhdHRycywgY2ZnKTtcbiAgICBpZiAoY2ZnLmNvbG9yICYmICFhdHRycy5zdHJva2UpIHtcbiAgICAgICAgYXR0cnMuc3Ryb2tlID0gYXR0cnMuc3Ryb2tlIHx8IGNmZy5jb2xvcjtcbiAgICB9XG4gICAgcmV0dXJuIGF0dHJzO1xufTtcbnZhciBnZXRMaW5lQXR0cnMgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgdmFyIGRlZmF1bHRBdHRycyA9IHtcbiAgICAgICAgZmlsbDogJyNmZmYnLFxuICAgICAgICBzdHJva2U6IGdsb2JhbFRoZW1lLmNvbG9yLFxuICAgICAgICBmaWxsT3BhY2l0eTogMCxcbiAgICAgICAgbGluZVdpZHRoOiAyLFxuICAgIH07XG4gICAgdmFyIGF0dHJzID0gdXRpbF8xLm1peCh7fSwgZGVmYXVsdEF0dHJzLCBjZmcuc3R5bGUpO1xuICAgIFNoYXBlVXRpbC5hZGRTdHJva2VBdHRycyhhdHRycywgY2ZnKTtcbiAgICByZXR1cm4gYXR0cnM7XG59O1xuLyoqXG4gKiDnlKjotJ3loZ7lsJTmm7Lnur/mqKHmi5/mraPlvKbms6JcbiAqIFVzaW5nIEJlemllciBjdXJ2ZXMgdG8gZml0IHNpbmUgd2F2ZS5cbiAqIFRoZXJlIGlzIDQgY29udHJvbCBwb2ludHMgZm9yIGVhY2ggY3VydmUgb2Ygd2F2ZSxcbiAqIHdoaWNoIGlzIGF0IDEvNCB3YXZlIGxlbmd0aCBvZiB0aGUgc2luZSB3YXZlLlxuICpcbiAqIFRoZSBjb250cm9sIHBvaW50cyBmb3IgYSB3YXZlIGZyb20gKGEpIHRvIChkKSBhcmUgYS1iLWMtZDpcbiAqICAgICAgICAgIGMgKi0tLS0qIGRcbiAqICAgICBiICpcbiAqICAgICAgIHxcbiAqIC4uLiBhICogLi4uLi4uLi4uLi4uLi4uLi4uXG4gKlxuICogd2hvc2UgcG9zaXRpb25zIGFyZSBhOiAoMCwgMCksIGI6ICgwLjUsIDAuNSksIGM6ICgxLCAxKSwgZDogKFBJIC8gMiwgMSlcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0geCAgICAgICAgICB4IHBvc2l0aW9uIG9mIHRoZSBsZWZ0LW1vc3QgcG9pbnQgKGEpXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhZ2UgICAgICAwLTMsIHN0YXRpbmcgd2hpY2ggcGFydCBvZiB0aGUgd2F2ZSBpdCBpc1xuICogQHBhcmFtIHtudW1iZXJ9IHdhdmVMZW5ndGggd2F2ZSBsZW5ndGggb2YgdGhlIHNpbmUgd2F2ZVxuICogQHBhcmFtIHtudW1iZXJ9IGFtcGxpdHVkZSAgd2F2ZSBhbXBsaXR1ZGVcbiAqIEByZXR1cm4ge0FycmF5fSDmraPlvKbniYfmrrXmm7Lnur9cbiAqL1xuZnVuY3Rpb24gZ2V0V2F0ZXJXYXZlUG9zaXRpb25zKHgsIHN0YWdlLCB3YXZlTGVuZ3RoLCBhbXBsaXR1ZGUpIHtcbiAgICBpZiAoc3RhZ2UgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFt4ICsgKCgxIC8gMikgKiB3YXZlTGVuZ3RoKSAvIE1hdGguUEkgLyAyLCBhbXBsaXR1ZGUgLyAyXSxcbiAgICAgICAgICAgIFt4ICsgKCgxIC8gMikgKiB3YXZlTGVuZ3RoKSAvIE1hdGguUEksIGFtcGxpdHVkZV0sXG4gICAgICAgICAgICBbeCArIHdhdmVMZW5ndGggLyA0LCBhbXBsaXR1ZGVdLFxuICAgICAgICBdO1xuICAgIH1cbiAgICBpZiAoc3RhZ2UgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFt4ICsgKCgoMSAvIDIpICogd2F2ZUxlbmd0aCkgLyBNYXRoLlBJIC8gMikgKiAoTWF0aC5QSSAtIDIpLCBhbXBsaXR1ZGVdLFxuICAgICAgICAgICAgW3ggKyAoKCgxIC8gMikgKiB3YXZlTGVuZ3RoKSAvIE1hdGguUEkgLyAyKSAqIChNYXRoLlBJIC0gMSksIGFtcGxpdHVkZSAvIDJdLFxuICAgICAgICAgICAgW3ggKyB3YXZlTGVuZ3RoIC8gNCwgMF0sXG4gICAgICAgIF07XG4gICAgfVxuICAgIGlmIChzdGFnZSA9PT0gMikge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgW3ggKyAoKDEgLyAyKSAqIHdhdmVMZW5ndGgpIC8gTWF0aC5QSSAvIDIsIC1hbXBsaXR1ZGUgLyAyXSxcbiAgICAgICAgICAgIFt4ICsgKCgxIC8gMikgKiB3YXZlTGVuZ3RoKSAvIE1hdGguUEksIC1hbXBsaXR1ZGVdLFxuICAgICAgICAgICAgW3ggKyB3YXZlTGVuZ3RoIC8gNCwgLWFtcGxpdHVkZV0sXG4gICAgICAgIF07XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICAgIFt4ICsgKCgoMSAvIDIpICogd2F2ZUxlbmd0aCkgLyBNYXRoLlBJIC8gMikgKiAoTWF0aC5QSSAtIDIpLCAtYW1wbGl0dWRlXSxcbiAgICAgICAgW3ggKyAoKCgxIC8gMikgKiB3YXZlTGVuZ3RoKSAvIE1hdGguUEkgLyAyKSAqIChNYXRoLlBJIC0gMSksIC1hbXBsaXR1ZGUgLyAyXSxcbiAgICAgICAgW3ggKyB3YXZlTGVuZ3RoIC8gNCwgMF0sXG4gICAgXTtcbn1cbi8qKlxuICog6I635Y+W5rC05rOi6Lev5b6EXG4gKiBAcGFyYW0gIHtudW1iZXJ9IHJhZGl1cyAgICAgICAgICDljYrlvoRcbiAqIEBwYXJhbSAge251bWJlcn0gd2F0ZXJMZXZlbCAgICAgIOawtOS9jVxuICogQHBhcmFtICB7bnVtYmVyfSB3YXZlTGVuZ3RoICAgICAg5rOi6ZW/XG4gKiBAcGFyYW0gIHtudW1iZXJ9IHBoYXNlICAgICAgICAgICDnm7jkvY1cbiAqIEBwYXJhbSAge251bWJlcn0gYW1wbGl0dWRlICAgICAgIOmch+W5hVxuICogQHBhcmFtICB7bnVtYmVyfSBjeCAgICAgICAgICAgICAg5ZyG5b+DeFxuICogQHBhcmFtICB7bnVtYmVyfSBjeSAgICAgICAgICAgICAg5ZyG5b+DeVxuICogQHJldHVybiB7QXJyYXl9ICBwYXRoICAgICAgICAgICAg6Lev5b6EXG4gKiBAcmVmZXJlbmNlIGh0dHA6Ly9naXRsYWIuYWxpcGF5LWluYy5jb20vZGF0YXZpcy9nNi9ibG9iLzEuMi4wL3NyYy9ncmFwaC91dGlscy9wYXRoLmpzI0wxMzVcbiAqL1xuZnVuY3Rpb24gZ2V0V2F0ZXJXYXZlUGF0aChyYWRpdXMsIHdhdGVyTGV2ZWwsIHdhdmVMZW5ndGgsIHBoYXNlLCBhbXBsaXR1ZGUsIGN4LCBjeSkge1xuICAgIHZhciBjdXJ2ZXMgPSBNYXRoLmNlaWwoKCgyICogcmFkaXVzKSAvIHdhdmVMZW5ndGgpICogNCkgKiAyO1xuICAgIHZhciBwYXRoID0gW107XG4gICAgdmFyIF9waGFzZSA9IHBoYXNlO1xuICAgIC8vIG1hcCBwaGFzZSB0byBbLU1hdGguUEkgKiAyLCAwXVxuICAgIHdoaWxlIChfcGhhc2UgPCAtTWF0aC5QSSAqIDIpIHtcbiAgICAgICAgX3BoYXNlICs9IE1hdGguUEkgKiAyO1xuICAgIH1cbiAgICB3aGlsZSAoX3BoYXNlID4gMCkge1xuICAgICAgICBfcGhhc2UgLT0gTWF0aC5QSSAqIDI7XG4gICAgfVxuICAgIF9waGFzZSA9IChfcGhhc2UgLyBNYXRoLlBJIC8gMikgKiB3YXZlTGVuZ3RoO1xuICAgIHZhciBsZWZ0ID0gY3ggLSByYWRpdXMgKyBfcGhhc2UgLSByYWRpdXMgKiAyO1xuICAgIC8qKlxuICAgICAqIHRvcC1sZWZ0IGNvcm5lciBhcyBzdGFydCBwb2ludFxuICAgICAqXG4gICAgICogZHJhd3MgdGhpcyBwb2ludFxuICAgICAqICB8XG4gICAgICogXFx8L1xuICAgICAqICB+fn5+fn5+flxuICAgICAqICB8ICAgICAgfFxuICAgICAqICArLS0tLS0tK1xuICAgICAqL1xuICAgIHBhdGgucHVzaChbJ00nLCBsZWZ0LCB3YXRlckxldmVsXSk7XG4gICAgLyoqXG4gICAgICogdG9wIHdhdmVcbiAgICAgKlxuICAgICAqIH5+fn5+fn5+IDwtIGRyYXdzIHRoaXMgc2luZSB3YXZlXG4gICAgICogfCAgICAgIHxcbiAgICAgKiArLS0tLS0tK1xuICAgICAqL1xuICAgIHZhciB3YXZlUmlnaHQgPSAwO1xuICAgIGZvciAodmFyIGMgPSAwOyBjIDwgY3VydmVzOyArK2MpIHtcbiAgICAgICAgdmFyIHN0YWdlID0gYyAlIDQ7XG4gICAgICAgIHZhciBwb3MgPSBnZXRXYXRlcldhdmVQb3NpdGlvbnMoKGMgKiB3YXZlTGVuZ3RoKSAvIDQsIHN0YWdlLCB3YXZlTGVuZ3RoLCBhbXBsaXR1ZGUpO1xuICAgICAgICBwYXRoLnB1c2goW1xuICAgICAgICAgICAgJ0MnLFxuICAgICAgICAgICAgcG9zWzBdWzBdICsgbGVmdCxcbiAgICAgICAgICAgIC1wb3NbMF1bMV0gKyB3YXRlckxldmVsLFxuICAgICAgICAgICAgcG9zWzFdWzBdICsgbGVmdCxcbiAgICAgICAgICAgIC1wb3NbMV1bMV0gKyB3YXRlckxldmVsLFxuICAgICAgICAgICAgcG9zWzJdWzBdICsgbGVmdCxcbiAgICAgICAgICAgIC1wb3NbMl1bMV0gKyB3YXRlckxldmVsLFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKGMgPT09IGN1cnZlcyAtIDEpIHtcbiAgICAgICAgICAgIHdhdmVSaWdodCA9IHBvc1syXVswXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiB0b3AtcmlnaHQgY29ybmVyXG4gICAgICpcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgfn5+fn5+fn5cbiAgICAgKiAzLiBkcmF3cyB0aGlzIGxpbmUgLT4gfCAgICAgIHwgPC0gMS4gZHJhd3MgdGhpcyBsaW5lXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0rXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIF5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICAgICAqICAgICAgICAgICAgICAgICAgMi4gZHJhd3MgdGhpcyBsaW5lXG4gICAgICovXG4gICAgcGF0aC5wdXNoKFsnTCcsIHdhdmVSaWdodCArIGxlZnQsIGN5ICsgcmFkaXVzXSk7XG4gICAgcGF0aC5wdXNoKFsnTCcsIGxlZnQsIGN5ICsgcmFkaXVzXSk7XG4gICAgcGF0aC5wdXNoKFsnTCcsIGxlZnQsIHdhdGVyTGV2ZWxdKTtcbiAgICByZXR1cm4gcGF0aDtcbn1cbi8qKlxuICog5re75Yqg5rC05rOiXG4gKiBAcGFyYW0ge251bWJlcn0geCAgICAgICAgICAg5Lit5b+DeFxuICogQHBhcmFtIHtudW1iZXJ9IHkgICAgICAgICAgIOS4reW/g3lcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAgICAgICDmsLTkvY3nrYnnuqcgMO+9njFcbiAqIEBwYXJhbSB7bnVtYmVyfSB3YXZlQ291bnQgICDmsLTms6LmlbBcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb2xvcnMgICAgICDoibLlgLxcbiAqIEBwYXJhbSB7bnVtYmVyfSBncm91cCAgICAgICDlm77nu4RcbiAqIEBwYXJhbSB7bnVtYmVyfSBjbGlwICAgICAgICDnlKjkuo7liarliIfnmoTlm77lvaJcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWRpdXMgICAgICDnu5jliLblm77lvaLnmoTpq5jluqZcbiAqL1xuZnVuY3Rpb24gYWRkV2F0ZXJXYXZlKHgsIHksIGxldmVsLCB3YXZlQ291bnQsIGNvbG9yLCBncm91cCwgY2xpcCwgcmFkaXVzKSB7XG4gICAgdmFyIGJib3ggPSBjbGlwLmdldEJCb3goKTtcbiAgICB2YXIgd2lkdGggPSBiYm94Lm1heFggLSBiYm94Lm1pblg7XG4gICAgdmFyIGhlaWdodCA9IGJib3gubWF4WSAtIGJib3gubWluWTtcbiAgICB2YXIgZHVyYXRpb24gPSA1MDAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgd2F2ZUNvdW50OyBpKyspIHtcbiAgICAgICAgdmFyIGZhY3RvciA9IHdhdmVDb3VudCA8PSAxID8gMCA6IGkgLyAod2F2ZUNvdW50IC0gMSk7XG4gICAgICAgIHZhciB3YXZlID0gZ3JvdXAuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHBhdGg6IGdldFdhdGVyV2F2ZVBhdGgocmFkaXVzLCBiYm94Lm1pblkgKyBoZWlnaHQgKiBsZXZlbCwgd2lkdGggLyA0LCAwLCB3aWR0aCAvIFZhbHVlVXRpbC5sZXJwKDU2LCA2NCwgZmFjdG9yKSwgeCwgeSksXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogVmFsdWVVdGlsLmxlcnAoMC42LCAwLjMsIGZhY3RvciksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgLyp3YXZlLnNldENsaXAoe1xuICAgICAgICAgIHR5cGU6J2NpcmNsZScsXG4gICAgICAgICAgYXR0cnM6IGNsaXAuYXR0cnNcbiAgICAgICAgfSkqL1xuICAgICAgICAvLyBGSVhNRSB3YXZlIGFuaW1hdGlvbiBlcnJvciBpbiBzdmdcbiAgICAgICAgLy8gaWYgKEdsb2JhbC5yZW5kZXJlciA9PT0gJ2NhbnZhcycpIHtcbiAgICAgICAgdmFyIG1hdHJpeCA9IGdfdXRpbF8xLnRyYW5zZm9ybShbWyd0Jywgd2lkdGggLyAyLCAwXV0pO1xuICAgICAgICB3YXZlLmFuaW1hdGUoeyBtYXRyaXg6IG1hdHJpeCB9LCB7XG4gICAgICAgICAgICBkdXJhdGlvbjogVmFsdWVVdGlsLmxlcnAoZHVyYXRpb24sIDAuNyAqIGR1cmF0aW9uLCBmYWN0b3IpLFxuICAgICAgICAgICAgcmVwZWF0OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgLy99XG4gICAgfVxufVxuZGVwZW5kZW50c18xLnJlZ2lzdGVyU2hhcGUoJ2ludGVydmFsJywgJ2xpcXVpZC1maWxsLWdhdWdlJywge1xuICAgIGRyYXc6IGZ1bmN0aW9uIChjZmcsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgY3kgPSAwLjU7XG4gICAgICAgIHZhciBtaW5YID0gSW5maW5pdHk7XG4gICAgICAgIHV0aWxfMS5lYWNoKGNmZy5wb2ludHMsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICBpZiAocC54IDwgbWluWCkge1xuICAgICAgICAgICAgICAgIG1pblggPSBwLng7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY3ggPSAwLjU7XG4gICAgICAgIHZhciBjcCA9IHRoaXMucGFyc2VQb2ludCh7IHg6IGN4LCB5OiBjeSB9KTtcbiAgICAgICAgdmFyIG1pblAgPSB0aGlzLnBhcnNlUG9pbnQoeyB4OiBtaW5YLCB5OiAwLjUgfSk7XG4gICAgICAgIHZhciB4V2lkdGggPSBjcC54IC0gbWluUC54O1xuICAgICAgICB2YXIgcmFkaXVzID0gTWF0aC5taW4oeFdpZHRoLCBtaW5QLnkpO1xuICAgICAgICB2YXIgZmlsbCA9IGdldEZpbGxBdHRycyhjZmcpLmZpbGw7XG4gICAgICAgIHZhciB3YXZlcyA9IGNvbnRhaW5lci5hZGRHcm91cCh7XG4gICAgICAgICAgICBuYW1lOiAnd2F2ZXMnLFxuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4OiBjcC54LFxuICAgICAgICAgICAgICAgIHk6IGNwLnksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgd2F2ZXMuc2V0Q2xpcCh7XG4gICAgICAgICAgICB0eXBlOiAnY2lyY2xlJyxcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgICAgeDogY3AueCxcbiAgICAgICAgICAgICAgICB5OiBjcC55LFxuICAgICAgICAgICAgICAgIHI6IHJhZGl1cyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY2xpcENpcmNsZSA9IHdhdmVzLmdldCgnY2xpcFNoYXBlJyk7XG4gICAgICAgIGFkZFdhdGVyV2F2ZShjcC54LCBjcC55LCAxIC0gY2ZnLnBvaW50c1sxXS55LCAvLyBjZmcueSAvICgyICogY3AueSksXG4gICAgICAgIDMsIGZpbGwsIHdhdmVzLCBjbGlwQ2lyY2xlLCByYWRpdXMgKiA0KTtcbiAgICAgICAgY29udGFpbmVyLmFkZFNoYXBlKCdjaXJjbGUnLCB7XG4gICAgICAgICAgICBuYW1lOiAnd3JhcCcsXG4gICAgICAgICAgICBhdHRyczogdXRpbF8xLm1peChnZXRMaW5lQXR0cnMoY2ZnKSwge1xuICAgICAgICAgICAgICAgIHg6IGNwLngsXG4gICAgICAgICAgICAgICAgeTogY3AueSxcbiAgICAgICAgICAgICAgICByOiByYWRpdXMsXG4gICAgICAgICAgICAgICAgZmlsbDogJ3RyYW5zcGFyZW50JyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHdhdmVzWzBdO1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpcXVpZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgTGlxdWlkID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKExpcXVpZCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaXF1aWQoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgTGlxdWlkLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnbGlxdWlkJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIExpcXVpZC5wcm90b3R5cGUuY2hhbmdlVmFsdWUgPSBmdW5jdGlvbiAodmFsdWUsIGFsbCkge1xuICAgICAgICBpZiAoYWxsID09PSB2b2lkIDApIHsgYWxsID0gZmFsc2U7IH1cbiAgICAgICAgaWYgKGFsbCkge1xuICAgICAgICAgICAgdGhpcy5lYWNoTGF5ZXIoZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGxheWVyIGluc3RhbmNlb2YgbGF5ZXJfMS5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGxheWVyLmNoYW5nZVZhbHVlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICAgICAgaWYgKGxheWVyIGluc3RhbmNlb2YgbGF5ZXJfMS5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgbGF5ZXIuY2hhbmdlVmFsdWUodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBMaXF1aWQuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIExpcXVpZDtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpcXVpZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZG9tX3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9kb20tdXRpbFwiKTtcbnZhciBiYm94XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vdXRpbC9iYm94XCIpKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvc2NhbGVcIik7XG52YXIgY29sb3JfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2NvbG9yXCIpO1xudmFyIGxpcXVpZF9zdGF0aXN0aWNfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbXBvbmVudC9saXF1aWQtc3RhdGlzdGljXCIpKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnJlcXVpcmUoXCIuL2dlb21ldHJ5L3NoYXBlL2xpcXVpZFwiKTtcbnJlcXVpcmUoXCIuL2FuaW1hdGlvbi9saXF1aWQtbW92ZS1pblwiKTtcbnZhciBHMl9HRU9NX01BUCA9IHtcbiAgICBjb2x1bW46ICdpbnRlcnZhbCcsXG59O1xudmFyIFBMT1RfR0VPTV9NQVAgPSB7XG4gICAgaW50ZXJ2YWw6ICdsaXF1aWQnLFxufTtcbnZhciBMaXF1aWRMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaXF1aWRMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBMaXF1aWRMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnbGlxdWlkJztcbiAgICAgICAgX3RoaXMuc2hvdWxkRmFkZUluQW5ub3RhdGlvbiA9IHRydWU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgTGlxdWlkTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSB7XG4gICAgICAgICAgICBwYWRkaW5nOiBbMCwgMCwgMCwgMF0sXG4gICAgICAgICAgICBhbmltYXRpb246IHtcbiAgICAgICAgICAgICAgICBmYWN0b3I6IDAuNCxcbiAgICAgICAgICAgICAgICBlYXNpbmc6ICdlYXNlRXhwT3V0JyxcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogODAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpcXVpZFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbG9yOiAnIzZhOTlmOScsXG4gICAgICAgICAgICBpbnRlcmFjdGlvbnM6IFtdLFxuICAgICAgICAgICAgc3RhdGlzdGljOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIGNmZyk7XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuYmVmb3JlSW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heCwgdmFsdWUgPSBfYS52YWx1ZTtcbiAgICAgICAgaWYgKCF1dGlsXzEuaXNOdW1iZXIobWluKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgbWluIHZhbHVlIG9mIExpcXVpZCBpcyByZXF1aXJlZCwgYW5kIHRoZSB0eXBlIG9mIG1pbiBtdXN0IGJlIE51bWJlci4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXV0aWxfMS5pc051bWJlcihtYXgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBtYXggdmFsdWUgb2YgTGlxdWlkIGlzIHJlcXVpcmVkLCBhbmQgdGhlIHR5cGUgb2YgbWF4IG11c3QgYmUgTnVtYmVyLicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXRpbF8xLmlzTnVtYmVyKHZhbHVlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgdmFsdWUgb2YgTGlxdWlkIGlzIHJlcXVpcmVkLCBhbmQgdGhlIHR5cGUgb2YgdmFsdWUgbXVzdCBiZSBOdW1iZXIuJyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExpcXVpZExheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9wdGlvbnMuZGF0YSA9IFt7fV07XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgTGlxdWlkTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIG1pbiA9IHByb3BzLm1pbiwgbWF4ID0gcHJvcHMubWF4O1xuICAgICAgICB2YXIgc2NhbGVzID0ge1xuICAgICAgICAgICAgdmFsdWU6IHt9LFxuICAgICAgICB9O1xuICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXMudmFsdWUsIHtcbiAgICAgICAgICAgIG1pbjogTWF0aC5taW4obWluLCBtYXgpLFxuICAgICAgICAgICAgbWF4OiBNYXRoLm1heChtaW4sIG1heCksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuYXhpcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2F4ZXMnLCBmYWxzZSk7XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuYWRqdXN0TGlxdWlkID0gZnVuY3Rpb24gKGxpcXVpZCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGxpcXVpZC5zaGFwZSA9IHtcbiAgICAgICAgICAgIHZhbHVlczogWydsaXF1aWQtZmlsbC1nYXVnZSddLFxuICAgICAgICB9O1xuICAgICAgICBsaXF1aWQudG9vbHRpcCA9IGZhbHNlO1xuICAgICAgICB2YXIgbGlxdWlkU3R5bGUgPSBwcm9wcy5saXF1aWRTdHlsZTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKGxpcXVpZFN0eWxlKSlcbiAgICAgICAgICAgIGxpcXVpZFN0eWxlID0gbGlxdWlkU3R5bGUoKTtcbiAgICAgICAgaWYgKGxpcXVpZFN0eWxlKSB7XG4gICAgICAgICAgICBsaXF1aWQuc3R5bGUgPSBsaXF1aWRTdHlsZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTGlxdWlkTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGlxdWlkID0gZmFjdG9yeV8xLmdldEdlb20oJ2ludGVydmFsJywgJ21haW4nLCB7XG4gICAgICAgICAgICBwb3NpdGlvbkZpZWxkczogWzEsICd2YWx1ZSddLFxuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWRqdXN0TGlxdWlkKGxpcXVpZCk7XG4gICAgICAgIHZhciB2aWV3UmFuZ2UgPSB0aGlzLmdldFZpZXdSYW5nZSgpO1xuICAgICAgICB2YXIgZGVmYXVsdFNpemUgPSBNYXRoLm1pbih2aWV3UmFuZ2Uud2lkdGgsIHZpZXdSYW5nZS5oZWlnaHQpICogMC44O1xuICAgICAgICB2YXIgbGlxdWlkU2l6ZSA9IHRoaXMub3B0aW9ucy5saXF1aWRTaXplID8gdGhpcy5vcHRpb25zLmxpcXVpZFNpemUgOiBkZWZhdWx0U2l6ZTtcbiAgICAgICAgbGlxdWlkLnNpemUgPSB7IHZhbHVlczogW2xpcXVpZFNpemVdIH07XG4gICAgICAgIHRoaXMubGlxdWlkID0gbGlxdWlkO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBsaXF1aWQpO1xuICAgIH07XG4gICAgTGlxdWlkTGF5ZXIucHJvdG90eXBlLmFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAocHJvcHMuYW5pbWF0aW9uID09PSBmYWxzZSkge1xuICAgICAgICAgICAgLyoqIOWFs+mXreWKqOeUuyAqL1xuICAgICAgICAgICAgdGhpcy5saXF1aWQuYW5pbWF0ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGZhY3RvciA9IHV0aWxfMS5nZXQocHJvcHMsICdhbmltYXRpb24uZmFjdG9yJyk7XG4gICAgICAgICAgICB2YXIgZWFzaW5nID0gdXRpbF8xLmdldChwcm9wcywgJ2FuaW1hdGlvbi5lYXNpbmcnKTtcbiAgICAgICAgICAgIHZhciBkdXJhdGlvbiA9IHV0aWxfMS5nZXQocHJvcHMsICdhbmltYXRpb24uZHVyYXRpb24nKTtcbiAgICAgICAgICAgIHRoaXMubGlxdWlkLmFuaW1hdGUgPSB7XG4gICAgICAgICAgICAgICAgYXBwZWFyOiB7XG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbjogJ2xpcXVpZE1vdmVJbicsXG4gICAgICAgICAgICAgICAgICAgIGZhY3RvcjogZmFjdG9yLFxuICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IGR1cmF0aW9uLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoZGltLCB0eXBlKSB7XG4gICAgICAgIGlmIChkaW0gPT09ICdnMicpIHtcbiAgICAgICAgICAgIHJldHVybiBHMl9HRU9NX01BUFt0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUExPVF9HRU9NX01BUFt0eXBlXTtcbiAgICB9O1xuICAgIExpcXVpZExheWVyLnByb3RvdHlwZS5hbm5vdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYW5ub3RhdGlvbkNvbmZpZ3MgPSBbXTtcbiAgICAgICAgdmFyIHN0YXRpc3RpY0NvbmZpZyA9IHRoaXMuZXh0cmFjdFN0YXRpc3RpYygpO1xuICAgICAgICBhbm5vdGF0aW9uQ29uZmlncy5wdXNoKHN0YXRpc3RpY0NvbmZpZyk7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdhbm5vdGF0aW9ucycsIGFubm90YXRpb25Db25maWdzKTtcbiAgICB9O1xuICAgIC8vIOaWsOWiniBodG1sQ29udGVudCDmlK/mjIHvvIzlhbzlrrnml6flip/og71cbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUudXNlSHRtbENvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHN0YXRpc3RpYyA9IHByb3BzLnN0YXRpc3RpYyB8fCB7fTtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5pc0Z1bmN0aW9uKHN0YXRpc3RpYy5odG1sQ29udGVudCk7XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuZXh0cmFjdFN0YXRpc3RpYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMudXNlSHRtbENvbnRlbnQoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHN0YXRpc3RpYyA9IHByb3BzLnN0YXRpc3RpYyB8fCB7fTtcbiAgICAgICAgdmFyIGNvbnRlbnQ7XG4gICAgICAgIGlmICh1dGlsXzEuaXNGdW5jdGlvbihzdGF0aXN0aWMuZm9ybWF0dGVyKSkge1xuICAgICAgICAgICAgY29udGVudCA9IHN0YXRpc3RpYy5mb3JtYXR0ZXIocHJvcHMudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29udGVudCA9IFwiXCIgKyBwcm9wcy52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm9udFNpemU7XG4gICAgICAgIHZhciBzaGFkb3dCbHVyO1xuICAgICAgICBpZiAoY29udGVudCkge1xuICAgICAgICAgICAgdmFyIGNvbnRlbnRXaWR0aCA9IE1hdGgubWluKHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcbiAgICAgICAgICAgIGZvbnRTaXplID0gKGNvbnRlbnRXaWR0aCAvIGNvbnRlbnQubGVuZ3RoKSAqIDAuNTtcbiAgICAgICAgICAgIHNoYWRvd0JsdXIgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwoMC4wMjUgKiBmb250U2l6ZSkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvcGFjaXR5O1xuICAgICAgICBpZiAoc3RhdGlzdGljLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHN0YXRpc3RpY0NvbmZpZyA9IHV0aWxfMS5kZWVwTWl4KHtcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZm9udFNpemU6IGZvbnRTaXplLFxuICAgICAgICAgICAgICAgIHNoYWRvd0JsdXI6IHNoYWRvd0JsdXIsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LCB7XG4gICAgICAgICAgICB0b3A6IHRydWUsXG4gICAgICAgICAgICBjb250ZW50OiBjb250ZW50LFxuICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgcG9zaXRpb246IFsnNTAlJywgJzUwJSddLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBvcGFjaXR5LFxuICAgICAgICAgICAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgICAgICAgICAgc2hhZG93Q29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sIHN0YXRpc3RpYyk7XG4gICAgICAgIGRlbGV0ZSBzdGF0aXN0aWNDb25maWcudmlzaWJsZTtcbiAgICAgICAgZGVsZXRlIHN0YXRpc3RpY0NvbmZpZy5mb3JtYXR0ZXI7XG4gICAgICAgIGRlbGV0ZSBzdGF0aXN0aWNDb25maWcuYWRqdXN0Q29sb3I7XG4gICAgICAgIHJldHVybiBzdGF0aXN0aWNDb25maWc7XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBFdmVudFBhcnNlcik7XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgaWYgKCgoX2EgPSB0aGlzLm9wdGlvbnMuc3RhdGlzdGljKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EudmlzaWJsZSkgJiYgIXRoaXMudXNlSHRtbENvbnRlbnQoKSkge1xuICAgICAgICAgICAgdGhpcy5mYWRlSW5Bbm5vdGF0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBwYWRkaW5nID0gb3B0aW9ucy5wYWRkaW5nID8gb3B0aW9ucy5wYWRkaW5nIDogdGhpcy5jb25maWcudGhlbWUucGFkZGluZztcbiAgICAgICAgLyoqIGRlZmF1bHRTdGF0ZSAqL1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0U3RhdGUgJiYgcGFkZGluZyAhPT0gJ2F1dG8nKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlQ29udHJvbGxlci5kZWZhdWx0U3RhdGVzKG9wdGlvbnMuZGVmYXVsdFN0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICAvKiogYXV0b3BhZGRpbmcgKi9cbiAgICAgICAgaWYgKHBhZGRpbmcgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgdGhpcy5wYWRkaW5nQ29udHJvbGxlci5wcm9jZXNzQXV0b1BhZGRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51c2VIdG1sQ29udGVudCgpKSB7XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5jYW52YXMuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRpc3RpYykge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZCh0aGlzLnN0YXRpc3RpYy53cmFwcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKirlm77kuK3lv4PmlofmnKwgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3RhdGlzdGljICYmIHRoaXMub3B0aW9ucy5zdGF0aXN0aWMudmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHZhciBjb250YWluZXJfMSA9IHRoaXMuY2FudmFzLmdldCgnY29udGFpbmVyJyk7XG4gICAgICAgICAgICAgICAgZG9tX3V0aWxfMS5tb2RpZnlDU1MoY29udGFpbmVyXzEsIHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0aXN0aWMgPSBuZXcgbGlxdWlkX3N0YXRpc3RpY18xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IGNvbnRhaW5lcjogY29udGFpbmVyXzEsIHZpZXc6IHRoaXMudmlldywgcGxvdDogdGhpcyB9LCB0aGlzLm9wdGlvbnMuc3RhdGlzdGljKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0aXN0aWMucmVuZGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyLmNhbGwodGhpcyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExpcXVpZExheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICByZXR1cm4gW3sgXzogJ18nLCB2YWx1ZTogcHJvcHMudmFsdWUgfV07XG4gICAgfTtcbiAgICBMaXF1aWRMYXllci5wcm90b3R5cGUuY2hhbmdlVmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBwcm9wcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLmNoYW5nZURhdGEoW10pO1xuICAgIH07XG4gICAgTGlxdWlkTGF5ZXIucHJvdG90eXBlLmZhZGVJbkFubm90YXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHRleHRTaGFwZSA9IHRoaXMudmlldy5mb3JlZ3JvdW5kR3JvdXAuZmluZEFsbChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgIHJldHVybiBlbC5nZXQoJ25hbWUnKSA9PT0gJ2Fubm90YXRpb24tdGV4dCc7XG4gICAgICAgIH0pWzBdO1xuICAgICAgICB2YXIgYW5pbWF0aW9uID0gcHJvcHMuYW5pbWF0aW9uIHx8IHt9O1xuICAgICAgICB2YXIgY29sb3JTdHlsZSA9IHRoaXMuY2FsY0Fubm90YXRpb25Db2xvclN0eWxlKCk7XG4gICAgICAgIGlmICh0aGlzLnNob3VsZEZhZGVJbkFubm90YXRpb24pIHtcbiAgICAgICAgICAgIHRleHRTaGFwZS5hbmltYXRlKGNvbG9yU3R5bGUsIGFuaW1hdGlvbi5kdXJhdGlvbiAqIE1hdGgubWluKDEsIDEuNSAqIGFuaW1hdGlvbi5mYWN0b3IpLCBudWxsLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2hvdWxkRmFkZUluQW5ub3RhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB1dGlsXzEuZm9ySW4oY29sb3JTdHlsZSwgZnVuY3Rpb24gKHYsIGspIHsgcmV0dXJuIHRleHRTaGFwZS5hdHRyKGssIHYpOyB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTGlxdWlkTGF5ZXIucHJvdG90eXBlLmNhbGNBbm5vdGF0aW9uQ29sb3JTdHlsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgbGlnaHRDb2xvclN0eWxlID0geyBmaWxsOiAnI2Y2ZjZmNicsIHNoYWRvd0NvbG9yOiAnYmxhY2snIH07XG4gICAgICAgIHZhciBkYXJrQ29sb3JTdHlsZSA9IHsgZmlsbDogJyMzMDMwMzAnLCBzaGFkb3dDb2xvcjogJ3doaXRlJyB9O1xuICAgICAgICBpZiAodXRpbF8xLmdldChwcm9wcywgJ3N0YXRpc3RpYy5hZGp1c3RDb2xvcicpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmaWxsOiB1dGlsXzEuZ2V0KHByb3BzLCAnc3RhdGlzdGljLnN0eWxlLmZpbGwnLCBkYXJrQ29sb3JTdHlsZS5maWxsKSxcbiAgICAgICAgICAgICAgICBzaGFkb3dDb2xvcjogdXRpbF8xLmdldChwcm9wcywgJ3N0YXRpc3RpYy5zdHlsZS5zaGFkb3dDb2xvcicsIGRhcmtDb2xvclN0eWxlLnNoYWRvd0NvbG9yKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1pbiA9IHByb3BzLm1pbiwgbWF4ID0gcHJvcHMubWF4O1xuICAgICAgICB2YXIgdmFsdWUgPSBwcm9wcy52YWx1ZTtcbiAgICAgICAgbWluID0gTWF0aC5taW4obWluLCBtYXgpO1xuICAgICAgICBtYXggPSBNYXRoLm1heChtaW4sIG1heCk7XG4gICAgICAgIHZhciBwZXJjZW50O1xuICAgICAgICBpZiAobWluID09IG1heCkge1xuICAgICAgICAgICAgcGVyY2VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gKHZhbHVlIC0gbWluKSAvIChtYXggLSBtaW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwZXJjZW50ID4gMC41NSkge1xuICAgICAgICAgICAgdmFyIHdhdmVDb2xvciA9IHRoaXMub3B0aW9ucy5jb2xvcjtcbiAgICAgICAgICAgIHZhciB3YXZlT3BhY2l0eSA9IDAuODtcbiAgICAgICAgICAgIHZhciByZ2IgPSBjb2xvcl8xLnJnYjJhcnIod2F2ZUNvbG9yKTtcbiAgICAgICAgICAgIHZhciBncmF5ID0gTWF0aC5yb3VuZChyZ2JbMF0gKiAwLjI5OSArIHJnYlsxXSAqIDAuNTg3ICsgcmdiWzJdICogMC4xMTQpIC8gd2F2ZU9wYWNpdHk7XG4gICAgICAgICAgICByZXR1cm4gZ3JheSA8IDE1NiA/IGxpZ2h0Q29sb3JTdHlsZSA6IGRhcmtDb2xvclN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXJrQ29sb3JTdHlsZTtcbiAgICB9O1xuICAgIExpcXVpZExheWVyLnByb3RvdHlwZS51cGRhdGVDb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUudXBkYXRlQ29uZmlnLmNhbGwodGhpcywgY2ZnKTtcbiAgICAgICAgdGhpcy5zaG91bGRGYWRlSW5Bbm5vdGF0aW9uID0gdHJ1ZTtcbiAgICB9O1xuICAgIExpcXVpZExheWVyLnByb3RvdHlwZS5nZXRWaWV3UmFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2aWV3UmFuZ2UgPSBfc3VwZXIucHJvdG90eXBlLmdldFZpZXdSYW5nZS5jYWxsKHRoaXMpO1xuICAgICAgICB2YXIgbGlxdWlkU3R5bGUgPSB0aGlzLm9wdGlvbnMubGlxdWlkU3R5bGU7XG4gICAgICAgIHZhciBzdHJva2VXaWR0aCA9IGxpcXVpZFN0eWxlLmxpbmVXaWR0aCA/IGxpcXVpZFN0eWxlLmxpbmVXaWR0aCA6IDI7XG4gICAgICAgIHZhciBtaW5YID0gdmlld1JhbmdlLm1pblgsIG1pblkgPSB2aWV3UmFuZ2UubWluWSwgd2lkdGggPSB2aWV3UmFuZ2Uud2lkdGgsIGhlaWdodCA9IHZpZXdSYW5nZS5oZWlnaHQ7XG4gICAgICAgIHZhciBzaXplID0gTWF0aC5taW4od2lkdGgsIGhlaWdodCkgLSBzdHJva2VXaWR0aCAqIDI7XG4gICAgICAgIHZhciBjeCA9IG1pblggKyB3aWR0aCAvIDI7XG4gICAgICAgIHZhciBjeSA9IG1pblkgKyBoZWlnaHQgLyAyO1xuICAgICAgICB2YXIgeCA9IGN4IC0gc2l6ZSAvIDI7XG4gICAgICAgIHZhciB5ID0gY3kgLSBzaXplIC8gMjtcbiAgICAgICAgcmV0dXJuIG5ldyBiYm94XzEuZGVmYXVsdCh4LCB5LCBzaXplLCBzaXplKTtcbiAgICB9O1xuICAgIHJldHVybiBMaXF1aWRMYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExpcXVpZExheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnbGlxdWlkJywgTGlxdWlkTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIE1ldGVyR2F1Z2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTWV0ZXJHYXVnZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBNZXRlckdhdWdlKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIE1ldGVyR2F1Z2UucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdtZXRlckdhdWdlJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIE1ldGVyR2F1Z2UuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIE1ldGVyR2F1Z2U7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBNZXRlckdhdWdlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2dhdWdlL2xheWVyXCIpKTtcbnZhciBNZXRlckdhdWdlTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTWV0ZXJHYXVnZUxheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIE1ldGVyR2F1Z2VMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnbWV0ZXJHYXVnZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgTWV0ZXJHYXVnZUxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICBheGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IC0xMCxcbiAgICAgICAgICAgICAgICB0aWNrQ291bnQ6IDI1LFxuICAgICAgICAgICAgICAgIHN1YlRpY2tDb3VudDogNCxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBsZW5ndGg6IDIsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICcjYWFhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gTWV0ZXJHYXVnZUxheWVyO1xufShsYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1ldGVyR2F1Z2VMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ21ldGVyR2F1Z2UnLCBNZXRlckdhdWdlTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFBlcmNlbnRTdGFja2VkQXJlYSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQZXJjZW50U3RhY2tlZEFyZWEsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUGVyY2VudFN0YWNrZWRBcmVhKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFBlcmNlbnRTdGFja2VkQXJlYS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3BlcmNlbnRTdGFja2VkQXJlYSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBQZXJjZW50U3RhY2tlZEFyZWEuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFBlcmNlbnRTdGFja2VkQXJlYTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBlcmNlbnRTdGFja2VkQXJlYTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9zdGFja2VkLWFyZWEvbGF5ZXJcIikpO1xudmFyIGRhdGFfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2RhdGFcIik7XG52YXIgUGVyY2VudFN0YWNrZWRBcmVhTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGVyY2VudFN0YWNrZWRBcmVhTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUGVyY2VudFN0YWNrZWRBcmVhTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3BlcmNlbnRTdGFja2VkQXJlYSc7XG4gICAgICAgIF90aGlzLmJhc2VUeXBlID0gJ3N0YWNrZWRBcmVhJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBQZXJjZW50U3RhY2tlZEFyZWFMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlcjogZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWcgPSAvJS9naTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2LnJlcGxhY2UocmVnLCAnJyk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUGVyY2VudFN0YWNrZWRBcmVhTGF5ZXIucHJvdG90eXBlLnByb2Nlc3NEYXRhID0gZnVuY3Rpb24gKG9yaWdpbkRhdGEpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZDtcbiAgICAgICAgcmV0dXJuIGRhdGFfMS50cmFuc2Zvcm1EYXRhUGVyY2VudGFnZShvcmlnaW5EYXRhLCB4RmllbGQsIFt5RmllbGRdKTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQXJlYUxheWVyLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1ldGFDb25maWcgPSB7fTtcbiAgICAgICAgdmFyIHlGaWVsZCA9IHRoaXMub3B0aW9ucy55RmllbGQ7XG4gICAgICAgIG1ldGFDb25maWdbdGhpcy5vcHRpb25zLnlGaWVsZF0gPSB7XG4gICAgICAgICAgICB0aWNrQ291bnQ6IDYsXG4gICAgICAgICAgICBhbGlhczogeUZpZWxkICsgXCIgKCUpXCIsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBmb3JtYXR0ZXI6IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgdmFyIGZvcm1hdHRlZFZhbHVlID0gKHYgKiAxMDApLnRvRml4ZWQoMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlZFZhbHVlICsgXCIlXCI7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9wdGlvbnMubWV0YSA9IHV0aWxfMS5kZWVwTWl4KHt9LCBtZXRhQ29uZmlnLCB0aGlzLm9wdGlvbnMubWV0YSk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2NhbGUuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIHJldHVybiBQZXJjZW50U3RhY2tlZEFyZWFMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQZXJjZW50U3RhY2tlZEFyZWFMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3BlcmNlbnRTdGFja2VkQXJlYScsIFBlcmNlbnRTdGFja2VkQXJlYUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBQZXJjZW50U3RhY2tlZEJhciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQZXJjZW50U3RhY2tlZEJhciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQZXJjZW50U3RhY2tlZEJhcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBQZXJjZW50U3RhY2tlZEJhci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3BlcmNlbnRTdGFja2VkQmFyJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQmFyLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBQZXJjZW50U3RhY2tlZEJhcjtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBlcmNlbnRTdGFja2VkQmFyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3N0YWNrZWQtYmFyL2xheWVyXCIpKTtcbnZhciBkYXRhXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9kYXRhXCIpO1xudmFyIFBlcmNlbnRTdGFja2VkQmFyTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGVyY2VudFN0YWNrZWRCYXJMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQZXJjZW50U3RhY2tlZEJhckxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdwZXJjZW50U3RhY2tlZEJhcic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUGVyY2VudFN0YWNrZWRCYXJMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgeEF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlcjogZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHYgKyBcIiAoJSlcIjsgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVnID0gLyUvZ2k7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdi5yZXBsYWNlKHJlZywgJycpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQmFyTGF5ZXIucHJvdG90eXBlLnByb2Nlc3NEYXRhID0gZnVuY3Rpb24gKG9yaWdpbkRhdGEpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZDtcbiAgICAgICAgdmFyIHByb2Nlc3NEYXRhID0gX3N1cGVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YS5jYWxsKHRoaXMsIG9yaWdpbkRhdGEpO1xuICAgICAgICByZXR1cm4gZGF0YV8xLnRyYW5zZm9ybURhdGFQZXJjZW50YWdlKHByb2Nlc3NEYXRhLCB5RmllbGQsIFt4RmllbGRdKTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQmFyTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWV0YUNvbmZpZyA9IHt9O1xuICAgICAgICB2YXIgeEZpZWxkID0gdGhpcy5vcHRpb25zLnhGaWVsZDtcbiAgICAgICAgbWV0YUNvbmZpZ1t4RmllbGRdID0ge1xuICAgICAgICAgICAgdGlja0NvdW50OiA2LFxuICAgICAgICAgICAgYWxpYXM6IHhGaWVsZCArIFwiICglKVwiLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgZm9ybWF0dGVyOiBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIHZhciBmb3JtYXR0ZWRWYWx1ZSA9ICh2ICogMTAwKS50b0ZpeGVkKDEpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZWRWYWx1ZSArIFwiJVwiO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vcHRpb25zLm1ldGEgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5vcHRpb25zLm1ldGEsIG1ldGFDb25maWcpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICByZXR1cm4gUGVyY2VudFN0YWNrZWRCYXJMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQZXJjZW50U3RhY2tlZEJhckxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgncGVyY2VudFN0YWNrZWRCYXInLCBQZXJjZW50U3RhY2tlZEJhckxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBQZXJjZW50U3RhY2tlZENvbHVtbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQZXJjZW50U3RhY2tlZENvbHVtbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQZXJjZW50U3RhY2tlZENvbHVtbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBQZXJjZW50U3RhY2tlZENvbHVtbi5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3BlcmNlbnRTdGFja2VkQ29sdW1uJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQ29sdW1uLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBQZXJjZW50U3RhY2tlZENvbHVtbjtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBlcmNlbnRTdGFja2VkQ29sdW1uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3N0YWNrZWQtY29sdW1uL2xheWVyXCIpKTtcbnZhciBkYXRhXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9kYXRhXCIpO1xudmFyIFBlcmNlbnRTdGFja2VkQ29sdW1uTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGVyY2VudFN0YWNrZWRDb2x1bW5MYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQZXJjZW50U3RhY2tlZENvbHVtbkxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdwZXJjZW50U3RhY2tlZENvbHVtbic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUGVyY2VudFN0YWNrZWRDb2x1bW5MYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHRpY2s6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQ29sdW1uTGF5ZXIucHJvdG90eXBlLnByb2Nlc3NEYXRhID0gZnVuY3Rpb24gKG9yaWdpbkRhdGEpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCB4RmllbGQgPSBfYS54RmllbGQsIHlGaWVsZCA9IF9hLnlGaWVsZDtcbiAgICAgICAgcmV0dXJuIGRhdGFfMS50cmFuc2Zvcm1EYXRhUGVyY2VudGFnZShvcmlnaW5EYXRhIHx8IFtdLCB4RmllbGQsIFt5RmllbGRdKTtcbiAgICB9O1xuICAgIFBlcmNlbnRTdGFja2VkQ29sdW1uTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWV0YUNvbmZpZyA9IHt9O1xuICAgICAgICB2YXIgeUZpZWxkID0gdGhpcy5vcHRpb25zLnlGaWVsZDtcbiAgICAgICAgbWV0YUNvbmZpZ1t5RmllbGRdID0ge1xuICAgICAgICAgICAgdGlja0NvdW50OiA2LFxuICAgICAgICAgICAgYWxpYXM6IHlGaWVsZCArIFwiICglKVwiLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgZm9ybWF0dGVyOiBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIHZhciBmb3JtYXR0ZWRWYWx1ZSA9ICh2ICogMTAwKS50b0ZpeGVkKDEpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZWRWYWx1ZSArIFwiJVwiO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vcHRpb25zLm1ldGEgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5vcHRpb25zLm1ldGEsIG1ldGFDb25maWcpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICByZXR1cm4gUGVyY2VudFN0YWNrZWRDb2x1bW5MYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQZXJjZW50U3RhY2tlZENvbHVtbkxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgncGVyY2VudFN0YWNrZWRDb2x1bW4nLCBQZXJjZW50U3RhY2tlZENvbHVtbkxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5wZXJjZW50Mk51bWJlciA9IGV4cG9ydHMuQ1JPT0tfRElTVEFOQ0UgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHV0aWxzXzEgPSByZXF1aXJlKFwiLi91dGlsc1wiKTtcbnZhciB0ZXh0XzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vLi4vdXRpbC90ZXh0XCIpO1xuLyoqIGxhYmVsIHRleHTlkoxsaW5l6Led56a7IDRweCAqL1xuZXhwb3J0cy5DUk9PS19ESVNUQU5DRSA9IDQ7XG5mdW5jdGlvbiBwZXJjZW50Mk51bWJlcih2YWx1ZSkge1xuICAgIHZhciBwZXJjZW50YWdlID0gTnVtYmVyKHZhbHVlLmVuZHNXaXRoKCclJykgPyB2YWx1ZS5zbGljZSgwLCAtMSkgOiB2YWx1ZSk7XG4gICAgcmV0dXJuIHBlcmNlbnRhZ2UgLyAxMDA7XG59XG5leHBvcnRzLnBlcmNlbnQyTnVtYmVyID0gcGVyY2VudDJOdW1iZXI7XG4vKipcbiAqIOi2heWHunBhbmVs6L6555WM55qE5qCH562+6buY6K6k6ZqQ6JePXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSW5QYW5lbChsYWJlbCwgcGFuZWwpIHtcbiAgICB2YXIgYm94ID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgIC8vICDmqKrlkJHmuqLlh7og5pqC5LiN6ZqQ6JePXG4gICAgaWYgKCEocGFuZWwueSA8PSBib3gueSAmJiBwYW5lbC55ICsgcGFuZWwuaGVpZ2h0ID49IGJveC55ICsgYm94LmhlaWdodCkpIHtcbiAgICAgICAgbGFiZWwuZ2V0KCdwYXJlbnQnKS5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgfVxufVxudmFyIFBpZUJhc2VMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBQaWVCYXNlTGFiZWwocGxvdCwgY2ZnKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucGxvdCA9IHBsb3Q7XG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZUJCb3ggPSB0aGlzLnBsb3Qudmlldy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB1dGlsXzEuZGVlcE1peCh0aGlzLmdldERlZmF1bHRPcHRpb25zKCksIGNmZywge30pO1xuICAgICAgICB0aGlzLmFkanVzdE9wdGlvbihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIC8qKiDlpITnkIbmoIfnrb7pga7mjKHpl67popggKi9cbiAgICBQaWVCYXNlTGFiZWwucHJvdG90eXBlLmFkanVzdE92ZXJsYXAgPSBmdW5jdGlvbiAobGFiZWxzLCBwYW5lbCkge1xuICAgICAgICAvLyBjbGVhck92ZXJsYXA7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgbGFiZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgbGFiZWwgPSBsYWJlbHNbaV07XG4gICAgICAgICAgICB2YXIgb3ZlcmxhcEFyZWEgPSAwO1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IGkgLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICAgICAgICAgIHZhciBwcmV2ID0gbGFiZWxzW2pdO1xuICAgICAgICAgICAgICAgIC8vIGZpeDogc3RhcnQgZHJhdyBwb2ludC54IGlzIGVycm9yIHdoZW4gdGV4dEFsaWduIGlzIHJpZ2h0XG4gICAgICAgICAgICAgICAgdmFyIHByZXZCb3ggPSBwcmV2LmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICB2YXIgY3VyckJveCA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgcHJldmlvdXMgb25lIGlzIGludmlzaWJsZSwgc2tpcFxuICAgICAgICAgICAgICAgIGlmIChwcmV2LmdldCgncGFyZW50JykuZ2V0KCd2aXNpYmxlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxhcEFyZWEgPSB1dGlsc18xLmdldE92ZXJsYXBBcmVhKHByZXZCb3gsIGN1cnJCb3gpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXV0aWxzXzEubmVhcihvdmVybGFwQXJlYSwgMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLmdldCgncGFyZW50Jykuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGFiZWxzLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsKSB7IHJldHVybiBjaGVja0luUGFuZWwobGFiZWwsIHBhbmVsKTsgfSk7XG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5hZGp1c3RJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5sYWJlbHNDb250YWluZXI7XG4gICAgICAgIHRoaXMucGxvdC52aWV3Lm9uKCdiZWZvcmVyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5jbGVhcigpO1xuICAgICAgICAgICAgX3RoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyDlhYjmuIXnqbog5YaN6YeN5paw5riy5p+T77yI6YG/5YWN5Y+M5qyh57uY5Yi277yJXG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5pbml0QXJjUG9pbnRzKCk7XG4gICAgICAgIHRoaXMuZHJhd1RleHRzKCk7XG4gICAgICAgIHRoaXMuZHJhd0xpbmVzKCk7XG4gICAgfTtcbiAgICBQaWVCYXNlTGFiZWwucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICB0aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgdHJ1ZSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9O1xuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUuZ2V0RmlsdGVyZWRTdW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhbmdsZUZpZWxkID0gdGhpcy5wbG90Lm9wdGlvbnMuYW5nbGVGaWVsZDtcbiAgICAgICAgdmFyIGZpbHRlcmVkRGF0YSA9IHRoaXMucGxvdC52aWV3LmZpbHRlcmVkRGF0YSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIGZpbHRlcmVkRGF0YS5yZWR1Y2UoZnVuY3Rpb24gKHByZSwgZmlsdGVyZWREYXRhSXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIHByZSArIGZpbHRlcmVkRGF0YUl0ZW1bYW5nbGVGaWVsZF07XG4gICAgICAgIH0sIDApO1xuICAgIH07XG4gICAgLyoqIOe7mOWItuaWh+acrCAqL1xuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUuZHJhd1RleHRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHN0eWxlID0gX2Euc3R5bGUsIGZvcm1hdHRlciA9IF9hLmZvcm1hdHRlciwgYXV0b1JvdGF0ZSA9IF9hLmF1dG9Sb3RhdGUsIG9mZnNldFggPSBfYS5vZmZzZXRYLCBvZmZzZXRZID0gX2Eub2Zmc2V0WSwgYWRqdXN0UG9zaXRpb24gPSBfYS5hZGp1c3RQb3NpdGlvbiwgYWxsb3dPdmVybGFwID0gX2EuYWxsb3dPdmVybGFwO1xuICAgICAgICB2YXIgc2hhcGVJbmZvcyA9IHRoaXMuZ2V0SXRlbXMoKTtcbiAgICAgICAgdmFyIHNoYXBlcyA9IFtdO1xuICAgICAgICBzaGFwZUluZm9zLm1hcChmdW5jdGlvbiAoc2hhcGVJbmZvLCBpZHgpIHtcbiAgICAgICAgICAgIHZhciBhdHRycyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBzaGFwZUluZm8sIHN0eWxlKTtcbiAgICAgICAgICAgIHZhciBmaWx0ZXJlZFN1bSA9IF90aGlzLmdldEZpbHRlcmVkU3VtKCk7XG4gICAgICAgICAgICB2YXIgYW5nbGVGaWVsZCA9IF90aGlzLnBsb3Qub3B0aW9ucy5hbmdsZUZpZWxkO1xuICAgICAgICAgICAgdmFyIHBlcmNlbnQgPSBzaGFwZUluZm8ub3JpZ2luW2FuZ2xlRmllbGRdIC8gZmlsdGVyZWRTdW07XG4gICAgICAgICAgICB2YXIgY29udGVudCA9IGZvcm1hdHRlclxuICAgICAgICAgICAgICAgID8gZm9ybWF0dGVyKHNoYXBlSW5mby5uYW1lLCB7XG4gICAgICAgICAgICAgICAgICAgIF9vcmlnaW46IHNoYXBlSW5mby5vcmlnaW4sXG4gICAgICAgICAgICAgICAgICAgIHBlcmNlbnQ6IHBlcmNlbnQsXG4gICAgICAgICAgICAgICAgfSwgaWR4KVxuICAgICAgICAgICAgICAgIDogc2hhcGVJbmZvLm5hbWU7XG4gICAgICAgICAgICB2YXIgaXRlbUdyb3VwID0gX3RoaXMuY29udGFpbmVyLmFkZEdyb3VwKHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnaXRlbUdyb3VwJyxcbiAgICAgICAgICAgICAgICBpbmRleDogaWR4LFxuICAgICAgICAgICAgICAgIGNhcHR1cmU6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgdGV4dFNoYXBlID0gaXRlbUdyb3VwLmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEuZGVlcE1peCh7fSwgYXR0cnMsIHtcbiAgICAgICAgICAgICAgICAgICAgeDogc2hhcGVJbmZvLnggKyBvZmZzZXRYLFxuICAgICAgICAgICAgICAgICAgICB5OiBzaGFwZUluZm8ueSArIG9mZnNldFksXG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGNvbnRlbnQsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRleHRTaGFwZS5zZXQoJ2lkJywgXCJ0ZXh0LVwiICsgc2hhcGVJbmZvLm5hbWUgKyBcIi1cIiArIGlkeCk7XG4gICAgICAgICAgICBzaGFwZXMucHVzaCh0ZXh0U2hhcGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgc2hhcGVzLmZvckVhY2goZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgICAgICB2YXIgcGFuZWxCb3ggPSBfdGhpcy5jb29yZGluYXRlQkJveDtcbiAgICAgICAgICAgIF90aGlzLmFkanVzdFRleHQoc2hhcGUsIHBhbmVsQm94KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChhZGp1c3RQb3NpdGlvbikge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXQoc2hhcGVzLCBzaGFwZUluZm9zLCB0aGlzLmNvb3JkaW5hdGVCQm94KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWFsbG93T3ZlcmxhcCkge1xuICAgICAgICAgICAgdGhpcy5hZGp1c3RPdmVybGFwKHNoYXBlcywgdGhpcy5jb29yZGluYXRlQkJveCk7XG4gICAgICAgIH1cbiAgICAgICAgc2hhcGVzLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsLCBpZHgpIHtcbiAgICAgICAgICAgIGlmIChhdXRvUm90YXRlKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMucm90YXRlTGFiZWwobGFiZWwsIHV0aWxzXzEuZ2V0TGFiZWxSb3RhdGUoc2hhcGVJbmZvc1tpZHhdLmFuZ2xlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5hZGp1c3RUZXh0ID0gZnVuY3Rpb24gKGxhYmVsLCBwYW5lbEJveCkge1xuICAgICAgICB2YXIgYm94ID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgd2lkdGggPSBib3gud2lkdGg7XG4gICAgICAgIHZhciBkZWx0YVdpZHRoID0gMDtcbiAgICAgICAgaWYgKGJveC5tYXhYID4gcGFuZWxCb3gubWF4WCkge1xuICAgICAgICAgICAgd2lkdGggPSBwYW5lbEJveC5tYXhYIC0gYm94Lm1pblg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYm94Lm1pblggPCBwYW5lbEJveC5taW5YKSB7XG4gICAgICAgICAgICB3aWR0aCA9IGJveC5tYXhYIC0gcGFuZWxCb3gubWluWDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFiZWwuYXR0cigndGV4dEFsaWduJykgPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgbGFiZWwuYXR0cigneCcsIE1hdGgubWF4KGJveC54IC0gZGVsdGFXaWR0aCwgMCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGxhYmVsLmF0dHIoJ3RleHRBbGlnbicpID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICBsYWJlbC5hdHRyKCd4JywgTWF0aC5tYXgoYm94Lm1heFggLSBkZWx0YVdpZHRoLCAwKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdpZHRoICE9PSBib3gud2lkdGgpIHtcbiAgICAgICAgICAgIHZhciBmb250XzEgPSB7fTtcbiAgICAgICAgICAgIFsnZm9udFNpemUnLCAnZm9udEZhbWlseScsICdmb250V2VpZ2h0J10uZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgICAgIGZvbnRfMVtrXSA9IGxhYmVsLmF0dHIoayk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBlbGxpcHNpc1RleHRzID0gbGFiZWxcbiAgICAgICAgICAgICAgICAuYXR0cigndGV4dCcpXG4gICAgICAgICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHRleHRfMS5nZXRFbGxpcHNpc1RleHQodCwgd2lkdGgsIGZvbnRfMSk7IH0pO1xuICAgICAgICAgICAgbGFiZWwuYXR0cigndGV4dCcsIGVsbGlwc2lzVGV4dHMuam9pbignXFxuJykpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog57uY5Yi25ouJ57q/ICovXG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5kcmF3TGluZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGluZS52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgaXRlbUdyb3VwcyA9IHRoaXMuY29udGFpbmVyLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIHZhciBjZW50ZXJfMSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpLmNlbnRlcjtcbiAgICAgICAgICAgIGl0ZW1Hcm91cHMuZm9yRWFjaChmdW5jdGlvbiAobGFiZWxHcm91cCwgaWR4KSB7XG4gICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gbGFiZWxHcm91cC5nZXQoJ2NoaWxkcmVuJylbMF07XG4gICAgICAgICAgICAgICAgdmFyIGFuY2hvciA9IF90aGlzLmFyY1BvaW50c1tpZHhdO1xuICAgICAgICAgICAgICAgIHZhciBpbkxlZnQgPSBhbmNob3IueCA8IGNlbnRlcl8xLng7XG4gICAgICAgICAgICAgICAgLy8g5ouJ57q/IOWSjCBsYWJlbCDkuYvpl7TnmoTot53nprtcbiAgICAgICAgICAgICAgICB2YXIgZGlzdGFuY2UgPSBfdGhpcy5vcHRpb25zLm9mZnNldCA+IDQgPyA0IDogMDtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aCA9IF90aGlzLmdldExpbmVQYXRoKGxhYmVsLCBhbmNob3IsIGRpc3RhbmNlKTtcbiAgICAgICAgICAgICAgICB2YXIgc3R5bGUgPSBfdGhpcy5vcHRpb25zLmxpbmU7XG4gICAgICAgICAgICAgICAgbGFiZWxHcm91cC5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyBwYXRoOiBwYXRoLCBzdHJva2U6IGFuY2hvci5jb2xvciB9LCBzdHlsZSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8g55Sx5LqO5ouJ57q/55qE5a2Y5ZyoIGxhYmVsIOmcgOimgei/m+ihjOWBj+enu1xuICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3gnLCBsYWJlbC5hdHRyKCd4JykgKyAoaW5MZWZ0ID8gLWRpc3RhbmNlIDogZGlzdGFuY2UpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog6I635Y+WbGFiZWwgbGVhZGVyLWxpbmUsIOm7mOiupCBub3Qgc21vb3RoICovXG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5nZXRMaW5lUGF0aCA9IGZ1bmN0aW9uIChsYWJlbCwgYW5jaG9yLCBkaXN0YW5jZSkge1xuICAgICAgICB2YXIgc21vb3RoID0gdGhpcy5vcHRpb25zLmxpbmUgPyB0aGlzLm9wdGlvbnMubGluZS5zbW9vdGggOiBmYWxzZTtcbiAgICAgICAgdmFyIGFuZ2xlID0gYW5jaG9yLmFuZ2xlO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldENvb3JkaW5hdGUoKSwgY2VudGVyID0gX2EuY2VudGVyLCByYWRpdXMgPSBfYS5yYWRpdXM7XG4gICAgICAgIHZhciBicmVha0F0ID0gdXRpbHNfMS5nZXRFbmRQb2ludChjZW50ZXIsIGFuZ2xlLCByYWRpdXMgKyBkaXN0YW5jZSk7XG4gICAgICAgIGlmIChkaXN0YW5jZSA8IDQpIHtcbiAgICAgICAgICAgIGJyZWFrQXQgPSBhbmNob3I7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGluTGVmdCA9IGFuY2hvci54IDwgY2VudGVyLng7XG4gICAgICAgIHZhciBib3ggPSBsYWJlbC5nZXRCQm94KCk7XG4gICAgICAgIHZhciBsYWJlbFBvc2l0aW9uID0geyB4OiBpbkxlZnQgPyBib3gubWF4WCA6IGJveC5taW5YLCB5OiBib3gueSArIGJveC5oZWlnaHQgLyAyIH07XG4gICAgICAgIHZhciBzbW9vdGhQYXRoID0gW1xuICAgICAgICAgICAgJ0MnLFxuICAgICAgICAgICAgLy8gMXN0IGNvbnRyb2wgcG9pbnQgKG9mIHRoZSBjdXJ2ZSlcbiAgICAgICAgICAgIGxhYmVsUG9zaXRpb24ueCArXG4gICAgICAgICAgICAgICAgLy8gNCBnaXZlcyB0aGUgY29ubmVjdG9yIGEgbGl0dGxlIGhvcml6b250YWwgYmVuZFxuICAgICAgICAgICAgICAgIChpbkxlZnQgPyAxIDogLTEpICogKGRpc3RhbmNlIDwgNCA/IGRpc3RhbmNlIC8gMiA6IDQpLFxuICAgICAgICAgICAgbGFiZWxQb3NpdGlvbi55LFxuICAgICAgICAgICAgMiAqIGJyZWFrQXQueCAtIGFuY2hvci54LFxuICAgICAgICAgICAgMiAqIGJyZWFrQXQueSAtIGFuY2hvci55LFxuICAgICAgICAgICAgYnJlYWtBdC54LFxuICAgICAgICAgICAgYnJlYWtBdC55LFxuICAgICAgICBdO1xuICAgICAgICB2YXIgc3RyYWlnaHRQYXRoID0gWydMJywgLyoqIHBvaW50eSBicmVhayAqLyBicmVha0F0LngsIGJyZWFrQXQueV07XG4gICAgICAgIHZhciBsaW5lUGF0aCA9IHNtb290aCA/IHNtb290aFBhdGggOiBzdHJhaWdodFBhdGg7XG4gICAgICAgIHZhciBwYXRoID0gWydNJywgbGFiZWxQb3NpdGlvbi54LCBsYWJlbFBvc2l0aW9uLnldLmNvbmNhdChsaW5lUGF0aCkuY29uY2F0KCdMJywgYW5jaG9yLngsIGFuY2hvci55KTtcbiAgICAgICAgcmV0dXJuIHBhdGguam9pbignLCcpO1xuICAgIH07XG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGxvdC52aWV3Lmdlb21ldHJpZXNbMF07XG4gICAgfTtcbiAgICBQaWVCYXNlTGFiZWwucHJvdG90eXBlLmdldENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRHZW9tZXRyeSgpLmNvb3JkaW5hdGU7XG4gICAgICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlLmdldENlbnRlcigpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHZhciByYWRpdXMgPSBjb29yZGluYXRlLmdldFJhZGl1cygpO1xuICAgICAgICB2YXIgc3RhcnRBbmdsZSA9IGNvb3JkaW5hdGUuc3RhcnRBbmdsZTtcbiAgICAgICAgcmV0dXJuIHsgY2VudGVyOiBjZW50ZXIsIHJhZGl1czogcmFkaXVzLCBzdGFydEFuZ2xlOiBzdGFydEFuZ2xlIH07XG4gICAgfTtcbiAgICBQaWVCYXNlTGFiZWwucHJvdG90eXBlLmFkanVzdE9wdGlvbiA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSBvcHRpb25zLm9mZnNldDtcbiAgICAgICAgdmFyIHJhZGl1cyA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpLnJhZGl1cztcbiAgICAgICAgaWYgKHV0aWxfMS5pc1N0cmluZyhvZmZzZXQpKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSByYWRpdXMgKiBwZXJjZW50Mk51bWJlcihvZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMub2Zmc2V0ID0gb2Zmc2V0O1xuICAgIH07XG4gICAgUGllQmFzZUxhYmVsLnByb3RvdHlwZS5yb3RhdGVMYWJlbCA9IGZ1bmN0aW9uIChsYWJlbCwgYW5nbGUpIHtcbiAgICAgICAgdmFyIHggPSBsYWJlbC5hdHRyKCd4Jyk7XG4gICAgICAgIHZhciB5ID0gbGFiZWwuYXR0cigneScpO1xuICAgICAgICB2YXIgbWF0cml4ID0gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKGxhYmVsLmdldE1hdHJpeCgpLCBbXG4gICAgICAgICAgICBbJ3QnLCAteCwgLXldLFxuICAgICAgICAgICAgWydyJywgYW5nbGVdLFxuICAgICAgICAgICAgWyd0JywgeCwgeV0sXG4gICAgICAgIF0pO1xuICAgICAgICBsYWJlbC5zZXRNYXRyaXgobWF0cml4KTtcbiAgICB9O1xuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUuZ2V0SXRlbXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLm9wdGlvbnMub2Zmc2V0O1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldENvb3JkaW5hdGUoKSwgY2VudGVyID0gX2EuY2VudGVyLCByYWRpdXMgPSBfYS5yYWRpdXM7XG4gICAgICAgIHZhciBpdGVtcyA9IHRoaXMuYXJjUG9pbnRzLm1hcChmdW5jdGlvbiAoYW5jaG9yKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSB1dGlsc18xLmdldEVuZFBvaW50KGNlbnRlciwgYW5jaG9yLmFuZ2xlLCByYWRpdXMgKyBvZmZzZXQpO1xuICAgICAgICAgICAgdmFyIGl0ZW0gPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGFuY2hvciksIHBvaW50KTtcbiAgICAgICAgICAgIF90aGlzLmFkanVzdEl0ZW0oaXRlbSk7XG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBpdGVtcztcbiAgICB9O1xuICAgIC8vIOWIneWni+WMluWchuW8p+S4iumUmueCuVxuICAgIFBpZUJhc2VMYWJlbC5wcm90b3R5cGUuaW5pdEFyY1BvaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGFuZ2xlRmllbGQgPSB0aGlzLnBsb3Qub3B0aW9ucy5hbmdsZUZpZWxkO1xuICAgICAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmdldEdlb21ldHJ5KCkuZWxlbWVudHM7XG4gICAgICAgIHZhciBjb29yZCA9IHRoaXMuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICB2YXIgY2VudGVyID0gY29vcmQuY2VudGVyLCByYWRpdXMgPSBjb29yZC5yYWRpdXM7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gdGhpcy5nZXRDb29yZGluYXRlKCkuc3RhcnRBbmdsZTtcbiAgICAgICAgLy8g5L2N572u5L+h5oGv5L2/55SoIHBvc2l0aW9uU2NhbGVcbiAgICAgICAgdmFyIHBvc2l0aW9uU2NhbGVzID0gdGhpcy5nZXRHZW9tZXRyeSgpLmF0dHJpYnV0ZXMucG9zaXRpb24uc2NhbGVzO1xuICAgICAgICB2YXIgc2NhbGUgPSBwb3NpdGlvblNjYWxlc1sxXTtcbiAgICAgICAgdmFyIHNjYWxlRmllbGQgPSBzY2FsZS5maWVsZDtcbiAgICAgICAgdmFyIGFuY2hvcnMgPSBlbGVtZW50cy5tYXAoZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgdmFyIG9yaWdpbiA9IGVsZS5zaGFwZS5nZXQoJ29yaWdpbicpO1xuICAgICAgICAgICAgdmFyIGNvbG9yID0gb3JpZ2luLmNvbG9yO1xuICAgICAgICAgICAgdmFyIG9yaWdpbkRhdGEgPSBvcmlnaW4uZGF0YVswXSB8fCBvcmlnaW4uZGF0YTtcbiAgICAgICAgICAgIHZhciBlbmRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBNYXRoLlBJICogMiAqIHNjYWxlLnNjYWxlKG9yaWdpbkRhdGFbc2NhbGVGaWVsZF0pO1xuICAgICAgICAgICAgdmFyIGFuZ2xlID0gKHN0YXJ0QW5nbGUgKyBlbmRBbmdsZSkgLyAyO1xuICAgICAgICAgICAgdmFyIHBvaW50ID0gdXRpbHNfMS5nZXRFbmRQb2ludChjZW50ZXIsIGFuZ2xlLCByYWRpdXMpO1xuICAgICAgICAgICAgc3RhcnRBbmdsZSA9IGVuZEFuZ2xlO1xuICAgICAgICAgICAgLy8g5qCH562+5ZCNIOS9v+eUqCBhbmdsZUZpZWxkXG4gICAgICAgICAgICB2YXIgbmFtZSA9IHNjYWxlLmdldFRleHQob3JpZ2luRGF0YVthbmdsZUZpZWxkXSk7XG4gICAgICAgICAgICB2YXIgdGV4dEFsaWduID0gcG9pbnQueCA+IGNlbnRlci54ID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgeDogcG9pbnQueCxcbiAgICAgICAgICAgICAgICB5OiBwb2ludC55LFxuICAgICAgICAgICAgICAgIGNvbG9yOiBjb2xvcixcbiAgICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICAgIG9yaWdpbjogb3JpZ2luRGF0YSxcbiAgICAgICAgICAgICAgICAvLyDlrp7pmYXnmoTop5LluqZcbiAgICAgICAgICAgICAgICBhbmdsZTogdXRpbHNfMS5nZXRBbmdsZUJ5UG9pbnQoX3RoaXMuZ2V0R2VvbWV0cnkoKS5jb29yZGluYXRlLCBwb2ludCksXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiB0ZXh0QWxpZ24sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hcmNQb2ludHMgPSBhbmNob3JzO1xuICAgIH07XG4gICAgcmV0dXJuIFBpZUJhc2VMYWJlbDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQaWVCYXNlTGFiZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRQaWVMYWJlbCA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGlubmVyX2xhYmVsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9pbm5lci1sYWJlbFwiKSk7XG52YXIgb3V0ZXJfbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL291dGVyLWxhYmVsXCIpKTtcbnZhciBvdXRlcl9jZW50ZXJfbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL291dGVyLWNlbnRlci1sYWJlbFwiKSk7XG52YXIgUGllTGFiZWxzID0ge1xuICAgIGlubmVyOiBpbm5lcl9sYWJlbF8xLmRlZmF1bHQsXG4gICAgb3V0ZXI6IG91dGVyX2xhYmVsXzEuZGVmYXVsdCxcbiAgICAnb3V0ZXItY2VudGVyJzogb3V0ZXJfY2VudGVyX2xhYmVsXzEuZGVmYXVsdCxcbn07XG5mdW5jdGlvbiBnZXRQaWVMYWJlbCh0eXBlKSB7XG4gICAgaWYgKCFQaWVMYWJlbHNbdHlwZV0pIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwidGhpcyBsYWJlbCBcIiArIHR5cGUgKyBcIiBpcyBub3QgcmVnaXN0ZXJlZFwiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4gUGllTGFiZWxzW3R5cGVdO1xufVxuZXhwb3J0cy5nZXRQaWVMYWJlbCA9IGdldFBpZUxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnBlcmNlbnQyTnVtYmVyID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV9sYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZS1sYWJlbFwiKSk7XG52YXIgdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xudmFyIG1hdGhfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi91dGlsL21hdGhcIik7XG5mdW5jdGlvbiBwZXJjZW50Mk51bWJlcih2YWx1ZSkge1xuICAgIHZhciBwZXJjZW50YWdlID0gTnVtYmVyKHZhbHVlLmVuZHNXaXRoKCclJykgPyB2YWx1ZS5zbGljZSgwLCAtMSkgOiB2YWx1ZSk7XG4gICAgcmV0dXJuIHBlcmNlbnRhZ2UgLyAxMDA7XG59XG5leHBvcnRzLnBlcmNlbnQyTnVtYmVyID0gcGVyY2VudDJOdW1iZXI7XG52YXIgUGllSW5uZXJMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhQaWVJbm5lckxhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFBpZUlubmVyTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgLyoqIEBvdmVycmlkZSDkuI3og73lpKfkuo4wICovXG4gICAgUGllSW5uZXJMYWJlbC5wcm90b3R5cGUuYWRqdXN0T3B0aW9uID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZGp1c3RPcHRpb24uY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKG9wdGlvbnMub2Zmc2V0ID4gMCkge1xuICAgICAgICAgICAgb3B0aW9ucy5vZmZzZXQgPSAwO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQaWVJbm5lckxhYmVsLnByb3RvdHlwZS5hZGp1c3RJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgaXRlbS50ZXh0QWxpZ24gPSAnbWlkZGxlJztcbiAgICB9O1xuICAgIC8qKiBAb3ZlcnJpZGUg5LiN57uY5Yi25ouJ57q/ICovXG4gICAgUGllSW5uZXJMYWJlbC5wcm90b3R5cGUuZHJhd0xpbmVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBQaWVJbm5lckxhYmVsLnByb3RvdHlwZS5sYXlvdXQgPSBmdW5jdGlvbiAobGFiZWxzLCBzaGFwZUluZm9zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIGxhYmVscy5mb3JFYWNoKGZ1bmN0aW9uIChsYWJlbCwgaWR4KSB7XG4gICAgICAgICAgICBpZiAoaWR4ID4gMCkge1xuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGxhYmVscy5zbGljZSgwLCBpZHgpLCBmdW5jdGlvbiAocHJldkxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnJlc29sdmVDb2xsaXNpb24obGFiZWwsIHByZXZMYWJlbCwgc2hhcGVJbmZvc1tpZHhdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBQaWVJbm5lckxhYmVsLnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRoZW1lID0gdGhpcy5wbG90LnRoZW1lO1xuICAgICAgICB2YXIgbGFiZWxTdHlsZSA9IHRoZW1lLmxhYmVsLnN0eWxlO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2Zmc2V0WDogMCxcbiAgICAgICAgICAgIG9mZnNldFk6IDAsXG4gICAgICAgICAgICBvZmZzZXQ6ICctMzAlJyxcbiAgICAgICAgICAgIHN0eWxlOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGxhYmVsU3R5bGUpLCB7IHRleHRBbGlnbjogJ2NlbnRlcicsIHRleHRCYXNlbGluZTogJ21pZGRsZScgfSksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKiogbGFiZWwg56Kw5pKe6LCD5pW0ICovXG4gICAgUGllSW5uZXJMYWJlbC5wcm90b3R5cGUucmVzb2x2ZUNvbGxpc2lvbiA9IGZ1bmN0aW9uIChsYWJlbCwgcHJldiwgc2hhcGVJbmZvKSB7XG4gICAgICAgIHZhciBjZW50ZXIgPSB0aGlzLmdldENvb3JkaW5hdGUoKS5jZW50ZXI7XG4gICAgICAgIHZhciBhbmdsZSA9IHNoYXBlSW5mby5hbmdsZTtcbiAgICAgICAgdmFyIGJveCA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgdmFyIHByZXZCQm94ID0gcHJldi5nZXRCQm94KCk7XG4gICAgICAgIHZhciBwb3MgPSB7IHg6IChib3gubWluWCArIGJveC5tYXhYKSAvIDIsIHk6IChib3gubWluWSArIGJveC5tYXhZKSAvIDIgfTtcbiAgICAgICAgLy8g5Lik56eN6LCD5pW05pa55qGIXG4gICAgICAgIC8qKiDlhYjlgY/np7sgeCDmlrnlkJEgLT4g5YaN6K6h566XIHkg5L2N572uICovXG4gICAgICAgIHZhciBwb3MxID0gdXRpbF8xLmNsb25lKHBvcyk7XG4gICAgICAgIC8qKiDlhYjlgY/np7sgeSDmlrnlkJEgLT4g5YaN6K6h566XIHgg5L2N572uICovXG4gICAgICAgIHZhciBwb3MyID0gdXRpbF8xLmNsb25lKHBvcyk7XG4gICAgICAgIC8vIGNoZWNrIG92ZXJsYXBcbiAgICAgICAgaWYgKHByZXYuZ2V0KCdpZCcpICE9PSBsYWJlbC5nZXQoJ2lkJykpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IHV0aWxzXzEuZ2V0T3ZlcmxhcEluZm8oYm94LCBwcmV2QkJveCksIHhPdmVybGFwID0gX2EueE92ZXJsYXAsIHlPdmVybGFwID0gX2EueU92ZXJsYXA7XG4gICAgICAgICAgICBpZiAoeE92ZXJsYXApIHtcbiAgICAgICAgICAgICAgICBwb3MxLnggPSBwb3MueCArIHhPdmVybGFwO1xuICAgICAgICAgICAgICAgIHBvczEueSA9IHBvcy55ICsgTWF0aC50YW4oYW5nbGUpICogeE92ZXJsYXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeU92ZXJsYXApIHtcbiAgICAgICAgICAgICAgICAvLyBmaXggaXNzdWUtNDYwXG4gICAgICAgICAgICAgICAgdmFyIHlNb3ZlciA9IHlPdmVybGFwO1xuICAgICAgICAgICAgICAgIGlmIChwb3MueSA8IGNlbnRlci55KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOS4iuaWuWxhYmVs5LyY5YWI5b6A5LiK5YGP56e7XG4gICAgICAgICAgICAgICAgICAgIHlNb3ZlciA9IHlNb3ZlciA8IDAgPyB5TW92ZXIgOiBwcmV2QkJveC5taW5ZIC0gYm94Lm1heFk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyDkuIvmlrlsYWJlbOS8mOWFiOW+gOS4i+WBj+enu1xuICAgICAgICAgICAgICAgICAgICB5TW92ZXIgPSB5TW92ZXIgPiAwID8geU1vdmVyIDogcHJldkJCb3gubWF4WSAtIGJveC5taW5ZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwb3MyLnkgPSBwb3MueSArIHlNb3ZlcjtcbiAgICAgICAgICAgICAgICBwb3MyLnggPSBwb3MueCArIHlNb3ZlciAvIE1hdGgudGFuKGFuZ2xlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkaXN0MSA9IG1hdGhfMS5kaXN0QmV0d2VlblBvaW50cyhwb3MsIHBvczEpO1xuICAgICAgICAgICAgdmFyIGRpc3QyID0gbWF0aF8xLmRpc3RCZXR3ZWVuUG9pbnRzKHBvcywgcG9zMik7XG4gICAgICAgICAgICB2YXIgYWN0dWFsUG9zID0gZGlzdDEgPCBkaXN0MiA/IHBvczEgOiBwb3MyO1xuICAgICAgICAgICAgLy8g5Y+W5YGP56e76Led56a75pyA5bCP55qEXG4gICAgICAgICAgICBsYWJlbC5hdHRyKCd4JywgYWN0dWFsUG9zLngpO1xuICAgICAgICAgICAgbGFiZWwuYXR0cigneScsIGFjdHVhbFBvcy55KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFBpZUlubmVyTGFiZWw7XG59KGJhc2VfbGFiZWxfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBQaWVJbm5lckxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5uZXItbGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkRFRkFVTFRfT0ZGU0VUID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV9sYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZS1sYWJlbFwiKSk7XG4vLyDpu5jorqRsYWJlbOWSjGVsZW1lbnTnmoTlgY/np7sgMTZweFxuZXhwb3J0cy5ERUZBVUxUX09GRlNFVCA9IDE2O1xudmFyIFBpZU91dGVyQ2VudGVyTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGllT3V0ZXJDZW50ZXJMYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQaWVPdXRlckNlbnRlckxhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKiBAb3ZlcnJpZGUg5LiN6IO95aSn5LqOMCAqL1xuICAgIFBpZU91dGVyQ2VudGVyTGFiZWwucHJvdG90eXBlLmFkanVzdE9wdGlvbiA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWRqdXN0T3B0aW9uLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9mZnNldCA8IDApIHtcbiAgICAgICAgICAgIG9wdGlvbnMub2Zmc2V0ID0gMDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUGllT3V0ZXJDZW50ZXJMYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aGVtZSA9IHRoaXMucGxvdC50aGVtZTtcbiAgICAgICAgdmFyIGxhYmVsU3R5bGUgPSB0aGVtZS5sYWJlbC5zdHlsZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9mZnNldFg6IDAsXG4gICAgICAgICAgICBvZmZzZXRZOiAwLFxuICAgICAgICAgICAgb2Zmc2V0OiAxMixcbiAgICAgICAgICAgIHN0eWxlOiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGxhYmVsU3R5bGUpLCB7IHRleHRCYXNlbGluZTogJ21pZGRsZScgfSksXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBQaWVPdXRlckNlbnRlckxhYmVsLnByb3RvdHlwZS5hZGp1c3RJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMub3B0aW9ucy5vZmZzZXQ7XG4gICAgICAgIGlmIChpdGVtLnRleHRBbGlnbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgICBpdGVtLnggKz0gb2Zmc2V0ID4gNCA/IDQgOiBvZmZzZXQgLyAyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGl0ZW0udGV4dEFsaWduID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICBpdGVtLnggLT0gb2Zmc2V0ID4gNCA/IDQgOiBvZmZzZXQgLyAyO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiogbGFiZWwg56Kw5pKe6LCD5pW0ICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyxAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgICBQaWVPdXRlckNlbnRlckxhYmVsLnByb3RvdHlwZS5sYXlvdXQgPSBmdW5jdGlvbiAobGFiZWxzLCBpdGVtcywgcGFuZWwpIHsgfTtcbiAgICByZXR1cm4gUGllT3V0ZXJDZW50ZXJMYWJlbDtcbn0oYmFzZV9sYWJlbF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBpZU91dGVyQ2VudGVyTGFiZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vdXRlci1jZW50ZXItbGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkRFRkFVTFRfT0ZGU0VUID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV9sYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vYmFzZS1sYWJlbFwiKSk7XG52YXIgdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuLy8g6buY6K6kbGFiZWzlkoxlbGVtZW5055qE5YGP56e7IDE2cHhcbmV4cG9ydHMuREVGQVVMVF9PRkZTRVQgPSAxNjtcbnZhciBQaWVPdXRlckxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBpZU91dGVyTGFiZWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUGllT3V0ZXJMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvKiogQG92ZXJyaWRlIOS4jeiDveWkp+S6jjAgKi9cbiAgICBQaWVPdXRlckxhYmVsLnByb3RvdHlwZS5hZGp1c3RPcHRpb24gPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFkanVzdE9wdGlvbi5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICAgICAgICBpZiAob3B0aW9ucy5vZmZzZXQgPCAwKSB7XG4gICAgICAgICAgICBvcHRpb25zLm9mZnNldCA9IDA7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFBpZU91dGVyTGFiZWwucHJvdG90eXBlLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnBsb3QudGhlbWU7XG4gICAgICAgIHZhciBsYWJlbFN0eWxlID0gdGhlbWUubGFiZWwuc3R5bGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvZmZzZXRYOiAwLFxuICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIG9mZnNldDogMTIsXG4gICAgICAgICAgICBzdHlsZTogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBsYWJlbFN0eWxlKSwgeyB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnIH0pLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyoqIGxhYmVsIOeisOaSnuiwg+aVtCAqL1xuICAgIFBpZU91dGVyTGFiZWwucHJvdG90eXBlLmxheW91dCA9IGZ1bmN0aW9uIChsYWJlbHMsIGl0ZW1zLCBwYW5lbCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgY2VudGVyID0gdGhpcy5nZXRDb29yZGluYXRlKCkuY2VudGVyO1xuICAgICAgICB2YXIgbGVmdEhhbGYgPSB1dGlsXzEuZmlsdGVyKGxhYmVscywgZnVuY3Rpb24gKGwpIHsgcmV0dXJuIGwuYXR0cigneCcpIDw9IGNlbnRlci54OyB9KTtcbiAgICAgICAgdmFyIHJpZ2h0SGFsZiA9IHV0aWxfMS5maWx0ZXIobGFiZWxzLCBmdW5jdGlvbiAobCkgeyByZXR1cm4gbC5hdHRyKCd4JykgPiBjZW50ZXIueDsgfSk7XG4gICAgICAgIFtyaWdodEhhbGYsIGxlZnRIYWxmXS5mb3JFYWNoKGZ1bmN0aW9uIChoYWxmLCBpc0xlZnQpIHtcbiAgICAgICAgICAgIF90aGlzLl9hbnRpQ29sbGlzaW9uKGhhbGYsICFpc0xlZnQsIHBhbmVsKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKiogbGFiZWxzIOeisOaSnuWkhOeQhu+8iOmHjeeCueeul+azle+8iSAqL1xuICAgIFBpZU91dGVyTGFiZWwucHJvdG90eXBlLl9hbnRpQ29sbGlzaW9uID0gZnVuY3Rpb24gKGxhYmVscywgaXNSaWdodCwgcGFuZWxCb3gpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGxhYmVsSGVpZ2h0ID0gdGhpcy5nZXRMYWJlbEhlaWdodChsYWJlbHMpO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldENvb3JkaW5hdGUoKSwgY2VudGVyID0gX2EuY2VudGVyLCByYWRpdXMgPSBfYS5yYWRpdXM7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLm9wdGlvbnMub2Zmc2V0O1xuICAgICAgICB2YXIgdG90YWxSID0gcmFkaXVzICsgb2Zmc2V0O1xuICAgICAgICB2YXIgdG90YWxIZWlnaHQgPSBNYXRoLm1pbihwYW5lbEJveC5oZWlnaHQsIE1hdGgubWF4KHRvdGFsUiAqIDIgKyBsYWJlbEhlaWdodCAqIDIsIGxhYmVscy5sZW5ndGggKiBsYWJlbEhlaWdodCkpO1xuICAgICAgICB2YXIgbWF4TGFiZWxzQ291bnQgPSBNYXRoLmZsb29yKHRvdGFsSGVpZ2h0IC8gbGFiZWxIZWlnaHQpO1xuICAgICAgICAvLyBmaXgtYnVnLCBtYXhMYWJlbHNDb3VudCDkuYvlkI7nmoRsYWJlbHMg5Zyo6Z2eIGFsbG93T3ZlcmxhcCDkuI3mmL7npLrvvIjpgb/lhY3lh7rnjrDlsL7pg6hsYWJlbOWxleekuu+8jOiAjOWJjee9rmxhYmVs5LiN5bGV56S677yJXG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLmFsbG93T3ZlcmxhcCkge1xuICAgICAgICAgICAgbGFiZWxzLnNsaWNlKG1heExhYmVsc0NvdW50KS5mb3JFYWNoKGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICAgICAgICAgIGxhYmVsLmdldCgncGFyZW50Jykuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgbGFiZWxzLnNwbGljZShtYXhMYWJlbHNDb3VudCwgbGFiZWxzLmxlbmd0aCAtIG1heExhYmVsc0NvdW50KTtcbiAgICAgICAgLy8gc29ydCBieSB5IERFU0NcbiAgICAgICAgbGFiZWxzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEuZ2V0QkJveCgpLnkgLSBiLmdldEJCb3goKS55OyB9KTtcbiAgICAgICAgLy8gYWRqdXN0IHkgcG9zaXRpb24gb2YgbGFiZWxzIHRvIGF2b2lkIG92ZXJsYXBwaW5nXG4gICAgICAgIHZhciBvdmVybGFwcGluZyA9IHRydWU7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgbWF4WSA9IGNlbnRlci55ICsgdG90YWxIZWlnaHQgLyAyO1xuICAgICAgICB2YXIgbWluWSA9IGNlbnRlci55IC0gdG90YWxIZWlnaHQgLyAyO1xuICAgICAgICB2YXIgYm94ZXMgPSBsYWJlbHMubWFwKGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICAgICAgdmFyIGxhYmVsQm94ID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICAgICAgaWYgKGxhYmVsQm94Lm1heFkgPiBtYXhZKSB7XG4gICAgICAgICAgICAgICAgbWF4WSA9IE1hdGgubWluKHBhbmVsQm94Lm1heFksIGxhYmVsQm94Lm1heFkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhYmVsQm94Lm1pblkgPCBtaW5ZKSB7XG4gICAgICAgICAgICAgICAgbWluWSA9IE1hdGgubWF4KHBhbmVsQm94Lm1pblksIGxhYmVsQm94Lm1pblkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBsYWJlbC5hdHRyKCd0ZXh0JyksXG4gICAgICAgICAgICAgICAgc2l6ZTogbGFiZWxIZWlnaHQsXG4gICAgICAgICAgICAgICAgcG9zOiBsYWJlbEJveC55LFxuICAgICAgICAgICAgICAgIHRhcmdldHM6IFtdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBqID0gMDtcbiAgICAgICAgd2hpbGUgKGogPCBib3hlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChqID09PSBib3hlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgYm94ZXNbal0udGFyZ2V0c1swXSA9IG1heFk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBib3hlc1tqXS50YXJnZXRzWzBdID0gYm94ZXNbaiArIDFdLnBvcyAtIGJveGVzW2ogKyAxXS5zaXplIC8gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGorKztcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAob3ZlcmxhcHBpbmcpIHtcbiAgICAgICAgICAgIGJveGVzLmZvckVhY2goZnVuY3Rpb24gKGJveCkge1xuICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSB1dGlsXzEubGFzdChib3gudGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgYm94LnBvcyA9IE1hdGgubWF4KG1pblksIE1hdGgubWluKGJveC5wb3MsIHRhcmdldCAtIGJveC5zaXplKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGRldGVjdCBvdmVybGFwcGluZyBhbmQgam9pbiBib3hlc1xuICAgICAgICAgICAgb3ZlcmxhcHBpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIGkgPSBib3hlcy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c0JveCA9IGJveGVzW2kgLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveCA9IGJveGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNCb3gucG9zICsgcHJldmlvdXNCb3guc2l6ZSA+IGJveC5wb3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG92ZXJsYXBwaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5zaXplICs9IGJveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNCb3gudGFyZ2V0cyA9IHByZXZpb3VzQm94LnRhcmdldHMuY29uY2F0KGJveC50YXJnZXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG92ZXJmbG93LCBzaGlmdCB1cFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldCA9IHV0aWxfMS5sYXN0KHByZXZpb3VzQm94LnRhcmdldHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzQm94LnBvcyArIHByZXZpb3VzQm94LnNpemUgPiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5wb3MgPSB0YXJnZXQgLSBwcmV2aW91c0JveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYm94ZXMuc3BsaWNlKGksIDEpOyAvLyByZW1vdmluZyBib3hcbiAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJsYXBwaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOaNouaOieacgOWQjuS4gOS4qlxuICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNCb3gudGFyZ2V0cy5zcGxpY2UoLTEsIDEsIGJveC5wb3MpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGkgPSAwO1xuICAgICAgICAvLyBzdGVwIDQ6IG5vcm1hbGl6ZSB5IGFuZCBhZGp1c3QgeFxuICAgICAgICBib3hlcy5mb3JFYWNoKGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICB2YXIgcG9zSW5Db21wb3NpdGVCb3ggPSBsYWJlbEhlaWdodCAvIDI7IC8vIG1pZGRsZSBvZiB0aGUgbGFiZWxcbiAgICAgICAgICAgIGIudGFyZ2V0cy5mb3JFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsYWJlbHNbaV0uYXR0cigneScsIGIucG9zICsgcG9zSW5Db21wb3NpdGVCb3gpO1xuICAgICAgICAgICAgICAgIHBvc0luQ29tcG9zaXRlQm94ICs9IGxhYmVsSGVpZ2h0O1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8g6LCD5pW0IHgg5L2N572u5Zyo5qSt5ZyG6L2o6YGT5LiKXG4gICAgICAgIHZhciB0b3BMYWJlbHMgPSBbXTtcbiAgICAgICAgdmFyIGJvdHRvbUxhYmVscyA9IFtdO1xuICAgICAgICBsYWJlbHMuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwsIGlkeCkge1xuICAgICAgICAgICAgdmFyIGFuY2hvciA9IF90aGlzLmFyY1BvaW50c1tpZHhdO1xuICAgICAgICAgICAgaWYgKGFuY2hvci5hbmdsZSA+PSAwICYmIGFuY2hvci5hbmdsZSA8PSBNYXRoLlBJKSB7XG4gICAgICAgICAgICAgICAgYm90dG9tTGFiZWxzLnB1c2gobGFiZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdG9wTGFiZWxzLnB1c2gobGFiZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgW3RvcExhYmVscywgYm90dG9tTGFiZWxzXS5mb3JFYWNoKGZ1bmN0aW9uIChhZGp1c3RMYWJlbHMsIGlzQm90dG9tKSB7XG4gICAgICAgICAgICBpZiAoIWFkanVzdExhYmVscy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcnkgPSBpc0JvdHRvbSA/IHV0aWxfMS5sYXN0KGFkanVzdExhYmVscykuZ2V0QkJveCgpLm1heFkgLSBjZW50ZXIueSA6IGNlbnRlci55IC0gdXRpbF8xLmhlYWQoYWRqdXN0TGFiZWxzKS5nZXRCQm94KCkubWluWTtcbiAgICAgICAgICAgIHJ5ID0gTWF0aC5tYXgodG90YWxSLCByeSk7XG4gICAgICAgICAgICB2YXIgZGlzdGFuY2UgPSBvZmZzZXQgPiA0ID8gNCA6IDA7XG4gICAgICAgICAgICB2YXIgbWF4TGFiZWxXaWR0aCA9IE1hdGgubWF4LmFwcGx5KDAsIHV0aWxfMS5tYXAobGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHsgcmV0dXJuIGxhYmVsLmdldEJCb3goKS53aWR0aDsgfSkpICtcbiAgICAgICAgICAgICAgICBvZmZzZXQgK1xuICAgICAgICAgICAgICAgIGRpc3RhbmNlO1xuICAgICAgICAgICAgdmFyIHJ4ID0gTWF0aC5tYXgodG90YWxSLCBNYXRoLm1pbigocnkgKyB0b3RhbFIpIC8gMiwgY2VudGVyLnggLSAocGFuZWxCb3gubWluWCArIG1heExhYmVsV2lkdGgpKSk7XG4gICAgICAgICAgICB2YXIgcnhQb3cyID0gcnggKiByeDtcbiAgICAgICAgICAgIHZhciByeVBvdzIgPSByeSAqIHJ5O1xuICAgICAgICAgICAgYWRqdXN0TGFiZWxzLmZvckVhY2goZnVuY3Rpb24gKGxhYmVsLCBpZHgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYW5jaG9yID0gX3RoaXMuYXJjUG9pbnRzW2lkeF07XG4gICAgICAgICAgICAgICAgdmFyIGJveCA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgICAgICAgICB2YXIgYm94Q2VudGVyID0geyB4OiBib3gubWluWCArIGJveC53aWR0aCAvIDIsIHk6IGJveC5taW5ZICsgYm94LmhlaWdodCAvIDIgfTtcbiAgICAgICAgICAgICAgICB2YXIgZHlQb3cyID0gTWF0aC5wb3coYm94Q2VudGVyLnkgLSBjZW50ZXIueSwgMik7XG4gICAgICAgICAgICAgICAgdmFyIGVuZFBvaW50ID0gdXRpbHNfMS5nZXRFbmRQb2ludChjZW50ZXIsIGFuY2hvci5hbmdsZSwgcmFkaXVzKTtcbiAgICAgICAgICAgICAgICB2YXIgZGlzdGFuY2Vfb2Zmc2V0ID0gKGlzUmlnaHQgPyAxIDogLTEpICogZGlzdGFuY2UgKiAyO1xuICAgICAgICAgICAgICAgIGlmIChkeVBvdzIgPiByeVBvdzIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCflvILluLgo5LiA6Iis5LiN5Lya5Ye6546wKScsIGxhYmVsLmF0dHIoJ3RleHQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3gnLCBlbmRQb2ludC54ICsgZGlzdGFuY2Vfb2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vICh4IC0gY3gpXjIgLyByeCBeIDIgKyAoeSAtIGN5KV4yIC8gcnkgXiAyID0gMVxuICAgICAgICAgICAgICAgICAgICAvLyDpgb/lhY0gbGFiZWznmoQg5ouJ57q/IOWcqCBlbGVtZW50IOS4ilxuICAgICAgICAgICAgICAgICAgICB2YXIgeFBvcyA9IGNlbnRlci54ICsgKGlzUmlnaHQgPyAxIDogLTEpICogTWF0aC5zcXJ0KCgxIC0gZHlQb3cyIC8gcnlQb3cyKSAqIHJ4UG93Mik7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoY2VudGVyLnggPT09IGVuZFBvaW50LnggJiYgYm94Q2VudGVyLnkgPT09IGVuZFBvaW50LnkpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAoY2VudGVyLnkgPT09IGVuZFBvaW50LnkgJiYgeFBvcyA9PT0gZW5kUG9pbnQueCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHhQb3MgPSBlbmRQb2ludC54O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc3QgazEgPSAoY2VudGVyLnkgLSBlbmRQb2ludC55KSAvIChjZW50ZXIueCAtIGVuZFBvaW50LngpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc3QgazIgPSAoYm94Q2VudGVyLnkgLSBlbmRQb2ludC55KSAvICh4UG9zIC0gZW5kUG9pbnQueCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zdCB0aGV0YSA9IE1hdGguYXRhbigoazEgLSBrMikgLyAoMSArIGsxICogazIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOWIh+inkiA8IDkw5bqm77yI55uu5YmN55qE5Z2Q5qCH57O7IOaXoOazleeyvuWHhuiuoeeul+WIh+inku+8iVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgKE1hdGguY29zKHRoZXRhKSA+IDAgJiYgKCFpc1JpZ2h0ID8geFBvcyA+IGVuZFBvaW50LnggOiB4UG9zIDwgZW5kUG9pbnQueCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgeFBvcyA9IGVuZFBvaW50Lng7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuYXR0cigneCcsIHhQb3MgKyBkaXN0YW5jZV9vZmZzZXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qKiDojrflj5ZsYWJlbCBoZWlnaHQgKi9cbiAgICBQaWVPdXRlckxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbEhlaWdodCA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubGFiZWxIZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlsXzEuaGVhZChsYWJlbHMpID8gdXRpbF8xLmhlYWQobGFiZWxzKS5nZXRCQm94KCkuaGVpZ2h0IDogMTQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5sYWJlbEhlaWdodDtcbiAgICB9O1xuICAgIHJldHVybiBQaWVPdXRlckxhYmVsO1xufShiYXNlX2xhYmVsXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUGllT3V0ZXJMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW91dGVyLWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbGF5ZXJfMSA9IHJlcXVpcmUoXCIuLi8uLi9sYXllclwiKTtcbnZhciBBTkNIT1JfT0ZGU0VUID0gMDsgLy8g6ZSa54K55YGP56e76YePXG52YXIgSU5GTEVDVElPTl9PRkZTRVQgPSAxNTsgLy8g5ouQ54K55YGP56e76YePXG52YXIgREVGQVVMVF9DT0xPUiA9ICcjQ0NDJztcbnZhciBMQUJFTDFfT0ZGU0VUWSA9IDI7XG52YXIgTEFCRUwyX09GRlNFVFkgPSAtMjtcbnZhciBBREpVU1RPRkZTRVQgPSAxNTtcbmZ1bmN0aW9uIGdldEVuZFBvaW50KGNlbnRlciwgYW5nbGUsIHIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBjZW50ZXIueCArIHIgKiBNYXRoLmNvcyhhbmdsZSksXG4gICAgICAgIHk6IGNlbnRlci55ICsgciAqIE1hdGguc2luKGFuZ2xlKSxcbiAgICB9O1xufVxudmFyIFNwaWRlckxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFNwaWRlckxhYmVsKGNmZykge1xuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnZpZXcgPSBjZmcudmlldztcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMuZ2V0RGVmYXVsdE9wdGlvbnMoKSwgY2ZnKTtcbiAgICAgICAgdGhpcy5fYWRqdXN0T3B0aW9ucyh0aGlzLm9wdGlvbnMpO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgU3BpZGVyTGFiZWwucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gdGhpcy52aWV3Lmdlb21ldHJpZXNbMF0ubGFiZWxzQ29udGFpbmVyO1xuICAgICAgICB0aGlzLnZpZXcub24oJ2JlZm9yZXJlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmNsZWFyKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU3BpZGVyTGFiZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKCF0aGlzLnZpZXcgfHwgdGhpcy52aWV3LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8qKiDlpoLmnpzmnIlmb3JtYXR0ZXLliJnkuovlhYjlpITnkIbmlbDmja4gKi9cbiAgICAgICAgdmFyIGRhdGEgPSB1dGlsXzEuY2xvbmUodGhpcy52aWV3LmdldERhdGEoKSk7XG4gICAgICAgIHRoaXMuaGFsdmVzID0gW1tdLCBbXV07XG4gICAgICAgIHZhciBzaGFwZXMgPSBbXTtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy52aWV3Lmdlb21ldHJpZXNbMF0uZWxlbWVudHM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWxlKSB7XG4gICAgICAgICAgICBzaGFwZXMucHVzaChlbGUuc2hhcGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jb29yZCA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmNvb3JkaW5hdGU7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgYWxsWmVybyA9IF9hLmFsbFplcm8sIHRydWVBbmdsZUZpZWxkID0gX2EuYW5nbGVGaWVsZDtcbiAgICAgICAgdmFyIGFuZ2xlRmllbGQgPSB0aGlzLm9wdGlvbnMuZmllbGRzWzBdO1xuICAgICAgICB2YXIgc2NhbGUgPSB0aGlzLnZpZXcuZ2V0U2NhbGVzQnlEaW0oJ3knKVthbmdsZUZpZWxkXTtcbiAgICAgICAgdmFyIGNlbnRlciA9IHRoaXMuY29vcmQuZ2V0Q2VudGVyKCk7XG4gICAgICAgIHZhciBzdGFydEFuZ2xlID0gdGhpcy5jb29yZC5zdGFydEFuZ2xlO1xuICAgICAgICB2YXIgcmFkaXVzID0gdGhpcy5jb29yZC5wb2xhclJhZGl1cztcbiAgICAgICAgdmFyIF9iID0gdGhpcy52aWV3LmNvb3JkaW5hdGVCQm94LCB3aWR0aCA9IF9iLndpZHRoLCBoZWlnaHQgPSBfYi5oZWlnaHQ7XG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHZhciBhbmdsZSA9IHN0YXJ0QW5nbGU7XG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKGlkeCkge1xuICAgICAgICAgICAgdmFyIGQgPSBkYXRhW2lkeF07XG4gICAgICAgICAgICAvLyDorqHnrpfmr4/kuKrliIfniYfnmoRtaWRkbGUgYW5nbGVcbiAgICAgICAgICAgIHZhciBhbmdsZVZhbHVlID0gc2NhbGUuc2NhbGUoZFthbmdsZUZpZWxkXSk7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0QW5nbGUgPSBhbmdsZSArIE1hdGguUEkgKiAyICogYW5nbGVWYWx1ZTtcbiAgICAgICAgICAgIHZhciBtaWRkbGVBbmdsZSA9IGFuZ2xlICsgKHRhcmdldEFuZ2xlIC0gYW5nbGUpIC8gMjtcbiAgICAgICAgICAgIGFuZ2xlID0gdGFyZ2V0QW5nbGU7XG4gICAgICAgICAgICAvLyDmoLnmja5taWRkbGUgYW5nbGXorqHnrpfplJrngrnlkozmi5Dngrnot53nprtcbiAgICAgICAgICAgIHZhciBhbmNob3JQb2ludCA9IGdldEVuZFBvaW50KGNlbnRlciwgbWlkZGxlQW5nbGUsIHJhZGl1cyArIEFOQ0hPUl9PRkZTRVQpO1xuICAgICAgICAgICAgdmFyIGluZmxlY3Rpb25Qb2ludCA9IGdldEVuZFBvaW50KGNlbnRlciwgbWlkZGxlQW5nbGUsIHJhZGl1cyArIElORkxFQ1RJT05fT0ZGU0VUKTtcbiAgICAgICAgICAgIC8vIOiOt+WPluWvueW6lHNoYXBl55qEY29sb3JcbiAgICAgICAgICAgIHZhciBjb2xvciA9IERFRkFVTFRfQ09MT1I7XG4gICAgICAgICAgICBpZiAodGhpc18xLm9wdGlvbnMuZmllbGRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgIHZhciBjb2xvckZpZWxkID0gdGhpc18xLm9wdGlvbnMuZmllbGRzWzFdO1xuICAgICAgICAgICAgICAgIHZhciBjb2xvclNjYWxlID0gdGhpc18xLnZpZXcuZ2VvbWV0cmllc1swXS5zY2FsZXNbY29sb3JGaWVsZF07XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9ySW5kZXggPSBjb2xvclNjYWxlLnNjYWxlKGRbY29sb3JGaWVsZF0pO1xuICAgICAgICAgICAgICAgIGlmIChjb2xvckluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzaGFwZUluZGV4ID0gTWF0aC5mbG9vcihjb2xvckluZGV4ICogKHNoYXBlcy5sZW5ndGggLSAxKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbG9yID0gc2hhcGVzW3NoYXBlSW5kZXhdLmF0dHIoJ2ZpbGwnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDnu4Too4VsYWJlbOaVsOaNrlxuICAgICAgICAgICAgdmFyIGxhYmVsID0ge1xuICAgICAgICAgICAgICAgIF9hbmNob3I6IGFuY2hvclBvaW50LFxuICAgICAgICAgICAgICAgIF9pbmZsZWN0aW9uOiBpbmZsZWN0aW9uUG9pbnQsXG4gICAgICAgICAgICAgICAgX2RhdGE6IGQsXG4gICAgICAgICAgICAgICAgeDogaW5mbGVjdGlvblBvaW50LngsXG4gICAgICAgICAgICAgICAgeTogaW5mbGVjdGlvblBvaW50LnksXG4gICAgICAgICAgICAgICAgcjogcmFkaXVzICsgSU5GTEVDVElPTl9PRkZTRVQsXG4gICAgICAgICAgICAgICAgZmlsbDogY29sb3IsXG4gICAgICAgICAgICAgICAgdGV4dEdyb3VwOiBudWxsLFxuICAgICAgICAgICAgICAgIF9zaWRlOiBudWxsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIOWIm+W7umxhYmVs5paH5pysXG4gICAgICAgICAgICB2YXIgdGV4dHMgPSBbXTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHRoaXNfMS5vcHRpb25zLmZpZWxkcywgZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWxsWmVybyAmJiBmID09PSBsYXllcl8xLnBlcmNlbnRhZ2VGaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0cy5wdXNoKGRbdHJ1ZUFuZ2xlRmllbGRdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRzLnB1c2goZFtmXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAodGhpc18xLm9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZvcm1hdHRlZCA9IHRoaXNfMS5vcHRpb25zLmZvcm1hdHRlcihkW3RydWVBbmdsZUZpZWxkXSwgeyBfb3JpZ2luOiBkLCBjb2xvcjogY29sb3IgfSwgaWR4KTtcbiAgICAgICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGZvcm1hdHRlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVkID0gW2Zvcm1hdHRlZF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRleHRzID0gZm9ybWF0dGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHRleHRHcm91cCA9IHRoaXNfMS5jb250YWluZXIuYWRkR3JvdXAoe1xuICAgICAgICAgICAgICAgIGNhcHR1cmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgdGV4dEF0dHJzID0ge1xuICAgICAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogdGhpc18xLm9wdGlvbnMudGV4dC5mb250U2l6ZSxcbiAgICAgICAgICAgICAgICBsaW5lSGVpZ2h0OiB0aGlzXzEub3B0aW9ucy50ZXh0LmZvbnRTaXplLFxuICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IHRoaXNfMS5vcHRpb25zLnRleHQuZm9udFdlaWdodCxcbiAgICAgICAgICAgICAgICBmaWxsOiB0aGlzXzEub3B0aW9ucy50ZXh0LmZpbGwsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gbGFiZWwxOuS4i+mDqGxhYmVsXG4gICAgICAgICAgICB2YXIgbG93ZXJUZXh0ID0gZFt0cnVlQW5nbGVGaWVsZF07XG4gICAgICAgICAgICBpZiAodGhpc18xLm9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgICAgbG93ZXJUZXh0ID0gdGV4dHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbG93ZXJUZXh0QXR0cnMgPSB1dGlsXzEuY2xvbmUodGV4dEF0dHJzKTtcbiAgICAgICAgICAgIGlmICh0ZXh0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgICBsb3dlclRleHRBdHRycy5mb250V2VpZ2h0ID0gNzAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGxvd2VyVGV4dFNoYXBlID0gdGV4dEdyb3VwLmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEubWl4KHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiB0ZXh0cy5sZW5ndGggPT09IDIgPyAndG9wJyA6ICdtaWRkbGUnLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBsb3dlclRleHQsXG4gICAgICAgICAgICAgICAgfSwgbG93ZXJUZXh0QXR0cnMpLFxuICAgICAgICAgICAgICAgIGRhdGE6IGQsXG4gICAgICAgICAgICAgICAgb2Zmc2V0WTogdGV4dHMubGVuZ3RoID09PSAyID8gTEFCRUwxX09GRlNFVFkgOiAwLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdsYWJlbCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGxvd2VyVGV4dFNoYXBlLm5hbWUgPSAnbGFiZWwnOyAvLyDnlKjkuo7kuovku7bmoIforrAgc2hhcGVOYW1lXG4gICAgICAgICAgICAvKiogbGFiZWwyOuS4iumDqGxhYmVsICovXG4gICAgICAgICAgICBpZiAodGV4dHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRvcFRleHRTaGFwZSA9IHRleHRHcm91cC5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5taXgoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnYm90dG9tJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IHRleHRzWzFdLFxuICAgICAgICAgICAgICAgICAgICB9LCB0ZXh0QXR0cnMpLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiBkLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXRZOiBMQUJFTDJfT0ZGU0VUWSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2xhYmVsJyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0b3BUZXh0U2hhcGUubmFtZSA9ICdsYWJlbCc7IC8vIOeUqOS6juS6i+S7tuagh+iusCBzaGFwZU5hbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhYmVsLnRleHRHcm91cCA9IHRleHRHcm91cDtcbiAgICAgICAgICAgIC8qKiDlsIZsYWJlbOWIhue7hCAqL1xuICAgICAgICAgICAgaWYgKGFuY2hvclBvaW50LnggPCBjZW50ZXIueCkge1xuICAgICAgICAgICAgICAgIGxhYmVsLl9zaWRlID0gJ2xlZnQnO1xuICAgICAgICAgICAgICAgIHRoaXNfMS5oYWx2ZXNbMF0ucHVzaChsYWJlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsYWJlbC5fc2lkZSA9ICdyaWdodCc7XG4gICAgICAgICAgICAgICAgdGhpc18xLmhhbHZlc1sxXS5wdXNoKGxhYmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHRoaXNfMSA9IHRoaXM7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogcHJlZmVyLWZvci1vZlxuICAgICAgICBmb3IgKHZhciBpZHggPSAwOyBpZHggPCBkYXRhLmxlbmd0aDsgaWR4KyspIHtcbiAgICAgICAgICAgIF9sb29wXzEoaWR4KTtcbiAgICAgICAgfVxuICAgICAgICAvKiog57uY5Yi2bGFiZWwgKi9cbiAgICAgICAgdmFyIG1heENvdW50Rm9yT25lU2lkZSA9IE1hdGguZmxvb3IoaGVpZ2h0IC8gdGhpcy5vcHRpb25zLmxpbmVIZWlnaHQpO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmhhbHZlcywgZnVuY3Rpb24gKGhhbGYpIHtcbiAgICAgICAgICAgIGlmIChoYWxmLmxlbmd0aCA+IG1heENvdW50Rm9yT25lU2lkZSkge1xuICAgICAgICAgICAgICAgIGhhbGYuc3BsaWNlKG1heENvdW50Rm9yT25lU2lkZSwgaGFsZi5sZW5ndGggLSBtYXhDb3VudEZvck9uZVNpZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFsZi5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEueSAtIGIueTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX3RoaXMuX2FudGlDb2xsaXNpb24oaGFsZik7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpZXcuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIFNwaWRlckxhYmVsLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTcGlkZXJMYWJlbC5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xuICAgICAgICB0aGlzLnZpZXcuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIFNwaWRlckxhYmVsLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy52aWV3LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBTcGlkZXJMYWJlbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgfTtcbiAgICBTcGlkZXJMYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC42NSknLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLjUsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgwLCAwLCAwLCAwLjQ1KScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZUhlaWdodDogMzIsXG4gICAgICAgICAgICAvKiogZGlzdGFuY2UgYmV0d2VlbiBsYWJlbCBhbmQgZWRnZSAqL1xuICAgICAgICAgICAgc2lkZVBhZGRpbmc6IDIwLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgU3BpZGVyTGFiZWwucHJvdG90eXBlLl9hbnRpQ29sbGlzaW9uID0gZnVuY3Rpb24gKGhhbGYpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNvb3JkID0gdGhpcy5jb29yZDtcbiAgICAgICAgdmFyIGNhbnZhc0hlaWdodCA9IGNvb3JkLmdldEhlaWdodCgpO1xuICAgICAgICB2YXIgY2VudGVyID0gY29vcmQuY2VudGVyO1xuICAgICAgICB2YXIgcmFkaXVzID0gY29vcmQuZ2V0UmFkaXVzKCk7XG4gICAgICAgIHZhciBzdGFydFkgPSBjZW50ZXIueSAtIHJhZGl1cyAtIElORkxFQ1RJT05fT0ZGU0VUIC0gdGhpcy5vcHRpb25zLmxpbmVIZWlnaHQ7XG4gICAgICAgIHZhciBvdmVybGFwcGluZyA9IHRydWU7XG4gICAgICAgIHZhciB0b3RhbEggPSBjYW52YXNIZWlnaHQ7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgbWF4WSA9IDA7XG4gICAgICAgIHZhciBtaW5ZID0gTnVtYmVyLk1JTl9WQUxVRTtcbiAgICAgICAgdmFyIG1heExhYmVsV2lkdGggPSAwO1xuICAgICAgICB2YXIgYm94ZXMgPSBoYWxmLm1hcChmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbFkgPSBsYWJlbC55O1xuICAgICAgICAgICAgaWYgKGxhYmVsWSA+IG1heFkpIHtcbiAgICAgICAgICAgICAgICBtYXhZID0gbGFiZWxZO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhYmVsWSA8IG1pblkpIHtcbiAgICAgICAgICAgICAgICBtaW5ZID0gbGFiZWxZO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHRleHRHcm91cCA9IGxhYmVsLnRleHRHcm91cDtcbiAgICAgICAgICAgIHZhciBsYWJlbFdpZHRoID0gdGV4dEdyb3VwLmdldEJCb3goKS53aWR0aDtcbiAgICAgICAgICAgIGlmIChsYWJlbFdpZHRoID49IG1heExhYmVsV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBtYXhMYWJlbFdpZHRoID0gbGFiZWxXaWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc2l6ZTogX3RoaXMub3B0aW9ucy5saW5lSGVpZ2h0LFxuICAgICAgICAgICAgICAgIHRhcmdldHM6IFtsYWJlbFkgLSBzdGFydFldLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChtYXhZIC0gc3RhcnRZID4gdG90YWxIKSB7XG4gICAgICAgICAgICB0b3RhbEggPSBtYXhZIC0gc3RhcnRZO1xuICAgICAgICB9XG4gICAgICAgIHZhciBpdGVyYXRvckJveGVkID0gZnVuY3Rpb24gKGl0ZW1zKSB7XG4gICAgICAgICAgICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChib3gpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gKE1hdGgubWluLmFwcGx5KG1pblksIGJveC50YXJnZXRzKSArIE1hdGgubWF4LmFwcGx5KG1pblksIGJveC50YXJnZXRzKSkgLyAyO1xuICAgICAgICAgICAgICAgIGJveC5wb3MgPSBNYXRoLm1pbihNYXRoLm1heChtaW5ZLCB0YXJnZXQgLSBib3guc2l6ZSAvIDIpLCB0b3RhbEggLSBib3guc2l6ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgd2hpbGUgKG92ZXJsYXBwaW5nKSB7XG4gICAgICAgICAgICBpdGVyYXRvckJveGVkKGJveGVzKTtcbiAgICAgICAgICAgIC8vIGRldGVjdCBvdmVybGFwcGluZyBhbmQgam9pbiBib3hlc1xuICAgICAgICAgICAgb3ZlcmxhcHBpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIGkgPSBib3hlcy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c0JveCA9IGJveGVzW2kgLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveCA9IGJveGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNCb3gucG9zICsgcHJldmlvdXNCb3guc2l6ZSA+IGJveC5wb3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG92ZXJsYXBwaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5zaXplICs9IGJveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNCb3gudGFyZ2V0cyA9IHByZXZpb3VzQm94LnRhcmdldHMuY29uY2F0KGJveC50YXJnZXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG92ZXJmbG93LCBzaGlmdCB1cFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzQm94LnBvcyArIHByZXZpb3VzQm94LnNpemUgPiB0b3RhbEgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0JveC5wb3MgPSB0b3RhbEggLSBwcmV2aW91c0JveC5zaXplO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYm94ZXMuc3BsaWNlKGksIDEpOyAvLyByZW1vdmluZyBib3hcbiAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJsYXBwaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpID0gMDtcbiAgICAgICAgYm94ZXMuZm9yRWFjaChmdW5jdGlvbiAoYikge1xuICAgICAgICAgICAgdmFyIHBvc0luQ29tcG9zaXRlQm94ID0gc3RhcnRZOyAvLyBtaWRkbGUgb2YgdGhlIGxhYmVsXG4gICAgICAgICAgICBiLnRhcmdldHMuZm9yRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaGFsZltpXS55ID0gYi5wb3MgKyBwb3NJbkNvbXBvc2l0ZUJveCArIF90aGlzLm9wdGlvbnMubGluZUhlaWdodCAvIDI7XG4gICAgICAgICAgICAgICAgcG9zSW5Db21wb3NpdGVCb3ggKz0gX3RoaXMub3B0aW9ucy5saW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGRyYXduTGFiZWxzID0gW107XG4gICAgICAgIGhhbGYuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0R3JvdXAgPSBfdGhpcy5fZHJhd0xhYmVsKGxhYmVsKTtcbiAgICAgICAgICAgIF90aGlzLl9kcmF3TGFiZWxMaW5lKGxhYmVsLCBtYXhMYWJlbFdpZHRoLCB0ZXh0R3JvdXApO1xuICAgICAgICAgICAgZHJhd25MYWJlbHMucHVzaCh0ZXh0R3JvdXApO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFNwaWRlckxhYmVsLnByb3RvdHlwZS5fZHJhd0xhYmVsID0gZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgIHZhciBjb29yZCA9IHRoaXMuY29vcmQ7XG4gICAgICAgIHZhciBjZW50ZXIgPSBjb29yZC5nZXRDZW50ZXIoKTtcbiAgICAgICAgdmFyIHJhZGl1cyA9IGNvb3JkLmdldFJhZGl1cygpO1xuICAgICAgICB2YXIgeSA9IGxhYmVsLnksIHRleHRHcm91cCA9IGxhYmVsLnRleHRHcm91cDtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGV4dEdyb3VwLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgdmFyIHhfZGlyID0gbGFiZWwuX3NpZGUgPT09ICdsZWZ0JyA/IDEgOiAtMTtcbiAgICAgICAgdmFyIHRleHRBdHRycyA9IHRzbGliXzEuX19hc3NpZ24oeyB0ZXh0QWxpZ246IGxhYmVsLl9zaWRlID09PSAnbGVmdCcgPyAncmlnaHQnIDogJ2xlZnQnLCB4OiBsYWJlbC5fc2lkZSA9PT0gJ2xlZnQnXG4gICAgICAgICAgICAgICAgPyBjZW50ZXIueCAtIHJhZGl1cyAtIHRoaXMub3B0aW9ucy5zaWRlUGFkZGluZ1xuICAgICAgICAgICAgICAgIDogY2VudGVyLnggKyByYWRpdXMgKyB0aGlzLm9wdGlvbnMuc2lkZVBhZGRpbmcgfSwgdGhpcy5vcHRpb25zLnN0eWxlKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5vZmZzZXRYKSB7XG4gICAgICAgICAgICB0ZXh0QXR0cnMueCArPSB0aGlzLm9wdGlvbnMub2Zmc2V0WCAqIHhfZGlyO1xuICAgICAgICB9XG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICB2YXIgb2Zmc2V0WSA9IGNoaWxkLmdldCgnb2Zmc2V0WScpO1xuICAgICAgICAgICAgdmFyIHlQb3NpdGlvbiA9IHkgKyBvZmZzZXRZO1xuICAgICAgICAgICAgY2hpbGQuYXR0cih0ZXh0QXR0cnMpO1xuICAgICAgICAgICAgY2hpbGQuYXR0cigneScsIHlQb3NpdGlvbik7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXh0R3JvdXAuc2hvdygpO1xuICAgICAgICByZXR1cm4gdGV4dEdyb3VwO1xuICAgIH07XG4gICAgU3BpZGVyTGFiZWwucHJvdG90eXBlLl9kcmF3TGFiZWxMaW5lID0gZnVuY3Rpb24gKGxhYmVsLCBtYXhMYWJlbFdpZHRoLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIF9hbmNob3IgPSBbbGFiZWwuX2FuY2hvci54LCBsYWJlbC5fYW5jaG9yLnldO1xuICAgICAgICB2YXIgX2luZmxlY3Rpb24gPSBbbGFiZWwuX2luZmxlY3Rpb24ueCwgbGFiZWwuX2luZmxlY3Rpb24ueV07XG4gICAgICAgIHZhciB5ID0gbGFiZWwueSwgdGV4dEdyb3VwID0gbGFiZWwudGV4dEdyb3VwO1xuICAgICAgICBpZiAoIXRleHRHcm91cClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIGxhc3RQb2ludCA9IFtsYWJlbC5fc2lkZSA9PT0gJ2xlZnQnID8gdGV4dEdyb3VwLmdldEJCb3goKS5tYXhYICsgNCA6IHRleHRHcm91cC5nZXRCQm94KCkubWluWCAtIDQsIHldO1xuICAgICAgICB2YXIgcG9pbnRzID0gW19hbmNob3IsIF9pbmZsZWN0aW9uLCBsYXN0UG9pbnRdO1xuICAgICAgICBpZiAoX2luZmxlY3Rpb25bMV0gIT09IHkpIHtcbiAgICAgICAgICAgIC8vIOWxleekuuWFqOmDqOaWh+acrOaWh+acrOS9jee9ruWBmui/h+iwg+aVtFxuICAgICAgICAgICAgaWYgKChfaW5mbGVjdGlvblsxXSA8IHRoaXMuaGVpZ2h0IC8gMiAmJiBfaW5mbGVjdGlvblsxXSA8IHkpIHx8XG4gICAgICAgICAgICAgICAgKF9pbmZsZWN0aW9uWzFdID49IHRoaXMuaGVpZ2h0IC8gMiAmJiBfaW5mbGVjdGlvblsxXSA+IHkpKSB7XG4gICAgICAgICAgICAgICAgLy8g5paH5pys6KKr6LCD5pW05LiL5Y675LqG77yM5YiZ5re75Yqg5ouQ54K56L+e5o6l57q/XG4gICAgICAgICAgICAgICAgdmFyIHBvaW50MSA9IF9pbmZsZWN0aW9uO1xuICAgICAgICAgICAgICAgIHZhciBsZWZ0UG9pbnQgPSBsYXN0UG9pbnRbMF0gKyBBREpVU1RPRkZTRVQ7XG4gICAgICAgICAgICAgICAgdmFyIHJpZ2h0UG9pbnQgPSBsYXN0UG9pbnRbMF0gLSBBREpVU1RPRkZTRVQ7XG4gICAgICAgICAgICAgICAgdmFyIHBvaW50MiA9IFtsYWJlbC5fc2lkZSA9PT0gJ2xlZnQnID8gbGVmdFBvaW50IDogcmlnaHRQb2ludCwgX2luZmxlY3Rpb25bMV1dO1xuICAgICAgICAgICAgICAgIHBvaW50cyA9IFtfYW5jaG9yLCBwb2ludDEsIHBvaW50MiwgbGFzdFBvaW50XTtcbiAgICAgICAgICAgICAgICBpZiAoKGxhYmVsLl9zaWRlID09PSAncmlnaHQnICYmIHBvaW50MlswXSA8IHBvaW50MVswXSkgfHwgKGxhYmVsLl9zaWRlID09PSAnbGVmdCcgJiYgcG9pbnQyWzBdID4gcG9pbnQxWzBdKSkge1xuICAgICAgICAgICAgICAgICAgICBwb2ludHMgPSBbX2FuY2hvciwgcG9pbnQxLCBsYXN0UG9pbnRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBvaW50cyA9IFtfYW5jaG9yLCBbX2luZmxlY3Rpb25bMF0sIHldLCBsYXN0UG9pbnRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBwYXRoID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIHZhciBzdGFydGVyID0gJ0wnO1xuICAgICAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgICAgICBzdGFydGVyID0gJ00nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGF0aC5wdXNoKFtzdGFydGVyLCBwWzBdLCBwWzFdXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogdGhpcy5vcHRpb25zLmxpbmUubGluZVdpZHRoLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogdGhpcy5vcHRpb25zLmxpbmUuc3Ryb2tlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOe7mOWItumUmueCuVxuICAgICAgICAvLyBjb250YWluZXIuYWRkU2hhcGUoJ2NpcmNsZScsIHtcbiAgICAgICAgLy8gICBhdHRyczoge1xuICAgICAgICAvLyAgICAgeDogX2FuY2hvclswXSxcbiAgICAgICAgLy8gICAgIHk6IF9hbmNob3JbMV0sXG4gICAgICAgIC8vICAgICByOiB0aGlzLmNvbmZpZy5hbmNob3JTaXplLFxuICAgICAgICAvLyAgICAgZmlsbCxcbiAgICAgICAgLy8gICB9LFxuICAgICAgICAvLyB9KTtcbiAgICB9O1xuICAgIFNwaWRlckxhYmVsLnByb3RvdHlwZS5fYWRqdXN0T3B0aW9ucyA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZy50ZXh0LmZvbnRTaXplKSB7XG4gICAgICAgICAgICBjb25maWcubGluZUhlaWdodCA9IGNvbmZpZy50ZXh0LmZvbnRTaXplICogMztcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFNwaWRlckxhYmVsO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNwaWRlckxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3BpZGVyLWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRMYWJlbFJvdGF0ZSA9IGV4cG9ydHMuZ2V0QW5nbGVCeVBvaW50ID0gZXhwb3J0cy5uZWFyID0gZXhwb3J0cy5pblBhbmVsID0gZXhwb3J0cy5nZXRPdmVybGFwSW5mbyA9IGV4cG9ydHMuZ2V0T3ZlcmxhcEFyZWEgPSBleHBvcnRzLmdldENlbnRlciA9IGV4cG9ydHMuZ2V0RW5kUG9pbnQgPSB2b2lkIDA7XG5mdW5jdGlvbiBnZXRFbmRQb2ludChjZW50ZXIsIGFuZ2xlLCByKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogY2VudGVyLnggKyByICogTWF0aC5jb3MoYW5nbGUpLFxuICAgICAgICB5OiBjZW50ZXIueSArIHIgKiBNYXRoLnNpbihhbmdsZSksXG4gICAgfTtcbn1cbmV4cG9ydHMuZ2V0RW5kUG9pbnQgPSBnZXRFbmRQb2ludDtcbi8qKiDojrflj5bnn6nlvaLkuK3ngrkgKi9cbmZ1bmN0aW9uIGdldENlbnRlcihib3gpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBib3gueCArIGJveC53aWR0aCAvIDIsXG4gICAgICAgIHk6IGJveC55ICsgYm94LmhlaWdodCAvIDIsXG4gICAgfTtcbn1cbmV4cG9ydHMuZ2V0Q2VudGVyID0gZ2V0Q2VudGVyO1xuZnVuY3Rpb24gZ2V0T3ZlcmxhcEFyZWEoYSwgYiwgbWFyZ2luKSB7XG4gICAgaWYgKG1hcmdpbiA9PT0gdm9pZCAwKSB7IG1hcmdpbiA9IDA7IH1cbiAgICB2YXIgeE92ZXJsYXAgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihhLnggKyBhLndpZHRoICsgbWFyZ2luLCBiLnggKyBiLndpZHRoICsgbWFyZ2luKSAtIE1hdGgubWF4KGEueCAtIG1hcmdpbiwgYi54IC0gbWFyZ2luKSk7XG4gICAgdmFyIHlPdmVybGFwID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oYS55ICsgYS5oZWlnaHQgKyBtYXJnaW4sIGIueSArIGIuaGVpZ2h0ICsgbWFyZ2luKSAtIE1hdGgubWF4KGEueSAtIG1hcmdpbiwgYi55IC0gbWFyZ2luKSk7XG4gICAgcmV0dXJuIHhPdmVybGFwICogeU92ZXJsYXA7XG59XG5leHBvcnRzLmdldE92ZXJsYXBBcmVhID0gZ2V0T3ZlcmxhcEFyZWE7XG4vKipcbiAqIOiuoeeul+S4pOS4quefqeW9ouS5i+mXtOeahOWghuWPoOaDheWGtVxuICogQHJldHVybiB4T3ZlcmxhcCB45pa55ZCR6YeN5Y+g5aSn5bCPXG4gKiBAcmV0dXJuIHlPdmVybGFwIHnmlrnlkJHph43lj6DlpKflsI9cbiAqL1xuZnVuY3Rpb24gZ2V0T3ZlcmxhcEluZm8oYSwgYiwgbWFyZ2luKSB7XG4gICAgaWYgKG1hcmdpbiA9PT0gdm9pZCAwKSB7IG1hcmdpbiA9IDA7IH1cbiAgICB2YXIgeE92ZXJsYXAgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihhLnggKyBhLndpZHRoICsgbWFyZ2luLCBiLnggKyBiLndpZHRoICsgbWFyZ2luKSAtIE1hdGgubWF4KGEueCAtIG1hcmdpbiwgYi54IC0gbWFyZ2luKSk7XG4gICAgdmFyIHlPdmVybGFwID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oYS55ICsgYS5oZWlnaHQgKyBtYXJnaW4sIGIueSArIGIuaGVpZ2h0ICsgbWFyZ2luKSAtIE1hdGgubWF4KGEueSAtIG1hcmdpbiwgYi55IC0gbWFyZ2luKSk7XG4gICAgLy8g5re75YqgIHNpZ25cbiAgICBpZiAoeE92ZXJsYXAgJiYgYS54IDwgYi54KSB7XG4gICAgICAgIHhPdmVybGFwID0gLXhPdmVybGFwO1xuICAgIH1cbiAgICBpZiAoeU92ZXJsYXAgJiYgYS55IDwgYi55KSB7XG4gICAgICAgIHlPdmVybGFwID0gLXlPdmVybGFwO1xuICAgIH1cbiAgICAvLyDph43lj6BcbiAgICBpZiAoYS54ID09PSBiLnggJiYgYS53aWR0aCA9PT0gYi53aWR0aCkge1xuICAgICAgICB4T3ZlcmxhcCA9IGIud2lkdGg7XG4gICAgfVxuICAgIGlmIChhLnkgPT09IGIueSAmJiBhLmhlaWdodCA9PT0gYi5oZWlnaHQpIHtcbiAgICAgICAgeU92ZXJsYXAgPSBiLmhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIHsgeE92ZXJsYXA6IHhPdmVybGFwLCB5T3ZlcmxhcDogeU92ZXJsYXAgfTtcbn1cbmV4cG9ydHMuZ2V0T3ZlcmxhcEluZm8gPSBnZXRPdmVybGFwSW5mbztcbi8qKlxuICog57KX55Wl5Zyw5Yik5pat5piv5ZCm5ZyocGFuZWzlhoXpg6hcbiAqIEBwYXJhbSBwYW5lbFxuICogQHBhcmFtIHNoYXBlXG4gKi9cbmZ1bmN0aW9uIGluUGFuZWwocGFuZWwsIHNoYXBlKSB7XG4gICAgcmV0dXJuIChwYW5lbC54IDwgc2hhcGUueCAmJlxuICAgICAgICBwYW5lbC54ICsgcGFuZWwud2lkdGggPiBzaGFwZS54ICsgc2hhcGUud2lkdGggJiZcbiAgICAgICAgcGFuZWwueSA8IHNoYXBlLnkgJiZcbiAgICAgICAgcGFuZWwueSArIHBhbmVsLmhlaWdodCA+IHNoYXBlLnkgKyBzaGFwZS5oZWlnaHQpO1xufVxuZXhwb3J0cy5pblBhbmVsID0gaW5QYW5lbDtcbi8qKlxuICog5Yik5pat5Lik5Liq5pWw5YC8IOaYr+WQpuaOpei/kVxuICogLSDop6PlhrPnsr7luqbpl67popjvvIjnlLHkuo7ml6Dms5Xnoa7lrprnsr7luqbkuIrpmZDvvIzmoLnmja7lhbfkvZPlnLrmma/lj6/kvKDlhaUg57K+5bqmIOWPguaVsO+8iVxuICovXG5leHBvcnRzLm5lYXIgPSBmdW5jdGlvbiAoeCwgeSwgZSkge1xuICAgIGlmIChlID09PSB2b2lkIDApIHsgZSA9IE1hdGgucG93KE51bWJlci5FUFNJTE9OLCAwLjUpOyB9XG4gICAgcmV0dXJuIFt4LCB5XS5pbmNsdWRlcyhJbmZpbml0eSkgPyBNYXRoLmFicyh4KSA9PT0gTWF0aC5hYnMoeSkgOiBNYXRoLmFicyh4IC0geSkgPCBlO1xufTtcbi8qKlxuICog6I635Y+W54K55Yiw5ZyG5b+D55qE6L+e57q/5LiO5rC05bmz5pa55ZCR55qE5aS56KeSXG4gKi9cbmZ1bmN0aW9uIGdldEFuZ2xlQnlQb2ludChjb29yZGluYXRlLCBwb2ludCkge1xuICAgIHZhciBjZW50ZXIgPSBjb29yZGluYXRlLmdldENlbnRlcigpO1xuICAgIHJldHVybiBNYXRoLmF0YW4yKHBvaW50LnkgLSBjZW50ZXIueSwgcG9pbnQueCAtIGNlbnRlci54KTtcbn1cbmV4cG9ydHMuZ2V0QW5nbGVCeVBvaW50ID0gZ2V0QW5nbGVCeVBvaW50O1xuLyoqXG4gKiDojrflj5YgbGFiZWwg55qE5peL6L2s6KeS5bqmXG4gKiBAcGFyYW0gYW5nbGVcbiAqL1xuZnVuY3Rpb24gZ2V0TGFiZWxSb3RhdGUoYW5nbGUpIHtcbiAgICB2YXIgSEFMRl9QSSA9IE1hdGguUEkgLyAyO1xuICAgIHZhciByb3RhdGUgPSBhbmdsZTtcbiAgICBpZiAocm90YXRlID4gSEFMRl9QSSB8fCByb3RhdGUgPCAtSEFMRl9QSSkge1xuICAgICAgICByb3RhdGUgPSByb3RhdGUgKyBNYXRoLlBJO1xuICAgIH1cbiAgICByZXR1cm4gcm90YXRlO1xufVxuZXhwb3J0cy5nZXRMYWJlbFJvdGF0ZSA9IGdldExhYmVsUm90YXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBwaWU6ICdpbnRlcnZhbCcsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgUGllID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBpZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQaWUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUGllLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAncGllJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFBpZS5wcm90b3R5cGUuZ2V0QW5nbGVTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy5sYXllcnNbMF07XG4gICAgICAgIHJldHVybiBsYXllci5nZXRBbmdsZVNjYWxlKCk7XG4gICAgfTtcbiAgICBQaWUuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFBpZTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFBpZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5wZXJjZW50YWdlRmllbGQgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50L2xhYmVsXCIpO1xudmFyIHNwaWRlcl9sYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50L2xhYmVsL3NwaWRlci1sYWJlbFwiKSk7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbmV4cG9ydHMucGVyY2VudGFnZUZpZWxkID0gJyQkcGVyY2VudGFnZSQkJztcbnZhciBHMl9HRU9NX01BUCA9IHtcbiAgICBwaWU6ICdpbnRlcnZhbCcsXG59O1xudmFyIFBMT1RfR0VPTV9NQVAgPSB7XG4gICAgcGllOiAnY29sdW1uJyxcbn07XG4vLyBAdHMtaWdub3JlXG52YXIgUGllTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUGllTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUGllTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3BpZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUGllTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHdpZHRoOiA0MDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDQwMCxcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmb3JjZUZpdDogdHJ1ZSxcbiAgICAgICAgICAgIHBhZGRpbmc6ICdhdXRvJyxcbiAgICAgICAgICAgIHJhZGl1czogMC44LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdpbm5lcicsXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgYWRqdXN0UG9zaXRpb246IHRydWUsXG4gICAgICAgICAgICAgICAgYWxsb3dPdmVybGFwOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHNtb290aDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdyaWdodC1jZW50ZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNoYXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dNYXJrZXJzOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwaWVTdHlsZToge1xuICAgICAgICAgICAgICAgIHN0cm9rZTogJ3doaXRlJyxcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFBpZUxheWVyLnByb3RvdHlwZS5hZnRlckluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJJbml0LmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgYW5nbGVGaWVsZCA9IF9hLmFuZ2xlRmllbGQsIGNvbG9yRmllbGQgPSBfYS5jb2xvckZpZWxkLCBkYXRhID0gX2EuZGF0YTtcbiAgICAgICAgdmFyIGFsbFplcm8gPSB1dGlsXzEuZXZlcnkoZGF0YSwgZnVuY3Rpb24gKGQpIHsgcmV0dXJuIGRbYW5nbGVGaWVsZF0gPT09IDA7IH0pO1xuICAgICAgICBpZiAoYWxsWmVybykge1xuICAgICAgICAgICAgdmFyIHBpZUdlb20gPSB0aGlzLnZpZXcuZ2VvbWV0cmllc1swXTtcbiAgICAgICAgICAgIHBpZUdlb20udG9vbHRpcChjb2xvckZpZWxkICsgXCIqXCIgKyBhbmdsZUZpZWxkKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUGllTGF5ZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICAvKiog6JyY6Jub5biD5bGAbGFiZWwgKi9cbiAgICAgICAgaWYgKG9wdGlvbnMubGFiZWwgJiYgb3B0aW9ucy5sYWJlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICAvLyDmuIXpmaTvvIzpgb/lhY3kuozmrKHmuLLmn5NcbiAgICAgICAgICAgIGlmICh0aGlzLmxhYmVsQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sYWJlbENvbXBvbmVudC5jbGVhcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGxhYmVsQ29uZmlnID0gb3B0aW9ucy5sYWJlbDtcbiAgICAgICAgICAgIGlmIChsYWJlbENvbmZpZy50eXBlID09PSAnc3BpZGVyJykge1xuICAgICAgICAgICAgICAgIHZhciBkYXRhID0gb3B0aW9ucy5kYXRhLCBjb2xvckZpZWxkID0gb3B0aW9ucy5jb2xvckZpZWxkLCBhbmdsZUZpZWxkXzEgPSBvcHRpb25zLmFuZ2xlRmllbGQ7XG4gICAgICAgICAgICAgICAgdmFyIGFsbFplcm8gPSB1dGlsXzEuZXZlcnkoZGF0YSwgZnVuY3Rpb24gKGQpIHsgcmV0dXJuIGRbYW5nbGVGaWVsZF8xXSA9PT0gMDsgfSk7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlRmllbGQgPSBhbGxaZXJvID8gZXhwb3J0cy5wZXJjZW50YWdlRmllbGQgOiBhbmdsZUZpZWxkXzE7XG4gICAgICAgICAgICAgICAgdGhpcy5sYWJlbENvbXBvbmVudCA9IG5ldyBzcGlkZXJfbGFiZWxfMS5kZWZhdWx0KHRzbGliXzEuX19hc3NpZ24oeyB2aWV3OiB0aGlzLnZpZXcsIGZpZWxkczogY29sb3JGaWVsZCA/IFt2YWx1ZUZpZWxkLCBjb2xvckZpZWxkXSA6IFt2YWx1ZUZpZWxkXSwgYW5nbGVGaWVsZDogYW5nbGVGaWVsZF8xLFxuICAgICAgICAgICAgICAgICAgICBhbGxaZXJvOiBhbGxaZXJvIH0sIHRoaXMub3B0aW9ucy5sYWJlbCkpO1xuICAgICAgICAgICAgICAgIHRoaXMubGFiZWxDb21wb25lbnQucmVuZGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgTGFiZWxDdG9yID0gbGFiZWxfMS5nZXRQaWVMYWJlbChsYWJlbENvbmZpZy50eXBlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVsQ29tcG9uZW50ID0gbmV3IExhYmVsQ3Rvcih0aGlzLCBvcHRpb25zLmxhYmVsKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVsQ29tcG9uZW50LnJlbmRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBQaWVMYXllci5wcm90b3R5cGUuZ2V0QW5nbGVTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFuZ2xlRmllbGQgPSB0aGlzLm9wdGlvbnMuYW5nbGVGaWVsZDtcbiAgICAgICAgaWYgKGFuZ2xlRmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKGFuZ2xlRmllbGQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQaWVMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoZGltLCB0eXBlKSB7XG4gICAgICAgIGlmIChkaW0gPT09ICdnMicpIHtcbiAgICAgICAgICAgIHJldHVybiBHMl9HRU9NX01BUFt0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUExPVF9HRU9NX01BUFt0eXBlXTtcbiAgICB9O1xuICAgIFBpZUxheWVyLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgc2NhbGVzW3Byb3BzLmFuZ2xlRmllbGRdID0ge307XG4gICAgICAgIHNjYWxlc1twcm9wcy5jb2xvckZpZWxkXSA9IHsgdHlwZTogJ2NhdCcgfTtcbiAgICAgICAgc2NhbGVzID0gdXRpbF8xLmRlZXBNaXgoe30sIHRoaXMuY29uZmlnLnNjYWxlcywgc2NhbGVzKTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ3NjYWxlcycsIHNjYWxlcyk7XG4gICAgfTtcbiAgICBQaWVMYXllci5wcm90b3R5cGUucHJvY2Vzc0RhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIga2V5ID0gdGhpcy5vcHRpb25zLmFuZ2xlRmllbGQ7XG4gICAgICAgIHZhciBhbGxaZXJvID0gdXRpbF8xLmV2ZXJ5KGRhdGEsIGZ1bmN0aW9uIChkKSB7IHJldHVybiBkW2tleV0gPT09IDA7IH0pO1xuICAgICAgICBpZiAoYWxsWmVybykge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGEubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgICAgIHJldHVybiAodHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBpdGVtKSwgKF9hID0ge30sIF9hW2tleV0gPSB0eXBlb2YgaXRlbVtrZXldID09PSAnc3RyaW5nJyA/IE51bWJlci5wYXJzZUZsb2F0KGl0ZW1ba2V5XSkgOiBpdGVtW2tleV0sIF9hW2V4cG9ydHMucGVyY2VudGFnZUZpZWxkXSA9IDEgLyBkYXRhLmxlbmd0aCwgX2EpKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGl0ZW1ba2V5XTtcbiAgICAgICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGl0ZW0pLCAoX2EgPSB7fSwgX2Fba2V5XSA9IHZhbHVlICYmICFpc05hTih2YWx1ZSkgPyArdmFsdWUgOiB2YWx1ZSwgX2EpKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBQaWVMYXllci5wcm90b3R5cGUuYXhpcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgUGllTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBjb29yZENvbmZpZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICd0aGV0YScsXG4gICAgICAgICAgICBjZmc6IHtcbiAgICAgICAgICAgICAgICByYWRpdXM6IHByb3BzLnJhZGl1cyxcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlIOS4muWKoeWumuWItizkuI3lvIDmlL7phY3nva5cbiAgICAgICAgICAgICAgICBpbm5lclJhZGl1czogcHJvcHMuaW5uZXJSYWRpdXMgfHwgMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdjb29yZGluYXRlJywgY29vcmRDb25maWcpO1xuICAgIH07XG4gICAgUGllTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBkYXRhID0gcHJvcHMuZGF0YSwgYW5nbGVGaWVsZCA9IHByb3BzLmFuZ2xlRmllbGQ7XG4gICAgICAgIHZhciBwaWU7XG4gICAgICAgIHZhciBhbGxaZXJvID0gdXRpbF8xLmV2ZXJ5KGRhdGEsIGZ1bmN0aW9uIChkKSB7IHJldHVybiBkW2FuZ2xlRmllbGRdID09PSAwOyB9KTtcbiAgICAgICAgaWYgKGFsbFplcm8pIHtcbiAgICAgICAgICAgIHBpZSA9IGZhY3RvcnlfMS5nZXRHZW9tKCdpbnRlcnZhbCcsICdtYWluJywge1xuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICAgICAgcG9zaXRpb25GaWVsZHM6IFsxLCBleHBvcnRzLnBlcmNlbnRhZ2VGaWVsZF0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHBpZSA9IGZhY3RvcnlfMS5nZXRHZW9tKCdpbnRlcnZhbCcsICdtYWluJywge1xuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICAgICAgcG9zaXRpb25GaWVsZHM6IFsxLCBwcm9wcy5hbmdsZUZpZWxkXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHBpZS5hZGp1c3QgPSBbeyB0eXBlOiAnc3RhY2snIH1dO1xuICAgICAgICB0aGlzLnBpZSA9IHBpZTtcbiAgICAgICAgaWYgKHByb3BzLmxhYmVsKSB7XG4gICAgICAgICAgICB0aGlzLmxhYmVsKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzLnRvb2x0aXAgJiYgKHByb3BzLnRvb2x0aXAuZmllbGRzIHx8IHByb3BzLnRvb2x0aXAuZm9ybWF0dGVyKSkge1xuICAgICAgICAgICAgdGhpcy5nZW9tZXRyeVRvb2x0aXAoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBwaWUpO1xuICAgIH07XG4gICAgUGllTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5waWUudG9vbHRpcCA9IHt9O1xuICAgICAgICB2YXIgdG9vbHRpcE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMudG9vbHRpcDtcbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgdGhpcy5waWUudG9vbHRpcC5maWVsZHMgPSB0b29sdGlwT3B0aW9ucy5maWVsZHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnBpZS50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMuYW5nbGVGaWVsZCwgdGhpcy5vcHRpb25zLmNvbG9yRmllbGRdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMucGllLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAoIXRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIHRoaXMucGllLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy5hbmdsZUZpZWxkLCB0aGlzLm9wdGlvbnMuY29sb3JGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFBpZUxheWVyLnByb3RvdHlwZS5hbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYW5pbWF0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8qKiDlhbPpl63liqjnlLsgKi9cbiAgICAgICAgICAgIHRoaXMucGllLmFuaW1hdGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUGllTGF5ZXIucHJvdG90eXBlLmFubm90YXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIFBpZUxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uIChldmVudFBhcnNlcikge1xuICAgICAgICBpZiAoZXZlbnRQYXJzZXIpIHtcbiAgICAgICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBldmVudFBhcnNlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgRXZlbnRQYXJzZXIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQaWVMYXllci5wcm90b3R5cGUubGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIOS4jeS9v+eUqCBnMiDlhoXnva5sYWJlbFxuICAgICAgICB0aGlzLnBpZS5sYWJlbCA9IGZhbHNlO1xuICAgIH07XG4gICAgcmV0dXJuIFBpZUxheWVyO1xufSh2aWV3X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUGllTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdwaWUnLCBQaWVMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIFBJRV9BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBmaWxsT3BhY2l0eTogb3BhY2l0eSAqIDAuOCB9O1xufTtcbnZhciBQSUVfRElTQUJMRV9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBvcGFjaXR5ID0gc3R5bGUub3BhY2l0eSB8fCAxO1xuICAgIHJldHVybiB7IGZpbGxPcGFjaXR5OiBvcGFjaXR5ICogMC41IH07XG59O1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdwaWUnLCB7XG4gICAgY29sdW1uU3R5bGU6IHtcbiAgICAgICAgbm9ybWFsOiB7fSxcbiAgICAgICAgYWN0aXZlOiBQSUVfQUNUSVZFX1NUWUxFLFxuICAgICAgICBkaXNhYmxlOiBQSUVfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IHsgbGluZVdpZHRoOiAxLCBzdHJva2U6ICdibGFjaycgfSxcbiAgICB9LFxufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE0XG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBhcmVhOiAnYXJlYScsXG4gICAgbGluZTogJ2xpbmUnLFxuICAgIHBvaW50OiAncG9pbnQnLFxufTtcbnZhciBTSEFQRV9FVkVOVF9NQVAgPSBldmVudF8xLmdldEV2ZW50TWFwKGNvbXBvbmVudE1hcCk7XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQ3JlYXRlIEJ5IEJydWNlIFRvb1xuICogT24gMjAyMC0wMi0xNFxuICovXG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBSYWRhciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhSYWRhciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSYWRhcigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBSYWRhci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3JhZGFyJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFJhZGFyLnByb3RvdHlwZS5nZXRBbmdsZVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgcmV0dXJuIGxheWVyLmdldEFuZ2xlU2NhbGUoKTtcbiAgICB9O1xuICAgIFJhZGFyLnByb3RvdHlwZS5nZXRSYWRpdXNTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy5sYXllcnNbMF07XG4gICAgICAgIHJldHVybiBsYXllci5nZXRSYWRpdXNTY2FsZSgpO1xuICAgIH07XG4gICAgUmFkYXIucHJvdG90eXBlLmdldENvbG9yU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0Q29sb3JTY2FsZSgpO1xuICAgIH07XG4gICAgUmFkYXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFJhZGFyO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmFkYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE0XG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9mYWN0b3J5XCIpO1xudmFyIGZhY3RvcnlfMiA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9zY2FsZVwiKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnJlcXVpcmUoXCIuL3RoZW1lXCIpO1xudmFyIEdFT01fTUFQID0ge1xuICAgIGFyZWE6ICdhcmVhJyxcbiAgICBsaW5lOiAnbGluZScsXG4gICAgcG9pbnQ6ICdwb2ludCcsXG59O1xudmFyIFJhZGFyTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoUmFkYXJMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSYWRhckxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdyYWRhcic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUmFkYXJMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgd2lkdGg6IDQwMCxcbiAgICAgICAgICAgIGhlaWdodDogNDAwLFxuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZvcmNlRml0OiB0cnVlLFxuICAgICAgICAgICAgcGFkZGluZzogJ2F1dG8nLFxuICAgICAgICAgICAgcmFkaXVzOiAwLjgsXG4gICAgICAgICAgICBzbW9vdGg6IGZhbHNlLFxuICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2l6ZTogMixcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXJlYToge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMC4yNSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvaW50OiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2l6ZTogNCxcbiAgICAgICAgICAgICAgICBzaGFwZTogJ3BvaW50JyxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYW5nbGVBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlVGl0bGU6IHRydWUsXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVEYXNoOiBbMCwgMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiAxNixcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJhZGl1c0F4aXM6IHtcbiAgICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAvKiogRzIgNC4wIOm7mOiupCBuaWNlIOS4jeeUn+aViO+8jOmcgOimgeaJi+WKqOa3u+WKoCAqL1xuICAgICAgICAgICAgICAgIG5pY2U6IHRydWUsXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZVRpdGxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBncmlkVHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lRGFzaDogWzAsIDBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdwb2ludCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2xlZnQtdG9wJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzaGFyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHByb3BzLnhGaWVsZCA9IHByb3BzLmFuZ2xlRmllbGQ7XG4gICAgICAgIHByb3BzLnlGaWVsZCA9IHByb3BzLnJhZGl1c0ZpZWxkO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIFJhZGFyTGF5ZXIucHJvdG90eXBlLmdldEFuZ2xlU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhbmdsZUZpZWxkID0gdGhpcy5vcHRpb25zLmFuZ2xlRmllbGQ7XG4gICAgICAgIHJldHVybiB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKGFuZ2xlRmllbGQpO1xuICAgIH07XG4gICAgUmFkYXJMYXllci5wcm90b3R5cGUuZ2V0UmFkaXVzU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByYWRpdXNGaWVsZCA9IHRoaXMub3B0aW9ucy5yYWRpdXNGaWVsZDtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQocmFkaXVzRmllbGQpO1xuICAgIH07XG4gICAgUmFkYXJMYXllci5wcm90b3R5cGUuZ2V0Q29sb3JTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNlcmllc0ZpZWxkID0gdGhpcy5vcHRpb25zLnNlcmllc0ZpZWxkO1xuICAgICAgICByZXR1cm4gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZChzZXJpZXNGaWVsZCk7XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIEdFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgUmFkYXJMYXllci5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHNjYWxlcyA9IHt9O1xuICAgICAgICAvKiog6YWN572ueC1zY2FsZSAqL1xuICAgICAgICBzY2FsZXNbcHJvcHMuYW5nbGVGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICdhbmdsZUF4aXMnKSkge1xuICAgICAgICAgICAgc2NhbGVfMS5leHRyYWN0U2NhbGUoc2NhbGVzW3Byb3BzLmFuZ2xlRmllbGRdLCBwcm9wcy5hbmdsZUF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIC8qKiDphY3nva55LXNjYWxlICovXG4gICAgICAgIHNjYWxlc1twcm9wcy5yYWRpdXNGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICdyYWRpdXNBeGlzJykpIHtcbiAgICAgICAgICAgIHNjYWxlXzEuZXh0cmFjdFNjYWxlKHNjYWxlc1twcm9wcy5yYWRpdXNGaWVsZF0sIHByb3BzLnJhZGl1c0F4aXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgY29vcmRDb25maWcgPSB7XG4gICAgICAgICAgICB0eXBlOiAncG9sYXInLFxuICAgICAgICAgICAgY2ZnOiB7XG4gICAgICAgICAgICAgICAgcmFkaXVzOiBwcm9wcy5yYWRpdXMsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldENvbmZpZygnY29vcmRpbmF0ZScsIGNvb3JkQ29uZmlnKTtcbiAgICB9O1xuICAgIFJhZGFyTGF5ZXIucHJvdG90eXBlLmF4aXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHhBeGlzX3BhcnNlciA9IGZhY3RvcnlfMS5nZXRDb21wb25lbnQoJ2F4aXMnLCB7XG4gICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgZGltOiAnYW5nbGUnLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHlBeGlzX3BhcnNlciA9IGZhY3RvcnlfMS5nZXRDb21wb25lbnQoJ2F4aXMnLCB7XG4gICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgZGltOiAncmFkaXVzJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBheGVzQ29uZmlnID0ge307XG4gICAgICAgIGF4ZXNDb25maWdbcHJvcHMuYW5nbGVGaWVsZF0gPSB4QXhpc19wYXJzZXI7XG4gICAgICAgIGF4ZXNDb25maWdbcHJvcHMucmFkaXVzRmllbGRdID0geUF4aXNfcGFyc2VyO1xuICAgICAgICAvKiog5a2Y5YKo5Z2Q5qCH6L206YWN572u6aG55YiwY29uZmlnICovXG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdheGVzJywgYXhlc0NvbmZpZyk7XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICAvKiog6YWN572u6Z2i56evICovXG4gICAgICAgIGlmIChwcm9wcy5hcmVhLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBhcmVhID0gZmFjdG9yeV8yLmdldEdlb20oJ2FyZWEnLCAnbWFpbicsIHtcbiAgICAgICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBhcmVhKTtcbiAgICAgICAgICAgIHRoaXMuYXJlYSA9IGFyZWE7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rue6vyAqL1xuICAgICAgICBpZiAocHJvcHMubGluZSAmJiBwcm9wcy5saW5lLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBsaW5lID0gZmFjdG9yeV8yLmdldEdlb20oJ2xpbmUnLCAnbWFpbicsIHtcbiAgICAgICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBsaW5lKTtcbiAgICAgICAgICAgIHRoaXMubGluZSA9IGxpbmU7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rueCuSAqL1xuICAgICAgICBpZiAocHJvcHMucG9pbnQgJiYgcHJvcHMucG9pbnQudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIHBvaW50ID0gZmFjdG9yeV8yLmdldEdlb20oJ3BvaW50JywgJ2d1aWRlJywge1xuICAgICAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIHBvaW50KTtcbiAgICAgICAgICAgIHRoaXMucG9pbnQgPSBwb2ludDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMubGFiZWwpIHtcbiAgICAgICAgICAgIHRoaXMubGFiZWwoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMudG9vbHRpcCAmJiAocHJvcHMudG9vbHRpcC5maWVsZHMgfHwgcHJvcHMudG9vbHRpcC5mb3JtYXR0ZXIpKSB7XG4gICAgICAgICAgICB0aGlzLmdlb21ldHJ5VG9vbHRpcCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBnZW9tQ29uZmlnID0gdGhpcy5saW5lID8gdGhpcy5saW5lIDogdGhpcy5hcmVhO1xuICAgICAgICBnZW9tQ29uZmlnLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIGdlb21Db25maWcudG9vbHRpcC5maWVsZHMgPSB0b29sdGlwT3B0aW9ucy5maWVsZHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcikge1xuICAgICAgICAgICAgZ2VvbUNvbmZpZy50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICBnZW9tQ29uZmlnLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy5hbmdsZUZpZWxkLCB0aGlzLm9wdGlvbnMucmFkaXVzRmllbGRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zZXJpZXNGaWVsZCkge1xuICAgICAgICAgICAgICAgIGdlb21Db25maWcudG9vbHRpcC5maWVsZHMucHVzaCh0aGlzLm9wdGlvbnMuc2VyaWVzRmllbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5sYWJlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAocHJvcHMubGFiZWwudmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBvaW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludC5sYWJlbCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMubGluZSkge1xuICAgICAgICAgICAgICAgIHRoaXMubGluZS5sYWJlbCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuYXJlYSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJlYS5sYWJlbCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIEBUb2RvIOmbt+i+vuWbvuagh+etvuW4g+WxgOeul+azleWQjue7reihpeWFhVxuICAgICAgICB2YXIgbGFiZWwgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdsYWJlbCcsIHRzbGliXzEuX19hc3NpZ24oeyBmaWVsZHM6IFtwcm9wcy5yYWRpdXNGaWVsZF0sIGNmZzoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdwb2xhcicsXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICB9LCBwbG90OiB0aGlzIH0sIHByb3BzLmxhYmVsKSk7XG4gICAgICAgIGlmICh0aGlzLnBvaW50KSB7XG4gICAgICAgICAgICB0aGlzLnBvaW50LmxhYmVsID0gbGFiZWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5saW5lKSB7XG4gICAgICAgICAgICB0aGlzLmxpbmUubGFiZWwgPSBsYWJlbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmFyZWEpIHtcbiAgICAgICAgICAgIHRoaXMuYXJlYS5sYWJlbCA9IGxhYmVsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5hbm5vdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBSYWRhckxheWVyLnByb3RvdHlwZS5hbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYW5pbWF0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8vIOWFs+mXreWKqOeUu1xuICAgICAgICAgICAgaWYgKHRoaXMuYXJlYSlcbiAgICAgICAgICAgICAgICB0aGlzLmFyZWEuYW5pbWF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHRoaXMubGluZSlcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmUuYW5pbWF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHRoaXMucG9pbnQpXG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludC5hbmltYXRlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJhZGFyTGF5ZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgRXZlbnRQYXJzZXIpO1xuICAgIH07XG4gICAgcmV0dXJuIFJhZGFyTGF5ZXI7XG59KHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSYWRhckxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgncmFkYXInLCBSYWRhckxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE0XG4gKi9cbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIEFSRUFfQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSB9O1xufTtcbnZhciBBUkVBX0RJU0FCTEVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5ICogMC41IH07XG59O1xudmFyIExJTkVfQUNUSVZFX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSB9O1xufTtcbnZhciBMSU5FX0RJU0FCTEVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgb3BhY2l0eSA9IHN0eWxlLm9wYWNpdHkgfHwgMTtcbiAgICByZXR1cm4geyBvcGFjaXR5OiBvcGFjaXR5ICogMC41IH07XG59O1xudmFyIExJTkVfU0VMRUNURURfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgbGluZVdpZHRoID0gc3R5bGUubGluZVdpZHRoIHx8IDE7XG4gICAgcmV0dXJuIHsgbGluZVdpZHRoOiBsaW5lV2lkdGggKyAyIH07XG59O1xudmFyIFBPSU5UX0FDVElWRV9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBjb2xvciA9IHN0eWxlLmZpbGwgfHwgc3R5bGUuZmlsbFN0eWxlO1xuICAgIHZhciByYWRpdXMgPSBzdHlsZS5zaXplIHx8IHN0eWxlLnJhZGl1cztcbiAgICByZXR1cm4ge1xuICAgICAgICByYWRpdXM6IHJhZGl1cyArIDEsXG4gICAgICAgIHNoYWRvd0JsdXI6IHJhZGl1cyxcbiAgICAgICAgc2hhZG93Q29sb3I6IGNvbG9yLFxuICAgICAgICBzdHJva2U6IGNvbG9yLFxuICAgICAgICBzdHJva2VPcGFjaXR5OiAxLFxuICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgfTtcbn07XG52YXIgUE9JTlRfU0VMRUNURURfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgY29sb3IgPSBzdHlsZS5maWxsIHx8IHN0eWxlLmZpbGxTdHlsZTtcbiAgICB2YXIgcmFkaXVzID0gc3R5bGUuc2l6ZSB8fCBzdHlsZS5yYWRpdXM7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmFkaXVzOiByYWRpdXMgKyAyLFxuICAgICAgICBzaGFkb3dCbHVyOiByYWRpdXMsXG4gICAgICAgIHNoYWRvd0NvbG9yOiBjb2xvcixcbiAgICAgICAgc3Ryb2tlOiBjb2xvcixcbiAgICAgICAgc3Ryb2tlT3BhY2l0eTogMSxcbiAgICAgICAgbGluZVdpZHRoOiAyLFxuICAgIH07XG59O1xudmFyIFBPSU5UX0RJU0FCTEVEX1NUWUxFID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdmFyIG9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5IHx8IHN0eWxlLmZpbGxPcGFjaXR5IHx8IDE7XG4gICAgcmV0dXJuIHsgb3BhY2l0eTogb3BhY2l0eSAqIDAuNSB9O1xufTtcbnRoZW1lXzEucmVnaXN0ZXJUaGVtZSgncmFkYXInLCB7XG4gICAgYXJlYVN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogQVJFQV9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IEFSRUFfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IHsgbGluZVdpZHRoOiAxLCBzdHJva2U6ICcjMzMzMzMzJyB9LFxuICAgIH0sXG4gICAgbGluZVN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogTElORV9BQ1RJVkVfU1RZTEUsXG4gICAgICAgIGRpc2FibGU6IExJTkVfRElTQUJMRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IExJTkVfU0VMRUNURURfU1RZTEUsXG4gICAgfSxcbiAgICBwb2ludFN0eWxlOiB7XG4gICAgICAgIG5vcm1hbDoge30sXG4gICAgICAgIGFjdGl2ZTogUE9JTlRfQUNUSVZFX1NUWUxFLFxuICAgICAgICBkaXNhYmxlOiBQT0lOVF9ESVNBQkxFRF9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IFBPSU5UX1NFTEVDVEVEX1NUWUxFLFxuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRoZW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5zZXRTaGFwZUNhY2hlID0gdm9pZCAwO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLy8g6K6w5b2V5LmL5YmN55qE54q25oCBXG52YXIgc2hhcGVDYWNoZTtcbmZ1bmN0aW9uIGNsaXBJbkZyb21DZW50ZXIoc2hhcGUsIGFuaW1hdGVDZmcpIHtcbiAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICB2YXIgY2VudGVyWCA9IGJib3gubWluWCArIGJib3gud2lkdGggLyAyO1xuICAgIHNoYXBlLnNldENsaXAoe1xuICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB4OiBjZW50ZXJYLFxuICAgICAgICAgICAgeTogYmJveC5taW5ZLFxuICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICBoZWlnaHQ6IGJib3guaGVpZ2h0LFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIHZhciBjbGlwZXIgPSBzaGFwZS5nZXQoJ2NsaXBTaGFwZScpO1xuICAgIGNsaXBlci5hbmltYXRlKHtcbiAgICAgICAgd2lkdGg6IGJib3gud2lkdGgsXG4gICAgICAgIHg6IGJib3gubWluWCxcbiAgICB9LCBhbmltYXRlQ2ZnLmR1cmF0aW9uLCBhbmltYXRlQ2ZnLmVhc2luZywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzaGFwZS5zZXRDbGlwKG51bGwpO1xuICAgIH0sIGFuaW1hdGVDZmcuZGVsYXkpO1xufVxuY2xpcEluRnJvbUNlbnRlci5hbmltYXRpb25OYW1lID0gJ2NsaXBJbkZyb21DZW50ZXInO1xuZnVuY3Rpb24gc2V0U2hhcGVDYWNoZShzaGFwZXMpIHtcbiAgICBzaGFwZUNhY2hlID0gc2hhcGVzO1xufVxuZXhwb3J0cy5zZXRTaGFwZUNhY2hlID0gc2V0U2hhcGVDYWNoZTtcbmZ1bmN0aW9uIHVwZGF0ZUZyb21DZW50ZXIoc2hhcGUsIGFuaW1hdGVDZmcpIHtcbiAgICB2YXIgZnJvbVBhdGggPSBnZXRTaGFwZUZyb21DYWNoZShzaGFwZSkuYXR0cigncGF0aCcpO1xuICAgIHZhciB0b1BhdGggPSB1dGlsXzEuY2xvbmUoc2hhcGUuYXR0cigncGF0aCcpKTtcbiAgICBzaGFwZS5hdHRyKCdwYXRoJywgZnJvbVBhdGgpO1xuICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICBwYXRoOiB0b1BhdGgsXG4gICAgfSwgYW5pbWF0ZUNmZy5kdXJhdGlvbiwgYW5pbWF0ZUNmZy5lYXNpbmcsIGFuaW1hdGVDZmcuY2FsbGJhY2ssIDEwMCk7XG59XG5mdW5jdGlvbiBnZXRTaGFwZUZyb21DYWNoZShzaGFwZSkge1xuICAgIHZhciBpZCA9IHNoYXBlLmlkO1xuICAgIHZhciB0YXJnZXQ7XG4gICAgdXRpbF8xLmVhY2goc2hhcGVDYWNoZSwgZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgaWYgKHMuaWQgPT09IGlkKSB7XG4gICAgICAgICAgICB0YXJnZXQgPSBzO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cbnVwZGF0ZUZyb21DZW50ZXIuYW5pbWF0aW9uTmFtZSA9ICd1cGRhdGVGcm9tQ2VudGVyJztcbmRlcGVuZGVudHNfMS5yZWdpc3RlckFuaW1hdGlvbignY2xpcEluRnJvbUNlbnRlcicsIGNsaXBJbkZyb21DZW50ZXIpO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyQW5pbWF0aW9uKCd1cGRhdGVGcm9tQ2VudGVyJywgdXBkYXRlRnJvbUNlbnRlcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hbmltYXRpb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBjb2xvcl8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvY29sb3JcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgREVGQVVMVF9PRkZTRVQgPSA4O1xuZnVuY3Rpb24gbWFwcGluZ0NvbG9yKGJhbmQsIGdyYXkpIHtcbiAgICB2YXIgcmVmbGVjdDtcbiAgICB1dGlsXzEuZWFjaChiYW5kLCBmdW5jdGlvbiAoYikge1xuICAgICAgICB2YXIgbWFwID0gYjtcbiAgICAgICAgaWYgKGdyYXkgPj0gbWFwLmZyb20gJiYgZ3JheSA8IG1hcC50bykge1xuICAgICAgICAgICAgcmVmbGVjdCA9IG1hcC5jb2xvcjtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZWZsZWN0O1xufVxudmFyIFJhbmdlQmFyTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUmFuZ2VCYXJMYWJlbChjZmcpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52aWV3ID0gY2ZnLnZpZXc7XG4gICAgICAgIHRoaXMucGxvdCA9IGNmZy5wbG90O1xuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmdldERlZmF1bHRPcHRpb25zKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KGRlZmF1bHRPcHRpb25zLCBjZmcsIHt9KTtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubGVmdFN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMubGVmdFN0eWxlID0gdGhpcy5vcHRpb25zLnN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLnJpZ2h0U3R5bGUpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5yaWdodFN0eWxlID0gdGhpcy5vcHRpb25zLnN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cbiAgICBSYW5nZUJhckxhYmVsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5sYWJlbHNDb250YWluZXI7XG4gICAgICAgIHRoaXMudmlldy5vbignYmVmb3JlcmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuY2xlYXIoKTtcbiAgICAgICAgICAgIF90aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBSYW5nZUJhckxhYmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMuZ2V0R2VvbWV0cnkoKSwgZWxlbWVudHMgPSBfYS5lbGVtZW50cywgY29vcmRpbmF0ZSA9IF9hLmNvb3JkaW5hdGU7XG4gICAgICAgIHRoaXMuY29vcmQgPSBjb29yZGluYXRlO1xuICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgdmFyIHNoYXBlID0gZWxlLnNoYXBlO1xuICAgICAgICAgICAgdmFyIHBvc2l0aW9ucyA9IF90aGlzLmdldFBvc2l0aW9uKHNoYXBlKTtcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBfdGhpcy5nZXRWYWx1ZShzaGFwZSk7XG4gICAgICAgICAgICB2YXIgdGV4dEFsaWduID0gX3RoaXMuZ2V0VGV4dEFsaWduKCk7XG4gICAgICAgICAgICB2YXIgbGFiZWxzID0gW107XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwb3NpdGlvbnMsIGZ1bmN0aW9uIChwb3MsIGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3R5bGUgPSBpID09PSAwID8gX3RoaXMub3B0aW9ucy5sZWZ0U3R5bGUgOiBfdGhpcy5vcHRpb25zLnJpZ2h0U3R5bGU7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9yID0gX3RoaXMuZ2V0VGV4dENvbG9yKHNoYXBlLCBpKTtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2lubmVyJyAmJiBfdGhpcy5vcHRpb25zLmFkanVzdENvbG9yICYmIGNvbG9yICE9PSAnYmxhY2snKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlLnN0cm9rZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBmb3JtYXR0ZXIgPSBfdGhpcy5vcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IGZvcm1hdHRlciA/IGZvcm1hdHRlcih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCBzdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgeDogcG9zLngsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBwb3MueSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogdGV4dEFsaWduW2ldLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdsYWJlbCcsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbGFiZWxzLnB1c2gobGFiZWwpO1xuICAgICAgICAgICAgICAgIF90aGlzLmRvQW5pbWF0aW9uKGxhYmVsKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2hhcGUuc2V0KCdsYWJlbFNoYXBlcycsIGxhYmVscyk7XG4gICAgICAgICAgICBfdGhpcy5hZGp1c3RQb3NpdGlvbihsYWJlbHNbMF0sIGxhYmVsc1sxXSwgc2hhcGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBSYW5nZUJhckxhYmVsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0KCd2aXNpYmxlJywgdHJ1ZSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgfTtcbiAgICBSYW5nZUJhckxhYmVsLnByb3RvdHlwZS5nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXIuZ2V0QkJveCgpO1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuZ2V0U2hhcGVCYm94ID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBwb2ludHMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2hhcGUuZ2V0KCdvcmlnaW4nKS5wb2ludHMsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICBwb2ludHMucHVzaChfdGhpcy5jb29yZC5jb252ZXJ0UG9pbnQocCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGJib3ggPSBuZXcgYmJveF8xLmRlZmF1bHQocG9pbnRzWzBdLngsIHBvaW50c1sxXS55LCBNYXRoLmFicyhwb2ludHNbMl0ueCAtIHBvaW50c1swXS54KSwgTWF0aC5hYnMocG9pbnRzWzBdLnkgLSBwb2ludHNbMV0ueSkpO1xuICAgICAgICByZXR1cm4gYmJveDtcbiAgICB9O1xuICAgIFJhbmdlQmFyTGFiZWwucHJvdG90eXBlLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhlbWUgPSB0aGlzLnBsb3QudGhlbWU7XG4gICAgICAgIHZhciBsYWJlbFN0eWxlID0gdGhlbWUubGFiZWwuc3R5bGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ291dGVyJyxcbiAgICAgICAgICAgIG9mZnNldFg6IERFRkFVTFRfT0ZGU0VULFxuICAgICAgICAgICAgb2Zmc2V0WTogMCxcbiAgICAgICAgICAgIHN0eWxlOiB1dGlsXzEuY2xvbmUobGFiZWxTdHlsZSksXG4gICAgICAgICAgICBhZGp1c3RDb2xvcjogdHJ1ZSxcbiAgICAgICAgICAgIGFkanVzdFBvc2l0aW9uOiB0cnVlLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuZ2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldFNoYXBlQmJveChzaGFwZSk7XG4gICAgICAgIHZhciBtaW5YID0gYmJveC5taW5YLCBtYXhYID0gYmJveC5tYXhYLCBtaW5ZID0gYmJveC5taW5ZLCBoZWlnaHQgPSBiYm94LmhlaWdodDtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLCBvZmZzZXRYID0gX2Eub2Zmc2V0WCwgb2Zmc2V0WSA9IF9hLm9mZnNldFk7XG4gICAgICAgIHZhciB5ID0gbWluWSArIGhlaWdodCAvIDIgKyBvZmZzZXRZO1xuICAgICAgICB2YXIgeDEsIHgyO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBvc2l0aW9uID09PSAnb3V0ZXInKSB7XG4gICAgICAgICAgICB4MSA9IG1pblggLSBvZmZzZXRYO1xuICAgICAgICAgICAgeDIgPSBtYXhYICsgb2Zmc2V0WDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHgxID0gbWluWCArIG9mZnNldFg7XG4gICAgICAgICAgICB4MiA9IG1heFggLSBvZmZzZXRYO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB7IHg6IHgxLCB5OiB5IH0sXG4gICAgICAgICAgICB7IHg6IHgyLCB5OiB5IH0sXG4gICAgICAgIF07XG4gICAgfTtcbiAgICBSYW5nZUJhckxhYmVsLnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICB2YXIgeEZpZWxkID0gdGhpcy5wbG90Lm9wdGlvbnMueEZpZWxkO1xuICAgICAgICByZXR1cm4gc2hhcGUuZ2V0KCdvcmlnaW4nKS5kYXRhW3hGaWVsZF07XG4gICAgfTtcbiAgICBSYW5nZUJhckxhYmVsLnByb3RvdHlwZS5nZXRUZXh0QWxpZ24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICdvdXRlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBbJ3JpZ2h0JywgJ2xlZnQnXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbJ2xlZnQnLCAncmlnaHQnXTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuZ2V0VGV4dENvbG9yID0gZnVuY3Rpb24gKHNoYXBlLCBpbmRleCkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFkanVzdENvbG9yICYmIHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2lubmVyJykge1xuICAgICAgICAgICAgdmFyIHNoYXBlQ29sb3IgPSBzaGFwZS5hdHRyKCdmaWxsJyk7XG4gICAgICAgICAgICB2YXIgc2hhcGVPcGFjaXR5ID0gc2hhcGUuYXR0cignb3BhY2l0eScpID8gc2hhcGUuYXR0cignb3BhY2l0eScpIDogMTtcbiAgICAgICAgICAgIHZhciByZ2IgPSBjb2xvcl8xLnJnYjJhcnIoc2hhcGVDb2xvcik7XG4gICAgICAgICAgICB2YXIgZ3JheSA9IE1hdGgucm91bmQocmdiWzBdICogMC4yOTkgKyByZ2JbMV0gKiAwLjU4NyArIHJnYlsyXSAqIDAuMTE0KSAvIHNoYXBlT3BhY2l0eTtcbiAgICAgICAgICAgIHZhciBjb2xvckJhbmQgPSBbXG4gICAgICAgICAgICAgICAgeyBmcm9tOiAwLCB0bzogODUsIGNvbG9yOiAnd2hpdGUnIH0sXG4gICAgICAgICAgICAgICAgeyBmcm9tOiA4NSwgdG86IDE3MCwgY29sb3I6ICcjRjZGNkY2JyB9LFxuICAgICAgICAgICAgICAgIHsgZnJvbTogMTcwLCB0bzogMjU1LCBjb2xvcjogJ2JsYWNrJyB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHZhciByZWZsZWN0ID0gbWFwcGluZ0NvbG9yKGNvbG9yQmFuZCwgZ3JheSk7XG4gICAgICAgICAgICByZXR1cm4gcmVmbGVjdDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVmYXVsdENvbG9yID0gaW5kZXggPT09IDAgPyB0aGlzLm9wdGlvbnMubGVmdFN0eWxlLmZpbGwgOiB0aGlzLm9wdGlvbnMucmlnaHRTdHlsZS5maWxsO1xuICAgICAgICByZXR1cm4gZGVmYXVsdENvbG9yO1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuZG9BbmltYXRpb24gPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgaWYgKHRoaXMucGxvdC5hbmltYXRpb24gJiYgdGhpcy5wbG90LmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsYWJlbC5hdHRyKCdmaWxsT3BhY2l0eScsIDApO1xuICAgICAgICBsYWJlbC5hdHRyKCdzdHJva2VPcGFjaXR5JywgMCk7XG4gICAgICAgIGxhYmVsLnN0b3BBbmltYXRlKCk7XG4gICAgICAgIGxhYmVsLmFuaW1hdGUoe1xuICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDEsXG4gICAgICAgICAgICBzdHJva2VPcGFjaXR5OiAxLFxuICAgICAgICB9LCA4MDAsICdlYXNlTGluZWFyJywgNTAwKTtcbiAgICB9O1xuICAgIFJhbmdlQmFyTGFiZWwucHJvdG90eXBlLmFkanVzdFBvc2l0aW9uID0gZnVuY3Rpb24gKGxhLCBsYiwgc2hhcGUpIHtcbiAgICAgICAgdmFyIG9yaWdpbiA9IHNoYXBlLmdldCgnb3JpZ2luJyk7XG4gICAgICAgIHZhciBzaGFwZU1pblggPSBvcmlnaW4ueFswXTtcbiAgICAgICAgdmFyIHNoYXBlTWF4WCA9IG9yaWdpbi54WzFdO1xuICAgICAgICB2YXIgc2hhcGVXaWR0aCA9IE1hdGguYWJzKHNoYXBlTWF4WCAtIHNoYXBlTWluWCk7XG4gICAgICAgIHZhciBwYW5lbFJhbmdlID0gdGhpcy52aWV3LmNvb3JkaW5hdGVCQm94O1xuICAgICAgICB2YXIgYm94ZXMgPSBbbGEuZ2V0QkJveCgpLCBsYi5nZXRCQm94KCldO1xuICAgICAgICB2YXIgYXggPSBsYS5hdHRyKCd4Jyk7XG4gICAgICAgIHZhciBieCA9IGxiLmF0dHIoJ3gnKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hZGp1c3RQb3NpdGlvbiAmJiB0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICdpbm5lcicpIHtcbiAgICAgICAgICAgIHZhciB0b3RhbExlbmd0aCA9IGJveGVzWzBdLndpZHRoICsgYm94ZXNbMV0ud2lkdGg7XG4gICAgICAgICAgICB2YXIgaXNPdmVybGFwID0gYm94ZXNbMF0ubWF4WCAtIGJveGVzWzFdLm1pblggPiAyO1xuICAgICAgICAgICAgdmFyIGlzVG9vU2hvcnQgPSB0b3RhbExlbmd0aCA+IHNoYXBlV2lkdGg7XG4gICAgICAgICAgICBpZiAoaXNPdmVybGFwIHx8IGlzVG9vU2hvcnQpIHtcbiAgICAgICAgICAgICAgICBheCA9IHNoYXBlTWluWCAtIHRoaXMub3B0aW9ucy5vZmZzZXRYO1xuICAgICAgICAgICAgICAgIGxhLmF0dHIoJ2ZpbGwnLCB0aGlzLm9wdGlvbnMubGVmdFN0eWxlLmZpbGwpO1xuICAgICAgICAgICAgICAgIGxhLmF0dHIoJ3RleHRBbGlnbicsICdyaWdodCcpO1xuICAgICAgICAgICAgICAgIGJveGVzWzBdID0gbGEuZ2V0QkJveCgpO1xuICAgICAgICAgICAgICAgIGJ4ID0gc2hhcGVNYXhYICsgdGhpcy5vcHRpb25zLm9mZnNldFg7XG4gICAgICAgICAgICAgICAgbGIuYXR0cignZmlsbCcsIHRoaXMub3B0aW9ucy5yaWdodFN0eWxlLmZpbGwpO1xuICAgICAgICAgICAgICAgIGxiLmF0dHIoJ3RleHRBbGlnbicsICdsZWZ0Jyk7XG4gICAgICAgICAgICAgICAgYm94ZXNbMV0gPSBsYi5nZXRCQm94KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJveGVzWzBdLm1pblggPCBwYW5lbFJhbmdlLm1pblgpIHtcbiAgICAgICAgICAgIGF4ID0gcGFuZWxSYW5nZS5taW5YICsgREVGQVVMVF9PRkZTRVQ7XG4gICAgICAgICAgICBsYS5hdHRyKCd0ZXh0QWxpZ24nLCAnbGVmdCcpO1xuICAgICAgICB9XG4gICAgICAgIGxhLmF0dHIoJ3gnLCBheCk7XG4gICAgICAgIGxiLmF0dHIoJ3gnLCBieCk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYWJlbC5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmluZCh0aGlzLnZpZXcuZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb20pIHsgcmV0dXJuIGdlb20udHlwZSA9PT0gJ2ludGVydmFsJzsgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gUmFuZ2VCYXJMYWJlbDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSYW5nZUJhckxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFJhbmdlQmFyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJhbmdlQmFyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJhbmdlQmFyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFJhbmdlQmFyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAncmFuZ2VCYXInO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgUmFuZ2VCYXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFJhbmdlQmFyO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmFuZ2VCYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYmFyL2xheWVyXCIpKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50L2xhYmVsXCIpKTtcbnZhciBhbmltYXRpb25fMSA9IHJlcXVpcmUoXCIuL2FuaW1hdGlvblwiKTtcbnZhciBSYW5nZUJhckxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJhbmdlQmFyTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmFuZ2VCYXJMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAncmFuZ2VCYXInO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFJhbmdlQmFyTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peChfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnb3V0ZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlVGl0bGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogMTIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB5QXhpczoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZVRpdGxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LCB7fSk7XG4gICAgfTtcbiAgICBSYW5nZUJhckxheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJMYWJlbCgpO1xuICAgICAgICAvLyDkuLrmm7TmlrDliqjnlLvnvJPlrZhzaGFwZVxuICAgICAgICB2YXIgc2hhcGVDYWNoZXMgPSBbXTtcbiAgICAgICAgdmFyIGdlb21zID0gdGhpcy52aWV3Lmdlb21ldHJpZXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKGdlb21zLCBmdW5jdGlvbiAoZ2VvbSkge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRzID0gZ2VvbS5lbGVtZW50cztcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWxlKSB7XG4gICAgICAgICAgICAgICAgc2hhcGVDYWNoZXMucHVzaChlbGUuc2hhcGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBhbmltYXRpb25fMS5zZXRTaGFwZUNhY2hlKHNoYXBlQ2FjaGVzKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgUmFuZ2VCYXJMYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGFiZWwgJiYgdGhpcy5vcHRpb25zLmxhYmVsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IG5ldyBsYWJlbF8xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IHZpZXc6IHRoaXMudmlldywgcGxvdDogdGhpcyB9LCB0aGlzLm9wdGlvbnMubGFiZWwpKTtcbiAgICAgICAgICAgIGxhYmVsLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBSYW5nZUJhckxheWVyLnByb3RvdHlwZS5hbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYW5pbWF0aW9uLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICByZXR1cm4gUmFuZ2VCYXJMYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSYW5nZUJhckxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgncmFuZ2VCYXInLCBSYW5nZUJhckxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5zZXRTaGFwZUNhY2hlID0gdm9pZCAwO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi9kZXBlbmRlbnRzXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLy8g6K6w5b2V5LmL5YmN55qE54q25oCBXG52YXIgc2hhcGVDYWNoZTtcbmZ1bmN0aW9uIGNsaXBJbkZyb21DZW50ZXJWZXJ0aWNhbChzaGFwZSwgYW5pbWF0ZUNmZykge1xuICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgIHZhciBjZW50ZXJZID0gYmJveC5taW5ZICsgYmJveC5oZWlnaHQgLyAyO1xuICAgIHNoYXBlLnNldENsaXAoe1xuICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB4OiBiYm94Lm1pblgsXG4gICAgICAgICAgICB5OiBjZW50ZXJZLFxuICAgICAgICAgICAgd2lkdGg6IGJib3gud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IDAsXG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgdmFyIGNsaXBlciA9IHNoYXBlLmdldCgnY2xpcFNoYXBlJyk7XG4gICAgY2xpcGVyLmFuaW1hdGUoe1xuICAgICAgICBoZWlnaHQ6IGJib3guaGVpZ2h0LFxuICAgICAgICB5OiBiYm94Lm1pblksXG4gICAgfSwgYW5pbWF0ZUNmZy5kdXJhdGlvbiwgYW5pbWF0ZUNmZy5lYXNpbmcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2hhcGUuc2V0Q2xpcChudWxsKTtcbiAgICB9LCBhbmltYXRlQ2ZnLmRlbGF5KTtcbn1cbmNsaXBJbkZyb21DZW50ZXJWZXJ0aWNhbC5hbmltYXRpb25OYW1lID0gJ2NsaXBJbkZyb21DZW50ZXJWZXJ0aWNhbCc7XG5mdW5jdGlvbiBzZXRTaGFwZUNhY2hlKHNoYXBlcykge1xuICAgIHNoYXBlQ2FjaGUgPSBzaGFwZXM7XG59XG5leHBvcnRzLnNldFNoYXBlQ2FjaGUgPSBzZXRTaGFwZUNhY2hlO1xuZnVuY3Rpb24gdXBkYXRlRnJvbUNlbnRlclZlcnRpY2FsKHNoYXBlLCBhbmltYXRlQ2ZnKSB7XG4gICAgdmFyIGZyb21QYXRoID0gZ2V0U2hhcGVGcm9tQ2FjaGUoc2hhcGUpLmF0dHIoJ3BhdGgnKTtcbiAgICB2YXIgdG9QYXRoID0gdXRpbF8xLmNsb25lKHNoYXBlLmF0dHIoJ3BhdGgnKSk7XG4gICAgc2hhcGUuYXR0cigncGF0aCcsIGZyb21QYXRoKTtcbiAgICBzaGFwZS5hbmltYXRlKHtcbiAgICAgICAgcGF0aDogdG9QYXRoLFxuICAgIH0sIGFuaW1hdGVDZmcuZHVyYXRpb24sIGFuaW1hdGVDZmcuZWFzaW5nLCBhbmltYXRlQ2ZnLmNhbGxiYWNrLCAxMDApO1xufVxuZnVuY3Rpb24gZ2V0U2hhcGVGcm9tQ2FjaGUoc2hhcGUpIHtcbiAgICB2YXIgaWQgPSBzaGFwZS5pZDtcbiAgICB2YXIgdGFyZ2V0O1xuICAgIHV0aWxfMS5lYWNoKHNoYXBlQ2FjaGUsIGZ1bmN0aW9uIChzKSB7XG4gICAgICAgIGlmIChzLmlkID09PSBpZCkge1xuICAgICAgICAgICAgdGFyZ2V0ID0gcztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0YXJnZXQ7XG59XG51cGRhdGVGcm9tQ2VudGVyVmVydGljYWwuYW5pbWF0aW9uTmFtZSA9ICd1cGRhdGVGcm9tQ2VudGVyVmVydGljYWwnO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyQW5pbWF0aW9uKCdjbGlwSW5Gcm9tQ2VudGVyVmVydGljYWwnLCBjbGlwSW5Gcm9tQ2VudGVyVmVydGljYWwpO1xuZGVwZW5kZW50c18xLnJlZ2lzdGVyQW5pbWF0aW9uKCd1cGRhdGVGcm9tQ2VudGVyVmVydGljYWwnLCB1cGRhdGVGcm9tQ2VudGVyVmVydGljYWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5pbWF0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgY29sb3JfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL2NvbG9yXCIpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL2Jib3hcIikpO1xudmFyIERFRkFVTFRfT0ZGU0VUID0gODtcbmZ1bmN0aW9uIG1hcHBpbmdDb2xvcihiYW5kLCBncmF5KSB7XG4gICAgdmFyIHJlZmxlY3Q7XG4gICAgdXRpbF8xLmVhY2goYmFuZCwgZnVuY3Rpb24gKGIpIHtcbiAgICAgICAgdmFyIG1hcCA9IGI7XG4gICAgICAgIGlmIChncmF5ID49IG1hcC5mcm9tICYmIGdyYXkgPCBtYXAudG8pIHtcbiAgICAgICAgICAgIHJlZmxlY3QgPSBtYXAuY29sb3I7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVmbGVjdDtcbn1cbnZhciBSYW5nZUNvbHVtbkxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFJhbmdlQ29sdW1uTGFiZWwoY2ZnKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudmlldyA9IGNmZy52aWV3O1xuICAgICAgICB0aGlzLnBsb3QgPSBjZmcucGxvdDtcbiAgICAgICAgdmFyIGRlZmF1bHRPcHRpb25zID0gdGhpcy5nZXREZWZhdWx0T3B0aW9ucygpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB1dGlsXzEuZGVlcE1peChkZWZhdWx0T3B0aW9ucywgY2ZnLCB7fSk7XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLnRvcFN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMudG9wU3R5bGUgPSB0aGlzLm9wdGlvbnMuc3R5bGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuYm90dG9tU3R5bGUpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5ib3R0b21TdHlsZSA9IHRoaXMub3B0aW9ucy5zdHlsZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgUmFuZ2VDb2x1bW5MYWJlbC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLmdldEdlb21ldHJ5KCkubGFiZWxzQ29udGFpbmVyO1xuICAgICAgICB0aGlzLnZpZXcub24oJ2JlZm9yZXJlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmNsZWFyKCk7XG4gICAgICAgICAgICBfdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYWJlbC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldEdlb21ldHJ5KCksIGNvb3JkaW5hdGUgPSBfYS5jb29yZGluYXRlLCBlbGVtZW50cyA9IF9hLmVsZW1lbnRzO1xuICAgICAgICB0aGlzLmNvb3JkID0gY29vcmRpbmF0ZTtcbiAgICAgICAgdXRpbF8xLmVhY2goZWxlbWVudHMsIGZ1bmN0aW9uIChlbGUpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZSA9IGVsZS5zaGFwZTtcbiAgICAgICAgICAgIHZhciBwb3NpdGlvbnMgPSBfdGhpcy5nZXRQb3NpdGlvbihzaGFwZSk7XG4gICAgICAgICAgICB2YXIgdmFsdWVzID0gX3RoaXMuZ2V0VmFsdWUoc2hhcGUpO1xuICAgICAgICAgICAgdmFyIHRleHRCYWVsaW5lID0gX3RoaXMuZ2V0VGV4dEJhc2VsaW5lKCk7XG4gICAgICAgICAgICB2YXIgbGFiZWxzID0gW107XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChwb3NpdGlvbnMsIGZ1bmN0aW9uIChwb3MsIGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3R5bGUgPSBpID09PSAxID8gX3RoaXMub3B0aW9ucy50b3BTdHlsZSA6IF90aGlzLm9wdGlvbnMuYm90dG9tU3R5bGU7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9yID0gX3RoaXMuZ2V0VGV4dENvbG9yKHNoYXBlLCBpKTtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2lubmVyJyAmJiBfdGhpcy5vcHRpb25zLmFkanVzdENvbG9yICYmIGNvbG9yICE9PSAnYmxhY2snKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlLnN0cm9rZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBmb3JtYXR0ZXIgPSBfdGhpcy5vcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IGZvcm1hdHRlciA/IGZvcm1hdHRlcih2YWx1ZXNbaV0pIDogdmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IF90aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgndGV4dCcsIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCBzdHlsZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgeDogcG9zLngsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBwb3MueSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QmFzZWxpbmU6IHRleHRCYWVsaW5lW2ldLFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2xhYmVsJyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBsYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgICAgICAgICAgX3RoaXMuZG9BbmltYXRpb24obGFiZWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzaGFwZS5zZXQoJ2xhYmVsU2hhcGVzJywgbGFiZWxzKTtcbiAgICAgICAgICAgIF90aGlzLmFkanVzdFBvc2l0aW9uKGxhYmVsc1swXSwgbGFiZWxzWzFdLCBzaGFwZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIFJhbmdlQ29sdW1uTGFiZWwucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB9O1xuICAgIFJhbmdlQ29sdW1uTGFiZWwucHJvdG90eXBlLmdldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5nZXRCQm94KCk7XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRTaGFwZUJib3ggPSBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHBvaW50cyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChzaGFwZS5nZXQoJ29yaWdpbicpLnBvaW50cywgZnVuY3Rpb24gKHApIHtcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKF90aGlzLmNvb3JkLmNvbnZlcnRQb2ludChwKSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgYmJveCA9IG5ldyBiYm94XzEuZGVmYXVsdChwb2ludHNbMF0ueCwgcG9pbnRzWzFdLnksIE1hdGguYWJzKHBvaW50c1syXS54IC0gcG9pbnRzWzBdLngpLCBNYXRoLmFicyhwb2ludHNbMF0ueSAtIHBvaW50c1sxXS55KSk7XG4gICAgICAgIHJldHVybiBiYm94O1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYWJlbC5wcm90b3R5cGUuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aGVtZSA9IHRoaXMucGxvdC50aGVtZTtcbiAgICAgICAgdmFyIGxhYmVsU3R5bGUgPSB0aGVtZS5sYWJlbC5zdHlsZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnb3V0ZXInLFxuICAgICAgICAgICAgb2Zmc2V0WDogMCxcbiAgICAgICAgICAgIG9mZnNldFk6IERFRkFVTFRfT0ZGU0VULFxuICAgICAgICAgICAgc3R5bGU6IHV0aWxfMS5jbG9uZShsYWJlbFN0eWxlKSxcbiAgICAgICAgICAgIGFkanVzdENvbG9yOiB0cnVlLFxuICAgICAgICAgICAgYWRqdXN0UG9zaXRpb246IHRydWUsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICB2YXIgYmJveCA9IHRoaXMuZ2V0U2hhcGVCYm94KHNoYXBlKTtcbiAgICAgICAgdmFyIG1pblggPSBiYm94Lm1pblgsIG1pblkgPSBiYm94Lm1pblksIG1heFkgPSBiYm94Lm1heFksIHdpZHRoID0gYmJveC53aWR0aDtcbiAgICAgICAgdmFyIG9mZnNldFkgPSB0aGlzLm9wdGlvbnMub2Zmc2V0WTtcbiAgICAgICAgdmFyIHggPSBtaW5YICsgd2lkdGggLyAyO1xuICAgICAgICB2YXIgeTEsIHkyO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBvc2l0aW9uID09PSAnb3V0ZXInKSB7XG4gICAgICAgICAgICB5MSA9IG1pblkgLSBvZmZzZXRZO1xuICAgICAgICAgICAgeTIgPSBtYXhZICsgb2Zmc2V0WTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHkxID0gbWluWSArIG9mZnNldFk7XG4gICAgICAgICAgICB5MiA9IG1heFkgLSBvZmZzZXRZO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB7IHg6IHgsIHk6IHkyIH0sXG4gICAgICAgICAgICB7IHg6IHgsIHk6IHkxIH0sXG4gICAgICAgIF07XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uIChzaGFwZSkge1xuICAgICAgICB2YXIgeUZpZWxkID0gdGhpcy5wbG90Lm9wdGlvbnMueUZpZWxkO1xuICAgICAgICByZXR1cm4gc2hhcGUuZ2V0KCdvcmlnaW4nKS5kYXRhW3lGaWVsZF07XG4gICAgfTtcbiAgICBSYW5nZUNvbHVtbkxhYmVsLnByb3RvdHlwZS5nZXRUZXh0QmFzZWxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICdvdXRlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBbJ3RvcCcsICdib3R0b20nXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbJ2JvdHRvbScsICd0b3AnXTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYWJlbC5wcm90b3R5cGUuZ2V0VGV4dENvbG9yID0gZnVuY3Rpb24gKHNoYXBlLCBpbmRleCkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFkanVzdENvbG9yICYmIHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2lubmVyJykge1xuICAgICAgICAgICAgdmFyIHNoYXBlQ29sb3IgPSBzaGFwZS5hdHRyKCdmaWxsJyk7XG4gICAgICAgICAgICB2YXIgc2hhcGVPcGFjaXR5ID0gc2hhcGUuYXR0cignb3BhY2l0eScpID8gc2hhcGUuYXR0cignb3BhY2l0eScpIDogMTtcbiAgICAgICAgICAgIHZhciByZ2IgPSBjb2xvcl8xLnJnYjJhcnIoc2hhcGVDb2xvcik7XG4gICAgICAgICAgICB2YXIgZ3JheSA9IE1hdGgucm91bmQocmdiWzBdICogMC4yOTkgKyByZ2JbMV0gKiAwLjU4NyArIHJnYlsyXSAqIDAuMTE0KSAvIHNoYXBlT3BhY2l0eTtcbiAgICAgICAgICAgIHZhciBjb2xvckJhbmQgPSBbXG4gICAgICAgICAgICAgICAgeyBmcm9tOiAwLCB0bzogODUsIGNvbG9yOiAnd2hpdGUnIH0sXG4gICAgICAgICAgICAgICAgeyBmcm9tOiA4NSwgdG86IDE3MCwgY29sb3I6ICcjRjZGNkY2JyB9LFxuICAgICAgICAgICAgICAgIHsgZnJvbTogMTcwLCB0bzogMjU1LCBjb2xvcjogJ2JsYWNrJyB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHZhciByZWZsZWN0ID0gbWFwcGluZ0NvbG9yKGNvbG9yQmFuZCwgZ3JheSk7XG4gICAgICAgICAgICByZXR1cm4gcmVmbGVjdDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVmYXVsdENvbG9yID0gaW5kZXggPT09IDEgPyB0aGlzLm9wdGlvbnMudG9wU3R5bGUuZmlsbCA6IHRoaXMub3B0aW9ucy5ib3R0b21TdHlsZS5maWxsO1xuICAgICAgICByZXR1cm4gZGVmYXVsdENvbG9yO1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYWJlbC5wcm90b3R5cGUuZG9BbmltYXRpb24gPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgaWYgKHRoaXMucGxvdC5hbmltYXRpb24gJiYgdGhpcy5wbG90LmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsYWJlbC5hdHRyKCdmaWxsT3BhY2l0eScsIDApO1xuICAgICAgICBsYWJlbC5hdHRyKCdzdHJva2VPcGFjaXR5JywgMCk7XG4gICAgICAgIGxhYmVsLnN0b3BBbmltYXRlKCk7XG4gICAgICAgIGxhYmVsLmFuaW1hdGUoe1xuICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDEsXG4gICAgICAgICAgICBzdHJva2VPcGFjaXR5OiAxLFxuICAgICAgICB9LCA4MDAsICdlYXNlTGluZWFyJywgNTAwKTtcbiAgICB9O1xuICAgIFJhbmdlQ29sdW1uTGFiZWwucHJvdG90eXBlLmFkanVzdFBvc2l0aW9uID0gZnVuY3Rpb24gKGxhLCBsYiwgc2hhcGUpIHtcbiAgICAgICAgdmFyIG9yaWdpbiA9IHNoYXBlLmdldCgnb3JpZ2luJyk7XG4gICAgICAgIHZhciBzaGFwZU1pblkgPSBvcmlnaW4ueVsxXTtcbiAgICAgICAgdmFyIHNoYXBlTWF4WSA9IG9yaWdpbi55WzBdO1xuICAgICAgICB2YXIgYmJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdmFyIGhlaWdodCA9IGJib3guaGVpZ2h0O1xuICAgICAgICB2YXIgc2hhcGVIZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHZhciBwYW5lbFJhbmdlID0gdGhpcy52aWV3LmNvb3JkaW5hdGVCQm94O1xuICAgICAgICB2YXIgYm94ZXMgPSBbbGEuZ2V0QkJveCgpLCBsYi5nZXRCQm94KCldO1xuICAgICAgICB2YXIgYXkgPSBsYS5hdHRyKCd5Jyk7XG4gICAgICAgIHZhciBieSA9IGxiLmF0dHIoJ3knKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hZGp1c3RQb3NpdGlvbiAmJiB0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICdpbm5lcicpIHtcbiAgICAgICAgICAgIHZhciB0b3RhbExlbmd0aCA9IGJveGVzWzBdLmhlaWdodCArIGJveGVzWzFdLmhlaWdodDtcbiAgICAgICAgICAgIHZhciBpc092ZXJsYXAgPSBib3hlc1sxXS5tYXhZIC0gYm94ZXNbMF0ubWluWSA+IDI7XG4gICAgICAgICAgICB2YXIgaXNUb29TaG9ydCA9IHRvdGFsTGVuZ3RoID4gc2hhcGVIZWlnaHQ7XG4gICAgICAgICAgICBpZiAoaXNPdmVybGFwIHx8IGlzVG9vU2hvcnQpIHtcbiAgICAgICAgICAgICAgICBieSA9IHNoYXBlTWluWSAtIHRoaXMub3B0aW9ucy5vZmZzZXRZO1xuICAgICAgICAgICAgICAgIGxiLmF0dHIoJ2ZpbGwnLCB0aGlzLm9wdGlvbnMudG9wU3R5bGUuZmlsbCk7XG4gICAgICAgICAgICAgICAgbGIuYXR0cigndGV4dEJhc2VsaW5lJywgJ2JvdHRvbScpO1xuICAgICAgICAgICAgICAgIGF5ID0gc2hhcGVNYXhZICsgdGhpcy5vcHRpb25zLm9mZnNldFk7XG4gICAgICAgICAgICAgICAgbGEuYXR0cignZmlsbCcsIHRoaXMub3B0aW9ucy5ib3R0b21TdHlsZS5maWxsKTtcbiAgICAgICAgICAgICAgICBsYS5hdHRyKCd0ZXh0QmFzZWxpbmUnLCAndG9wJyk7XG4gICAgICAgICAgICAgICAgYm94ZXNbMF0gPSBsYS5nZXRCQm94KCk7XG4gICAgICAgICAgICAgICAgYm94ZXNbMV0gPSBsYi5nZXRCQm94KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZml4bWU6IHRleHRCYXNlbGluZSDlj5bkuI3lh4ZiYm94XG4gICAgICAgIGlmIChib3hlc1swXS5tYXhZID4gcGFuZWxSYW5nZS5tYXhZIC0gREVGQVVMVF9PRkZTRVQpIHtcbiAgICAgICAgICAgIGF5ID0gcGFuZWxSYW5nZS5tYXhZIC0gREVGQVVMVF9PRkZTRVQgLyAyO1xuICAgICAgICAgICAgbGEuYXR0cigndGV4dEJhc2VsaW5lJywgJ2JvdHRvbScpO1xuICAgICAgICB9XG4gICAgICAgIGxhLmF0dHIoJ3knLCBheSk7XG4gICAgICAgIGxiLmF0dHIoJ3knLCBieSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYWJlbC5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZmluZCh0aGlzLnZpZXcuZ2VvbWV0cmllcywgZnVuY3Rpb24gKGdlb20pIHsgcmV0dXJuIGdlb20udHlwZSA9PT0gJ2ludGVydmFsJzsgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gUmFuZ2VDb2x1bW5MYWJlbDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSYW5nZUNvbHVtbkxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFJhbmdlQ29sdW1uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJhbmdlQ29sdW1uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJhbmdlQ29sdW1uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFJhbmdlQ29sdW1uLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAncmFuZ2VDb2x1bW4nO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW4uZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFJhbmdlQ29sdW1uO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmFuZ2VDb2x1bW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vY29sdW1uL2xheWVyXCIpKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50L2xhYmVsXCIpKTtcbnZhciBhbmltYXRpb25fMSA9IHJlcXVpcmUoXCIuL2FuaW1hdGlvblwiKTtcbnZhciBSYW5nZUNvbHVtbkxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJhbmdlQ29sdW1uTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUmFuZ2VDb2x1bW5MYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAncmFuZ2VDb2x1bW4nO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFJhbmdlQ29sdW1uTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peChfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnb3V0ZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSwge30pO1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyTGFiZWwoKTtcbiAgICAgICAgLy8g5Li65pu05paw5Yqo55S757yT5a2Yc2hhcGVcbiAgICAgICAgdmFyIHNoYXBlQ2FjaGVzID0gW107XG4gICAgICAgIHZhciBnZW9tcyA9IHRoaXMudmlldy5nZW9tZXRyaWVzO1xuICAgICAgICB1dGlsXzEuZWFjaChnZW9tcywgZnVuY3Rpb24gKGdlb20pIHtcbiAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IGdlb20uZWxlbWVudHM7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChlbGVtZW50cywgZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgICAgIHNoYXBlQ2FjaGVzLnB1c2goZWxlLnNoYXBlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgYW5pbWF0aW9uXzEuc2V0U2hhcGVDYWNoZShzaGFwZUNhY2hlcyk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIFJhbmdlQ29sdW1uTGF5ZXIucHJvdG90eXBlLmFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hbmltYXRpb24uY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5jb2x1bW4uYW5pbWF0ZSA9IHtcbiAgICAgICAgICAgIGFwcGVhcjoge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbjogJ2NsaXBJbkZyb21DZW50ZXJWZXJ0aWNhbCcsXG4gICAgICAgICAgICAgICAgZHVyYXRpb246IDYwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB1cGRhdGU6IHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb246ICd1cGRhdGVGcm9tQ2VudGVyVmVydGljYWwnLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiA2MDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH07XG4gICAgUmFuZ2VDb2x1bW5MYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGFiZWwgJiYgdGhpcy5vcHRpb25zLmxhYmVsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IG5ldyBsYWJlbF8xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IHZpZXc6IHRoaXMudmlldywgcGxvdDogdGhpcyB9LCB0aGlzLm9wdGlvbnMubGFiZWwpKTtcbiAgICAgICAgICAgIGxhYmVsLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gUmFuZ2VDb2x1bW5MYXllcjtcbn0obGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSYW5nZUNvbHVtbkxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgncmFuZ2VDb2x1bW4nLCBSYW5nZUNvbHVtbkxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5vbkV2ZW50ID0gZXhwb3J0cy5FVkVOVF9NQVAgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZXZlbnRfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL2V2ZW50XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRVZFTlRfTUFQXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLkVWRU5UX01BUDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9uRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEub25FdmVudDsgfSB9KTtcbnZhciBjb21wb25lbnRNYXAgPSB7XG4gICAgcm9zZTogJ2ludGVydmFsJyxcbn07XG52YXIgU0hBUEVfRVZFTlRfTUFQID0gZXZlbnRfMS5nZXRFdmVudE1hcChjb21wb25lbnRNYXApO1xudXRpbF8xLmFzc2lnbihldmVudF8xLkVWRU5UX01BUCwgU0hBUEVfRVZFTlRfTUFQKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKipcbiAqIENyZWF0ZSBCeSBCcnVjZSBUb29cbiAqIE9uIDIwMjAtMDItMTdcbiAqL1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG4vLyBUT0RPIGxhYmVs55qE5LyY5YyW77yM5Y+v6IO96KaB6YeN5paw5Y+C6ICDIGh0dHBzOi8vZ2l0aHViLmNvbS9hbnR2aXMvRzJQbG90L2Jsb2IvbWFzdGVyL3NyYy9wbG90cy9yb3NlL2NvbXBvbmVudC9sYWJlbC9yb3NlLWxhYmVsLnRzXG52YXIgUm9zZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhSb3NlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJvc2UoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUm9zZS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3Jvc2UnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgUm9zZS5wcm90b3R5cGUuZ2V0UmFkaXVzU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0UmFkaXVzU2NhbGUoKTtcbiAgICB9O1xuICAgIFJvc2UucHJvdG90eXBlLmdldEFuZ2xlU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0QW5nbGVTY2FsZSgpO1xuICAgIH07XG4gICAgUm9zZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gUm9zZTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFJvc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE3XG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9mYWN0b3J5XCIpO1xudmFyIGZhY3RvcnlfMiA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIEcyX0dFT01fTUFQID0ge1xuICAgIHJvc2U6ICdpbnRlcnZhbCcsXG59O1xudmFyIFBMT1RfR0VPTV9NQVAgPSB7XG4gICAgcm9zZTogJ2NvbHVtbicsXG59O1xudmFyIFJvc2VMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhSb3NlTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUm9zZUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdyb3NlJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBSb3NlTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHdpZHRoOiA0MDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDQwMCxcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmb3JjZUZpdDogdHJ1ZSxcbiAgICAgICAgICAgIHBhZGRpbmc6ICdhdXRvJyxcbiAgICAgICAgICAgIHJhZGl1czogMC44LFxuICAgICAgICAgICAgaW5uZXJSYWRpdXM6IDAsXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdHlwZTogJ2lubmVyJyxcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGFkanVzdENvbG9yOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAncmlnaHQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNoYXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dNYXJrZXJzOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2x1bW5TdHlsZToge1xuICAgICAgICAgICAgICAgIHN0cm9rZTogJ3doaXRlJyxcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeEF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFsaWduVGljazogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDAuNSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogNSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFJvc2VMYXllci5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IF9zdXBlci5wcm90b3R5cGUuZ2V0T3B0aW9ucy5jYWxsKHRoaXMsIHByb3BzKTtcbiAgICAgICAgdmFyIGNvbHVtblN0eWxlID0gcHJvcHMuc2VjdG9yU3R5bGU7XG4gICAgICAgIHZhciB4RmllbGQgPSBwcm9wcy5jYXRlZ29yeUZpZWxkO1xuICAgICAgICB2YXIgeUZpZWxkID0gcHJvcHMucmFkaXVzRmllbGQ7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgb3B0aW9ucywgeyBjb2x1bW5TdHlsZTogY29sdW1uU3R5bGUsIHhGaWVsZDogeEZpZWxkLCB5RmllbGQ6IHlGaWVsZCB9KTtcbiAgICB9O1xuICAgIFJvc2VMYXllci5wcm90b3R5cGUuZ2V0UmFkaXVzU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByYWRpdXNGaWVsZCA9IHRoaXMub3B0aW9ucy5yYWRpdXNGaWVsZDtcbiAgICAgICAgaWYgKHJhZGl1c0ZpZWxkKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKHJhZGl1c0ZpZWxkKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5nZXRBbmdsZVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2F0ZWdvcnlGaWVsZCA9IHRoaXMub3B0aW9ucy5jYXRlZ29yeUZpZWxkO1xuICAgICAgICBpZiAoY2F0ZWdvcnlGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZChjYXRlZ29yeUZpZWxkKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgaWYgKGRpbSA9PT0gJ2cyJykge1xuICAgICAgICAgICAgcmV0dXJuIEcyX0dFT01fTUFQW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQTE9UX0dFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gc3VwZXIuc2NhbGUoKTtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgc2NhbGVzID0ge307XG4gICAgICAgIHNjYWxlc1twcm9wcy5yYWRpdXNGaWVsZF0gPSB7fTtcbiAgICAgICAgc2NhbGVzW3Byb3BzLmNhdGVnb3J5RmllbGRdID0geyB0eXBlOiAnY2F0JyB9O1xuICAgICAgICB0aGlzLnNldENvbmZpZygnc2NhbGVzJywgc2NhbGVzKTtcbiAgICB9O1xuICAgIC8qKiDkuI3mmL7npLrlnZDmoIfovbQgKi9cbiAgICAvKnByb3RlY3RlZCBheGlzKCkge1xuICAgICAgc3VwZXIuYXhpcygpO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgIGlmICghb3B0aW9ucy5zdGFja0ZpZWxkICYmICFvcHRpb25zLmdyb3VwRmllbGQpIHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2F4ZXMnLCBmYWxzZSk7XG4gICAgICB9XG4gICAgfSovXG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgY29vcmRDb25maWcgPSB7XG4gICAgICAgICAgICB0eXBlOiAncG9sYXInLFxuICAgICAgICAgICAgY2ZnOiB7XG4gICAgICAgICAgICAgICAgcmFkaXVzOiBwcm9wcy5yYWRpdXMsXG4gICAgICAgICAgICAgICAgaW5uZXJSYWRpdXM6IHByb3BzLmlubmVyUmFkaXVzIHx8IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldENvbmZpZygnY29vcmRpbmF0ZScsIGNvb3JkQ29uZmlnKTtcbiAgICB9O1xuICAgIFJvc2VMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgcm9zZSA9IGZhY3RvcnlfMi5nZXRHZW9tKCdpbnRlcnZhbCcsICdtYWluJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgICAgIHBvc2l0aW9uRmllbGRzOiBbb3B0aW9ucy5jYXRlZ29yeUZpZWxkLCBvcHRpb25zLnJhZGl1c0ZpZWxkXSxcbiAgICAgICAgICAgIHdpZHRoUmF0aW86IHtcbiAgICAgICAgICAgICAgICByb3NlOiAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJvc2UubGFiZWwgPSB0aGlzLmV4dHJhY3RMYWJlbCgpO1xuICAgICAgICByb3NlLmFkanVzdCA9IHRoaXMuYWRqdXN0Um9zZUFkanVzdCgpO1xuICAgICAgICB0aGlzLnJvc2UgPSByb3NlO1xuICAgICAgICBpZiAob3B0aW9ucy50b29sdGlwICYmIChvcHRpb25zLnRvb2x0aXAuZmllbGRzIHx8IG9wdGlvbnMudG9vbHRpcC5mb3JtYXR0ZXIpKSB7XG4gICAgICAgICAgICB0aGlzLmdlb21ldHJ5VG9vbHRpcCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIHJvc2UpO1xuICAgIH07XG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5hZGp1c3RSb3NlQWRqdXN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBSb3NlTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yb3NlLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIHRoaXMucm9zZS50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLnJvc2UudG9vbHRpcC5jYWxsYmFjayA9IHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgIGlmICghdG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yb3NlLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy5yYWRpdXNGaWVsZCwgdGhpcy5vcHRpb25zLmNhdGVnb3J5RmllbGQsIHRoaXMub3B0aW9ucy5jb2xvckZpZWxkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5hbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYW5pbWF0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHByb3BzLmFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8qKiDlhbPpl63liqjnlLsgKi9cbiAgICAgICAgICAgIHRoaXMucm9zZS5hbmltYXRlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJvc2VMYXllci5wcm90b3R5cGUuYW5ub3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgUm9zZUxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIFJvc2VMYXllci5wcm90b3R5cGUuZXh0cmFjdExhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKCFvcHRpb25zLmxhYmVsIHx8ICFvcHRpb25zLmxhYmVsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFiZWwgPSB1dGlsXzEuZGVlcE1peCh7fSwgb3B0aW9ucy5sYWJlbCk7XG4gICAgICAgIHRoaXMuYWRqdXN0TGFiZWxPcHRpb25zKGxhYmVsKTtcbiAgICAgICAgdmFyIGZpZWxkcyA9IFtvcHRpb25zLmNhdGVnb3J5RmllbGQsIG9wdGlvbnMucmFkaXVzRmllbGRdO1xuICAgICAgICB2YXIgbGFiZWxDb25maWcgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdsYWJlbCcsIHRzbGliXzEuX19hc3NpZ24oeyBwbG90OiB0aGlzLCBsYWJlbFR5cGU6ICdwb2xhcicsIGZpZWxkczogZmllbGRzIH0sIGxhYmVsKSk7XG4gICAgICAgIHJldHVybiBsYWJlbENvbmZpZztcbiAgICB9O1xuICAgIFJvc2VMYXllci5wcm90b3R5cGUuYWRqdXN0TGFiZWxPcHRpb25zID0gZnVuY3Rpb24gKGxhYmVsT3B0aW9ucykge1xuICAgICAgICB2YXIgcmFkaXVzRmllbGQgPSB0aGlzLm9wdGlvbnMucmFkaXVzRmllbGQ7XG4gICAgICAgIGlmIChsYWJlbE9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSBsYWJlbE9wdGlvbnMub2Zmc2V0LCB0eXBlID0gbGFiZWxPcHRpb25zLnR5cGUsIGNvbnRlbnQgPSBsYWJlbE9wdGlvbnMuY29udGVudDtcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnaW5uZXInKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxPcHRpb25zLm9mZnNldCA9IG9mZnNldCA8IDAgPyBvZmZzZXQgOiAtMTA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlID09PSAnb3V0ZXInKSB7XG4gICAgICAgICAgICAgICAgbGFiZWxPcHRpb25zLm9mZnNldCA9IG9mZnNldCA+PSAwID8gb2Zmc2V0IDogMTA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICAvLyDpu5jorqTmmL7npLog5pWw5YC8XG4gICAgICAgICAgICAgICAgbGFiZWxPcHRpb25zLmNvbnRlbnQgPSBmdW5jdGlvbiAodGV4dCwgaXRlbSkgeyByZXR1cm4gXCJcIiArIGl0ZW0uX29yaWdpbltyYWRpdXNGaWVsZF07IH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBSb3NlTGF5ZXI7XG59KHZpZXdfbGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSb3NlTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdyb3NlJywgUm9zZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmJveF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvYmJveFwiKSk7XG52YXIgUXVhZHJhbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUXVhZHJhbnQoY2ZnKSB7XG4gICAgICAgIHRoaXMucXVhZHJhbnRHcm91cHMgPSBbXTtcbiAgICAgICAgdGhpcy5yZWdpb25EYXRhID0gW107XG4gICAgICAgIHRoaXMubGluZURhdGEgPSBbXTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gY2ZnO1xuICAgICAgICB0aGlzLnZpZXcgPSB0aGlzLm9wdGlvbnMudmlldztcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIFF1YWRyYW50LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHhCYXNlbGluZSA9IF9hLnhCYXNlbGluZSwgeUJhc2VsaW5lID0gX2EueUJhc2VsaW5lO1xuICAgICAgICB2YXIgY29vcmQgPSB0aGlzLnZpZXcuZ2V0Q29vcmRpbmF0ZSgpO1xuICAgICAgICAvLyBUT0RPOiB4QmFzZWxpbmXlkox5QmFzZWxpbmXmlK/mjIHnmb7liIbmr5RcbiAgICAgICAgLy8g5qC55o2uIHhCYXNlbGluZSDlkowgeUJhc2VsaW5lIOWIhuWJsuixoemZkFxuICAgICAgICB2YXIgeFNjYWxlID0gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZCh0aGlzLm9wdGlvbnMucGxvdE9wdGlvbnMueEZpZWxkKTtcbiAgICAgICAgdmFyIHlTY2FsZSA9IHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQodGhpcy5vcHRpb25zLnBsb3RPcHRpb25zLnlGaWVsZCk7XG4gICAgICAgIC8vIOWFiOi/m+ihjCB4IOaWueWQkeeahOWIhuWJslxuICAgICAgICB2YXIgeFJlZ2lvbjtcbiAgICAgICAgaWYgKHhCYXNlbGluZSA+IHhTY2FsZS5taW4gJiYgeEJhc2VsaW5lIDwgeFNjYWxlLm1heCkge1xuICAgICAgICAgICAgdmFyIHJhdGlvID0gKHhCYXNlbGluZSAtIHhTY2FsZS5taW4pIC8gKHhTY2FsZS5tYXggLSB4U2NhbGUubWluKTtcbiAgICAgICAgICAgIHhSZWdpb24gPSBbXG4gICAgICAgICAgICAgICAgbmV3IGJib3hfMS5kZWZhdWx0KGNvb3JkLnN0YXJ0LngsIGNvb3JkLmVuZC55LCBjb29yZC5nZXRXaWR0aCgpICogcmF0aW8sIGNvb3JkLmdldEhlaWdodCgpKSxcbiAgICAgICAgICAgICAgICBuZXcgYmJveF8xLmRlZmF1bHQoY29vcmQuc3RhcnQueCArIGNvb3JkLmdldFdpZHRoKCkgKiByYXRpbywgY29vcmQuZW5kLnksIGNvb3JkLmdldFdpZHRoKCkgKiAoMSAtIHJhdGlvKSwgY29vcmQuZ2V0SGVpZ2h0KCkpLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHZhciB2ZXJ0aWNhbExpbmVEYXRhID0ge1xuICAgICAgICAgICAgICAgIHN0YXJ0OiB7IHg6IGNvb3JkLnN0YXJ0LnggKyBjb29yZC5nZXRXaWR0aCgpICogcmF0aW8sIHk6IGNvb3JkLmVuZC55IH0sXG4gICAgICAgICAgICAgICAgZW5kOiB7IHg6IGNvb3JkLnN0YXJ0LnggKyBjb29yZC5nZXRXaWR0aCgpICogcmF0aW8sIHk6IGNvb3JkLnN0YXJ0LnkgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmxpbmVEYXRhLnB1c2godmVydGljYWxMaW5lRGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB4UmVnaW9uID0gW25ldyBiYm94XzEuZGVmYXVsdChjb29yZC5zdGFydC54LCBjb29yZC5lbmQueSwgY29vcmQuZ2V0V2lkdGgoKSwgY29vcmQuZ2V0SGVpZ2h0KCkpXTtcbiAgICAgICAgfVxuICAgICAgICAvLyDlho3ov5vooYwgeSDmlrnlkJHnmoTliIblibJcbiAgICAgICAgaWYgKHlCYXNlbGluZSA+IHlTY2FsZS5taW4gJiYgeUJhc2VsaW5lIDwgeVNjYWxlLm1heCkge1xuICAgICAgICAgICAgdmFyIHJhdGlvID0gKHlCYXNlbGluZSAtIHlTY2FsZS5taW4pIC8gKHlTY2FsZS5tYXggLSB5U2NhbGUubWluKTtcbiAgICAgICAgICAgIHZhciBob3Jpem9udGFsTGluZURhdGEgPSB7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IHsgeDogY29vcmQuc3RhcnQueCwgeTogY29vcmQuc3RhcnQueSAtIGNvb3JkLmdldEhlaWdodCgpICogcmF0aW8gfSxcbiAgICAgICAgICAgICAgICBlbmQ6IHsgeDogY29vcmQuZW5kLngsIHk6IGNvb3JkLnN0YXJ0LnkgLSBjb29yZC5nZXRIZWlnaHQoKSAqIHJhdGlvIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5saW5lRGF0YS5wdXNoKGhvcml6b250YWxMaW5lRGF0YSk7XG4gICAgICAgICAgICB2YXIgdG9wUXVhZHJhbnQgPSB7XG4gICAgICAgICAgICAgICAgbmFtZTogeEJhc2VsaW5lIDw9IHhTY2FsZS5taW4gPyAndG9wLXJpZ2h0JyA6ICd0b3AtbGVmdCcsXG4gICAgICAgICAgICAgICAgYmJveDogbmV3IGJib3hfMS5kZWZhdWx0KHhSZWdpb25bMF0ubWluWCwgeFJlZ2lvblswXS5taW5ZLCB4UmVnaW9uWzBdLndpZHRoLCB4UmVnaW9uWzBdLmhlaWdodCAqICgxIC0gcmF0aW8pKSxcbiAgICAgICAgICAgICAgICBpbmRleDogeEJhc2VsaW5lIDw9IHhTY2FsZS5taW4gPyAyIDogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnJlZ2lvbkRhdGEucHVzaCh0b3BRdWFkcmFudCk7XG4gICAgICAgICAgICB2YXIgYm90dG9tUXVhZHJhbnQgPSB7XG4gICAgICAgICAgICAgICAgbmFtZTogeEJhc2VsaW5lIDw9IHhTY2FsZS5taW4gPyAnYm90dG9tLXJpZ2h0JyA6ICdib3R0b20tbGVmdCcsXG4gICAgICAgICAgICAgICAgYmJveDogbmV3IGJib3hfMS5kZWZhdWx0KHhSZWdpb25bMF0ubWluWCwgeFJlZ2lvblswXS5taW5ZICsgeFJlZ2lvblswXS5oZWlnaHQgKiAoMSAtIHJhdGlvKSwgeFJlZ2lvblswXS53aWR0aCwgeFJlZ2lvblswXS5oZWlnaHQgKiByYXRpbyksXG4gICAgICAgICAgICAgICAgaW5kZXg6IHhCYXNlbGluZSA8PSB4U2NhbGUubWluID8gMyA6IDEsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5yZWdpb25EYXRhLnB1c2goYm90dG9tUXVhZHJhbnQpO1xuICAgICAgICAgICAgLy8g5Zub6LGh6ZmQ6b2Q5YWoXG4gICAgICAgICAgICBpZiAoeFJlZ2lvbi5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJpZ2h0VG9wUXVhZHJhbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0b3AtcmlnaHQnLFxuICAgICAgICAgICAgICAgICAgICBiYm94OiBuZXcgYmJveF8xLmRlZmF1bHQoeFJlZ2lvblsxXS5taW5YLCB4UmVnaW9uWzFdLm1pblksIHhSZWdpb25bMV0ud2lkdGgsIHhSZWdpb25bMV0uaGVpZ2h0ICogKDEgLSByYXRpbykpLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogMixcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMucmVnaW9uRGF0YS5wdXNoKHJpZ2h0VG9wUXVhZHJhbnQpO1xuICAgICAgICAgICAgICAgIHZhciByaWdodEJvdHRvbVF1YWRyYW50ID0ge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnYm90dG9tLXJpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgYmJveDogbmV3IGJib3hfMS5kZWZhdWx0KHhSZWdpb25bMV0ubWluWCwgeFJlZ2lvblsxXS5taW5ZICsgeFJlZ2lvblsxXS5oZWlnaHQgKiAoMSAtIHJhdGlvKSwgeFJlZ2lvblsxXS53aWR0aCwgeFJlZ2lvblsxXS5oZWlnaHQgKiByYXRpbyksXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiAzLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5yZWdpb25EYXRhLnB1c2gocmlnaHRCb3R0b21RdWFkcmFudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoeFJlZ2lvbi5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGlmICh5QmFzZWxpbmUgPD0geVNjYWxlLm1pbikge1xuICAgICAgICAgICAgICAgIHZhciBsZWZ0VG9wUXVhZHJhbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0b3AtbGVmdCcsXG4gICAgICAgICAgICAgICAgICAgIGJib3g6IHhSZWdpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5yZWdpb25EYXRhLnB1c2gobGVmdFRvcFF1YWRyYW50KTtcbiAgICAgICAgICAgICAgICB2YXIgcmlnaHRUb3BRdWFkcmFudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3RvcC1yaWdodCcsXG4gICAgICAgICAgICAgICAgICAgIGJib3g6IHhSZWdpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiAyLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5yZWdpb25EYXRhLnB1c2gocmlnaHRUb3BRdWFkcmFudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgbGVmdEJvdHRvbVF1YWRyYW50ID0ge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnYm90dG9tLWxlZnQnLFxuICAgICAgICAgICAgICAgICAgICBiYm94OiB4UmVnaW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogMSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMucmVnaW9uRGF0YS5wdXNoKGxlZnRCb3R0b21RdWFkcmFudCk7XG4gICAgICAgICAgICAgICAgdmFyIHJpZ2h0Qm90dG9tUXVhZHJhbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdib3R0b20tcmlnaHQnLFxuICAgICAgICAgICAgICAgICAgICBiYm94OiB4UmVnaW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogMyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMucmVnaW9uRGF0YS5wdXNoKHJpZ2h0Qm90dG9tUXVhZHJhbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8g5b2T5YmN57uY5Yi25Yy65Z+f5YWo6YOo5Zyo5LiA5Liq6LGh6ZmQ5LitXG4gICAgICAgICAgICBpZiAoeEJhc2VsaW5lIDw9IHhTY2FsZS5taW4pIHtcbiAgICAgICAgICAgICAgICBpZiAoeUJhc2VsaW5lIDw9IHlTY2FsZS5taW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJpZ2h0VG9wUXVhZHJhbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndG9wLXJpZ2h0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJib3g6IHhSZWdpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogMixcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWdpb25EYXRhLnB1c2gocmlnaHRUb3BRdWFkcmFudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmlnaHRCb3R0b21RdWFkcmFudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdib3R0b20tcmlnaHQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmJveDogeFJlZ2lvblswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiAzLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZ2lvbkRhdGEucHVzaChyaWdodEJvdHRvbVF1YWRyYW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoeUJhc2VsaW5lIDw9IHlTY2FsZS5taW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlZnRUb3BRdWFkcmFudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0b3AtbGVmdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBiYm94OiB4UmVnaW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVnaW9uRGF0YS5wdXNoKGxlZnRUb3BRdWFkcmFudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGVmdEJvdHRvbVF1YWRyYW50ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2JvdHRvbS1sZWZ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJib3g6IHhSZWdpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogMSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWdpb25EYXRhLnB1c2gobGVmdEJvdHRvbVF1YWRyYW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Yib5bu6Y29udGFpbmVyXG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gdGhpcy52aWV3LmJhY2tncm91bmRHcm91cC5hZGRHcm91cCgpO1xuICAgIH07XG4gICAgUXVhZHJhbnQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMucmVnaW9uRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YXIgZGVmYXVsdFN0eWxlXzEgPSB0aGlzLmdldERlZmF1bHRTdHlsZSgpO1xuICAgICAgICAgICAgdmFyIHJlZ2lvblN0eWxlXzEgPSB0aGlzLmdldFJlZ2lvblN0eWxlKHRoaXMucmVnaW9uRGF0YSk7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLnJlZ2lvbkRhdGEsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gZC5pbmRleDtcbiAgICAgICAgICAgICAgICB2YXIgZ3JvdXAgPSBfdGhpcy5jb250YWluZXIuYWRkR3JvdXAoKTtcbiAgICAgICAgICAgICAgICB2YXIgcmVjdCA9IGdyb3VwLmFkZFNoYXBlKCdyZWN0Jywge1xuICAgICAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHg6IGQuYmJveC5taW5YLCB5OiBkLmJib3gubWluWSwgd2lkdGg6IGQuYmJveC53aWR0aCwgaGVpZ2h0OiBkLmJib3guaGVpZ2h0IH0sIHJlZ2lvblN0eWxlXzFbaW5kZXhdKSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3F1YWRyYW50JyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5sYWJlbCAmJiBfdGhpcy5vcHRpb25zLmxhYmVsLnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxhYmVsT3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBkZWZhdWx0U3R5bGVfMS5sYWJlbCwgX3RoaXMub3B0aW9ucy5sYWJlbCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbENmZyA9IF90aGlzLmdldExhYmVsQ29uZmlnKGQsIGxhYmVsT3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oe30sIGxhYmVsQ2ZnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdxdWFkcmFudC1sYWJlbCcsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyByZWN0LnNldFNpbGVudCgnZGF0YScsIGQpO1xuICAgICAgICAgICAgICAgIHJlY3Quc2V0KCdkYXRhJywgZCk7XG4gICAgICAgICAgICAgICAgX3RoaXMucXVhZHJhbnRHcm91cHMucHVzaChncm91cCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIOe7mOWItuixoemZkOi+heWKqee6v1xuICAgICAgICAgICAgdmFyIGxpbmVTdHlsZV8xID0gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRTdHlsZV8xLmxpbmUsIHRoaXMub3B0aW9ucy5saW5lU3R5bGUpO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2godGhpcy5saW5lRGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsnTScsIGQuc3RhcnQueCwgZC5zdGFydC55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJ0wnLCBkLmVuZC54LCBkLmVuZC55XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIF0gfSwgbGluZVN0eWxlXzEpLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAncXVhZHJhbnQtbGluZScsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMudmlldy5jYW52YXMuZHJhdygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBRdWFkcmFudC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUXVhZHJhbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFF1YWRyYW50LnByb3RvdHlwZS5nZXREZWZhdWx0U3R5bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAnIzliYTI5YScsXG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlZ2lvblN0eWxlOiBbXG4gICAgICAgICAgICAgICAgeyBmaWxsOiAnIzAwMDAwMCcsIG9wYWNpdHk6IDAuMDUgfSxcbiAgICAgICAgICAgICAgICB7IGZpbGw6ICcjZmZmZmZmJywgb3BhY2l0eTogMCB9LFxuICAgICAgICAgICAgICAgIHsgZmlsbDogJyNmZmZmZmYnLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgICAgICAgeyBmaWxsOiAnIzAwMDAwMCcsIG9wYWNpdHk6IDAuMDUgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnb3V0dGVyLWlubmVyJyxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDEwLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxNCxcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJyNjY2MnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH07XG4gICAgUXVhZHJhbnQucHJvdG90eXBlLmdldFJlZ2lvblN0eWxlID0gZnVuY3Rpb24gKHJlZ2lvbkRhdGEpIHtcbiAgICAgICAgdmFyIGRlZmF1bHRTdHlsZSA9IHRoaXMuZ2V0RGVmYXVsdFN0eWxlKCk7XG4gICAgICAgIHZhciBzdHlsZSA9IGRlZmF1bHRTdHlsZS5yZWdpb25TdHlsZTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZWdpb25TdHlsZSkge1xuICAgICAgICAgICAgdmFyIHJlZ2lvblN0eWxlXzIgPSB0aGlzLm9wdGlvbnMucmVnaW9uU3R5bGU7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkocmVnaW9uU3R5bGVfMikpIHtcbiAgICAgICAgICAgICAgICBzdHlsZSA9IHN0eWxlLm1hcChmdW5jdGlvbiAocywgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2lvblN0eWxlXzIubGVuZ3RoID4gaW5kZXggJiYgcmVnaW9uU3R5bGVfMltpbmRleF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWdpb25TdHlsZV8yW2luZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHJlZ2lvblN0eWxlXzIpKSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLmVhY2gocmVnaW9uRGF0YSwgZnVuY3Rpb24gKGQsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlW2luZGV4XSA9IHJlZ2lvblN0eWxlXzIoZCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgIH07XG4gICAgUXVhZHJhbnQucHJvdG90eXBlLmdldExhYmVsQ29uZmlnID0gZnVuY3Rpb24gKHJlZ2lvbiwgbGFiZWxPcHRpb25zKSB7XG4gICAgICAgIHZhciBpbmRleCA9IHJlZ2lvbi5pbmRleDtcbiAgICAgICAgdmFyIHggPSAwO1xuICAgICAgICB2YXIgeSA9IDA7XG4gICAgICAgIHZhciBzdHlsZSA9IHt9O1xuICAgICAgICB2YXIgdGV4dCA9IGxhYmVsT3B0aW9ucy50ZXh0O1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24odGV4dCkpIHtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0KHJlZ2lvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodXRpbF8xLmlzQXJyYXkodGV4dCkpIHtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0W2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcG9zaXRpb24gPSBsYWJlbE9wdGlvbnMucG9zaXRpb247XG4gICAgICAgIHZhciBwb3MgPSBwb3NpdGlvbi5zcGxpdCgnLScpO1xuICAgICAgICB2YXIgZGltID0gcmVnaW9uLm5hbWUuc3BsaXQoJy0nKTtcbiAgICAgICAgLy8geOaWueWQkVxuICAgICAgICBpZiAoZGltWzFdID09PSAnbGVmdCcpIHtcbiAgICAgICAgICAgIGlmIChwb3NbMF0gPT09ICdpbm5lcicpIHtcbiAgICAgICAgICAgICAgICB4ID0gcmVnaW9uLmJib3gubWF4WCAtIGxhYmVsT3B0aW9ucy5vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc3R5bGUudGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb3NbMF0gPT09ICdvdXR0ZXInKSB7XG4gICAgICAgICAgICAgICAgeCA9IHJlZ2lvbi5iYm94Lm1pblggKyBsYWJlbE9wdGlvbnMub2Zmc2V0O1xuICAgICAgICAgICAgICAgIHN0eWxlLnRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkaW1bMV0gPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIGlmIChwb3NbMF0gPT09ICdpbm5lcicpIHtcbiAgICAgICAgICAgICAgICB4ID0gcmVnaW9uLmJib3gubWluWCArIGxhYmVsT3B0aW9ucy5vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc3R5bGUudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBvc1swXSA9PT0gJ291dHRlcicpIHtcbiAgICAgICAgICAgICAgICB4ID0gcmVnaW9uLmJib3gubWF4WCAtIGxhYmVsT3B0aW9ucy5vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc3R5bGUudGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyB55pa55ZCRXG4gICAgICAgIGlmIChkaW1bMF0gPT09ICd0b3AnKSB7XG4gICAgICAgICAgICBpZiAocG9zWzFdID09PSAnaW5uZXInKSB7XG4gICAgICAgICAgICAgICAgeSA9IHJlZ2lvbi5iYm94Lm1heFkgLSBsYWJlbE9wdGlvbnMub2Zmc2V0O1xuICAgICAgICAgICAgICAgIHN0eWxlLnRleHRCYXNlbGluZSA9ICdib3R0b20nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBvc1sxXSA9PT0gJ291dHRlcicpIHtcbiAgICAgICAgICAgICAgICB5ID0gcmVnaW9uLmJib3gubWluWSArIGxhYmVsT3B0aW9ucy5vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc3R5bGUudGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGltWzBdID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgaWYgKHBvc1sxXSA9PT0gJ2lubmVyJykge1xuICAgICAgICAgICAgICAgIHkgPSByZWdpb24uYmJveC5taW5ZICsgbGFiZWxPcHRpb25zLm9mZnNldDtcbiAgICAgICAgICAgICAgICBzdHlsZS50ZXh0QmFzZWxpbmUgPSAndG9wJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb3NbMV0gPT09ICdvdXR0ZXInKSB7XG4gICAgICAgICAgICAgICAgeSA9IHJlZ2lvbi5iYm94Lm1heFkgLSBsYWJlbE9wdGlvbnMub2Zmc2V0O1xuICAgICAgICAgICAgICAgIHN0eWxlLnRleHRCYXNlbGluZSA9ICdib3R0b20nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0eWxlID0gdXRpbF8xLmRlZXBNaXgoe30sIGxhYmVsT3B0aW9ucy5zdHlsZSwgc3R5bGUpO1xuICAgICAgICBzdHlsZS5saW5lSGVpZ2h0ID0gc3R5bGUuZm9udFNpemU7XG4gICAgICAgIHJldHVybiB0c2xpYl8xLl9fYXNzaWduKHsgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB0ZXh0OiB0ZXh0IH0sIHN0eWxlKTtcbiAgICB9O1xuICAgIHJldHVybiBRdWFkcmFudDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBRdWFkcmFudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXF1YWRyYW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgc2NhbGVfMSA9IHJlcXVpcmUoXCJAYW50di9zY2FsZVwiKTtcbnZhciBkM19yZWdyZXNzaW9uXzEgPSByZXF1aXJlKFwiZDMtcmVncmVzc2lvblwiKTtcbnZhciBwYXRoXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9wYXRoXCIpO1xudmFyIFJFR1JFU1NJT05fTUFQID0ge1xuICAgIGV4cDogZDNfcmVncmVzc2lvbl8xLnJlZ3Jlc3Npb25FeHAsXG4gICAgbGluZWFyOiBkM19yZWdyZXNzaW9uXzEucmVncmVzc2lvbkxpbmVhcixcbiAgICBsb2VzczogZDNfcmVncmVzc2lvbl8xLnJlZ3Jlc3Npb25Mb2VzcyxcbiAgICBsb2c6IGQzX3JlZ3Jlc3Npb25fMS5yZWdyZXNzaW9uTG9nLFxuICAgIHBvbHk6IGQzX3JlZ3Jlc3Npb25fMS5yZWdyZXNzaW9uUG9seSxcbiAgICBwb3c6IGQzX3JlZ3Jlc3Npb25fMS5yZWdyZXNzaW9uUG93LFxuICAgIHF1YWQ6IGQzX3JlZ3Jlc3Npb25fMS5yZWdyZXNzaW9uUXVhZCxcbn07XG5mdW5jdGlvbiBzZTk1KHAsIG4pIHtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KChwICogKDEgLSBwKSkgLyBuKSAqIDEuOTY7XG59XG52YXIgVHJlbmRMaW5lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFRyZW5kTGluZShjZmcpIHtcbiAgICAgICAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgICAgICAgICAgdHlwZTogJ2xpbmVhcicsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHN0cm9rZTogJyM5YmEyOWEnLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjUsXG4gICAgICAgICAgICAgICAgbGluZUpvaW46ICdyb3VuZCcsXG4gICAgICAgICAgICAgICAgbGluZUNhcDogJ3JvdW5kJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaG93Q29uZmlkZW5jZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWRlbmNlU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiAnI2NjYycsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC4xLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoe30sIGRlZmF1bHRPcHRpb25zLCBjZmcpO1xuICAgICAgICB0aGlzLnZpZXcgPSB0aGlzLm9wdGlvbnMudmlldztcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIFRyZW5kTGluZS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g5aSE55CG5pWw5o2uXG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucy5wbG90T3B0aW9ucywgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQsIGRhdGEgPSBfYS5kYXRhO1xuICAgICAgICB2YXIgcmVnID0gUkVHUkVTU0lPTl9NQVBbdGhpcy5vcHRpb25zLnR5cGVdKClcbiAgICAgICAgICAgIC54KGZ1bmN0aW9uIChkKSB7IHJldHVybiBkW3hGaWVsZF07IH0pXG4gICAgICAgICAgICAueShmdW5jdGlvbiAoZCkgeyByZXR1cm4gZFt5RmllbGRdOyB9KTtcbiAgICAgICAgdGhpcy5kYXRhID0gdGhpcy5wcm9jZXNzRGF0YShyZWcoZGF0YSkpO1xuICAgICAgICAvLyDliJvlu7pjb250YWluZXJcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLnZpZXcuYmFja2dyb3VuZEdyb3VwLmFkZEdyb3VwKCk7XG4gICAgfTtcbiAgICBUcmVuZExpbmUucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHhzY2FsZV92aWV3ID0gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZCh0aGlzLm9wdGlvbnMucGxvdE9wdGlvbnMueEZpZWxkKTtcbiAgICAgICAgdmFyIHlzY2FsZV92aWV3ID0gdGhpcy52aWV3LmdldFNjYWxlQnlGaWVsZCh0aGlzLm9wdGlvbnMucGxvdE9wdGlvbnMueUZpZWxkKTtcbiAgICAgICAgdmFyIGNvb3JkID0gdGhpcy52aWV3LmdldENvb3JkaW5hdGUoKTtcbiAgICAgICAgdmFyIHRyZW5kbGluZURhdGEgPSB0aGlzLmRhdGEudHJlbmRsaW5lRGF0YTtcbiAgICAgICAgLy8g5Yib5bu65Zu+5b2i57uY5Yi255qEc2NhbGVcbiAgICAgICAgdmFyIExpbmVhclNjYWxlID0gc2NhbGVfMS5nZXRTY2FsZSgnbGluZWFyJyk7XG4gICAgICAgIHZhciB4UmFuZ2UgPSB0aGlzLmFkanVzdFNjYWxlKHhzY2FsZV92aWV3LCB0cmVuZGxpbmVEYXRhLCAneCcpO1xuICAgICAgICB2YXIgeFNjYWxlID0gbmV3IExpbmVhclNjYWxlKHtcbiAgICAgICAgICAgIG1pbjogeFJhbmdlLm1pbixcbiAgICAgICAgICAgIG1heDogeFJhbmdlLm1heCxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB5UmFuZ2UgPSB0aGlzLmFkanVzdFNjYWxlKHlzY2FsZV92aWV3LCB0cmVuZGxpbmVEYXRhLCAneScpO1xuICAgICAgICB2YXIgeVNjYWxlID0gbmV3IExpbmVhclNjYWxlKHtcbiAgICAgICAgICAgIG1pbjogeVJhbmdlLm1pbixcbiAgICAgICAgICAgIG1heDogeVJhbmdlLm1heCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOe7mOWItue9ruS/oeWMuumXtOabsue6v1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dDb25maWRlbmNlKSB7XG4gICAgICAgICAgICB2YXIgY29uZmlkZW5jZVBhdGggPSB0aGlzLmdldENvbmZpZGVuY2VQYXRoKHhTY2FsZSwgeVNjYWxlLCBjb29yZCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IGNvbmZpZGVuY2VQYXRoIH0sIHRoaXMub3B0aW9ucy5jb25maWRlbmNlU3R5bGUpLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdjb25maWRlbmNlJyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIOe7mOWItnRyZW5kbGluZVxuICAgICAgICB2YXIgcG9pbnRzID0gdGhpcy5nZXRUcmVuZGxpbmVQb2ludHMoeFNjYWxlLCB5U2NhbGUsIGNvb3JkKTtcbiAgICAgICAgdmFyIGNvbnN0cmFpbnQgPSBbXG4gICAgICAgICAgICBbMCwgMF0sXG4gICAgICAgICAgICBbMSwgMV0sXG4gICAgICAgIF07XG4gICAgICAgIHZhciBwYXRoID0gcGF0aF8xLmdldFNwbGluZVBhdGgocG9pbnRzLCBmYWxzZSwgY29uc3RyYWludCk7XG4gICAgICAgIHRoaXMuc2hhcGUgPSB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgcGF0aDogcGF0aCB9LCB0aGlzLm9wdGlvbnMuc3R5bGUpLFxuICAgICAgICAgICAgbmFtZTogJ3RyZW5kbGluZScsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVHJlbmRMaW5lLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUcmVuZExpbmUucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUcmVuZExpbmUucHJvdG90eXBlLnByb2Nlc3NEYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIHRyZW5kbGluZSA9IFtdO1xuICAgICAgICB2YXIgY29uZmlkZW5jZSA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChkYXRhLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdHJlbmRsaW5lLnB1c2goeyB4OiBkWzBdLCB5OiBkWzFdIH0pO1xuICAgICAgICAgICAgdmFyIGNvbmYgPSBzZTk1KGRhdGEuclNxdWFyZWQsIGRbMV0pO1xuICAgICAgICAgICAgY29uZmlkZW5jZS5wdXNoKHsgeDogZFswXSwgeTA6IGRbMV0gLSBjb25mLCB5MTogZFsxXSArIGNvbmYgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4geyB0cmVuZGxpbmVEYXRhOiB0cmVuZGxpbmUsIGNvbmZpZGVuY2VEYXRhOiBjb25maWRlbmNlIH07XG4gICAgfTtcbiAgICBUcmVuZExpbmUucHJvdG90eXBlLmdldFRyZW5kbGluZVBvaW50cyA9IGZ1bmN0aW9uICh4U2NhbGUsIHlTY2FsZSwgY29vcmQpIHtcbiAgICAgICAgdmFyIHBvaW50cyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLmRhdGEudHJlbmRsaW5lRGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciB4UmF0aW8gPSB4U2NhbGUuc2NhbGUoZC54KTtcbiAgICAgICAgICAgIHZhciB5UmF0aW8gPSB5U2NhbGUuc2NhbGUoZC55KTtcbiAgICAgICAgICAgIHZhciB4ID0gY29vcmQuc3RhcnQueCArIGNvb3JkLndpZHRoICogeFJhdGlvO1xuICAgICAgICAgICAgdmFyIHkgPSBjb29yZC5zdGFydC55IC0gY29vcmQuaGVpZ2h0ICogeVJhdGlvO1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goeyB4OiB4LCB5OiB5IH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBvaW50cztcbiAgICB9O1xuICAgIFRyZW5kTGluZS5wcm90b3R5cGUuZ2V0Q29uZmlkZW5jZVBhdGggPSBmdW5jdGlvbiAoeFNjYWxlLCB5U2NhbGUsIGNvb3JkKSB7XG4gICAgICAgIHZhciB1cHBlclBvaW50cyA9IFtdO1xuICAgICAgICB2YXIgbG93ZXJQb2ludHMgPSBbXTtcbiAgICAgICAgdmFyIHBhdGggPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5kYXRhLmNvbmZpZGVuY2VEYXRhLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdmFyIHhSYXRpbyA9IHhTY2FsZS5zY2FsZShkLngpO1xuICAgICAgICAgICAgdmFyIHkwUmF0aW8gPSB5U2NhbGUuc2NhbGUoZC55MCk7XG4gICAgICAgICAgICB2YXIgeTFSYXRpbyA9IHlTY2FsZS5zY2FsZShkLnkxKTtcbiAgICAgICAgICAgIHZhciB4ID0gY29vcmQuc3RhcnQueCArIGNvb3JkLndpZHRoICogeFJhdGlvO1xuICAgICAgICAgICAgdmFyIHkwID0gY29vcmQuc3RhcnQueSAtIGNvb3JkLmhlaWdodCAqIHkwUmF0aW87XG4gICAgICAgICAgICB2YXIgeTEgPSBjb29yZC5zdGFydC55IC0gY29vcmQuaGVpZ2h0ICogeTFSYXRpbztcbiAgICAgICAgICAgIHVwcGVyUG9pbnRzLnB1c2goeyB4OiB4LCB5OiB5MCB9KTtcbiAgICAgICAgICAgIGxvd2VyUG9pbnRzLnB1c2goeyB4OiB4LCB5OiB5MSB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdXBwZXJQb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBmbGFnID0gaSA9PT0gMCA/ICdNJyA6ICdMJztcbiAgICAgICAgICAgIHZhciBwID0gdXBwZXJQb2ludHNbaV07XG4gICAgICAgICAgICBpZiAoIWlzTmFOKHAueCkgJiYgIWlzTmFOKHAueSkpIHtcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goW2ZsYWcsIHAueCwgcC55XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaiA9IGxvd2VyUG9pbnRzLmxlbmd0aCAtIDE7IGogPiAwOyBqLS0pIHtcbiAgICAgICAgICAgIHZhciBwID0gbG93ZXJQb2ludHNbal07XG4gICAgICAgICAgICBpZiAoIWlzTmFOKHAueCkgJiYgIWlzTmFOKHAueSkpIHtcbiAgICAgICAgICAgICAgICBwYXRoLnB1c2goWydMJywgcC54LCBwLnldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9O1xuICAgIFRyZW5kTGluZS5wcm90b3R5cGUuYWRqdXN0U2NhbGUgPSBmdW5jdGlvbiAodmlld1NjYWxlLCB0cmVuZGxpbmVEYXRhLCBkaW0pIHtcbiAgICAgICAgLy8g5aSE55CG55So5oi36Ieq6KGM6YWN572ubWluIG1heOeahOaDheWGtVxuICAgICAgICB2YXIgbWluID0gdmlld1NjYWxlLm1pbiwgbWF4ID0gdmlld1NjYWxlLm1heDtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5vcHRpb25zLnBsb3RPcHRpb25zLCBkYXRhID0gX2EuZGF0YSwgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQ7XG4gICAgICAgIHZhciBmaWVsZCA9IGRpbSA9PT0gJ3gnID8geEZpZWxkIDogeUZpZWxkO1xuICAgICAgICB2YXIgZGF0YU1pbiA9IHV0aWxfMS5taW5CeShkYXRhLCBmaWVsZClbZmllbGRdO1xuICAgICAgICB2YXIgZGF0YU1heCA9IHV0aWxfMS5tYXhCeShkYXRhLCBmaWVsZClbZmllbGRdO1xuICAgICAgICB2YXIgbWluUmF0aW8gPSAobWluIC0gZGF0YU1pbikgLyAoZGF0YU1heCAtIGRhdGFNaW4pO1xuICAgICAgICB2YXIgbWF4UmF0aW8gPSAobWF4IC0gZGF0YU1heCkgLyAoZGF0YU1heCAtIGRhdGFNaW4pO1xuICAgICAgICB2YXIgdHJlbmRNaW4gPSB1dGlsXzEubWluQnkodHJlbmRsaW5lRGF0YSwgZGltKVtkaW1dO1xuICAgICAgICB2YXIgdHJlbmRNYXggPSB1dGlsXzEubWF4QnkodHJlbmRsaW5lRGF0YSwgZGltKVtkaW1dO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluOiB0cmVuZE1pbiArIG1pblJhdGlvICogKHRyZW5kTWF4IC0gdHJlbmRNaW4pLFxuICAgICAgICAgICAgbWF4OiB0cmVuZE1heCArIG1heFJhdGlvICogKHRyZW5kTWF4IC0gdHJlbmRNaW4pLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRyZW5kTGluZTtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUcmVuZExpbmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10cmVuZGxpbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICBwb2ludDogJ3BvaW50JyxcbiAgICB0cmVuZGxpbmU6ICd0cmVuZGxpbmUnLFxuICAgIGNvbmZpZGVuY2U6ICdjb25maWRlbmNlJyxcbiAgICBxdWFkcmFudDogJ3F1YWRyYW50JyxcbiAgICBxdWFkcmFudExhYmVsOiAncXVhZHJhbnQtbGFiZWwnLFxuICAgIHF1YWRyYW50TGluZTogJ3F1YWRyYW50LWxpbmUnLFxufTtcbnZhciBTSEFQRV9FVkVOVF9NQVAgPSBldmVudF8xLmdldEV2ZW50TWFwKGNvbXBvbmVudE1hcCk7XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFNjYXR0ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2NhdHRlciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTY2F0dGVyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFNjYXR0ZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdzY2F0dGVyJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFNjYXR0ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFNjYXR0ZXI7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTY2F0dGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciB2aWV3X2xheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS92aWV3LWxheWVyXCIpKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vZ2VvbXMvZmFjdG9yeVwiKTtcbnZhciBzY2FsZV8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvc2NhbGVcIik7XG52YXIgcXVhZHJhbnRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvcXVhZHJhbnRcIikpO1xudmFyIHRyZW5kbGluZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50cy90cmVuZGxpbmVcIikpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIGZhY3RvcnlfMiA9IHJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnRzL2ZhY3RvcnlcIik7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnZhciBHMl9HRU9NX01BUCA9IHtcbiAgICBzY2F0dGVyOiAncG9pbnQnLFxufTtcbnZhciBQTE9UX0dFT01fTUFQID0ge1xuICAgIHBvaW50OiAncG9pbnQnLFxufTtcbnZhciBTY2F0dGVyTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU2NhdHRlckxheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFNjYXR0ZXJMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnc2NhdHRlcic7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgU2NhdHRlckxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICBwb2ludFNpemU6IDQsXG4gICAgICAgICAgICBwb2ludFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIHN0cm9rZU9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDAuOTUsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAnI2ZmZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeEF4aXM6IHtcbiAgICAgICAgICAgICAgICBuaWNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgbmljZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAvLyBmYWxzZSDkvJrpgKDmiJAgdG9vbHRpcCDlj6rog73mmL7npLrkuIDmnaHmlbDmja7vvIx0cnVlIOS8mumAoOaIkCB0b29sdGlwIOWcqOepuueZveWMuuWfn+S5n+S8muaYvuekulxuICAgICAgICAgICAgICAgIHNoYXJlZDogbnVsbCxcbiAgICAgICAgICAgICAgICBzaG93VGl0bGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dNYXJrZXJzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzaG93Q3Jvc3NoYWlyczogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaGFwZTogJ2NpcmNsZScsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU2NhdHRlckxheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5xdWFkcmFudCkge1xuICAgICAgICAgICAgdGhpcy5xdWFkcmFudC5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJlbmRsaW5lKSB7XG4gICAgICAgICAgICB0aGlzLnRyZW5kbGluZS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5xdWFkcmFudCAmJiB0aGlzLm9wdGlvbnMucXVhZHJhbnQudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5xdWFkcmFudCA9IG5ldyBxdWFkcmFudF8xLmRlZmF1bHQodHNsaWJfMS5fX2Fzc2lnbih7IHZpZXc6IHRoaXMudmlldywgcGxvdE9wdGlvbnM6IHRoaXMub3B0aW9ucyB9LCB0aGlzLm9wdGlvbnMucXVhZHJhbnQpKTtcbiAgICAgICAgICAgIHRoaXMucXVhZHJhbnQucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50cmVuZGxpbmUgJiYgdGhpcy5vcHRpb25zLnRyZW5kbGluZS52aXNpYmxlKSB7XG4gICAgICAgICAgICB0aGlzLnRyZW5kbGluZSA9IG5ldyB0cmVuZGxpbmVfMS5kZWZhdWx0KHRzbGliXzEuX19hc3NpZ24oeyB2aWV3OiB0aGlzLnZpZXcsIHBsb3RPcHRpb25zOiB0aGlzLm9wdGlvbnMgfSwgdGhpcy5vcHRpb25zLnRyZW5kbGluZSkpO1xuICAgICAgICAgICAgdGhpcy50cmVuZGxpbmUucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNjYXR0ZXJMYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucXVhZHJhbnQpIHtcbiAgICAgICAgICAgIHRoaXMucXVhZHJhbnQuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5xdWFkcmFudCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJlbmRsaW5lKSB7XG4gICAgICAgICAgICB0aGlzLnRyZW5kbGluZS5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLnRyZW5kbGluZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBTY2F0dGVyTGF5ZXIucHJvdG90eXBlLmlzVmFsaWRMaW5lYXJWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKE51bWJlci5pc05hTihOdW1iZXIodmFsdWUpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgU2NhdHRlckxheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgeEZpZWxkID0gX2EueEZpZWxkLCB5RmllbGQgPSBfYS55RmllbGQ7XG4gICAgICAgIHZhciB4QXhpc1R5cGUgPSB1dGlsXzEuZ2V0KHRoaXMub3B0aW9ucywgWyd4QXhpcycsICd0eXBlJ10sICdsaW5lYXInKTtcbiAgICAgICAgdmFyIHlBeGlzVHlwZSA9IHV0aWxfMS5nZXQodGhpcy5vcHRpb25zLCBbJ3lBeGlzJywgJ3R5cGUnXSwgJ2xpbmVhcicpO1xuICAgICAgICBpZiAoeEF4aXNUeXBlICYmIHlBeGlzVHlwZSkge1xuICAgICAgICAgICAgdmFyIGZpdGVyZWREYXRhID0gZGF0YVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoeEF4aXNUeXBlID09PSAnbGluZWFyJyAmJiAhX3RoaXMuaXNWYWxpZExpbmVhclZhbHVlKGl0ZW1beEZpZWxkXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoeUF4aXNUeXBlID09PSAnbGluZWFyJyAmJiAhX3RoaXMuaXNWYWxpZExpbmVhclZhbHVlKGl0ZW1beUZpZWxkXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBpdGVtKSwgKF9hID0ge30sIF9hW3hGaWVsZF0gPSB4QXhpc1R5cGUgPT09ICdsaW5lYXInID8gTnVtYmVyKGl0ZW1beEZpZWxkXSkgOiBTdHJpbmcoaXRlbVt4RmllbGRdKSwgX2FbeUZpZWxkXSA9IHlBeGlzVHlwZSA9PT0gJ2xpbmVhcicgPyBOdW1iZXIoaXRlbVt5RmllbGRdKSA6IFN0cmluZyhpdGVtW3lGaWVsZF0pLCBfYSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gZml0ZXJlZERhdGE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfTtcbiAgICBTY2F0dGVyTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKGRpbSwgdHlwZSkge1xuICAgICAgICBpZiAoZGltID09PSAnZzInKSB7XG4gICAgICAgICAgICByZXR1cm4gRzJfR0VPTV9NQVBbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBMT1RfR0VPTV9NQVBbdHlwZV07XG4gICAgfTtcbiAgICBTY2F0dGVyTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgLyoqIOmFjee9rngtc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW3Byb3BzLnhGaWVsZF0gPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5oYXMocHJvcHMsICd4QXhpcycpKSB7XG4gICAgICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXNbcHJvcHMueEZpZWxkXSwgcHJvcHMueEF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIC8qKiDphY3nva55LXNjYWxlICovXG4gICAgICAgIHNjYWxlc1twcm9wcy55RmllbGRdID0ge307XG4gICAgICAgIGlmICh1dGlsXzEuaGFzKHByb3BzLCAneUF4aXMnKSkge1xuICAgICAgICAgICAgc2NhbGVfMS5leHRyYWN0U2NhbGUoc2NhbGVzW3Byb3BzLnlGaWVsZF0sIHByb3BzLnlBeGlzKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGltZUxpbmVJbnRlcmFjdGlvbiA9IHV0aWxfMS5maW5kKHByb3BzLmludGVyYWN0aW9ucywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb24udHlwZSA9PT0gJ3RpbWVsaW5lJztcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aW1lTGluZUludGVyYWN0aW9uICYmIHV0aWxfMS5nZXQodGltZUxpbmVJbnRlcmFjdGlvbiwgJ2NmZy5rZXknKSkge1xuICAgICAgICAgICAgdmFyIGtleUZpZWxkID0gdGltZUxpbmVJbnRlcmFjdGlvbi5jZmcua2V5O1xuICAgICAgICAgICAgaWYgKHNjYWxlc1trZXlGaWVsZF0pIHtcbiAgICAgICAgICAgICAgICBzY2FsZXNba2V5RmllbGRdLmtleSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzY2FsZXNba2V5RmllbGRdID0geyBrZXk6IHRydWUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnc2NhbGVzJywgc2NhbGVzKTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5zY2FsZS5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgU2NhdHRlckxheWVyLnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgU2NhdHRlckxheWVyLnByb3RvdHlwZS5hbm5vdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBTY2F0dGVyTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcG9pbnRzID0gZmFjdG9yeV8xLmdldEdlb20oJ3BvaW50JywgJ2NpcmNsZScsIHtcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvaW50cyA9IHBvaW50cztcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50b29sdGlwICYmIHRoaXMub3B0aW9ucy50b29sdGlwLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucy50b29sdGlwLCBzaG93VGl0bGUgPSBfYS5zaG93VGl0bGUsIHRpdGxlRmllbGQgPSBfYS50aXRsZUZpZWxkO1xuICAgICAgICAgICAgdGhpcy5leHRyYWN0VG9vbHRpcCgpO1xuICAgICAgICAgICAgdGhpcy5zZXRDb25maWcoJ3Rvb2x0aXAnLCB0c2xpYl8xLl9fYXNzaWduKHsgc2hvd1RpdGxlOiBzaG93VGl0bGUsIHRpdGxlOiBzaG93VGl0bGUgPyB0aXRsZUZpZWxkIDogdW5kZWZpbmVkIH0sIHRoaXMub3B0aW9ucy50b29sdGlwKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sYWJlbCkge1xuICAgICAgICAgICAgdGhpcy5sYWJlbCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIHBvaW50cyk7XG4gICAgfTtcbiAgICBTY2F0dGVyTGF5ZXIucHJvdG90eXBlLmxhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmIChwcm9wcy5sYWJlbC52aXNpYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludHMubGFiZWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGFiZWwgPSBmYWN0b3J5XzIuZ2V0Q29tcG9uZW50KCdsYWJlbCcsIHRzbGliXzEuX19hc3NpZ24odHNsaWJfMS5fX2Fzc2lnbih7IGZpZWxkczogcHJvcHMubGFiZWwuZmllbGQgPyBbcHJvcHMubGFiZWwuZmllbGRdIDogW3Byb3BzLnlGaWVsZF0gfSwgcHJvcHMubGFiZWwpLCB7IHBsb3Q6IHRoaXMgfSkpO1xuICAgICAgICBpZiAodGhpcy5wb2ludHMpIHtcbiAgICAgICAgICAgIHRoaXMucG9pbnRzLmxhYmVsID0gbGFiZWw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNjYXR0ZXJMYXllci5wcm90b3R5cGUuYW5pbWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFuaW1hdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmIChwcm9wcy5hbmltYXRpb24gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAvKiog5YWz6Zet5Yqo55S7ICovXG4gICAgICAgICAgICB0aGlzLnBvaW50cy5hbmltYXRlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFNjYXR0ZXJMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoZXZlbnRQYXJzZXIpIHtcbiAgICAgICAgLy8g5rCU5rOh5Zu+57un5om/5pWj54K55Zu+5pe277yM5Lya5a2Y5ZyoIGV2ZW50UGFyc2VyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBldmVudFBhcnNlciB8fCBFdmVudFBhcnNlcik7XG4gICAgfTtcbiAgICBTY2F0dGVyTGF5ZXIucHJvdG90eXBlLmV4dHJhY3RUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnBvaW50cy50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLnBvaW50cy50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucG9pbnRzLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy54RmllbGQsIHRoaXMub3B0aW9ucy55RmllbGRdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMucG9pbnRzLnRvb2x0aXAuY2FsbGJhY2sgPSB0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNvbG9yRmllbGQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBvaW50cy50b29sdGlwLmZpZWxkcy5wdXNoKHRoaXMub3B0aW9ucy5jb2xvckZpZWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFNjYXR0ZXJMYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNjYXR0ZXJMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3NjYXR0ZXInLCBTY2F0dGVyTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciBQT0lOVF9BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgc3Ryb2tlID0gc3R5bGUuc3Ryb2tlIHx8ICcjMDAwJztcbiAgICByZXR1cm4ge1xuICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICB9O1xufTtcbnZhciBQT0lOVF9TRUxFQ1RFRF9TVFlMRSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHZhciBzdHJva2UgPSBzdHlsZS5zdHJva2UgfHwgJyMwMDAnO1xuICAgIHZhciBsaW5lV2lkdGggPSBzdHlsZS5saW5lV2lkdGggfHwgMjtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgbGluZVdpZHRoOiBsaW5lV2lkdGgsXG4gICAgfTtcbn07XG52YXIgUE9JTlRfSU5BQ1RJVkVfU1RZTEUgPSBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICB2YXIgZmlsbE9wYWNpdHkgPSBzdHlsZS5maWxsT3BhY2l0eSB8fCBzdHlsZS5vcGFjaXR5IHx8IDAuMztcbiAgICByZXR1cm4ge1xuICAgICAgICBmaWxsT3BhY2l0eTogZmlsbE9wYWNpdHksXG4gICAgfTtcbn07XG50aGVtZV8xLnJlZ2lzdGVyVGhlbWUoJ3NjYXR0ZXInLCB7XG4gICAgcG9pbnRTdHlsZToge1xuICAgICAgICBub3JtYWw6IHt9LFxuICAgICAgICBhY3RpdmU6IFBPSU5UX0FDVElWRV9TVFlMRSxcbiAgICAgICAgc2VsZWN0ZWQ6IFBPSU5UX1NFTEVDVEVEX1NUWUxFLFxuICAgICAgICBpbmFjdGl2ZTogUE9JTlRfSU5BQ1RJVkVfU1RZTEUsXG4gICAgfSxcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFBsb3RDb21wb25lbnRzID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbGluZV9sYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGFiZWwvbGluZS1sYWJlbFwiKSk7XG52YXIgYXJlYV9sYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGFiZWwvYXJlYS1sYWJlbFwiKSk7XG52YXIgQ29tcG9uZW50c0luZm8gPSB7XG4gICAgbGluZUxhYmVsOiB7IEN0cjogbGluZV9sYWJlbF8xLmRlZmF1bHQgfSxcbiAgICBhcmVhTGFiZWw6IHsgQ3RyOiBhcmVhX2xhYmVsXzEuZGVmYXVsdCB9LFxufTtcbmZ1bmN0aW9uIGdldFBsb3RDb21wb25lbnRzKHBsb3QsIHR5cGUsIGNmZykge1xuICAgIGlmIChwbG90Lm9wdGlvbnNbdHlwZV0gJiYgcGxvdC5vcHRpb25zW3R5cGVdLnZpc2libGUpIHtcbiAgICAgICAgdmFyIGNvbXBvbmVudEluZm8gPSBDb21wb25lbnRzSW5mb1t0eXBlXTtcbiAgICAgICAgdmFyIGNvbXBvbmVudCA9IG5ldyBjb21wb25lbnRJbmZvLkN0cihjZmcpO1xuICAgICAgICBpZiAoY29tcG9uZW50SW5mby5wYWRkaW5nKSB7XG4gICAgICAgICAgICBwbG90LnBhZGRpbmdDb250cm9sbGVyLnJlZ2lzdGVyUGFkZGluZyhjb21wb25lbnQsIGNvbXBvbmVudEluZm8ucGFkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudDtcbiAgICB9XG59XG5leHBvcnRzLmdldFBsb3RDb21wb25lbnRzID0gZ2V0UGxvdENvbXBvbmVudHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIERFRkFVTFRfU0laRSA9IDEyO1xudmFyIFRPTEVSQU5DRSA9IDAuMDE7XG52YXIgTUFYX0lURVJBVElPTiA9IDEwMDtcbnZhciBNSU5fSEVJR0hUID0gMTI7XG5mdW5jdGlvbiBnZXRSYW5nZShwb2ludHMpIHtcbiAgICB2YXIgbWF4SGVpZ2h0ID0gLUluZmluaXR5O1xuICAgIHZhciBtaW4gPSBJbmZpbml0eTtcbiAgICB2YXIgbWF4ID0gLUluZmluaXR5O1xuICAgIHV0aWxfMS5lYWNoKHBvaW50cywgZnVuY3Rpb24gKHApIHtcbiAgICAgICAgbWluID0gTWF0aC5taW4ocC54LCBtaW4pO1xuICAgICAgICBtYXggPSBNYXRoLm1heChwLngsIG1heCk7XG4gICAgICAgIHZhciBoZWlnaHQgPSBNYXRoLmFicyhwLnlbMF0gLSBwLnlbMV0pO1xuICAgICAgICBtYXhIZWlnaHQgPSBNYXRoLm1heChtYXhIZWlnaHQsIGhlaWdodCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeFJhbmdlOiBbbWluLCBtYXhdLFxuICAgICAgICBtYXhIZWlnaHQ6IG1heEhlaWdodCxcbiAgICB9O1xufVxuZnVuY3Rpb24gaW50ZXJwb2xhdGVZKHgsIHBvaW50cywgaW5kZXgpIHtcbiAgICB2YXIgbGVmdFBvaW50ID0gcG9pbnRzWzBdO1xuICAgIHZhciByaWdodFBvaW50ID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcbiAgICB1dGlsXzEuZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgIGlmIChwLnggPT09IHgpIHtcbiAgICAgICAgICAgIHJldHVybiBwLnlbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwLnggPCB4ICYmIHAueCA+IGxlZnRQb2ludC54KSB7XG4gICAgICAgICAgICBsZWZ0UG9pbnQgPSBwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwLnggPiB4ICYmIHAueCA8IHJpZ2h0UG9pbnQueCkge1xuICAgICAgICAgICAgcmlnaHRQb2ludCA9IHA7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICB2YXIgdCA9ICh4IC0gbGVmdFBvaW50LngpIC8gKHJpZ2h0UG9pbnQueCAtIGxlZnRQb2ludC54KTtcbiAgICByZXR1cm4gbGVmdFBvaW50LnlbaW5kZXhdICogKDEgLSB0KSArIHJpZ2h0UG9pbnQueVtpbmRleF0gKiB0O1xufVxuZnVuY3Rpb24gZ2V0WEluZGV4KGRhdGEsIHgpIHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IHByZWZlci1mb3Itb2ZcbiAgICB2YXIgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZCA9IGRhdGFbaV07XG4gICAgICAgIGlmIChkLnggPT09IHggfHwgZC54ID4geCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGk7XG59XG52YXIgQXJlYUxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEFyZWFMYWJlbChjZmcpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zY2FsZUZhY3RvciA9IFtdO1xuICAgICAgICB0aGlzLnZpZXcgPSBjZmcudmlldztcbiAgICAgICAgdGhpcy5wbG90ID0gY2ZnLnBsb3Q7XG4gICAgICAgIHZhciBkZWZhdWx0T3B0aW9ucyA9IHRoaXMuZ2V0RGVmYXVsdE9wdGlvbnMoKTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoZGVmYXVsdE9wdGlvbnMsIGNmZywge30pO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5sYWJlbHNDb250YWluZXI7XG4gICAgICAgIHRoaXMudmlldy5vbignYmVmb3JlcmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuY2xlYXIoKTtcbiAgICAgICAgICAgIF90aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBBcmVhTGFiZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHN0YWNrRmllbGQgPSB0aGlzLnBsb3Qub3B0aW9ucy5zdGFja0ZpZWxkO1xuICAgICAgICB2YXIgZ3JvdXBlZFBvaW50cyA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5kYXRhQXJyYXk7XG4gICAgICAgIHZhciBsYWJlbFBvaW50cyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChncm91cGVkUG9pbnRzLCBmdW5jdGlvbiAocG9pbnRBcnJheSwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIGxhYmVsUG9pbnQgPSBfdGhpcy5kcmF3TGFiZWwocG9pbnRBcnJheSwgbmFtZSk7XG4gICAgICAgICAgICBpZiAobGFiZWxQb2ludCkge1xuICAgICAgICAgICAgICAgIGxhYmVsUG9pbnRzLnB1c2godXRpbF8xLmRlZXBNaXgoe30sIHBvaW50QXJyYXlbMF0sIGxhYmVsUG9pbnQpKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5zY2FsZUZhY3Rvci5wdXNoKGxhYmVsUG9pbnQuc2NhbGVGYWN0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGxhYmVsU2hhcGVzID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKGxhYmVsUG9pbnRzLCBmdW5jdGlvbiAocCwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBfYSA9IF90aGlzLm9wdGlvbnMsIHN0eWxlID0gX2Euc3R5bGUsIG9mZnNldFggPSBfYS5vZmZzZXRYLCBvZmZzZXRZID0gX2Eub2Zmc2V0WTtcbiAgICAgICAgICAgIHZhciBsYWJlbFNpemUgPSBfdGhpcy5nZXRGb250U2l6ZShpbmRleCk7XG4gICAgICAgICAgICB2YXIgZm9ybWF0dGVyID0gX3RoaXMub3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgICAgICB2YXIgY29udGVudCA9IGZvcm1hdHRlciA/IGZvcm1hdHRlcihwLl9vcmlnaW5bc3RhY2tGaWVsZF0pIDogcC5fb3JpZ2luW3N0YWNrRmllbGRdO1xuICAgICAgICAgICAgdmFyIHRleHQgPSBfdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHV0aWxfMS5kZWVwTWl4KHt9LCB7XG4gICAgICAgICAgICAgICAgICAgIHg6IHAueCArIG9mZnNldFgsXG4gICAgICAgICAgICAgICAgICAgIHk6IHAueSArIG9mZnNldFksXG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IHAuY29sb3IsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiBsYWJlbFNpemUsXG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgIHRleHRCYXNlbGluZTogJ3RvcCcsXG4gICAgICAgICAgICAgICAgfSwgc3R5bGUpLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdsYWJlbCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGxhYmVsU2hhcGVzLnB1c2godGV4dCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBsb3QuY2FudmFzLmRyYXcoKTtcbiAgICB9O1xuICAgIEFyZWFMYWJlbC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBBcmVhTGFiZWwucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXIuZ2V0QkJveCgpO1xuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRoZW1lID0gdGhpcy5wbG90LnRoZW1lO1xuICAgICAgICB2YXIgbGFiZWxTdHlsZSA9IHV0aWxfMS5jbG9uZSh0aGVtZS5sYWJlbC5zdHlsZSk7XG4gICAgICAgIGxhYmVsU3R5bGUuc3Ryb2tlID0gbnVsbDtcbiAgICAgICAgZGVsZXRlIGxhYmVsU3R5bGUuZmlsbDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9mZnNldFg6IDAsXG4gICAgICAgICAgICBvZmZzZXRZOiAwLFxuICAgICAgICAgICAgc3R5bGU6IGxhYmVsU3R5bGUsXG4gICAgICAgICAgICBhdXRvU2NhbGU6IHRydWUsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBBcmVhTGFiZWwucHJvdG90eXBlLmRyYXdMYWJlbCA9IGZ1bmN0aW9uIChwb2ludHMsIG5hbWUpIHtcbiAgICAgICAgdmFyIF9hID0gZ2V0UmFuZ2UocG9pbnRzKSwgeFJhbmdlID0gX2EueFJhbmdlLCBtYXhIZWlnaHQgPSBfYS5tYXhIZWlnaHQ7XG4gICAgICAgIC8vIOagueaNrmFyZWHlrr3luqblnKh45pa55ZCR5ZCE54K56Ze05YGa5o+S5YC8XG4gICAgICAgIHZhciByZXNvbHV0aW9uID0geFJhbmdlWzFdIC0geFJhbmdlWzBdO1xuICAgICAgICB2YXIgaW50ZXJwb2xhdGVkUG9pbnRzID0gdGhpcy5nZXRJbnRlcnBvbGF0ZWRQb2ludHMoeFJhbmdlWzBdLCByZXNvbHV0aW9uLCBwb2ludHMpO1xuICAgICAgICAvLyDojrflj5ZsYWJlbOeahGJib3hcbiAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldExhYmVsQmJveChuYW1lKTtcbiAgICAgICAgdmFyIGZpdE9wdGlvbiA9IHtcbiAgICAgICAgICAgIHhSYW5nZTogeFJhbmdlLFxuICAgICAgICAgICAgYXNwZWN0OiBiYm94LndpZHRoIC8gYmJveC5oZWlnaHQsXG4gICAgICAgICAgICBkYXRhOiBpbnRlcnBvbGF0ZWRQb2ludHMsXG4gICAgICAgICAgICBqdXN0VGVzdDogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGhlaWdodCA9IHRoaXMuYmlzZWN0aW9uKE1JTl9IRUlHSFQsIG1heEhlaWdodCwgdGhpcy50ZXN0Rml0LCBmaXRPcHRpb24sIFRPTEVSQU5DRSwgTUFYX0lURVJBVElPTik7XG4gICAgICAgIGlmIChoZWlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmaXRPcHRpb24uanVzdFRlc3QgPSBmYWxzZTtcbiAgICAgICAgdmFyIGZpdCA9IHRoaXMudGVzdEZpdChmaXRPcHRpb24pO1xuICAgICAgICBmaXQueCA9IGZpdC54O1xuICAgICAgICBmaXQueSA9IGZpdC55MCArIChmaXQueTEgLSBmaXQueTApIC8gMjtcbiAgICAgICAgZml0LnNjYWxlRmFjdG9yID0gKGhlaWdodCAvIGJib3guaGVpZ2h0KSAqIDAuMjtcbiAgICAgICAgcmV0dXJuIGZpdDtcbiAgICB9O1xuICAgIEFyZWFMYWJlbC5wcm90b3R5cGUuZ2V0SW50ZXJwb2xhdGVkUG9pbnRzID0gZnVuY3Rpb24gKG1pblgsIHJlc29sdXRpb24sIHBvaW50cykge1xuICAgICAgICB2YXIgaW50ZXJwb2xhdGVkUG9pbnRzID0gW107XG4gICAgICAgIHZhciBzdGVwID0gMjtcbiAgICAgICAgZm9yICh2YXIgaSA9IG1pblg7IGkgPCByZXNvbHV0aW9uOyBpICs9IHN0ZXApIHtcbiAgICAgICAgICAgIHZhciB5MCA9IGludGVycG9sYXRlWShpLCBwb2ludHMsIDApO1xuICAgICAgICAgICAgdmFyIHkxID0gaW50ZXJwb2xhdGVZKGksIHBvaW50cywgMSk7XG4gICAgICAgICAgICBpbnRlcnBvbGF0ZWRQb2ludHMucHVzaCh7XG4gICAgICAgICAgICAgICAgeDogaSxcbiAgICAgICAgICAgICAgICB5OiBbeTAsIHkxXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnRlcnBvbGF0ZWRQb2ludHM7XG4gICAgfTtcbiAgICBBcmVhTGFiZWwucHJvdG90eXBlLmJpc2VjdGlvbiA9IGZ1bmN0aW9uIChtaW4sIG1heCwgdGVzdCwgdGVzdE9wdGlvbiwgdG9sZXJhbmNlLCBtYXhJdGVyYXRpb24pIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXhJdGVyYXRpb247IGkrKykge1xuICAgICAgICAgICAgdmFyIG1pZGRsZSA9IChtaW4gKyBtYXgpIC8gMjtcbiAgICAgICAgICAgIHZhciBvcHRpb25zID0gdGVzdE9wdGlvbjtcbiAgICAgICAgICAgIG9wdGlvbnMuaGVpZ2h0ID0gbWlkZGxlO1xuICAgICAgICAgICAgb3B0aW9ucy53aWR0aCA9IG1pZGRsZSAqIG9wdGlvbnMuYXNwZWN0O1xuICAgICAgICAgICAgdmFyIHBhc3Nlc1Rlc3QgPSB0ZXN0KG9wdGlvbnMpO1xuICAgICAgICAgICAgdmFyIHdpdGhpblRvbGVyYW5jZSA9IChtYXggLSBtaW4pIC8gMiA8IHRvbGVyYW5jZTtcbiAgICAgICAgICAgIGlmIChwYXNzZXNUZXN0ICYmIHdpdGhpblRvbGVyYW5jZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtaWRkbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGFzc2VzVGVzdCkge1xuICAgICAgICAgICAgICAgIG1pbiA9IG1pZGRsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1heCA9IG1pZGRsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIEFyZWFMYWJlbC5wcm90b3R5cGUudGVzdEZpdCA9IGZ1bmN0aW9uIChvcHRpb24pIHtcbiAgICAgICAgdmFyIHhSYW5nZSA9IG9wdGlvbi54UmFuZ2UsIHdpZHRoID0gb3B0aW9uLndpZHRoLCBoZWlnaHQgPSBvcHRpb24uaGVpZ2h0LCBkYXRhID0gb3B0aW9uLmRhdGEsIGp1c3RUZXN0ID0gb3B0aW9uLmp1c3RUZXN0O1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBkID0gZGF0YVtpXTtcbiAgICAgICAgICAgIHZhciB4MCA9IGQueDtcbiAgICAgICAgICAgIHZhciB4MSA9IHgwICsgd2lkdGg7XG4gICAgICAgICAgICBpZiAoeDEgPiB4UmFuZ2VbMV0pIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB4MV9pbmRleCA9IGdldFhJbmRleChkYXRhLCB4MSk7XG4gICAgICAgICAgICB2YXIgY2VpbGluZyA9IC1JbmZpbml0eTtcbiAgICAgICAgICAgIHZhciBjZWlsaW5nRmxvb3IgPSBudWxsOyAvLyDkv53lrZhjZWlsaW5n5pe25a+55bqU55qEYm90dG9t5L2N572u77yMY2VpbOWSjGZsb29y5LiN5LiA5a6a5piv5LiA5a+55Z2Q5qCHXG4gICAgICAgICAgICB2YXIgZmxvb3IgPSBJbmZpbml0eTtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSBpOyBqIDwgeDFfaW5kZXg7IGorKykge1xuICAgICAgICAgICAgICAgIHZhciB0b3BfMSA9IGRhdGFbal0ueVsxXTtcbiAgICAgICAgICAgICAgICB2YXIgYm90dG9tID0gZGF0YVtqXS55WzBdO1xuICAgICAgICAgICAgICAgIGlmIChib3R0b20gPCBmbG9vcikge1xuICAgICAgICAgICAgICAgICAgICBmbG9vciA9IGJvdHRvbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRvcF8xID4gY2VpbGluZykge1xuICAgICAgICAgICAgICAgICAgICBjZWlsaW5nID0gdG9wXzE7XG4gICAgICAgICAgICAgICAgICAgIGNlaWxpbmdGbG9vciA9IGJvdHRvbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGZsb29yIC0gY2VpbGluZyA8IGhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmxvb3IgLSBjZWlsaW5nID49IGhlaWdodCkge1xuICAgICAgICAgICAgICAgIGlmIChqdXN0VGVzdCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgeDogeDAsXG4gICAgICAgICAgICAgICAgICAgIHkwOiBjZWlsaW5nLFxuICAgICAgICAgICAgICAgICAgICB5MTogY2VpbGluZ0Zsb29yLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5nZXRMYWJlbEJib3ggPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICB2YXIgbGFiZWxTdHlsZSA9IHV0aWxfMS5jbG9uZSh0aGlzLnBsb3QudGhlbWUubGFiZWwudGV4dFN0eWxlKTtcbiAgICAgICAgbGFiZWxTdHlsZS5mb250U2l6ZSA9IERFRkFVTFRfU0laRTtcbiAgICAgICAgdmFyIHRTaGFwZSA9IHRoaXMuY29udGFpbmVyLmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgYXR0cnM6IHRzbGliXzEuX19hc3NpZ24oeyB0ZXh0OiB0ZXh0LCB4OiAwLCB5OiAwIH0sIGxhYmVsU3R5bGUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGJib3ggPSB0U2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB0U2hhcGUucmVtb3ZlKCk7XG4gICAgICAgIHJldHVybiBiYm94O1xuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5maW5kKHRoaXMudmlldy5nZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbSkgeyByZXR1cm4gZ2VvbS50eXBlID09PSAnYXJlYSc7IH0pO1xuICAgIH07XG4gICAgQXJlYUxhYmVsLnByb3RvdHlwZS5nZXRGb250U2l6ZSA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9TY2FsZSkge1xuICAgICAgICAgICAgdmFyIHNjYWxlRmFjdG9yID0gdGhpcy5zY2FsZUZhY3RvcltpbmRleF07XG4gICAgICAgICAgICByZXR1cm4gREVGQVVMVF9TSVpFICogc2NhbGVGYWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIERFRkFVTFRfU0laRTtcbiAgICB9O1xuICAgIHJldHVybiBBcmVhTGFiZWw7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJlYUxhYmVsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXJlYS1sYWJlbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgYXJlYV9wb2ludF9hdXRvXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vLi4vYXJlYS9jb21wb25lbnQvbGFiZWwvYXJlYS1wb2ludC1hdXRvXCIpKTtcbnZhciBTdGFja2VkQXJlYVBvaW50QXV0b0xhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrZWRBcmVhUG9pbnRBdXRvTGFiZWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tlZEFyZWFQb2ludEF1dG9MYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvKiog5a+55aCG56ev6Z2i56ev5L2/55So6Ieq5a6a5LmJ55qE5o6S5bqPICovXG4gICAgU3RhY2tlZEFyZWFQb2ludEF1dG9MYWJlbC5wcm90b3R5cGUuc29ydExhYmVscyA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgbGFiZWxzKSB7XG4gICAgICAgIHZhciBzb3J0ZWQgPSBbXTtcbiAgICAgICAgaWYgKGxhYmVscy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzb3J0ZWQucHVzaChsYWJlbHMuc2hpZnQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhYmVscy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzb3J0ZWQucHVzaChsYWJlbHMucG9wKCkpO1xuICAgICAgICB9XG4gICAgICAgIHNvcnRlZC5wdXNoLmFwcGx5KHNvcnRlZCwgbGFiZWxzKTtcbiAgICAgICAgcmV0dXJuIHNvcnRlZDtcbiAgICB9O1xuICAgIHJldHVybiBTdGFja2VkQXJlYVBvaW50QXV0b0xhYmVsO1xufShhcmVhX3BvaW50X2F1dG9fMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGFja2VkQXJlYVBvaW50QXV0b0xhYmVsO1xuYmFzZV8xLnJlZ2lzdGVyTGFiZWxDb21wb25lbnQoJ3N0YWNrZWRBcmVhLXBvaW50LWF1dG8nLCBTdGFja2VkQXJlYVBvaW50QXV0b0xhYmVsKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFyZWEtcG9pbnQtYXV0by5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgYXJlYV9wb2ludF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2FyZWEvY29tcG9uZW50L2xhYmVsL2FyZWEtcG9pbnRcIikpO1xudmFyIFN0YWNrZWRBcmVhUG9pbnRMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTdGFja2VkQXJlYVBvaW50TGFiZWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tlZEFyZWFQb2ludExhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIHJldHVybiBTdGFja2VkQXJlYVBvaW50TGFiZWw7XG59KGFyZWFfcG9pbnRfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGFja2VkQXJlYVBvaW50TGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnc3RhY2tlZEFyZWEtcG9pbnQnLCBTdGFja2VkQXJlYVBvaW50TGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXJlYS1wb2ludC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGxpbmVfbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi9saW5lL2NvbXBvbmVudC9sYWJlbC9saW5lLWxhYmVsXCIpKTtcbi8qKlxuICog5aSN55So5omO57q/5Zu+55qEIGxhYmVs77yM5bm25L+u5pS55Y+W5YC85pa55byPXG4gKi9cbnZhciBBcmVhTGluZUxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEFyZWFMaW5lTGFiZWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQXJlYUxpbmVMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBBcmVhTGluZUxhYmVsLnByb3RvdHlwZS5nZXRTaGFwZUluZm8gPSBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgdmFyIG9yaWdpblBvaW50cyA9IHNoYXBlLmdldCgnb3JpZ2luJykucG9pbnRzO1xuICAgICAgICB2YXIgbGFzdFBvaW50ID0gb3JpZ2luUG9pbnRzW29yaWdpblBvaW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgdmFyIGNvbG9yID0gc2hhcGUuYXR0cignc3Ryb2tlJyk7XG4gICAgICAgIHZhciBzdGFja0ZpZWxkID0gdGhpcy5wbG90Lm9wdGlvbnMuc3RhY2tGaWVsZDtcbiAgICAgICAgdmFyIG5hbWUgPSBzaGFwZS5nZXQoJ29yaWdpbicpLmRhdGFbMF1bc3RhY2tGaWVsZF07XG4gICAgICAgIHZhciB5ID0gdXRpbF8xLnJlZHVjZShsYXN0UG9pbnQueSwgZnVuY3Rpb24gKHIsIGEpIHtcbiAgICAgICAgICAgIHJldHVybiByICsgYTtcbiAgICAgICAgfSwgMCkgLyB1dGlsXzEuc2l6ZShsYXN0UG9pbnQueSk7XG4gICAgICAgIHJldHVybiB7IHg6IGxhc3RQb2ludC54LCB5OiB5LCBjb2xvcjogY29sb3IsIG5hbWU6IG5hbWUgfTtcbiAgICB9O1xuICAgIHJldHVybiBBcmVhTGluZUxhYmVsO1xufShsaW5lX2xhYmVsXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXJlYUxpbmVMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpbmUtbGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFN0YWNrZWRBcmVhID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrZWRBcmVhLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFN0YWNrZWRBcmVhKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFN0YWNrZWRBcmVhLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnc3RhY2tlZEFyZWEnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgU3RhY2tlZEFyZWEuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFN0YWNrZWRBcmVhO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tlZEFyZWE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vYXJlYS9sYXllclwiKSk7XG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XG5yZXF1aXJlKFwiLi9jb21wb25lbnQvbGFiZWwvYXJlYS1wb2ludFwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbC9hcmVhLXBvaW50LWF1dG9cIik7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnZhciBTdGFja2VkQXJlYUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrZWRBcmVhTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tlZEFyZWFMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnBsb3RDb21wb25lbnRzID0gW107XG4gICAgICAgIF90aGlzLnR5cGUgPSAnc3RhY2tlZEFyZWEnO1xuICAgICAgICBfdGhpcy5iYXNlVHlwZSA9ICdhcmVhJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBTdGFja2VkQXJlYUxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdhcmVhJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU3RhY2tlZEFyZWFMYXllci5wcm90b3R5cGUuYmVmb3JlSW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZpc2libGUgPSB1dGlsXzEuZ2V0KHRoaXMub3B0aW9ucywgWydsYWJlbCcsICd2aXNpYmxlJ10pO1xuICAgICAgICB2YXIgdHlwZSA9IHV0aWxfMS5nZXQodGhpcy5vcHRpb25zLCBbJ2xhYmVsJywgJ3R5cGUnXSk7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdsaW5lJykge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMubGluZUxhYmVsID0gdGhpcy5vcHRpb25zLmxhYmVsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdhcmVhJykge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuYXJlYUxhYmVsID0gdGhpcy5vcHRpb25zLmxhYmVsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYmVmb3JlSW5pdC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgU3RhY2tlZEFyZWFMYXllci5wcm90b3R5cGUuZ2V0Q29sb3JTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHN0YWNrRmllbGQgPSB0aGlzLm9wdGlvbnMuc3RhY2tGaWVsZDtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoc3RhY2tGaWVsZCk7XG4gICAgfTtcbiAgICBTdGFja2VkQXJlYUxheWVyLnByb3RvdHlwZS5sYWJlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgbGFiZWwgPSBwcm9wcy5sYWJlbDtcbiAgICAgICAgaWYgKGxhYmVsICYmIGxhYmVsLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5saW5lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saW5lLmxhYmVsID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5wb2ludCkge1xuICAgICAgICAgICAgICAgIHRoaXMucG9pbnQubGFiZWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYXJlYS5sYWJlbCA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTdGFja2VkQXJlYUxheWVyLnByb3RvdHlwZS5hZGp1c3RBcmVhID0gZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICBlbGUuYWRqdXN0ID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgIH07XG4gICAgU3RhY2tlZEFyZWFMYXllci5wcm90b3R5cGUuYWRqdXN0TGluZSA9IGZ1bmN0aW9uIChlbGUpIHtcbiAgICAgICAgZWxlLmFkanVzdCA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIFN0YWNrZWRBcmVhTGF5ZXIucHJvdG90eXBlLmFkanVzdFBvaW50ID0gZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICBlbGUuYWRqdXN0ID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgIH07XG4gICAgU3RhY2tlZEFyZWFMYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyUGxvdENvbXBvbmVudHMoKTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnJlc3BvbnNpdmUgPSBmYWxzZTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5hZnRlclJlbmRlci5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgU3RhY2tlZEFyZWFMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmFyZWEudG9vbHRpcCA9IHt9O1xuICAgICAgICB2YXIgdG9vbHRpcE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMudG9vbHRpcDtcbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgdGhpcy5hcmVhLnRvb2x0aXAuZmllbGRzID0gdG9vbHRpcE9wdGlvbnMuZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuYXJlYS50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZWEudG9vbHRpcC5maWVsZHMgPSBbdGhpcy5vcHRpb25zLnhGaWVsZCwgdGhpcy5vcHRpb25zLnlGaWVsZCwgdGhpcy5vcHRpb25zLnN0YWNrRmllbGRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBTdGFja2VkQXJlYUxheWVyLnByb3RvdHlwZS5yZW5kZXJQbG90Q29tcG9uZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGNvbXBvbmVudHNUeXBlID0gWydhcmVhTGFiZWwnLCAnbGluZUxhYmVsJ107XG4gICAgICAgIHV0aWxfMS5lYWNoKGNvbXBvbmVudHNUeXBlLCBmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgdmFyIGNmZyA9IHRzbGliXzEuX19hc3NpZ24oeyB2aWV3OiBfdGhpcy52aWV3LCBwbG90OiBfdGhpcyB9LCBfdGhpcy5vcHRpb25zW3RdKTtcbiAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBjb21wb25lbnRfMS5nZXRQbG90Q29tcG9uZW50cyhfdGhpcywgdCwgY2ZnKTtcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICBjb21wb25lbnQucmVuZGVyKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMucGxvdENvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTdGFja2VkQXJlYUxheWVyO1xufShsYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YWNrZWRBcmVhTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdzdGFja2VkQXJlYScsIFN0YWNrZWRBcmVhTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciB0aGVtZV8yID0gcmVxdWlyZShcIi4uL2FyZWEvdGhlbWVcIik7XG50aGVtZV8xLnJlZ2lzdGVyVGhlbWUoJ3N0YWNrZWRBcmVhJywgdGhlbWVfMi5ERUZBVUxUX0FSRUFfVEhFTUUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vY29tcG9uZW50cy9sYWJlbC9iYXNlXCIpO1xudmFyIGxhYmVsX2F1dG9fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXIvY29tcG9uZW50L2xhYmVsLWF1dG9cIikpO1xuLyoqIOiHquWKqOaooeW8j+eahCBTdGFja2VkQmFyIOaVsOaNruagh+etvu+8jOS8muagueaNruWbvuW9ouWSjOaVsOaNruagh+etvuiHquWKqOS8mOWMluaVsOaNruagh+etvuW4g+WxgOWSjOagt+W8j+etiSAqL1xudmFyIFN0YWNrZWRCYXJBdXRvTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZEJhckF1dG9MYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkQmFyQXV0b0xhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKiDloIbnp6/mn7HlvaLlm77lhajpg6jlhoXnva4gKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgU3RhY2tlZEJhckF1dG9MYWJlbC5wcm90b3R5cGUuc2hvdWxkSW5TaGFwZUxhYmVscyA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICByZXR1cm4gU3RhY2tlZEJhckF1dG9MYWJlbDtcbn0obGFiZWxfYXV0b18xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YWNrZWRCYXJBdXRvTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnc3RhY2tlZC1iYXItYXV0bycsIFN0YWNrZWRCYXJBdXRvTGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwtYXV0by5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXIvY29tcG9uZW50L2xhYmVsXCIpKTtcbnZhciBTdGFja2VkQmFyTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZEJhckxhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFN0YWNrZWRCYXJMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBTdGFja2VkQmFyTGFiZWwucHJvdG90eXBlLmFkanVzdExhYmVsID0gZnVuY3Rpb24gKGxhYmVsLCBlbGVtZW50KSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWRqdXN0UG9zaXRpb24pIHtcbiAgICAgICAgICAgIHZhciBsYWJlbFJhbmdlID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHNoYXBlUmFuZ2UgPSB0aGlzLmdldEVsZW1lbnRTaGFwZUJCb3goZWxlbWVudCk7XG4gICAgICAgICAgICAvLyBsYWJlbCDmnIkgb2Zmc2V0XG4gICAgICAgICAgICBpZiAoc2hhcGVSYW5nZS5tYXhYIDw9IGxhYmVsUmFuZ2UubWF4WCkge1xuICAgICAgICAgICAgICAgIGxhYmVsLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFN0YWNrZWRCYXJMYWJlbDtcbn0obGFiZWxfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGFja2VkQmFyTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnc3RhY2tlZC1iYXInLCBTdGFja2VkQmFyTGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFN0YWNrZWRCYXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZEJhciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkQmFyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFN0YWNrZWRCYXIucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdzdGFja2VkQmFyJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFN0YWNrZWRCYXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFN0YWNrZWRCYXI7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGFja2VkQmFyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2Jhci9sYXllclwiKSk7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbFwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbC1hdXRvXCIpO1xudmFyIHZpZXdfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3ZpZXdcIik7XG52YXIgU3RhY2tlZEJhckxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrZWRCYXJMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkQmFyTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3N0YWNrZWRCYXInO1xuICAgICAgICBfdGhpcy5iYXNlVHlwZSA9ICdiYXInO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFN0YWNrZWRCYXJMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgeEF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGVUaXRsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHNwYWNpbmc6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGVUaXRsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3BhY2luZzogMTIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAndG9wLWxlZnQnLFxuICAgICAgICAgICAgICAgIG9mZnNldFk6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFN0YWNrZWRCYXJMYXllci5wcm90b3R5cGUuZ2V0Q29sb3JTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHN0YWNrRmllbGQgPSB0aGlzLm9wdGlvbnMuc3RhY2tGaWVsZDtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoc3RhY2tGaWVsZCk7XG4gICAgfTtcbiAgICBTdGFja2VkQmFyTGF5ZXIucHJvdG90eXBlLmFkanVzdEJhciA9IGZ1bmN0aW9uIChiYXIpIHtcbiAgICAgICAgYmFyLmFkanVzdCA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIFN0YWNrZWRCYXJMYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmNvbmZpZy5zY2FsZXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgbGFiZWwgPSBfYS5sYWJlbCwgeEZpZWxkID0gX2EueEZpZWxkO1xuICAgICAgICB2YXIgc2NhbGUgPSBzY2FsZXNbeEZpZWxkXTtcbiAgICAgICAgaWYgKGxhYmVsID09PSBudWxsIHx8IGxhYmVsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsYWJlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnkgPSB2aWV3XzEuZ2V0R2VvbWV0cnlCeVR5cGUodGhpcy52aWV3LCAnaW50ZXJ2YWwnKTtcbiAgICAgICAgICAgIHRoaXMuZG9SZW5kZXJMYWJlbChnZW9tZXRyeSwgdHNsaWJfMS5fX2Fzc2lnbih7IHR5cGU6ICdzdGFja2VkLWJhcicsIGZvcm1hdHRlcjogc2NhbGUuZm9ybWF0dGVyICYmIChmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHNjYWxlLmZvcm1hdHRlcih2YWx1ZSk7IH0pIH0sIHRoaXMub3B0aW9ucy5sYWJlbCkpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTdGFja2VkQmFyTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5iYXIudG9vbHRpcCA9IHt9O1xuICAgICAgICB2YXIgdG9vbHRpcE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMudG9vbHRpcDtcbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZpZWxkcykge1xuICAgICAgICAgICAgdGhpcy5iYXIudG9vbHRpcC5maWVsZHMgPSB0b29sdGlwT3B0aW9ucy5maWVsZHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcikge1xuICAgICAgICAgICAgdGhpcy5iYXIudG9vbHRpcC5jYWxsYmFjayA9IHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgIGlmICghdG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5iYXIudG9vbHRpcC5maWVsZHMgPSBbdGhpcy5vcHRpb25zLnhGaWVsZCwgdGhpcy5vcHRpb25zLnlGaWVsZCwgdGhpcy5vcHRpb25zLnN0YWNrRmllbGRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gU3RhY2tlZEJhckxheWVyO1xufShsYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YWNrZWRCYXJMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3N0YWNrZWRCYXInLCBTdGFja2VkQmFyTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGhlbWVfMSA9IHJlcXVpcmUoXCIuLi8uLi90aGVtZVwiKTtcbnZhciB0aGVtZV8yID0gcmVxdWlyZShcIi4uL2Jhci90aGVtZVwiKTtcbnRoZW1lXzEucmVnaXN0ZXJUaGVtZSgnc3RhY2tlZEJhcicsIHRoZW1lXzIuREVGQVVMVF9CQVJfVEhFTUUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vY29tcG9uZW50cy9sYWJlbC9iYXNlXCIpO1xudmFyIGxhYmVsX2F1dG9fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9jb2x1bW4vY29tcG9uZW50L2xhYmVsLWF1dG9cIikpO1xuLyoqIOiHquWKqOaooeW8j+eahCBTdGFja2VkQ29sdW1uIOaVsOaNruagh+etvu+8jOS8muagueaNruWbvuW9ouWSjOaVsOaNruagh+etvuiHquWKqOS8mOWMluaVsOaNruagh+etvuW4g+WxgOWSjOagt+W8j+etiSAqL1xudmFyIFN0YWNrZWRDb2x1bW5BdXRvTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZENvbHVtbkF1dG9MYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkQ29sdW1uQXV0b0xhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIC8qKiDloIbnp6/mn7HlvaLlm77lhajpg6jlhoXnva4gKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgU3RhY2tlZENvbHVtbkF1dG9MYWJlbC5wcm90b3R5cGUuc2hvdWxkSW5TaGFwZUxhYmVscyA9IGZ1bmN0aW9uIChsYWJlbHMpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICByZXR1cm4gU3RhY2tlZENvbHVtbkF1dG9MYWJlbDtcbn0obGFiZWxfYXV0b18xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YWNrZWRDb2x1bW5BdXRvTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnc3RhY2tlZC1jb2x1bW4tYXV0bycsIFN0YWNrZWRDb2x1bW5BdXRvTGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGFiZWwtYXV0by5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9jb2x1bW4vY29tcG9uZW50L2xhYmVsXCIpKTtcbnZhciBTdGFja2VkQ29sdW1uTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZENvbHVtbkxhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFN0YWNrZWRDb2x1bW5MYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBTdGFja2VkQ29sdW1uTGFiZWwucHJvdG90eXBlLmFkanVzdExhYmVsID0gZnVuY3Rpb24gKGxhYmVsLCBlbGVtZW50KSB7XG4gICAgICAgIHZhciBhZGp1c3RQb3NpdGlvbiA9IHRoaXMub3B0aW9ucy5hZGp1c3RQb3NpdGlvbjtcbiAgICAgICAgaWYgKGFkanVzdFBvc2l0aW9uKSB7XG4gICAgICAgICAgICB2YXIgbGFiZWxSYW5nZSA9IGxhYmVsLmdldEJCb3goKTtcbiAgICAgICAgICAgIHZhciBzaGFwZVJhbmdlID0gdGhpcy5nZXRFbGVtZW50U2hhcGVCQm94KGVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKHNoYXBlUmFuZ2UuaGVpZ2h0IDwgbGFiZWxSYW5nZS5oZWlnaHQgfHwgc2hhcGVSYW5nZS53aWR0aCA8IGxhYmVsUmFuZ2Uud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzmlofmnKznmoTpq5jluqbotoXlh7rlm77lvaLnmoTpq5jluqbmiJbogIXmlofmnKznmoTlrr3luqbotoXlh7rlm77lvaLnmoTlrr3luqblsLHkuI3mmL7npLpcbiAgICAgICAgICAgICAgICBsYWJlbC5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBTdGFja2VkQ29sdW1uTGFiZWw7XG59KGxhYmVsXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tlZENvbHVtbkxhYmVsO1xuYmFzZV8xLnJlZ2lzdGVyTGFiZWxDb21wb25lbnQoJ3N0YWNrZWQtY29sdW1uJywgU3RhY2tlZENvbHVtbkxhYmVsKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBTdGFja2VkQ29sdW1uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrZWRDb2x1bW4sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tlZENvbHVtbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBTdGFja2VkQ29sdW1uLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnc3RhY2tlZENvbHVtbic7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBTdGFja2VkQ29sdW1uLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBTdGFja2VkQ29sdW1uO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tlZENvbHVtbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgY29ubmVjdGVkX2FyZWFfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9jb21wb25lbnRzL2Nvbm5lY3RlZC1hcmVhXCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL2NvbHVtbi9sYXllclwiKSk7XG5yZXF1aXJlKFwiLi90aGVtZVwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbFwiKTtcbnJlcXVpcmUoXCIuL2NvbXBvbmVudC9sYWJlbC1hdXRvXCIpO1xudmFyIHZpZXdfMSA9IHJlcXVpcmUoXCIuLi8uLi91dGlsL3ZpZXdcIik7XG52YXIgU3RhY2tlZENvbHVtbkxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0YWNrZWRDb2x1bW5MYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkQ29sdW1uTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3N0YWNrZWRDb2x1bW4nO1xuICAgICAgICBfdGhpcy5iYXNlVHlwZSA9ICdjb2x1bW4nO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFN0YWNrZWRDb2x1bW5MYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ3JpZ2h0LXRvcCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ21pZGRsZScsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICAgICAgICAgIGFkanVzdENvbG9yOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbm5lY3RlZEFyZWE6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0cmlnZ2VyT246ICdtb3VzZWVudGVyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgU3RhY2tlZENvbHVtbkxheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNvbm5lY3RlZEFyZWEudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnRvb2x0aXAuY3Jvc3NoYWlycyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBTdGFja2VkQ29sdW1uTGF5ZXIucHJvdG90eXBlLmFmdGVyUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIC8vIOe7mOWItuWMuuWfn+i/nuaOpee7hOS7tlxuICAgICAgICBpZiAocHJvcHMuY29ubmVjdGVkQXJlYS52aXNpYmxlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3RlZEFyZWEgPSBuZXcgY29ubmVjdGVkX2FyZWFfMS5kZWZhdWx0KHRzbGliXzEuX19hc3NpZ24oeyB2aWV3OiB0aGlzLnZpZXcsIGZpZWxkOiBwcm9wcy5zdGFja0ZpZWxkLCBhbmltYXRpb246IHByb3BzLmFuaW1hdGlvbiA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWUgfSwgcHJvcHMuY29ubmVjdGVkQXJlYSkpO1xuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIFN0YWNrZWRDb2x1bW5MYXllci5wcm90b3R5cGUuZ2V0Q29sb3JTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHN0YWNrRmllbGQgPSB0aGlzLm9wdGlvbnMuc3RhY2tGaWVsZDtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlldy5nZXRTY2FsZUJ5RmllbGQoc3RhY2tGaWVsZCk7XG4gICAgfTtcbiAgICBTdGFja2VkQ29sdW1uTGF5ZXIucHJvdG90eXBlLmFkanVzdENvbHVtbiA9IGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgICAgY29sdW1uLmFkanVzdCA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIFN0YWNrZWRDb2x1bW5MYXllci5wcm90b3R5cGUucmVuZGVyTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzY2FsZXMgPSB0aGlzLmNvbmZpZy5zY2FsZXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgbGFiZWwgPSBfYS5sYWJlbCwgeUZpZWxkID0gX2EueUZpZWxkO1xuICAgICAgICB2YXIgc2NhbGUgPSBzY2FsZXNbeUZpZWxkXTtcbiAgICAgICAgaWYgKGxhYmVsICYmIGxhYmVsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IHZpZXdfMS5nZXRHZW9tZXRyeUJ5VHlwZSh0aGlzLnZpZXcsICdpbnRlcnZhbCcpO1xuICAgICAgICAgICAgdGhpcy5kb1JlbmRlckxhYmVsKGdlb21ldHJ5LCB0c2xpYl8xLl9fYXNzaWduKHsgdHlwZTogJ3N0YWNrZWQtY29sdW1uJywgZm9ybWF0dGVyOiBzY2FsZS5mb3JtYXR0ZXIgJiYgKGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gc2NhbGUuZm9ybWF0dGVyKHZhbHVlKTsgfSkgfSwgdGhpcy5vcHRpb25zLmxhYmVsKSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFN0YWNrZWRDb2x1bW5MYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbi50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMueEZpZWxkLCB0aGlzLm9wdGlvbnMueUZpZWxkLCB0aGlzLm9wdGlvbnMuc3RhY2tGaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBTdGFja2VkQ29sdW1uTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tlZENvbHVtbkxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgnc3RhY2tlZENvbHVtbicsIFN0YWNrZWRDb2x1bW5MYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aGVtZV8xID0gcmVxdWlyZShcIi4uLy4uL3RoZW1lXCIpO1xudmFyIHRoZW1lXzIgPSByZXF1aXJlKFwiLi4vY29sdW1uL3RoZW1lXCIpO1xudGhlbWVfMS5yZWdpc3RlclRoZW1lKCdzdGFja2VkQ29sdW1uJywgdGhlbWVfMi5ERUZBVUxUX0NPTFVNTl9USEVNRSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aGVtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgU3RhY2tlZFJvc2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZFJvc2UsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RhY2tlZFJvc2UoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgU3RhY2tlZFJvc2UucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICdzdGFja2VkUm9zZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBTdGFja2VkUm9zZS5wcm90b3R5cGUuZ2V0UmFkaXVzU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICByZXR1cm4gbGF5ZXIuZ2V0UmFkaXVzU2NhbGUoKTtcbiAgICB9O1xuICAgIFN0YWNrZWRSb3NlLnByb3RvdHlwZS5nZXRBbmdsZVNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmxheWVyc1swXTtcbiAgICAgICAgcmV0dXJuIGxheWVyLmdldEFuZ2xlU2NhbGUoKTtcbiAgICB9O1xuICAgIFN0YWNrZWRSb3NlLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBTdGFja2VkUm9zZTtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YWNrZWRSb3NlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3Jvc2UvbGF5ZXJcIikpO1xudmFyIFN0YWNrZWRSb3NlTGF5ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhY2tlZFJvc2VMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGFja2VkUm9zZUxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdzdGFja2VkUm9zZSc7XG4gICAgICAgIF90aGlzLmJhc2VUeXBlID0gJ3Jvc2UnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFN0YWNrZWRSb3NlTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFsaWduVGljazogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDAuNSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogNSxcbiAgICAgICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFN0YWNrZWRSb3NlTGF5ZXIucHJvdG90eXBlLmdldENvbG9yU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdGFja0ZpZWxkID0gdGhpcy5vcHRpb25zLnN0YWNrRmllbGQ7XG4gICAgICAgIHJldHVybiB0aGlzLnZpZXcuZ2V0U2NhbGVCeUZpZWxkKHN0YWNrRmllbGQpO1xuICAgIH07XG4gICAgU3RhY2tlZFJvc2VMYXllci5wcm90b3R5cGUuYWRqdXN0Um9zZUFkanVzdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9O1xuICAgIFN0YWNrZWRSb3NlTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5VG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yb3NlLnRvb2x0aXAgPSB7fTtcbiAgICAgICAgdmFyIHRvb2x0aXBPcHRpb25zID0gdGhpcy5vcHRpb25zLnRvb2x0aXA7XG4gICAgICAgIGlmICh0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgIHRoaXMucm9zZS50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLnJvc2UudG9vbHRpcC5jYWxsYmFjayA9IHRvb2x0aXBPcHRpb25zLmZvcm1hdHRlcjtcbiAgICAgICAgICAgIGlmICghdG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yb3NlLnRvb2x0aXAuZmllbGRzID0gW3RoaXMub3B0aW9ucy5yYWRpdXNGaWVsZCwgdGhpcy5vcHRpb25zLmNhdGVnb3J5RmllbGQsIHRoaXMub3B0aW9ucy5zdGFja0ZpZWxkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFN0YWNrZWRSb3NlTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU3RhY2tlZFJvc2VMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3N0YWNrZWRSb3NlJywgU3RhY2tlZFJvc2VMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGxheWVyXzEgPSByZXF1aXJlKFwiLi9sYXllclwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBTdGVwTGluZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhTdGVwTGluZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBTdGVwTGluZSgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDlpI3lhpnniLbnsbvmlrnms5VcbiAgICAgKiBAcGFyYW0gcHJvcHNcbiAgICAgKi9cbiAgICBTdGVwTGluZS5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3N0ZXAtbGluZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBTdGVwTGluZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuU3RlcExpbmVMYXllci5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gU3RlcExpbmU7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBTdGVwTGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TdGVwTGluZUxheWVyID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9saW5lL2xheWVyXCIpKTtcbnZhciBnbG9iYWxfMSA9IHJlcXVpcmUoXCIuLi8uLi9iYXNlL2dsb2JhbFwiKTtcbnZhciBTdGVwTGluZUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFN0ZXBMaW5lTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gU3RlcExpbmVMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnc3RlcC1saW5lJzsgLy8g6KaG5YaZ54i257G755qEIHR5cGVcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBTdGVwTGluZUxheWVyLmdldERlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmRlZXBNaXgoe30sIF9zdXBlci5nZXREZWZhdWx0T3B0aW9ucy5jYWxsKHRoaXMpLCB7XG4gICAgICAgICAgICBzdGVwOiAnaHYnLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTdGVwTGluZUxheWVyO1xufShsYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuU3RlcExpbmVMYXllciA9IFN0ZXBMaW5lTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdzdGVwLWxpbmUnLCBTdGVwTGluZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbW1vbl8xID0gcmVxdWlyZShcIi4uLy4uLy4uL3V0aWwvY29tbW9uXCIpO1xudmFyIExFQUZfTEFCRUxfT0ZGU0VUID0gNDtcbnZhciBNSU5fRk9OVFNJWkUgPSA4O1xuZnVuY3Rpb24gaXNMZWFmKGRhdGEsIG1heExldmVsKSB7XG4gICAgcmV0dXJuICFkYXRhLmNoaWxkcmVuIHx8IGRhdGEuZGVwdGggPj0gbWF4TGV2ZWw7XG59XG5mdW5jdGlvbiB0ZXh0V3JhcHBlcihsYWJlbCwgd2lkdGgsIGNvbnRhaW5lcikge1xuICAgIHZhciBmb250U2l6ZSA9IGxhYmVsLmF0dHIoJ2ZvbnRTaXplJyk7XG4gICAgdmFyIHRleHRDb250ZW50ID0gbGFiZWwuYXR0cigndGV4dCcpO1xuICAgIHZhciB0U2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgZm9udFNpemU6IGZvbnRTaXplLFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIHZhciB0ZXh0QXJyID0gdGV4dENvbnRlbnQuc3BsaXQoJ1xcbicpO1xuICAgIHZhciB3cmFwcGVkVGV4dEFyciA9IHRleHRBcnIubWFwKGZ1bmN0aW9uICh3cmFwcGVkVGV4dCkge1xuICAgICAgICB2YXIgdGV4dCA9ICcnO1xuICAgICAgICB2YXIgY2hhcnMgPSB3cmFwcGVkVGV4dC5zcGxpdCgnJyk7XG4gICAgICAgIHZhciBicmVha0luZGV4ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hhcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gY2hhcnNbaV07XG4gICAgICAgICAgICB0U2hhcGUuYXR0cigndGV4dCcsICh0ZXh0ICs9IGl0ZW0pKTtcbiAgICAgICAgICAgIHZhciBjdXJyZW50V2lkdGggPSB0U2hhcGUuZ2V0QkJveCgpLndpZHRoIC0gMTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50V2lkdGggPiB3aWR0aCkge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOaYr+esrOS4gOS4quWtl+espuWwseWkp+S6juWuveW6puS4jeWBmuS7u+S9leaNouihjOWkhOeQhlxuICAgICAgICAgICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVha0luZGV4LnB1c2goaSk7XG4gICAgICAgICAgICAgICAgdGV4dCA9ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb21tb25fMS5icmVha1RleHQoY2hhcnMsIGJyZWFrSW5kZXgpO1xuICAgIH0pO1xuICAgIHRTaGFwZS5yZW1vdmUoKTtcbiAgICByZXR1cm4gd3JhcHBlZFRleHRBcnIuam9pbignXFxuJyk7XG59XG5mdW5jdGlvbiB0ZXh0QWJicmV2aWF0ZSh0ZXh0LCBmb250U2l6ZSwgd2lkdGgsIGNvbnRhaW5lcikge1xuICAgIHZhciB0YWlsU2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB0ZXh0OiAnLi4uJyxcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgZm9udFNpemU6IGZvbnRTaXplLFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIHZhciB0YWlsV2lkdGggPSB0YWlsU2hhcGUuZ2V0QkJveCgpLndpZHRoO1xuICAgIHZhciB0U2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgZm9udFNpemU6IGZvbnRTaXplLFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIHZhciB0ID0gJyc7XG4gICAgdmFyIGFiYnJldmlhdGVXaWR0aCA9IHdpZHRoIC0gdGFpbFdpZHRoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgaXRlbSA9IHRleHRbaV07XG4gICAgICAgIHRTaGFwZS5hdHRyKCd0ZXh0JywgKHQgKz0gaXRlbSkpO1xuICAgICAgICB2YXIgY3VycmVudFdpZHRoID0gdFNoYXBlLmdldEJCb3goKS53aWR0aDtcbiAgICAgICAgaWYgKGN1cnJlbnRXaWR0aCA+PSBhYmJyZXZpYXRlV2lkdGgpIHtcbiAgICAgICAgICAgIHZhciBzdHJpbmcgPSB0LnN1YnN0cigwLCB0Lmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgaWYgKHN0cmluZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZyArICcuLi4nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHRTaGFwZS5yZW1vdmUoKTtcbiAgICB0YWlsU2hhcGUucmVtb3ZlKCk7XG4gICAgcmV0dXJuIHQ7XG59XG52YXIgVHJlZW1hcExhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFRyZWVtYXBMYWJlbChjZmcpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52aWV3ID0gY2ZnLnZpZXc7XG4gICAgICAgIHRoaXMucGxvdCA9IGNmZy5wbG90O1xuICAgICAgICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmdldERlZmF1bHRPcHRpb25zKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KGRlZmF1bHRPcHRpb25zLCBjZmcsIHt9KTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIFRyZWVtYXBMYWJlbC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLmdldEdlb21ldHJ5KCkubGFiZWxzQ29udGFpbmVyO1xuICAgICAgICB0aGlzLnZpZXcub24oJ2JlZm9yZXJlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmNsZWFyKCk7XG4gICAgICAgICAgICBfdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5lbGVtZW50cztcbiAgICAgICAgdXRpbF8xLmVhY2goZWxlbWVudHMsIGZ1bmN0aW9uIChlbGUpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZSA9IGVsZS5zaGFwZTtcbiAgICAgICAgICAgIHZhciBkYXRhID0gc2hhcGUuZ2V0KCdvcmlnaW4nKS5kYXRhO1xuICAgICAgICAgICAgdmFyIGlzTGVhZk5vZGUgPSBpc0xlYWYoZGF0YSwgX3RoaXMucGxvdC5vcHRpb25zLm1heExldmVsKTtcbiAgICAgICAgICAgIGlmIChkYXRhLnNob3dMYWJlbCkge1xuICAgICAgICAgICAgICAgIHZhciBzdHlsZSA9IHV0aWxfMS5jbG9uZShfdGhpcy5vcHRpb25zLnN0eWxlKTtcbiAgICAgICAgICAgICAgICB2YXIgcG9zaXRpb24gPSBfdGhpcy5nZXRQb3NpdGlvbihzaGFwZSwgaXNMZWFmTm9kZSk7XG4gICAgICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IF90aGlzLm9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgICAgIHZhciBjb250ZW50ID0gZm9ybWF0dGVyID8gZm9ybWF0dGVyKGRhdGEubmFtZSkgOiBkYXRhLm5hbWU7XG4gICAgICAgICAgICAgICAgdmFyIHRleHRCYXNlbGluZSA9IF90aGlzLmdldFRleHRCYXNlTGluZShpc0xlYWZOb2RlKTtcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBfdGhpcy5jb250YWluZXIuYWRkU2hhcGUoJ3RleHQnLCB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJzOiB1dGlsXzEuZGVlcE1peCh7fSwgc3R5bGUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IHBvc2l0aW9uLngsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBwb3NpdGlvbi55LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogY29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6ICdibGFjaycsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiB0ZXh0QmFzZWxpbmUsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiBpc0xlYWZOb2RlID8gMzAwIDogNjAwLFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2xhYmVsJyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBfdGhpcy5hZGp1c3RMYWJlbChsYWJlbCwgc2hhcGUsIGlzTGVhZk5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYWJlbC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCB0cnVlKTtcbiAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICBUcmVlbWFwTGFiZWwucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXIuZ2V0QkJveCgpO1xuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uIChzaGFwZSwgaXNMZWFmTm9kZSkge1xuICAgICAgICB2YXIgc2hhcGVCYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICB2YXIgeCA9IDA7XG4gICAgICAgIHZhciB5ID0gMDtcbiAgICAgICAgaWYgKCFpc0xlYWZOb2RlKSB7XG4gICAgICAgICAgICB4ID0gc2hhcGVCYm94LnggKyBzaGFwZUJib3gud2lkdGggLyAyO1xuICAgICAgICAgICAgeSA9IHNoYXBlQmJveC55ICsgNDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHggPSBzaGFwZUJib3gubWluWCArIHNoYXBlQmJveC53aWR0aCAvIDI7XG4gICAgICAgICAgICB5ID0gc2hhcGVCYm94Lm1pblkgKyBzaGFwZUJib3guaGVpZ2h0IC8gMjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG4gICAgfTtcbiAgICBUcmVlbWFwTGFiZWwucHJvdG90eXBlLmdldFRleHRCYXNlTGluZSA9IGZ1bmN0aW9uIChpc0xlYWZOb2RlKSB7XG4gICAgICAgIHJldHVybiBpc0xlYWZOb2RlID8gJ21pZGRsZScgOiAndG9wJztcbiAgICB9O1xuICAgIFRyZWVtYXBMYWJlbC5wcm90b3R5cGUuYWRqdXN0TGFiZWwgPSBmdW5jdGlvbiAobGFiZWwsIHNoYXBlLCBpc0xlYWZOb2RlKSB7XG4gICAgICAgIGlmIChpc0xlYWZOb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmFkanVzdExlYWZMYWJlbChsYWJlbCwgc2hhcGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGp1c3RQYXJlbnRMYWJlbChsYWJlbCwgc2hhcGUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUcmVlbWFwTGFiZWwucHJvdG90eXBlLmFkanVzdExlYWZMYWJlbCA9IGZ1bmN0aW9uIChsYWJlbCwgc2hhcGUpIHtcbiAgICAgICAgdmFyIGJib3ggPSBzaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIHZhciBsYWJlbEJCb3ggPSBsYWJlbC5nZXRCQm94KCk7XG4gICAgICAgIHZhciBsYWJlbFRleHQgPSB1dGlsXzEuY2xvbmUobGFiZWwuYXR0cigndGV4dCcpKTtcbiAgICAgICAgdmFyIHNpemVPZmZzZXQgPSAyO1xuICAgICAgICB2YXIgZm9udFNpemUgPSBNYXRoLm1heChsYWJlbC5hdHRyKCdmb250U2l6ZScpIC0gc2l6ZU9mZnNldCwgTUlOX0ZPTlRTSVpFKTtcbiAgICAgICAgdmFyIGNlbnRlclggPSBiYm94LnggKyBiYm94LndpZHRoIC8gMjtcbiAgICAgICAgdmFyIGNlbnRlclkgPSBiYm94LnkgKyBiYm94LmhlaWdodCAvIDI7XG4gICAgICAgIGxhYmVsLmF0dHIoe1xuICAgICAgICAgICAgeDogY2VudGVyWCxcbiAgICAgICAgICAgIHk6IGNlbnRlclksXG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIGxpbmVIZWlnaHQ6IGZvbnRTaXplLFxuICAgICAgICAgICAgZm9udFNpemU6IGZvbnRTaXplLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHdyYXBwZXJXaWR0aCA9IGJib3gud2lkdGggLSBMRUFGX0xBQkVMX09GRlNFVCAqIDI7XG4gICAgICAgIGlmIChsYWJlbEJCb3gud2lkdGggPiBiYm94LndpZHRoICYmIGxhYmVsQkJveC5oZWlnaHQgPiBiYm94LmhlaWdodCkge1xuICAgICAgICAgICAgbGFiZWwuYXR0cigndGV4dCcsICcnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh3cmFwcGVyV2lkdGggPCBmb250U2l6ZSkge1xuICAgICAgICAgICAgbGFiZWwuYXR0cigndGV4dCcsICcnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFiZWxCQm94LndpZHRoID4gYmJveC53aWR0aCkge1xuICAgICAgICAgICAgdmFyIHdyYXBwZWRUZXh0ID0gdGV4dFdyYXBwZXIobGFiZWwsIHdyYXBwZXJXaWR0aCwgdGhpcy5jb250YWluZXIpO1xuICAgICAgICAgICAgbGFiZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogbGFiZWwuYXR0cignZm9udFNpemUnKSxcbiAgICAgICAgICAgICAgICB0ZXh0OiB3cmFwcGVkVGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHRlbV9iYm94ID0gbGFiZWwuZ2V0QkJveCgpO1xuICAgICAgICAgICAgaWYgKHRlbV9iYm94LmhlaWdodCA+IGJib3guaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHRleHQgPSB0ZXh0QWJicmV2aWF0ZShsYWJlbFRleHQsIGZvbnRTaXplLCB3cmFwcGVyV2lkdGgsIHRoaXMuY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICBsYWJlbC5hdHRyKCd0ZXh0JywgdGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRyZWVtYXBMYWJlbC5wcm90b3R5cGUuYWRqdXN0UGFyZW50TGFiZWwgPSBmdW5jdGlvbiAobGFiZWwsIHNoYXBlKSB7XG4gICAgICAgIHZhciBzaGFwZUJib3ggPSBzaGFwZS5nZXRCQm94KCk7XG4gICAgICAgIHZhciB3cmFwcGVyV2lkdGggPSBzaGFwZUJib3gud2lkdGggLSBMRUFGX0xBQkVMX09GRlNFVCAqIDI7XG4gICAgICAgIGlmIChsYWJlbC5nZXRCQm94KCkud2lkdGggPiB3cmFwcGVyV2lkdGgpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0ID0gdGV4dEFiYnJldmlhdGUobGFiZWwuYXR0cigndGV4dCcpLCBsYWJlbC5hdHRyKCdmb250U2l6ZScpLCB3cmFwcGVyV2lkdGgsIHRoaXMuY29udGFpbmVyKTtcbiAgICAgICAgICAgIGxhYmVsLmF0dHIoJ3RleHQnLCB0ZXh0KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRoZW1lID0gdGhpcy5wbG90LnRoZW1lO1xuICAgICAgICB2YXIgbGFiZWxTdHlsZSA9IHRoZW1lLmxhYmVsLnN0eWxlO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2Zmc2V0WDogMCxcbiAgICAgICAgICAgIG9mZnNldFk6IDAsXG4gICAgICAgICAgICBzdHlsZTogdXRpbF8xLmNsb25lKGxhYmVsU3R5bGUpLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgVHJlZW1hcExhYmVsLnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5maW5kKHRoaXMudmlldy5nZW9tZXRyaWVzLCBmdW5jdGlvbiAoZ2VvbSkgeyByZXR1cm4gZ2VvbS50eXBlID09PSAncG9seWdvbic7IH0pO1xuICAgIH07XG4gICAgcmV0dXJuIFRyZWVtYXBMYWJlbDtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUcmVlbWFwTGFiZWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYWJlbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVWRU5UX01BUFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5FVkVOVF9NQVA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvbkV2ZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLm9uRXZlbnQ7IH0gfSk7XG52YXIgY29tcG9uZW50TWFwID0ge1xuICAgIHJlY3Q6ICdwb2x5Z29uJyxcbiAgICBicmVhZGNydW1iOiAnYnJlYWRjcnVtYicsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgVHJlZW1hcCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUcmVlbWFwLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRyZWVtYXAoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgVHJlZW1hcC5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3RyZWVtYXAnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgVHJlZW1hcC5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gVHJlZW1hcDtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRyZWVtYXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucm9sbGluZ1VwID0gZXhwb3J0cy5kcmlsbGluZ0Rvd24gPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ191dGlsXzEgPSByZXF1aXJlKFwiLi4vLi4vLi4vdXRpbC9nLXV0aWxcIik7XG52YXIgdWxNYXRyaXggPSBbMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMV07XG52YXIgZHVyYXRpb24gPSA0MDA7XG52YXIgZWFzaW5nID0gJ2Vhc2VRdWFkSW5PdXQnO1xuZnVuY3Rpb24gZHJpbGxpbmdEb3duKHRhcmdldCwgdmlldywgY2FsbGJhY2spIHtcbiAgICB2YXIgcmVjdCA9IGdldFJlY3QodGFyZ2V0KTtcbiAgICB2YXIgcmFuZ2UgPSBnZXRSYW5nZSh2aWV3KTtcbiAgICB2YXIgeFJhdGlvID0gcmFuZ2Uud2lkdGggLyByZWN0LndpZHRoO1xuICAgIHZhciB5UmF0aW8gPSByYW5nZS5oZWlnaHQgLyByZWN0LmhlaWdodDtcbiAgICB2YXIgb2Zmc2V0WCA9IChyYW5nZS5taW5YIC0gcmVjdC5taW5YKSAqIHhSYXRpbztcbiAgICB2YXIgb2Zmc2V0WSA9IChyYW5nZS5taW5ZIC0gcmVjdC5taW5ZKSAqIHlSYXRpbztcbiAgICB2YXIgdHJhbnNmb3JtTWF0cml4ID0gZ191dGlsXzEudHJhbnNmb3JtKFtcbiAgICAgICAgWydzJywgeFJhdGlvLCB5UmF0aW9dLFxuICAgICAgICBbJ3QnLCBvZmZzZXRYLCBvZmZzZXRZXSxcbiAgICBdKTtcbiAgICB2YXIgZ2VvbWV0cnkgPSB2aWV3Lmdlb21ldHJpZXNbMF07XG4gICAgaGlkZUxhYmVsKGdlb21ldHJ5KTtcbiAgICB2YXIgdGVtX2NvbnRhaW5lciA9IHZpZXcuYmFja2dyb3VuZEdyb3VwLmFkZEdyb3VwKCk7XG4gICAgdGVtX2NvbnRhaW5lci5zZXQoJ3pJbmRleCcsIC0xMDApO1xuICAgIHRlbV9jb250YWluZXIuc2V0Q2xpcCh7XG4gICAgICAgIHR5cGU6ICdyZWN0JyxcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgIHg6IHJhbmdlLm1pblgsXG4gICAgICAgICAgICB5OiByYW5nZS5taW5ZLFxuICAgICAgICAgICAgd2lkdGg6IHJhbmdlLndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiByYW5nZS5oZWlnaHQsXG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgdmFyIHRlbV9zaGFwZXMgPSBnZXRUZW1TaGFwZXMoZ2VvbWV0cnksIHRlbV9jb250YWluZXIpO1xuICAgIGdlb21ldHJ5LmNvbnRhaW5lci5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgdmlldy5jYW52YXMuZHJhdygpO1xuICAgIGNhbGxiYWNrKCk7XG4gICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICB1dGlsXzEuZWFjaCh0ZW1fc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUsIGluZGV4KSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICBzaGFwZS5hbmltYXRlKHsgbWF0cml4OiB0cmFuc2Zvcm1NYXRyaXggfSwgZHVyYXRpb24sIGVhc2luZywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0ZW1fY29udGFpbmVyLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICB2aWV3LmNhbnZhcy5kcmF3KCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaGFwZS5hbmltYXRlKGdfdXRpbF8xLnRyYW5zZm9ybSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZ2VvbWV0cnkgPSB2aWV3Lmdlb21ldHJpZXNbMF07XG4gICAgICAgIGhpZGVMYWJlbChnZW9tZXRyeSk7XG4gICAgICAgIHZhciBzaGFwZXMgPSBnZW9tZXRyeS5nZXRTaGFwZXMoKTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgICAgIHNoYXBlLmF0dHIoJ29wYWNpdHknLCAwKTtcbiAgICAgICAgICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICB9LCBkdXJhdGlvbiwgZWFzaW5nKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBjb250YWluZXIgPSBnZW9tZXRyeS5jb250YWluZXI7XG4gICAgICAgIGNvbnRhaW5lci5zdG9wQW5pbWF0ZSgpO1xuICAgICAgICBjb250YWluZXIuc2V0KCd2aXNpYmxlJywgdHJ1ZSk7XG4gICAgICAgIGNvbnRhaW5lci5hdHRyKCdtYXRyaXgnLCB1dGlsXzEuY2xvbmUodWxNYXRyaXgpKTtcbiAgICAgICAgZ191dGlsXzEuZ3JvdXBUcmFuc2Zvcm0oY29udGFpbmVyLCBbXG4gICAgICAgICAgICBbJ3MnLCByZWN0LndpZHRoIC8gcmFuZ2Uud2lkdGgsIHJlY3QuaGVpZ2h0IC8gcmFuZ2UuaGVpZ2h0XSxcbiAgICAgICAgICAgIFsndCcsIHJlY3QubWluWCwgcmVjdC5taW5ZXSxcbiAgICAgICAgXSk7XG4gICAgICAgIHZhciBtYXRyaXggPSB1dGlsXzEuY2xvbmUodWxNYXRyaXgpO1xuICAgICAgICBnZW9tZXRyeS5jb250YWluZXIuYW5pbWF0ZSh7XG4gICAgICAgICAgICBtYXRyaXg6IG1hdHJpeCxcbiAgICAgICAgfSwgZHVyYXRpb24sIGVhc2luZywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2hvd0xhYmVsKGdlb21ldHJ5KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZpZXcuY2FudmFzLmRyYXcoKTtcbiAgICB9LCAxNik7XG59XG5leHBvcnRzLmRyaWxsaW5nRG93biA9IGRyaWxsaW5nRG93bjtcbmZ1bmN0aW9uIGdldFRlbVNoYXBlcyhnZW9tZXRyeSwgY29udGFpbmVyKSB7XG4gICAgdmFyIHNoYXBlcyA9IGdlb21ldHJ5LmdldFNoYXBlcygpO1xuICAgIHZhciB0ZW1fc2hhcGVzID0gW107XG4gICAgdXRpbF8xLmVhY2goc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgdmFyIHMgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdXRpbF8xLmRlZXBNaXgoe30sIHNoYXBlLmF0dHJzLCB7IGNhcHR1cmU6IGZhbHNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgdGVtX3NoYXBlcy5wdXNoKHMpO1xuICAgIH0pO1xuICAgIHJldHVybiB0ZW1fc2hhcGVzO1xufVxuZnVuY3Rpb24gcm9sbGluZ1VwKG5hbWUsIHZpZXcsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGdlb21ldHJ5ID0gdmlldy5nZW9tZXRyaWVzWzBdO1xuICAgIGhpZGVMYWJlbChnZW9tZXRyeSk7XG4gICAgdmFyIGNvbnRhaW5lciA9IGdlb21ldHJ5LmNvbnRhaW5lcjtcbiAgICBjb250YWluZXIuYXR0cignbWF0cml4JywgdXRpbF8xLmNsb25lKHVsTWF0cml4KSk7XG4gICAgdmFyIHRlbV9jb250YWluZXIgPSB2aWV3LmJhY2tncm91bmRHcm91cC5hZGRHcm91cCgpO1xuICAgIHRlbV9jb250YWluZXIuc2V0KCd6SW5kZXgnLCAtMTAwKTtcbiAgICB2YXIgdGVtX3NoYXBlcyA9IGdldFRlbVNoYXBlcyhnZW9tZXRyeSwgdGVtX2NvbnRhaW5lcik7XG4gICAgY29udGFpbmVyLnNldCgndmlzaWJsZScsIGZhbHNlKTtcbiAgICB2aWV3LmNhbnZhcy5kcmF3KCk7XG4gICAgY2FsbGJhY2soKTtcbiAgICBnZW9tZXRyeSA9IHZpZXcuZ2VvbWV0cmllc1swXTtcbiAgICBoaWRlTGFiZWwoZ2VvbWV0cnkpO1xuICAgIGNvbnRhaW5lciA9IGdlb21ldHJ5LmNvbnRhaW5lcjtcbiAgICB2YXIgc2hhcGUgPSBmaW5kU2hhcGVCeU5hbWUoZ2VvbWV0cnkuZ2V0U2hhcGVzKCksIG5hbWUpOyAvL+agueaNrm5hbWXojrflvpfkuIrkuIDnuqdzaGFwZVxuICAgIHZhciByZWN0ID0gZ2V0UmVjdChzaGFwZSk7XG4gICAgdmFyIHJhbmdlID0gZ2V0UmFuZ2Uodmlldyk7XG4gICAgdmFyIGNvbnRhaW5lclBhcmVudCA9IGNvbnRhaW5lci5nZXQoJ3BhcmVudCcpO1xuICAgIGlmICghY29udGFpbmVyUGFyZW50LmdldCgnY2xpcFNoYXBlJykpIHtcbiAgICAgICAgY29udGFpbmVyLnNldENsaXAoe1xuICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICB4OiByYW5nZS5taW5YLFxuICAgICAgICAgICAgICAgIHk6IHJhbmdlLm1pblksXG4gICAgICAgICAgICAgICAgd2lkdGg6IHJhbmdlLndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogcmFuZ2UuaGVpZ2h0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHNocmlua1RlbXAodGVtX2NvbnRhaW5lciwgdGVtX3NoYXBlcywgcmVjdCwgcmFuZ2UpO1xuICAgIHZhciB4UmF0aW8gPSByYW5nZS53aWR0aCAvIHJlY3Qud2lkdGg7XG4gICAgdmFyIHlSYXRpbyA9IHJhbmdlLmhlaWdodCAvIHJlY3QuaGVpZ2h0O1xuICAgIHZhciBvZmZzZXRYID0gKHJhbmdlLm1pblggLSByZWN0Lm1pblgpICogeFJhdGlvO1xuICAgIHZhciBvZmZzZXRZID0gKHJhbmdlLm1pblkgLSByZWN0Lm1pblkpICogeVJhdGlvO1xuICAgIHZhciB0cmFuc2Zvcm1NYXRyaXggPSBnX3V0aWxfMS50cmFuc2Zvcm0oW1xuICAgICAgICBbJ3MnLCB4UmF0aW8sIHlSYXRpb10sXG4gICAgICAgIFsndCcsIG9mZnNldFgsIG9mZnNldFldLFxuICAgIF0pO1xuICAgIGNvbnRhaW5lci5zZXRNYXRyaXgodHJhbnNmb3JtTWF0cml4KTtcbiAgICBjb250YWluZXIuc2V0KCd2aXNpYmxlJywgdHJ1ZSk7XG4gICAgY29udGFpbmVyLmFuaW1hdGUoe1xuICAgICAgICBtYXRyaXg6IHVsTWF0cml4LFxuICAgIH0sIGR1cmF0aW9uLCBlYXNpbmcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2hvd0xhYmVsKGdlb21ldHJ5KTtcbiAgICB9KTtcbn1cbmV4cG9ydHMucm9sbGluZ1VwID0gcm9sbGluZ1VwO1xuZnVuY3Rpb24gZmluZFNoYXBlQnlOYW1lKHNoYXBlcywgbikge1xuICAgIHZhciBzaGFwZTtcbiAgICB1dGlsXzEuZWFjaChzaGFwZXMsIGZ1bmN0aW9uIChzKSB7XG4gICAgICAgIHZhciBuYW1lID0gcy5nZXQoJ29yaWdpbicpLmRhdGEubmFtZTtcbiAgICAgICAgaWYgKG5hbWUgPT09IG4pIHtcbiAgICAgICAgICAgIHNoYXBlID0gcztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzaGFwZTtcbn1cbmZ1bmN0aW9uIGdldFJhbmdlKHZpZXcpIHtcbiAgICB2YXIgdmlld1JhbmdlID0gdmlldy5jb29yZGluYXRlQkJveDtcbiAgICB2YXIgcmFuZ2UgPSB7XG4gICAgICAgIG1pblg6IHZpZXdSYW5nZS5taW5YLFxuICAgICAgICBtaW5ZOiB2aWV3UmFuZ2UubWluWSxcbiAgICAgICAgY2VudGVyWDogKHZpZXdSYW5nZS5tYXhYIC0gdmlld1JhbmdlLm1pblgpIC8gMixcbiAgICAgICAgY2VudGVyWTogKHZpZXdSYW5nZS5tYXhZIC0gdmlld1JhbmdlLm1pblkpIC8gMixcbiAgICAgICAgd2lkdGg6IHZpZXdSYW5nZS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiB2aWV3UmFuZ2UuaGVpZ2h0LFxuICAgIH07XG4gICAgcmV0dXJuIHJhbmdlO1xufVxuZnVuY3Rpb24gZ2V0UmVjdChzaGFwZSkge1xuICAgIHZhciBwYXRoID0gc2hhcGUuYXR0cigncGF0aCcpO1xuICAgIHZhciB4MCA9IHBhdGhbMF1bMV07XG4gICAgdmFyIHkxID0gcGF0aFswXVsyXTtcbiAgICB2YXIgeDEgPSBwYXRoWzFdWzFdO1xuICAgIHZhciB5MCA9IHBhdGhbMl1bMl07XG4gICAgdmFyIHJlY3QgPSB7XG4gICAgICAgIG1pblg6IHgwLFxuICAgICAgICBtaW5ZOiB5MCxcbiAgICAgICAgY2VudGVyWDogKHgxIC0geDApIC8gMixcbiAgICAgICAgY2VudGVyWTogKHkxIC0geTApIC8gMixcbiAgICAgICAgd2lkdGg6IE1hdGguYWJzKHgxIC0geDApLFxuICAgICAgICBoZWlnaHQ6IE1hdGguYWJzKHkxIC0geTApLFxuICAgIH07XG4gICAgcmV0dXJuIHJlY3Q7XG59XG5mdW5jdGlvbiBzaHJpbmtUZW1wKGNvbnRhaW5lciwgc2hhcGVzLCByZWN0LCByYW5nZSkge1xuICAgIHZhciB4UmF0aW8gPSByZWN0LndpZHRoIC8gcmFuZ2Uud2lkdGg7XG4gICAgdmFyIHlSYXRpbyA9IHJlY3QuaGVpZ2h0IC8gcmFuZ2UuaGVpZ2h0O1xuICAgIHZhciB0cmFuc2Zvcm1NYXRyaXggPSBnX3V0aWxfMS50cmFuc2Zvcm0oW1xuICAgICAgICBbJ3MnLCB4UmF0aW8sIHlSYXRpb10sXG4gICAgICAgIFsndCcsIHJlY3QubWluWCwgcmVjdC5taW5ZXSxcbiAgICBdKTtcbiAgICBjb250YWluZXIuYW5pbWF0ZSh7IG1hdHJpeDogdHJhbnNmb3JtTWF0cml4IH0sIGR1cmF0aW9uLCBlYXNpbmcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29udGFpbmVyLnJlbW92ZSgpO1xuICAgIH0pO1xuICAgIHV0aWxfMS5lYWNoKHNoYXBlcywgZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHNoYXBlLmFuaW1hdGUoe1xuICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgfSwgZHVyYXRpb24sIGVhc2luZyk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBoaWRlTGFiZWwoZ2VvbWV0cnkpIHtcbiAgICB2YXIgbGFiZWxDb250YWluZXIgPSBnZW9tZXRyeS5sYWJlbHNDb250YWluZXI7XG4gICAgbGFiZWxDb250YWluZXIuc2V0KCd2aXNpYmxlJywgZmFsc2UpO1xufVxuZnVuY3Rpb24gc2hvd0xhYmVsKGdlb21ldHJ5KSB7XG4gICAgdmFyIGxhYmVsQ29udGFpbmVyID0gZ2VvbWV0cnkubGFiZWxzQ29udGFpbmVyO1xuICAgIGxhYmVsQ29udGFpbmVyLnNldCgndmlzaWJsZScsIHRydWUpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5pbWF0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYnJlYWRjcnVtYl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2NvbXBvbmVudHMvYnJlYWRjcnVtYlwiKSk7XG52YXIgYmFzZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uLy4uL2ludGVyYWN0aW9uL2Jhc2VcIikpO1xudmFyIGJib3hfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi91dGlsL2Jib3hcIikpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGFuaW1hdGlvbl8xID0gcmVxdWlyZShcIi4vYW5pbWF0aW9uXCIpO1xudmFyIERFRkFVTFRfSVRFTV9XSURUSCA9IDEwMDtcbnZhciBERUZBVUxUX0lURU1fSEVJR0hUID0gMzA7XG52YXIgUEFERElOR19UT1AgPSAxMDtcbnZhciBnZXRWYWxpZEJyZWFkY3J1bWJDb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgaWYgKGNmZyA9PT0gdm9pZCAwKSB7IGNmZyA9IHt9OyB9XG4gICAgdmFyIF9jZmcgPSB0c2xpYl8xLl9fYXNzaWduKHsgeDogMCwgeTogMCwgc3RhcnROb2RlOiB7IG5hbWU6ICdyb290JyB9LCBpdGVtV2lkdGg6IERFRkFVTFRfSVRFTV9XSURUSCwgaXRlbUhlaWdodDogREVGQVVMVF9JVEVNX0hFSUdIVCwgcGFkZGluZzogWzAsIDAsIDAsIDBdIH0sIGNmZyk7XG4gICAgcmV0dXJuIF9jZmc7XG59O1xudmFyIERyaWxsRG93bkludGVyYWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKERyaWxsRG93bkludGVyYWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIERyaWxsRG93bkludGVyYWN0aW9uKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIERyaWxsRG93bkludGVyYWN0aW9uLmdldEludGVyYWN0aW9uUmFuZ2UgPSBmdW5jdGlvbiAobGF5ZXJSYW5nZSwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgdmFyIGNvbmZpZyA9IGdldFZhbGlkQnJlYWRjcnVtYkNvbmZpZyhpbnRlcmFjdGlvbik7XG4gICAgICAgIHZhciBfYSA9IGNvbmZpZy5wYWRkaW5nLCBwYWRkaW5nVG9wID0gX2FbMF0sIHBhZGRpbmdCb3R0b20gPSBfYVsxXTtcbiAgICAgICAgaWYgKGxheWVyUmFuZ2UpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYmJveF8xLmRlZmF1bHQobGF5ZXJSYW5nZS5taW5YLCBsYXllclJhbmdlLm1heFkgLSBjb25maWcuaXRlbUhlaWdodCAtIHBhZGRpbmdUb3AgLSBwYWRkaW5nQm90dG9tLCBsYXllclJhbmdlLndpZHRoLCBjb25maWcuaXRlbUhlaWdodCArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBkYXRhID0gZXYuZGF0YS5kYXRhO1xuICAgICAgICBpZiAoZGF0YS5jaGlsZHJlbikge1xuICAgICAgICAgICAgdGhpcy5wYXJlbnROb2RlID0ge1xuICAgICAgICAgICAgICAgIGNvbG9yOiBldi50YXJnZXQuYXR0cignZmlsbCcpLFxuICAgICAgICAgICAgICAgIHNoYXBlOiBldi50YXJnZXQsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiB1dGlsXzEuY2xvbmUodGhpcy5jdXJyZW50Tm9kZS5uYW1lKSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHV0aWxfMS5jbG9uZSh0aGlzLmN1cnJlbnROb2RlLnZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGRlcHRoOiB1dGlsXzEuY2xvbmUodGhpcy5jdXJyZW50RGVwdGgpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudERlcHRoKys7XG4gICAgICAgICAgICBhbmltYXRpb25fMS5kcmlsbGluZ0Rvd24oZXYudGFyZ2V0LCB0aGlzLnZpZXcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy51cGRhdGUoZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIGlmICghdXRpbF8xLmhhc0tleSh0aGlzLmNhY2hlLCBkYXRhLm5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlW2RhdGEubmFtZV0gPSBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0ZW1wb0RhdGEgPSB0aGlzLnBsb3QuZ2V0VHJlZW1hcERhdGEoZGF0YSwgZGF0YS5kZXB0aCk7XG4gICAgICAgIHRoaXMudmlldy5jaGFuZ2VEYXRhKHRlbXBvRGF0YSk7XG4gICAgICAgIHRoaXMuYWRqdXN0U2NhbGUodGhpcy5jdXJyZW50RGVwdGgpO1xuICAgICAgICB0aGlzLmN1cnJlbnROb2RlID0gZGF0YTtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9O1xuICAgIERyaWxsRG93bkludGVyYWN0aW9uLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmJyZWFkY3J1bWIpIHtcbiAgICAgICAgICAgIHZhciBpdGVtcyA9IHRoaXMuZ2V0SXRlbXMoKTtcbiAgICAgICAgICAgIHRoaXMuYnJlYWRjcnVtYi51cGRhdGUoe1xuICAgICAgICAgICAgICAgIGl0ZW1zOiBpdGVtcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5icmVhZGNydW1iLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdEdlb21ldHJ5KCk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlID0ge307XG4gICAgICAgICAgICB0aGlzLnNhdmVPcmlnaW5NYXBwaW5nKCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMucGxvdC5jYW52YXMuYWRkR3JvdXAoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGFydE5vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0Tm9kZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3Jvb3QnLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zdGFydE5vZGUubmFtZSA9PT0gJ3Jvb3QnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydE5vZGVOYW1lID0gdXRpbF8xLmhhc0tleSh0aGlzLnBsb3Qub3B0aW9ucy5kYXRhLCAnbmFtZScpID8gdGhpcy5wbG90Lm9wdGlvbnMuZGF0YS5uYW1lIDogJ3Jvb3QnO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE5vZGUgPSB0aGlzLnBsb3Qub3B0aW9ucy5kYXRhO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudERlcHRoID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnROb2RlTmFtZSA9IHRoaXMuc3RhcnROb2RlLm5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Tm9kZSA9IHRoaXMuc3RhcnROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy55ID0gdGhpcy52aWV3LmNvb3JkaW5hdGVCQm94Lm1heFkgKyBQQURESU5HX1RPUDtcbiAgICAgICAgICAgIHRoaXMuYnJlYWRjcnVtYiA9IG5ldyBicmVhZGNydW1iXzEuZGVmYXVsdCh7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiB0aGlzLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgIHk6IHRoaXMueSxcbiAgICAgICAgICAgICAgICBpdGVtczogdGhpcy5nZXRJdGVtcygpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmJyZWFkY3J1bWIuaW5pdCgpO1xuICAgICAgICAgICAgdGhpcy5icmVhZGNydW1iLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5wbG90LmNhbnZhcy5kcmF3KCk7XG4gICAgICAgICAgICB0aGlzLmxheW91dCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub25JbnRlcmFjdGlvbigpO1xuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBEcmlsbERvd25JbnRlcmFjdGlvbi5wcm90b3R5cGUubGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3VycmVudFdpZHRoID0gdGhpcy5jb250YWluZXIuZ2V0QkJveCgpLndpZHRoO1xuICAgICAgICB2YXIgeCA9ICh0aGlzLnBsb3Qud2lkdGggLSBjdXJyZW50V2lkdGgpIC8gMjtcbiAgICAgICAgdGhpcy5icmVhZGNydW1iLnVwZGF0ZSh7XG4gICAgICAgICAgICB4OiB4LFxuICAgICAgICAgICAgeTogdGhpcy55LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5icmVhZGNydW1iLnJlbmRlcigpO1xuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldEl0ZW1zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudE5vZGUubmFtZSAmJiB0aGlzLmN1cnJlbnROb2RlLm5hbWUgPT09IHRoaXMuc3RhcnROb2RlTmFtZSkge1xuICAgICAgICAgICAgdmFyIHJvb3RJdGVtID0gdGhpcy5nZXRSb290SXRlbSgpO1xuICAgICAgICAgICAgaXRlbXMucHVzaChyb290SXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpdGVtcyA9IFtdO1xuICAgICAgICAgICAgdmFyIHBhcmVudHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZmluZFBhcmVudCh0aGlzLmN1cnJlbnROb2RlLCBwYXJlbnRzKTtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2godGhpcy5nZXRSb290SXRlbSgpKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKHBhcmVudHMsIGZ1bmN0aW9uIChwLCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goeyBrZXk6IFN0cmluZyhpbmRleCArIDIpLCB0ZXh0OiBwLm5hbWUsIGRhdGE6IHAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goeyBrZXk6IFN0cmluZyhwYXJlbnRzLmxlbmd0aCArIDIpLCB0ZXh0OiB0aGlzLmN1cnJlbnROb2RlLm5hbWUsIGRhdGE6IHRoaXMuY3VycmVudE5vZGUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLmZpbmRQYXJlbnQgPSBmdW5jdGlvbiAoZGF0YSwgcGFyZW50cykge1xuICAgICAgICBpZiAoZGF0YS5wYXJlbnQpIHtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaGFzS2V5KHRoaXMuY2FjaGUsIGRhdGEucGFyZW50Lm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKHRoaXMuY2FjaGVbZGF0YS5wYXJlbnQubmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKGRhdGEucGFyZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmluZFBhcmVudChkYXRhLnBhcmVudCwgcGFyZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERyaWxsRG93bkludGVyYWN0aW9uLnByb3RvdHlwZS5vbkludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5vbignY2xpY2snLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciB0YXJnZXRQYXJlbnQgPSBldi50YXJnZXQuZ2V0KCdwYXJlbnQnKTtcbiAgICAgICAgICAgIGlmICh0YXJnZXRQYXJlbnQgJiYgdGFyZ2V0UGFyZW50LmdldCgnY2xhc3MnKSA9PT0gJ2l0ZW0tZ3JvdXAnKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGFfMSA9IHRhcmdldFBhcmVudC5nZXQoJ2RhdGEnKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YV8xLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFfMS50ZXh0ID09PSBfdGhpcy5zdGFydE5vZGVOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0RGVwdGggPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy/lj6rmnInliY3lkI5kZXB0aOebuOmCu+aJjeaJp+ihjOS4iuWNt+WKqOeUu++8jOWQpuWImeebtOaOpeabtOaWsFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLmN1cnJlbnREZXB0aCAtIDEgPT09IHRhcmdldERlcHRoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uXzEucm9sbGluZ1VwKF90aGlzLmN1cnJlbnROb2RlLm5hbWUsIF90aGlzLnZpZXcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlUm9vdChkYXRhXzEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlUm9vdChkYXRhXzEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY3VycmVudERlcHRoID0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChfdGhpcy5jdXJyZW50Tm9kZSA9PT0gZGF0YV8xLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c0RlcHRoID0gdXRpbF8xLmNsb25lKF90aGlzLmN1cnJlbnREZXB0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50RGVwdGggPSBwYXJzZUludChkYXRhXzEua2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c0RlcHRoIC0gMSA9PT0gX3RoaXMuY3VycmVudERlcHRoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uXzEucm9sbGluZ1VwKF90aGlzLmN1cnJlbnROb2RlLm5hbWUsIF90aGlzLnZpZXcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMudXBkYXRlKGRhdGFfMS5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnVwZGF0ZShkYXRhXzEuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLmdldFJvb3RJdGVtID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcm9vdERhdGEgPSB0aGlzLnBsb3Qub3B0aW9ucy5kYXRhO1xuICAgICAgICB2YXIgcm9vdE5hbWUgPSB1dGlsXzEuaGFzS2V5KHJvb3REYXRhLCAnbmFtZScpID8gcm9vdERhdGEubmFtZSA6ICdyb290JztcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnMScsIHRleHQ6IHJvb3ROYW1lLCBkYXRhOiB0aGlzLnBsb3Qucm9vdERhdGEgfTtcbiAgICB9O1xuICAgIERyaWxsRG93bkludGVyYWN0aW9uLnByb3RvdHlwZS5zYXZlT3JpZ2luTWFwcGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hID0gdGhpcy5wbG90Lm9wdGlvbnMsIGNvbG9yRmllbGQgPSBfYS5jb2xvckZpZWxkLCBjb2xvcnMgPSBfYS5jb2xvcnM7XG4gICAgICAgIHZhciBtYXBwaW5nSW5mbyA9IHsgZmllbGQ6IGNvbG9yRmllbGQsIHZhbHVlczogY29sb3JzIH07XG4gICAgICAgIHRoaXMub3JpZ2luTWFwcGluZyA9IG1hcHBpbmdJbmZvO1xuICAgIH07XG4gICAgRHJpbGxEb3duSW50ZXJhY3Rpb24ucHJvdG90eXBlLmFkanVzdFNjYWxlID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciB2aWV3ID0gdGhpcy52aWV3O1xuICAgICAgICAvLyDmoLnmja7lvZPliY3lsYLnuqfnoa7lrpptYXBwaW5n6YWN572u6aG5XG4gICAgICAgIGlmICh0aGlzLm1hcHBpbmcgJiYgdXRpbF8xLmhhc0tleSh0aGlzLm1hcHBpbmcsIFN0cmluZyhpbmRleCkpKSB7XG4gICAgICAgICAgICB2YXIgbWFwcGluZ0NmZyA9IHV0aWxfMS5jbG9uZSh0aGlzLm1hcHBpbmdbaW5kZXhdKTtcbiAgICAgICAgICAgIGlmIChtYXBwaW5nQ2ZnLnZhbHVlcyAmJiB1dGlsXzEuaXNGdW5jdGlvbihtYXBwaW5nQ2ZnLnZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gbWFwcGluZ0NmZy52YWx1ZXModGhpcy5wYXJlbnROb2RlLCB0aGlzLmN1cnJlbnROb2RlKTtcbiAgICAgICAgICAgICAgICBtYXBwaW5nQ2ZnLnZhbHVlcyA9IHZhbHVlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmNvbG9yKG1hcHBpbmdDZmcuZmllbGQsIG1hcHBpbmdDZmcudmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBtYXBwaW5nQ2ZnID0gdXRpbF8xLmNsb25lKHRoaXMub3JpZ2luTWFwcGluZyk7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZ2VvbWV0cmllc1swXS5jb2xvcihtYXBwaW5nQ2ZnLmZpZWxkLCBtYXBwaW5nQ2ZnLnZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgICAgdmlldy5yZW5kZXIoKTtcbiAgICB9O1xuICAgIERyaWxsRG93bkludGVyYWN0aW9uLnByb3RvdHlwZS5pbml0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZ2VvbWV0cnkgPSB0aGlzLnZpZXcuZ2VvbWV0cmllc1swXTtcbiAgICAgICAgdmFyIHZpZXdSYW5nZSA9IHRoaXMudmlldy52aWV3QkJveDtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2VvbWV0cnkuY29udGFpbmVyO1xuICAgICAgICBjb250YWluZXIuc2V0Q2xpcCh7XG4gICAgICAgICAgICB0eXBlOiAncmVjdCcsXG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHg6IHZpZXdSYW5nZS5taW5YLFxuICAgICAgICAgICAgICAgIHk6IHZpZXdSYW5nZS5taW5ZLFxuICAgICAgICAgICAgICAgIHdpZHRoOiB2aWV3UmFuZ2Uud2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB2aWV3UmFuZ2UuaGVpZ2h0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBEcmlsbERvd25JbnRlcmFjdGlvbi5wcm90b3R5cGUudXBkYXRlUm9vdCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmlldy5jaGFuZ2VEYXRhKGRhdGEuZGF0YSk7XG4gICAgICAgIHRoaXMuYWRqdXN0U2NhbGUoMSk7XG4gICAgICAgIHRoaXMuY3VycmVudE5vZGUgPSB0aGlzLnBsb3Qub3B0aW9ucy5kYXRhO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH07XG4gICAgcmV0dXJuIERyaWxsRG93bkludGVyYWN0aW9uO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gRHJpbGxEb3duSW50ZXJhY3Rpb247XG5iYXNlXzEuZGVmYXVsdC5yZWdpc3RlckludGVyYWN0aW9uKCdkcmlsbGRvd24nLCBEcmlsbERvd25JbnRlcmFjdGlvbik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kcmlsbERvd24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLklOVEVSQUNUSU9OX01BUCA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRyaWxsRG93bl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZHJpbGxEb3duXCIpKTtcbmV4cG9ydHMuSU5URVJBQ1RJT05fTUFQID0ge1xuICAgIGRyaWxsZG93bjogZHJpbGxEb3duXzEuZGVmYXVsdCxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIHZpZXdfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3ZpZXctbGF5ZXJcIikpO1xudmFyIHNxdWFyaWZ5XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXlvdXQvc3F1YXJpZnlcIikpO1xudmFyIGludGVyYWN0aW9uXzEgPSByZXF1aXJlKFwiLi9pbnRlcmFjdGlvblwiKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnZhciBsYWJlbF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vY29tcG9uZW50cy9sYWJlbFwiKSk7XG52YXIgUEFSRU5UX05PREVfT0ZGU0VUID0gNDtcbnZhciBCTE9DS19NQVJHSU4gPSA0O1xudmFyIFRyZWVtYXBMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUcmVlbWFwTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVHJlZW1hcExheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICd0cmVlbWFwJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUcmVlbWFwTGF5ZXIuZ2V0RGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgX3N1cGVyLmdldERlZmF1bHRPcHRpb25zLmNhbGwodGhpcyksIHtcbiAgICAgICAgICAgIG1heExldmVsOiAyLFxuICAgICAgICAgICAgcGFkZGluZzogWzAsIDAsIDAsIDBdLFxuICAgICAgICAgICAgdG9vbHRpcDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dUaXRsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dNYXJrZXJzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzaGFyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB4RmllbGQ6ICd4JyxcbiAgICAgICAgICAgIHlGaWVsZDogJ3knLFxuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGFkanVzdFBvc2l0aW9uOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJ3JnYmEoMCwwLDAsMCknLFxuICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDAsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICB4OiB7XG4gICAgICAgICAgICAgICAgICAgIG5pY2U6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgeToge1xuICAgICAgICAgICAgICAgICAgICBuaWNlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGludGVyYWN0aW9uczogW3sgdHlwZTogJ3Rvb2x0aXAnIH1dLFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuYmVmb3JlSW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5iZWZvcmVJbml0LmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBpbnRlcmFjdGlvbnMgPSB0aGlzLm9wdGlvbnMuaW50ZXJhY3Rpb25zO1xuICAgICAgICBpZiAoaW50ZXJhY3Rpb25zKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChpbnRlcmFjdGlvbnMsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdGlvbi50eXBlID09PSAnZHJpbGxkb3duJykge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5pc0RyaWxsZG93biA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm9wdGlvbnMubWF4TGV2ZWwgPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkYXRhID0gdGhpcy5vcHRpb25zLmRhdGE7XG4gICAgICAgIHZhciB0cmVlbWFwRGF0YSA9IHRoaXMuZ2V0VHJlZW1hcERhdGEoZGF0YSk7XG4gICAgICAgIHRoaXMucm9vdERhdGEgPSB0cmVlbWFwRGF0YTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sYWJlbCAmJiB0aGlzLm9wdGlvbnMubGFiZWwudmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIGxhYmVsID0gbmV3IGxhYmVsXzEuZGVmYXVsdCh0c2xpYl8xLl9fYXNzaWduKHsgdmlldzogdGhpcy52aWV3LCBwbG90OiB0aGlzIH0sIHRoaXMub3B0aW9ucy5sYWJlbCkpO1xuICAgICAgICAgICAgbGFiZWwucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAncG9seWdvbic7XG4gICAgfTtcbiAgICBUcmVlbWFwTGF5ZXIucHJvdG90eXBlLmdldFRyZWVtYXBEYXRhID0gZnVuY3Rpb24gKGRhdGEsIGxldmVsKSB7XG4gICAgICAgIHZhciB2aWV3UmFuZ2UgPSB0aGlzLmdldFZpZXdSYW5nZSgpO1xuICAgICAgICB2YXIgcm9vdCA9IHNxdWFyaWZ5XzEuZGVmYXVsdChkYXRhLCB2aWV3UmFuZ2UueCwgdmlld1JhbmdlLnksIHZpZXdSYW5nZS53aWR0aCwgdmlld1JhbmdlLmhlaWdodCk7XG4gICAgICAgIHRoaXMucmVjdXJzaXZlKHJvb3QsIDEpO1xuICAgICAgICB2YXIgdHJlZW1hcERhdGEgPSBbXTtcbiAgICAgICAgdGhpcy5nZXRBbGxOb2Rlcyhyb290LCB0cmVlbWFwRGF0YSwgbGV2ZWwpO1xuICAgICAgICB0cmVlbWFwRGF0YS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYS5kZXB0aCAtIGIuZGVwdGg7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9wdGlvbnMueEZpZWxkID0gJ3gnO1xuICAgICAgICB0aGlzLm9wdGlvbnMueUZpZWxkID0gJ3knO1xuICAgICAgICByZXR1cm4gdHJlZW1hcERhdGE7XG4gICAgfTtcbiAgICBUcmVlbWFwTGF5ZXIucHJvdG90eXBlLnByb2Nlc3NEYXRhID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yb290RGF0YTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuY29vcmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYSA9IHRoaXMub3B0aW9ucywgZGF0YSA9IF9hLmRhdGEsIGNvbG9yRmllbGQgPSBfYS5jb2xvckZpZWxkLCBjb2xvciA9IF9hLmNvbG9yO1xuICAgICAgICB2YXIgdHJlZW1hcERhdGEgPSB0aGlzLmdldFRyZWVtYXBEYXRhKGRhdGEpO1xuICAgICAgICB0aGlzLnJvb3REYXRhID0gdHJlZW1hcERhdGE7XG4gICAgICAgIHZhciBpc05lc3RlZCA9IHRoaXMuaXNOZXN0ZWQodHJlZW1hcERhdGEpO1xuICAgICAgICB0aGlzLnJlY3QgPSB7XG4gICAgICAgICAgICB0eXBlOiAncG9seWdvbicsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogWyd4JywgJ3knXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xvcjoge1xuICAgICAgICAgICAgICAgIGZpZWxkczogW2NvbG9yRmllbGRdLFxuICAgICAgICAgICAgICAgIHZhbHVlczogY29sb3IsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFsnZGVwdGgnXSxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRlZmF1bHRTdHlsZSA9IF90aGlzLmFkanVzdFN0eWxlQnlEZXB0aChkLCBpc05lc3RlZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1dGlsXzEuZGVlcE1peCh7fSwgZGVmYXVsdFN0eWxlLCBfdGhpcy5vcHRpb25zLnJlY3RTdHlsZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgZmllbGRzOiBbJ25hbWUnLCAndmFsdWUnXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudG9vbHRpcCAmJiB0aGlzLm9wdGlvbnMudG9vbHRpcC5mb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMucmVjdC50b29sdGlwLmNhbGxiYWNrID0gdGhpcy5vcHRpb25zLnRvb2x0aXAuZm9ybWF0dGVyO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIHRoaXMucmVjdCk7XG4gICAgfTtcbiAgICBUcmVlbWFwTGF5ZXIucHJvdG90eXBlLmFwcGx5SW50ZXJhY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaW50ZXJhY3Rpb25DZmcgPSB0aGlzLm9wdGlvbnMuaW50ZXJhY3Rpb25zO1xuICAgICAgICB2YXIgaW50ZXJhY3Rpb25zID0gdGhpcy52aWV3LmludGVyYWN0aW9ucztcbiAgICAgICAgdXRpbF8xLmVhY2goaW50ZXJhY3Rpb25DZmcsIGZ1bmN0aW9uIChpbnRlcikge1xuICAgICAgICAgICAgdmFyIEN0ciA9IGludGVyYWN0aW9uXzEuSU5URVJBQ1RJT05fTUFQW2ludGVyLnR5cGVdO1xuICAgICAgICAgICAgaWYgKEN0cikge1xuICAgICAgICAgICAgICAgIHZhciBpbnRlcmFjdGlvbiA9IG5ldyBDdHIodXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgICAgICAgICAgdmlldzogX3RoaXMudmlldyxcbiAgICAgICAgICAgICAgICAgICAgcGxvdDogX3RoaXMsXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0RXZlbnQ6ICdwb2x5Z29uOmNsaWNrJyxcbiAgICAgICAgICAgICAgICB9LCBpbnRlci5jZmcsIEN0ci5nZXRJbnRlcmFjdGlvblJhbmdlKF90aGlzLmxheWVyQkJveCwgaW50ZXIuY2ZnKSkpO1xuICAgICAgICAgICAgICAgIGludGVyYWN0aW9uc1tpbnRlci50eXBlXSA9IGludGVyYWN0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuYW5pbWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmFuaW1hdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5pc0RyaWxsZG93bikge1xuICAgICAgICAgICAgdGhpcy5yZWN0LmFuaW1hdGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVHJlZW1hcExheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUucmVjdXJzaXZlID0gZnVuY3Rpb24gKHJvd3MsIGRlcHRoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBjb2xvckZpZWxkID0gdGhpcy5vcHRpb25zLmNvbG9yRmllbGQ7XG4gICAgICAgIHV0aWxfMS5lYWNoKHJvd3MsIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChyLmNoaWxkcmVuLCBmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgIGMuZGVwdGggPSBkZXB0aDtcbiAgICAgICAgICAgICAgICBpZiAoZGVwdGggPiAxKVxuICAgICAgICAgICAgICAgICAgICBjLnBhcmVudCA9IHI7XG4gICAgICAgICAgICAgICAgaWYgKCF1dGlsXzEuaGFzS2V5KGMsIGNvbG9yRmllbGQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNbY29sb3JGaWVsZF0gPSByW2NvbG9yRmllbGRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjLnNob3dMYWJlbCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdmFyIGxlYWYgPSBfdGhpcy5pc0xlYWYoYyk7XG4gICAgICAgICAgICAgICAgaWYgKCFsZWFmKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGlwZXJIZWlnaHQgPSBNYXRoLmFicyhjLnkxIC0gYy55MCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbEhlaWdodCA9IF90aGlzLmdldExhYmVsSGVpZ2h0KCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRMYWJlbE9mZnNldCA9IGNsaXBlckhlaWdodCAvIDIgPiBsYWJlbEhlaWdodCA/IGxhYmVsSGVpZ2h0IDogQkxPQ0tfTUFSR0lOO1xuICAgICAgICAgICAgICAgICAgICBjLnNob3dMYWJlbCA9IHBhcmVudExhYmVsT2Zmc2V0ID09PSBCTE9DS19NQVJHSU4gPyBmYWxzZSA6IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjX3Jvd3MgPSBzcXVhcmlmeV8xLmRlZmF1bHQoYywgYy54MCArIEJMT0NLX01BUkdJTiwgYy55MCArIHBhcmVudExhYmVsT2Zmc2V0LCBjLngxIC0gQkxPQ0tfTUFSR0lOLCBjLnkxIC0gQkxPQ0tfTUFSR0lOKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuZmlsbENvbG9yRmllbGQoY19yb3dzLCBjb2xvckZpZWxkLCBjW2NvbG9yRmllbGRdKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucmVjdXJzaXZlKGNfcm93cywgYy5kZXB0aCArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuZ2V0QWxsTm9kZXMgPSBmdW5jdGlvbiAoZGF0YSwgbm9kZXMsIGxldmVsKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBtYXggPSBsZXZlbCA/IGxldmVsIDogdGhpcy5vcHRpb25zLm1heExldmVsO1xuICAgICAgICB2YXIgdmlld1JhbmdlID0gdGhpcy5nZXRWaWV3UmFuZ2UoKTtcbiAgICAgICAgdXRpbF8xLmVhY2goZGF0YSwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaGFzS2V5KGQsICd4MCcpICYmIGQuZGVwdGggPD0gbWF4KSB7XG4gICAgICAgICAgICAgICAgbm9kZXMucHVzaCh0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGQpLCB7IHg6IFtkLngwLCBkLngxLCBkLngxLCBkLngwXSwgeTogW3ZpZXdSYW5nZS5oZWlnaHQgLSBkLnkxLCB2aWV3UmFuZ2UuaGVpZ2h0IC0gZC55MSwgdmlld1JhbmdlLmhlaWdodCAtIGQueTAsIHZpZXdSYW5nZS5oZWlnaHQgLSBkLnkwXSB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXRpbF8xLmhhc0tleShkLCAnY2hpbGRyZW4nKSkge1xuICAgICAgICAgICAgICAgIF90aGlzLmdldEFsbE5vZGVzKGQuY2hpbGRyZW4sIG5vZGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBUcmVlbWFwTGF5ZXIucHJvdG90eXBlLmZpbGxDb2xvckZpZWxkID0gZnVuY3Rpb24gKHJvd3MsIGZpZWxkTmFtZSwgdmFsdWUpIHtcbiAgICAgICAgdXRpbF8xLmVhY2gocm93cywgZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgIGlmICghdXRpbF8xLmhhc0tleShyLCBmaWVsZE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcltmaWVsZE5hbWVdID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVHJlZW1hcExheWVyLnByb3RvdHlwZS5nZXRMYWJlbEhlaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGxhYmVsID0gdGhpcy5vcHRpb25zLmxhYmVsO1xuICAgICAgICB2YXIgZm9udFNpemUgPSB0aGlzLmdldFBsb3RUaGVtZSgpLmxhYmVsLnN0eWxlLmZvbnRTaXplO1xuICAgICAgICB2YXIgc2l6ZSA9IDA7XG4gICAgICAgIGlmIChsYWJlbCAmJiBsYWJlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YXIgbGFiZWxTdHlsZSA9IGxhYmVsLnN0eWxlO1xuICAgICAgICAgICAgc2l6ZSA9IGxhYmVsU3R5bGUgJiYgbGFiZWxTdHlsZS5mb250U2l6ZSA/IGxhYmVsU3R5bGUuZm9udFNpemUgOiBmb250U2l6ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2l6ZSArIFBBUkVOVF9OT0RFX09GRlNFVCAqIDI7XG4gICAgfTtcbiAgICBUcmVlbWFwTGF5ZXIucHJvdG90eXBlLmlzTGVhZiA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHJldHVybiAhZGF0YS5jaGlsZHJlbiB8fCBkYXRhLmNoaWxkcmVuLmxlbmd0aCA9PT0gMDtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuaXNOZXN0ZWQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgbWF4TGV2ZWwgPSB0aGlzLm9wdGlvbnMubWF4TGV2ZWw7XG4gICAgICAgIGlmIChtYXhMZXZlbCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuZXN0ZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtpXS5jaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIG5lc3RlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lc3RlZDtcbiAgICB9O1xuICAgIFRyZWVtYXBMYXllci5wcm90b3R5cGUuYWRqdXN0U3R5bGVCeURlcHRoID0gZnVuY3Rpb24gKGRlcHRoLCBpc05lc3RlZCkge1xuICAgICAgICB2YXIgbWF4TGV2ZWwgPSB0aGlzLm9wdGlvbnMubWF4TGV2ZWw7XG4gICAgICAgIGlmICghaXNOZXN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIHN0cm9rZTogJ3JnYmEoMCwwLDAsMC45KScsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC45LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZXB0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAnYmxhY2snLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IGRlcHRoIC8gbWF4TGV2ZWwsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgwLDAsMCwwLjMpJyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBkZXB0aCAvIG1heExldmVsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFRyZWVtYXBMYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRyZWVtYXBMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3RyZWVtYXAnLCBUcmVlbWFwTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRpY2UgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG5mdW5jdGlvbiBkaWNlKHJvb3QsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgdmFyIHdpZHRoID0geDEgLSB4MDtcbiAgICB2YXIgY2hpbGRyZW4gPSByb290LmNoaWxkcmVuLCB2YWx1ZSA9IHJvb3QudmFsdWU7XG4gICAgY2hpbGRyZW4uc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gYi52YWx1ZSAtIGEudmFsdWU7XG4gICAgfSk7XG4gICAgdmFyIGsgPSB3aWR0aCAvIHZhbHVlO1xuICAgIHZhciBub2RlX3ggPSB4MDtcbiAgICB1dGlsXzEuZWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgYy55MCA9IHkwO1xuICAgICAgICBjLnkxID0geTE7XG4gICAgICAgIGMueDAgPSBub2RlX3g7XG4gICAgICAgIG5vZGVfeCArPSBjLnZhbHVlICogaztcbiAgICAgICAgYy54MSA9IGMueDAgKyBjLnZhbHVlICogaztcbiAgICB9KTtcbn1cbmV4cG9ydHMuZGljZSA9IGRpY2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kaWNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5zbGljZSA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbmZ1bmN0aW9uIHNsaWNlKHJvb3QsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgdmFyIGhlaWdodCA9IHkxIC0geTA7XG4gICAgdmFyIGNoaWxkcmVuID0gcm9vdC5jaGlsZHJlbiwgdmFsdWUgPSByb290LnZhbHVlO1xuICAgIGNoaWxkcmVuLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGIudmFsdWUgLSBhLnZhbHVlO1xuICAgIH0pO1xuICAgIHZhciBrID0gaGVpZ2h0IC8gdmFsdWU7XG4gICAgdmFyIG5vZGVfeSA9IHkwO1xuICAgIHV0aWxfMS5lYWNoKGNoaWxkcmVuLCBmdW5jdGlvbiAoYykge1xuICAgICAgICBjLngwID0geDA7XG4gICAgICAgIGMueDEgPSB4MTtcbiAgICAgICAgYy55MCA9IG5vZGVfeTtcbiAgICAgICAgbm9kZV95ICs9IGMudmFsdWUgKiBrO1xuICAgICAgICBjLnkxID0gYy55MCArIGMudmFsdWUgKiBrO1xuICAgIH0pO1xufVxuZXhwb3J0cy5zbGljZSA9IHNsaWNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2xpY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZGljZV8xID0gcmVxdWlyZShcIi4vZGljZVwiKTtcbnZhciBzbGljZV8xID0gcmVxdWlyZShcIi4vc2xpY2VcIik7XG4vL3JlZmVyZW5jZTogaHR0cHM6Ly9naXRodWIuY29tL2QzL2QzLWhpZXJhcmNoeS9ibG9iL21hc3Rlci9zcmMvdHJlZW1hcC9zcXVhcmlmeS5qc1xuLy8g6buE6YeR5YiG5YmyXG52YXIgcmF0aW8gPSAoMSArIE1hdGguc3FydCg1KSkgLyAyO1xuZnVuY3Rpb24gc3F1YXJpZnkocm9vdCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSByb290LmNoaWxkcmVuO1xuICAgIHZhciB2YWx1ZSA9IHJvb3QudmFsdWU7XG4gICAgY2hpbGRyZW4uc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gYi52YWx1ZSAtIGEudmFsdWU7XG4gICAgfSk7XG4gICAgdmFyIHJvd3MgPSBbXTtcbiAgICB2YXIgc3VtVmFsdWUsIG1heFZhbHVlLCBtaW5WYWx1ZTtcbiAgICB2YXIgYWxwaGEsIGJldGE7XG4gICAgdmFyIG5ld1JhdGlvLCBtaW5SYXRpbztcbiAgICB2YXIgbm9kZVZhbHVlO1xuICAgIHZhciBpID0gMCwgaiA9IDA7XG4gICAgLy8gdG9kbzog5YmU6ZmkZW1wdHkgbm9kZVxuICAgIHdoaWxlIChpIDwgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgIHZhciB3aWR0aCA9IHgxIC0geDA7XG4gICAgICAgIHZhciBoZWlnaHQgPSB5MSAtIHkwO1xuICAgICAgICBzdW1WYWx1ZSA9IGNoaWxkcmVuW2orK10udmFsdWU7XG4gICAgICAgIG1heFZhbHVlID0gc3VtVmFsdWU7XG4gICAgICAgIG1pblZhbHVlID0gc3VtVmFsdWU7XG4gICAgICAgIGFscGhhID0gTWF0aC5tYXgoaGVpZ2h0IC8gd2lkdGgsIHdpZHRoIC8gaGVpZ2h0KSAvICh2YWx1ZSAqIHJhdGlvKTtcbiAgICAgICAgYmV0YSA9IHN1bVZhbHVlICogc3VtVmFsdWUgKiBhbHBoYTtcbiAgICAgICAgbWluUmF0aW8gPSBNYXRoLm1heChtYXhWYWx1ZSAvIGJldGEsIGJldGEgLyBtaW5WYWx1ZSk7XG4gICAgICAgIGZvciAoOyBqIDwgY2hpbGRyZW4ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIG5vZGVWYWx1ZSA9IGNoaWxkcmVuW2pdLnZhbHVlO1xuICAgICAgICAgICAgc3VtVmFsdWUgKz0gbm9kZVZhbHVlO1xuICAgICAgICAgICAgaWYgKG5vZGVWYWx1ZSA8IG1pblZhbHVlKVxuICAgICAgICAgICAgICAgIG1pblZhbHVlID0gbm9kZVZhbHVlO1xuICAgICAgICAgICAgaWYgKG5vZGVWYWx1ZSA+IG1heFZhbHVlKVxuICAgICAgICAgICAgICAgIG1heFZhbHVlID0gbm9kZVZhbHVlO1xuICAgICAgICAgICAgYmV0YSA9IHN1bVZhbHVlICogc3VtVmFsdWUgKiBhbHBoYTtcbiAgICAgICAgICAgIG5ld1JhdGlvID0gTWF0aC5tYXgobWF4VmFsdWUgLyBiZXRhLCBiZXRhIC8gbWluVmFsdWUpO1xuICAgICAgICAgICAgaWYgKG5ld1JhdGlvID4gbWluUmF0aW8pIHtcbiAgICAgICAgICAgICAgICBzdW1WYWx1ZSAtPSBub2RlVmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtaW5SYXRpbyA9IG5ld1JhdGlvO1xuICAgICAgICB9XG4gICAgICAgIHZhciByb3cgPSB7IHZhbHVlOiBzdW1WYWx1ZSwgZGljZTogd2lkdGggPCBoZWlnaHQsIGNoaWxkcmVuOiBjaGlsZHJlbi5zbGljZShpLCBqKSB9O1xuICAgICAgICByb3dzLnB1c2gocm93KTtcbiAgICAgICAgaWYgKHJvdy5kaWNlKSB7XG4gICAgICAgICAgICB2YXIgaCA9IHZhbHVlID8gKGhlaWdodCAqIHN1bVZhbHVlKSAvIHZhbHVlIDogaGVpZ2h0O1xuICAgICAgICAgICAgZGljZV8xLmRpY2Uocm93LCB4MCwgeTAsIHgxLCB5MCArIGgpO1xuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgeTAgKz0gaDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciB3ID0gdmFsdWUgPyAod2lkdGggKiBzdW1WYWx1ZSkgLyB2YWx1ZSA6IHdpZHRoO1xuICAgICAgICAgICAgc2xpY2VfMS5zbGljZShyb3csIHgwLCB5MCwgeDAgKyB3LCB5MSk7XG4gICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICB4MCArPSB3O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhbHVlIC09IHN1bVZhbHVlO1xuICAgICAgICBpID0gajtcbiAgICB9XG4gICAgcmV0dXJuIHJvd3M7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzcXVhcmlmeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNxdWFyaWZ5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKipcbiAqIENyZWF0ZSBCeSBCcnVjZSBUb29cbiAqIE9uIDIwMjAtMDItMThcbiAqL1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGxheWVyXzEgPSByZXF1aXJlKFwiLi4vLi4vbGF5ZXJcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG5mdW5jdGlvbiBnZXREZWZhdWx0Q2ZnKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGZpbGw6ICcjZmZmJyxcbiAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICBsaW5lSGVpZ2h0OiAxMixcbiAgICAgICAgc3Ryb2tlOiAncmdiYSgwLCAwLCAwLCAwLjQ1KScsXG4gICAgfTtcbn1cbnZhciBEaWZmTGFiZWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRGlmZkxhYmVsKGNmZykge1xuICAgICAgICB0aGlzLnRleHRBdHRycyA9IHt9O1xuICAgICAgICB0aGlzLnZpZXcgPSBjZmcudmlldztcbiAgICAgICAgdGhpcy5maWVsZHMgPSBjZmcuZmllbGRzO1xuICAgICAgICB0aGlzLmZvcm1hdHRlciA9IGNmZy5mb3JtYXR0ZXI7XG4gICAgICAgIHRoaXMudGV4dEF0dHJzID0gdXRpbF8xLm1peChnZXREZWZhdWx0Q2ZnKCksIGNmZy5zdHlsZSk7XG4gICAgICAgIHRoaXMuX2luaXQoKTtcbiAgICB9XG4gICAgLyoqIOe7mOWItui+heWKqWxhYmVscyAqL1xuICAgIERpZmZMYWJlbC5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKCF0aGlzLnZpZXcgfHwgdGhpcy52aWV3LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkYXRhID0gdXRpbF8xLmNsb25lKHRoaXMudmlldy5nZXREYXRhKCkpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMudmlldy5mb3JlZ3JvdW5kR3JvdXAuYWRkR3JvdXAoKTtcbiAgICAgICAgdmFyIHNoYXBlcyA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmVsZW1lbnRzLm1hcChmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHZhbHVlLnNoYXBlOyB9KTtcbiAgICAgICAgdXRpbF8xLmVhY2goc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUsIGlkeCkge1xuICAgICAgICAgICAgaWYgKCFzaGFwZS5jZmcub3JpZ2luKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHZhciBfb3JpZ2luID0gc2hhcGUuY2ZnLm9yaWdpbi5kYXRhO1xuICAgICAgICAgICAgdmFyIHNoYXBlQm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgICAgICAgICAgdmFyIHZhbHVlcyA9IF9vcmlnaW5bbGF5ZXJfMS5WQUxVRV9GSUVMRF07XG4gICAgICAgICAgICB2YXIgZGlmZiA9IHZhbHVlcztcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheSh2YWx1ZXMpKSB7XG4gICAgICAgICAgICAgICAgZGlmZiA9IHZhbHVlc1sxXSAtIHZhbHVlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpZmYgPSBkaWZmID4gMCA/IFwiK1wiICsgZGlmZiA6IGRpZmY7XG4gICAgICAgICAgICAvKiogaXMgdG90YWwsIHRvdGFsIGRvIG5vdCBuZWVkIGArYCBzaWduICovXG4gICAgICAgICAgICBpZiAoX29yaWdpbltsYXllcl8xLklTX1RPVEFMXSkge1xuICAgICAgICAgICAgICAgIGRpZmYgPSB2YWx1ZXNbMF0gLSB2YWx1ZXNbMV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZm9ybWF0dGVkVGV4dCA9IGRpZmY7XG4gICAgICAgICAgICBpZiAoX3RoaXMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbG9yID0gc2hhcGVzW2lkeF0uYXR0cignZmlsbCcpO1xuICAgICAgICAgICAgICAgIGZvcm1hdHRlZFRleHQgPSBfdGhpcy5mb3JtYXR0ZXIoXCJcIiArIGRpZmYsIHsgX29yaWdpbjogZGF0YVtpZHhdLCBjb2xvcjogY29sb3IgfSwgaWR4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB0ZXh0ID0gX3RoaXMuY29udGFpbmVyLmFkZFNoYXBlKCd0ZXh0Jywge1xuICAgICAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgdGV4dDogZm9ybWF0dGVkVGV4dCwgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJywgdGV4dEFsaWduOiAnY2VudGVyJywgeDogKHNoYXBlQm94Lm1pblggKyBzaGFwZUJveC5tYXhYKSAvIDIsIHk6IChzaGFwZUJveC5taW5ZICsgc2hhcGVCb3gubWF4WSkgLyAyIH0sIF90aGlzLnRleHRBdHRycyksXG4gICAgICAgICAgICAgICAgbmFtZTogJ2RpbGwtbGFiZWwnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAodGV4dC5nZXRCQm94KCkuaGVpZ2h0ID4gc2hhcGVCb3guaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgdGV4dC5zZXQoJ3Zpc2libGUnLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpZXcuZ2V0Q2FudmFzKCkuZHJhdygpO1xuICAgIH07XG4gICAgRGlmZkxhYmVsLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBEaWZmTGFiZWwucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLnZpZXcub24oZGVwZW5kZW50c18xLlZJRVdfTElGRV9DSVJDTEUuQkVGT1JFX1JFTkRFUiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlldy5vbihkZXBlbmRlbnRzXzEuVklFV19MSUZFX0NJUkNMRS5BRlRFUl9SRU5ERVIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF90aGlzLmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gRGlmZkxhYmVsO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IERpZmZMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpZmYtbGFiZWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQ3JlYXRlIEJ5IEJydWNlIFRvb1xuICogT24gMjAyMC0wMi0xOFxuICovXG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbGFiZWxfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi8uLi9jb2x1bW4vY29tcG9uZW50L2xhYmVsXCIpKTtcbnZhciBsYXllcl8xID0gcmVxdWlyZShcIi4uLy4uL2xheWVyXCIpO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2xhYmVsL2Jhc2VcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgTUFSR0lOID0gMjtcbnZhciBXYXRlcmZhbGxMYWJlbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhXYXRlcmZhbGxMYWJlbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBXYXRlcmZhbGxMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBXYXRlcmZhbGxMYWJlbC5wcm90b3R5cGUuYWRqdXN0TGFiZWwgPSBmdW5jdGlvbiAobGFiZWwsIGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB2YXIgX2I7XG4gICAgICAgIHZhciBzaGFwZSA9IGVsZW1lbnQuc2hhcGU7XG4gICAgICAgIHZhciBzaGFwZUJveCA9IHNoYXBlLmdldEJCb3goKTtcbiAgICAgICAgdmFyIGRhdGEgPSBlbGVtZW50LmdldERhdGEoKTtcbiAgICAgICAgdmFyIHZhbHVlcyA9IGRhdGFbbGF5ZXJfMS5WQUxVRV9GSUVMRF07XG4gICAgICAgIHZhciBkaWZmID0gZGF0YVt0aGlzLmxheWVyLm9wdGlvbnMueUZpZWxkXTtcbiAgICAgICAgdmFyIHZhbHVlID0gdXRpbF8xLmlzQXJyYXkodmFsdWVzKSA/IHZhbHVlc1sxXSA6IHZhbHVlcztcbiAgICAgICAgdmFyIGZvcm1hdHRlciA9IHRoaXMub3B0aW9ucy5mb3JtYXR0ZXI7XG4gICAgICAgIHZhciBtYXBwaW5nRGF0YSA9IFtdLmNvbmNhdChlbGVtZW50LmdldE1vZGVsKCkubWFwcGluZ0RhdGEpO1xuICAgICAgICB2YXIgZWxlbWVudEluZGV4ID0gZm9ybWF0dGVyID8gbWFwcGluZ0RhdGFbMF0gJiYgbWFwcGluZ0RhdGFbMF1bJ19vcmlnaW4nXVtsYXllcl8xLklOREVYX0ZJRUxEXSA6IDA7XG4gICAgICAgIHZhciBmb3JtYXR0ZXJWYWx1ZSA9IGZvcm1hdHRlclxuICAgICAgICAgICAgPyBmb3JtYXR0ZXIodmFsdWUsIChfYSA9IHt9LFxuICAgICAgICAgICAgICAgIF9hW2RlcGVuZGVudHNfMS5fT1JJR0lOXSA9IChfYiA9IG1hcHBpbmdEYXRhWzBdKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuX29yaWdpbixcbiAgICAgICAgICAgICAgICBfYS5tYXBwaW5nRGF0dW0gPSBtYXBwaW5nRGF0YVswXSxcbiAgICAgICAgICAgICAgICBfYS5tYXBwaW5nRGF0dW1JbmRleCA9IDAsXG4gICAgICAgICAgICAgICAgX2EuZWxlbWVudCA9IGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgX2EuZWxlbWVudEluZGV4ID0gZWxlbWVudEluZGV4LFxuICAgICAgICAgICAgICAgIF9hKSwgZWxlbWVudEluZGV4KVxuICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgdmFyIHlQb3MgPSAoc2hhcGVCb3gubWluWSArIHNoYXBlQm94Lm1heFkpIC8gMjtcbiAgICAgICAgdmFyIHRleHRCYXNlbGluZSA9ICdib3R0b20nO1xuICAgICAgICBpZiAoZGlmZiA8IDApIHtcbiAgICAgICAgICAgIHlQb3MgPSBzaGFwZUJveC5tYXhZICsgTUFSR0lOO1xuICAgICAgICAgICAgdGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB5UG9zID0gc2hhcGVCb3gubWluWSAtIE1BUkdJTjtcbiAgICAgICAgfVxuICAgICAgICBsYWJlbC5hdHRyKCd5JywgeVBvcyk7XG4gICAgICAgIGxhYmVsLmF0dHIoJ3RleHQnLCBmb3JtYXR0ZXJWYWx1ZSk7XG4gICAgICAgIGxhYmVsLmF0dHIoJ3RleHRCYXNlbGluZScsIHRleHRCYXNlbGluZSk7XG4gICAgfTtcbiAgICByZXR1cm4gV2F0ZXJmYWxsTGFiZWw7XG59KGxhYmVsXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gV2F0ZXJmYWxsTGFiZWw7XG5iYXNlXzEucmVnaXN0ZXJMYWJlbENvbXBvbmVudCgnd2F0ZXJmYWxsJywgV2F0ZXJmYWxsTGFiZWwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2F0ZXJmYWxsLWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE4XG4gKi9cbi8qKlxuICogQGZpbGUgZXZlbnRzIG9mIHdhdGVyZmFsbCBjaGFydCBpcyBlcXVhbCB0byBjb2x1bW4gY2hhcnRcbiAqL1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vY29sdW1uL2V2ZW50XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRVZFTlRfTUFQXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLkVWRU5UX01BUDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9uRXZlbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEub25FdmVudDsgfSB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKipcbiAqIENyZWF0ZSBCeSBCcnVjZSBUb29cbiAqIE9uIDIwMjAtMDItMThcbiAqL1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi9kZXBlbmRlbnRzXCIpO1xuZnVuY3Rpb24gZ2V0U3R5bGUoY2ZnLCBpc1N0cm9rZSwgaXNGaWxsKSB7XG4gICAgdmFyIHN0eWxlID0gY2ZnLnN0eWxlLCBkZWZhdWx0U3R5bGUgPSBjZmcuZGVmYXVsdFN0eWxlLCBjb2xvciA9IGNmZy5jb2xvcjtcbiAgICB2YXIgYXR0cnMgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGRlZmF1bHRTdHlsZSksIHN0eWxlKTtcbiAgICBpZiAoY29sb3IpIHtcbiAgICAgICAgaWYgKGlzU3Ryb2tlKSB7XG4gICAgICAgICAgICBhdHRycy5zdHJva2UgPSBjb2xvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNGaWxsKSB7XG4gICAgICAgICAgICBhdHRycy5maWxsID0gY29sb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGF0dHJzO1xufVxuZnVuY3Rpb24gZ2V0UmVjdFBhdGgocG9pbnRzKSB7XG4gICAgdmFyIHBhdGggPSBbXTtcbiAgICB2YXIgZmlyc3RQb2ludCA9IHBvaW50c1swXTtcbiAgICBwYXRoLnB1c2goWydNJywgZmlyc3RQb2ludC54LCBmaXJzdFBvaW50LnldKTtcbiAgICBmb3IgKHZhciBpID0gMSwgbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHBhdGgucHVzaChbJ0wnLCBwb2ludHNbaV0ueCwgcG9pbnRzW2ldLnldKTtcbiAgICB9XG4gICAgcGF0aC5wdXNoKFsnTCcsIGZpcnN0UG9pbnQueCwgZmlyc3RQb2ludC55XSk7IC8vIOmcgOimgemXreWQiFxuICAgIHBhdGgucHVzaChbJ3onXSk7XG4gICAgcmV0dXJuIHBhdGg7XG59XG4vLyBAdHMtaWdub3JlXG5kZXBlbmRlbnRzXzEucmVnaXN0ZXJTaGFwZSgnaW50ZXJ2YWwnLCAnd2F0ZXJmYWxsJywge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBkcmF3OiBmdW5jdGlvbiAoY2ZnLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gZ2V0U3R5bGUoY2ZnLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIHZhciBwYXRoID0gdGhpcy5wYXJzZVBhdGgoZ2V0UmVjdFBhdGgoY2ZnLnBvaW50cykpO1xuICAgICAgICB2YXIgc2hhcGUgPSBjb250YWluZXIuYWRkU2hhcGUoJ3BhdGgnLCB7XG4gICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzdHlsZSksIHsgcGF0aDogcGF0aCB9KSxcbiAgICAgICAgICAgIG5hbWU6ICdpbnRlcnZhbCcsXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgbGVhZGVyTGluZSA9IHV0aWxfMS5nZXQoY2ZnLnN0eWxlLCAnbGVhZGVyTGluZScpO1xuICAgICAgICBpZiAobGVhZGVyTGluZSAmJiBsZWFkZXJMaW5lLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciBsaW5lU3R5bGUgPSBsZWFkZXJMaW5lLnN0eWxlIHx8IHt9O1xuICAgICAgICAgICAgLy8gMi4g6Jma57q/6L+e57q/XG4gICAgICAgICAgICBpZiAoY2ZnLm5leHRQb2ludHMpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGlua1BhdGggPSBbXG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgWydNJywgY2ZnLnBvaW50c1syXS54LCBjZmcucG9pbnRzWzJdLnldLFxuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIGNmZy5uZXh0UG9pbnRzWzBdLngsIGNmZy5uZXh0UG9pbnRzWzBdLnldLFxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgbGlua1BhdGggPSB0aGlzLnBhcnNlUGF0aChsaW5rUGF0aCk7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFkZFNoYXBlKCdwYXRoJywge1xuICAgICAgICAgICAgICAgICAgICBhdHRyczogdHNsaWJfMS5fX2Fzc2lnbih7IHBhdGg6IGxpbmtQYXRoLCBzdHJva2U6ICcjZDNkM2QzJywgbGluZURhc2g6IFs0LCAyXSwgbGluZVdpZHRoOiAxIH0sIGxpbmVTdHlsZSksXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdsZWFkZXItbGluZScsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNoYXBlO1xuICAgIH0sXG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdGVyZmFsbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE4XG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFdhdGVyZmFsbCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhXYXRlcmZhbGwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gV2F0ZXJmYWxsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFdhdGVyZmFsbC5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBsYXllclByb3BzID0gdXRpbF8xLmRlZXBNaXgoe30sIHByb3BzKTtcbiAgICAgICAgbGF5ZXJQcm9wcy50eXBlID0gJ3dhdGVyZmFsbCc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBXYXRlcmZhbGwuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFdhdGVyZmFsbDtcbn0ocGxvdF8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFdhdGVyZmFsbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5JTkRFWF9GSUVMRCA9IGV4cG9ydHMuSVNfVE9UQUwgPSBleHBvcnRzLlZBTFVFX0ZJRUxEID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG4vKipcbiAqIENyZWF0ZSBCeSBCcnVjZSBUb29cbiAqIE9uIDIwMjAtMDItMThcbiAqL1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xucmVxdWlyZShcIi4vZ2VvbWV0cnkvc2hhcGUvd2F0ZXJmYWxsXCIpO1xudmFyIHZpZXdfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3ZpZXctbGF5ZXJcIikpO1xudmFyIHNjYWxlXzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9zY2FsZVwiKTtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi4vLi4vY29tcG9uZW50cy9mYWN0b3J5XCIpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xucmVxdWlyZShcIi4vY29tcG9uZW50L2xhYmVsL3dhdGVyZmFsbC1sYWJlbFwiKTtcbnZhciBkaWZmX2xhYmVsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9jb21wb25lbnQvbGFiZWwvZGlmZi1sYWJlbFwiKSk7XG52YXIgdmlld18xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvdmlld1wiKTtcbnZhciBHMl9HRU9NX01BUCA9IHtcbiAgICB3YXRlcmZhbGw6ICdpbnRlcnZhbCcsXG59O1xudmFyIFBMT1RfR0VPTV9NQVAgPSB7XG4gICAgaW50ZXJ2YWw6ICd3YXRlcmZhbGwnLFxufTtcbmV4cG9ydHMuVkFMVUVfRklFTEQgPSAnJCR2YWx1ZSQkJztcbmV4cG9ydHMuSVNfVE9UQUwgPSAnJCR0b3RhbCQkJztcbmV4cG9ydHMuSU5ERVhfRklFTEQgPSAnJCRpbmRleCQkJztcbnZhciBXYXRlcmZhbGxMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhXYXRlcmZhbGxMYXllciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBXYXRlcmZhbGxMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnd2F0YXJmYWxsJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBXYXRlcmZhbGxMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdib3R0b20nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhZGp1c3RQb3NpdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAvKiog5beu5YC8IGxhYmVsICovXG4gICAgICAgICAgICBkaWZmTGFiZWw6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8qKiDov4Hnp7vnur8gKi9cbiAgICAgICAgICAgIGxlYWRlckxpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8qKiDmmL7npLrmgLvorqEgKi9cbiAgICAgICAgICAgIHNob3dUb3RhbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgbGFiZWw6ICfmgLvorqHlgLwnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdhdGVyZmFsbFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgLyoqIOm7mOiupOaXoOaPj+i+uSAqL1xuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzaGFyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgc2hvd0Nyb3NzaGFpcnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNob3dNYXJrZXJzOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLmdldE9wdGlvbnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSBfc3VwZXIucHJvdG90eXBlLmdldE9wdGlvbnMuY2FsbCh0aGlzLCBwcm9wcyk7XG4gICAgICAgIHRoaXMuYWRqdXN0TGVnZW5kT3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgdGhpcy5hZGp1c3RNZXRhKG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9O1xuICAgIFdhdGVyZmFsbExheWVyLnByb3RvdHlwZS5hZnRlckluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJJbml0LmNhbGwodGhpcyk7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBpZiAob3B0aW9ucy5kaWZmTGFiZWwgJiYgb3B0aW9ucy5kaWZmTGFiZWwudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5kaWZmTGFiZWwgPSBuZXcgZGlmZl9sYWJlbF8xLmRlZmF1bHQoe1xuICAgICAgICAgICAgICAgIHZpZXc6IHRoaXMudmlldyxcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFtvcHRpb25zLnhGaWVsZCwgb3B0aW9ucy55RmllbGQsIGV4cG9ydHMuVkFMVUVfRklFTERdLFxuICAgICAgICAgICAgICAgIGZvcm1hdHRlcjogb3B0aW9ucy5kaWZmTGFiZWwuZm9ybWF0dGVyLFxuICAgICAgICAgICAgICAgIHN0eWxlOiBvcHRpb25zLmRpZmZMYWJlbC5zdHlsZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuZGlmZkxhYmVsKSB7XG4gICAgICAgICAgICB0aGlzLmRpZmZMYWJlbC5jbGVhcigpO1xuICAgICAgICAgICAgdGhpcy5kaWZmTGFiZWwgPSBudWxsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBXYXRlcmZhbGxMYXllci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuYWZ0ZXJSZW5kZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHRoaXMudmlldy5vbigndG9vbHRpcDpjaGFuZ2UnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIGl0ZW1zID0gZS5pdGVtcztcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIHZhciBkYXRhID0gdXRpbF8xLmdldChpdGVtLCAnZGF0YScsIHt9KTtcbiAgICAgICAgICAgICAgICAvLyDmlLnlj5ggdG9vbHRpcCDmmL7npLrnmoRuYW1l5ZKMdmFsdWVcbiAgICAgICAgICAgICAgICBpdGVtLm5hbWUgPSBkYXRhW29wdGlvbnMueEZpZWxkXTtcbiAgICAgICAgICAgICAgICBpdGVtLnZhbHVlID0gZGF0YVtvcHRpb25zLnlGaWVsZF07XG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtLnZhbHVlICYmIGRhdGFbZXhwb3J0cy5JU19UT1RBTF0pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IGRhdGFbZXhwb3J0cy5WQUxVRV9GSUVMRF07XG4gICAgICAgICAgICAgICAgICAgIGl0ZW0udmFsdWUgPSB2YWx1ZXNbMF0gLSB2YWx1ZXNbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGUuaXRlbXNbaV0gPSBpdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZW5kZXJMYWJlbCgpO1xuICAgIH07XG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLnJlbmRlckxhYmVsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZ2VvbWV0cnkgPSB2aWV3XzEuZ2V0R2VvbWV0cnlCeVR5cGUodGhpcy52aWV3LCAnaW50ZXJ2YWwnKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sYWJlbCAmJiB0aGlzLm9wdGlvbnMubGFiZWwudmlzaWJsZSkge1xuICAgICAgICAgICAgdGhpcy5kb1JlbmRlckxhYmVsKGdlb21ldHJ5LCB0c2xpYl8xLl9fYXNzaWduKHsgdHlwZTogJ3dhdGVyZmFsbCcgfSwgdGhpcy5vcHRpb25zLmxhYmVsKSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFdhdGVyZmFsbExheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgaWYgKGRpbSA9PT0gJ2cyJykge1xuICAgICAgICAgICAgcmV0dXJuIEcyX0dFT01fTUFQW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQTE9UX0dFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLmludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldENvbmZpZygnaW50ZXJhY3Rpb25zJywgW3sgdHlwZTogJ3Rvb2x0aXAnIH0sIHsgdHlwZTogJ2FjdGl2ZS1yZWdpb24nIH1dKTtcbiAgICB9O1xuICAgIFdhdGVyZmFsbExheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciB3YXRlcmZhbGwgPSB7XG4gICAgICAgICAgICB0eXBlOiAnaW50ZXJ2YWwnLFxuICAgICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgICAgICBmaWVsZHM6IFtvcHRpb25zLnhGaWVsZCwgZXhwb3J0cy5WQUxVRV9GSUVMRF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2hhcGU6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IFsnd2F0ZXJmYWxsJ10sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB3YXRlcmZhbGwuc3R5bGUgPSB0aGlzLl9wYXJzZVN0eWxlKCk7XG4gICAgICAgIHdhdGVyZmFsbC5jb2xvciA9IHRoaXMuX3BhcnNlQ29sb3IoKTtcbiAgICAgICAgdGhpcy53YXRlcmZhbGwgPSB3YXRlcmZhbGw7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudG9vbHRpcCAmJiAodGhpcy5vcHRpb25zLnRvb2x0aXAuZmllbGRzIHx8IHRoaXMub3B0aW9ucy50b29sdGlwLmZvcm1hdHRlcikpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VvbWV0cnlUb29sdGlwKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5Jywgd2F0ZXJmYWxsKTtcbiAgICB9O1xuICAgIFdhdGVyZmFsbExheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uIChvcmlnaW5EYXRhKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIHBsb3REYXRhID0gW107XG4gICAgICAgIHZhciB4RmllbGQgPSB0aGlzLm9wdGlvbnMueEZpZWxkO1xuICAgICAgICB2YXIgeUZpZWxkID0gdGhpcy5vcHRpb25zLnlGaWVsZDtcbiAgICAgICAgdXRpbF8xLm1hcChvcmlnaW5EYXRhLCBmdW5jdGlvbiAoZGF0YUl0ZW0sIGlkeCkge1xuICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gZGF0YUl0ZW1beUZpZWxkXTtcbiAgICAgICAgICAgIGlmIChpZHggPiAwKSB7XG4gICAgICAgICAgICAgICAgdmFyIHByZXZWYWx1ZSA9IHBsb3REYXRhW2lkeCAtIDFdW2V4cG9ydHMuVkFMVUVfRklFTERdO1xuICAgICAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheShwcmV2VmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ByZXZWYWx1ZVsxXSwgZGF0YUl0ZW1beUZpZWxkXSArIHByZXZWYWx1ZVsxXV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFtwcmV2VmFsdWUsIGRhdGFJdGVtW3lGaWVsZF0gKyBwcmV2VmFsdWVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBsb3REYXRhLnB1c2godHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBkYXRhSXRlbSksIChfYSA9IHt9LCBfYVtleHBvcnRzLlZBTFVFX0ZJRUxEXSA9IHZhbHVlLCBfYVtleHBvcnRzLklOREVYX0ZJRUxEXSA9IGlkeCwgX2EpKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dUb3RhbCAmJiB0aGlzLm9wdGlvbnMuc2hvd1RvdGFsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSB1dGlsXzEubWFwKG9yaWdpbkRhdGEsIGZ1bmN0aW9uIChvKSB7IHJldHVybiBvW3lGaWVsZF07IH0pO1xuICAgICAgICAgICAgdmFyIHRvdGFsVmFsdWUgPSB1dGlsXzEucmVkdWNlKHZhbHVlcywgZnVuY3Rpb24gKHAsIG4pIHsgcmV0dXJuIHAgKyBuOyB9LCAwKTtcbiAgICAgICAgICAgIHBsb3REYXRhLnB1c2goKF9hID0ge30sXG4gICAgICAgICAgICAgICAgX2FbeEZpZWxkXSA9IHRoaXMub3B0aW9ucy5zaG93VG90YWwubGFiZWwsXG4gICAgICAgICAgICAgICAgX2FbeUZpZWxkXSA9IG51bGwsXG4gICAgICAgICAgICAgICAgX2FbZXhwb3J0cy5WQUxVRV9GSUVMRF0gPSBbdG90YWxWYWx1ZSwgMF0sXG4gICAgICAgICAgICAgICAgX2FbZXhwb3J0cy5JTkRFWF9GSUVMRF0gPSBwbG90RGF0YS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgX2FbZXhwb3J0cy5JU19UT1RBTF0gPSB0cnVlLFxuICAgICAgICAgICAgICAgIF9hKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBsb3REYXRhO1xuICAgIH07XG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIHNjYWxlcyA9IHt9O1xuICAgICAgICAvKiog6YWN572ueC1zY2FsZSAqL1xuICAgICAgICBzY2FsZXNbb3B0aW9ucy54RmllbGRdID0geyB0eXBlOiAnY2F0JyB9O1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhvcHRpb25zLCAneEF4aXMnKSkge1xuICAgICAgICAgICAgc2NhbGVfMS5leHRyYWN0U2NhbGUoc2NhbGVzW29wdGlvbnMueEZpZWxkXSwgb3B0aW9ucy54QXhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqIOmFjee9rnktc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW2V4cG9ydHMuVkFMVUVfRklFTERdID0ge307XG4gICAgICAgIGlmICh1dGlsXzEuaGFzKG9wdGlvbnMsICd5QXhpcycpKSB7XG4gICAgICAgICAgICBzY2FsZV8xLmV4dHJhY3RTY2FsZShzY2FsZXNbZXhwb3J0cy5WQUxVRV9GSUVMRF0sIG9wdGlvbnMueUF4aXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdzY2FsZXMnLCBzY2FsZXMpO1xuICAgIH07XG4gICAgLyoqIEBvdmVycmlkZSAqL1xuICAgIFdhdGVyZmFsbExheWVyLnByb3RvdHlwZS5heGlzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeEF4aXNfcGFyc2VyID0gZmFjdG9yeV8xLmdldENvbXBvbmVudCgnYXhpcycsIHtcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgICAgICBkaW06ICd4JyxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB5QXhpc19wYXJzZXIgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdheGlzJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgICAgIGRpbTogJ3knLFxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGF4ZXNDb25maWcgPSB7fTtcbiAgICAgICAgYXhlc0NvbmZpZ1t0aGlzLm9wdGlvbnMueEZpZWxkXSA9IHhBeGlzX3BhcnNlcjtcbiAgICAgICAgYXhlc0NvbmZpZ1tleHBvcnRzLlZBTFVFX0ZJRUxEXSA9IHlBeGlzX3BhcnNlcjtcbiAgICAgICAgLyoqIOWtmOWCqOWdkOagh+i9tOmFjee9rumhueWIsGNvbmZpZyAqL1xuICAgICAgICB0aGlzLnNldENvbmZpZygnYXhlcycsIGF4ZXNDb25maWcpO1xuICAgIH07XG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBXYXRlcmZhbGxMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBFdmVudFBhcnNlcik7XG4gICAgfTtcbiAgICBXYXRlcmZhbGxMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlUb29sdGlwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLndhdGVyZmFsbC50b29sdGlwID0ge307XG4gICAgICAgIHZhciB0b29sdGlwT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50b29sdGlwO1xuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZmllbGRzKSB7XG4gICAgICAgICAgICB0aGlzLndhdGVyZmFsbC50b29sdGlwLmZpZWxkcyA9IHRvb2x0aXBPcHRpb25zLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICB0aGlzLndhdGVyZmFsbC50b29sdGlwLmNhbGxiYWNrID0gdG9vbHRpcE9wdGlvbnMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgaWYgKCF0b29sdGlwT3B0aW9ucy5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndhdGVyZmFsbC50b29sdGlwLmZpZWxkcyA9IFt0aGlzLm9wdGlvbnMueEZpZWxkLCBleHBvcnRzLlZBTFVFX0ZJRUxEXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgLyoqIOeJteW8lee6v+eahOagt+W8j+azqOWFpeWIsHN0eWxl5LitICovXG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLl9wYXJzZVN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLm9wdGlvbnMud2F0ZXJmYWxsU3R5bGU7XG4gICAgICAgIHZhciBsZWFkZXJMaW5lID0gdGhpcy5vcHRpb25zLmxlYWRlckxpbmU7XG4gICAgICAgIHZhciBjb25maWcgPSB7fTtcbiAgICAgICAgaWYgKHV0aWxfMS5pc0Z1bmN0aW9uKHN0eWxlKSkge1xuICAgICAgICAgICAgY29uZmlnLmNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3R5bGUuYXBwbHkodm9pZCAwLCBhcmdzKSwgeyBsZWFkZXJMaW5lOiBsZWFkZXJMaW5lIH0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5jZmcgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIHN0eWxlKSwgeyBsZWFkZXJMaW5lOiBsZWFkZXJMaW5lIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25maWc7XG4gICAgfTtcbiAgICBXYXRlcmZhbGxMYXllci5wcm90b3R5cGUuX3BhcnNlQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLm9wdGlvbnMsIHhGaWVsZCA9IF9hLnhGaWVsZCwgeUZpZWxkID0gX2EueUZpZWxkO1xuICAgICAgICB2YXIgY29uZmlnID0ge1xuICAgICAgICAgICAgZmllbGRzOiBbeEZpZWxkLCB5RmllbGQsIGV4cG9ydHMuVkFMVUVfRklFTEQsIGV4cG9ydHMuSU5ERVhfRklFTERdLFxuICAgICAgICB9O1xuICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24ob3B0aW9ucy5jb2xvcikpIHtcbiAgICAgICAgICAgIGNvbmZpZy5jYWxsYmFjayA9IG9wdGlvbnMuY29sb3I7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgcmlzaW5nQ29sb3JfMSA9ICcjZjQ2NjRhJztcbiAgICAgICAgICAgIHZhciBmYWxsaW5nQ29sb3JfMSA9ICcjMzBiZjc4JztcbiAgICAgICAgICAgIHZhciB0b3RhbENvbG9yXzEgPSAncmdiYSgwLCAwLCAwLCAwLjI1KSc7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKG9wdGlvbnMuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgcmlzaW5nQ29sb3JfMSA9IGZhbGxpbmdDb2xvcl8xID0gdG90YWxDb2xvcl8xID0gb3B0aW9ucy5jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc09iamVjdChvcHRpb25zLmNvbG9yKSkge1xuICAgICAgICAgICAgICAgIHZhciBfYiA9IG9wdGlvbnMuY29sb3IsIHJpc2luZyA9IF9iLnJpc2luZywgZmFsbGluZyA9IF9iLmZhbGxpbmcsIHRvdGFsID0gX2IudG90YWw7XG4gICAgICAgICAgICAgICAgcmlzaW5nQ29sb3JfMSA9IHJpc2luZztcbiAgICAgICAgICAgICAgICBmYWxsaW5nQ29sb3JfMSA9IGZhbGxpbmc7XG4gICAgICAgICAgICAgICAgdG90YWxDb2xvcl8xID0gdG90YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25maWcuY2FsbGJhY2sgPSBmdW5jdGlvbiAodHlwZSwgdmFsdWUsIHZhbHVlcywgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IF90aGlzLm9wdGlvbnMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsQ29sb3JfMSB8fCAodmFsdWVzWzBdID49IDAgPyByaXNpbmdDb2xvcl8xIDogZmFsbGluZ0NvbG9yXzEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gKHV0aWxfMS5pc0FycmF5KHZhbHVlcykgPyB2YWx1ZXNbMV0gLSB2YWx1ZXNbMF0gOiB2YWx1ZXMpID49IDAgPyByaXNpbmdDb2xvcl8xIDogZmFsbGluZ0NvbG9yXzE7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25maWc7XG4gICAgfTtcbiAgICAvKiog5aSN5YaZIGxlZ2VuZCDphY3nva4sIOeAkeW4g+Wbvum7mOiupOaXoGxlZ2VuZCAqL1xuICAgIFdhdGVyZmFsbExheWVyLnByb3RvdHlwZS5hZGp1c3RMZWdlbmRPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIGxlZ2VuZE9wdGlvbnMgPSBvcHRpb25zLmxlZ2VuZDtcbiAgICAgICAgaWYgKGxlZ2VuZE9wdGlvbnMpIHtcbiAgICAgICAgICAgIGxlZ2VuZE9wdGlvbnMudmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKiog5aSN5YaZIG1ldGEg6YWN572uICovXG4gICAgV2F0ZXJmYWxsTGF5ZXIucHJvdG90eXBlLmFkanVzdE1ldGEgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICB2YXIgbWV0YU9wdGlvbnMgPSBvcHRpb25zLm1ldGE7XG4gICAgICAgIGlmIChtZXRhT3B0aW9ucykge1xuICAgICAgICAgICAgdmFyIHZhbHVlRmllbGRNZXRhID0gbWV0YU9wdGlvbnMgPyBtZXRhT3B0aW9uc1tvcHRpb25zLnlGaWVsZF0gOiB7fTtcbiAgICAgICAgICAgIHZhbHVlRmllbGRNZXRhLmFsaWFzID0gdmFsdWVGaWVsZE1ldGEuYWxpYXMgfHwgb3B0aW9ucy55RmllbGQ7XG4gICAgICAgICAgICBvcHRpb25zLm1ldGFbZXhwb3J0cy5WQUxVRV9GSUVMRF0gPSB2YWx1ZUZpZWxkTWV0YTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIFdhdGVyZmFsbExheWVyO1xufSh2aWV3X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gV2F0ZXJmYWxsTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCd3YXRlcmZhbGwnLCBXYXRlcmZhbGxMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xuLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE0XG4gKi9cbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIFdvcmRDbG91ZCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhXb3JkQ2xvdWQsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gV29yZENsb3VkKGNvbnRhaW5lciwgcHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgLy8gb25seSBjYW52YXMgd29ya3MgZm9yIG5vd1xuICAgICAgICBwcm9wcy5yZW5kZXJlciA9ICdjYW52YXMnO1xuICAgICAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbnRhaW5lciwgcHJvcHMpIHx8IHRoaXM7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgV29yZENsb3VkLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAnd29yZENsb3VkJztcbiAgICAgICAgbGF5ZXJQcm9wcy5jb250YWluZXIgPSB0aGlzLmNvbnRhaW5lckRPTTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIHJldHVybiBXb3JkQ2xvdWQ7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBXb3JkQ2xvdWQ7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCd3b3JkQ2xvdWQnLCBsYXllcl8xLmRlZmF1bHQpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvbGF5ZXJcIikpO1xudmFyIHdvcmRfY2xvdWRfdG9vbHRpcHNfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3dvcmQtY2xvdWQtdG9vbHRpcHNcIikpO1xudmFyIHdvcmRjbG91ZDJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3dvcmRjbG91ZDJcIikpO1xudmFyIFdvcmRDbG91ZExheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFdvcmRDbG91ZExheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFdvcmRDbG91ZExheWVyKHByb3BzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHByb3BzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5fdG9vbFRpcHNBY3Rpb24gPSBmdW5jdGlvbiAoaXRlbSwgZGltZW5zaW9uLCBldnQsIHN0YXJ0KSB7XG4gICAgICAgICAgICBpZiAoZGltZW5zaW9uKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX3Rvb2xUaXBzLnVwZGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I6IGl0ZW0uY29sb3IgfHwgJ3JlZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogaXRlbS53b3JkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBpdGVtLndlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIHg6IGV2dC5vZmZzZXRYLFxuICAgICAgICAgICAgICAgICAgICB5OiBldnQub2Zmc2V0WSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBfdGhpcy5fdG9vbFRpcHMuc2hvdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX3Rvb2xUaXBzLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF90aGlzLl90b29sVGlwcy5yZW5kZXIoKTtcbiAgICAgICAgICAgIF90aGlzLl9jb25maWdIb3ZlckFjdGlvbiAmJiBfdGhpcy5fY29uZmlnSG92ZXJBY3Rpb24oaXRlbSwgZGltZW5zaW9uLCBldnQsIHN0YXJ0KTtcbiAgICAgICAgfTtcbiAgICAgICAgX3RoaXMuX2NvbmZpZ0hvdmVyQWN0aW9uID0gcHJvcHMub25Xb3JkQ2xvdWRIb3ZlcjtcbiAgICAgICAgX3RoaXMuX2VuYWJsZVRvb2xUaXBzID0gdXRpbF8xLmdldChwcm9wcywgJ3Rvb2x0aXAudmlzaWJsZScsIHRydWUpO1xuICAgICAgICBfdGhpcy5vcHRpb25zID0gdXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgIHdpZHRoOiA0MDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDQwMCxcbiAgICAgICAgICAgIGVuYWJsZVRvb2xUaXBzOiB0cnVlLFxuICAgICAgICB9LCBwcm9wcywgXG4gICAgICAgIC8vIHJlcGxhY2UgdXNlIGNvbmZpZydzIGhvdmVyIGFjdGlvbiBpZiBuZWVkZWQsIGFuZCB0cmlnZ2VyIGxhdGVyXG4gICAgICAgIHtcbiAgICAgICAgICAgIG9uV29yZENsb3VkSG92ZXI6IF90aGlzLl9lbmFibGVUb29sVGlwcyA/IF90aGlzLl90b29sVGlwc0FjdGlvbiA6IF90aGlzLl9jb25maWdIb3ZlckFjdGlvbixcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgV29yZENsb3VkTGF5ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLl9pbml0VG9vbFRpcHMoKTtcbiAgICB9O1xuICAgIFdvcmRDbG91ZExheWVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucmVuZGVyLmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcigpO1xuICAgIH07XG4gICAgV29yZENsb3VkTGF5ZXIucHJvdG90eXBlLl9pbml0VG9vbFRpcHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX3Rvb2xUaXBzID0gbmV3IHdvcmRfY2xvdWRfdG9vbHRpcHNfMS5kZWZhdWx0KHtcbiAgICAgICAgICAgIHNob3dUaXRsZTogZmFsc2UsXG4gICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmVudDogdGhpcy5vcHRpb25zLmNvbnRhaW5lcixcbiAgICAgICAgICAgIGZvbGxvdzogdHJ1ZSxcbiAgICAgICAgICAgIGluUGFuZWw6IGZhbHNlLFxuICAgICAgICAgICAgaXRlbXM6IFtdLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdG9vbFRpcHMuaW5pdCgpO1xuICAgIH07XG4gICAgV29yZENsb3VkTGF5ZXIucHJvdG90eXBlLl9yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX3RhcmdldENhbnZhcyA9IHRoaXMuY2FudmFzLmdldCgnZWwnKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5tYXNrSW1hZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuX2hhbmRsZU1hc2tJbWFnZSgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gbWFzayBpbWFnZSBub3QgZXhpc3RcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFdvcmRDbG91ZExheWVyLnByb3RvdHlwZS5faGFuZGxlTWFza0ltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gdGhpcy5vcHRpb25zLm1hc2tJbWFnZSArICc/JyArIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBpbWFnZS5jcm9zc09yaWdpbiA9ICdBbm9ueW1vdXMnO1xuICAgICAgICBpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoaW1hZ2UubmF0dXJhbEhlaWdodCArIGltYWdlLm5hdHVyYWxXaWR0aCA9PT0gMCB8fCBpbWFnZS53aWR0aCArIGltYWdlLmhlaWdodCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIF90aGlzLl9zdGFydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gaGFuZGxlIG5vLXplcm8gaW1hZ2Ugc2lsaG91ZXR0ZVxuICAgICAgICAgICAgICAgIF90aGlzLl9zdGFydFdpdGhNYXNrSW1hZ2UoaW1hZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignaW1hZ2UgJXMgbG9hZCBmYWlsZWQgISEhJywgX3RoaXMub3B0aW9ucy5tYXNrSW1hZ2UpO1xuICAgICAgICAgICAgLy8gbG9hZCBpbWFnZSBlcnJvciwgaWdub3JlIHRoaXMgbWFza1xuICAgICAgICAgICAgX3RoaXMuX3N0YXJ0KCk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBXb3JkQ2xvdWRMYXllci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9oYW5kbGVHMlBsb3RDb25maWcoKTtcbiAgICAgICAgdmFyIHRhcmdldEN0eCA9IHRoaXMuX3RhcmdldENhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICAvLyBpdCdzIGEgdHJpY2ssIGJlY2F1c2Ug44CMZ+OAjSB1c2UgY29udGV4dCB0byBzY2FsZSBjYW52YXMgYnkgcGl4ZWxSYXRpbyxcbiAgICAgICAgLy8gYnV0IGhlcmUgaSBuZWVkIHNjYWxlIGl0IGJhY2tcbiAgICAgICAgdmFyIHBpeGVsUmF0aW8gPSB0aGlzLmNhbnZhcy5nZXQoJ3dpZHRoJykgLyB0aGlzLmNhbnZhcy5nZXQoJ2VsJykud2lkdGg7XG4gICAgICAgIHRhcmdldEN0eC5zY2FsZShwaXhlbFJhdGlvLCBwaXhlbFJhdGlvKTtcbiAgICAgICAgd29yZGNsb3VkMl8xLmRlZmF1bHQodGhpcy5fdGFyZ2V0Q2FudmFzLCB0aGlzLm9wdGlvbnMpO1xuICAgIH07XG4gICAgV29yZENsb3VkTGF5ZXIucHJvdG90eXBlLl9oYW5kbGVHMlBsb3RDb25maWcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmb250U2l6ZSA9IHRoaXMub3B0aW9ucy53b3JkU3R5bGUuZm9udFNpemUgfHwgWzEwLCA2MF07XG4gICAgICAgIHZhciByb3RhdGlvbiA9IHRoaXMub3B0aW9ucy53b3JkU3R5bGUucm90YXRpb24gfHwgWy1NYXRoLlBJIC8gMiwgTWF0aC5QSSAvIDJdO1xuICAgICAgICB2YXIgYWN0aXZlLCBzaGFkb3dDb2xvciwgc2hhZG93Qmx1cjtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy53b3JkU3R5bGUuYWN0aXZlKSB7XG4gICAgICAgICAgICBhY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgc2hhZG93Q29sb3IgPSB0aGlzLm9wdGlvbnMud29yZFN0eWxlLmFjdGl2ZS5zaGFkb3dDb2xvciB8fCAnIzMzMyc7XG4gICAgICAgICAgICBzaGFkb3dCbHVyID0gdGhpcy5vcHRpb25zLndvcmRTdHlsZS5hY3RpdmUuc2hhZG93Qmx1ciB8fCAxMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHV0aWxfMS5kZWVwTWl4KHt9LCB0aGlzLm9wdGlvbnMsIHtcbiAgICAgICAgICAgIG1pbkZvbnRTaXplOiBmb250U2l6ZVswXSxcbiAgICAgICAgICAgIG1heEZvbnRTaXplOiBmb250U2l6ZVsxXSxcbiAgICAgICAgICAgIG1pblJvdGF0aW9uOiByb3RhdGlvblswXSxcbiAgICAgICAgICAgIG1heFJvdGF0aW9uOiByb3RhdGlvblsxXSxcbiAgICAgICAgICAgIGFjdGl2ZTogYWN0aXZlLFxuICAgICAgICAgICAgc2hhZG93Q29sb3I6IHNoYWRvd0NvbG9yLFxuICAgICAgICAgICAgc2hhZG93Qmx1cjogc2hhZG93Qmx1cixcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBXb3JkQ2xvdWRMYXllci5wcm90b3R5cGUuX3N0YXJ0V2l0aE1hc2tJbWFnZSA9IGZ1bmN0aW9uIChpbWFnZSkge1xuICAgICAgICB2YXIgX2EgPSB0aGlzLl9zY2FsZU1hc2tJbWFnZUNhbnZhcyh0aGlzLl90cmFuc2Zvcm1XaGl0ZTJCbGFja1BpeGVscyhpbWFnZSkpLCBtYXNrSW1hZ2VDYW52YXMgPSBfYS5tYXNrSW1hZ2VDYW52YXMsIG1hc2tJbWFnZUNvbnRleHQgPSBfYS5tYXNrSW1hZ2VDb250ZXh0O1xuICAgICAgICAvKiBEZXRlcm1pbmUgYmdQaXhlbCBieSBjcmVhdGluZ1xuICAgICAgICAgYW5vdGhlciBjYW52YXMgYW5kIGZpbGwgdGhlIHNwZWNpZmllZCBiYWNrZ3JvdW5kIGNvbG9yLiAqL1xuICAgICAgICB2YXIgYmN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGJjdHguZmlsbFN0eWxlID0gdGhpcy5vcHRpb25zLmJhY2tncm91bmRDb2xvciB8fCAnI2ZmZic7XG4gICAgICAgIGJjdHguZmlsbFJlY3QoMCwgMCwgMSwgMSk7XG4gICAgICAgIHZhciBiZ1BpeGVsID0gYmN0eC5nZXRJbWFnZURhdGEoMCwgMCwgMSwgMSkuZGF0YTtcbiAgICAgICAgdmFyIGltYWdlRGF0YSA9IG1hc2tJbWFnZUNvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIG1hc2tJbWFnZUNhbnZhcy53aWR0aCwgbWFza0ltYWdlQ2FudmFzLmhlaWdodCk7XG4gICAgICAgIHZhciBuZXdJbWFnZURhdGEgPSBtYXNrSW1hZ2VDb250ZXh0LmNyZWF0ZUltYWdlRGF0YShpbWFnZURhdGEpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltYWdlRGF0YS5kYXRhLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICAgICAgICBpZiAoaW1hZ2VEYXRhLmRhdGFbaSArIDNdID4gMTI4KSB7XG4gICAgICAgICAgICAgICAgLy8ga2VlcCB0aGlzIGFyZWEncyBkYXRhIHRoZSBzYW1lIGFzIHBpeGVsIGNvbG9yXG4gICAgICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaV0gPSBiZ1BpeGVsWzBdO1xuICAgICAgICAgICAgICAgIG5ld0ltYWdlRGF0YS5kYXRhW2kgKyAxXSA9IGJnUGl4ZWxbMV07XG4gICAgICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaSArIDJdID0gYmdQaXhlbFsyXTtcbiAgICAgICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgM10gPSBiZ1BpeGVsWzNdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb2xvciBtdXN0IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGUgYmdQaXhlbC5cbiAgICAgICAgICAgICAgICAvLyBjaGVjayB3b3JkY2xvdWQyLmpzIzExOTIgJ3MgY29uZGl0aW9uXG4gICAgICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaV0gPSBiZ1BpeGVsWzBdO1xuICAgICAgICAgICAgICAgIG5ld0ltYWdlRGF0YS5kYXRhW2kgKyAxXSA9IGJnUGl4ZWxbMV07XG4gICAgICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaSArIDJdID0gYmdQaXhlbFsyXTtcbiAgICAgICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgM10gPSAyNTQ7IC8vIGp1c3QgZm9yIG5vdCBzYW1lIGFzIHRoZSBiZyBjb2xvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1hc2tJbWFnZUNvbnRleHQucHV0SW1hZ2VEYXRhKG5ld0ltYWdlRGF0YSwgMCwgMCk7XG4gICAgICAgIHZhciB0YXJnZXRDdHggPSB0aGlzLl90YXJnZXRDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgdGFyZ2V0Q3R4LmRyYXdJbWFnZShtYXNrSW1hZ2VDYW52YXMsIDAsIDApO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSB1dGlsXzEuZGVlcE1peCh7fSwgdGhpcy5vcHRpb25zLCB7IGNsZWFyQ2FudmFzOiBmYWxzZSB9KTtcbiAgICAgICAgdGhpcy5fc3RhcnQoKTtcbiAgICB9O1xuICAgIFdvcmRDbG91ZExheWVyLnByb3RvdHlwZS5fc2NhbGVNYXNrSW1hZ2VDYW52YXMgPSBmdW5jdGlvbiAobWFza0ltYWdlQ2FudmFzKSB7XG4gICAgICAgIHZhciBtYXNrQ2FudmFzU2NhbGVkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgIC8vIGdldCByZWFsIGNhbnZhcyBkZXRlcm1pbmVkIGJ5IHBpeGVsUmF0aW9cbiAgICAgICAgbWFza0NhbnZhc1NjYWxlZC53aWR0aCA9IHRoaXMuY2FudmFzLmdldCgnd2lkdGgnKTtcbiAgICAgICAgbWFza0NhbnZhc1NjYWxlZC5oZWlnaHQgPSB0aGlzLmNhbnZhcy5nZXQoJ2hlaWdodCcpO1xuICAgICAgICB2YXIgY3R4ID0gbWFza0NhbnZhc1NjYWxlZC5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICAvLyBrZWVwIHNjYWxlIHNtb290aFxuICAgICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgLy8gY3R4Lm1vekltYWdlU21vb3RoaW5nRW5hYmxlZCA9IHRydWU7XG4gICAgICAgIC8vIGN0eC53ZWJraXRJbWFnZVNtb290aGluZ0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAvLyBjdHgubXNJbWFnZVNtb290aGluZ0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICBjdHguZHJhd0ltYWdlKG1hc2tJbWFnZUNhbnZhcywgMCwgMCwgbWFza0ltYWdlQ2FudmFzLndpZHRoLCBtYXNrSW1hZ2VDYW52YXMuaGVpZ2h0LCAwLCAwLCBtYXNrQ2FudmFzU2NhbGVkLndpZHRoLCBtYXNrQ2FudmFzU2NhbGVkLmhlaWdodCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtYXNrSW1hZ2VDYW52YXM6IG1hc2tDYW52YXNTY2FsZWQsXG4gICAgICAgICAgICBtYXNrSW1hZ2VDb250ZXh0OiBjdHgsXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBXb3JkQ2xvdWRMYXllci5wcm90b3R5cGUuX3RyYW5zZm9ybVdoaXRlMkJsYWNrUGl4ZWxzID0gZnVuY3Rpb24gKGltYWdlKSB7XG4gICAgICAgIHZhciBtYXNrSW1hZ2VDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgICAgbWFza0ltYWdlQ2FudmFzLndpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgICAgIG1hc2tJbWFnZUNhbnZhcy5oZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICAgIHZhciBjdHggPSBtYXNrSW1hZ2VDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY3R4LmRyYXdJbWFnZShpbWFnZSwgMCwgMCwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCk7XG4gICAgICAgIHZhciBpbWFnZURhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIG1hc2tJbWFnZUNhbnZhcy53aWR0aCwgbWFza0ltYWdlQ2FudmFzLmhlaWdodCk7XG4gICAgICAgIHZhciBTSU5HTEVfQ09NUE9ORU5UX1NJWkUgPSA0O1xuICAgICAgICB2YXIgQkxBQ0tfUElYRUwgPSAwO1xuICAgICAgICB2YXIgRlVMTF9QSVhFTCA9IDI1NTtcbiAgICAgICAgLy8gUiAtIEcgLSBCIC0gQVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltYWdlRGF0YS5kYXRhLmxlbmd0aDsgaSArPSBTSU5HTEVfQ09NUE9ORU5UX1NJWkUpIHtcbiAgICAgICAgICAgIHZhciByZ2IgPSBpbWFnZURhdGEuZGF0YVtpXSArIGltYWdlRGF0YS5kYXRhW2kgKyAxXSArIGltYWdlRGF0YS5kYXRhW2kgKyAyXTtcbiAgICAgICAgICAgIHZhciBhbHBoYSA9IGltYWdlRGF0YS5kYXRhW2kgKyAzXTtcbiAgICAgICAgICAgIGlmIChhbHBoYSA8IDEyOCB8fCByZ2IgPiAyNTAgKiAzKSB7XG4gICAgICAgICAgICAgICAgLy8gd2hpdGUgYXJlYShub3QgdG8gZHJhdylcbiAgICAgICAgICAgICAgICBpbWFnZURhdGEuZGF0YVtpXSA9IEZVTExfUElYRUw7XG4gICAgICAgICAgICAgICAgaW1hZ2VEYXRhLmRhdGFbaSArIDFdID0gRlVMTF9QSVhFTDtcbiAgICAgICAgICAgICAgICBpbWFnZURhdGEuZGF0YVtpICsgMl0gPSBGVUxMX1BJWEVMO1xuICAgICAgICAgICAgICAgIGltYWdlRGF0YS5kYXRhW2kgKyAzXSA9IEJMQUNLX1BJWEVMO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gYmxhY2sgYXJlYSB3YWl0IHRvIGRyYXcoaW1hZ2UgYmxhY2sgc2lsaG91ZXR0ZSlcbiAgICAgICAgICAgICAgICBpbWFnZURhdGEuZGF0YVtpXSA9IEJMQUNLX1BJWEVMO1xuICAgICAgICAgICAgICAgIGltYWdlRGF0YS5kYXRhW2kgKyAxXSA9IEJMQUNLX1BJWEVMO1xuICAgICAgICAgICAgICAgIGltYWdlRGF0YS5kYXRhW2kgKyAyXSA9IEJMQUNLX1BJWEVMO1xuICAgICAgICAgICAgICAgIGltYWdlRGF0YS5kYXRhW2kgKyAzXSA9IEZVTExfUElYRUw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY3R4LnB1dEltYWdlRGF0YShpbWFnZURhdGEsIDAsIDApO1xuICAgICAgICByZXR1cm4gbWFza0ltYWdlQ2FudmFzO1xuICAgIH07XG4gICAgcmV0dXJuIFdvcmRDbG91ZExheWVyO1xufShsYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFdvcmRDbG91ZExheWVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICogQ3JlYXRlIEJ5IEJydWNlIFRvb1xuICogT24gMjAyMC0wMi0xNFxuICovXG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uLy4uL2RlcGVuZGVudHNcIik7XG52YXIgV29yZENsb3VkVG9vbHRpcHMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoV29yZENsb3VkVG9vbHRpcHMsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gV29yZENsb3VkVG9vbHRpcHMoY2ZnKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBuZXdDZmcgPSB1dGlsXzEuZGVlcE1peCh7fSwgY2ZnLCB7XG4gICAgICAgICAgICBpdGVtVHBsOiBcIjxkaXYgZGF0YS1pbmRleD17aW5kZXh9PlxcbiAgICAgICAgPHNwYW4gc3R5bGU9XFxcImJhY2tncm91bmQtY29sb3I6e2NvbG9yfTtcXFwiIGNsYXNzPVxcXCJnMi10b29sdGlwLW1hcmtlclxcXCI+PC9zcGFuPlxcbiAgICAgICAge25hbWV9PHNwYW4gY2xhc3M9XFxcImcyLXRvb2x0aXAtdmFsdWVcXFwiPnt2YWx1ZX08L3NwYW4+PC9kaXY+XCIsXG4gICAgICAgIH0sIGNmZyk7XG4gICAgICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgbmV3Q2ZnKSB8fCB0aGlzO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIHJldHVybiBXb3JkQ2xvdWRUb29sdGlwcztcbn0oZGVwZW5kZW50c18xLkh0bWxUb29sdGlwKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBXb3JkQ2xvdWRUb29sdGlwcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdvcmQtY2xvdWQtdG9vbHRpcHMuanMubWFwIiwiLyoqXG4gKiBDcmVhdGUgQnkgQnJ1Y2UgVG9vXG4gKiBPbiAyMDIwLTAyLTE0XG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIHVuaWNvcm4vbm8tYWJ1c2l2ZS1lc2xpbnQtZGlzYWJsZSAqL1xuLyogZXNsaW50LWRpc2FibGUgKi9cbi8vIEB0cy1ub2NoZWNrXG4vLyBUT0RPIHJld3JpdGUgd2l0aCB0eXBlc2NyaXB0IEBicnVjZXRvb1xuLyohXG4gKiB3b3JkY2xvdWQyLmpzXG4gKiBodHRwOi8vdGltZHJlYW0ub3JnL3dvcmRjbG91ZDIuanMvXG4gKlxuICogQ29weXJpZ2h0IDIwMTEgLSAyMDEzIFRpbSBDaGllblxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKi9cbid1c2Ugc3RyaWN0Jztcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuLy8gc2V0SW1tZWRpYXRlXG5pZiAoIXdpbmRvdy5zZXRJbW1lZGlhdGUpIHtcbiAgICB3aW5kb3cuc2V0SW1tZWRpYXRlID0gKGZ1bmN0aW9uIHNldHVwU2V0SW1tZWRpYXRlKCkge1xuICAgICAgICByZXR1cm4gKHdpbmRvdy5tc1NldEltbWVkaWF0ZSB8fFxuICAgICAgICAgICAgd2luZG93LndlYmtpdFNldEltbWVkaWF0ZSB8fFxuICAgICAgICAgICAgd2luZG93Lm1velNldEltbWVkaWF0ZSB8fFxuICAgICAgICAgICAgd2luZG93Lm9TZXRJbW1lZGlhdGUgfHxcbiAgICAgICAgICAgIChmdW5jdGlvbiBzZXR1cFNldFplcm9UaW1lb3V0KCkge1xuICAgICAgICAgICAgICAgIGlmICghd2luZG93LnBvc3RNZXNzYWdlIHx8ICF3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrcyA9IFt1bmRlZmluZWRdO1xuICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gJ3plcm8tdGltZW91dC1tZXNzYWdlJztcbiAgICAgICAgICAgICAgICAvLyBMaWtlIHNldFRpbWVvdXQsIGJ1dCBvbmx5IHRha2VzIGEgZnVuY3Rpb24gYXJndW1lbnQuICBUaGVyZSdzXG4gICAgICAgICAgICAgICAgLy8gbm8gdGltZSBhcmd1bWVudCAoYWx3YXlzIHplcm8pIGFuZCBubyBhcmd1bWVudHMgKHlvdSBoYXZlIHRvXG4gICAgICAgICAgICAgICAgLy8gdXNlIGEgY2xvc3VyZSkuXG4gICAgICAgICAgICAgICAgdmFyIHNldFplcm9UaW1lb3V0ID0gZnVuY3Rpb24gc2V0WmVyb1RpbWVvdXQoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlkID0gY2FsbGJhY2tzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UobWVzc2FnZSArIGlkLnRvU3RyaW5nKDM2KSwgJyonKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiBzZXRaZXJvVGltZW91dE1lc3NhZ2UoZXZ0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNraXBwaW5nIGNoZWNraW5nIGV2ZW50IHNvdXJjZSwgcmV0YXJkZWQgSUUgY29uZnVzZWQgdGhpcyB3aW5kb3dcbiAgICAgICAgICAgICAgICAgICAgLy8gb2JqZWN0IHdpdGggYW5vdGhlciBpbiB0aGUgcHJlc2VuY2Ugb2YgaWZyYW1lXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXZ0LmRhdGEgIT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBldnQuZGF0YS5zdWJzdHIoMCwgbWVzc2FnZS5sZW5ndGgpICE9PSBtZXNzYWdlIC8qIHx8XG4gICAgICAgICAgICAgICAgICBldnQuc291cmNlICE9PSB3aW5kb3cgKi8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBldnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZCA9IHBhcnNlSW50KGV2dC5kYXRhLnN1YnN0cihtZXNzYWdlLmxlbmd0aCksIDM2KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYWxsYmFja3NbaWRdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzW2lkXSgpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3NbaWRdID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH0sIHRydWUpO1xuICAgICAgICAgICAgICAgIC8qIHNwZWNpZnkgY2xlYXJJbW1lZGlhdGUoKSBoZXJlIHNpbmNlIHdlIG5lZWQgdGhlIHNjb3BlICovXG4gICAgICAgICAgICAgICAgd2luZG93LmNsZWFySW1tZWRpYXRlID0gZnVuY3Rpb24gY2xlYXJaZXJvVGltZW91dChpZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNhbGxiYWNrc1tpZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3NbaWRdID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNldFplcm9UaW1lb3V0O1xuICAgICAgICAgICAgfSkoKSB8fFxuICAgICAgICAgICAgLy8gZmFsbGJhY2tcbiAgICAgICAgICAgIGZ1bmN0aW9uIHNldEltbWVkaWF0ZUZhbGxiYWNrKGZuKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZm4sIDApO1xuICAgICAgICAgICAgfSk7XG4gICAgfSkoKTtcbn1cbmlmICghd2luZG93LmNsZWFySW1tZWRpYXRlKSB7XG4gICAgd2luZG93LmNsZWFySW1tZWRpYXRlID0gKGZ1bmN0aW9uIHNldHVwQ2xlYXJJbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiAod2luZG93Lm1zQ2xlYXJJbW1lZGlhdGUgfHxcbiAgICAgICAgICAgIHdpbmRvdy53ZWJraXRDbGVhckltbWVkaWF0ZSB8fFxuICAgICAgICAgICAgd2luZG93Lm1vekNsZWFySW1tZWRpYXRlIHx8XG4gICAgICAgICAgICB3aW5kb3cub0NsZWFySW1tZWRpYXRlIHx8XG4gICAgICAgICAgICAvLyBcImNsZWFyWmVyb1RpbWVvdXRcIiBpcyBpbXBsZW1lbnQgb24gdGhlIHByZXZpb3VzIGJsb2NrIHx8XG4gICAgICAgICAgICAvLyBmYWxsYmFja1xuICAgICAgICAgICAgZnVuY3Rpb24gY2xlYXJJbW1lZGlhdGVGYWxsYmFjayh0aW1lcikge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgfSkoKTtcbn1cbi8vIENoZWNrIGlmIFdvcmRDbG91ZCBjYW4gcnVuIG9uIHRoaXMgYnJvd3NlclxudmFyIGlzU3VwcG9ydGVkID0gKGZ1bmN0aW9uIGlzU3VwcG9ydGVkKCkge1xuICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBpZiAoIWNhbnZhcyB8fCAhY2FudmFzLmdldENvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgaWYgKCFjdHguZ2V0SW1hZ2VEYXRhKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFjdHguZmlsbFRleHQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIUFycmF5LnByb3RvdHlwZS5zb21lKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5wcm90b3R5cGUucHVzaCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufSkoKTtcbi8vIEZpbmQgb3V0IGlmIHRoZSBicm93c2VyIGltcG9zZSBtaW5pdW0gZm9udCBzaXplIGJ5XG4vLyBkcmF3aW5nIHNtYWxsIHRleHRzIG9uIGEgY2FudmFzIGFuZCBtZWFzdXJlIGl0J3Mgd2lkdGguXG52YXIgbWluRm9udFNpemUgPSAoZnVuY3Rpb24gZ2V0TWluRm9udFNpemUoKSB7XG4gICAgaWYgKCFpc1N1cHBvcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBjdHggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKS5nZXRDb250ZXh0KCcyZCcpO1xuICAgIC8vIHN0YXJ0IGZyb20gMjBcbiAgICB2YXIgc2l6ZSA9IDIwO1xuICAgIC8vIHR3byBzaXplcyB0byBtZWFzdXJlXG4gICAgdmFyIGhhbldpZHRoLCBtV2lkdGg7XG4gICAgd2hpbGUgKHNpemUpIHtcbiAgICAgICAgY3R4LmZvbnQgPSBzaXplLnRvU3RyaW5nKDEwKSArICdweCBzYW5zLXNlcmlmJztcbiAgICAgICAgaWYgKGN0eC5tZWFzdXJlVGV4dCgnXFx1RkYzNycpLndpZHRoID09PSBoYW5XaWR0aCAmJiBjdHgubWVhc3VyZVRleHQoJ20nKS53aWR0aCA9PT0gbVdpZHRoKSB7XG4gICAgICAgICAgICByZXR1cm4gc2l6ZSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgaGFuV2lkdGggPSBjdHgubWVhc3VyZVRleHQoJ1xcdUZGMzcnKS53aWR0aDtcbiAgICAgICAgbVdpZHRoID0gY3R4Lm1lYXN1cmVUZXh0KCdtJykud2lkdGg7XG4gICAgICAgIHNpemUtLTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59KSgpO1xuLy8gQmFzZWQgb24gaHR0cDovL2pzZnJvbWhlbGwuY29tL2FycmF5L3NodWZmbGVcbnZhciBzaHVmZmxlQXJyYXkgPSBmdW5jdGlvbiBzaHVmZmxlQXJyYXkoYXJyKSB7XG4gICAgZm9yICh2YXIgaiwgeCwgaSA9IGFyci5sZW5ndGg7IGk7IGogPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBpKSwgeCA9IGFyclstLWldLCBhcnJbaV0gPSBhcnJbal0sIGFycltqXSA9IHgpIHsgfVxuICAgIHJldHVybiBhcnI7XG59O1xudmFyIFdvcmRDbG91ZCA9IGZ1bmN0aW9uIFdvcmRDbG91ZChlbGVtZW50cywgb3B0aW9ucykge1xuICAgIGlmICghaXNTdXBwb3J0ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZWxlbWVudHMpKSB7XG4gICAgICAgIGVsZW1lbnRzID0gW2VsZW1lbnRzXTtcbiAgICB9XG4gICAgZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZWwsIGkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBlbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzW2ldID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWwpO1xuICAgICAgICAgICAgaWYgKCFlbGVtZW50c1tpXSkge1xuICAgICAgICAgICAgICAgIHRocm93ICdUaGUgZWxlbWVudCBpZCBzcGVjaWZpZWQgaXMgbm90IGZvdW5kLic7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWVsLnRhZ05hbWUgJiYgIWVsLmFwcGVuZENoaWxkKSB7XG4gICAgICAgICAgICB0aHJvdyAnWW91IG11c3QgcGFzcyB2YWxpZCBIVE1MIGVsZW1lbnRzLCBvciBJRCBvZiB0aGUgZWxlbWVudC4nO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgLyogRGVmYXVsdCB2YWx1ZXMgdG8gYmUgb3ZlcndyaXR0ZW4gYnkgb3B0aW9ucyBvYmplY3QgKi9cbiAgICB2YXIgc2V0dGluZ3MgPSB7XG4gICAgICAgIGRhdGE6IFtdLFxuICAgICAgICBmb250RmFtaWx5OiAnXCJUcmVidWNoZXQgTVNcIiwgXCJIZWl0aSBUQ1wiLCBcIuW+rui7n+ato+m7kemrlFwiLCAnICsgJ1wiQXJpYWwgVW5pY29kZSBNU1wiLCBcIkRyb2lkIEZhbGxiYWNrIFNhbnNcIiwgc2Fucy1zZXJpZicsXG4gICAgICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgICAgICBjb2xvcjogJ3JhbmRvbS1kYXJrJyxcbiAgICAgICAgbWluRm9udFNpemU6IG1pbkZvbnRTaXplLFxuICAgICAgICBtYXhGb250U2l6ZTogNjAsXG4gICAgICAgIGNsZWFyQ2FudmFzOiB0cnVlLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICcjZmZmJyxcbiAgICAgICAgZ3JpZFNpemU6IDgsXG4gICAgICAgIGRyYXdPdXRPZkJvdW5kOiBmYWxzZSxcbiAgICAgICAgb3JpZ2luOiBudWxsLFxuICAgICAgICBkcmF3TWFzazogZmFsc2UsXG4gICAgICAgIG1hc2tDb2xvcjogJ3JnYmEoMjU1LDAsMCwwLjMpJyxcbiAgICAgICAgbWFza0dhcFdpZHRoOiAwLjMsXG4gICAgICAgIHdhaXQ6IDAsXG4gICAgICAgIGFib3J0VGhyZXNob2xkOiAwLFxuICAgICAgICBhYm9ydDogZnVuY3Rpb24gbm9vcCgpIHsgfSxcbiAgICAgICAgbWluUm90YXRpb246IC1NYXRoLlBJIC8gMixcbiAgICAgICAgbWF4Um90YXRpb246IE1hdGguUEkgLyAyLFxuICAgICAgICByb3RhdGVSYXRpbzogMC41LFxuICAgICAgICByb3RhdGlvblN0ZXBzOiAxLFxuICAgICAgICBzaHVmZmxlOiB0cnVlLFxuICAgICAgICBzaGFwZTogJ2NpcmNsZScsXG4gICAgICAgIGVsbGlwdGljaXR5OiAxLFxuICAgICAgICBhY3RpdmU6IHRydWUsXG4gICAgICAgIGFuaW1hdGFibGU6IHRydWUsXG4gICAgICAgIHNlbGVjdGVkOiAtMSxcbiAgICAgICAgc2hhZG93Q29sb3I6ICcjMzMzJyxcbiAgICAgICAgc2hhZG93Qmx1cjogMTAsXG4gICAgICAgIGZvbnRTY2FsZTogMS4yLFxuICAgICAgICBjbGFzc2VzOiBudWxsLFxuICAgICAgICBvbldvcmRDbG91ZEhvdmVyOiBudWxsLFxuICAgICAgICBvbldvcmRDbG91ZENsaWNrOiBudWxsLFxuICAgIH07XG4gICAgdmFyIGludGVyYWN0aW9uSXRlbXMgPSBbXTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKGtleSA9PT0gJ3dvcmRTdHlsZScpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBmb250S2V5IGluIG9wdGlvbnNba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZm9udEtleSBpbiBzZXR0aW5ncykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NbZm9udEtleV0gPSBvcHRpb25zW2tleV1bZm9udEtleV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoa2V5IGluIHNldHRpbmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmdzW2tleV0gPSBvcHRpb25zW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChzZXR0aW5ncy5taW5Gb250U2l6ZSA8IG1pbkZvbnRTaXplKSB7XG4gICAgICAgIC8vIGNhbid0IGxlc3MgdGhhbiBicm93c2UncyBtaW4gZm9udCBzaXplXG4gICAgICAgIHNldHRpbmdzLm1pbkZvbnRTaXplID0gbWluRm9udFNpemU7XG4gICAgfVxuICAgIGlmIChzZXR0aW5ncy5taW5Gb250U2l6ZSA+IHNldHRpbmdzLm1heEZvbnRTaXplKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ21pblNpemUgY2FudCBiaWdnZXIgdGhhbiBtYXhTaXplJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIG1heFdlaWdodCA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXR0aW5ncy5kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChtYXhXZWlnaHQgPCBzZXR0aW5ncy5kYXRhW2ldLndlaWdodCkge1xuICAgICAgICAgICAgbWF4V2VpZ2h0ID0gc2V0dGluZ3MuZGF0YVtpXS53ZWlnaHQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIGdldFJlYWxGb250U2l6ZSA9IGZ1bmN0aW9uIGdldFJlYWxGb250U2l6ZSh3ZWlnaHQpIHtcbiAgICAgICAgdmFyIGZvbnRTaXplID0gTWF0aC5taW4oTWF0aC5tYXgoc2V0dGluZ3MubWluRm9udFNpemUsIChzZXR0aW5ncy5tYXhGb250U2l6ZSAqIHdlaWdodCkgLyBtYXhXZWlnaHQpLCBzZXR0aW5ncy5tYXhGb250U2l6ZSk7XG4gICAgICAgIGlmICh0d2ljZVJlbmRlcikge1xuICAgICAgICAgICAgcmV0dXJuIGZvbnRTaXplICogc2V0dGluZ3MuZm9udFNjYWxlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmb250U2l6ZTtcbiAgICB9O1xuICAgIHZhciBpc0NhcmRpb2lkID0gZmFsc2U7XG4gICAgLyogQ29udmVydCBzaGFwZSBpbnRvIGEgZnVuY3Rpb24gKi9cbiAgICBpZiAodHlwZW9mIHNldHRpbmdzLnNoYXBlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHN3aXRjaCAoc2V0dGluZ3Muc2hhcGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2NpcmNsZSc6XG4gICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIC8vICdjaXJjbGUnIGlzIHRoZSBkZWZhdWx0IGFuZCBhIHNob3J0Y3V0IGluIHRoZSBjb2RlIGxvb3AuXG4gICAgICAgICAgICAgICAgc2V0dGluZ3Muc2hhcGUgPSAnY2lyY2xlJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2NhcmRpb2lkJzpcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL2JhaWtlLmJhaWR1LmNvbS9pdGVtLyVFNSVCRiU4MyVFOCU4NCU4RiVFNyVCQSVCRi8xMDMyMzg0Mz9mcm9tdGl0bGU9JUU1JUJGJTgzJUU1JUJEJUEyJUU3JUJBJUJGJmZyb21pZD0xMDAxODgxOFxuICAgICAgICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVDYXJkaW9pZCh0aGV0YSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMSAtIE1hdGguc2luKHRoZXRhKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlzQ2FyZGlvaWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgIFRvIHdvcmsgb3V0IGFuIFgtZ29uLCBvbmUgaGFzIHRvIGNhbGN1bGF0ZSBcIm1cIixcbiAgICAgICAgICAgIHdoZXJlIDEvKGNvcygyKlBJL1gpK20qc2luKDIqUEkvWCkpID0gMS8oY29zKDApK20qc2luKDApKVxuICAgICAgICAgICAgaHR0cDovL3d3dy53b2xmcmFtYWxwaGEuY29tL2lucHV0Lz9pPTElMkYlMjhjb3MlMjgyKlBJJTJGWCUyOSUyQm0qc2luJTI4XG4gICAgICAgICAgICAyKlBJJTJGWCUyOSUyOSslM0QrMSUyRiUyOGNvcyUyODAlMjklMkJtKnNpbiUyODAlMjklMjlcbiAgICAgICAgICAgIENvcHkgdGhlIHNvbHV0aW9uIGludG8gcG9sYXIgZXF1YXRpb24gciA9IDEvKGNvcyh0JykgKyBtKnNpbih0JykpXG4gICAgICAgICAgICB3aGVyZSB0JyBlcXVhbHMgdG8gbW9kKHQsIDJQSS9YKTtcbiAgICAgICAgICAgICovXG4gICAgICAgICAgICBjYXNlICdkaWFtb25kJzpcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlU3F1YXJlKHRoZXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0aGV0YVByaW1lID0gdGhldGEgJSAoKDIgKiBNYXRoLlBJKSAvIDQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIE1hdGguc2luKHRoZXRhUHJpbWUpKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc3F1YXJlJzpcbiAgICAgICAgICAgICAgICAvLyBodHRwOi8vd3d3LndvbGZyYW1hbHBoYS5jb20vaW5wdXQvP2k9cGxvdCtyKyUzRCsxJTJGJTI4Y29zJTI4bW9kK1xuICAgICAgICAgICAgICAgIC8vICUyOHQlMkMrUEklMkYyJTI5JTI5JTJCc2luJTI4bW9kKyUyOHQlMkMrUEklMkYyJTI5JTI5JTI5JTJDK3QrJTNEXG4gICAgICAgICAgICAgICAgLy8gKzArLi4rMipQSVxuICAgICAgICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVTcXVhcmUodGhldGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSAodGhldGEgKyBNYXRoLlBJIC8gNCkgJSAoKDIgKiBNYXRoLlBJKSAvIDQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIE1hdGguc2luKHRoZXRhUHJpbWUpKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndHJpYW5nbGUtZm9yd2FyZCc6XG4gICAgICAgICAgICAgICAgLy8gaHR0cDovL3d3dy53b2xmcmFtYWxwaGEuY29tL2lucHV0Lz9pPXBsb3QrcislM0QrMSUyRiUyOGNvcyUyOG1vZCtcbiAgICAgICAgICAgICAgICAvLyAlMjh0JTJDKzIqUEklMkYzJTI5JTI5JTJCc3FydCUyODMlMjlzaW4lMjhtb2QrJTI4dCUyQysyKlBJJTJGMyUyOVxuICAgICAgICAgICAgICAgIC8vICUyOSUyOSUyQyt0KyUzRCswKy4uKzIqUElcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlVHJpYW5nbGUodGhldGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSB0aGV0YSAlICgoMiAqIE1hdGguUEkpIC8gMyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsgTWF0aC5zcXJ0KDMpICogTWF0aC5zaW4odGhldGFQcmltZSkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0cmlhbmdsZS1iYWNrd2FyZCc6XG4gICAgICAgICAgICAgICAgc2V0dGluZ3Muc2hhcGUgPSBmdW5jdGlvbiBzaGFwZVRyaWFuZ2xlKHRoZXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0aGV0YVByaW1lID0gKHRoZXRhICsgTWF0aC5QSSkgJSAoKDIgKiBNYXRoLlBJKSAvIDMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIE1hdGguc3FydCgzKSAqIE1hdGguc2luKHRoZXRhUHJpbWUpKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndHJpYW5nbGUnOlxuICAgICAgICAgICAgY2FzZSAndHJpYW5nbGUtdXAnOlxuICAgICAgICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVUcmlhbmdsZSh0aGV0YSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGhldGFQcmltZSA9ICh0aGV0YSArIChNYXRoLlBJICogMykgLyAyKSAlICgoMiAqIE1hdGguUEkpIC8gMyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsgTWF0aC5zcXJ0KDMpICogTWF0aC5zaW4odGhldGFQcmltZSkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0cmlhbmdsZS1kb3duJzpcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlVHJpYW5nbGUodGhldGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSAodGhldGEgKyAoTWF0aC5QSSAqIDUpIC8gMikgJSAoKDIgKiBNYXRoLlBJKSAvIDMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIE1hdGguc3FydCgzKSAqIE1hdGguc2luKHRoZXRhUHJpbWUpKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncGVudGFnb24nOlxuICAgICAgICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVQZW50YWdvbih0aGV0YSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGhldGFQcmltZSA9ICh0aGV0YSArIDAuOTU1KSAlICgoMiAqIE1hdGguUEkpIC8gNSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsgMC43MjY1NDMgKiBNYXRoLnNpbih0aGV0YVByaW1lKSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3N0YXInOlxuICAgICAgICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVTdGFyKHRoZXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0aGV0YVByaW1lID0gKHRoZXRhICsgMC45NTUpICUgKCgyICogTWF0aC5QSSkgLyAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoKHRoZXRhICsgMC45NTUpICUgKCgyICogTWF0aC5QSSkgLyA1KSkgLSAoMiAqIE1hdGguUEkpIC8gMTAgPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgxIC8gKE1hdGguY29zKCgyICogTWF0aC5QSSkgLyAxMCAtIHRoZXRhUHJpbWUpICsgMy4wNzc2OCAqIE1hdGguc2luKCgyICogTWF0aC5QSSkgLyAxMCAtIHRoZXRhUHJpbWUpKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIDMuMDc3NjggKiBNYXRoLnNpbih0aGV0YVByaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qIE1ha2Ugc3VyZSBncmlkU2l6ZSBpcyBhIHdob2xlIG51bWJlciBhbmQgaXMgbm90IHNtYWxsZXIgdGhhbiA0cHggKi9cbiAgICBzZXR0aW5ncy5ncmlkU2l6ZSA9IE1hdGgubWF4KE1hdGguZmxvb3Ioc2V0dGluZ3MuZ3JpZFNpemUpLCA0KTtcbiAgICAvKiBzaG9ydGhhbmQgKi9cbiAgICB2YXIgZyA9IHNldHRpbmdzLmdyaWRTaXplO1xuICAgIHZhciBtYXNrUmVjdFdpZHRoID0gZyAtIHNldHRpbmdzLm1hc2tHYXBXaWR0aDtcbiAgICAvKiBub3JtYWxpemUgcm90YXRpb24gc2V0dGluZ3MgKi9cbiAgICB2YXIgcm90YXRpb25SYW5nZSA9IE1hdGguYWJzKHNldHRpbmdzLm1heFJvdGF0aW9uIC0gc2V0dGluZ3MubWluUm90YXRpb24pO1xuICAgIHZhciBtaW5Sb3RhdGlvbiA9IE1hdGgubWluKHNldHRpbmdzLm1heFJvdGF0aW9uLCBzZXR0aW5ncy5taW5Sb3RhdGlvbik7XG4gICAgdmFyIHJvdGF0aW9uU3RlcHMgPSBzZXR0aW5ncy5yb3RhdGlvblN0ZXBzO1xuICAgIC8qIGluZm9ybWF0aW9uL29iamVjdCBhdmFpbGFibGUgdG8gYWxsIGZ1bmN0aW9ucywgc2V0IHdoZW4gc3RhcnQoKSAqL1xuICAgIHZhciBncmlkLCAvLyAyZCBhcnJheSBjb250YWluaW5nIGZpbGxpbmcgaW5mb3JtYXRpb25cbiAgICBuZ3gsIG5neSwgLy8gd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgZ3JpZFxuICAgIGNlbnRlciwgLy8gcG9zaXRpb24gb2YgdGhlIGNlbnRlciBvZiB0aGUgY2xvdWRcbiAgICBtYXhSYWRpdXM7XG4gICAgLyogdGltZXN0YW1wIGZvciBtZWFzdXJpbmcgZWFjaCBwdXRXb3JkKCkgYWN0aW9uICovXG4gICAgdmFyIGVzY2FwZVRpbWU7XG4gICAgLyogZnVuY3Rpb24gZm9yIGdldHRpbmcgdGhlIGNvbG9yIG9mIHRoZSB0ZXh0ICovXG4gICAgdmFyIGdldFRleHRDb2xvcjtcbiAgICBmdW5jdGlvbiByYW5kb21faHNsX2NvbG9yKG1pbiwgbWF4KSB7XG4gICAgICAgIHJldHVybiAoJ2hzbCgnICtcbiAgICAgICAgICAgIChNYXRoLnJhbmRvbSgpICogMzYwKS50b0ZpeGVkKCkgK1xuICAgICAgICAgICAgJywnICtcbiAgICAgICAgICAgIChNYXRoLnJhbmRvbSgpICogMzAgKyA3MCkudG9GaXhlZCgpICtcbiAgICAgICAgICAgICclLCcgK1xuICAgICAgICAgICAgKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluKSArIG1pbikudG9GaXhlZCgpICtcbiAgICAgICAgICAgICclKScpO1xuICAgIH1cbiAgICBzd2l0Y2ggKHNldHRpbmdzLmNvbG9yKSB7XG4gICAgICAgIGNhc2UgJ3JhbmRvbS1kYXJrJzpcbiAgICAgICAgICAgIGdldFRleHRDb2xvciA9IGZ1bmN0aW9uIGdldFJhbmRvbURhcmtDb2xvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmFuZG9tX2hzbF9jb2xvcigxMCwgNTApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdyYW5kb20tbGlnaHQnOlxuICAgICAgICAgICAgZ2V0VGV4dENvbG9yID0gZnVuY3Rpb24gZ2V0UmFuZG9tTGlnaHRDb2xvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmFuZG9tX2hzbF9jb2xvcig1MCwgOTApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzZXR0aW5ncy5jb2xvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGdldFRleHRDb2xvciA9IHNldHRpbmdzLmNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIC8qIGZ1bmN0aW9uIGZvciBnZXR0aW5nIHRoZSBjbGFzc2VzIG9mIHRoZSB0ZXh0ICovXG4gICAgdmFyIGdldFRleHRDbGFzc2VzID0gbnVsbDtcbiAgICBpZiAodHlwZW9mIHNldHRpbmdzLmNsYXNzZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZ2V0VGV4dENsYXNzZXMgPSBzZXR0aW5ncy5jbGFzc2VzO1xuICAgIH1cbiAgICAvKiBJbnRlcmFjdGl2ZSAqL1xuICAgIHZhciBpbnRlcmFjdGl2ZSA9IGZhbHNlO1xuICAgIHZhciBpbmZvR3JpZCA9IFtdO1xuICAgIHZhciBob3ZlcmVkO1xuICAgIHZhciBnZXRJbmZvR3JpZEZyb21Nb3VzZVRvdWNoRXZlbnQgPSBmdW5jdGlvbiBnZXRJbmZvR3JpZEZyb21Nb3VzZVRvdWNoRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciBjYW52YXMgPSBldnQuY3VycmVudFRhcmdldDtcbiAgICAgICAgdmFyIHJlY3QgPSBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHZhciBjbGllbnRYO1xuICAgICAgICB2YXIgY2xpZW50WTtcbiAgICAgICAgLyoqIERldGVjdCBpZiB0b3VjaGVzIGFyZSBhdmFpbGFibGUgKi9cbiAgICAgICAgaWYgKGV2dC50b3VjaGVzKSB7XG4gICAgICAgICAgICBjbGllbnRYID0gZXZ0LnRvdWNoZXNbMF0uY2xpZW50WDtcbiAgICAgICAgICAgIGNsaWVudFkgPSBldnQudG91Y2hlc1swXS5jbGllbnRZO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2xpZW50WCA9IGV2dC5jbGllbnRYO1xuICAgICAgICAgICAgY2xpZW50WSA9IGV2dC5jbGllbnRZO1xuICAgICAgICB9XG4gICAgICAgIHZhciBldmVudFggPSBjbGllbnRYIC0gcmVjdC5sZWZ0O1xuICAgICAgICB2YXIgZXZlbnRZID0gY2xpZW50WSAtIHJlY3QudG9wO1xuICAgICAgICB2YXIgeCA9IE1hdGguZmxvb3IoKGV2ZW50WCAqIChjYW52YXMud2lkdGggLyByZWN0LndpZHRoIHx8IDEpKSAvIGcpO1xuICAgICAgICB2YXIgeSA9IE1hdGguZmxvb3IoKGV2ZW50WSAqIChjYW52YXMuaGVpZ2h0IC8gcmVjdC5oZWlnaHQgfHwgMSkpIC8gZyk7XG4gICAgICAgIHJldHVybiBpbmZvR3JpZCAmJiBpbmZvR3JpZFt4XSAmJiBpbmZvR3JpZFt4XVt5XTtcbiAgICB9O1xuICAgIHZhciBkZWZhdWx0SG92ZXJBY3Rpb24gPSBmdW5jdGlvbiBkZWZhdWx0SG92ZXJBY3Rpb24oaXRlbSwgZGltZW5zaW9uLCBldnQsIHN0YXJ0KSB7XG4gICAgICAgIGlmIChpdGVtKSB7XG4gICAgICAgICAgICBzdGFydChpdGVtLmlkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0KC0xKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgdmFyIHdvcmRjbG91ZGhvdmVyID0gZnVuY3Rpb24gd29yZGNsb3VkaG92ZXIoZXZ0KSB7XG4gICAgICAgIHZhciBpbmZvID0gZ2V0SW5mb0dyaWRGcm9tTW91c2VUb3VjaEV2ZW50KGV2dCk7XG4gICAgICAgIGlmIChob3ZlcmVkID09PSBpbmZvKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR3aWNlUmVuZGVyICYmIGluZm8gJiYgaW5mby5pdGVtICYmICF1dGlsXzEuZ2V0KGluZm8sIFsnaXRlbScsICd0d2ljZVJlbmRlciddKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaW5mbykge1xuICAgICAgICAgICAgc2V0dGluZ3Mub25Xb3JkQ2xvdWRIb3Zlcih1bmRlZmluZWQsIHVuZGVmaW5lZCwgZXZ0LCBzdGFydCk7XG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuYWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdEhvdmVyQWN0aW9uKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBldnQsIHN0YXJ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzZXR0aW5ncy5vbldvcmRDbG91ZEhvdmVyKGluZm8uaXRlbSwgaW5mby5kaW1lbnNpb24sIGV2dCwgc3RhcnQpO1xuICAgICAgICBpZiAoc2V0dGluZ3MuYWN0aXZlKSB7XG4gICAgICAgICAgICBkZWZhdWx0SG92ZXJBY3Rpb24oaW5mby5pdGVtLCBpbmZvLmRpbWVuc2lvbiwgZXZ0LCBzdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgaG92ZXJlZCA9IGluZm87XG4gICAgfTtcbiAgICB2YXIgd29yZGNsb3VkY2xpY2sgPSBmdW5jdGlvbiB3b3JkY2xvdWRjbGljayhldnQpIHtcbiAgICAgICAgdmFyIGluZm8gPSBnZXRJbmZvR3JpZEZyb21Nb3VzZVRvdWNoRXZlbnQoZXZ0KTtcbiAgICAgICAgaWYgKCFpbmZvKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc2V0dGluZ3Mub25Xb3JkQ2xvdWRDbGljayhpbmZvLml0ZW0sIGluZm8uZGltZW5zaW9uLCBldnQpO1xuICAgICAgICBldnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9O1xuICAgIC8qIEdldCBwb2ludHMgb24gdGhlIGdyaWQgZm9yIGEgZ2l2ZW4gcmFkaXVzIGF3YXkgZnJvbSB0aGUgY2VudGVyICovXG4gICAgdmFyIHBvaW50c0F0UmFkaXVzID0gW107XG4gICAgdmFyIGdldFBvaW50c0F0UmFkaXVzID0gZnVuY3Rpb24gZ2V0UG9pbnRzQXRSYWRpdXMocmFkaXVzKSB7XG4gICAgICAgIGlmIChwb2ludHNBdFJhZGl1c1tyYWRpdXNdKSB7XG4gICAgICAgICAgICByZXR1cm4gcG9pbnRzQXRSYWRpdXNbcmFkaXVzXTtcbiAgICAgICAgfVxuICAgICAgICAvLyBMb29rIGZvciB0aGVzZSBudW1iZXIgb2YgcG9pbnRzIG9uIGVhY2ggcmFkaXVzXG4gICAgICAgIHZhciBUID0gcmFkaXVzICogODtcbiAgICAgICAgLy8gR2V0dGluZyBhbGwgdGhlIHBvaW50cyBhdCB0aGlzIHJhZGl1c1xuICAgICAgICB2YXIgdCA9IFQ7XG4gICAgICAgIHZhciBwb2ludHMgPSBbXTtcbiAgICAgICAgaWYgKHJhZGl1cyA9PT0gMCkge1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goW2NlbnRlclswXSwgY2VudGVyWzFdLCAwXSk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHQtLSkge1xuICAgICAgICAgICAgLy8gZGlzdG9ydCB0aGUgcmFkaXVzIHRvIHB1dCB0aGUgY2xvdWQgaW4gc2hhcGVcbiAgICAgICAgICAgIHZhciByeCA9IDE7XG4gICAgICAgICAgICBpZiAoc2V0dGluZ3Muc2hhcGUgIT09ICdjaXJjbGUnKSB7XG4gICAgICAgICAgICAgICAgcnggPSBzZXR0aW5ncy5zaGFwZSgodCAvIFQpICogMiAqIE1hdGguUEkpOyAvLyAwIHRvIDFcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFB1c2ggW3gsIHksIHRdOyB0IGlzIHVzZWQgc29sZWx5IGZvciBnZXRUZXh0Q29sb3IoKVxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW1xuICAgICAgICAgICAgICAgIGNlbnRlclswXSArIHJhZGl1cyAqIHJ4ICogTWF0aC5jb3MoKC10IC8gVCkgKiAyICogTWF0aC5QSSksXG4gICAgICAgICAgICAgICAgY2VudGVyWzFdICsgcmFkaXVzICogcnggKiBNYXRoLnNpbigoLXQgLyBUKSAqIDIgKiBNYXRoLlBJKSAqIHNldHRpbmdzLmVsbGlwdGljaXR5LFxuICAgICAgICAgICAgICAgICh0IC8gVCkgKiAyICogTWF0aC5QSSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9XG4gICAgICAgIHBvaW50c0F0UmFkaXVzW3JhZGl1c10gPSBwb2ludHM7XG4gICAgICAgIHJldHVybiBwb2ludHM7XG4gICAgfTtcbiAgICAvKiBSZXR1cm4gdHJ1ZSBpZiB3ZSBoYWQgc3BlbnQgdG9vIG11Y2ggdGltZSAqL1xuICAgIHZhciBleGNlZWRUaW1lID0gZnVuY3Rpb24gZXhjZWVkVGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHNldHRpbmdzLmFib3J0VGhyZXNob2xkID4gMCAmJiBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGVzY2FwZVRpbWUgPiBzZXR0aW5ncy5hYm9ydFRocmVzaG9sZDtcbiAgICB9O1xuICAgIC8qIEdldCB0aGUgZGVnIG9mIHJvdGF0aW9uIGFjY29yZGluZyB0byBzZXR0aW5ncywgYW5kIGx1Y2suICovXG4gICAgdmFyIGdldFJvdGF0ZURlZyA9IGZ1bmN0aW9uIGdldFJvdGF0ZURlZygpIHtcbiAgICAgICAgaWYgKHNldHRpbmdzLnJvdGF0ZVJhdGlvID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTWF0aC5yYW5kb20oKSA+IHNldHRpbmdzLnJvdGF0ZVJhdGlvKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm90YXRpb25SYW5nZSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIG1pblJvdGF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJldHVybiBtaW5Sb3RhdGlvbiArIE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIHJvdGF0aW9uUmFuZ2UgLyByb3RhdGlvblN0ZXBzKSAqIHJvdGF0aW9uU3RlcHM7XG4gICAgICAgIGlmIChyb3RhdGlvblN0ZXBzID4gMCkge1xuICAgICAgICAgICAgLy8gTWluIHJvdGF0aW9uICsgemVybyBvciBtb3JlIHN0ZXBzICogc3BhbiBvZiBvbmUgc3RlcFxuICAgICAgICAgICAgcmV0dXJuIG1pblJvdGF0aW9uICsgKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHJvdGF0aW9uU3RlcHMpICogcm90YXRpb25SYW5nZSkgLyByb3RhdGlvblN0ZXBzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1pblJvdGF0aW9uICsgTWF0aC5yYW5kb20oKSAqIHJvdGF0aW9uUmFuZ2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHZhciBnZXRUZXh0SW5mbyA9IGZ1bmN0aW9uIGdldFRleHRJbmZvKHdvcmQsIHdlaWdodCwgcm90YXRlRGVnKSB7XG4gICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgYWN1dGFsIGZvbnQgc2l6ZVxuICAgICAgICAvLyBmb250U2l6ZSA9PT0gMCBtZWFucyB3YW50cyB0aGUgdGV4dCBza2lwcGVkLFxuICAgICAgICAvLyBhbmQgc2l6ZSA8IG1pblNpemUgbWVhbnMgd2UgY2Fubm90IGRyYXcgdGhlIHRleHRcbiAgICAgICAgdmFyIGRlYnVnID0gZmFsc2U7XG4gICAgICAgIHZhciBmb250U2l6ZSA9IGdldFJlYWxGb250U2l6ZSh3ZWlnaHQpO1xuICAgICAgICBpZiAoZm9udFNpemUgPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNjYWxlIGZhY3RvciBoZXJlIGlzIHRvIG1ha2Ugc3VyZSBmaWxsVGV4dCBpcyBub3QgbGltaXRlZCBieVxuICAgICAgICAvLyB0aGUgbWluaXVtIGZvbnQgc2l6ZSBzZXQgYnkgYnJvd3Nlci5cbiAgICAgICAgLy8gSXQgd2lsbCBhbHdheXMgYmUgMSBvciAybi5cbiAgICAgICAgdmFyIG11ID0gMTtcbiAgICAgICAgaWYgKGZvbnRTaXplIDwgbWluRm9udFNpemUpIHtcbiAgICAgICAgICAgIG11ID0gKGZ1bmN0aW9uIGNhbGN1bGF0ZVNjYWxlRmFjdG9yKCkge1xuICAgICAgICAgICAgICAgIHZhciBtdSA9IDI7XG4gICAgICAgICAgICAgICAgd2hpbGUgKG11ICogZm9udFNpemUgPCBtaW5Gb250U2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICBtdSArPSAyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbXU7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBmY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgIHZhciBmY3R4ID0gZmNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHsgd2lsbFJlYWRGcmVxdWVudGx5OiB0cnVlIH0pO1xuICAgICAgICBmY3R4LmZvbnQgPSBzZXR0aW5ncy5mb250V2VpZ2h0ICsgJyAnICsgKGZvbnRTaXplICogbXUpLnRvU3RyaW5nKDEwKSArICdweCAnICsgc2V0dGluZ3MuZm9udEZhbWlseTtcbiAgICAgICAgLy8gRXN0aW1hdGUgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGV4dCB3aXRoIG1lYXN1cmVUZXh0KCkuXG4gICAgICAgIHZhciBmdyA9IGZjdHgubWVhc3VyZVRleHQod29yZCkud2lkdGggLyBtdTtcbiAgICAgICAgdmFyIGZoID0gTWF0aC5tYXgoZm9udFNpemUgKiBtdSwgZmN0eC5tZWFzdXJlVGV4dCgnbScpLndpZHRoLCBmY3R4Lm1lYXN1cmVUZXh0KCdcXHVGRjM3Jykud2lkdGgpIC8gbXU7XG4gICAgICAgIC8vIENyZWF0ZSBhIGJvdW5kYXJ5IGJveCB0aGF0IGlzIGxhcmdlciB0aGFuIG91ciBlc3RpbWF0ZXMsXG4gICAgICAgIC8vIHNvIHRleHQgZG9uJ3QgZ2V0IGN1dCBvZiAoaXQgc2lsbCBtaWdodClcbiAgICAgICAgdmFyIGJveFdpZHRoID0gZncgKyBmaCAqIDI7XG4gICAgICAgIHZhciBib3hIZWlnaHQgPSBmaCAqIDM7XG4gICAgICAgIHZhciBmZ3cgPSBNYXRoLmNlaWwoYm94V2lkdGggLyBnKTtcbiAgICAgICAgdmFyIGZnaCA9IE1hdGguY2VpbChib3hIZWlnaHQgLyBnKTtcbiAgICAgICAgYm94V2lkdGggPSBmZ3cgKiBnO1xuICAgICAgICBib3hIZWlnaHQgPSBmZ2ggKiBnO1xuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIHByb3BlciBvZmZzZXRzIHRvIG1ha2UgdGhlIHRleHQgY2VudGVyZWQgYXRcbiAgICAgICAgLy8gdGhlIHByZWZlcnJlZCBwb3NpdGlvbi5cbiAgICAgICAgLy8gVGhpcyBpcyBzaW1wbHkgaGFsZiBvZiB0aGUgd2lkdGguXG4gICAgICAgIHZhciBmaWxsVGV4dE9mZnNldFggPSAtZncgLyAyO1xuICAgICAgICAvLyBJbnN0ZWFkIG9mIG1vdmluZyB0aGUgYm94IHRvIHRoZSBleGFjdCBtaWRkbGUgb2YgdGhlIHByZWZlcnJlZFxuICAgICAgICAvLyBwb3NpdGlvbiwgZm9yIFktb2Zmc2V0IHdlIG1vdmUgMC40IGluc3RlYWQsIHNvIExhdGluIGFscGhhYmV0cyBsb29rXG4gICAgICAgIC8vIHZlcnRpY2FsIGNlbnRlcmVkLlxuICAgICAgICB2YXIgZmlsbFRleHRPZmZzZXRZID0gLWZoICogMC40O1xuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGFjdHVhbCBkaW1lbnNpb24gb2YgdGhlIGNhbnZhcywgY29uc2lkZXJpbmcgdGhlIHJvdGF0aW9uLlxuICAgICAgICB2YXIgY2doID0gTWF0aC5jZWlsKChib3hXaWR0aCAqIE1hdGguYWJzKE1hdGguc2luKHJvdGF0ZURlZykpICsgYm94SGVpZ2h0ICogTWF0aC5hYnMoTWF0aC5jb3Mocm90YXRlRGVnKSkpIC8gZyk7XG4gICAgICAgIHZhciBjZ3cgPSBNYXRoLmNlaWwoKGJveFdpZHRoICogTWF0aC5hYnMoTWF0aC5jb3Mocm90YXRlRGVnKSkgKyBib3hIZWlnaHQgKiBNYXRoLmFicyhNYXRoLnNpbihyb3RhdGVEZWcpKSkgLyBnKTtcbiAgICAgICAgdmFyIHdpZHRoID0gY2d3ICogZztcbiAgICAgICAgdmFyIGhlaWdodCA9IGNnaCAqIGc7XG4gICAgICAgIGZjYW52YXMuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHdpZHRoKTtcbiAgICAgICAgZmNhbnZhcy5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGhlaWdodCk7XG4gICAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICAgICAgLy8gQXR0YWNoIGZjYW52YXMgdG8gdGhlIERPTVxuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmY2FudmFzKTtcbiAgICAgICAgICAgIC8vIFNhdmUgaXQncyBzdGF0ZSBzbyB0aGF0IHdlIGNvdWxkIHJlc3RvcmUgYW5kIGRyYXcgdGhlIGdyaWQgY29ycmVjdGx5LlxuICAgICAgICAgICAgZmN0eC5zYXZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2NhbGUgdGhlIGNhbnZhcyB3aXRoIHxtdXwuXG4gICAgICAgIGZjdHguc2NhbGUoMSAvIG11LCAxIC8gbXUpO1xuICAgICAgICBmY3R4LnRyYW5zbGF0ZSgod2lkdGggKiBtdSkgLyAyLCAoaGVpZ2h0ICogbXUpIC8gMik7XG4gICAgICAgIGZjdHgucm90YXRlKC1yb3RhdGVEZWcpO1xuICAgICAgICAvLyBPbmNlIHRoZSB3aWR0aC9oZWlnaHQgaXMgc2V0LCBjdHggaW5mbyB3aWxsIGJlIHJlc2V0LlxuICAgICAgICAvLyBTZXQgaXQgYWdhaW4gaGVyZS5cbiAgICAgICAgZmN0eC5mb250ID0gc2V0dGluZ3MuZm9udFdlaWdodCArICcgJyArIChmb250U2l6ZSAqIG11KS50b1N0cmluZygxMCkgKyAncHggJyArIHNldHRpbmdzLmZvbnRGYW1pbHk7XG4gICAgICAgIC8vIEZpbGwgdGhlIHRleHQgaW50byB0aGUgZmNhbnZhcy5cbiAgICAgICAgLy8gWFhYOiBXZSBjYW5ub3QgYmVjYXVzZSB0ZXh0QmFzZWxpbmUgPSAndG9wJyBoZXJlIGJlY2F1c2VcbiAgICAgICAgLy8gRmlyZWZveCBhbmQgQ2hyb21lIHVzZXMgZGlmZmVyZW50IGRlZmF1bHQgbGluZS1oZWlnaHQgZm9yIGNhbnZhcy5cbiAgICAgICAgLy8gUGxlYXNlIHJlYWQgaHR0cHM6Ly9idWd6aWwubGEvNzM3ODUyI2M2LlxuICAgICAgICAvLyBIZXJlLCB3ZSB1c2UgdGV4dEJhc2VsaW5lID0gJ21pZGRsZScgYW5kIGRyYXcgdGhlIHRleHQgYXQgZXhhY3RseVxuICAgICAgICAvLyAwLjUgKiBmb250U2l6ZSBsb3dlci5cbiAgICAgICAgZmN0eC5maWxsU3R5bGUgPSAnIzAwMCc7XG4gICAgICAgIGZjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgICAgIGZjdHguZmlsbFRleHQod29yZCwgZmlsbFRleHRPZmZzZXRYICogbXUsIChmaWxsVGV4dE9mZnNldFkgKyBmb250U2l6ZSAqIDAuNSkgKiBtdSk7XG4gICAgICAgIC8vIEdldCB0aGUgcGl4ZWxzIG9mIHRoZSB0ZXh0XG4gICAgICAgIHZhciBpbWFnZURhdGE7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpbWFnZURhdGEgPSBmY3R4LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KS5kYXRhO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBkYXRhIG5vdCBsb25nIHR5cGVcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhjZWVkVGltZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgICAgICAvLyBEcmF3IHRoZSBib3ggb2YgdGhlIG9yaWdpbmFsIGVzdGltYXRpb25cbiAgICAgICAgICAgIGZjdHguc3Ryb2tlUmVjdChmaWxsVGV4dE9mZnNldFggKiBtdSwgZmlsbFRleHRPZmZzZXRZLCBmdyAqIG11LCBmaCAqIG11KTtcbiAgICAgICAgICAgIGZjdHgucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlYWQgdGhlIHBpeGVscyBhbmQgc2F2ZSB0aGUgaW5mb3JtYXRpb24gdG8gdGhlIG9jY3VwaWVkIGFycmF5XG4gICAgICAgIHZhciBvY2N1cGllZCA9IFtdO1xuICAgICAgICB2YXIgZ3ggPSBjZ3csIGd5LCB4LCB5O1xuICAgICAgICB2YXIgYm91bmRzID0gW2NnaCAvIDIsIGNndyAvIDIsIGNnaCAvIDIsIGNndyAvIDJdO1xuICAgICAgICB3aGlsZSAoZ3gtLSkge1xuICAgICAgICAgICAgZ3kgPSBjZ2g7XG4gICAgICAgICAgICB3aGlsZSAoZ3ktLSkge1xuICAgICAgICAgICAgICAgIHkgPSBnO1xuICAgICAgICAgICAgICAgIHNpbmdsZUdyaWRMb29wOiB7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICh5LS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSBnO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHgtLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbWFnZURhdGFbKChneSAqIGcgKyB5KSAqIHdpZHRoICsgKGd4ICogZyArIHgpKSAqIDQgKyAzXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZC5wdXNoKFtneCwgZ3ldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGd4IDwgYm91bmRzWzNdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHNbM10gPSBneDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3ggPiBib3VuZHNbMV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kc1sxXSA9IGd4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChneSA8IGJvdW5kc1swXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRzWzBdID0gZ3k7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGd5ID4gYm91bmRzWzJdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSBneTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZjdHguZmlsbFN0eWxlID0gJ3JnYmEoMjU1LCAwLCAwLCAwLjUpJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZjdHguZmlsbFJlY3QoZ3ggKiBnLCBneSAqIGcsIGcgLSAwLjUsIGcgLSAwLjUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIHNpbmdsZUdyaWRMb29wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZjdHguZmlsbFN0eWxlID0gJ3JnYmEoMCwgMCwgMjU1LCAwLjUpJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGZjdHguZmlsbFJlY3QoZ3ggKiBnLCBneSAqIGcsIGcgLSAwLjUsIGcgLSAwLjUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICAgICAgLy8gcmVhbCBib3VuZHNcbiAgICAgICAgICAgIGZjdHguZmlsbFN0eWxlID0gJ3JnYmEoMCwgMjU1LCAwLCAwLjUpJztcbiAgICAgICAgICAgIGZjdHguZmlsbFJlY3QoYm91bmRzWzNdICogZywgYm91bmRzWzBdICogZywgKGJvdW5kc1sxXSAtIGJvdW5kc1szXSArIDEpICogZywgKGJvdW5kc1syXSAtIGJvdW5kc1swXSArIDEpICogZyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmV0dXJuIGluZm9ybWF0aW9uIG5lZWRlZCB0byBjcmVhdGUgdGhlIHRleHQgb24gdGhlIHJlYWwgY2FudmFzXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtdTogbXUsXG4gICAgICAgICAgICBvY2N1cGllZDogb2NjdXBpZWQsXG4gICAgICAgICAgICBib3VuZHM6IGJvdW5kcyxcbiAgICAgICAgICAgIGd3OiBjZ3csXG4gICAgICAgICAgICBnaDogY2doLFxuICAgICAgICAgICAgZmlsbFRleHRPZmZzZXRYOiBmaWxsVGV4dE9mZnNldFgsXG4gICAgICAgICAgICBmaWxsVGV4dE9mZnNldFk6IGZpbGxUZXh0T2Zmc2V0WSxcbiAgICAgICAgICAgIGZpbGxUZXh0V2lkdGg6IGZ3LFxuICAgICAgICAgICAgZmlsbFRleHRIZWlnaHQ6IGZoLFxuICAgICAgICAgICAgZm9udFNpemU6IGZvbnRTaXplLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLyogRGV0ZXJtaW5lIGlmIHRoZXJlIGlzIHJvb20gYXZhaWxhYmxlIGluIHRoZSBnaXZlbiBkaW1lbnNpb24gKi9cbiAgICB2YXIgY2FuRml0VGV4dCA9IGZ1bmN0aW9uIGNhbkZpdFRleHQoZ3gsIGd5LCBndywgZ2gsIG9jY3VwaWVkKSB7XG4gICAgICAgIC8vIEdvIHRocm91Z2ggdGhlIG9jY3VwaWVkIHBvaW50cyxcbiAgICAgICAgLy8gcmV0dXJuIGZhbHNlIGlmIHRoZSBzcGFjZSBpcyBub3QgYXZhaWxhYmxlLlxuICAgICAgICB2YXIgaSA9IG9jY3VwaWVkLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgdmFyIHB4ID0gZ3ggKyBvY2N1cGllZFtpXVswXTtcbiAgICAgICAgICAgIHZhciBweSA9IGd5ICsgb2NjdXBpZWRbaV1bMV07XG4gICAgICAgICAgICBpZiAocHggPj0gbmd4IHx8IHB5ID49IG5neSB8fCBweCA8IDAgfHwgcHkgPCAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzZXR0aW5ncy5kcmF3T3V0T2ZCb3VuZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFncmlkW3B4XVtweV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICAvKiBBY3R1YWxseSBkcmF3IHRoZSB0ZXh0IG9uIHRoZSBncmlkICovXG4gICAgdmFyIGRyYXdUZXh0ID0gZnVuY3Rpb24gZHJhd1RleHQoZ3gsIGd5LCBpbmZvLCB3b3JkLCB3ZWlnaHQsIGRpc3RhbmNlLCB0aGV0YSwgcm90YXRlRGVnLCBhdHRyaWJ1dGVzLCBpZCwgcmVmcmVzaCkge1xuICAgICAgICB2YXIgZm9udFNpemUgPSBpbmZvLmZvbnRTaXplO1xuICAgICAgICB2YXIgY29sb3IgPSBzZXR0aW5ncy5jb2xvcjtcbiAgICAgICAgdmFyIGNsYXNzZXMgPSBzZXR0aW5ncy5jbGFzc2VzO1xuICAgICAgICBpZiAoIXJlZnJlc2gpIHtcbiAgICAgICAgICAgIGlmIChnZXRUZXh0Q29sb3IpIHtcbiAgICAgICAgICAgICAgICBjb2xvciA9IGdldFRleHRDb2xvcih3b3JkLCB3ZWlnaHQsIGZvbnRTaXplLCBkaXN0YW5jZSwgdGhldGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29sb3IgPSBzZXR0aW5ncy5jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChnZXRUZXh0Q2xhc3Nlcykge1xuICAgICAgICAgICAgICAgIGNsYXNzZXMgPSBnZXRUZXh0Q2xhc3Nlcyh3b3JkLCB3ZWlnaHQsIGZvbnRTaXplLCBkaXN0YW5jZSwgdGhldGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY2xhc3NlcyA9IHNldHRpbmdzLmNsYXNzZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgZmluZCA9IGdldEludGVyYWN0aW9uSXRlbUJ5SWQoaWQpO1xuICAgICAgICAgICAgY29sb3IgPSBmaW5kID8gZmluZC5jb2xvciA6IHNldHRpbmdzLmNvbG9yO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkaW1lbnNpb247XG4gICAgICAgIHZhciBib3VuZHMgPSBpbmZvLmJvdW5kcztcbiAgICAgICAgZGltZW5zaW9uID0ge1xuICAgICAgICAgICAgeDogKGd4ICsgYm91bmRzWzNdKSAqIGcsXG4gICAgICAgICAgICB5OiAoZ3kgKyBib3VuZHNbMF0pICogZyxcbiAgICAgICAgICAgIHc6IChib3VuZHNbMV0gLSBib3VuZHNbM10gKyAxKSAqIGcsXG4gICAgICAgICAgICBoOiAoYm91bmRzWzJdIC0gYm91bmRzWzBdICsgMSkgKiBnLFxuICAgICAgICB9O1xuICAgICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgaWYgKGVsLmdldENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICB2YXIgY3R4ID0gZWwuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgICAgICAgICB2YXIgbXUgPSBpbmZvLm11O1xuICAgICAgICAgICAgICAgIC8vIFNhdmUgdGhlIGN1cnJlbnQgc3RhdGUgYmVmb3JlIG1lc3NpbmcgaXRcbiAgICAgICAgICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICAgICAgICAgIHZhciBmb250ID0gc2V0dGluZ3MuZm9udFdlaWdodCArICcgJyArIChmb250U2l6ZSAqIG11KS50b1N0cmluZygxMCkgKyAncHggJyArIHNldHRpbmdzLmZvbnRGYW1pbHk7XG4gICAgICAgICAgICAgICAgY3R4LnNjYWxlKDEgLyBtdSwgMSAvIG11KTtcbiAgICAgICAgICAgICAgICBjdHguZm9udCA9IGZvbnQ7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGNvbG9yO1xuICAgICAgICAgICAgICAgIC8vIFRyYW5zbGF0ZSB0aGUgY2FudmFzIHBvc2l0aW9uIHRvIHRoZSBvcmlnaW4gY29vcmRpbmF0ZSBvZiB3aGVyZVxuICAgICAgICAgICAgICAgIC8vIHRoZSB0ZXh0IHNob3VsZCBiZSBwdXQuXG4gICAgICAgICAgICAgICAgdmFyIHRyYW5zWCA9IChneCArIGluZm8uZ3cgLyAyKSAqIGcgKiBtdTtcbiAgICAgICAgICAgICAgICB2YXIgdHJhbnNZID0gKGd5ICsgaW5mby5naCAvIDIpICogZyAqIG11O1xuICAgICAgICAgICAgICAgIGN0eC50cmFuc2xhdGUodHJhbnNYLCB0cmFuc1kpO1xuICAgICAgICAgICAgICAgIGlmIChyb3RhdGVEZWcgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4LnJvdGF0ZSgtcm90YXRlRGVnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gRmluYWxseSwgZmlsbCB0aGUgdGV4dC5cbiAgICAgICAgICAgICAgICAvLyBYWFg6IFdlIGNhbm5vdCBiZWNhdXNlIHRleHRCYXNlbGluZSA9ICd0b3AnIGhlcmUgYmVjYXVzZVxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggYW5kIENocm9tZSB1c2VzIGRpZmZlcmVudCBkZWZhdWx0IGxpbmUtaGVpZ2h0IGZvciBjYW52YXMuXG4gICAgICAgICAgICAgICAgLy8gUGxlYXNlIHJlYWQgaHR0cHM6Ly9idWd6aWwubGEvNzM3ODUyI2M2LlxuICAgICAgICAgICAgICAgIC8vIEhlcmUsIHdlIHVzZSB0ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJyBhbmQgZHJhdyB0aGUgdGV4dCBhdCBleGFjdGx5XG4gICAgICAgICAgICAgICAgLy8gMC41ICogZm9udFNpemUgbG93ZXIuXG4gICAgICAgICAgICAgICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5zZWxlY3RlZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4LnNoYWRvd0NvbG9yID0gc2V0dGluZ3Muc2hhZG93Q29sb3I7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5zaGFkb3dCbHVyID0gc2V0dGluZ3Muc2hhZG93Qmx1cjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxUZXh0KHdvcmQsIGluZm8uZmlsbFRleHRPZmZzZXRYICogbXUsIChpbmZvLmZpbGxUZXh0T2Zmc2V0WSArIGZvbnRTaXplICogMC41KSAqIG11KTtcbiAgICAgICAgICAgICAgICAvLyBUaGUgYmVsb3cgYm94IGlzIGFsd2F5cyBtYXRjaGVzIGhvdyA8c3Bhbj5zIGFyZSBwb3NpdGlvbmVkXG4gICAgICAgICAgICAgICAgLy8gY3R4LnN0cm9rZVJlY3QoaW5mby5maWxsVGV4dE9mZnNldFgsIGluZm8uZmlsbFRleHRPZmZzZXRZLFxuICAgICAgICAgICAgICAgIC8vICAgaW5mby5maWxsVGV4dFdpZHRoLCBpbmZvLmZpbGxUZXh0SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlZnJlc2gpIHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb25JdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGd4OiBneCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGd5OiBneSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZm86IGluZm8sXG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JkOiB3b3JkLFxuICAgICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0OiB3ZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZTogZGlzdGFuY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGV0YTogdGhldGEsXG4gICAgICAgICAgICAgICAgICAgICAgICByb3RhdGVEZWc6IHJvdGF0ZURlZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IGF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcjogY29sb3IsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBzdGF0ZS5cbiAgICAgICAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZHJhd1RleHQgb24gRElWIGVsZW1lbnRcbiAgICAgICAgICAgICAgICB2YXIgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgICAgICB2YXIgdHJhbnNmb3JtUnVsZSA9ICcnO1xuICAgICAgICAgICAgICAgIHRyYW5zZm9ybVJ1bGUgPSAncm90YXRlKCcgKyAoLXJvdGF0ZURlZyAvIE1hdGguUEkpICogMTgwICsgJ2RlZykgJztcbiAgICAgICAgICAgICAgICBpZiAoaW5mby5tdSAhPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1SdWxlICs9ICd0cmFuc2xhdGVYKC0nICsgaW5mby5maWxsVGV4dFdpZHRoIC8gNCArICdweCkgJyArICdzY2FsZSgnICsgMSAvIGluZm8ubXUgKyAnKSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBzdHlsZVJ1bGVzID0ge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udDogc2V0dGluZ3MuZm9udFdlaWdodCArICcgJyArIGZvbnRTaXplICogaW5mby5tdSArICdweCAnICsgc2V0dGluZ3MuZm9udEZhbWlseSxcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogKGd4ICsgaW5mby5ndyAvIDIpICogZyArIGluZm8uZmlsbFRleHRPZmZzZXRYICsgJ3B4JyxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAoZ3kgKyBpbmZvLmdoIC8gMikgKiBnICsgaW5mby5maWxsVGV4dE9mZnNldFkgKyAncHgnLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogaW5mby5maWxsVGV4dFdpZHRoICsgJ3B4JyxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBpbmZvLmZpbGxUZXh0SGVpZ2h0ICsgJ3B4JyxcbiAgICAgICAgICAgICAgICAgICAgbGluZUhlaWdodDogZm9udFNpemUgKyAncHgnLFxuICAgICAgICAgICAgICAgICAgICB3aGl0ZVNwYWNlOiAnbm93cmFwJyxcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2Zvcm1SdWxlLFxuICAgICAgICAgICAgICAgICAgICB3ZWJraXRUcmFuc2Zvcm06IHRyYW5zZm9ybVJ1bGUsXG4gICAgICAgICAgICAgICAgICAgIG1zVHJhbnNmb3JtOiB0cmFuc2Zvcm1SdWxlLFxuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1PcmlnaW46ICc1MCUgNDAlJyxcbiAgICAgICAgICAgICAgICAgICAgd2Via2l0VHJhbnNmb3JtT3JpZ2luOiAnNTAlIDQwJScsXG4gICAgICAgICAgICAgICAgICAgIG1zVHJhbnNmb3JtT3JpZ2luOiAnNTAlIDQwJScsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAoY29sb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGVSdWxlcy5jb2xvciA9IGNvbG9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzcGFuLnRleHRDb250ZW50ID0gd29yZDtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBjc3NQcm9wIGluIHN0eWxlUnVsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bhbi5zdHlsZVtjc3NQcm9wXSA9IHN0eWxlUnVsZXNbY3NzUHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNsYXNzZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bhbi5jbGFzc05hbWUgKz0gY2xhc3NlcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyogSGVscCBmdW5jdGlvbiB0byB1cGRhdGVHcmlkICovXG4gICAgdmFyIGZpbGxHcmlkQXQgPSBmdW5jdGlvbiBmaWxsR3JpZEF0KHgsIHksIGRyYXdNYXNrLCBkaW1lbnNpb24sIGl0ZW0pIHtcbiAgICAgICAgaWYgKHggPj0gbmd4IHx8IHkgPj0gbmd5IHx8IHggPCAwIHx8IHkgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZ3JpZFt4XVt5XSA9IGZhbHNlO1xuICAgICAgICBpZiAoZHJhd01hc2spIHtcbiAgICAgICAgICAgIHZhciBjdHggPSBlbGVtZW50c1swXS5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICAgICAgY3R4LmZpbGxSZWN0KHggKiBnLCB5ICogZywgbWFza1JlY3RXaWR0aCwgbWFza1JlY3RXaWR0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGludGVyYWN0aXZlKSB7XG4gICAgICAgICAgICBpbmZvR3JpZFt4XVt5XSA9IHsgaXRlbTogaXRlbSwgZGltZW5zaW9uOiBkaW1lbnNpb24gfTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLyogVXBkYXRlIHRoZSBmaWxsaW5nIGluZm9ybWF0aW9uIG9mIHRoZSBnaXZlbiBzcGFjZSB3aXRoIG9jY3VwaWVkIHBvaW50cy5cbiAgICAgICBEcmF3IHRoZSBtYXNrIG9uIHRoZSBjYW52YXMgaWYgbmVjZXNzYXJ5LiAqL1xuICAgIHZhciB1cGRhdGVHcmlkID0gZnVuY3Rpb24gdXBkYXRlR3JpZChneCwgZ3ksIGd3LCBnaCwgaW5mbykge1xuICAgICAgICB2YXIgb2NjdXBpZWQgPSBpbmZvLm9jY3VwaWVkO1xuICAgICAgICB2YXIgZHJhd01hc2sgPSBzZXR0aW5ncy5kcmF3TWFzaztcbiAgICAgICAgdmFyIGN0eDtcbiAgICAgICAgaWYgKGRyYXdNYXNrKSB7XG4gICAgICAgICAgICBjdHggPSBlbGVtZW50c1swXS5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBzZXR0aW5ncy5tYXNrQ29sb3I7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRpbWVuc2lvbjtcbiAgICAgICAgaWYgKGludGVyYWN0aXZlKSB7XG4gICAgICAgICAgICB2YXIgYm91bmRzID0gaW5mby5ib3VuZHM7XG4gICAgICAgICAgICBkaW1lbnNpb24gPSB7XG4gICAgICAgICAgICAgICAgeDogKGd4ICsgYm91bmRzWzNdKSAqIGcsXG4gICAgICAgICAgICAgICAgeTogKGd5ICsgYm91bmRzWzBdKSAqIGcsXG4gICAgICAgICAgICAgICAgdzogKGJvdW5kc1sxXSAtIGJvdW5kc1szXSArIDEpICogZyxcbiAgICAgICAgICAgICAgICBoOiAoYm91bmRzWzJdIC0gYm91bmRzWzBdICsgMSkgKiBnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaSA9IG9jY3VwaWVkLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgdmFyIHB4ID0gZ3ggKyBvY2N1cGllZFtpXVswXTtcbiAgICAgICAgICAgIHZhciBweSA9IGd5ICsgb2NjdXBpZWRbaV1bMV07XG4gICAgICAgICAgICBpZiAocHggPj0gbmd4IHx8IHB5ID49IG5neSB8fCBweCA8IDAgfHwgcHkgPCAwKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBzYXZlIGl0ZW0ncyBjb2xvciBmcm9tIGluZm9cbiAgICAgICAgICAgIHZhciBmaW5kID0gZ2V0SW50ZXJhY3Rpb25JdGVtQnlJZChpbmZvLml0ZW0uaWQpO1xuICAgICAgICAgICAgaWYgKGZpbmQpIHtcbiAgICAgICAgICAgICAgICBpbmZvLml0ZW0uY29sb3IgPSBmaW5kLmNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZmlsbEdyaWRBdChweCwgcHksIGRyYXdNYXNrLCBkaW1lbnNpb24sIGluZm8uaXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRyYXdNYXNrKSB7XG4gICAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgdHJ5VG9QdXRXb3JkQXRQb2ludCA9IGZ1bmN0aW9uIHRyeVRvUHV0V29yZEF0UG9pbnQoZ3h5LCBpbmZvLCB3b3JkLCB3ZWlnaHQsIGRpc3RhbmNlLCByb3RhdGVEZWcsIGF0dHJpYnV0ZXMsIGlkKSB7XG4gICAgICAgIHZhciBneCA9IE1hdGguZmxvb3IoZ3h5WzBdIC0gaW5mby5ndyAvIDIpO1xuICAgICAgICB2YXIgZ3kgPSBNYXRoLmZsb29yKGd4eVsxXSAtIGluZm8uZ2ggLyAyKTtcbiAgICAgICAgdmFyIGd3ID0gaW5mby5ndztcbiAgICAgICAgdmFyIGdoID0gaW5mby5naDtcbiAgICAgICAgLy8gSWYgd2UgY2Fubm90IGZpdCB0aGUgdGV4dCBhdCB0aGlzIHBvc2l0aW9uLCByZXR1cm4gZmFsc2VcbiAgICAgICAgLy8gYW5kIGdvIHRvIHRoZSBuZXh0IHBvc2l0aW9uLlxuICAgICAgICBpZiAoIWNhbkZpdFRleHQoZ3gsIGd5LCBndywgZ2gsIGluZm8ub2NjdXBpZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQWN0dWFsbHkgcHV0IHRoZSB0ZXh0IG9uIHRoZSBjYW52YXNcbiAgICAgICAgZHJhd1RleHQoZ3gsIGd5LCBpbmZvLCB3b3JkLCB3ZWlnaHQsIGRpc3RhbmNlLCBneHlbMl0sIHJvdGF0ZURlZywgYXR0cmlidXRlcywgaWQsIGZhbHNlKTtcbiAgICAgICAgLy8gTWFyayB0aGUgc3BhY2VzIG9uIHRoZSBncmlkIGFzIGZpbGxlZFxuICAgICAgICB1cGRhdGVHcmlkKGd4LCBneSwgZ3csIGdoLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGd4OiBneCxcbiAgICAgICAgICAgIGd5OiBneSxcbiAgICAgICAgICAgIHJvdDogcm90YXRlRGVnLFxuICAgICAgICAgICAgaW5mbzogaW5mbyxcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qIHB1dFdvcmQoKSBwcm9jZXNzZXMgZWFjaCBpdGVtIG9uIHRoZSBsaXN0LFxuICAgICAgIGNhbGN1bGF0ZSBpdCdzIHNpemUgYW5kIGRldGVybWluZSBpdCdzIHBvc2l0aW9uLCBhbmQgYWN0dWFsbHlcbiAgICAgICBwdXQgaXQgb24gdGhlIGNhbnZhcy4gKi9cbiAgICB2YXIgcHV0V29yZCA9IGZ1bmN0aW9uIHB1dFdvcmQoaXRlbSkge1xuICAgICAgICB2YXIgd29yZCwgd2VpZ2h0LCBhdHRyaWJ1dGVzLCBpZDtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaXRlbSkpIHtcbiAgICAgICAgICAgIHdvcmQgPSBpdGVtWzBdO1xuICAgICAgICAgICAgd2VpZ2h0ID0gaXRlbVsxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHdvcmQgPSBpdGVtLndvcmQ7XG4gICAgICAgICAgICB3ZWlnaHQgPSBpdGVtLndlaWdodDtcbiAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBpdGVtLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICBpZCA9IGl0ZW0uaWQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJvdGF0ZURlZyA9IHV0aWxfMS5pc05pbChpdGVtLnJvdGF0ZURlZykgPyBnZXRSb3RhdGVEZWcoKSA6IGl0ZW0ucm90YXRlRGVnO1xuICAgICAgICAvLyBnZXQgaW5mbyBuZWVkZWQgdG8gcHV0IHRoZSB0ZXh0IG9udG8gdGhlIGNhbnZhc1xuICAgICAgICB2YXIgaW5mbyA9IGdldFRleHRJbmZvKHdvcmQsIHdlaWdodCwgcm90YXRlRGVnKTtcbiAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgIGluZm9bJ2l0ZW0nXSA9IGl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgLy8gbm90IGdldHRpbmcgdGhlIGluZm8gbWVhbnMgd2Ugc2hvdWxkbid0IGJlIGRyYXdpbmcgdGhpcyBvbmUuXG4gICAgICAgIGlmICghaW5mbykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChleGNlZWRUaW1lKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiBkcmF3T3V0T2ZCb3VuZCBpcyBzZXQgdG8gZmFsc2UsXG4gICAgICAgIC8vIHNraXAgdGhlIGxvb3AgaWYgd2UgaGF2ZSBhbHJlYWR5IGtub3cgdGhlIGJvdW5kaW5nIGJveCBvZlxuICAgICAgICAvLyB3b3JkIGlzIGxhcmdlciB0aGFuIHRoZSBjYW52YXMuXG4gICAgICAgIGlmICghc2V0dGluZ3MuZHJhd091dE9mQm91bmQpIHtcbiAgICAgICAgICAgIHZhciBib3VuZHMgPSBpbmZvLmJvdW5kcztcbiAgICAgICAgICAgIGlmIChib3VuZHNbMV0gLSBib3VuZHNbM10gKyAxID4gbmd4IHx8IGJvdW5kc1syXSAtIGJvdW5kc1swXSArIDEgPiBuZ3kpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBwb3NpdGlvbiB0byBwdXQgdGhlIHRleHQgYnlcbiAgICAgICAgLy8gc3RhcnQgbG9va2luZyBmb3IgdGhlIG5lYXJlc3QgcG9pbnRzXG4gICAgICAgIHZhciByID0gbWF4UmFkaXVzICsgMTtcbiAgICAgICAgd2hpbGUgKHItLSkge1xuICAgICAgICAgICAgdmFyIHBvaW50cyA9IGdldFBvaW50c0F0UmFkaXVzKG1heFJhZGl1cyAtIHIpO1xuICAgICAgICAgICAgaWYgKHNldHRpbmdzLnNodWZmbGUpIHtcbiAgICAgICAgICAgICAgICBwb2ludHMgPSBbXS5jb25jYXQocG9pbnRzKTtcbiAgICAgICAgICAgICAgICBzaHVmZmxlQXJyYXkocG9pbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRyeSB0byBmaXQgdGhlIHdvcmRzIGJ5IGxvb2tpbmcgYXQgZWFjaCBwb2ludC5cbiAgICAgICAgICAgIC8vIGFycmF5LnNvbWUoKSB3aWxsIHN0b3AgYW5kIHJldHVybiB0cnVlXG4gICAgICAgICAgICAvLyB3aGVuIHB1dFdvcmRBdFBvaW50KCkgcmV0dXJucyB0cnVlLlxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzID0gdHJ5VG9QdXRXb3JkQXRQb2ludChwb2ludHNbaV0sIGluZm8sIHdvcmQsIHdlaWdodCwgbWF4UmFkaXVzIC0gciwgcm90YXRlRGVnLCBhdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHZhciBkcmF3biA9IHBvaW50cy5zb21lKHRyeVRvUHV0V29yZEF0UG9pbnQpO1xuICAgICAgICAgICAgLy8gaWYgKGRyYXduKSB7XG4gICAgICAgICAgICAvLyAgIC8vIGxlYXZlIHB1dFdvcmQoKSBhbmQgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIC8vICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gd2UgdHJpZWQgYWxsIGRpc3RhbmNlcyBidXQgdGV4dCB3b24ndCBmaXQsIHJldHVybiBudWxsXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgLyogU2VuZCBET00gZXZlbnQgdG8gYWxsIGVsZW1lbnRzLiBXaWxsIHN0b3Agc2VuZGluZyBldmVudCBhbmQgcmV0dXJuXG4gICAgICAgaWYgdGhlIHByZXZpb3VzIG9uZSBpcyBjYW5jZWxlZCAoZm9yIGNhbmNlbGFibGUgZXZlbnRzKS4gKi9cbiAgICB2YXIgc2VuZEV2ZW50ID0gZnVuY3Rpb24gc2VuZEV2ZW50KHR5cGUsIGNhbmNlbGFibGUsIGRldGFpbCkge1xuICAgICAgICBpZiAoY2FuY2VsYWJsZSkge1xuICAgICAgICAgICAgcmV0dXJuICFlbGVtZW50cy5zb21lKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgICAgICAgICAgICBldnQuaW5pdEN1c3RvbUV2ZW50KHR5cGUsIHRydWUsIGNhbmNlbGFibGUsIGRldGFpbCB8fCB7fSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuICFlbC5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gICAgICAgICAgICB9LCB0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdDdXN0b21FdmVudCcpO1xuICAgICAgICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQodHlwZSwgdHJ1ZSwgY2FuY2VsYWJsZSwgZGV0YWlsIHx8IHt9KTtcbiAgICAgICAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gICAgICAgICAgICB9LCB0aGlzKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgdmFyIGdldEludGVyYWN0aW9uSXRlbUJ5SWQgPSBmdW5jdGlvbiBnZXRJbnRlcmFjdGlvbkl0ZW1CeUlkKGlkKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW50ZXJhY3Rpb25JdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGZpbmQgPSBpbnRlcmFjdGlvbkl0ZW1zW2ldO1xuICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uSXRlbXNbaV0uaWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbmQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9O1xuICAgIHZhciB0d2ljZVJlbmRlcjtcbiAgICAvKiBTdGFydCBkcmF3aW5nIG9uIGEgY2FudmFzICovXG4gICAgdmFyIHN0YXJ0ID0gZnVuY3Rpb24gc3RhcnQoc2VsZWN0ZWQpIHtcbiAgICAgICAgaWYgKHNlbGVjdGVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIHJlLXJlZnJlc2ggY2FudmFzIHdpdGggc2VsZWN0ZWRcbiAgICAgICAgICAgIC8vIHdvcmsgaW4gY2FudmFzIG9ubHkgZm9yIG5vd1xuICAgICAgICAgICAgaWYgKHNldHRpbmdzLnNlbGVjdGVkICE9PSBzZWxlY3RlZCAmJiBlbGVtZW50c1swXS5nZXRDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgc2V0dGluZ3Muc2VsZWN0ZWQgPSBzZWxlY3RlZDtcbiAgICAgICAgICAgICAgICB2YXIgY3R4ID0gZWxlbWVudHNbMF0uZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgICAgICAgICAvLyBkcmF3IGJhY2tncm91bmRcbiAgICAgICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICAgICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgZWxlbWVudHNbMF0ud2lkdGgsIGVsZW1lbnRzWzBdLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIGVsZW1lbnRzWzBdLndpZHRoLCBlbGVtZW50c1swXS5oZWlnaHQpO1xuICAgICAgICAgICAgICAgIC8vIGRyYXcgdGV4dFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGlfMSA9IDA7IGlfMSA8IGludGVyYWN0aW9uSXRlbXMubGVuZ3RoOyBpXzErKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZmluZCA9IGludGVyYWN0aW9uSXRlbXNbaV8xXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0d2ljZVJlbmRlciB8fCAodHdpY2VSZW5kZXIgJiYgdXRpbF8xLmdldChmaW5kLCBbJ2luZm8nLCAnaXRlbScsICd0d2ljZVJlbmRlciddKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICog6K+N5LqR5Zu+6K+N6YeP6L6D5bCR55qE5pe25YCZ77yM6YeN5paw5riy5p+T5LiA5qyh6K+N5rGH77yM5pS+5aSn6K+N5LqR5Zu+5pWI5p6cXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiDov5nph4zlhYjkuLTml7bop6PlhrPvvIzlkI7nu63ov5jmmK/pnIDopoHkvJjljJbor43kupHlm77nrpfms5XmnaXop6PlhrNcbiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgZHJhd1RleHQoZmluZC5neCwgZmluZC5neSwgZmluZC5pbmZvLCBmaW5kLndvcmQsIGZpbmQud2VpZ2h0LCBmaW5kLmRpc3RhbmNlLCBmaW5kLnRoZXRhLCBmaW5kLnJvdGF0ZURlZywgZmluZC5hdHRyaWJ1dGVzLCBmaW5kLmlkLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3IgZGltZW5zaW9ucywgY2xlYXJDYW52YXMgZXRjLixcbiAgICAgICAgLy8gd2Ugb25seSBjYXJlIGFib3V0IHRoZSBmaXJzdCBlbGVtZW50LlxuICAgICAgICB2YXIgY2FudmFzID0gZWxlbWVudHNbMF07XG4gICAgICAgIGlmIChjYW52YXMuZ2V0Q29udGV4dCkge1xuICAgICAgICAgICAgbmd4ID0gTWF0aC5jZWlsKGNhbnZhcy53aWR0aCAvIGcpO1xuICAgICAgICAgICAgbmd5ID0gTWF0aC5jZWlsKGNhbnZhcy5oZWlnaHQgLyBnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZWN0ID0gY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgbmd4ID0gTWF0aC5jZWlsKHJlY3Qud2lkdGggLyBnKTtcbiAgICAgICAgICAgIG5neSA9IE1hdGguY2VpbChyZWN0LmhlaWdodCAvIGcpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlbmRpbmcgYSB3b3JkY2xvdWRzdGFydCBldmVudCB3aGljaCBjYXVzZSB0aGUgcHJldmlvdXMgbG9vcCB0byBzdG9wLlxuICAgICAgICAvLyBEbyBub3RoaW5nIGlmIHRoZSBldmVudCBpcyBjYW5jZWxlZC5cbiAgICAgICAgaWYgKCFzZW5kRXZlbnQoJ3dvcmRjbG91ZHN0YXJ0JywgdHJ1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGNlbnRlciBvZiB0aGUgd29yZCBjbG91ZFxuICAgICAgICBjZW50ZXIgPSBzZXR0aW5ncy5vcmlnaW4gPyBbc2V0dGluZ3Mub3JpZ2luWzBdIC8gZywgc2V0dGluZ3Mub3JpZ2luWzFdIC8gZ10gOiBbbmd4IC8gMiwgbmd5IC8gKGlzQ2FyZGlvaWQgPyA0IDogMildO1xuICAgICAgICAvLyBNYXhpdW0gcmFkaXVzIHRvIGxvb2sgZm9yIHNwYWNlXG4gICAgICAgIG1heFJhZGl1cyA9IE1hdGguZmxvb3IoTWF0aC5zcXJ0KG5neCAqIG5neCArIG5neSAqIG5neSkpO1xuICAgICAgICAvKiBDbGVhciB0aGUgY2FudmFzIG9ubHkgaWYgdGhlIGNsZWFyQ2FudmFzIGlzIHNldCxcbiAgICAgICAgICAgaWYgbm90LCB1cGRhdGUgdGhlIGdyaWQgdG8gdGhlIGN1cnJlbnQgY2FudmFzIHN0YXRlICovXG4gICAgICAgIGdyaWQgPSBbXTtcbiAgICAgICAgdmFyIGd4LCBneSwgaTtcbiAgICAgICAgaWYgKCFjYW52YXMuZ2V0Q29udGV4dCB8fCBzZXR0aW5ncy5jbGVhckNhbnZhcykge1xuICAgICAgICAgICAgZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWwuZ2V0Q29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3R4ID0gZWwuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IHNldHRpbmdzLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBuZ3ggKiAoZyArIDEpLCBuZ3kgKiAoZyArIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIG5neCAqIChnICsgMSksIG5neSAqIChnICsgMSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZWwudGV4dENvbnRlbnQgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgZWwuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICAgICAgICAgICAgICBlbC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvKiBmaWxsIHRoZSBncmlkIHdpdGggZW1wdHkgc3RhdGUgKi9cbiAgICAgICAgICAgIGd4ID0gbmd4O1xuICAgICAgICAgICAgd2hpbGUgKGd4LS0pIHtcbiAgICAgICAgICAgICAgICBncmlkW2d4XSA9IFtdO1xuICAgICAgICAgICAgICAgIGd5ID0gbmd5O1xuICAgICAgICAgICAgICAgIHdoaWxlIChneS0tKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyaWRbZ3hdW2d5XSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLyogRGV0ZXJtaW5lIGJnUGl4ZWwgYnkgY3JlYXRpbmdcbiAgICAgICAgICAgICAgIGFub3RoZXIgY2FudmFzIGFuZCBmaWxsIHRoZSBzcGVjaWZpZWQgYmFja2dyb3VuZCBjb2xvci4gKi9cbiAgICAgICAgICAgIHZhciBiY3R4ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgICAgIGJjdHguZmlsbFN0eWxlID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICAgICAgYmN0eC5maWxsUmVjdCgwLCAwLCAxLCAxKTtcbiAgICAgICAgICAgIHZhciBiZ1BpeGVsID0gYmN0eC5nZXRJbWFnZURhdGEoMCwgMCwgMSwgMSkuZGF0YTtcbiAgICAgICAgICAgIC8qIFJlYWQgYmFjayB0aGUgcGl4ZWxzIG9mIHRoZSBjYW52YXMgd2UgZ290IHRvIHRlbGwgd2hpY2ggcGFydCBvZiB0aGVcbiAgICAgICAgICAgICAgIGNhbnZhcyBpcyBlbXB0eS5cbiAgICAgICAgICAgICAgIChubyBjbGVhckNhbnZhcyBvbmx5IHdvcmtzIHdpdGggYSBjYW52YXMsIG5vdCBkaXZzKSAqL1xuICAgICAgICAgICAgdmFyIGltYWdlRGF0YSA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmdldEltYWdlRGF0YSgwLCAwLCBuZ3ggKiBnLCBuZ3kgKiBnKS5kYXRhO1xuICAgICAgICAgICAgZ3ggPSBuZ3g7XG4gICAgICAgICAgICB2YXIgeCwgeTtcbiAgICAgICAgICAgIHdoaWxlIChneC0tKSB7XG4gICAgICAgICAgICAgICAgZ3JpZFtneF0gPSBbXTtcbiAgICAgICAgICAgICAgICBneSA9IG5neTtcbiAgICAgICAgICAgICAgICB3aGlsZSAoZ3ktLSkge1xuICAgICAgICAgICAgICAgICAgICB5ID0gZztcbiAgICAgICAgICAgICAgICAgICAgc2luZ2xlR3JpZExvb3A6IHdoaWxlICh5LS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSBnO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHgtLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPSA0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGltYWdlRGF0YVsoKGd5ICogZyArIHkpICogbmd4ICogZyArIChneCAqIGcgKyB4KSkgKiA0ICsgaV0gIT09IGJnUGl4ZWxbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyaWRbZ3hdW2d5XSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2luZ2xlR3JpZExvb3A7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGdyaWRbZ3hdW2d5XSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyaWRbZ3hdW2d5XSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbWFnZURhdGEgPSBiY3R4ID0gYmdQaXhlbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBmaWxsIHRoZSBpbmZvR3JpZCB3aXRoIGVtcHR5IHN0YXRlIGlmIHdlIG5lZWQgaXRcbiAgICAgICAgaWYgKHNldHRpbmdzLm9uV29yZENsb3VkSG92ZXIgfHwgc2V0dGluZ3Mub25Xb3JkQ2xvdWRDbGljaykge1xuICAgICAgICAgICAgaW50ZXJhY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgLyogZmlsbCB0aGUgZ3JpZCB3aXRoIGVtcHR5IHN0YXRlICovXG4gICAgICAgICAgICBneCA9IG5neCArIDE7XG4gICAgICAgICAgICB3aGlsZSAoZ3gtLSkge1xuICAgICAgICAgICAgICAgIGluZm9HcmlkW2d4XSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLm9uV29yZENsb3VkSG92ZXIpIHtcbiAgICAgICAgICAgICAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgd29yZGNsb3VkaG92ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLm9uV29yZENsb3VkQ2xpY2spIHtcbiAgICAgICAgICAgICAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB3b3JkY2xvdWRjbGljayk7XG4gICAgICAgICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB3b3JkY2xvdWRjbGljayk7XG4gICAgICAgICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNhbnZhcy5zdHlsZS53ZWJraXRUYXBIaWdobGlnaHRDb2xvciA9ICdyZ2JhKDAsIDAsIDAsIDApJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIGZ1bmN0aW9uIHN0b3BJbnRlcmFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICBjYW52YXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBzdG9wSW50ZXJhY3Rpb24pO1xuICAgICAgICAgICAgICAgIGNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB3b3JkY2xvdWRob3Zlcik7XG4gICAgICAgICAgICAgICAgY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgd29yZGNsb3VkY2xpY2spO1xuICAgICAgICAgICAgICAgIGhvdmVyZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXNldHRpbmdzLmFuaW1hdGFibGUpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLm1hc2tJbWFnZSkge1xuICAgICAgICAgICAgICAgIC8qKiDkv67lpI3popzoibLpgI/mmI7vvIzov5jnlZnmnIkgbWFza0ltYWdlIOeahOaDheWGtSAqL1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbC5nZXRDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3R4ID0gZWwuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBzZXR0aW5ncy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIG5neCAqIChnICsgMSksIG5neSAqIChnICsgMSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIG5neCAqIChnICsgMSksIG5neSAqIChnICsgMSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcmVuZGVyZWRXb3JkcyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaV8yID0gMDsgaV8yIDwgc2V0dGluZ3MuZGF0YS5sZW5ndGg7IGlfMisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gcHV0V29yZChzZXR0aW5ncy5kYXRhW2lfMl0pO1xuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJlZFdvcmRzLnB1c2gocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZW5kZXJlZFdvcmRzLmxlbmd0aCA9PT0gc2V0dGluZ3MuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXR3aWNlUmVuZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwuZ2V0Q29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdHggPSBlbC5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBzZXR0aW5ncy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBuZ3ggKiAoZyArIDEpLCBuZ3kgKiAoZyArIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguZmlsbFJlY3QoMCwgMCwgbmd4ICogKGcgKyAxKSwgbmd5ICogKGcgKyAxKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAvKiBmaWxsIHRoZSBncmlkIHdpdGggZW1wdHkgc3RhdGUgKi9cbiAgICAgICAgICAgICAgICAgICAgZ3ggPSBuZ3g7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChneC0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBncmlkW2d4XSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ3kgPSBuZ3k7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZ3ktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyaWRbZ3hdW2d5XSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdHdpY2VSZW5kZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpXzMgPSAwOyBpXzMgPCBzZXR0aW5ncy5kYXRhLmxlbmd0aDsgaV8zKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1dFdvcmQodHNsaWJfMS5fX2Fzc2lnbih0c2xpYl8xLl9fYXNzaWduKHt9LCBzZXR0aW5ncy5kYXRhW2lfM10pLCB7IHR3aWNlUmVuZGVyOiB0d2ljZVJlbmRlciB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpID0gMDtcbiAgICAgICAgICAgIHZhciBsb29waW5nRnVuY3Rpb24sIHN0b3BwaW5nRnVuY3Rpb247XG4gICAgICAgICAgICBpZiAoc2V0dGluZ3Mud2FpdCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGxvb3BpbmdGdW5jdGlvbiA9IHdpbmRvdy5zZXRUaW1lb3V0O1xuICAgICAgICAgICAgICAgIHN0b3BwaW5nRnVuY3Rpb24gPSB3aW5kb3cuY2xlYXJUaW1lb3V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9vcGluZ0Z1bmN0aW9uID0gd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICAgICAgICAgICAgICBzdG9wcGluZ0Z1bmN0aW9uID0gd2luZG93LmNsZWFySW1tZWRpYXRlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIHJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIGFub3RoZXJXb3JkQ2xvdWRTdGFydCA9IGZ1bmN0aW9uIGFub3RoZXJXb3JkQ2xvdWRTdGFydCgpIHtcbiAgICAgICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIGFub3RoZXJXb3JkQ2xvdWRTdGFydCk7XG4gICAgICAgICAgICAgICAgc3RvcHBpbmdGdW5jdGlvbih0aW1lcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpO1xuICAgICAgICAgICAgdmFyIHRpbWVyID0gbG9vcGluZ0Z1bmN0aW9uKGZ1bmN0aW9uIGxvb3AoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPj0gc2V0dGluZ3MuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RvcHBpbmdGdW5jdGlvbih0aW1lcik7XG4gICAgICAgICAgICAgICAgICAgIHNlbmRFdmVudCgnd29yZGNsb3Vkc3RvcCcsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVzY2FwZVRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICB2YXIgZHJhd24gPSBwdXRXb3JkKHNldHRpbmdzLmRhdGFbaV0pO1xuICAgICAgICAgICAgICAgIHZhciBjYW5jZWxlZCA9ICFzZW5kRXZlbnQoJ3dvcmRjbG91ZGRyYXduJywgdHJ1ZSwge1xuICAgICAgICAgICAgICAgICAgICBpdGVtOiBzZXR0aW5ncy5kYXRhW2ldLFxuICAgICAgICAgICAgICAgICAgICBkcmF3bjogZHJhd24sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGV4Y2VlZFRpbWUoKSB8fCBjYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICBzdG9wcGluZ0Z1bmN0aW9uKHRpbWVyKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VuZEV2ZW50KCd3b3JkY2xvdWRhYm9ydCcsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgc2VuZEV2ZW50KCd3b3JkY2xvdWRzdG9wJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIGFub3RoZXJXb3JkQ2xvdWRTdGFydCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgICAgIHRpbWVyID0gbG9vcGluZ0Z1bmN0aW9uKGxvb3AsIHNldHRpbmdzLndhaXQpO1xuICAgICAgICAgICAgfSwgc2V0dGluZ3Mud2FpdCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8vIEFsbCBzZXQsIHN0YXJ0IHRoZSBkcmF3aW5nXG4gICAgc3RhcnQoKTtcbn07XG5Xb3JkQ2xvdWQuaXNTdXBwb3J0ZWQgPSBpc1N1cHBvcnRlZDtcbldvcmRDbG91ZC5taW5Gb250U2l6ZSA9IG1pbkZvbnRTaXplO1xuZXhwb3J0cy5kZWZhdWx0ID0gV29yZENsb3VkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d29yZGNsb3VkMi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIE1hcmtlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNYXJrZXIoY2ZnKSB7XG4gICAgICAgIHV0aWxfMS5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICAgIE1hcmtlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2hhcGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhcGUuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNYXJrZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChjZmcsIGR1cmF0aW9uLCBlYXNpbmcpIHtcbiAgICAgICAgdmFyIHVwZGF0ZUNmZyA9IHt9O1xuICAgICAgICB1dGlsXzEuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgICAgIHRoaXMuY29vcmQgPSB0aGlzLnZpZXcuZ2VvbWV0cmllc1swXS5jb29yZGluYXRlO1xuICAgICAgICBpZiAoY2ZnLnZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgeCA9IHRoaXMuY29vcmQuY29udmVydCh7IHg6IDAsIHk6IHRoaXMudmFsdWUgfSkueDtcbiAgICAgICAgICAgIHZhciBtYXRyaXggPSBbMSwgMCwgMCwgMCwgMSwgMCwgeCwgMCwgMV07XG4gICAgICAgICAgICB1cGRhdGVDZmcubWF0cml4ID0gbWF0cml4O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjZmcuc3R5bGUpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZSA9IHRoaXMuc2hhcGU7XG4gICAgICAgICAgICB2YXIgb3JpZ2luX2F0dHIgPSBzaGFwZS5hdHRycztcbiAgICAgICAgICAgIHZhciBhdHRycyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBvcmlnaW5fYXR0ciwgY2ZnLnN0eWxlKTtcbiAgICAgICAgICAgIHVwZGF0ZUNmZyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBhdHRycywgdXBkYXRlQ2ZnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNoYXBlLnN0b3BBbmltYXRlKCk7XG4gICAgICAgIHRoaXMuc2hhcGUuYW5pbWF0ZSh1cGRhdGVDZmcsIGR1cmF0aW9uLCBlYXNpbmcpO1xuICAgIH07XG4gICAgTWFya2VyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvb3JkID0gdGhpcy52aWV3Lmdlb21ldHJpZXNbMF0uY29vcmRpbmF0ZTtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLnZpZXcuZm9yZWdyb3VuZEdyb3VwLmFkZEdyb3VwKCk7XG4gICAgICAgIHZhciB4ID0gdGhpcy5jb29yZC5jb252ZXJ0KHsgeDogMCwgeTogdGhpcy52YWx1ZSB9KS54OyAvLyBwcm9ncmVzc+WdkOagh+ezu+aYr+i9rOe9ruWdkOagh+ezu1xuICAgICAgICB2YXIgeTAgPSB0aGlzLmNvb3JkLmNlbnRlci55IC0gdGhpcy5wcm9ncmVzc1NpemUgLyAyIC0gMjtcbiAgICAgICAgdmFyIHkxID0gdGhpcy5jb29yZC5jZW50ZXIueSArIHRoaXMucHJvZ3Jlc3NTaXplIC8gMiArIDI7XG4gICAgICAgIHZhciBzdHlsZSA9IHV0aWxfMS5kZWVwTWl4KHt9LCB7IHN0cm9rZTogJ2dyZXknLCBsaW5lV2lkdGg6IDEgfSwgdGhpcy5zdHlsZSk7XG4gICAgICAgIHRoaXMuc2hhcGUgPSB0aGlzLmNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgIGF0dHJzOiB0c2xpYl8xLl9fYXNzaWduKHsgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICBbJ00nLCAwLCB5MF0sXG4gICAgICAgICAgICAgICAgICAgIFsnTCcsIDAsIHkxXSxcbiAgICAgICAgICAgICAgICBdIH0sIHN0eWxlKSxcbiAgICAgICAgICAgIG5hbWU6ICdwcm9ncmVzcy1tYXJrZXInLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zaGFwZS5tb3ZlKHgsIDApO1xuICAgICAgICB0aGlzLmNhbnZhcy5kcmF3KCk7XG4gICAgfTtcbiAgICByZXR1cm4gTWFya2VyO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IE1hcmtlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1hcmtlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVWRU5UX01BUFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5FVkVOVF9NQVA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvbkV2ZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLm9uRXZlbnQ7IH0gfSk7XG52YXIgY29tcG9uZW50TWFwID0ge1xuICAgIHByb2dyZXNzOiAnaW50ZXJ2YWwnLFxufTtcbnZhciBTSEFQRV9FVkVOVF9NQVAgPSBldmVudF8xLmdldEV2ZW50TWFwKGNvbXBvbmVudE1hcCk7XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFByb2dyZXNzID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFByb2dyZXNzLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFByb2dyZXNzKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFByb2dyZXNzLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAncHJvZ3Jlc3MnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgUHJvZ3Jlc3MucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSwgc3R5bGUpIHtcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy5sYXllcnNbMF07XG4gICAgICAgIGxheWVyLnVwZGF0ZSh2YWx1ZSwgc3R5bGUpO1xuICAgIH07XG4gICAgUHJvZ3Jlc3MuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFByb2dyZXNzO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUHJvZ3Jlc3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xudmFyIHRpbnlfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi90aW55LWxheWVyXCIpKTtcbnZhciBtYXJrZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbXBvbmVudC9tYXJrZXJcIikpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIEcyX0dFT01fTUFQID0ge1xuICAgIHByb2dyZXNzOiAnaW50ZXJ2YWwnLFxufTtcbnZhciBQTE9UX0dFT01fTUFQID0ge1xuICAgIGludGVydmFsOiAncHJvZ3Jlc3MnLFxufTtcbnZhciBERUZBVUxUX0NPTE9SID0gWycjNTVBNkYzJywgJyNFOEVERjMnXTtcbnZhciBQcm9ncmVzc0xheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFByb2dyZXNzTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gUHJvZ3Jlc3NMYXllcigpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWwhui/m+W6puadoemFjee9rumhuei9rOS4uuWghuWPoOadoeW9ouWbvumFjee9rumhuVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAncHJvZ3Jlc3MnO1xuICAgICAgICBfdGhpcy5pc0VudGVyZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5wcm9jZXNzUHJvcHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgcHJvcHMuZGF0YSA9IHRoaXMucHJvY2Vzc0RhdGEoKTtcbiAgICAgICAgdmFyIGNmZyA9IHtcbiAgICAgICAgICAgIHBhZGRpbmc6IFswLCAwLCAwLCAwXSxcbiAgICAgICAgICAgIHhGaWVsZDogJ3ZhbHVlJyxcbiAgICAgICAgICAgIHlGaWVsZDogJzEnLFxuICAgICAgICAgICAgc3RhY2tGaWVsZDogJ3R5cGUnLFxuICAgICAgICAgICAgYmFyU2l6ZTogcHJvcHMuc2l6ZSA/IHByb3BzLnNpemUgOiB0aGlzLmdldFNpemUoKSxcbiAgICAgICAgICAgIGJhclN0eWxlOiBwcm9wcy5wcm9ncmVzc1N0eWxlLFxuICAgICAgICAgICAgY29sb3I6IHRoaXMucGFyc2VDb2xvclByb3BzKHByb3BzKSB8fCBERUZBVUxUX0NPTE9SLFxuICAgICAgICB9O1xuICAgICAgICBwcm9wcyA9IHV0aWxfMS5taXgocHJvcHMsIGNmZyk7XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NQcm9wcygpO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzKTtcbiAgICB9O1xuICAgIFByb2dyZXNzTGF5ZXIucHJvdG90eXBlLmJlZm9yZUluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwZXJjZW50ID0gdGhpcy5vcHRpb25zLnBlcmNlbnQ7XG4gICAgICAgIGlmICghdXRpbF8xLmlzTnVtYmVyKHBlcmNlbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BlcmNlbnQgdmFsdWUgaXMgcmVxdWlyZWQsIGFuZCB0aGUgdHlwZSBvZiBwZXJjZW50IG11c3QgYmUgTnVtYmVyLicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgaWYgKHV0aWxfMS5oYXNLZXkoY2ZnLCAncGVyY2VudCcpKSB7XG4gICAgICAgICAgICBwcm9wcy5wZXJjZW50ID0gY2ZnLnBlcmNlbnQ7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZURhdGEodGhpcy5wcm9jZXNzRGF0YSgpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2ZnLnN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLnN0eWxlVXBkYXRlQW5pbWF0aW9uKGNmZy5zdHlsZSk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNvbG9yQ29uZmlnQnlTdHlsZShjZmcuc3R5bGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjZmcuY29sb3IpIHtcbiAgICAgICAgICAgIHZhciBzdHlsZSA9IHZvaWQgMDtcbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNBcnJheShjZmcuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmNvbG9yID0gY2ZnLmNvbG9yO1xuICAgICAgICAgICAgICAgIHN0eWxlID0gW3sgZmlsbDogY2ZnLmNvbG9yWzBdIH0sIHsgZmlsbDogY2ZnLmNvbG9yWzFdIH1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmNvbG9yWzBdID0gY2ZnLmNvbG9yO1xuICAgICAgICAgICAgICAgIHN0eWxlID0geyBmaWxsOiBjZmcuY29sb3IgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3R5bGVVcGRhdGVBbmltYXRpb24oc3R5bGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjZmcubWFya2VyKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1hcmtlcnMoY2ZnLm1hcmtlcik7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMubWFya2VyID0gY2ZnLm1hcmtlcjtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMubWFya2VycyAmJiB0aGlzLm1hcmtlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdXRpbF8xLmVhY2godGhpcy5tYXJrZXJzLCBmdW5jdGlvbiAobWFya2VyKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5tYXJrZXJzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5kZXN0cm95LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5hZnRlclJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5tYXJrZXIgJiYgIXRoaXMubWFya2Vycykge1xuICAgICAgICAgICAgdGhpcy5tYXJrZXJzID0gW107XG4gICAgICAgICAgICB1dGlsXzEuZWFjaCh0aGlzLm9wdGlvbnMubWFya2VyLCBmdW5jdGlvbiAoY2ZnKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1hcmtlckNmZyA9IHV0aWxfMS5taXgoe1xuICAgICAgICAgICAgICAgICAgICBjYW52YXM6IF90aGlzLmNhbnZhcyxcbiAgICAgICAgICAgICAgICAgICAgdmlldzogX3RoaXMudmlldyxcbiAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3NTaXplOiBfdGhpcy5vcHRpb25zLmJhclNpemUsXG4gICAgICAgICAgICAgICAgfSwgY2ZnKTtcbiAgICAgICAgICAgICAgICB2YXIgbWFya2VyID0gbmV3IG1hcmtlcl8xLmRlZmF1bHQobWFya2VyQ2ZnKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5tYXJrZXJzLnB1c2gobWFya2VyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcm9ncmVzc0NvbnRhaW5lciA9IHRoaXMudmlldy5nZW9tZXRyaWVzWzBdLmNvbnRhaW5lcjtcbiAgICAgICAgdmFyIGJib3ggPSBwcm9ncmVzc0NvbnRhaW5lci5nZXRCQm94KCk7XG4gICAgICAgIHZhciByZWN0ID0gcHJvZ3Jlc3NDb250YWluZXIuYWRkU2hhcGUoJ3JlY3QnLCB7XG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIHdpZHRoOiBiYm94LndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogYmJveC5oZWlnaHQsXG4gICAgICAgICAgICAgICAgeDogYmJveC5taW5YLFxuICAgICAgICAgICAgICAgIHk6IGJib3gubWluWSxcbiAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgwLDAsMCwwKScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jYW52YXMuZHJhdygpO1xuICAgICAgICByZWN0Lm9uKCdtb3VzZWVudGVyJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBfdGhpcy5pc0VudGVyZWQgPSB0cnVlO1xuICAgICAgICAgICAgX3RoaXMudmlldy5lbWl0KCdwcm9ncmVzczptb3VzZWVudGVyJywgZXYpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVjdC5vbignbW91c2VsZWF2ZScsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgX3RoaXMuaXNFbnRlcmVkID0gZmFsc2U7XG4gICAgICAgICAgICBfdGhpcy52aWV3LmVtaXQoJ3Byb2dyZXNzOm1vdXNlbGVhdmUnLCBldik7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY2FudmFzRG9tID0gdGhpcy5jYW52YXMuZ2V0KCdjb250YWluZXInKTtcbiAgICAgICAgY2FudmFzRG9tLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5pc0VudGVyZWQpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy52aWV3LmVtaXQoJ3Byb2dyZXNzOm1vdXNlbGVhdmUnLCBldik7XG4gICAgICAgICAgICAgICAgX3RoaXMuaXNFbnRlcmVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUuZ2VvbWV0cnlQYXJzZXIgPSBmdW5jdGlvbiAoZGltLCB0eXBlKSB7XG4gICAgICAgIGlmIChkaW0gPT09ICdnMicpIHtcbiAgICAgICAgICAgIHJldHVybiBHMl9HRU9NX01BUFt0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUExPVF9HRU9NX01BUFt0eXBlXTtcbiAgICB9O1xuICAgIFByb2dyZXNzTGF5ZXIucHJvdG90eXBlLmNvb3JkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldENvbmZpZygnY29vcmRpbmF0ZScsIHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtbJ3RyYW5zcG9zZSddXSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgYmFyID0gZmFjdG9yeV8xLmdldEdlb20oJ2ludGVydmFsJywgJ21haW4nLCB7XG4gICAgICAgICAgICBwb3NpdGlvbkZpZWxkczogW3Byb3BzLnlGaWVsZCwgcHJvcHMueEZpZWxkXSxcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICBiYXIuYWRqdXN0ID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhwcm9wcywgJ2FuaW1hdGlvbicpKSB7XG4gICAgICAgICAgICBiYXIuYW5pbWF0ZSA9IHByb3BzLmFuaW1hdGlvbjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCBiYXIpO1xuICAgIH07XG4gICAgUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoZXZlbnRQYXJzZXIpIHtcbiAgICAgICAgaWYgKGV2ZW50UGFyc2VyKSB7XG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgZXZlbnRQYXJzZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUucGFyc2VDb2xvclByb3BzID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgIHZhciBjb2xvck9wdGlvbjtcbiAgICAgICAgaWYgKHByb3BzLmNvbG9yKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzRnVuY3Rpb24ocHJvcHMuY29sb3IpKSB7XG4gICAgICAgICAgICAgICAgY29sb3JPcHRpb24gPSBwcm9wcy5jb2xvcihwcm9wcy5wZXJjZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbG9yT3B0aW9uID0gcHJvcHMuY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKGNvbG9yT3B0aW9uKSkge1xuICAgICAgICAgICAgICAgIHZhciBjb2xvciA9IHV0aWxfMS5jbG9uZShERUZBVUxUX0NPTE9SKTtcbiAgICAgICAgICAgICAgICBjb2xvclswXSA9IGNvbG9yT3B0aW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb2xvck9wdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcHMuY29sb3I7XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5wcm9jZXNzRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgZGF0YSA9IFtcbiAgICAgICAgICAgIHsgdHlwZTogJ2N1cnJlbnQnLCB2YWx1ZTogcHJvcHMucGVyY2VudCB9LFxuICAgICAgICAgICAgeyB0eXBlOiAncmVzdCcsIHZhbHVlOiAxLjAgLSBwcm9wcy5wZXJjZW50IH0sXG4gICAgICAgIF07XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH07XG4gICAgUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUudXBkYXRlTWFya2VycyA9IGZ1bmN0aW9uIChtYXJrZXJDZmcpIHtcbiAgICAgICAgdmFyIG1hcmtlckxlbmd0aCA9IG1hcmtlckNmZy5sZW5ndGg7XG4gICAgICAgIHZhciBhbmltYXRpb25PcHRpb25zID0gdGhpcy5nZXRVcGRhdGVBbmltYXRpb25PcHRpb25zKCk7XG4gICAgICAgIC8vIG1hcmtlciBkaWZmXG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMubWFya2VycywgZnVuY3Rpb24gKG1hcmtlciwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmIChpbmRleCA+IG1hcmtlckxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBtYXJrZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbWFya2VyLnVwZGF0ZShtYXJrZXJDZmdbaW5kZXhdLCBhbmltYXRpb25PcHRpb25zLmR1cmF0aW9uLCBhbmltYXRpb25PcHRpb25zLmVhc2luZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBhZGQgbmV3IG1hcmtlcnNcbiAgICAgICAgaWYgKHRoaXMubWFya2Vycy5sZW5ndGggPCBtYXJrZXJMZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBzdGFydEluZGV4ID0gdGhpcy5tYXJrZXJzLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBzdGFydEluZGV4OyBpIDwgbWFya2VyTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgY2ZnID0gdXRpbF8xLmRlZXBNaXgoe30sIHtcbiAgICAgICAgICAgICAgICAgICAgY2FudmFzOiB0aGlzLmNhbnZhcyxcbiAgICAgICAgICAgICAgICAgICAgdmlldzogdGhpcy52aWV3LFxuICAgICAgICAgICAgICAgICAgICBwcm9ncmVzc1NpemU6IHRoaXMub3B0aW9ucy5iYXJTaXplLFxuICAgICAgICAgICAgICAgIH0sIG1hcmtlckNmZ1tpXSk7XG4gICAgICAgICAgICAgICAgdmFyIG1hcmtlciA9IG5ldyBtYXJrZXJfMS5kZWZhdWx0KGNmZyk7XG4gICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJzLnB1c2gobWFya2VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUuZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICBpZiAoaGVpZ2h0ID49IDUwKSB7XG4gICAgICAgICAgICByZXR1cm4gMTA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDQ7XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5zdHlsZVVwZGF0ZUFuaW1hdGlvbiA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgICAvLyBzdHlsZeabtOaWsOWKqOeUu+aOpeWPl+eUqOaIt2FuaW1hdGlvbumFjee9rueahOmAj+S8oFxuICAgICAgICB2YXIgX2EgPSB0aGlzLmdldFVwZGF0ZUFuaW1hdGlvbk9wdGlvbnMoKSwgZHVyYXRpb24gPSBfYS5kdXJhdGlvbiwgZWFzaW5nID0gX2EuZWFzaW5nO1xuICAgICAgICAvLyBnZXQgZ2VvbWV0cnkgc2hhcGVzXG4gICAgICAgIHZhciBwcm9ncmVzc1NoYXBlcyA9IFtdO1xuICAgICAgICB2YXIgdmlldyA9IHRoaXMudmlldztcbiAgICAgICAgdmFyIGdlb21ldHJ5ID0gdmlldy5nZW9tZXRyaWVzO1xuICAgICAgICB1dGlsXzEuZWFjaChnZW9tZXRyeSwgZnVuY3Rpb24gKGdlb20pIHtcbiAgICAgICAgICAgIGlmIChnZW9tLnR5cGUgPT09ICdpbnRlcnZhbCcpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudHMgPSBnZW9tLmVsZW1lbnRzO1xuICAgICAgICAgICAgICAgIHV0aWxfMS5lYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb2dyZXNzU2hhcGVzLnB1c2guYXBwbHkocHJvZ3Jlc3NTaGFwZXMsIGVsZS5zaGFwZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoc3R5bGUpKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzdHlsZSwgZnVuY3Rpb24gKHMsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NTaGFwZXNbaW5kZXhdLmFuaW1hdGUocywgZHVyYXRpb24sIGVhc2luZyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHByb2dyZXNzU2hhcGVzWzBdLmFuaW1hdGUoc3R5bGUsIGR1cmF0aW9uLCBlYXNpbmcpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5nZXRVcGRhdGVBbmltYXRpb25PcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZHVyYXRpb24gPSA0NTA7XG4gICAgICAgIHZhciBlYXNpbmcgPSAnZWFzZVF1YWRJbk91dCc7XG4gICAgICAgIHZhciBhbmltYXRpb25PcHRpb25zID0gdGhpcy5vcHRpb25zLmFuaW1hdGlvbjtcbiAgICAgICAgaWYgKGFuaW1hdGlvbk9wdGlvbnMgJiYgYW5pbWF0aW9uT3B0aW9ucy51cGRhdGUpIHtcbiAgICAgICAgICAgIGlmIChhbmltYXRpb25PcHRpb25zLnVwZGF0ZS5kdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gYW5pbWF0aW9uT3B0aW9ucy51cGRhdGUuZHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYW5pbWF0aW9uT3B0aW9ucy51cGRhdGUuZWFzaW5nKSB7XG4gICAgICAgICAgICAgICAgZWFzaW5nID0gYW5pbWF0aW9uT3B0aW9ucy51cGRhdGUuZWFzaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IGR1cmF0aW9uOiBkdXJhdGlvbiwgZWFzaW5nOiBlYXNpbmcgfTtcbiAgICB9O1xuICAgIFByb2dyZXNzTGF5ZXIucHJvdG90eXBlLnVwZGF0ZUNvbG9yQ29uZmlnQnlTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICBpZiAodXRpbF8xLmlzQXJyYXkoc3R5bGUpKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzdHlsZSwgZnVuY3Rpb24gKHMsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgaWYgKHMuZmlsbCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5vcHRpb25zLmNvbG9yW2luZGV4XSA9IHMuZmlsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdHlsZS5maWxsKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuY29sb3JbMF0gPSBzdHlsZS5maWxsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gUHJvZ3Jlc3NMYXllcjtcbn0odGlueV9sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFByb2dyZXNzTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdwcm9ncmVzcycsIFByb2dyZXNzTGF5ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIGNvbXBvbmVudE1hcCA9IHtcbiAgICByaW5nUHJvZ3Jlc3M6ICdpbnRlcnZhbCcsXG59O1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IGV2ZW50XzEuZ2V0RXZlbnRNYXAoY29tcG9uZW50TWFwKTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgUmluZ1Byb2dyZXNzID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJpbmdQcm9ncmVzcywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSaW5nUHJvZ3Jlc3MoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgUmluZ1Byb2dyZXNzLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAncmluZ1Byb2dyZXNzJztcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jcmVhdGVMYXllcnMuY2FsbCh0aGlzLCBsYXllclByb3BzKTtcbiAgICB9O1xuICAgIFJpbmdQcm9ncmVzcy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBsYXllciA9IHRoaXMubGF5ZXJzWzBdO1xuICAgICAgICBsYXllci51cGRhdGUodmFsdWUpO1xuICAgIH07XG4gICAgUmluZ1Byb2dyZXNzLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBSaW5nUHJvZ3Jlc3M7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSaW5nUHJvZ3Jlc3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vcHJvZ3Jlc3MvbGF5ZXJcIikpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIERFRkFVTFRfQ09MT1IgPSBbJyM1NUE2RjMnLCAnI0U4RURGMyddO1xudmFyIFJpbmdQcm9ncmVzc0xheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFJpbmdQcm9ncmVzc0xheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJpbmdQcm9ncmVzc0xheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdyaW5nUHJvZ3Jzc3MnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFJpbmdQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5wcm9jZXNzUHJvcHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgcHJvcHMuZGF0YSA9IHRoaXMucHJvY2Vzc0RhdGEoKTtcbiAgICAgICAgdmFyIGNmZyA9IHtcbiAgICAgICAgICAgIHBhZGRpbmc6IFswLCAwLCAwLCAwXSxcbiAgICAgICAgICAgIHhGaWVsZDogJ3ZhbHVlJyxcbiAgICAgICAgICAgIHlGaWVsZDogJzEnLFxuICAgICAgICAgICAgc3RhY2tGaWVsZDogJ3R5cGUnLFxuICAgICAgICAgICAgYmFyU3R5bGU6IHByb3BzLnByb2dyZXNzU3R5bGUsXG4gICAgICAgICAgICBjb2xvcjogdGhpcy5wYXJzZUNvbG9yUHJvcHMocHJvcHMpIHx8IERFRkFVTFRfQ09MT1IsXG4gICAgICAgIH07XG4gICAgICAgIHByb3BzID0gdXRpbF8xLm1peChwcm9wcywgY2ZnKTtcbiAgICB9O1xuICAgIFJpbmdQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5jb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvb3JkQ29uZmlnID0ge1xuICAgICAgICAgICAgdHlwZTogJ3RoZXRhJyxcbiAgICAgICAgICAgIGNmZzoge1xuICAgICAgICAgICAgICAgIHJhZGl1czogMS4wLFxuICAgICAgICAgICAgICAgIGlubmVyUmFkaXVzOiB0aGlzLmdldFRoaWNrbmVzcyh0aGlzLm9wdGlvbnMuc2l6ZSksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldENvbmZpZygnY29vcmRpbmF0ZScsIGNvb3JkQ29uZmlnKTtcbiAgICB9O1xuICAgIFJpbmdQcm9ncmVzc0xheWVyLnByb3RvdHlwZS5hbm5vdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbiAgICBSaW5nUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdGhpcy5yaW5nID0gZmFjdG9yeV8xLmdldEdlb20oJ2ludGVydmFsJywgJ21haW4nLCB7XG4gICAgICAgICAgICBwb3NpdGlvbkZpZWxkczogW3Byb3BzLnlGaWVsZCwgcHJvcHMueEZpZWxkXSxcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJpbmcuYWRqdXN0ID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCB0aGlzLnJpbmcpO1xuICAgIH07XG4gICAgUmluZ1Byb2dyZXNzTGF5ZXIucHJvdG90eXBlLmFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yaW5nLmFuaW1hdGUgPSB7XG4gICAgICAgICAgICBhcHBlYXI6IHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogMTAwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBSaW5nUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUucGFyc2VFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucGFyc2VFdmVudHMuY2FsbCh0aGlzLCBFdmVudFBhcnNlcik7XG4gICAgfTtcbiAgICBSaW5nUHJvZ3Jlc3NMYXllci5wcm90b3R5cGUuZ2V0VGhpY2tuZXNzID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgIHZhciBoZWlnaHQgPSB0aGlzLmhlaWdodDtcbiAgICAgICAgdmFyIHNpemUgPSBNYXRoLm1pbih3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gMS4wIC0gdmFsdWUgLyBzaXplO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzaXplID49IDYwKSB7XG4gICAgICAgICAgICByZXR1cm4gMS4wIC0gMjAgLyBzaXplO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAxLjAgLSAxMCAvIHNpemU7XG4gICAgfTtcbiAgICByZXR1cm4gUmluZ1Byb2dyZXNzTGF5ZXI7XG59KGxheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUmluZ1Byb2dyZXNzTGF5ZXI7XG5nbG9iYWxfMS5yZWdpc3RlclBsb3RUeXBlKCdyaW5nUHJvZ3Jlc3MnLCBSaW5nUHJvZ3Jlc3NMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVWRU5UX01BUFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5FVkVOVF9NQVA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvbkV2ZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLm9uRXZlbnQ7IH0gfSk7XG52YXIgU0hBUEVfRVZFTlRfTUFQID0ge1xuICAgIG9uQXJlYUNsaWNrOiAnYXJlYTpjbGljaycsXG4gICAgb25BcmVhRGJsY2xpY2s6ICdhcmVhOmRibGNsaWNrJyxcbiAgICBvbkFyZWFNb3VzZW1vdmU6ICdhcmVhOm1vdXNlbW92ZScsXG4gICAgb25BcmVhTW91c2Vkb3duOiAnYXJlYTptb3VzZWRvd24nLFxuICAgIG9uQXJlYU1vdXNldXA6ICdhcmVhOm1vdXNldXAnLFxuICAgIG9uQXJlYU1vdXNlZW50ZXI6ICdhcmVhOm1vdXNlZW50ZXInLFxuICAgIG9uQXJlYU1vdXNlbGVhdmU6ICdhcmVhOm1vdXNlbGVhdmUnLFxuICAgIG9uQXJlYUNvbnRleHRtZW51OiAnYXJlYTpjb250ZXh0bWVudScsXG4gICAgb25MaW5lQ2xpY2s6ICdsaW5lOmNsaWNrJyxcbiAgICBvbkxpbmVEYmxjbGljazogJ2xpbmU6ZGJsY2xpY2snLFxuICAgIG9uTGluZU1vdXNlbW92ZTogJ2xpbmU6bW91c2Vtb3ZlJyxcbiAgICBvbkxpbmVNb3VzZWRvd246ICdsaW5lOm1vdXNlZG93bicsXG4gICAgb25MaW5lTW91c2V1cDogJ2xpbmU6bW91c2V1cCcsXG4gICAgb25MaW5lTW91c2VlbnRlcjogJ2xpbmU6bW91c2VlbnRlcicsXG4gICAgb25MaW5lTW91c2VsZWF2ZTogJ2xpbmU6bW91c2VsZWF2ZScsXG4gICAgb25MaW5lQ29udGV4dG1lbnU6ICdsaW5lOmNvbnRleHRtZW51Jyxcbn07XG51dGlsXzEuYXNzaWduKGV2ZW50XzEuRVZFTlRfTUFQLCBTSEFQRV9FVkVOVF9NQVApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBwbG90XzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vLi4vYmFzZS9wbG90XCIpKTtcbnZhciBsYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbGF5ZXJcIikpO1xudmFyIFRpbnlBcmVhID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFRpbnlBcmVhLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRpbnlBcmVhKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFRpbnlBcmVhLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAndGlueUFyZWEnO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNyZWF0ZUxheWVycy5jYWxsKHRoaXMsIGxheWVyUHJvcHMpO1xuICAgIH07XG4gICAgVGlueUFyZWEuZ2V0RGVmYXVsdE9wdGlvbnMgPSBsYXllcl8xLmRlZmF1bHQuZ2V0RGVmYXVsdE9wdGlvbnM7XG4gICAgcmV0dXJuIFRpbnlBcmVhO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGlueUFyZWE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4uLy4uL2Jhc2UvZ2xvYmFsXCIpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi8uLi9nZW9tcy9mYWN0b3J5XCIpO1xudmFyIHRpbnlfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi90aW55LWxheWVyXCIpKTtcbnZhciBFdmVudFBhcnNlciA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2V2ZW50XCIpKTtcbnZhciBHRU9NX01BUCA9IHtcbiAgICBhcmVhOiAnYXJlYScsXG4gICAgbGluZTogJ2xpbmUnLFxufTtcbnZhciBUaW55QXJlYUxheWVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFRpbnlBcmVhTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVGlueUFyZWFMYXllcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAndGlueUFyZWEnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRpbnlBcmVhTGF5ZXIucHJvdG90eXBlLmdlb21ldHJ5UGFyc2VyID0gZnVuY3Rpb24gKGRpbSwgdHlwZSkge1xuICAgICAgICByZXR1cm4gR0VPTV9NQVBbdHlwZV07XG4gICAgfTtcbiAgICBUaW55QXJlYUxheWVyLnByb3RvdHlwZS5hZGRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hcmVhID0gZmFjdG9yeV8xLmdldEdlb20oJ2FyZWEnLCAnbWluaScsIHtcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnZ2VvbWV0cnknLCB0aGlzLmFyZWEpO1xuICAgICAgICB0aGlzLmxpbmUgPSBmYWN0b3J5XzEuZ2V0R2VvbSgnbGluZScsICdtaW5pJywge1xuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIHRoaXMubGluZSk7XG4gICAgfTtcbiAgICBUaW55QXJlYUxheWVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5wYXJzZUV2ZW50cy5jYWxsKHRoaXMsIEV2ZW50UGFyc2VyKTtcbiAgICB9O1xuICAgIHJldHVybiBUaW55QXJlYUxheWVyO1xufSh0aW55X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGlueUFyZWFMYXllcjtcbmdsb2JhbF8xLnJlZ2lzdGVyUGxvdFR5cGUoJ3RpbnlBcmVhJywgVGlueUFyZWFMYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub25FdmVudCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50XzEgPSByZXF1aXJlKFwiLi4vLi4vdXRpbC9ldmVudFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVWRU5UX01BUFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5FVkVOVF9NQVA7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvbkV2ZW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBldmVudF8xLm9uRXZlbnQ7IH0gfSk7XG52YXIgU0hBUEVfRVZFTlRfTUFQID0ge1xuICAgIG9uQ29sdW1uQ2xpY2s6ICdpbnRlcnZhbDpjbGljaycsXG4gICAgb25Db2x1bW5EYmxjbGljazogJ2ludGVydmFsOmRibGNsaWNrJyxcbiAgICBvbkNvbHVtbk1vdXNlbW92ZTogJ2ludGVydmFsOm1vdXNlbW92ZScsXG4gICAgb25Db2x1bW5Nb3VzZWRvd246ICdpbnRlcnZhbDptb3VzZWRvd24nLFxuICAgIG9uQ29sdW1uTW91c2V1cDogJ2ludGVydmFsOm1vdXNldXAnLFxuICAgIG9uQ29sdW1uTW91c2VlbnRlcjogJ2ludGVydmFsOm1vdXNlZW50ZXInLFxuICAgIG9uQ29sdW1uTW91c2VsZWF2ZTogJ2ludGVydmFsOm1vdXNlbGVhdmUnLFxuICAgIG9uQ29sdW1uQ29udGV4dG1lbnU6ICdpbnRlcnZhbDpjb250ZXh0bWVudScsXG59O1xudXRpbF8xLmFzc2lnbihldmVudF8xLkVWRU5UX01BUCwgU0hBUEVfRVZFTlRfTUFQKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcGxvdF8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uLy4uL2Jhc2UvcGxvdFwiKSk7XG52YXIgbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2xheWVyXCIpKTtcbnZhciBUaW55Q29sdW1uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFRpbnlDb2x1bW4sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVGlueUNvbHVtbigpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBUaW55Q29sdW1uLnByb3RvdHlwZS5jcmVhdGVMYXllcnMgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgdmFyIGxheWVyUHJvcHMgPSB1dGlsXzEuZGVlcE1peCh7fSwgcHJvcHMpO1xuICAgICAgICBsYXllclByb3BzLnR5cGUgPSAndGlueUNvbHVtbic7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBUaW55Q29sdW1uLmdldERlZmF1bHRPcHRpb25zID0gbGF5ZXJfMS5kZWZhdWx0LmdldERlZmF1bHRPcHRpb25zO1xuICAgIHJldHVybiBUaW55Q29sdW1uO1xufShwbG90XzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGlueUNvbHVtbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgZmFjdG9yeV8xID0gcmVxdWlyZShcIi4uLy4uL2dlb21zL2ZhY3RvcnlcIik7XG52YXIgdGlueV9sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3RpbnktbGF5ZXJcIikpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIFdJRFRIX1JBVElPID0gMC42O1xudmFyIEcyX0dFT01fTUFQID0ge1xuICAgIGNvbHVtbjogJ2ludGVydmFsJyxcbn07XG52YXIgUExPVF9HRU9NX01BUCA9IHtcbiAgICBpbnRlcnZhbDogJ2NvbHVtbicsXG59O1xudmFyIFRpbnlDb2x1bW5MYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUaW55Q29sdW1uTGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVGlueUNvbHVtbkxheWVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICd0aW55Q29sdW1uJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUaW55Q29sdW1uTGF5ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc1Byb3BzKCk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgVGlueUNvbHVtbkxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgaWYgKGRpbSA9PT0gJ2cyJykge1xuICAgICAgICAgICAgcmV0dXJuIEcyX0dFT01fTUFQW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQTE9UX0dFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgVGlueUNvbHVtbkxheWVyLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBzY2FsZXMgPSB7fTtcbiAgICAgICAgLyoqIOmFjee9rngtc2NhbGUgKi9cbiAgICAgICAgc2NhbGVzW29wdGlvbnMueEZpZWxkXSA9IHsgdHlwZTogJ2NhdCcgfTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ3NjYWxlcycsIHNjYWxlcyk7XG4gICAgfTtcbiAgICBUaW55Q29sdW1uTGF5ZXIucHJvdG90eXBlLmFkZEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcHJvcHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciBjb2x1bW4gPSBmYWN0b3J5XzEuZ2V0R2VvbSgnaW50ZXJ2YWwnLCAnbWFpbicsIHtcbiAgICAgICAgICAgIHBvc2l0aW9uRmllbGRzOiBbcHJvcHMueEZpZWxkLCBwcm9wcy55RmllbGRdLFxuICAgICAgICAgICAgcGxvdDogdGhpcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKCdnZW9tZXRyeScsIGNvbHVtbik7XG4gICAgfTtcbiAgICBUaW55Q29sdW1uTGF5ZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgRXZlbnRQYXJzZXIpO1xuICAgIH07XG4gICAgVGlueUNvbHVtbkxheWVyLnByb3RvdHlwZS5wcm9jZXNzUHJvcHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjZmcgPSB7XG4gICAgICAgICAgICBwYWRkaW5nOiBbMCwgMCwgMCwgMF0sXG4gICAgICAgICAgICBjb2x1bW5TaXplOiB0aGlzLmdldFNpemUoKSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdXRpbF8xLm1peCh0aGlzLm9wdGlvbnMsIGNmZyk7XG4gICAgfTtcbiAgICBUaW55Q29sdW1uTGF5ZXIucHJvdG90eXBlLmdldFNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGNvbHVtbk51bWJlciA9IHRoaXMuZ2V0Q29sdW1uTnVtKHByb3BzLmRhdGEsIHByb3BzLnhGaWVsZCk7XG4gICAgICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgIHJldHVybiAod2lkdGggLyBjb2x1bW5OdW1iZXIpICogV0lEVEhfUkFUSU87XG4gICAgfTtcbiAgICBUaW55Q29sdW1uTGF5ZXIucHJvdG90eXBlLmdldENvbHVtbk51bSA9IGZ1bmN0aW9uIChkYXRhLCBmaWVsZCkge1xuICAgICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICAgIHV0aWxfMS5lYWNoKGRhdGEsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICB2YXIgdiA9IGRbZmllbGRdO1xuICAgICAgICAgICAgaWYgKHZhbHVlcy5pbmRleE9mKHYpIDwgMCkge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5sZW5ndGg7XG4gICAgfTtcbiAgICByZXR1cm4gVGlueUNvbHVtbkxheWVyO1xufSh0aW55X2xheWVyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGlueUNvbHVtbkxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgndGlueUNvbHVtbicsIFRpbnlDb2x1bW5MYXllcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXllci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHZpZXdfbGF5ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9iYXNlL3ZpZXctbGF5ZXJcIikpO1xudmFyIGZhY3RvcnlfMSA9IHJlcXVpcmUoXCIuLi9jb21wb25lbnRzL2ZhY3RvcnlcIik7XG5yZXF1aXJlKFwiLi4vZ2VvbXMvbGluZS9taW5pXCIpO1xudmFyIFRpbnlMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUaW55TGF5ZXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVGlueUxheWVyKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIFRpbnlMYXllci5nZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5kZWVwTWl4KHt9LCBfc3VwZXIuZ2V0RGVmYXVsdE9wdGlvbnMuY2FsbCh0aGlzKSwge1xuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBhZGRpbmc6IFswLCAwLCAwLCAwXSxcbiAgICAgICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFRpbnlMYXllci5wcm90b3R5cGUuY29vcmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIFRpbnlMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuICAgIFRpbnlMYXllci5wcm90b3R5cGUuYW5ub3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5vcHRpb25zO1xuICAgICAgICB2YXIgY29uZmlnID0gW107XG4gICAgICAgIHZhciBkZWZhdWx0R3VpZGVsaW5lQ2ZnID0ge1xuICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAnIzY2ZDZhOCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHV0aWxfMS5lYWNoKHByb3BzLmd1aWRlTGluZSwgZnVuY3Rpb24gKGxpbmUpIHtcbiAgICAgICAgICAgIHZhciBndWlkZUxpbmUgPSBmYWN0b3J5XzEuZ2V0Q29tcG9uZW50KCdndWlkZUxpbmUnLCB7XG4gICAgICAgICAgICAgICAgcGxvdDogX3RoaXMsXG4gICAgICAgICAgICAgICAgY2ZnOiB1dGlsXzEuZGVlcE1peCh7fSwgZGVmYXVsdEd1aWRlbGluZUNmZywgbGluZSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbmZpZy5wdXNoKGd1aWRlTGluZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldENvbmZpZygnYW5ub3RhdGlvbnMnLCBjb25maWcpO1xuICAgIH07XG4gICAgcmV0dXJuIFRpbnlMYXllcjtcbn0odmlld19sYXllcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRpbnlMYXllcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRpbnktbGF5ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkVWRU5UX01BUCA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBldmVudF8xID0gcmVxdWlyZShcIi4uLy4uL3V0aWwvZXZlbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFVkVOVF9NQVBcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGV2ZW50XzEuRVZFTlRfTUFQOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib25FdmVudFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZXZlbnRfMS5vbkV2ZW50OyB9IH0pO1xudmFyIFNIQVBFX0VWRU5UX01BUCA9IHtcbiAgICBvbkxpbmVDbGljazogJ2xpbmU6Y2xpY2snLFxuICAgIG9uTGluZURibGNsaWNrOiAnbGluZTpkYmxjbGljaycsXG4gICAgb25MaW5lTW91c2Vtb3ZlOiAnbGluZTptb3VzZW1vdmUnLFxuICAgIG9uTGluZU1vdXNlZG93bjogJ2xpbmU6bW91c2Vkb3duJyxcbiAgICBvbkxpbmVNb3VzZXVwOiAnbGluZTptb3VzZXVwJyxcbiAgICBvbkxpbmVNb3VzZWVudGVyOiAnbGluZTptb3VzZWVudGVyJyxcbiAgICBvbkxpbmVNb3VzZWxlYXZlOiAnbGluZTptb3VzZWxlYXZlJyxcbiAgICBvbkxpbmVDb250ZXh0bWVudTogJ2xpbmU6Y29udGV4dG1lbnUnLFxufTtcbnV0aWxfMS5hc3NpZ24oZXZlbnRfMS5FVkVOVF9NQVAsIFNIQVBFX0VWRU5UX01BUCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHBsb3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi8uLi9iYXNlL3Bsb3RcIikpO1xudmFyIGxheWVyXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9sYXllclwiKSk7XG52YXIgVGlueUxpbmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoVGlueUxpbmUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVGlueUxpbmUoKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICB9XG4gICAgVGlueUxpbmUucHJvdG90eXBlLmNyZWF0ZUxheWVycyA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgICAgICB2YXIgbGF5ZXJQcm9wcyA9IHV0aWxfMS5kZWVwTWl4KHt9LCBwcm9wcyk7XG4gICAgICAgIGxheWVyUHJvcHMudHlwZSA9ICd0aW55TGluZSc7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY3JlYXRlTGF5ZXJzLmNhbGwodGhpcywgbGF5ZXJQcm9wcyk7XG4gICAgfTtcbiAgICBUaW55TGluZS5nZXREZWZhdWx0T3B0aW9ucyA9IGxheWVyXzEuZGVmYXVsdC5nZXREZWZhdWx0T3B0aW9ucztcbiAgICByZXR1cm4gVGlueUxpbmU7XG59KHBsb3RfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUaW55TGluZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZ2xvYmFsXzEgPSByZXF1aXJlKFwiLi4vLi4vYmFzZS9nbG9iYWxcIik7XG52YXIgZmFjdG9yeV8xID0gcmVxdWlyZShcIi4uLy4uL2dlb21zL2ZhY3RvcnlcIik7XG52YXIgdGlueV9sYXllcl8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3RpbnktbGF5ZXJcIikpO1xudmFyIEV2ZW50UGFyc2VyID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4vZXZlbnRcIikpO1xudmFyIEdFT01fTUFQID0ge1xuICAgIGxpbmU6ICdsaW5lJyxcbn07XG52YXIgVGlueUxpbmVMYXllciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUaW55TGluZUxheWVyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRpbnlMaW5lTGF5ZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3RpbnlMaW5lJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUaW55TGluZUxheWVyLnByb3RvdHlwZS5nZW9tZXRyeVBhcnNlciA9IGZ1bmN0aW9uIChkaW0sIHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIEdFT01fTUFQW3R5cGVdO1xuICAgIH07XG4gICAgVGlueUxpbmVMYXllci5wcm90b3R5cGUuYWRkR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMubGluZSA9IGZhY3RvcnlfMS5nZXRHZW9tKCdsaW5lJywgJ21pbmknLCB7XG4gICAgICAgICAgICBwbG90OiB0aGlzLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoJ2dlb21ldHJ5JywgdGhpcy5saW5lKTtcbiAgICB9O1xuICAgIFRpbnlMaW5lTGF5ZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnBhcnNlRXZlbnRzLmNhbGwodGhpcywgRXZlbnRQYXJzZXIpO1xuICAgIH07XG4gICAgcmV0dXJuIFRpbnlMaW5lTGF5ZXI7XG59KHRpbnlfbGF5ZXJfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBUaW55TGluZUxheWVyO1xuZ2xvYmFsXzEucmVnaXN0ZXJQbG90VHlwZSgndGlueUxpbmUnLCBUaW55TGluZUxheWVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxheWVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5ERUZBVUxUX0RBUktfVEhFTUUgPSB2b2lkIDA7XG52YXIgZGVmYXVsdF8xID0gcmVxdWlyZShcIi4vZGVmYXVsdFwiKTtcbmV4cG9ydHMuREVGQVVMVF9EQVJLX1RIRU1FID0ge1xuICAgIGJhY2tncm91bmRTdHlsZToge1xuICAgICAgICBmaWxsOiAnIzI2MjYyNicsXG4gICAgfSxcbiAgICBkZWZhdWx0Q29sb3I6ICcjNUI4RkY5JyxcbiAgICB3aWR0aDogNDAwLFxuICAgIGhlaWdodDogNDAwLFxuICAgIGJsZWVkaW5nOiBbZGVmYXVsdF8xLlRPUF9CTEVFRElORywgMjQsIGRlZmF1bHRfMS5CT1RUT01fQkxFRURJTkcsIDI0XSxcbiAgICBwYWRkaW5nOiAnYXV0bycsXG4gICAgdGl0bGU6IHtcbiAgICAgICAgcGFkZGluZzogWzI0LCAyNCwgMjQsIDI0XSxcbiAgICAgICAgZm9udEZhbWlseTogJ1BpbmdGYW5nIFNDJyxcbiAgICAgICAgZm9udFNpemU6IDE4LFxuICAgICAgICBmb250V2VpZ2h0OiAnYm9sZCcsXG4gICAgICAgIGZpbGw6ICdyZ2JhKDI1NSwyNTUsMjU1LDAuNjUpJyxcbiAgICAgICAgc3Ryb2tlOiAncmdiYSgwLDAsMCwwLjk1KScsXG4gICAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxuICAgICAgICB0ZXh0QmFzZWxpbmU6ICd0b3AnLFxuICAgICAgICBsaW5lSGVpZ2h0OiAyMCxcbiAgICAgICAgYWxpZ25XaXRoQXhpczogZmFsc2UsXG4gICAgfSxcbiAgICBkZXNjcmlwdGlvbjoge1xuICAgICAgICBwYWRkaW5nOiBbMTAsIDI0LCBkZWZhdWx0XzEuREVTQ1JJUFRJT05fQk9UVE9NX01BUkdJTiwgMjRdLFxuICAgICAgICBmb250RmFtaWx5OiAnUGluZ0ZhbmcgU0MnLFxuICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgIGZpbGw6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNjUpJyxcbiAgICAgICAgc3Ryb2tlOiAncmdiYSgwLDAsMCwwLjk1KScsXG4gICAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxuICAgICAgICB0ZXh0QmFzZWxpbmU6ICd0b3AnLFxuICAgICAgICBsaW5lSGVpZ2h0OiAxNixcbiAgICAgICAgYWxpZ25XaXRoQXhpczogZmFsc2UsXG4gICAgfSxcbiAgICBheGlzOiB7XG4gICAgICAgIHk6IHtcbiAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2xlZnQnLFxuICAgICAgICAgICAgYXV0b1JvdGF0ZVRpdGxlOiB0cnVlLFxuICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjE1KScsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lRGFzaDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLjUsXG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aDogNCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDgsXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzcGFjaW5nOiAxMixcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjY1KScsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnYm90dG9tJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgeDoge1xuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICAgIGF1dG9Sb3RhdGVUaXRsZTogZmFsc2UsXG4gICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjE1KScsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lRGFzaDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBsZW5ndGg6IDQsXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJ3JnYmEoMjU1LCAyNTUsIDI1NSwgMC40NSknLFxuICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDAuNSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB0ZXh0U3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMjU1LCAyNTUsIDI1NSwgMC42NSknLFxuICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDE2LFxuICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGF1dG9Sb3RhdGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzcGFjaW5nOiAxMixcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjY1KScsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgY2lyY2xlOiB7XG4gICAgICAgICAgICBhdXRvUm90YXRlVGl0bGU6IHRydWUsXG4gICAgICAgICAgICAvLyBncmlkVHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpbmVEYXNoOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJyNFM0U4RUMnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAnI0JGQkZCRicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAnI2JkYzhkMycsXG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aDogNCxcbiAgICAgICAgICAgICAgICAgICAgYWxpZ25XaXRoTGFiZWw6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIG9mZnNldDogMTYsXG4gICAgICAgICAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICcjYTBhNGFhJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhdXRvSGlkZTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgIG9mZnNldDogMTIsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHsgZmlsbDogJyM3NjdiODQnLCBmb250U2l6ZTogMTIgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHJhZGl1czoge1xuICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDEyLFxuICAgICAgICAgICAgICAgIHRleHRTdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnI2EwYTRhYScsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIGxlZ2VuZDoge1xuICAgICAgICBmbGlwUGFnZTogZmFsc2UsXG4gICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgLy8g6Led56a7cGFuZWxSYW5nZeeahOi3neemu1xuICAgICAgICBpbm5lclBhZGRpbmc6IFsxNiwgMTYsIDE2LCAxNl0sXG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZmlsbDogJyNiZGM4ZDMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgdGV4dDoge1xuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBmaWxsOiAnI2JkYzhkMycsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgb2Zmc2V0OiAxMixcbiAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjY1KScsXG4gICAgICAgIH0sXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjY1KScsXG4gICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBjb21wb25lbnRzOiB7XG4gICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgIGRvbVN0eWxlczoge1xuICAgICAgICAgICAgICAgICdnMi10b29sdGlwJzoge1xuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDMzLDMzLDMzLCAwLjk1KScsXG4gICAgICAgICAgICAgICAgICAgIGJveFNoYWRvdzogJzBweCAwcHggOHB4IHJnYmEoMCwwLDAsMC42NSknLFxuICAgICAgICAgICAgICAgICAgICBjb2xvcjogJ3JnYmEoMjU1LCAyNTUsIDI1NSwgMC42NSknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGFyay5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuREVGQVVMVF9HTE9CQUxfVEhFTUUgPSBleHBvcnRzLkJPVFRPTV9CTEVFRElORyA9IGV4cG9ydHMuVE9QX0JMRUVESU5HID0gZXhwb3J0cy5ERVNDUklQVElPTl9CT1RUT01fTUFSR0lOID0gZXhwb3J0cy5DT0xPUl9QTEFURV8yMCA9IGV4cG9ydHMuQ09MT1JfUExBVEVfMTAgPSB2b2lkIDA7XG52YXIgQ09MT1IgPSAnIzVCOEZGOSc7XG5leHBvcnRzLkNPTE9SX1BMQVRFXzEwID0gW1xuICAgICcjNUI4RkY5JyxcbiAgICAnIzVBRDhBNicsXG4gICAgJyM1RDcwOTInLFxuICAgICcjRjZCRDE2JyxcbiAgICAnI0U4Njg0QScsXG4gICAgJyM2REM4RUMnLFxuICAgICcjOTI3MENBJyxcbiAgICAnI0ZGOUQ0RCcsXG4gICAgJyMyNjlBOTknLFxuICAgICcjRkY5OUMzJyxcbl07XG5leHBvcnRzLkNPTE9SX1BMQVRFXzIwID0gW1xuICAgICcjNUI4RkY5JyxcbiAgICAnI0JERDJGRCcsXG4gICAgJyM1QUQ4QTYnLFxuICAgICcjQkRFRkRCJyxcbiAgICAnIzVENzA5MicsXG4gICAgJyNDMkM4RDUnLFxuICAgICcjRjZCRDE2JyxcbiAgICAnI0ZCRTVBMicsXG4gICAgJyNFODY4NEEnLFxuICAgICcjRjZDM0I3JyxcbiAgICAnIzZEQzhFQycsXG4gICAgJyNCNkUzRjUnLFxuICAgICcjOTI3MENBJyxcbiAgICAnI0QzQzZFQScsXG4gICAgJyNGRjlENEQnLFxuICAgICcjRkZEOEI4JyxcbiAgICAnIzI2OUE5OScsXG4gICAgJyNBQUQ4RDgnLFxuICAgICcjRkY5OUMzJyxcbiAgICAnI0ZGRDZFNycsXG5dO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuZXhwb3J0cy5ERVNDUklQVElPTl9CT1RUT01fTUFSR0lOID0gZnVuY3Rpb24gKGxlZ2VuZFBvc2l0aW9uKSB7XG4gICAgaWYgKGxlZ2VuZFBvc2l0aW9uICYmIGxlZ2VuZFBvc2l0aW9uLnNwbGl0KCctJylbMF0gPT09ICd0b3AnKSB7XG4gICAgICAgIHJldHVybiAxMjtcbiAgICB9XG4gICAgcmV0dXJuIDI0O1xufTtcbmV4cG9ydHMuVE9QX0JMRUVESU5HID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgdmFyIHRpdGxlVmlzaWJsZSA9IHByb3BzLnRpdGxlICYmIHByb3BzLnRpdGxlLnZpc2libGU7XG4gICAgdmFyIGRlc2NyaXB0aW9uVmlzaWJsZSA9IHByb3BzLmRlc2NyaXB0aW9uICYmIHByb3BzLmRlc2NyaXB0aW9uLnZpc2libGU7XG4gICAgaWYgKHRpdGxlVmlzaWJsZSB8fCBkZXNjcmlwdGlvblZpc2libGUpIHtcbiAgICAgICAgLy8g55SxIHRpdGxlL2Rlc2NyaXB0aW9uIOeahCBib3R0b20tcGFkZGluZyDotJ/otKNcbiAgICAgICAgcmV0dXJuIDEyO1xuICAgIH1cbiAgICByZXR1cm4gMjQ7XG59O1xuZXhwb3J0cy5CT1RUT01fQkxFRURJTkcgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICBpZiAodXRpbF8xLnNvbWUocHJvcHMuaW50ZXJhY3Rpb25zIHx8IFtdLCBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIChpbnRlcmFjdGlvbi50eXBlID09PSAnc2xpZGVyJyB8fCBpbnRlcmFjdGlvbi50eXBlID09PSAnc2Nyb2xsYmFyJykgJiZcbiAgICAgICAgICAgIChpbnRlcmFjdGlvbi5jZmcgJiYgaW50ZXJhY3Rpb24uY2ZnLnR5cGUpICE9PSAndmVydGljYWwnO1xuICAgIH0pKSB7XG4gICAgICAgIHJldHVybiA4O1xuICAgIH1cbiAgICByZXR1cm4gMjQ7XG59O1xuZXhwb3J0cy5ERUZBVUxUX0dMT0JBTF9USEVNRSA9IHtcbiAgICB3aWR0aDogNDAwLFxuICAgIGhlaWdodDogNDAwLFxuICAgIGJsZWVkaW5nOiBbZXhwb3J0cy5UT1BfQkxFRURJTkcsIDI0LCBleHBvcnRzLkJPVFRPTV9CTEVFRElORywgMjRdLFxuICAgIHBhZGRpbmc6ICdhdXRvJyxcbiAgICBkZWZhdWx0Q29sb3I6IENPTE9SLFxuICAgIGNvbG9yczogZXhwb3J0cy5DT0xPUl9QTEFURV8xMCxcbiAgICBjb2xvcnNfMjA6IGV4cG9ydHMuQ09MT1JfUExBVEVfMjAsXG4gICAgdGl0bGU6IHtcbiAgICAgICAgcGFkZGluZzogWzI0LCAyNCwgMjQsIDI0XSxcbiAgICAgICAgZm9udEZhbWlseTogJ1BpbmdGYW5nIFNDJyxcbiAgICAgICAgZm9udFNpemU6IDE4LFxuICAgICAgICBmaWxsOiAnYmxhY2snLFxuICAgICAgICB0ZXh0QWxpZ246ICdsZWZ0JyxcbiAgICAgICAgdGV4dEJhc2VsaW5lOiAndG9wJyxcbiAgICAgICAgbGluZUhlaWdodDogMjAsXG4gICAgICAgIGFsaWduV2l0aEF4aXM6IGZhbHNlLFxuICAgIH0sXG4gICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgcGFkZGluZzogWzEwLCAyNCwgZXhwb3J0cy5ERVNDUklQVElPTl9CT1RUT01fTUFSR0lOLCAyNF0sXG4gICAgICAgIGZvbnRGYW1pbHk6ICdQaW5nRmFuZyBTQycsXG4gICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgZmlsbDogJ2dyZXknLFxuICAgICAgICB0ZXh0QWxpZ246ICdsZWZ0JyxcbiAgICAgICAgdGV4dEJhc2VsaW5lOiAndG9wJyxcbiAgICAgICAgbGluZUhlaWdodDogMTYsXG4gICAgICAgIGFsaWduV2l0aEF4aXM6IGZhbHNlLFxuICAgIH0sXG4gICAgYXhpczoge1xuICAgICAgICB5OiB7XG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgcG9zaXRpb246ICdsZWZ0JyxcbiAgICAgICAgICAgIGF1dG9Sb3RhdGVUaXRsZTogdHJ1ZSxcbiAgICAgICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJ3JnYmEoMCwgMCwgMCwgMC4xNSknLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZURhc2g6IFswLCAwXSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsIDAsIDAsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGlja0xpbmU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsMCwwLDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLjUsXG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aDogNCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IDgsXG4gICAgICAgICAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICdyZ2JhKDAsMCwwLDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYXV0b1JvdGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXV0b0hpZGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzcGFjaW5nOiAxMixcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgwLCAwLCAwLCAwLjY1KScsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICAgICAgdGV4dEJhc2VsaW5lOiAnYm90dG9tJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgeDoge1xuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICAgIGF1dG9Sb3RhdGVUaXRsZTogZmFsc2UsXG4gICAgICAgICAgICBncmlkOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgwLCAwLCAwLCAwLjE1KScsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lRGFzaDogWzAsIDBdLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZToge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogJ3JnYmEoMCwgMCwgMCwgMC40NSknLFxuICAgICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aWNrTGluZToge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiA0LFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsIDAsIDAsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAwLjUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICdyZ2JhKDAsMCwwLDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAxNixcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc3BhY2luZzogMTIsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHsgZmlsbDogJ3JnYmEoMCwgMCwgMCwgMC42NSknLCBmb250U2l6ZTogMTIgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNpcmNsZToge1xuICAgICAgICAgICAgYXV0b0hpZGVMYWJlbDogZmFsc2UsXG4gICAgICAgICAgICAvLyBncmlkVHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVEYXNoOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAncmdiYSgwLCAwLCAwLCAwLjE1KScsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsIDAsIDAsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpY2tMaW5lOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiAxLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICdyZ2JhKDAsIDAsIDAsIDAuNDUpJyxcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiA0LFxuICAgICAgICAgICAgICAgICAgICBhbGlnbldpdGhMYWJlbDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAxNixcbiAgICAgICAgICAgICAgICB0ZXh0U3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3JnYmEoMCwwLDAsMC40NSknLFxuICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogMTIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhdXRvUm90YXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGF1dG9IaWRlOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAxMixcbiAgICAgICAgICAgICAgICBzdHlsZTogeyBmaWxsOiAncmdiYSgwLCAwLCAwLCAwLjY1KScsIGZvbnRTaXplOiAxMiB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcmFkaXVzOiB7XG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHRleHRTdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiAncmdiYSgwLDAsMCwwLjQ1KScsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIGxlZ2VuZDoge1xuICAgICAgICBmbGlwUGFnZTogZmFsc2UsXG4gICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgLy8g6Led56a7cGFuZWxSYW5nZeeahOi3neemu1xuICAgICAgICBpbm5lclBhZGRpbmc6IFsxNiwgMTYsIDE2LCAxNl0sXG4gICAgICAgIG1hcmdpbjogWzAsIDI0LCAyNCwgMjRdLFxuICAgIH0sXG4gICAgbGFiZWw6IHtcbiAgICAgICAgb2Zmc2V0OiAxMixcbiAgICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAnIzU5NTk1OScsXG4gICAgICAgIH0sXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICBmaWxsOiAnIzU5NTk1OScsXG4gICAgICAgICAgICBzdHJva2U6ICcjZmZmZmZmJyxcbiAgICAgICAgICAgIGxpbmVXaWR0aDogMixcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHRvb2x0aXA6IHtcbiAgICAgICAgJ2cyLXRvb2x0aXAnOiB7XG4gICAgICAgICAgICBib3hTaGFkb3c6ICcwcHggMHB4IDhweCByZ2JhKDAsMCwwLDAuMTUpJyxcbiAgICAgICAgfSxcbiAgICAgICAgb2Zmc2V0OiAxMCxcbiAgICB9LFxuICAgIC8vIEcyUGxvdCDnu4Tku7bkuLvpopjphY3nva5cbiAgICBjb21wb25lbnRzOiB7XG4gICAgICAgIGxlZ2VuZDoge1xuICAgICAgICAgICAgbWFyZ2luOiBbMCwgMjQsIDI0LCAyNF0sXG4gICAgICAgIH0sXG4gICAgICAgIHRvb2x0aXBJbmRpY2F0b3I6IHtcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDE0LFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzI2MjYyNicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGluYWN0aXZlU3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMC4zLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaXRlbVRpdGxlOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzhDOEM4QycsXG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbmFjdGl2ZVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuMyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGl0ZW1OYW1lOiB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDEyLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzhDOEM4QycsXG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbmFjdGl2ZVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuMyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGl0ZW1WYWx1ZToge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxNCxcbiAgICAgICAgICAgICAgICAgICAgZm9udFdlaWdodDogJ2JvbGQnLFxuICAgICAgICAgICAgICAgICAgICBmaWxsOiAnIzU5NTk1OScsXG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbmFjdGl2ZVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuMyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlZmF1bHQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldEdsb2JhbFRoZW1lID0gZXhwb3J0cy5yZWdpc3Rlckdsb2JhbFRoZW1lID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlZmF1bHRfMSA9IHJlcXVpcmUoXCIuL2RlZmF1bHRcIik7XG52YXIgZGFya18xID0gcmVxdWlyZShcIi4vZGFya1wiKTtcbi8qKiDmiYDmnInnmoTlhajlsYDkuLvpopggKi9cbnZhciBHTE9CQUxfVEhFTUVfTUFQID0ge1xuICAgIGRlZmF1bHQ6IGRlZmF1bHRfMS5ERUZBVUxUX0dMT0JBTF9USEVNRSxcbiAgICBkYXJrOiBkYXJrXzEuREVGQVVMVF9EQVJLX1RIRU1FLFxufTtcbi8qKlxuICog5rOo5YaM5YWo5bGA5Li76aKYXG4gKiBAcGFyYW0gbmFtZVxuICogQHBhcmFtIHRoZW1lXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyR2xvYmFsVGhlbWUobmFtZSwgdGhlbWUpIHtcbiAgICB2YXIgZGVmYXVsdFRoZW1lID0gZ2V0R2xvYmFsVGhlbWUoKTtcbiAgICBHTE9CQUxfVEhFTUVfTUFQW25hbWUudG9Mb3dlckNhc2UoKV0gPSB1dGlsXzEuZGVlcE1peCh7fSwgZGVmYXVsdFRoZW1lLCB0aGVtZSk7XG59XG5leHBvcnRzLnJlZ2lzdGVyR2xvYmFsVGhlbWUgPSByZWdpc3Rlckdsb2JhbFRoZW1lO1xuLyoqXG4gKiDojrflj5bpu5jorqTkuLvpophcbiAqIEBwYXJhbSBuYW1lIOWmguaenCBuYW1lIOS4uuepuu+8jOWImei/lOWbnum7mOiupOeahOS4u+mimO+8jOWQpuWImei/lOWbnuaMh+WumiBuYW1lIOeahOS4u+mimFxuICovXG5mdW5jdGlvbiBnZXRHbG9iYWxUaGVtZShuYW1lKSB7XG4gICAgaWYgKG5hbWUgPT09IHZvaWQgMCkgeyBuYW1lID0gJ2RlZmF1bHQnOyB9XG4gICAgdmFyIHRoZW1lID0gR0xPQkFMX1RIRU1FX01BUFtuYW1lLnRvTG93ZXJDYXNlKCldO1xuICAgIGlmICh0aGVtZSkge1xuICAgICAgICByZXR1cm4gdGhlbWU7XG4gICAgfVxuICAgIC8vIOWmguayoeacieaJvuWIsO+8jOWImeS9v+eUqOW9k+WJjeWFqOWxgOS4u+mimOabv+S7o1xuICAgIGNvbnNvbGUud2FybihcImVycm9yIGluIHRoZW1lOiBDYW4ndCBmaW5kIHRoZSB0aGVtZSBuYW1lZCAlcy4gUGxlYXNlIHJlZ2lzdGVyIHRoZW1lIGZpcnN0LlwiLCBuYW1lKTtcbiAgICByZXR1cm4gZGVmYXVsdF8xLkRFRkFVTFRfR0xPQkFMX1RIRU1FO1xufVxuZXhwb3J0cy5nZXRHbG9iYWxUaGVtZSA9IGdldEdsb2JhbFRoZW1lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2xvYmFsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLy8gLy8gZGVmYXVsdFRoZW1lIOW/hemhu+mmluWFiOazqOWGjFxuLy8gaW1wb3J0IGRlZmF1bHRUaGVtZSBmcm9tICcuL2RlZmF1bHQnO1xuLy9cbi8vIGltcG9ydCBUaGVtZSBmcm9tICcuL3RoZW1lJztcbi8vXG4vLyBleHBvcnQgeyBUaGVtZSBhcyBkZWZhdWx0LCBkZWZhdWx0VGhlbWUgfTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIOWFqOWxgOS4u+mimOeahOaWueazlVxudmFyIGdsb2JhbF8xID0gcmVxdWlyZShcIi4vZ2xvYmFsXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0R2xvYmFsVGhlbWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGdsb2JhbF8xLmdldEdsb2JhbFRoZW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJHbG9iYWxUaGVtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZ2xvYmFsXzEucmVnaXN0ZXJHbG9iYWxUaGVtZTsgfSB9KTtcbi8vIOWbvuihqOS4u+mimOeahOaWueazlVxudmFyIHRoZW1lXzEgPSByZXF1aXJlKFwiLi90aGVtZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFRoZW1lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGVtZV8xLmdldFRoZW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJUaGVtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhlbWVfMS5yZWdpc3RlclRoZW1lOyB9IH0pO1xuLy8g5bel5YW35Ye95pWwXG52YXIgdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiY29udmVydFRvRzJUaGVtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfMS5jb252ZXJ0VG9HMlRoZW1lOyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFRoZW1lID0gZXhwb3J0cy5yZWdpc3RlclRoZW1lID0gZXhwb3J0cy5jb252ZXJ0VGhlbWVUb0cyVGhlbWUgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIOaJgOacieeahCBwbG90IHRoZW1lIG9iamVjdO+8jOavj+S4quWbvuexu+Wei+WPquS8muWtmOWcqOS4gOS4qiB0aGVtZVxuICovXG52YXIgUExPVF9USEVNRV9NQVAgPSB7fTtcbi8qKlxuICog5bCGIOS4u+mimCDovazmjaLkuLogRzIg5Li76aKY6YWN572uXG4gKiBAcGFyYW0gdHlwZSBwbG90VHlwZVxuICovXG5mdW5jdGlvbiBjb252ZXJ0VGhlbWVUb0cyVGhlbWUodHlwZSAvKiogcGxvdCBzdHlsZSAqLywgdGhlbWUpIHtcbiAgICB2YXIgc3R5bGVNYXBTaGFwZSA9IHtcbiAgICAgICAgbGluZVN0eWxlOiAnbGluZS5saW5lJyxcbiAgICAgICAgY29sdW1uU3R5bGU6ICdpbnRlcnZhbC5yZWN0JyxcbiAgICAgICAgcG9pbnRTdHlsZTogJ3BvaW50LmNpcmNsZScsXG4gICAgfTtcbiAgICB2YXIgZzJUaGVtZSA9IHt9O1xuICAgIGlmICh0eXBlID09PSAnYXJlYScpIHtcbiAgICAgICAgc3R5bGVNYXBTaGFwZSA9IHtcbiAgICAgICAgICAgIGFyZWFTdHlsZTogJ2FyZWEuYXJlYScsXG4gICAgICAgICAgICBsaW5lU3R5bGU6ICdhcmVhLmxpbmUnLFxuICAgICAgICAgICAgcG9pbnRTdHlsZTogJ3BvaW50LmNpcmNsZScsXG4gICAgICAgIH07XG4gICAgfVxuICAgIHZhciBnZW9tZXRyeVRoZW1lID0ge307XG4gICAgdXRpbF8xLmVhY2godGhlbWUsIGZ1bmN0aW9uIChzdHlsZSwgc3R5bGVLZXkpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBpZiAodXRpbF8xLmhhcyhzdHlsZU1hcFNoYXBlLCBzdHlsZUtleSkpIHtcbiAgICAgICAgICAgIHZhciBzaGFwZVBhdGhfMSA9IHN0eWxlTWFwU2hhcGVbc3R5bGVLZXldO1xuICAgICAgICAgICAgdXRpbF8xLmVhY2goc3R5bGUsIGZ1bmN0aW9uICh2LCBrKSB7XG4gICAgICAgICAgICAgICAgdXRpbF8xLnNldChnZW9tZXRyeVRoZW1lLCBzaGFwZVBhdGhfMSArIFwiLlwiICsgW2sgPT09ICdub3JtYWwnID8gJ2RlZmF1bHQnIDogayA9PT0gJ2Rpc2FibGUnID8gJ2luYWN0aXZlJyA6IGtdICsgXCIuc3R5bGVcIiwgdik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8qKiBzdHlsZU1hcCDmib7kuI3liLDvvIznm7TmjqXmlL7lhaUgRzIgdGhlbWUgKi9cbiAgICAgICAgICAgIGcyVGhlbWUgPSB1dGlsXzEuZGVlcE1peCh7fSwgZzJUaGVtZSwgKF9hID0ge30sIF9hW3N0eWxlS2V5XSA9IHN0eWxlLCBfYSkpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCF1dGlsXzEuaXNFbXB0eShnZW9tZXRyeVRoZW1lKSkge1xuICAgICAgICBnMlRoZW1lID0gdXRpbF8xLmRlZXBNaXgoe30sIGcyVGhlbWUsIHsgZ2VvbWV0cmllczogZ2VvbWV0cnlUaGVtZSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGcyVGhlbWU7XG59XG5leHBvcnRzLmNvbnZlcnRUaGVtZVRvRzJUaGVtZSA9IGNvbnZlcnRUaGVtZVRvRzJUaGVtZTtcbi8qKlxuICog5rOo5YaM5paw55qE5Zu+6KGo5Li76aKYXG4gKiBAcGFyYW0gdHlwZVxuICogQHBhcmFtIHRoZW1lXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyVGhlbWUodHlwZSwgdGhlbWUpIHtcbiAgICBQTE9UX1RIRU1FX01BUFt0eXBlLnRvTG93ZXJDYXNlKCldID0gY29udmVydFRoZW1lVG9HMlRoZW1lKHR5cGUsIHRoZW1lKTtcbn1cbmV4cG9ydHMucmVnaXN0ZXJUaGVtZSA9IHJlZ2lzdGVyVGhlbWU7XG4vKipcbiAqIOagueaNruexu+Wei+iOt+WPluS4u+mimFxuICogQHBhcmFtIHR5cGUgcGxvdFR5cGUsIHN1Y2ggYXMgbGluZSwgY29sdW1uLCBiYXIsIHBpZSwgYnVsbGV0LCByYWRhciBhbmQgc28gb25cbiAqL1xuZnVuY3Rpb24gZ2V0VGhlbWUodHlwZSkge1xuICAgIHJldHVybiBQTE9UX1RIRU1FX01BUFt0eXBlLnRvTG93ZXJDYXNlKCldIHx8IHt9O1xufVxuZXhwb3J0cy5nZXRUaGVtZSA9IGdldFRoZW1lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGhlbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNvbnZlcnRUb0cyVGhlbWUgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIG11dGFibGUg55qE5pa55byP5L+u5pS5IGF4aXMg6YWN572uXG4gKiBAcGFyYW0gYXhpc1xuICovXG4vLyBmdW5jdGlvbiBjb252ZXJ0VG9HMkF4aXMoYXhpczogYW55KTogdm9pZCB7XG4vLyAgIGlmIChheGlzLmxpbmUgJiYgYXhpcy5saW5lLnN0eWxlKSB7XG4vLyAgICAgY29uc3QgbGluZVN0eWxlID0gYXhpcy5saW5lLnN0eWxlO1xuLy8gICAgIGRlbGV0ZSBheGlzLmxpbmUuc3R5bGU7XG4vLyAgICAgbWl4KGF4aXMubGluZSwgbGluZVN0eWxlKTtcbi8vICAgfVxuLy8gICBpZiAoYXhpcy50aWNrTGluZSkge1xuLy8gICAgIGNvbnN0IHRpY2tMaW5lU3R5bGUgPSBheGlzLnRpY2tMaW5lLnN0eWxlO1xuLy8gICAgIGRlbGV0ZSBheGlzLnRpY2tMaW5lLnN0eWxlO1xuLy8gICAgIG1peChheGlzLnRpY2tMaW5lLCB0aWNrTGluZVN0eWxlKTtcbi8vICAgfVxuLy8gICBpZiAoYXhpcy5ncmlkKSB7XG4vLyAgICAgY29uc3QgZ3JpZFN0eWxlID0gYXhpcy5ncmlkLnN0eWxlO1xuLy8gICAgIGRlbGV0ZSBheGlzLmdyaWQuc3R5bGU7XG4vLyAgICAgbWl4KGF4aXMuZ3JpZCwgZ3JpZFN0eWxlKTtcbi8vICAgfVxuLy8gICBpZiAoYXhpcy5sYWJlbCkge1xuLy8gICAgIGlmIChheGlzLmxhYmVsLnN0eWxlKSB7XG4vLyAgICAgICBheGlzLmxhYmVsLnRleHRTdHlsZSA9IGF4aXMubGFiZWwuc3R5bGU7XG4vLyAgICAgICBkZWxldGUgYXhpcy5sYWJlbC5zdHlsZTtcbi8vICAgICB9XG4vLyAgIH1cbi8vICAgaWYgKGF4aXMudGl0bGUpIHtcbi8vICAgICBpZiAoYXhpcy50aXRsZS5zdHlsZSkge1xuLy8gICAgICAgYXhpcy50aXRsZS50ZXh0U3R5bGUgPSBheGlzLnRpdGxlLnN0eWxlO1xuLy8gICAgICAgZGVsZXRlIGF4aXMudGl0bGUuc3R5bGU7XG4vLyAgICAgfVxuLy8gICB9XG4vLyB9XG4vKipcbiAqIOWwhuWbvuW9ouS4u+mimOi9rOaNouaIkCBnMiB0aGVtZSDmoLzlvI9cbiAqIEBwYXJhbSBwbG90VGhlbWVcbiAqL1xuZnVuY3Rpb24gY29udmVydFRvRzJUaGVtZShwbG90VGhlbWUpIHtcbiAgICB2YXIgZzJUaGVtZSA9IHV0aWxfMS5jbG9uZShwbG90VGhlbWUpO1xuICAgIC8qKiB0ZW1wbzogbGVnZW5kIG1hcmdpbuiuvue9ruS4ujAgKi9cbiAgICBpZiAoIWcyVGhlbWUubGVnZW5kKSB7XG4gICAgICAgIGcyVGhlbWUubGVnZW5kID0ge307XG4gICAgfVxuICAgIHJldHVybiBnMlRoZW1lO1xufVxuZXhwb3J0cy5jb252ZXJ0VG9HMlRoZW1lID0gY29udmVydFRvRzJUaGVtZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWxzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmJveF8xID0gcmVxdWlyZShcIkBhbnR2L2cyL2xpYi91dGlsL2Jib3hcIik7XG52YXIgY29uc3RhbnRfMSA9IHJlcXVpcmUoXCJAYW50di9nMi9saWIvY29uc3RhbnRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJESVJFQ1RJT05cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnN0YW50XzEuRElSRUNUSU9OOyB9IH0pO1xudmFyIEJCb3ggPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoQkJveCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCQm94KCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEJCb3guZnJvbUJCb3hPYmplY3QgPSBmdW5jdGlvbiAoYmJveCkge1xuICAgICAgICByZXR1cm4gbmV3IEJCb3goYmJveC54LCBiYm94LnksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICB9O1xuICAgIHJldHVybiBCQm94O1xufShiYm94XzEuQkJveCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQkJveDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJib3guanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmlzQ29udHJhc3RDb2xvcldoaXRlID0gZXhwb3J0cy5tYXBwaW5nQ29sb3IgPSBleHBvcnRzLmFycjJyZ2IgPSBleHBvcnRzLnRvSGV4ID0gZXhwb3J0cy5yZ2IyYXJyID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuZnVuY3Rpb24gcmdiMmFycihzdHIpIHtcbiAgICB2YXIgY29sb3JTdHIgPSBzdHIuaW5kZXhPZignIycpID09PSAwID8gc3RyLnN1YnN0cigxKSA6IHN0cjtcbiAgICB2YXIgYXJyID0gW107XG4gICAgYXJyLnB1c2gocGFyc2VJbnQoY29sb3JTdHIuc3Vic3RyKDAsIDIpLCAxNikpO1xuICAgIGFyci5wdXNoKHBhcnNlSW50KGNvbG9yU3RyLnN1YnN0cigyLCAyKSwgMTYpKTtcbiAgICBhcnIucHVzaChwYXJzZUludChjb2xvclN0ci5zdWJzdHIoNCwgMiksIDE2KSk7XG4gICAgcmV0dXJuIGFycjtcbn1cbmV4cG9ydHMucmdiMmFyciA9IHJnYjJhcnI7XG5mdW5jdGlvbiB0b0hleCh2YWx1ZSkge1xuICAgIHZhciB2O1xuICAgIHYgPSBNYXRoLnJvdW5kKHZhbHVlKTtcbiAgICB2ID0gdi50b1N0cmluZygxNik7XG4gICAgaWYgKHYubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHYgPSBcIjBcIiArIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdjtcbn1cbmV4cG9ydHMudG9IZXggPSB0b0hleDtcbmZ1bmN0aW9uIGFycjJyZ2IoYXJyKSB7XG4gICAgcmV0dXJuIFwiI1wiICsgKHRvSGV4KGFyclswXSkgKyB0b0hleChhcnJbMV0pICsgdG9IZXgoYXJyWzJdKSk7XG59XG5leHBvcnRzLmFycjJyZ2IgPSBhcnIycmdiO1xuZnVuY3Rpb24gbWFwcGluZ0NvbG9yKGJhbmQsIGdyYXkpIHtcbiAgICB2YXIgcmVmbGVjdDtcbiAgICB1dGlsXzEuZWFjaChiYW5kLCBmdW5jdGlvbiAoYikge1xuICAgICAgICB2YXIgbWFwID0gYjtcbiAgICAgICAgaWYgKGdyYXkgPj0gbWFwLmZyb20gJiYgZ3JheSA8IG1hcC50bykge1xuICAgICAgICAgICAgcmVmbGVjdCA9IG1hcC5jb2xvcjtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZWZsZWN0O1xufVxuZXhwb3J0cy5tYXBwaW5nQ29sb3IgPSBtYXBwaW5nQ29sb3I7XG4vLyDmoLnmja5ZSVHkuq7luqbliKTmlq3mjIflrprpopzoibLlj5blj43oibLmmK/kuI3mmK/nmb3oibJcbi8vIGh0dHA6Ly8yNHdheXMub3JnLzIwMTAvY2FsY3VsYXRpbmctY29sb3ItY29udHJhc3RcbmV4cG9ydHMuaXNDb250cmFzdENvbG9yV2hpdGUgPSBmdW5jdGlvbiAocmdiKSB7XG4gICAgdmFyIF9hID0gcmdiMmFycihyZ2IpLCByID0gX2FbMF0sIGcgPSBfYVsxXSwgYiA9IF9hWzJdO1xuICAgIHZhciBpc0RhcmsgPSAociAqIDI5OSArIGcgKiA1ODcgKyBiICogMTE0KSAvIDEwMDAgPCAxMjg7XG4gICAgcmV0dXJuIGlzRGFyaztcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb2xvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaXNNb2JpbGUgPSBleHBvcnRzLmlzQkJveEludGVyc2VjdCA9IGV4cG9ydHMuc29ydGVkTGFzdEluZGV4ID0gZXhwb3J0cy5nZXRMZWdlbmRTaGFwZXMgPSBleHBvcnRzLmdldEF4aXNTaGFwZXMgPSBleHBvcnRzLmdldExlZ2VuZENvbXBvbmVudHMgPSBleHBvcnRzLmdldEF4aXNDb21wb25lbnRzID0gZXhwb3J0cy5icmVha1RleHQgPSBleHBvcnRzLmlzVGV4dFVzYWJsZSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIGRlcGVuZGVudHNfMSA9IHJlcXVpcmUoXCIuLi9kZXBlbmRlbnRzXCIpO1xuLyoqXG4gKiDliKTmlq10ZXh05piv5ZCm5Y+v55SoLCB0aXRsZSBkZXNjcmlwdGlvblxuICpcbiAqIEBwYXJhbSBzb3VyY2VcbiAqL1xuZnVuY3Rpb24gaXNUZXh0VXNhYmxlKHNvdXJjZSkge1xuICAgIGlmICghc291cmNlKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHNvdXJjZS52aXNpYmxlID09PSB0cnVlICYmIHR5cGVvZiBzb3VyY2UudGV4dCA9PT0gJ3N0cmluZycgJiYgc291cmNlLnRleHQudHJpbSgpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnRzLmlzVGV4dFVzYWJsZSA9IGlzVGV4dFVzYWJsZTtcbi8qKlxuICog5Li65a2X56ym5Liy5re75Yqg5o2i6KGM56ymXG4gKiBAcGFyYW0gc291cmNlIC0g5a2X56ym5Liy5pWw57uEIFsnYScsICdiJywgJ2MnXVxuICogQHBhcmFtIGJyZWFrcyAtIOimgea3u+WKoOaNouihjOeahGluZGV4XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBicmVha1RleHQoWydhJywnYicsJ2MnXSwgWzFdKVxuICpcbiAqIC8vIGFcXG5iY1xuICogYGBgXG4gKi9cbmZ1bmN0aW9uIGJyZWFrVGV4dChzb3VyY2UsIGJyZWFrcykge1xuICAgIHZhciByZXN1bHQgPSB0c2xpYl8xLl9fc3ByZWFkQXJyYXlzKHNvdXJjZSk7XG4gICAgYnJlYWtzLmZvckVhY2goZnVuY3Rpb24gKHBvcywgaW5kZXgpIHtcbiAgICAgICAgcmVzdWx0LnNwbGljZShwb3MgKyBpbmRleCwgMCwgJ1xcbicpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG59XG5leHBvcnRzLmJyZWFrVGV4dCA9IGJyZWFrVGV4dDtcbi8qKlxuICog6I635Y+WIFZpZXcg5Lit5omA5pyJ55qEIEF4aXMg57uE5Lu2XG4gKi9cbmZ1bmN0aW9uIGdldEF4aXNDb21wb25lbnRzKHZpZXcpIHtcbiAgICByZXR1cm4gdmlld1xuICAgICAgICAuZ2V0Q29tcG9uZW50cygpXG4gICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGNvKSB7IHJldHVybiBjby50eXBlID09PSBkZXBlbmRlbnRzXzEuQ09NUE9ORU5UX1RZUEUuQVhJUzsgfSlcbiAgICAgICAgLm1hcChmdW5jdGlvbiAoY28pIHsgcmV0dXJuIGNvLmNvbXBvbmVudDsgfSk7XG59XG5leHBvcnRzLmdldEF4aXNDb21wb25lbnRzID0gZ2V0QXhpc0NvbXBvbmVudHM7XG5mdW5jdGlvbiBnZXRMZWdlbmRDb21wb25lbnRzKHZpZXcpIHtcbiAgICByZXR1cm4gdmlld1xuICAgICAgICAuZ2V0Q29tcG9uZW50cygpXG4gICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGNvKSB7IHJldHVybiBjby50eXBlID09PSBkZXBlbmRlbnRzXzEuQ09NUE9ORU5UX1RZUEUuTEVHRU5EOyB9KVxuICAgICAgICAubWFwKGZ1bmN0aW9uIChjbykgeyByZXR1cm4gY28uY29tcG9uZW50OyB9KTtcbn1cbmV4cG9ydHMuZ2V0TGVnZW5kQ29tcG9uZW50cyA9IGdldExlZ2VuZENvbXBvbmVudHM7XG5mdW5jdGlvbiBnZXRBeGlzU2hhcGVzKHZpZXcpIHtcbiAgICB2YXIgYXhpc1NoYXBlID0gdmlldy5iYWNrZ3JvdW5kR3JvdXAuZmluZEFsbChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgaWYgKGVsLmdldCgnbmFtZScpKSB7XG4gICAgICAgICAgICB2YXIgbmFtZV8xID0gZWwuZ2V0KCduYW1lJykuc3BsaXQoJy0nKTtcbiAgICAgICAgICAgIHJldHVybiBuYW1lXzFbMF0gPT09ICdheGlzJztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBheGlzU2hhcGU7XG59XG5leHBvcnRzLmdldEF4aXNTaGFwZXMgPSBnZXRBeGlzU2hhcGVzO1xuZnVuY3Rpb24gZ2V0TGVnZW5kU2hhcGVzKHZpZXcpIHtcbiAgICB2YXIgYXhpc1NoYXBlID0gdmlldy5mb3JlZ3JvdW5kR3JvdXAuZmluZEFsbChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgaWYgKGVsLmdldCgnbmFtZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gZWwuZ2V0KCduYW1lJykgPT09ICdsZWdlbmQtaXRlbS1ncm91cCc7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYXhpc1NoYXBlO1xufVxuZXhwb3J0cy5nZXRMZWdlbmRTaGFwZXMgPSBnZXRMZWdlbmRTaGFwZXM7XG5mdW5jdGlvbiBzb3J0ZWRMYXN0SW5kZXgoYXJyLCB2YWwpIHtcbiAgICB2YXIgaSA9IGFyci5sZW5ndGg7XG4gICAgd2hpbGUgKGkgPiAwKSB7XG4gICAgICAgIGlmICh2YWwgPj0gYXJyW2kgLSAxXSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaSAtPSAxO1xuICAgIH1cbiAgICByZXR1cm4gaTtcbn1cbmV4cG9ydHMuc29ydGVkTGFzdEluZGV4ID0gc29ydGVkTGFzdEluZGV4O1xuLyog5qOA5rWL5Lik5LiqbGFiZWzljIXlm7Tnm5LmmK/lkKbph43lj6AgKi9cbmZ1bmN0aW9uIGlzQkJveEludGVyc2VjdChiYm94QSwgYmJveEIpIHtcbiAgICBpZiAoYmJveEEubWF4WSA8IGJib3hCLm1pblkgfHwgYmJveEIubWF4WSA8IGJib3hBLm1pblkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYmJveEEubWF4WCA8IGJib3hCLm1pblggfHwgYmJveEIubWF4WCA8IGJib3hBLm1pblgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmV4cG9ydHMuaXNCQm94SW50ZXJzZWN0ID0gaXNCQm94SW50ZXJzZWN0O1xuLyoqXG4gKiDliKTmlq3mmK/lkKbnp7vliqjnq6/njq/looNcbiAqL1xuZnVuY3Rpb24gaXNNb2JpbGUoKSB7XG4gICAgcmV0dXJuICEhbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvKE1vYmlsZSl8KEFuZHJvaWQpfChXZWJPUyl8KGlQaG9uZSl8KGlQYWQpLyk7XG59XG5leHBvcnRzLmlzTW9iaWxlID0gaXNNb2JpbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb21tb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnRyYW5zZm9ybURhdGFQZXJjZW50YWdlID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG5leHBvcnRzLnRyYW5zZm9ybURhdGFQZXJjZW50YWdlID0gZnVuY3Rpb24gKGRhdGEsIGdyb3VwRmllbGQsIG1lYXN1cmVzKSB7XG4gICAgLy8g5oyJ54WnZ3JvdXBCeeWtl+auteiuoeeul+WQhOS4qmdyb3Vw55qE5oC75ZKMXG4gICAgdmFyIGNoYWluID0gdXRpbF8xLmdyb3VwQnkoZGF0YSwgZ3JvdXBGaWVsZCk7XG4gICAgY2hhaW4gPSB1dGlsXzEubWFwVmFsdWVzKGNoYWluLCBmdW5jdGlvbiAoaXRlbXMpIHsgcmV0dXJuIHV0aWxfMS5tYXAoaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiB1dGlsXzEubWFwKG1lYXN1cmVzLCBmdW5jdGlvbiAoZmllbGQpIHsgcmV0dXJuIGl0ZW1bZmllbGRdOyB9KTsgfSk7IH0pO1xuICAgIGNoYWluID0gdXRpbF8xLm1hcFZhbHVlcyhjaGFpbiwgdXRpbF8xLmZsYXR0ZW4pO1xuICAgIGNoYWluID0gdXRpbF8xLm1hcFZhbHVlcyhjaGFpbiwgZnVuY3Rpb24gKHZhbHMpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5tYXAodmFscywgZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgdmFyIHYgPSBOdW1iZXIucGFyc2VGbG9hdCh2YWwpO1xuICAgICAgICAgICAgaWYgKCF1dGlsXzEuaXNOdW1iZXIodikgfHwgaXNOYU4odikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdmFyIGdyb3VwVG90YWxzID0gdXRpbF8xLm1hcFZhbHVlcyhjaGFpbiwgZnVuY3Rpb24gKHZhbHMpIHsgcmV0dXJuIHV0aWxfMS5yZWR1Y2UodmFscywgZnVuY3Rpb24gKHN1bSwgdmFsKSB7IHJldHVybiBzdW0gKyB2YWw7IH0sIDApOyB9KTtcbiAgICAvLyDopobnm5ZtZWFzdXJlc+Wtl+auteeahOWAvOS4uuWvueS6jueahOeZvuWIhuavlFxuICAgIHZhciBuZXdEYXRhID0gdXRpbF8xLm1hcChkYXRhLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHZhciByc3QgPSB0c2xpYl8xLl9fYXNzaWduKHRzbGliXzEuX19hc3NpZ24oe30sIGl0ZW0pLCB7IF9vcmlnaW46IGl0ZW0sIHRvdGFsOiBncm91cFRvdGFsc1tpdGVtW2dyb3VwRmllbGRdXSB9KTtcbiAgICAgICAgdXRpbF8xLmVhY2gobWVhc3VyZXMsIGZ1bmN0aW9uIChmaWVsZCkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcnN0W2ZpZWxkXSA9IGl0ZW1bZmllbGRdIC8gKGdyb3VwVG90YWxzW2l0ZW1bZ3JvdXBGaWVsZF1dIHx8IDEpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9KTtcbiAgICAvLyDmo4Dmn6Xnsr7luqbvvIznoa7kv53mgLvlkozkuLoxXG4gICAgdXRpbF8xLmVhY2godXRpbF8xLmdyb3VwQnkobmV3RGF0YSwgZ3JvdXBGaWVsZCksIGZ1bmN0aW9uIChpdGVtcykge1xuICAgICAgICB2YXIgc3VtID0gMDtcbiAgICAgICAgdXRpbF8xLmVhY2goaXRlbXMsIGZ1bmN0aW9uIChpdGVtLCBpdGVtSWR4KSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChtZWFzdXJlcywgZnVuY3Rpb24gKGZpZWxkLCBmaWVsZElkeCkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBpZiAoc3VtICsgaXRlbVtmaWVsZF0gPj0gMSB8fCAoaXRlbUlkeCA9PT0gaXRlbXMubGVuZ3RoIC0gMSAmJiBmaWVsZElkeCA9PT0gbWVhc3VyZXMubGVuZ3RoIC0gMSAmJiBzdW0gPiAwKSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtW2ZpZWxkXSA9IDEgLSBzdW07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBzdW0gKz0gaXRlbVtmaWVsZF07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBuZXdEYXRhO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGEuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmFkdmFuY2VCeSA9IGV4cG9ydHMuZ2V0RGF5ID0gZXhwb3J0cy5nZXRXZWVrID0gZXhwb3J0cy5pc0xhc3REYXlPZk1vbnRoID0gZXhwb3J0cy5pc0xhc3RXZWVrT2ZNb250aCA9IGV4cG9ydHMuZ2V0WWVhclJhbmdlID0gZXhwb3J0cy5nZXREYXRlUmFuZ2UgPSBleHBvcnRzLkRBWV9NUyA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGZlY2hhXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiZmVjaGFcIikpO1xudmFyIGNvbnN0YW50XzEgPSByZXF1aXJlKFwiLi4vcGxvdHMvY2FsZW5kYXIvY29uc3RhbnRcIik7XG4vKipcbiAqIOS4gOWkqeWkmuWwkSBtc1xuICovXG5leHBvcnRzLkRBWV9NUyA9IDg2NDAwMDAwO1xuLyoqXG4gKiDojrflj5bmnIDlpKfmnIDlsI/ml6XmnJ/ojIPlm7RcbiAqIEBwYXJhbSBkYXRlc1xuICovXG5mdW5jdGlvbiBnZXREYXRlUmFuZ2UoZGF0ZXMpIHtcbiAgICB2YXIgZHMgPSB0c2xpYl8xLl9fc3ByZWFkQXJyYXlzKGRhdGVzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLmdldFRpbWUoKSAtIGIuZ2V0VGltZSgpOyB9KTtcbiAgICByZXR1cm4gW2ZlY2hhXzEuZGVmYXVsdC5mb3JtYXQodXRpbF8xLmhlYWQoZHMpLCBjb25zdGFudF8xLkZPUk1BVFRFUiksIGZlY2hhXzEuZGVmYXVsdC5mb3JtYXQodXRpbF8xLmxhc3QoZHMpLCBjb25zdGFudF8xLkZPUk1BVFRFUildO1xufVxuZXhwb3J0cy5nZXREYXRlUmFuZ2UgPSBnZXREYXRlUmFuZ2U7XG4vKipcbiAqIOaXpeacn+WvueW6lOW5tOeahOiMg+WbtFxuICogQHBhcmFtIGRhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0WWVhclJhbmdlKGRhdGUpIHtcbiAgICB2YXIgY3VyciA9IGRhdGUgPyBkYXRlIDogbmV3IERhdGUoKTtcbiAgICByZXR1cm4gW1xuICAgICAgICBmZWNoYV8xLmRlZmF1bHQuZm9ybWF0KG5ldyBEYXRlKGN1cnIuZ2V0RnVsbFllYXIoKSwgMCwgMSksIGNvbnN0YW50XzEuRk9STUFUVEVSKSxcbiAgICAgICAgZmVjaGFfMS5kZWZhdWx0LmZvcm1hdChuZXcgRGF0ZShjdXJyLmdldEZ1bGxZZWFyKCksIDExLCAzMCksIGNvbnN0YW50XzEuRk9STUFUVEVSKSxcbiAgICBdO1xufVxuZXhwb3J0cy5nZXRZZWFyUmFuZ2UgPSBnZXRZZWFyUmFuZ2U7XG4vKipcbiAqIOaYr+WQpuW9k+WJjeaciOeahOacgOWQjuS4gOWRqFxuICovXG5mdW5jdGlvbiBpc0xhc3RXZWVrT2ZNb250aChkYXRlKSB7XG4gICAgLy8g5YGP56e7IDcg5aSp5LmL5ZCO77yM5pyI5Lu95piv5ZCm5LiA5qC3XG4gICAgcmV0dXJuIGRhdGUuZ2V0TW9udGgoKSAhPT0gYWR2YW5jZUJ5KG5ldyBEYXRlKGRhdGUpLCA3ICogZXhwb3J0cy5EQVlfTVMpLmdldE1vbnRoKCk7XG59XG5leHBvcnRzLmlzTGFzdFdlZWtPZk1vbnRoID0gaXNMYXN0V2Vla09mTW9udGg7XG4vKipcbiAqIOaYr+WQpuaYr+W9k+aciOeahOacgOWQjuS4gOWkqVxuICovXG5mdW5jdGlvbiBpc0xhc3REYXlPZk1vbnRoKGRhdGUpIHtcbiAgICAvLyDlgY/np7sgMSDlpKnkuYvlkI7vvIzmnIjku73mmK/lkKbkuIDmoLdcbiAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpICE9PSBhZHZhbmNlQnkobmV3IERhdGUoZGF0ZSksIGV4cG9ydHMuREFZX01TKS5nZXRNb250aCgpO1xufVxuZXhwb3J0cy5pc0xhc3REYXlPZk1vbnRoID0gaXNMYXN0RGF5T2ZNb250aDtcbi8qKlxuICog6I635Y+WIGRhdGUg5a+55bqU55qE5ZGo57Si5byV77yI5Zu96ZmF5qCH5YeG77ya5LiA5bm055qE56ys5LiA5Liq5ZGo5Zub5Li656ys5LiA5ZGo77yJXG4gKiBAcGFyYW0gZGF0ZVxuICovXG5mdW5jdGlvbiBnZXRXZWVrKGRhdGUpIHtcbiAgICAvLyDlvZPlubTnmoTnrKzkuIDlpKlcbiAgICB2YXIgb25lSmFuID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCAwLCAxKTtcbiAgICByZXR1cm4gTWF0aC5jZWlsKCgoZGF0ZS5nZXRUaW1lKCkgLSBvbmVKYW4uZ2V0VGltZSgpKSAvIGV4cG9ydHMuREFZX01TICsgb25lSmFuLmdldERheSgpICsgMSkgLyA3KTtcbn1cbmV4cG9ydHMuZ2V0V2VlayA9IGdldFdlZWs7XG4vKipcbiAqIOiOt+W+l+S4gOWRqOeahOesrOWHoOWkqe+8iOWRqOaXpeesrCAwIOWkqe+8iVxuICogQHBhcmFtIGRhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0RGF5KGRhdGUpIHtcbiAgICByZXR1cm4gZGF0ZS5nZXREYXkoKTtcbn1cbmV4cG9ydHMuZ2V0RGF5ID0gZ2V0RGF5O1xuLyoqXG4gKiDlsIYgRGF0ZSDliY3ov5sgbXMg5pe26Ze0XG4gKiBAcGFyYW0gZFxuICogQHBhcmFtIG1zXG4gKi9cbmZ1bmN0aW9uIGFkdmFuY2VCeShkLCBtcykge1xuICAgIGQuc2V0TWlsbGlzZWNvbmRzKGQuZ2V0TWlsbGlzZWNvbmRzKCkgKyBtcyk7XG4gICAgcmV0dXJuIGQ7XG59XG5leHBvcnRzLmFkdmFuY2VCeSA9IGFkdmFuY2VCeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm9uRXZlbnQgPSBleHBvcnRzLkxBWUVSX0VWRU5UX01BUCA9IGV4cG9ydHMuQ0FOVkFTX0VWRU5UX01BUCA9IGV4cG9ydHMuRVZFTlRfTUFQID0gZXhwb3J0cy5nZXRNb2JpbGVFdmVudE1hcCA9IGV4cG9ydHMuZ2V0UmVnaW9uRXZlbnRNYXAgPSBleHBvcnRzLmdldEV2ZW50TWFwID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV2ZW50TmFtZXMgPSBbXG4gICAgJ2NsaWNrJyxcbiAgICAnZGJsY2xpY2snLFxuICAgICdtb3VzZW1vdmUnLFxuICAgICdtb3VzZWVudGVyJyxcbiAgICAnbW91c2VsZWF2ZScsXG4gICAgJ21vdXNlZG93bicsXG4gICAgJ21vdXNldXAnLFxuICAgICdjb250ZXh0bWVudScsXG5dO1xudmFyIG1vYmlsZUV2ZW50TmFtZXMgPSBbXG4vKid0b3VjaHN0YXJ0Jyxcbid0b3VjaG1vdmUnLFxuJ3RvdWNoZW5kJyxcbidwcmVzc3N0YXJ0JyxcbidwcmVzcycsXG4ncHJlc3NlbmQnLFxuJ3N3aXBlc3RhcnQnLFxuJ3N3aXBlJyxcbidzd2lwZWVuZCcsXG4ncGluY2hzdGFydCcsXG4ncGluY2gnLFxuJ3BpbmNoZW5kJyxcbidwYW5zdGFydCcsXG4ncGFuJyxcbidwYW5lbmQnLCovXG5dO1xudmFyIHZpZXdDb21wb25lbnRNYXAgPSB7XG4gICAgYXhpczogJ2F4aXMtbGFiZWwnLFxuICAgIGxhYmVsOiAnbGFiZWwnLFxuICAgIGxlZ2VuZDogJ2xlZ2VuZC1pdGVtJyxcbn07XG52YXIgY2FudmFzQ29tcG9uZW50TWFwID0ge1xuICAgIHRpdGxlOiAndGl0bGUnLFxuICAgIGRlc2NyaXB0aW9uOiAnZGVzY3JpcHRpb24nLFxuICAgIGJyZWFkY3J1bWI6ICdicmVhZGNydW1iJyxcbn07XG52YXIgQ0FOVkFTX0VWRU5UX01BUCA9IHV0aWxfMS5kZWVwTWl4KGdldEV2ZW50TWFwKGNhbnZhc0NvbXBvbmVudE1hcCksIGdldFJlZ2lvbkV2ZW50TWFwKCdQbG90JywgZXZlbnROYW1lcykpO1xuZXhwb3J0cy5DQU5WQVNfRVZFTlRfTUFQID0gQ0FOVkFTX0VWRU5UX01BUDtcbnZhciBMQVlFUl9FVkVOVF9NQVAgPSBnZXRSZWdpb25FdmVudE1hcCgnTGF5ZXInLCBldmVudE5hbWVzKTtcbmV4cG9ydHMuTEFZRVJfRVZFTlRfTUFQID0gTEFZRVJfRVZFTlRfTUFQO1xuLy/np7vliqjnq6/kuovku7bmmoLml7blj6rmlK/mjIF2aWV357qnXG52YXIgRVZFTlRfTUFQID0gdXRpbF8xLmRlZXBNaXgoe30sIGdldEV2ZW50TWFwKHZpZXdDb21wb25lbnRNYXApLCBnZXRSZWdpb25FdmVudE1hcCgnVmlldycsIGV2ZW50TmFtZXMpLCBnZXRNb2JpbGVFdmVudE1hcCgpKTtcbmV4cG9ydHMuRVZFTlRfTUFQID0gRVZFTlRfTUFQO1xuZnVuY3Rpb24gb25FdmVudChsYXllciwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgbGF5ZXIudmlldy5vbihldmVudE5hbWUsIGZ1bmN0aW9uIChldikge1xuICAgICAgICB2YXIgZXZlbnREYXRhID0ge1xuICAgICAgICAgICAgeDogZXYgPT09IG51bGwgfHwgZXYgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGV2LngsXG4gICAgICAgICAgICB5OiBldiA9PT0gbnVsbCB8fCBldiA9PT0gdm9pZCAwID8gdm9pZCAwIDogZXYueSxcbiAgICAgICAgICAgIGNsaWVudFg6IGV2ID09PSBudWxsIHx8IGV2ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBldi5jbGllbnRYLFxuICAgICAgICAgICAgY2xpZW50WTogZXYgPT09IG51bGwgfHwgZXYgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGV2LmNsaWVudFksXG4gICAgICAgICAgICB0YXJnZXQ6IGV2ID09PSBudWxsIHx8IGV2ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBldi50YXJnZXQsXG4gICAgICAgICAgICBkYXRhOiAoZXYgPT09IG51bGwgfHwgZXYgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGV2LmRhdGEpID8gZXYuZGF0YS5kYXRhIDogbnVsbCxcbiAgICAgICAgICAgIHBsb3Q6IGxheWVyLFxuICAgICAgICAgICAgY2FudmFzOiBsYXllci5jYW52YXMsXG4gICAgICAgICAgICBnRXZlbnQ6IGV2ID09PSBudWxsIHx8IGV2ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBldi5nRXZlbnQsXG4gICAgICAgIH07XG4gICAgICAgIGhhbmRsZXIoZXZlbnREYXRhKTtcbiAgICB9KTtcbn1cbmV4cG9ydHMub25FdmVudCA9IG9uRXZlbnQ7XG5mdW5jdGlvbiBnZXRFdmVudE1hcChtYXApIHtcbiAgICB2YXIgZXZlbnRNYXAgPSB7fTtcbiAgICB1dGlsXzEuZWFjaChtYXAsIGZ1bmN0aW9uIChpdGVtLCBrZXkpIHtcbiAgICAgICAgdmFyIGNvbXBvbmVudE5hbWUgPSB1dGlsXzEudXBwZXJGaXJzdChrZXkpO1xuICAgICAgICB2YXIgbmFtZVByZWZpeCA9IFwib25cIiArIGNvbXBvbmVudE5hbWU7XG4gICAgICAgIHZhciBldmVudFByZWZpeCA9IGl0ZW0gKyBcIjpcIjtcbiAgICAgICAgdXRpbF8xLmVhY2goZXZlbnROYW1lcywgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBldmVudE5hbWUgPSB1dGlsXzEudXBwZXJGaXJzdChuYW1lKTtcbiAgICAgICAgICAgIHZhciBldmVudEtleSA9IFwiXCIgKyBuYW1lUHJlZml4ICsgZXZlbnROYW1lO1xuICAgICAgICAgICAgdmFyIGV2ZW50ID0gXCJcIiArIGV2ZW50UHJlZml4ICsgbmFtZTtcbiAgICAgICAgICAgIGV2ZW50TWFwW2V2ZW50S2V5XSA9IGV2ZW50O1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gZXZlbnRNYXA7XG59XG5leHBvcnRzLmdldEV2ZW50TWFwID0gZ2V0RXZlbnRNYXA7XG5mdW5jdGlvbiBnZXRSZWdpb25FdmVudE1hcChwcmVmaXgsIGV2ZW50TGlzdCkge1xuICAgIHZhciBldmVudE1hcCA9IHt9O1xuICAgIHZhciBuYW1lUHJlZml4ID0gXCJvblwiO1xuICAgIHV0aWxfMS5lYWNoKGV2ZW50TGlzdCwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgdmFyIGV2ZW50TmFtZSA9IHV0aWxfMS51cHBlckZpcnN0KG5hbWUpO1xuICAgICAgICB2YXIgZXZlbnRLZXkgPSBcIlwiICsgbmFtZVByZWZpeCArIHByZWZpeCArIGV2ZW50TmFtZTtcbiAgICAgICAgZXZlbnRNYXBbZXZlbnRLZXldID0gbmFtZTtcbiAgICB9KTtcbiAgICByZXR1cm4gZXZlbnRNYXA7XG59XG5leHBvcnRzLmdldFJlZ2lvbkV2ZW50TWFwID0gZ2V0UmVnaW9uRXZlbnRNYXA7XG5mdW5jdGlvbiBnZXRNb2JpbGVFdmVudE1hcCgpIHtcbiAgICB2YXIgZXZlbnRNYXAgPSB7fTtcbiAgICB2YXIgbmFtZVByZWZpeCA9IFwib25cIjtcbiAgICB1dGlsXzEuZWFjaChtb2JpbGVFdmVudE5hbWVzLCBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB2YXIgZXZlbnROYW1lID0gdXRpbF8xLnVwcGVyRmlyc3QobmFtZSk7XG4gICAgICAgIHZhciBldmVudEtleSA9IFwiXCIgKyBuYW1lUHJlZml4ICsgZXZlbnROYW1lO1xuICAgICAgICBldmVudE1hcFtldmVudEtleV0gPSBuYW1lO1xuICAgIH0pO1xuICAgIHJldHVybiBldmVudE1hcDtcbn1cbmV4cG9ydHMuZ2V0TW9iaWxlRXZlbnRNYXAgPSBnZXRNb2JpbGVFdmVudE1hcDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRTdWZmaXhGb3JtYXR0ZXIgPSBleHBvcnRzLmdldFByZWNpc2lvbkZvcm1hdHRlciA9IGV4cG9ydHMuZ2V0Tm9vcEZvcm1hdHRlciA9IGV4cG9ydHMuY29tYmluZUZvcm1hdHRlciA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbmV4cG9ydHMuY29tYmluZUZvcm1hdHRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZm9ybWF0dGVycyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIGZvcm1hdHRlcnNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0ZXh0LCBpdGVtLCBpZHgpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdHRlcnMucmVkdWNlKGZ1bmN0aW9uIChjdXJUZXh0LCBmb3JtYXR0ZXIpIHsgcmV0dXJuIGZvcm1hdHRlcihjdXJUZXh0LCBpdGVtLCBpZHgpOyB9LCB0ZXh0KTtcbiAgICB9O1xufTtcbmV4cG9ydHMuZ2V0Tm9vcEZvcm1hdHRlciA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZ1bmN0aW9uICh0ZXh0KSB7IHJldHVybiB0ZXh0OyB9OyB9O1xuZXhwb3J0cy5nZXRQcmVjaXNpb25Gb3JtYXR0ZXIgPSBmdW5jdGlvbiAocHJlY2lzaW9uKSB7IHJldHVybiBmdW5jdGlvbiAodGV4dCkge1xuICAgIHZhciBudW0gPSBOdW1iZXIodGV4dCk7XG4gICAgcmV0dXJuIGlzTmFOKG51bSkgfHwgdXRpbF8xLmlzTmlsKHByZWNpc2lvbikgPyB0ZXh0IDogbnVtLnRvRml4ZWQocHJlY2lzaW9uKTtcbn07IH07XG5leHBvcnRzLmdldFN1ZmZpeEZvcm1hdHRlciA9IGZ1bmN0aW9uIChzdWZmaXgpIHsgcmV0dXJuIGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgcmV0dXJuIHV0aWxfMS5pc05pbChzdWZmaXgpID8gdGV4dCA6IHRleHQgKyBcIiBcIiArIHN1ZmZpeDtcbn07IH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mb3JtYXR0ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJvdGF0ZSA9IGV4cG9ydHMudHJhbnNsYXRlID0gZXhwb3J0cy5tb3ZlID0gZXhwb3J0cy50cmFuc2Zvcm0gPSBleHBvcnRzLmdyb3VwVHJhbnNmb3JtID0gdm9pZCAwO1xudmFyIG1hdHJpeF91dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvbWF0cml4LXV0aWxcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZGVwZW5kZW50c18xID0gcmVxdWlyZShcIi4uL2RlcGVuZGVudHNcIik7XG5mdW5jdGlvbiBncm91cFRyYW5zZm9ybShncm91cCwgYWN0aW9ucykge1xuICAgIHZhciB1bE1hdHJpeCA9IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICB2YXIgbWF0cml4ID0gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHVsTWF0cml4LCBhY3Rpb25zKTtcbiAgICBncm91cC5zZXRNYXRyaXgobWF0cml4KTtcbn1cbmV4cG9ydHMuZ3JvdXBUcmFuc2Zvcm0gPSBncm91cFRyYW5zZm9ybTtcbmZ1bmN0aW9uIHRyYW5zZm9ybShhY3Rpb25zLCBtYXRyaXgpIHtcbiAgICB2YXIgdWxNYXRyaXggPSBtYXRyaXggPyB1dGlsXzEuY2xvbmUobWF0cml4KSA6IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICByZXR1cm4gbWF0cml4X3V0aWxfMS5leHQudHJhbnNmb3JtKHVsTWF0cml4LCBhY3Rpb25zKTtcbn1cbmV4cG9ydHMudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuZnVuY3Rpb24gbW92ZShlbGVtZW50LCB4LCB5LCBtYXRyaXgpIHtcbiAgICB2YXIgdWxNYXRyaXggPSBtYXRyaXggPyB1dGlsXzEuY2xvbmUobWF0cml4KSA6IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICB1bE1hdHJpeFs2XSA9IHg7XG4gICAgdWxNYXRyaXhbN10gPSB5O1xuICAgIGVsZW1lbnQuc2V0TWF0cml4KHVsTWF0cml4KTtcbn1cbmV4cG9ydHMubW92ZSA9IG1vdmU7XG5mdW5jdGlvbiB0cmFuc2xhdGUoZWxlbWVudCwgeCwgeSkge1xuICAgIGRlcGVuZGVudHNfMS5VdGlsLnRyYW5zbGF0ZShlbGVtZW50LCB4LCB5KTtcbn1cbmV4cG9ydHMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xuZnVuY3Rpb24gcm90YXRlKGVsZW1lbnQsIHJhZGlhbikge1xuICAgIGRlcGVuZGVudHNfMS5VdGlsLnJvdGF0ZShlbGVtZW50LCByYWRpYW4pO1xufVxuZXhwb3J0cy5yb3RhdGUgPSByb3RhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nLXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldFN0cm9rZVBvaW50cyA9IGV4cG9ydHMuZGlzdDIgPSBleHBvcnRzLnN0dXJnZXMgPSBleHBvcnRzLmdldE1lYW4gPSBleHBvcnRzLmdldE1lZGlhbiA9IGV4cG9ydHMubGluZVNpbXBsaWZpY2F0aW9uID0gZXhwb3J0cy5hbmdsZVRvID0gZXhwb3J0cy5zdWIyRCA9IGV4cG9ydHMuY3Jvc3NQcm9kdWN0M0QgPSBleHBvcnRzLmNyb3NzUHJvZHVjdDJEID0gZXhwb3J0cy5kb3RQcm9kdWN0MkQgPSBleHBvcnRzLmJib3hPblJvdGF0ZSA9IGV4cG9ydHMubWluRGlzdEJldHdlZW5Db252ZXhQb2x5Z29uID0gZXhwb3J0cy5pc1BvbHlnb25JbnRlcnNlY3Rpb24gPSBleHBvcnRzLmRpc3RCZXR3ZWVuUG9pbnRMaW5lID0gZXhwb3J0cy5kaXN0QmV0d2VlblBvaW50cyA9IGV4cG9ydHMuaXNQb2ludEluUG9seWdvbiA9IGV4cG9ydHMuZ2V0TGluZUludGVyc2VjdCA9IGV4cG9ydHMuaXNCZXR3ZWVuID0gZXhwb3J0cy5hcHBseU1hdHJpeCA9IHZvaWQgMDtcbnZhciBtYXRyaXhfdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L21hdHJpeC11dGlsXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuZnVuY3Rpb24gbWFnbml0dWRlKHYpIHtcbiAgICB2YXIgc3VtID0gMDtcbiAgICB1dGlsXzEuZWFjaCh2LCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgc3VtICs9IHZhbHVlICogdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIE1hdGguc3FydChzdW0pO1xufVxuZnVuY3Rpb24gZG90UHJvZHVjdDJEKHZhLCB2Yikge1xuICAgIHJldHVybiB2YS54ICogdmIueSArIHZhLnkgKiB2Yi54O1xufVxuZXhwb3J0cy5kb3RQcm9kdWN0MkQgPSBkb3RQcm9kdWN0MkQ7XG5mdW5jdGlvbiBhbmdsZVRvKHZhLCB2Yikge1xuICAgIHZhciBtYWdBID0gbWFnbml0dWRlKHZhKTtcbiAgICB2YXIgbWFnQiA9IG1hZ25pdHVkZSh2Yik7XG4gICAgdmFyIGRvdCA9IGRvdFByb2R1Y3QyRCh2YSwgdmIpO1xuICAgIHZhciBhbmdsZSA9IE1hdGguYWNvcyhkb3QgLyBtYWdBIC8gbWFnQik7XG4gICAgcmV0dXJuIGFuZ2xlO1xufVxuZXhwb3J0cy5hbmdsZVRvID0gYW5nbGVUbztcbmZ1bmN0aW9uIGNyb3NzUHJvZHVjdDJEKHZhLCB2Yikge1xuICAgIHZhciBtYWdBID0gbWFnbml0dWRlKHZhKTtcbiAgICB2YXIgbWFnQiA9IG1hZ25pdHVkZSh2Yik7XG4gICAgdmFyIGRvdCA9IGRvdFByb2R1Y3QyRCh2YSwgdmIpO1xuICAgIHZhciBhbmdsZSA9IE1hdGguYWNvcyhkb3QgLyBtYWdBIC8gbWFnQik7XG4gICAgcmV0dXJuIG1hZ0EgKiBtYWdCICogTWF0aC5zaW4oYW5nbGUpO1xufVxuZXhwb3J0cy5jcm9zc1Byb2R1Y3QyRCA9IGNyb3NzUHJvZHVjdDJEO1xuZnVuY3Rpb24gY3Jvc3NQcm9kdWN0M0QodmEsIHZiKSB7XG4gICAgdmFyIGF4ID0gdmEueCwgYXkgPSB2YS55LCBheiA9IHZhLno7XG4gICAgdmFyIGJ4ID0gdmIueCwgYnkgPSB2Yi55LCBieiA9IHZiLno7XG4gICAgdmFyIHggPSBheSAqIGJ6IC0gYXogKiBieTtcbiAgICB2YXIgeSA9IGF6ICogYnggLSBheCAqIGJ6O1xuICAgIHZhciB6ID0gYXggKiBieSAtIGF5ICogYng7XG4gICAgcmV0dXJuIHsgeDogeCwgeTogeSwgejogeiB9O1xufVxuZXhwb3J0cy5jcm9zc1Byb2R1Y3QzRCA9IGNyb3NzUHJvZHVjdDNEO1xuZnVuY3Rpb24gc3ViMkQodmEsIHZiKSB7XG4gICAgcmV0dXJuIHsgeDogdmEueCAtIHZiLngsIHk6IHZhLnkgLSB2Yi55IH07XG59XG5leHBvcnRzLnN1YjJEID0gc3ViMkQ7XG5mdW5jdGlvbiBhcHBseU1hdHJpeChwb2ludCwgbWF0cml4LCB0YWcpIHtcbiAgICBpZiAodGFnID09PSB2b2lkIDApIHsgdGFnID0gMTsgfVxuICAgIHZhciB2ZWN0b3IgPSBbcG9pbnQueCwgcG9pbnQueSwgdGFnXTtcbiAgICBtYXRyaXhfdXRpbF8xLnZlYzMudHJhbnNmb3JtTWF0Myh2ZWN0b3IsIHZlY3RvciwgbWF0cml4KTtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB2ZWN0b3JbMF0sXG4gICAgICAgIHk6IHZlY3RvclsxXSxcbiAgICB9O1xufVxuZXhwb3J0cy5hcHBseU1hdHJpeCA9IGFwcGx5TWF0cml4O1xuZnVuY3Rpb24gaXNCZXR3ZWVuKHZhbHVlLCBtaW4sIG1heCkge1xuICAgIHJldHVybiB2YWx1ZSA+PSBtaW4gJiYgdmFsdWUgPD0gbWF4O1xufVxuZXhwb3J0cy5pc0JldHdlZW4gPSBpc0JldHdlZW47XG52YXIgdG9sZXJhbmNlID0gMC4wMDE7XG5mdW5jdGlvbiBnZXRMaW5lSW50ZXJzZWN0KHAwLCBwMSwgcDIsIHAzKSB7XG4gICAgdmFyIEUgPSB7XG4gICAgICAgIHg6IHAyLnggLSBwMC54LFxuICAgICAgICB5OiBwMi55IC0gcDAueSxcbiAgICB9O1xuICAgIHZhciBEMCA9IHtcbiAgICAgICAgeDogcDEueCAtIHAwLngsXG4gICAgICAgIHk6IHAxLnkgLSBwMC55LFxuICAgIH07XG4gICAgdmFyIEQxID0ge1xuICAgICAgICB4OiBwMy54IC0gcDIueCxcbiAgICAgICAgeTogcDMueSAtIHAyLnksXG4gICAgfTtcbiAgICB2YXIga3Jvc3MgPSBEMC54ICogRDEueSAtIEQwLnkgKiBEMS54O1xuICAgIHZhciBzcXJLcm9zcyA9IGtyb3NzICoga3Jvc3M7XG4gICAgdmFyIHNxckxlbjAgPSBEMC54ICogRDAueCArIEQwLnkgKiBEMC55O1xuICAgIHZhciBzcXJMZW4xID0gRDEueCAqIEQxLnggKyBEMS55ICogRDEueTtcbiAgICB2YXIgcG9pbnQgPSBudWxsO1xuICAgIGlmIChzcXJLcm9zcyA+IHRvbGVyYW5jZSAqIHNxckxlbjAgKiBzcXJMZW4xKSB7XG4gICAgICAgIHZhciBzID0gKEUueCAqIEQxLnkgLSBFLnkgKiBEMS54KSAvIGtyb3NzO1xuICAgICAgICB2YXIgdCA9IChFLnggKiBEMC55IC0gRS55ICogRDAueCkgLyBrcm9zcztcbiAgICAgICAgaWYgKGlzQmV0d2VlbihzLCAwLCAxKSAmJiBpc0JldHdlZW4odCwgMCwgMSkpIHtcbiAgICAgICAgICAgIHBvaW50ID0ge1xuICAgICAgICAgICAgICAgIHg6IHAwLnggKyBzICogRDAueCxcbiAgICAgICAgICAgICAgICB5OiBwMC55ICsgcyAqIEQwLnksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwb2ludDtcbn1cbmV4cG9ydHMuZ2V0TGluZUludGVyc2VjdCA9IGdldExpbmVJbnRlcnNlY3Q7XG5mdW5jdGlvbiBpc1BvaW50SW5Qb2x5Z29uKHAsIHBvbHlnb24pIHtcbiAgICAvKiog5bCE57q/5rOVICovXG4gICAgdmFyIGluc2lkZSA9IGZhbHNlO1xuICAgIGZvciAodmFyIGkgPSAwLCBqID0gcG9seWdvbi5sZW5ndGggLSAxOyBpIDwgcG9seWdvbi5sZW5ndGg7IGogPSBpKyspIHtcbiAgICAgICAgdmFyIHhpID0gcG9seWdvbltpXS54O1xuICAgICAgICB2YXIgeWkgPSBwb2x5Z29uW2ldLnk7XG4gICAgICAgIHZhciB4aiA9IHBvbHlnb25bal0ueDtcbiAgICAgICAgdmFyIHlqID0gcG9seWdvbltqXS55O1xuICAgICAgICB2YXIgaW50ZXJzZWN0ID0geWkgPiBwLnkgIT09IHlqID4gcC55ICYmIHAueCA8PSAoKHhqIC0geGkpICogKHAueSAtIHlpKSkgLyAoeWogLSB5aSkgKyB4aTtcbiAgICAgICAgaWYgKGludGVyc2VjdCkge1xuICAgICAgICAgICAgaW5zaWRlID0gIWluc2lkZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaW5zaWRlO1xufVxuZXhwb3J0cy5pc1BvaW50SW5Qb2x5Z29uID0gaXNQb2ludEluUG9seWdvbjtcbmZ1bmN0aW9uIHNxcih2KSB7XG4gICAgcmV0dXJuIHYgKiB2O1xufVxuZnVuY3Rpb24gZGlzdDIoYSwgYikge1xuICAgIHJldHVybiBNYXRoLnNxcnQoc3FyKGEueCAtIGIueCkgKyBzcXIoYS55IC0gYi55KSk7XG59XG5leHBvcnRzLmRpc3QyID0gZGlzdDI7XG5mdW5jdGlvbiBkaXN0QmV0d2VlblBvaW50cyhhLCBiKSB7XG4gICAgcmV0dXJuIE1hdGguc3FydChzcXIoYS54IC0gYi54KSArIHNxcihhLnkgLSBiLnkpKTtcbn1cbmV4cG9ydHMuZGlzdEJldHdlZW5Qb2ludHMgPSBkaXN0QmV0d2VlblBvaW50cztcbmZ1bmN0aW9uIGRpc3RCZXR3ZWVuUG9pbnRMaW5lKHAsIHAxLCBwMikge1xuICAgIHZhciBsMiA9IGRpc3QyKHAxLCBwMik7XG4gICAgaWYgKGwyID09PSAwKSB7XG4gICAgICAgIHJldHVybiBkaXN0MihwLCBwMSk7XG4gICAgfVxuICAgIHZhciB0ID0gKChwLnggLSBwMS54KSAqIChwMi54IC0gcDEueCkgKyAocC55IC0gcDEueSkgKiAocDIueSAtIHAxLnkpKSAvIGwyO1xuICAgIHQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCB0KSk7XG4gICAgdmFyIGRpc3RTcXVhcmUgPSBkaXN0MihwLCB7IHg6IHAxLnggKyB0ICogKHAyLnggLSBwMS54KSwgeTogcDEueSArIHQgKiAocDIueSAtIHAxLnkpIH0pO1xuICAgIHJldHVybiBNYXRoLnNxcnQoZGlzdFNxdWFyZSk7XG59XG5leHBvcnRzLmRpc3RCZXR3ZWVuUG9pbnRMaW5lID0gZGlzdEJldHdlZW5Qb2ludExpbmU7XG4vLyB0b2Rv77ya5b6F5LyY5YyWIGh0dHBzOi8vYmxvZy5jc2RuLm5ldC9XaWxsaWFtU3VuMDEyMi9hcnRpY2xlL2RldGFpbHMvNzc5OTQ1MjZcbmZ1bmN0aW9uIG1pbkRpc3RCZXR3ZWVuUG9pbnRQb2x5Z29uKHAsIHBvbHlnb24pIHtcbiAgICB2YXIgbWluID0gSW5maW5pdHk7XG4gICAgLyoqIHZlcnRpY2UgdG8gdmVydGljZSAqL1xuICAgIHV0aWxfMS5lYWNoKHBvbHlnb24sIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgIHZhciBkaXN0ID0gTWF0aC5zcXJ0KGRpc3QyKHYsIHApKTtcbiAgICAgICAgaWYgKG1pbiA+IGRpc3QpIHtcbiAgICAgICAgICAgIG1pbiA9IGRpc3Q7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvKiogdmVydGljZSB0byBlZGdlICovXG4gICAgZm9yICh2YXIgaSA9IDAsIGogPSBwb2x5Z29uLmxlbmd0aCAtIDE7IGkgPCBwb2x5Z29uLmxlbmd0aDsgaiA9IGkrKykge1xuICAgICAgICB2YXIgeGkgPSBwb2x5Z29uW2ldLng7XG4gICAgICAgIHZhciB5aSA9IHBvbHlnb25baV0ueTtcbiAgICAgICAgdmFyIHhqID0gcG9seWdvbltqXS54O1xuICAgICAgICB2YXIgeWogPSBwb2x5Z29uW2pdLnk7XG4gICAgICAgIHZhciBkaXN0ID0gZGlzdEJldHdlZW5Qb2ludExpbmUocCwgeyB4OiB4aSwgeTogeWkgfSwgeyB4OiB4aiwgeTogeWogfSk7XG4gICAgICAgIGlmIChtaW4gPiBkaXN0KSB7XG4gICAgICAgICAgICBtaW4gPSBkaXN0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtaW47XG59XG5mdW5jdGlvbiBpc1BvbHlnb25JbnRlcnNlY3Rpb24ocG9seUEsIHBvbHlCKSB7XG4gICAgZm9yICh2YXIgX2kgPSAwLCBwb2x5QV8xID0gcG9seUE7IF9pIDwgcG9seUFfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIHAgPSBwb2x5QV8xW19pXTtcbiAgICAgICAgdmFyIGluc2lkZSA9IGlzUG9pbnRJblBvbHlnb24ocCwgcG9seUIpO1xuICAgICAgICBpZiAoaW5zaWRlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnRzLmlzUG9seWdvbkludGVyc2VjdGlvbiA9IGlzUG9seWdvbkludGVyc2VjdGlvbjtcbmZ1bmN0aW9uIG1pbkRpc3RCZXR3ZWVuQ29udmV4UG9seWdvbihwb2x5QSwgcG9seUIpIHtcbiAgICBpZiAoaXNQb2x5Z29uSW50ZXJzZWN0aW9uKHBvbHlBLCBwb2x5QikpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHZhciBtaW5BID0gSW5maW5pdHk7XG4gICAgdmFyIG1pbkIgPSBJbmZpbml0eTtcbiAgICB1dGlsXzEuZWFjaChwb2x5QSwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgdmFyIGxvY2FsTWluID0gbWluRGlzdEJldHdlZW5Qb2ludFBvbHlnb24odiwgcG9seUIpO1xuICAgICAgICBpZiAobWluQSA+IGxvY2FsTWluKSB7XG4gICAgICAgICAgICBtaW5BID0gbG9jYWxNaW47XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICB1dGlsXzEuZWFjaChwb2x5QiwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgdmFyIGxvY2FsTWluID0gbWluRGlzdEJldHdlZW5Qb2ludFBvbHlnb24odiwgcG9seUEpO1xuICAgICAgICBpZiAobWluQiA+IGxvY2FsTWluKSB7XG4gICAgICAgICAgICBtaW5CID0gbG9jYWxNaW47XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gTWF0aC5taW4obWluQSwgbWluQik7XG59XG5leHBvcnRzLm1pbkRpc3RCZXR3ZWVuQ29udmV4UG9seWdvbiA9IG1pbkRpc3RCZXR3ZWVuQ29udmV4UG9seWdvbjtcbmZ1bmN0aW9uIGJib3hPblJvdGF0ZShzaGFwZSkge1xuICAgIHZhciBiYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgIHZhciB4ID0gYmJveC5taW5YO1xuICAgIHZhciB5ID0gYmJveC5taW5ZO1xuICAgIC8qXG4gICAgICogc3RlcDE6IOiOt+W+l+aXi+i9rOWQjueahHNoYXBl5YyF5Zu055uSXG4gICAgICog5bCG5YyF5Zu055uS5a+56b2Q5Yiw5Y6f54K577yMYXBwbHnml4vovaznn6npmLVcbiAgICAgKiDnp7vlm57ljp/mnaXnmoTkvY3nva5cbiAgICAgKi9cbiAgICB2YXIgYmJveFdpZHRoID0gYmJveC5tYXhYIC0gYmJveC5taW5YO1xuICAgIHZhciBiYm94SGVpZ2h0ID0gYmJveC5tYXhZIC0gYmJveC5taW5ZO1xuICAgIC8vIGNvbnN0IG1hdHJpeCA9IHNoYXBlLmdldFRvdGFsTWF0cml4KCk7XG4gICAgdmFyIG1hdHJpeCA9IHNoYXBlLmF0dHIoJ21hdHJpeCcpO1xuICAgIHZhciB1bE1hdHJpeDtcbiAgICBpZiAobWF0cml4KSB7XG4gICAgICAgIHVsTWF0cml4ID0gW21hdHJpeFswXSwgbWF0cml4WzFdLCAwLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgMCwgMCwgMCwgMV07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB1bE1hdHJpeCA9IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICB9XG4gICAgdmFyIHRvcF9sZWZ0ID0gYXBwbHlNYXRyaXgoeyB4OiAwLCB5OiAwIH0sIHVsTWF0cml4KTtcbiAgICB0b3BfbGVmdC54ICs9IHg7XG4gICAgdG9wX2xlZnQueSArPSB5O1xuICAgIHZhciB0b3BfcmlnaHQgPSBhcHBseU1hdHJpeCh7IHg6IGJib3hXaWR0aCwgeTogMCB9LCB1bE1hdHJpeCk7XG4gICAgdG9wX3JpZ2h0LnggKz0geDtcbiAgICB0b3BfcmlnaHQueSArPSB5O1xuICAgIHZhciBib3R0b21fbGVmdCA9IGFwcGx5TWF0cml4KHsgeDogMCwgeTogYmJveEhlaWdodCB9LCB1bE1hdHJpeCk7XG4gICAgYm90dG9tX2xlZnQueCArPSB4O1xuICAgIGJvdHRvbV9sZWZ0LnkgKz0geTtcbiAgICB2YXIgYm90dG9tX3JpZ2h0ID0gYXBwbHlNYXRyaXgoeyB4OiBiYm94V2lkdGgsIHk6IGJib3hIZWlnaHQgfSwgdWxNYXRyaXgpO1xuICAgIGJvdHRvbV9yaWdodC54ICs9IHg7XG4gICAgYm90dG9tX3JpZ2h0LnkgKz0geTtcbiAgICAvKiogc3RlcDLvvJrmoLnmja7ml4vovazlkI7nmoTnlLvluIPkvY3nva7ph43mlrDorqHnrpfljIXlm7Tnm5LvvIzku6XlhY3lm77lvaLov5vooYzml4vovazlkI7kuIrkuIvpoqDlgJIgKi9cbiAgICB2YXIgcG9pbnRzID0gW3RvcF9sZWZ0LCB0b3BfcmlnaHQsIGJvdHRvbV9sZWZ0LCBib3R0b21fcmlnaHRdO1xuICAgIHBvaW50cy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBhLnkgLSBiLnk7XG4gICAgfSk7XG4gICAgdmFyIG1pblkgPSBwb2ludHNbMF0ueTtcbiAgICB2YXIgbWF4WSA9IHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV0ueTtcbiAgICB2YXIgdG9wcyA9IFtwb2ludHNbMF0sIHBvaW50c1sxXV07XG4gICAgdmFyIGJvdHRvbXMgPSBbcG9pbnRzWzJdLCBwb2ludHNbM11dO1xuICAgIHZhciB0b3BMZWZ0ID0gdG9wc1swXS54IDwgdG9wc1sxXS54ID8gdG9wc1swXSA6IHRvcHNbMV07XG4gICAgdmFyIHRvcFJpZ2h0ID0gdG9wc1swXS54IDwgdG9wc1sxXS54ID8gdG9wc1sxXSA6IHRvcHNbMF07XG4gICAgdmFyIGJvdHRvbUxlZnQgPSBib3R0b21zWzBdLnggPCBib3R0b21zWzFdLnggPyBib3R0b21zWzBdIDogYm90dG9tc1sxXTtcbiAgICB2YXIgYm90dG9tUmlnaHQgPSBib3R0b21zWzBdLnggPCBib3R0b21zWzFdLnggPyBib3R0b21zWzFdIDogYm90dG9tc1swXTtcbiAgICBwb2ludHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gYS54IC0gYi54O1xuICAgIH0pO1xuICAgIHZhciBtaW5YID0gcG9pbnRzWzBdLng7XG4gICAgdmFyIG1heFggPSBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdLng7XG4gICAgdmFyIG5vZGUgPSB7XG4gICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgaGVpZ2h0OiBtYXhZIC0gbWluWSxcbiAgICAgICAgbGVmdDogbWluWCxcbiAgICAgICAgcmlnaHQ6IG1heFgsXG4gICAgICAgIHRvcDogbWluWSxcbiAgICAgICAgYm90dG9tOiBtYXhZLFxuICAgICAgICB0b3BMZWZ0OiB0b3BMZWZ0LFxuICAgICAgICB0b3BSaWdodDogdG9wUmlnaHQsXG4gICAgICAgIGJvdHRvbUxlZnQ6IGJvdHRvbUxlZnQsXG4gICAgICAgIGJvdHRvbVJpZ2h0OiBib3R0b21SaWdodCxcbiAgICAgICAgY2VudGVyWDogbWluWCArIChtYXhYIC0gbWluWCkgLyAyLFxuICAgICAgICBjZW50ZXJZOiBtaW5ZICsgKG1heFkgLSBtaW5ZKSAvIDIsXG4gICAgfTtcbiAgICByZXR1cm4gbm9kZTtcbn1cbmV4cG9ydHMuYmJveE9uUm90YXRlID0gYmJveE9uUm90YXRlO1xuLyoqXG4gKiDnur/nroDljJbnrpfms5VcbiAqL1xudmFyIFRIUkVTSE9MRCA9IDI7XG5mdW5jdGlvbiBsaW5lU2ltcGxpZmljYXRpb24ocG9pbnRzKSB7XG4gICAgaWYgKHBvaW50cy5sZW5ndGggPCA1KSB7XG4gICAgICAgIHJldHVybiBwb2ludHM7XG4gICAgfVxuICAgIHJldHVybiBEb3VnbGFzUGV1Y2tlcihwb2ludHMsIFRIUkVTSE9MRCk7XG59XG5leHBvcnRzLmxpbmVTaW1wbGlmaWNhdGlvbiA9IGxpbmVTaW1wbGlmaWNhdGlvbjtcbi8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1JhbWVyJUUyJTgwJTkzRG91Z2xhcyVFMiU4MCU5M1BldWNrZXJfYWxnb3JpdGhtXG5mdW5jdGlvbiBEb3VnbGFzUGV1Y2tlcihwb2ludHMsIHRocmVzaG9sZCkge1xuICAgIHZhciByZXN1bHQ7XG4gICAgdmFyIG1heCA9IC1JbmZpbml0eTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBlbmRJbmRleCA9IHBvaW50cy5sZW5ndGggLSAxO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgZW5kSW5kZXg7IGkrKykge1xuICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgIHZhciBsaW5lID0geyBzdGFydDogcG9pbnRzWzBdLCBlbmQ6IHBvaW50c1tlbmRJbmRleF0gfTtcbiAgICAgICAgdmFyIGRpc3QgPSBkaXN0QmV0d2VlblBvaW50TGluZShwb2ludCwgbGluZS5zdGFydCwgbGluZS5lbmQpO1xuICAgICAgICBpZiAoZGlzdCA+IG1heCkge1xuICAgICAgICAgICAgbWF4ID0gZGlzdDtcbiAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAobWF4ID4gdGhyZXNob2xkKSB7XG4gICAgICAgIHZhciBsaXN0MSA9IERvdWdsYXNQZXVja2VyKHBvaW50cy5zbGljZSgwLCBpbmRleCArIDEpLCB0aHJlc2hvbGQpO1xuICAgICAgICB2YXIgbGlzdDIgPSBEb3VnbGFzUGV1Y2tlcihwb2ludHMuc2xpY2UoaW5kZXgsIHBvaW50cy5sZW5ndGgpLCB0aHJlc2hvbGQpO1xuICAgICAgICByZXN1bHQgPSBsaXN0MS5jb25jYXQobGlzdDIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gW3BvaW50c1swXSwgcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG4vKiog57uf6K6h55qE5Lul5ZCO6L+B5Ye65Y6777yM5pqC5pe25YWI5pS+6L+Z6YeMICovXG5mdW5jdGlvbiBnZXRNZWRpYW4oYXJyYXkpIHtcbiAgICB2YXIgbGlzdCA9IHV0aWxfMS5jbG9uZShhcnJheSk7XG4gICAgbGlzdC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBhIC0gYjtcbiAgICB9KTtcbiAgICB2YXIgaGFsZiA9IE1hdGguZmxvb3IobGlzdC5sZW5ndGggLyAyKTtcbiAgICBpZiAobGlzdC5sZW5ndGggJSAyKSB7XG4gICAgICAgIHJldHVybiBsaXN0W2hhbGZdO1xuICAgIH1cbiAgICByZXR1cm4gKGxpc3RbaGFsZiAtIDFdICsgbGlzdFtoYWxmXSkgLyAyLjA7XG59XG5leHBvcnRzLmdldE1lZGlhbiA9IGdldE1lZGlhbjtcbmZ1bmN0aW9uIGdldE1lYW4oYXJyYXkpIHtcbiAgICB2YXIgc3VtID0gMDtcbiAgICB1dGlsXzEuZWFjaChhcnJheSwgZnVuY3Rpb24gKG51bSkge1xuICAgICAgICBzdW0gKz0gbnVtO1xuICAgIH0pO1xuICAgIHJldHVybiBzdW0gLyBhcnJheS5sZW5ndGg7XG59XG5leHBvcnRzLmdldE1lYW4gPSBnZXRNZWFuO1xuZnVuY3Rpb24gc3R1cmdlcyh2YWx1ZXMpIHtcbiAgICByZXR1cm4gTWF0aC5jZWlsKE1hdGgubG9nKHZhbHVlcy5sZW5ndGgpIC8gTWF0aC5MTjIpICsgMTtcbn1cbmV4cG9ydHMuc3R1cmdlcyA9IHN0dXJnZXM7XG4vKipcbiAqIOiOt+WPliB4L3kvd2lkdGgvaGVpZ2h05oyH5a6a55qEQkJveOi+ueeVjOS4iueahOaJgOacieeCue+8jOeUsXN0ZXDmir3moLdcbiAqIEBwYXJhbSB4XG4gKiBAcGFyYW0geVxuICogQHBhcmFtIHdpZHRoXG4gKiBAcGFyYW0gaGVpZ2h0XG4gKiBAcGFyYW0gc3RlcFxuICovXG5mdW5jdGlvbiBnZXRTdHJva2VQb2ludHMoeCwgeSwgd2lkdGgsIGhlaWdodCwgc3RlcCkge1xuICAgIGlmIChzdGVwID09PSB2b2lkIDApIHsgc3RlcCA9IDI7IH1cbiAgICB2YXIgcG9pbnRzID0gW107XG4gICAgLy8gdG9wXG4gICAgZm9yICh2YXIgY3VyWCA9IHg7IGN1clggPD0geCArIHdpZHRoOyBjdXJYICs9IHN0ZXApIHtcbiAgICAgICAgcG9pbnRzLnB1c2goW2N1clgsIHldKTtcbiAgICB9XG4gICAgLy8gcmlnaHRcbiAgICBmb3IgKHZhciBjdXJZID0geTsgY3VyWSA8PSB5ICsgaGVpZ2h0OyBjdXJZICs9IHN0ZXApIHtcbiAgICAgICAgcG9pbnRzLnB1c2goW3ggKyB3aWR0aCwgY3VyWV0pO1xuICAgIH1cbiAgICAvLyBib3R0b21cbiAgICBmb3IgKHZhciBjdXJYID0geCArIHdpZHRoOyBjdXJYID49IHg7IGN1clggLT0gc3RlcCkge1xuICAgICAgICBwb2ludHMucHVzaChbY3VyWCwgeSArIGhlaWdodF0pO1xuICAgIH1cbiAgICAvLyBsZWZ0XG4gICAgZm9yICh2YXIgY3VyWSA9IHkgKyBoZWlnaHQ7IGN1clkgPj0geTsgY3VyWSAtPSBzdGVwKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFt4LCBjdXJZXSk7XG4gICAgfVxuICAgIHJldHVybiBwb2ludHM7XG59XG5leHBvcnRzLmdldFN0cm9rZVBvaW50cyA9IGdldFN0cm9rZVBvaW50cztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1hdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBwYXRoIOiuoeeul+OAgei9rOaNoueahOi+heWKqeW3peWFt1xuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNvbnZlcnRQb2xhclBhdGggPSBleHBvcnRzLmNvbnZlcnROb3JtYWxQYXRoID0gZXhwb3J0cy5nZXRQb2ludEFuZ2xlID0gZXhwb3J0cy5nZXRQb2ludFJhZGl1cyA9IGV4cG9ydHMuZ2V0U3BsaW5lUGF0aCA9IGV4cG9ydHMuZ2V0TGluZVBhdGggPSBleHBvcnRzLmNhdG11bGxSb20yYmV6aWVyID0gZXhwb3J0cy5zbW9vdGhCZXppZXIgPSB2b2lkIDA7XG52YXIgbWF0cml4X3V0aWxfMSA9IHJlcXVpcmUoXCJAYW50di9tYXRyaXgtdXRpbFwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbmZ1bmN0aW9uIF9wb2ludHMycGF0aChwb2ludHMsIGlzSW5DaXJjbGUpIHtcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIGlmIChwb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGhfMSA9IHBvaW50cy5sZW5ndGg7IGkgPCBsZW5ndGhfMTsgaSArPSAxKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIHZhciBjb21tYW5kID0gaSA9PT0gMCA/ICdNJyA6ICdMJztcbiAgICAgICAgICAgIHBhdGgucHVzaChbY29tbWFuZCwgaXRlbS54LCBpdGVtLnldKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNJbkNpcmNsZSkge1xuICAgICAgICAgICAgcGF0aC5wdXNoKFsnWiddKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGF0aDtcbn1cbmZ1bmN0aW9uIF9nZXRQb2ludFJhZGl1cyhjb29yZCwgcG9pbnQpIHtcbiAgICB2YXIgY2VudGVyID0gY29vcmQuZ2V0Q2VudGVyKCk7XG4gICAgdmFyIHIgPSBNYXRoLnNxcnQoTWF0aC5wb3cocG9pbnQueCAtIGNlbnRlci54LCAyKSArIE1hdGgucG93KHBvaW50LnkgLSBjZW50ZXIueSwgMikpO1xuICAgIHJldHVybiByO1xufVxuZnVuY3Rpb24gX2NvbnZlcnRBcnIoYXJyLCBjb29yZCkge1xuICAgIHZhciB0bXAgPSBbYXJyWzBdXTtcbiAgICBmb3IgKHZhciBpID0gMSwgbGVuID0gYXJyLmxlbmd0aDsgaSA8IGxlbjsgaSA9IGkgKyAyKSB7XG4gICAgICAgIHZhciBwb2ludCA9IGNvb3JkLmNvbnZlcnRQb2ludCh7XG4gICAgICAgICAgICB4OiBhcnJbaV0sXG4gICAgICAgICAgICB5OiBhcnJbaSArIDFdLFxuICAgICAgICB9KTtcbiAgICAgICAgdG1wLnB1c2gocG9pbnQueCwgcG9pbnQueSk7XG4gICAgfVxuICAgIHJldHVybiB0bXA7XG59XG5mdW5jdGlvbiBfY29udmVydFBvbGFyUGF0aChwcmUsIGN1ciwgY29vcmQpIHtcbiAgICB2YXIgaXNUcmFuc3Bvc2VkID0gY29vcmQuaXNUcmFuc3Bvc2VkLCBzdGFydEFuZ2xlID0gY29vcmQuc3RhcnRBbmdsZSwgZW5kQW5nbGUgPSBjb29yZC5lbmRBbmdsZTtcbiAgICB2YXIgcHJlUG9pbnQgPSB7XG4gICAgICAgIHg6IHByZVsxXSxcbiAgICAgICAgeTogcHJlWzJdLFxuICAgIH07XG4gICAgdmFyIGN1clBvaW50ID0ge1xuICAgICAgICB4OiBjdXJbMV0sXG4gICAgICAgIHk6IGN1clsyXSxcbiAgICB9O1xuICAgIHZhciByc3QgPSBbXTtcbiAgICB2YXIgeERpbSA9IGlzVHJhbnNwb3NlZCA/ICd5JyA6ICd4JztcbiAgICB2YXIgYW5nbGVSYW5nZSA9IE1hdGguYWJzKGN1clBvaW50W3hEaW1dIC0gcHJlUG9pbnRbeERpbV0pICogKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSk7XG4gICAgdmFyIGRpcmVjdGlvbiA9IGN1clBvaW50W3hEaW1dID49IHByZVBvaW50W3hEaW1dID8gMSA6IDA7IC8vIOWchuW8p+eahOaWueWQkVxuICAgIHZhciBmbGFnID0gYW5nbGVSYW5nZSA+IE1hdGguUEkgPyAxIDogMDsgLy8g5aSn5byn6L+Y5piv5bCP5byn5qCH5b+X5L2NXG4gICAgdmFyIGNvbnZlcnRQb2ludCA9IGNvb3JkLmNvbnZlcnRQb2ludChjdXJQb2ludCk7XG4gICAgdmFyIHIgPSBfZ2V0UG9pbnRSYWRpdXMoY29vcmQsIGNvbnZlcnRQb2ludCk7XG4gICAgaWYgKHIgPj0gMC41KSB7XG4gICAgICAgIC8vIOWwj+S6jjHlg4/ntKDnmoTlnIblnKjlm77lg4/kuIrml6Dms5Xor4bliKtcbiAgICAgICAgaWYgKGFuZ2xlUmFuZ2UgPT09IE1hdGguUEkgKiAyKSB7XG4gICAgICAgICAgICB2YXIgbWlkZGxlUG9pbnQgPSB7XG4gICAgICAgICAgICAgICAgeDogKGN1clBvaW50LnggKyBwcmVQb2ludC54KSAvIDIsXG4gICAgICAgICAgICAgICAgeTogKGN1clBvaW50LnkgKyBwcmVQb2ludC55KSAvIDIsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIG1pZGRsZUNvbnZlcnRQb2ludCA9IGNvb3JkLmNvbnZlcnRQb2ludChtaWRkbGVQb2ludCk7XG4gICAgICAgICAgICByc3QucHVzaChbJ0EnLCByLCByLCAwLCBmbGFnLCBkaXJlY3Rpb24sIG1pZGRsZUNvbnZlcnRQb2ludC54LCBtaWRkbGVDb252ZXJ0UG9pbnQueV0pO1xuICAgICAgICAgICAgcnN0LnB1c2goWydBJywgciwgciwgMCwgZmxhZywgZGlyZWN0aW9uLCBjb252ZXJ0UG9pbnQueCwgY29udmVydFBvaW50LnldKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJzdC5wdXNoKFsnQScsIHIsIHIsIDAsIGZsYWcsIGRpcmVjdGlvbiwgY29udmVydFBvaW50LngsIGNvbnZlcnRQb2ludC55XSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJzdDtcbn1cbi8vIOW9k+WtmOWcqOaVtOS9k+eahOWchuaXtu+8jOWOu+mZpOWchuWJjemdouWSjOWQjumdoueahOe6v++8jOmYsuatouWHuueOsOebtOe6v+epv+i/h+aVtOS4quWchueahOaDheW9olxuZnVuY3Rpb24gX2ZpbHRlckZ1bGxDaXJsZUxpbmUocGF0aCkge1xuICAgIHV0aWxfMS5lYWNoKHBhdGgsIGZ1bmN0aW9uIChzdWJQYXRoLCBpbmRleCkge1xuICAgICAgICB2YXIgY3VyID0gc3ViUGF0aDtcbiAgICAgICAgaWYgKGN1clswXS50b0xvd2VyQ2FzZSgpID09PSAnYScpIHtcbiAgICAgICAgICAgIHZhciBwcmUgPSBwYXRoW2luZGV4IC0gMV07XG4gICAgICAgICAgICB2YXIgbmV4dCA9IHBhdGhbaW5kZXggKyAxXTtcbiAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHRbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ2EnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByZSAmJiBwcmVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ2wnKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZVswXSA9ICdNJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChwcmUgJiYgcHJlWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdhJykge1xuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHRbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ2wnKSB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRbMF0gPSAnTSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnRzLnNtb290aEJlemllciA9IGZ1bmN0aW9uIChwb2ludHMsIHNtb290aCwgaXNMb29wLCBjb25zdHJhaW50KSB7XG4gICAgdmFyIGNwcyA9IFtdO1xuICAgIHZhciBwcmV2UG9pbnQ7XG4gICAgdmFyIG5leHRQb2ludDtcbiAgICB2YXIgaGFzQ29uc3RyYWludCA9ICEhY29uc3RyYWludDtcbiAgICB2YXIgbWluO1xuICAgIHZhciBtYXg7XG4gICAgaWYgKGhhc0NvbnN0cmFpbnQpIHtcbiAgICAgICAgbWluID0gW0luZmluaXR5LCBJbmZpbml0eV07XG4gICAgICAgIG1heCA9IFstSW5maW5pdHksIC1JbmZpbml0eV07XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gcG9pbnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgdmFyIHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgbWluID0gbWF0cml4X3V0aWxfMS52ZWMyLm1pbihbMCwgMF0sIG1pbiwgcG9pbnQpO1xuICAgICAgICAgICAgbWF4ID0gbWF0cml4X3V0aWxfMS52ZWMyLm1heChbMCwgMF0sIG1heCwgcG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIG1pbiA9IG1hdHJpeF91dGlsXzEudmVjMi5taW4oWzAsIDBdLCBtaW4sIGNvbnN0cmFpbnRbMF0pO1xuICAgICAgICBtYXggPSBtYXRyaXhfdXRpbF8xLnZlYzIubWF4KFswLCAwXSwgbWF4LCBjb25zdHJhaW50WzFdKTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgIGlmIChpc0xvb3ApIHtcbiAgICAgICAgICAgIHByZXZQb2ludCA9IHBvaW50c1tpID8gaSAtIDEgOiBsZW4gLSAxXTtcbiAgICAgICAgICAgIG5leHRQb2ludCA9IHBvaW50c1soaSArIDEpICUgbGVuXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChpID09PSAwIHx8IGkgPT09IGxlbiAtIDEpIHtcbiAgICAgICAgICAgICAgICBjcHMucHVzaChwb2ludCk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2UG9pbnQgPSBwb2ludHNbaSAtIDFdO1xuICAgICAgICAgICAgICAgIG5leHRQb2ludCA9IHBvaW50c1tpICsgMV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHYgPSBbMCwgMF07XG4gICAgICAgIHYgPSBtYXRyaXhfdXRpbF8xLnZlYzIuc3ViKHYsIG5leHRQb2ludCwgcHJldlBvaW50KTtcbiAgICAgICAgdiA9IG1hdHJpeF91dGlsXzEudmVjMi5zY2FsZSh2LCB2LCBzbW9vdGgpO1xuICAgICAgICB2YXIgZDAgPSBtYXRyaXhfdXRpbF8xLnZlYzIuZGlzdGFuY2UocG9pbnQsIHByZXZQb2ludCk7XG4gICAgICAgIHZhciBkMSA9IG1hdHJpeF91dGlsXzEudmVjMi5kaXN0YW5jZShwb2ludCwgbmV4dFBvaW50KTtcbiAgICAgICAgdmFyIHN1bSA9IGQwICsgZDE7XG4gICAgICAgIGlmIChzdW0gIT09IDApIHtcbiAgICAgICAgICAgIGQwIC89IHN1bTtcbiAgICAgICAgICAgIGQxIC89IHN1bTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdjEgPSBtYXRyaXhfdXRpbF8xLnZlYzIuc2NhbGUoWzAsIDBdLCB2LCAtZDApO1xuICAgICAgICB2YXIgdjIgPSBtYXRyaXhfdXRpbF8xLnZlYzIuc2NhbGUoWzAsIDBdLCB2LCBkMSk7XG4gICAgICAgIHZhciBjcDAgPSBtYXRyaXhfdXRpbF8xLnZlYzIuYWRkKFswLCAwXSwgcG9pbnQsIHYxKTtcbiAgICAgICAgdmFyIGNwMSA9IG1hdHJpeF91dGlsXzEudmVjMi5hZGQoWzAsIDBdLCBwb2ludCwgdjIpO1xuICAgICAgICBpZiAoaGFzQ29uc3RyYWludCkge1xuICAgICAgICAgICAgY3AwID0gbWF0cml4X3V0aWxfMS52ZWMyLm1heChbMCwgMF0sIGNwMCwgbWluKTtcbiAgICAgICAgICAgIGNwMCA9IG1hdHJpeF91dGlsXzEudmVjMi5taW4oWzAsIDBdLCBjcDAsIG1heCk7XG4gICAgICAgICAgICBjcDEgPSBtYXRyaXhfdXRpbF8xLnZlYzIubWF4KFswLCAwXSwgY3AxLCBtaW4pO1xuICAgICAgICAgICAgY3AxID0gbWF0cml4X3V0aWxfMS52ZWMyLm1pbihbMCwgMF0sIGNwMSwgbWF4KTtcbiAgICAgICAgfVxuICAgICAgICBjcHMucHVzaChjcDApO1xuICAgICAgICBjcHMucHVzaChjcDEpO1xuICAgIH1cbiAgICBpZiAoaXNMb29wKSB7XG4gICAgICAgIGNwcy5wdXNoKGNwcy5zaGlmdCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNwcztcbn07XG4vLyDotJ3loZ7lsJTmm7Lnur9cbmZ1bmN0aW9uIGNhdG11bGxSb20yYmV6aWVyKGNycCwgeiwgY29uc3RyYWludCkge1xuICAgIHZhciBpc0xvb3AgPSAhIXo7XG4gICAgdmFyIHBvaW50TGlzdCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gY3JwLmxlbmd0aDsgaSA8IGw7IGkgKz0gMikge1xuICAgICAgICBwb2ludExpc3QucHVzaChbY3JwW2ldLCBjcnBbaSArIDFdXSk7XG4gICAgfVxuICAgIHZhciBjb250cm9sUG9pbnRMaXN0ID0gZXhwb3J0cy5zbW9vdGhCZXppZXIocG9pbnRMaXN0LCAwLjQsIGlzTG9vcCwgY29uc3RyYWludCk7XG4gICAgdmFyIGxlbiA9IHBvaW50TGlzdC5sZW5ndGg7XG4gICAgdmFyIGQxID0gW107XG4gICAgdmFyIGNwMTtcbiAgICB2YXIgY3AyO1xuICAgIHZhciBwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuIC0gMTsgaSsrKSB7XG4gICAgICAgIGNwMSA9IGNvbnRyb2xQb2ludExpc3RbaSAqIDJdO1xuICAgICAgICBjcDIgPSBjb250cm9sUG9pbnRMaXN0W2kgKiAyICsgMV07XG4gICAgICAgIHAgPSBwb2ludExpc3RbaSArIDFdO1xuICAgICAgICBkMS5wdXNoKFsnQycsIGNwMVswXSwgY3AxWzFdLCBjcDJbMF0sIGNwMlsxXSwgcFswXSwgcFsxXV0pO1xuICAgIH1cbiAgICBpZiAoaXNMb29wKSB7XG4gICAgICAgIGNwMSA9IGNvbnRyb2xQb2ludExpc3RbbGVuXTtcbiAgICAgICAgY3AyID0gY29udHJvbFBvaW50TGlzdFtsZW4gKyAxXTtcbiAgICAgICAgcCA9IHBvaW50TGlzdFswXTtcbiAgICAgICAgZDEucHVzaChbJ0MnLCBjcDFbMF0sIGNwMVsxXSwgY3AyWzBdLCBjcDJbMV0sIHBbMF0sIHBbMV1dKTtcbiAgICB9XG4gICAgcmV0dXJuIGQxO1xufVxuZXhwb3J0cy5jYXRtdWxsUm9tMmJlemllciA9IGNhdG11bGxSb20yYmV6aWVyO1xuLy8g5bCG54K56L+e5o6l5oiQ6Lev5b6EIHBhdGhcbmZ1bmN0aW9uIGdldExpbmVQYXRoKHBvaW50cywgaXNJbkNpcmNsZSkge1xuICAgIHJldHVybiBfcG9pbnRzMnBhdGgocG9pbnRzLCBpc0luQ2lyY2xlKTtcbn1cbmV4cG9ydHMuZ2V0TGluZVBhdGggPSBnZXRMaW5lUGF0aDtcbi8vIGdldCBzcGxpbmXvvJog6ZmQ5a6a5LqG6IyD5Zu055qE5bmz5ruR57q/XG5mdW5jdGlvbiBnZXRTcGxpbmVQYXRoKHBvaW50cywgaXNJbkNpcmNsZSwgY29uc3RhaW50KSB7XG4gICAgdmFyIGRhdGEgPSBbXTtcbiAgICB2YXIgZmlyc3QgPSBwb2ludHNbMF07XG4gICAgdmFyIHByZVBvaW50ID0gbnVsbDtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgIC8vIOS4pOeCueS7peWGheebtOaOpee7mOWItuaIkOi3r+W+hFxuICAgICAgICByZXR1cm4gZ2V0TGluZVBhdGgocG9pbnRzLCBpc0luQ2lyY2xlKTtcbiAgICB9XG4gICAgdXRpbF8xLmVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgaWYgKCFwcmVQb2ludCB8fCAhKHByZVBvaW50LnggPT09IHBvaW50LnggJiYgcHJlUG9pbnQueSA9PT0gcG9pbnQueSkpIHtcbiAgICAgICAgICAgIGRhdGEucHVzaChwb2ludC54KTtcbiAgICAgICAgICAgIGRhdGEucHVzaChwb2ludC55KTtcbiAgICAgICAgICAgIHByZVBvaW50ID0gcG9pbnQ7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICB2YXIgY29uc3RyYWludCA9IGNvbnN0YWludCB8fCBbXG4gICAgICAgIC8vIOiMg+WbtFxuICAgICAgICBbMCwgMF0sXG4gICAgICAgIFsxLCAxXSxcbiAgICBdO1xuICAgIHZhciBzcGxpbmVQYXRoID0gY2F0bXVsbFJvbTJiZXppZXIoZGF0YSwgaXNJbkNpcmNsZSwgY29uc3RyYWludCk7XG4gICAgc3BsaW5lUGF0aC51bnNoaWZ0KFsnTScsIGZpcnN0LngsIGZpcnN0LnldKTtcbiAgICByZXR1cm4gc3BsaW5lUGF0aDtcbn1cbmV4cG9ydHMuZ2V0U3BsaW5lUGF0aCA9IGdldFNwbGluZVBhdGg7XG4vLyDojrflj5bngrnliLDlnIblv4PnmoTot53nprtcbmZ1bmN0aW9uIGdldFBvaW50UmFkaXVzKGNvb3JkLCBwb2ludCkge1xuICAgIHJldHVybiBfZ2V0UG9pbnRSYWRpdXMoY29vcmQsIHBvaW50KTtcbn1cbmV4cG9ydHMuZ2V0UG9pbnRSYWRpdXMgPSBnZXRQb2ludFJhZGl1cztcbi8vIOiOt+WPlueCueWIsOWchuW/g+eahOWkueinklxuZnVuY3Rpb24gZ2V0UG9pbnRBbmdsZShjb29yZCwgcG9pbnQpIHtcbiAgICB2YXIgY2VudGVyID0gY29vcmQuZ2V0Q2VudGVyKCk7XG4gICAgcmV0dXJuIE1hdGguYXRhbjIocG9pbnQueSAtIGNlbnRlci55LCBwb2ludC54IC0gY2VudGVyLngpO1xufVxuZXhwb3J0cy5nZXRQb2ludEFuZ2xlID0gZ2V0UG9pbnRBbmdsZTtcbmZ1bmN0aW9uIGNvbnZlcnROb3JtYWxQYXRoKGNvb3JkLCBwYXRoKSB7XG4gICAgdmFyIHRtcCA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKHBhdGgsIGZ1bmN0aW9uIChzdWJQYXRoKSB7XG4gICAgICAgIHZhciBhY3Rpb24gPSBzdWJQYXRoWzBdO1xuICAgICAgICBzd2l0Y2ggKGFjdGlvbi50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlICdtJzpcbiAgICAgICAgICAgIGNhc2UgJ2wnOlxuICAgICAgICAgICAgY2FzZSAnYyc6XG4gICAgICAgICAgICAgICAgdG1wLnB1c2goX2NvbnZlcnRBcnIoc3ViUGF0aCwgY29vcmQpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3onOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0bXAucHVzaChzdWJQYXRoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0bXA7XG59XG5leHBvcnRzLmNvbnZlcnROb3JtYWxQYXRoID0gY29udmVydE5vcm1hbFBhdGg7XG5mdW5jdGlvbiBjb252ZXJ0UG9sYXJQYXRoKGNvb3JkLCBwYXRoKSB7XG4gICAgdmFyIHRtcCA9IFtdO1xuICAgIHZhciBwcmU7XG4gICAgdmFyIGN1cjtcbiAgICB2YXIgdHJhbnNwb3NlZDtcbiAgICB2YXIgZXF1YWxzO1xuICAgIHV0aWxfMS5lYWNoKHBhdGgsIGZ1bmN0aW9uIChzdWJQYXRoLCBpbmRleCkge1xuICAgICAgICB2YXIgYWN0aW9uID0gc3ViUGF0aFswXTtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSAnbSc6XG4gICAgICAgICAgICBjYXNlICdjJzpcbiAgICAgICAgICAgIGNhc2UgJ3EnOlxuICAgICAgICAgICAgICAgIHRtcC5wdXNoKF9jb252ZXJ0QXJyKHN1YlBhdGgsIGNvb3JkKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdsJzpcbiAgICAgICAgICAgICAgICBwcmUgPSBwYXRoW2luZGV4IC0gMV07XG4gICAgICAgICAgICAgICAgY3VyID0gc3ViUGF0aDtcbiAgICAgICAgICAgICAgICB0cmFuc3Bvc2VkID0gY29vcmQuaXNUcmFuc3Bvc2VkO1xuICAgICAgICAgICAgICAgIC8vIOaYr+WQpuWNiuW+hOebuOWQjO+8jOi9rOaNouaIkOWchuW8p1xuICAgICAgICAgICAgICAgIGVxdWFscyA9IHRyYW5zcG9zZWQgPyBwcmVbcHJlLmxlbmd0aCAtIDJdID09PSBjdXJbMV0gOiBwcmVbcHJlLmxlbmd0aCAtIDFdID09PSBjdXJbMl07XG4gICAgICAgICAgICAgICAgaWYgKGVxdWFscykge1xuICAgICAgICAgICAgICAgICAgICB0bXAgPSB0bXAuY29uY2F0KF9jb252ZXJ0UG9sYXJQYXRoKHByZSwgY3VyLCBjb29yZCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8geSDkuI3nm7jnrYnvvIzmiYDku6Xnm7TmjqXovazmjaJcbiAgICAgICAgICAgICAgICAgICAgdG1wLnB1c2goX2NvbnZlcnRBcnIoc3ViUGF0aCwgY29vcmQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd6JzpcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdG1wLnB1c2goc3ViUGF0aCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBfZmlsdGVyRnVsbENpcmxlTGluZSh0bXApOyAvLyDov4fmu6TlpJrkvZnnmoTnm7Tnur9cbiAgICByZXR1cm4gdG1wO1xufVxuZXhwb3J0cy5jb252ZXJ0UG9sYXJQYXRoID0gY29udmVydFBvbGFyUGF0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhdGguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBzaGFwZV9ub2Rlc18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL25vZGUvc2hhcGUtbm9kZXNcIikpO1xudmFyIHJlc3BvbnNpdmVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuLi9yZXNwb25zaXZlXCIpKTtcbnZhciBiYXNlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9iYXNlXCIpKTtcbnZhciBTQ0FMRV9NQVBQRVIgPSB7XG4gICAgY2F0OiAnY2F0ZWdvcnknLFxuICAgIHRpbWVDYXQ6ICdjYXRlZ29yeScsXG4gICAgdGltZTogJ2RhdGVUaW1lJyxcbiAgICBsaW5lYXI6ICdsaW5lYXInLFxufTtcbnZhciBBcHBseVJlc3BvbnNpdmVBeGlzID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEFwcGx5UmVzcG9uc2l2ZUF4aXMsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQXBwbHlSZXNwb25zaXZlQXhpcygpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIH1cbiAgICBBcHBseVJlc3BvbnNpdmVBeGlzLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmF4aXNJbnN0YW5jZSA9IHRoaXMuZ2V0QXhpc0luc3RhbmNlKCk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgQXBwbHlSZXNwb25zaXZlQXhpcy5wcm90b3R5cGUuc2hvdWxkQXBwbHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIGlmICghdGhpcy5yZXNwb25zaXZlVGhlbWUuYXhpcykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJlc3BvbnNpdmVUaGVtZS5heGlzW3RoaXMuZGltXSAmJlxuICAgICAgICAgICAgb3B0aW9uc1t0aGlzLmRpbSArIFwiQXhpc1wiXS52aXNpYmxlICYmXG4gICAgICAgICAgICBvcHRpb25zW3RoaXMuZGltICsgXCJBeGlzXCJdLmxhYmVsICYmXG4gICAgICAgICAgICBvcHRpb25zW3RoaXMuZGltICsgXCJBeGlzXCJdLmxhYmVsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEFwcGx5UmVzcG9uc2l2ZUF4aXMucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgcmF3TGFiZWxzID0gdGhpcy5wbG90LnZpZXcuYmFja2dyb3VuZEdyb3VwLmZpbmRBbGwoZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IGVsLmdldCgnbmFtZScpO1xuICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdheGlzLWxhYmVsJykge1xuICAgICAgICAgICAgICAgIHZhciBmaWVsZCA9IGVsLmdldCgnZGVsZWdhdGVPYmplY3QnKS5heGlzLmdldCgnZmllbGQnKTtcbiAgICAgICAgICAgICAgICBpZiAoZmllbGQgPT09IF90aGlzLnBsb3Qub3B0aW9uc1tfdGhpcy5kaW0gKyBcIkZpZWxkXCJdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgc2hhcGVzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmF3TGFiZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzaGFwZXMucHVzaChyYXdMYWJlbHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzaGFwZU5vZGVzID0gbmV3IHNoYXBlX25vZGVzXzEuZGVmYXVsdCh7XG4gICAgICAgICAgICBzaGFwZXM6IHNoYXBlcyxcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBfYSA9IHRoaXMucmVzcG9uc2l2ZVRoZW1lLmF4aXMueFt0aGlzLnR5cGVdLCBjb25zdHJhaW50cyA9IF9hLmNvbnN0cmFpbnRzLCBydWxlcyA9IF9hLnJ1bGVzO1xuICAgICAgICBuZXcgcmVzcG9uc2l2ZV8xLmRlZmF1bHQoe1xuICAgICAgICAgICAgbm9kZXM6IHNoYXBlTm9kZXMsXG4gICAgICAgICAgICBjb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICByZWdpb246IHRoaXMucGxvdC5nZXRWaWV3UmFuZ2UoKSxcbiAgICAgICAgICAgIHJ1bGVzOiBydWxlcyxcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMucGxvdCxcbiAgICAgICAgICAgIG9uRW5kOiBmdW5jdGlvbiAobm9kZXMpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy51cGRhdGVUaWNrcyhub2Rlcy5vcmlnaW9uX25vZGVzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgQXBwbHlSZXNwb25zaXZlQXhpcy5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wbG90Lm9wdGlvbnM7XG4gICAgICAgIHZhciBheGlzID0gdGhpcy5kaW0gKyBcIkF4aXNcIjtcbiAgICAgICAgdmFyIGZpZWxkID0gdGhpcy5kaW0gKyBcIkZpZWxkXCI7XG4gICAgICAgIGlmIChwcm9wc1theGlzXSAmJiBwcm9wc1theGlzXS50eXBlICYmIHByb3BzW2F4aXNdLnR5cGUgPT09ICdkYXRlVGltZScpIHtcbiAgICAgICAgICAgIHJldHVybiAnZGF0ZVRpbWUnO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzY2FsZVR5cGUgPSB0aGlzLnBsb3Qudmlldy5nZXRTY2FsZUJ5RmllbGQoW3Byb3BzW2ZpZWxkXV0pLnR5cGU7XG4gICAgICAgIHJldHVybiBTQ0FMRV9NQVBQRVJbc2NhbGVUeXBlXTtcbiAgICB9O1xuICAgIEFwcGx5UmVzcG9uc2l2ZUF4aXMucHJvdG90eXBlLmdldEF4aXNJbnN0YW5jZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgdmFyIGF4aXNJbmRleCA9IHRoaXMuZGltID09PSAneCcgPyAwIDogMTtcbiAgICAgICAgdmFyIGNvbXBvbmVudHMgPSAoX2EgPSB0aGlzLnBsb3Qudmlldy5nZXRDb250cm9sbGVyKCdheGlzJykpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5nZXRDb21wb25lbnRzKCk7XG4gICAgICAgIGlmIChjb21wb25lbnRzKSB7XG4gICAgICAgICAgICByZXR1cm4gKF9iID0gY29tcG9uZW50c1theGlzSW5kZXhdKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY29tcG9uZW50O1xuICAgICAgICB9XG4gICAgfTtcbiAgICBBcHBseVJlc3BvbnNpdmVBeGlzLnByb3RvdHlwZS51cGRhdGVUaWNrcyA9IGZ1bmN0aW9uIChub2Rlcykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdGlja0xpbmVDb250YWluZXIgPSB0aGlzLnBsb3Qudmlldy5iYWNrZ3JvdW5kR3JvdXAuZmluZEFsbChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgIHZhciBuYW1lID0gZWwuZ2V0KCduYW1lJyk7XG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gJ2F4aXMtdGlja2xpbmUtZ3JvdXAnKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gZWwuZ2V0KCdkZWxlZ2F0ZU9iamVjdCcpLmF4aXMuZ2V0KCdmaWVsZCcpO1xuICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PT0gX3RoaXMucGxvdC5vcHRpb25zW190aGlzLmRpbSArIFwiRmllbGRcIl0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlbMF07XG4gICAgICAgIGlmICh0aWNrTGluZUNvbnRhaW5lcikge1xuICAgICAgICAgICAgdmFyIHRpY2tTaGFwZXNfMSA9IHRpY2tMaW5lQ29udGFpbmVyLmdldCgnY2hpbGRyZW4nKTtcbiAgICAgICAgICAgIHV0aWxfMS5lYWNoKG5vZGVzLCBmdW5jdGlvbiAobiwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAobi5zaGFwZS5hdHRyKCd0ZXh0JykgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpY2tTaGFwZXNfMVtpbmRleF0uYXR0cignb3BhY2l0eScsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGxvdC5jYW52YXMuZHJhdygpO1xuICAgIH07XG4gICAgcmV0dXJuIEFwcGx5UmVzcG9uc2l2ZUF4aXM7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBcHBseVJlc3BvbnNpdmVBeGlzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXhpcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBBcHBseVJlc3BvbnNpdmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQXBwbHlSZXNwb25zaXZlKGNmZykge1xuICAgICAgICB1dGlsXzEuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cbiAgICBBcHBseVJlc3BvbnNpdmUucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHRoaXMuZ2V0VHlwZSgpO1xuICAgICAgICBpZiAodGhpcy5zaG91bGRBcHBseSgpKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBBcHBseVJlc3BvbnNpdmU7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQXBwbHlSZXNwb25zaXZlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHNoYXBlX25vZGVzXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi4vbm9kZS9zaGFwZS1ub2Rlc1wiKSk7XG52YXIgcmVzcG9uc2l2ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4uL3Jlc3BvbnNpdmVcIikpO1xudmFyIGJhc2VfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2Jhc2VcIikpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIEFwcGx5UmVzcG9uc2l2ZUxhYmVsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKEFwcGx5UmVzcG9uc2l2ZUxhYmVsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEFwcGx5UmVzcG9uc2l2ZUxhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgfVxuICAgIEFwcGx5UmVzcG9uc2l2ZUxhYmVsLnByb3RvdHlwZS5zaG91bGRBcHBseSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlc3BvbnNpdmVUaGVtZS5sYWJlbCB8fCAhdGhpcy5yZXNwb25zaXZlVGhlbWUubGFiZWxbdGhpcy50eXBlXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgQXBwbHlSZXNwb25zaXZlTGFiZWwucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbGFiZWxTaGFwZXNDb250YWluZXIgPSB0aGlzLnBsb3Qudmlldy5nZW9tZXRyaWVzWzBdLmxhYmVsc0NvbnRhaW5lci5nZXQoJ2NoaWxkcmVuJyk7XG4gICAgICAgIHZhciBsYWJlbFNoYXBlcyA9IFtdO1xuICAgICAgICB1dGlsXzEuZWFjaChsYWJlbFNoYXBlc0NvbnRhaW5lciwgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgIGxhYmVsU2hhcGVzID0gbGFiZWxTaGFwZXMuY29uY2F0KGMuZmluZEFsbEJ5TmFtZSgnbGFiZWwnKSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgbm9kZXMgPSBuZXcgc2hhcGVfbm9kZXNfMS5kZWZhdWx0KHtcbiAgICAgICAgICAgIHNoYXBlczogbGFiZWxTaGFwZXMsXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgX2EgPSB0aGlzLnJlc3BvbnNpdmVUaGVtZS5sYWJlbFt0aGlzLnR5cGVdLCBjb25zdHJhaW50cyA9IF9hLmNvbnN0cmFpbnRzLCBydWxlcyA9IF9hLnJ1bGVzO1xuICAgICAgICBuZXcgcmVzcG9uc2l2ZV8xLmRlZmF1bHQoe1xuICAgICAgICAgICAgbm9kZXM6IG5vZGVzLFxuICAgICAgICAgICAgY29uc3RyYWludHM6IGNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgcnVsZXM6IHJ1bGVzLFxuICAgICAgICAgICAgcGxvdDogdGhpcy5wbG90LFxuICAgICAgICAgICAgcmVnaW9uOiB0aGlzLnBsb3Qudmlldy5jb29yZGluYXRlQkJveCxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBBcHBseVJlc3BvbnNpdmVMYWJlbC5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gQXBwbHlSZXNwb25zaXZlTGFiZWw7XG59KGJhc2VfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBBcHBseVJlc3BvbnNpdmVMYWJlbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxhYmVsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZnVuY3Rpb24gY29sdW1uV2lkdGgobm9kZSwgcmVnaW9uLCBjZmcpIHtcbiAgICBpZiAoY2ZnID09PSB2b2lkIDApIHsgY2ZnID0geyByYXRpbzogMC42IH07IH1cbiAgICByZXR1cm4gcmVnaW9uLndpZHRoICogY2ZnLnJhdGlvO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICAgIHR5cGU6ICdwYWRkaW5nJyxcbiAgICB1c2FnZTogJ2Fzc2lnbicsXG4gICAgZXhwcmVzc2lvbjogY29sdW1uV2lkdGgsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29sdW1uLXdpZHRoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgTWF0aFV0aWwgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi4vLi4vbWF0aFwiKSk7XG5mdW5jdGlvbiBlbGVtZW50Q29sbGlzaW9uKGEsIGIpIHtcbiAgICB2YXIgcG9seWdvbkEgPSBbYS50b3BMZWZ0LCBhLnRvcFJpZ2h0LCBhLmJvdHRvbVJpZ2h0LCBhLmJvdHRvbUxlZnRdOyAvLyDpobbngrnpobrml7bpkohcbiAgICB2YXIgcG9seWdvbkIgPSBbYi50b3BMZWZ0LCBiLnRvcFJpZ2h0LCBiLmJvdHRvbVJpZ2h0LCBiLmJvdHRvbUxlZnRdO1xuICAgIHZhciBkaXN0ID0gTWF0aFV0aWwubWluRGlzdEJldHdlZW5Db252ZXhQb2x5Z29uKHBvbHlnb25BLCBwb2x5Z29uQik7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoZGlzdCkgPj0gMjtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICB0eXBlOiAnZ3JvdXAnLFxuICAgIHVzYWdlOiAnY29tcGFyZScsXG4gICAgZXhwcmVzc2lvbjogZWxlbWVudENvbGxpc2lvbixcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbGVtZW50LWNvbGxpc2lvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGVsZW1lbnREaXN0VmVydGljYWwoYSwgYiwgY2ZnKSB7XG4gICAgaWYgKGNmZyA9PT0gdm9pZCAwKSB7IGNmZyA9IHsgdmFsdWU6IDUgfTsgfVxuICAgIHZhciBkaXN0ID0gTWF0aC5hYnMoYS5ib3R0b20gLSBiLnRvcCk7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoZGlzdCkgPj0gY2ZnLnZhbHVlO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICAgIHR5cGU6ICdjaGFpbicsXG4gICAgdXNhZ2U6ICdjb21wYXJlJyxcbiAgICBleHByZXNzaW9uOiBlbGVtZW50RGlzdFZlcnRpY2FsLFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVsZW1lbnQtZGlzdC12ZXJ0aWNhbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIE1hdGhVdGlsID0gdHNsaWJfMS5fX2ltcG9ydFN0YXIocmVxdWlyZShcIi4uLy4uL21hdGhcIikpO1xuZnVuY3Rpb24gZWxlbWVudERpc3QoYSwgYiwgY2ZnKSB7XG4gICAgaWYgKGNmZyA9PT0gdm9pZCAwKSB7IGNmZyA9IHsgdmFsdWU6IDQgfTsgfVxuICAgIHZhciBwb2x5Z29uQSA9IFthLnRvcExlZnQsIGEudG9wUmlnaHQsIGEuYm90dG9tUmlnaHQsIGEuYm90dG9tTGVmdF07IC8vIOmhtueCuemhuuaXtumSiFxuICAgIHZhciBwb2x5Z29uQiA9IFtiLnRvcExlZnQsIGIudG9wUmlnaHQsIGIuYm90dG9tUmlnaHQsIGIuYm90dG9tTGVmdF07XG4gICAgdmFyIGRpc3QgPSBNYXRoVXRpbC5taW5EaXN0QmV0d2VlbkNvbnZleFBvbHlnb24ocG9seWdvbkEsIHBvbHlnb25CKTtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChkaXN0KSA+PSBjZmcudmFsdWU7XG59XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgdHlwZTogJ2NoYWluJyxcbiAgICB1c2FnZTogJ2NvbXBhcmUnLFxuICAgIGV4cHJlc3Npb246IGVsZW1lbnREaXN0LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVsZW1lbnQtZGlzdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGVsZW1lbnRXaWR0aChub2RlLCByZWdpb24sIGNmZykge1xuICAgIGlmIChjZmcgPT09IHZvaWQgMCkgeyBjZmcgPSB7IHJhdGlvOiAwLjE1IH07IH1cbiAgICByZXR1cm4gbm9kZS53aWR0aCA8IHJlZ2lvbi53aWR0aCAqIGNmZy5yYXRpbztcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICB0eXBlOiAncGFkZGluZycsXG4gICAgdXNhZ2U6ICdjb21wYXJlJyxcbiAgICBleHByZXNzaW9uOiBlbGVtZW50V2lkdGgsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxlbWVudC13aWR0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucmVnaXN0ZXJSZXNwb25zaXZlQ29uc3RyYWludCA9IGV4cG9ydHMuY29uc3RyYWludHNMaWIgPSB2b2lkIDA7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBjb2x1bW5fd2lkdGhfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NvbHVtbi13aWR0aFwiKSk7XG52YXIgZWxlbWVudF9jb2xsaXNpb25fMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2VsZW1lbnQtY29sbGlzaW9uXCIpKTtcbnZhciBlbGVtZW50X2Rpc3RfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2VsZW1lbnQtZGlzdFwiKSk7XG52YXIgZWxlbWVudF9kaXN0X3ZlcnRpY2FsXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9lbGVtZW50LWRpc3QtdmVydGljYWxcIikpO1xudmFyIGVsZW1lbnRfd2lkdGhfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2VsZW1lbnQtd2lkdGhcIikpO1xudmFyIG1pbl9yaW5nX3RoaWNrbmVzc18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbWluLXJpbmctdGhpY2tuZXNzXCIpKTtcbnZhciByaW5nX3RoaWNrbmVzc18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vcmluZy10aGlja25lc3NcIikpO1xuZXhwb3J0cy5jb25zdHJhaW50c0xpYiA9IHtcbiAgICBlbGVtZW50RGlzdDogZWxlbWVudF9kaXN0XzEuZGVmYXVsdCxcbiAgICBlbGVtZW50RGlzdFZlcnRpY2FsOiBlbGVtZW50X2Rpc3RfdmVydGljYWxfMS5kZWZhdWx0LFxuICAgIGVsZW1lbnRDb2xsaXNpb246IGVsZW1lbnRfY29sbGlzaW9uXzEuZGVmYXVsdCxcbiAgICBlbGVtZW50V2lkdGg6IGVsZW1lbnRfd2lkdGhfMS5kZWZhdWx0LFxuICAgIGNvbHVtbldpZHRoOiBjb2x1bW5fd2lkdGhfMS5kZWZhdWx0LFxuICAgIHJpbmdUaGlja25lc3M6IHJpbmdfdGhpY2tuZXNzXzEuZGVmYXVsdCxcbiAgICBtaW5SaW5nVGhpY2tuZXNzOiBtaW5fcmluZ190aGlja25lc3NfMS5kZWZhdWx0LFxufTtcbmZ1bmN0aW9uIHJlZ2lzdGVyUmVzcG9uc2l2ZUNvbnN0cmFpbnQobmFtZSwgY29uc3RyYWludCkge1xuICAgIC8vIHRvZG86IOmYsuatouimhuebllxuICAgIGV4cG9ydHMuY29uc3RyYWludHNMaWJbbmFtZV0gPSBjb25zdHJhaW50O1xufVxuZXhwb3J0cy5yZWdpc3RlclJlc3BvbnNpdmVDb25zdHJhaW50ID0gcmVnaXN0ZXJSZXNwb25zaXZlQ29uc3RyYWludDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZnVuY3Rpb24gbWluUmluZ1RoaWNrbmVzcyhub2RlLCByZWdpb24pIHtcbiAgICB2YXIgbWluVGhpY2tuZXNzUGl4ZWwgPSAyO1xuICAgIHZhciBtaW5UaGlja25lc3MgPSByZWdpb24uY29vcmQucmFkaXVzIC8gbWluVGhpY2tuZXNzUGl4ZWw7XG4gICAgcmV0dXJuIE1hdGgubWluKG1pblRoaWNrbmVzcywgbm9kZS52YWx1ZSk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gICAgdHlwZTogJ3BhZGRpbmcnLFxuICAgIHVzYWdlOiAnYXNzaWduJyxcbiAgICBleHByZXNzaW9uOiBtaW5SaW5nVGhpY2tuZXNzLFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbi1yaW5nLXRoaWNrbmVzcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHJpbmdUaGlja25lc3Mobm9kZSwgcmVnaW9uLCBjZmcpIHtcbiAgICBpZiAoY2ZnID09PSB2b2lkIDApIHsgY2ZnID0geyByYXRpbzogMC44IH07IH1cbiAgICByZXR1cm4gcmVnaW9uLnJhZGl1cyAqIGNmZy5yYXRpbztcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgICB0eXBlOiAncGFkZGluZycsXG4gICAgdXNhZ2U6ICdhc3NpZ24nLFxuICAgIGV4cHJlc3Npb246IHJpbmdUaGlja25lc3MsXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmluZy10aGlja25lc3MuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkRFRkFVTFRfUkVTUE9OU0lWRV9USEVNRSA9IHZvaWQgMDtcbi8vIOWtmOWCqOS4gOS6m+WFseeUqOmDqOWIhlxuZXhwb3J0cy5ERUZBVUxUX1JFU1BPTlNJVkVfVEhFTUUgPSB7XG4gICAgYXhpczoge1xuICAgICAgICB4OiB7XG4gICAgICAgICAgICBjYXRlZ29yeToge1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzOiBbeyBuYW1lOiAnZWxlbWVudERpc3QnIH1dLFxuICAgICAgICAgICAgICAgIHJ1bGVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnREaXN0OiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3RleHRXcmFwcGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZU51bWJlcjogMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dFJvdGF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVncmVlOiA0NSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dFJvdGF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVncmVlOiA5MCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dEFiYnJldmlhdGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYmJyZXZpYXRlQnk6ICdlbmQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXh0SGlkZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZWFyOiB7XG4gICAgICAgICAgICAgICAgY29uc3RyYWludHM6IFt7IG5hbWU6ICdlbGVtZW50RGlzdCcgfV0sXG4gICAgICAgICAgICAgICAgcnVsZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudERpc3Q6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbm9kZXNSZXNhbXBsaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcDogWydlbmQnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dFJvdGF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVncmVlOiA0NSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dFJvdGF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVncmVlOiA5MCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAncm9idXN0QWJicmV2YWl0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXQ6ICd0aG91c2FuZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWw6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFiYnJldmlhdGVCeTogJ2VuZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3RleHRIaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkYXRlVGltZToge1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzOiBbeyBuYW1lOiAnZWxlbWVudERpc3QnIH1dLFxuICAgICAgICAgICAgICAgIHJ1bGVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnREaXN0OiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2RhdGV0aW1lU3RyaW5nQWJicmV2YWl0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdub2Rlc1Jlc2FtcGxpbmdCeUFiYnJldmF0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXA6IFsnZW5kJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3RleHRSb3RhdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZ3JlZTogNDUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3RleHRSb3RhdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZ3JlZTogOTAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ25vZGVzUmVzYW1wbGluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdub2Rlc1Jlc2FtcGxpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dEhpZGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgeToge1xuICAgICAgICAgICAgbGluZWFyOiB7XG4gICAgICAgICAgICAgICAgY29uc3RyYWludHM6IFt7IG5hbWU6ICdlbGVtZW50RGlzdFZlcnRpY2FsJyB9LCB7IG5hbWU6ICdlbGVtZW50V2lkdGgnIH1dLFxuICAgICAgICAgICAgICAgIHJ1bGVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnREaXN0VmVydGljYWw6IFt7IG5hbWU6ICdub2Rlc1Jlc2FtcGxpbmcnIH0sIHsgbmFtZTogJ3RleHRIaWRlJyB9XSxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFdpZHRoOiBbeyBuYW1lOiAnZGlnaXRzQWJicmV2aWF0ZScgfSwgeyBuYW1lOiAndGV4dEhpZGUnIH1dLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2F0ZWdvcnk6IHtcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50czogW3sgbmFtZTogJ2VsZW1lbnREaXN0VmVydGljYWwnIH0sIHsgbmFtZTogJ2VsZW1lbnRXaWR0aCcgfV0sXG4gICAgICAgICAgICAgICAgcnVsZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudERpc3RWZXJ0aWNhbDogW3sgbmFtZTogJ25vZGVzUmVzYW1wbGluZycgfSwgeyBuYW1lOiAndGV4dEhpZGUnIH1dLFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50V2lkdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGV4dEFiYnJldmlhdGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYmJyZXZpYXRlQnk6ICdlbmQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAndGV4dEhpZGUnIH0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWZhdWx0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgTWF0aFV0aWwgPSB0c2xpYl8xLl9faW1wb3J0U3RhcihyZXF1aXJlKFwiLi4vLi4vbWF0aFwiKSk7XG52YXIgU2hhcGVOb2RlcyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTaGFwZU5vZGVzKGNmZykge1xuICAgICAgICB0aGlzLnR5cGUgPSAnc2hhcGUnO1xuICAgICAgICB0aGlzLnNoYXBlcyA9IGNmZy5zaGFwZXM7XG4gICAgICAgIHRoaXMubm9kZXMgPSBbXTtcbiAgICAgICAgdGhpcy5fcGFyc2VyTm9kZXMoKTtcbiAgICAgICAgdGhpcy5vcmlnaW9uX25vZGVzID0gdXRpbF8xLmRlZXBNaXgoW10sIHRoaXMubm9kZXMpO1xuICAgIH1cbiAgICBTaGFwZU5vZGVzLnByb3RvdHlwZS5tZWFzdXJlID0gZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBub2RlID0gdXRpbF8xLmRlZXBNaXgoe30sIE1hdGhVdGlsLmJib3hPblJvdGF0ZShzaGFwZSksIHsgc2hhcGU6IHNoYXBlIH0pO1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9O1xuICAgIFNoYXBlTm9kZXMucHJvdG90eXBlLm1lYXN1cmVOb2RlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG5vZGVzID0gW107XG4gICAgICAgIHZhciBzaGFwZXMgPSBbXTtcbiAgICAgICAgdXRpbF8xLmVhY2godGhpcy5zaGFwZXMsIGZ1bmN0aW9uIChzaGFwZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBub2RlID0gdXRpbF8xLmRlZXBNaXgoe30sIF90aGlzLm5vZGVzW2luZGV4XSwgX3RoaXMubWVhc3VyZShzaGFwZSkpO1xuICAgICAgICAgICAgaWYgKG5vZGUud2lkdGggIT09IDAgJiYgbm9kZS5oZWlnaHQgIT09IDApIHtcbiAgICAgICAgICAgICAgICBub2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgICAgIHNoYXBlcy5wdXNoKHNoYXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRoaXMubm9kZXNbaW5kZXhdID0gbm9kZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubm9kZXMgPSBub2RlcztcbiAgICAgICAgdGhpcy5zaGFwZXMgPSBzaGFwZXM7XG4gICAgfTtcbiAgICBTaGFwZU5vZGVzLnByb3RvdHlwZS5fcGFyc2VyTm9kZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRoaXMuc2hhcGVzLCBmdW5jdGlvbiAoc2hhcGUpIHtcbiAgICAgICAgICAgIHZhciBub2RlID0gX3RoaXMubWVhc3VyZShzaGFwZSk7XG4gICAgICAgICAgICBfdGhpcy5ub2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBTaGFwZU5vZGVzO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFNoYXBlTm9kZXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zaGFwZS1ub2Rlcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBpbmRleF8xID0gcmVxdWlyZShcIi4vY29uc3RyYWludHMvaW5kZXhcIik7XG52YXIgaW5kZXhfMiA9IHJlcXVpcmUoXCIuL3J1bGVzL2luZGV4XCIpO1xudmFyIFJlc3BvbnNpdmUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUmVzcG9uc2l2ZShjZmcpIHtcbiAgICAgICAgdGhpcy5pdGVyYXRpb25UaW1lID0gMTA7XG4gICAgICAgIHRoaXMuaXRlcmF0aW9uSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnJ1bGVzTG9ja2VyID0gW107XG4gICAgICAgIHRoaXMuY29uc3RyYWludEluZGV4ID0gMDtcbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLCBjZmcpO1xuICAgICAgICB0aGlzLmN1cnJlbnRDb25zdHJhaW50ID0gdGhpcy5jb25zdHJhaW50c1swXTtcbiAgICAgICAgaWYgKHRoaXMucnVsZXMpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlcmF0aW9uVGltZSA9IHRoaXMucnVsZXNbdGhpcy5jdXJyZW50Q29uc3RyYWludC5uYW1lXS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhcnQoKTtcbiAgICAgICAgdGhpcy5fcnVuKCk7XG4gICAgICAgIHRoaXMuX2VuZCgpO1xuICAgIH1cbiAgICBSZXNwb25zaXZlLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9uU3RhcnQpIHtcbiAgICAgICAgICAgIHRoaXMub25TdGFydCh0aGlzLm5vZGVzKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX2l0ZXJhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVzO1xuICAgICAgICBpZiAodGhpcy5ub2Rlcy50eXBlID09PSAnc2hhcGUnKSB7XG4gICAgICAgICAgICBub2RlcyA9IHRoaXMubm9kZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBub2RlcyA9IHRoaXMubm9kZXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGVzLnR5cGUgPT09ICdzaGFwZScpIHtcbiAgICAgICAgICAgIG5vZGVzLm1lYXN1cmVOb2RlcygpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJ1bGVzKSB7XG4gICAgICAgICAgICB0aGlzLl9hcHBseVJ1bGVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGVzLnR5cGUgPT09ICdzaGFwZScpIHtcbiAgICAgICAgICAgIG5vZGVzLm1lYXN1cmVOb2RlcygpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9uSXRlcmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLm9uSXRlcmF0aW9uKHRoaXMubm9kZXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBSZXNwb25zaXZlLnByb3RvdHlwZS5fZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5vbkVuZCkge1xuICAgICAgICAgICAgdGhpcy5vbkVuZCh0aGlzLm5vZGVzKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX3J1biA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnN0cmFpbnRQYXNzZWQgPSB0aGlzLl9jb25zdHJhaW50c1Rlc3QoKTtcbiAgICAgICAgd2hpbGUgKCFjb25zdHJhaW50UGFzc2VkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pdGVyYXRpb25JbmRleCA+IHRoaXMuaXRlcmF0aW9uVGltZSAtIDEpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGlvbigpO1xuICAgICAgICAgICAgY29uc3RyYWludFBhc3NlZCA9IHRoaXMuX2NvbnN0cmFpbnRzVGVzdCgpO1xuICAgICAgICAgICAgdGhpcy5pdGVyYXRpb25JbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNvbnN0cmFpbnRJbmRleCA8IHRoaXMuY29uc3RyYWludHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5jb25zdHJhaW50SW5kZXgrKztcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENvbnN0cmFpbnQgPSB0aGlzLmNvbnN0cmFpbnRzW3RoaXMuY29uc3RyYWludEluZGV4XTtcbiAgICAgICAgICAgIHRoaXMuaXRlcmF0aW9uVGltZSA9IHRoaXMucnVsZXMgPyB0aGlzLnJ1bGVzW3RoaXMuY3VycmVudENvbnN0cmFpbnQubmFtZV0ubGVuZ3RoIDogMTtcbiAgICAgICAgICAgIHRoaXMuaXRlcmF0aW9uSW5kZXggPSAwO1xuICAgICAgICAgICAgdGhpcy5fcnVuKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJlc3BvbnNpdmUucHJvdG90eXBlLl9jb25zdHJhaW50c1Rlc3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb25zdHJhaW50ID0gaW5kZXhfMS5jb25zdHJhaW50c0xpYlt0aGlzLmN1cnJlbnRDb25zdHJhaW50Lm5hbWVdO1xuICAgICAgICB2YXIgY29uc3RyYWludE9wdGlvbiA9IHRoaXMuY3VycmVudENvbnN0cmFpbnQub3B0aW9uO1xuICAgICAgICBpZiAoY29uc3RyYWludC51c2FnZSA9PT0gJ2NvbXBhcmUnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29uc3RyYWludENvbXBhcmUoY29uc3RyYWludCwgY29uc3RyYWludE9wdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnN0cmFpbnRBc3NpZ25tZW50KGNvbnN0cmFpbnQsIGNvbnN0cmFpbnRPcHRpb24pO1xuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX2NvbnN0cmFpbnRDb21wYXJlID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQsIG9wdGlvbikge1xuICAgICAgICB2YXIgdHlwZSA9IGNvbnN0cmFpbnQudHlwZSwgZXhwcmVzc2lvbiA9IGNvbnN0cmFpbnQuZXhwcmVzc2lvbjtcbiAgICAgICAgdmFyIG5vZGVzID0gdGhpcy5ub2Rlcy5ub2RlcztcbiAgICAgICAgaWYgKHR5cGUgPT09ICdjaGFpbicpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jaGFpbkNvbnN0cmFpbnRDb21wYXJlKGV4cHJlc3Npb24sIG5vZGVzLCBvcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncGFkZGluZycpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYWRkaW5nQ29uc3RyYWludENvbXBhcmUoZXhwcmVzc2lvbiwgdGhpcy5yZWdpb24sIG5vZGVzLCBvcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnZ3JvdXAnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ3JvdXBDb25zdHJhaW50Q29tcGFyZShleHByZXNzaW9uLCBub2Rlcywgb3B0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX2NoYWluQ29uc3RyYWludENvbXBhcmUgPSBmdW5jdGlvbiAoZXhwcmVzc2lvbiwgbm9kZXMsIG9wdGlvbikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgdmFyIGEgPSBub2Rlc1tpXTtcbiAgICAgICAgICAgIHZhciBiID0gbm9kZXNbaSArIDFdO1xuICAgICAgICAgICAgaWYgKGV4cHJlc3Npb24oYSwgYiwgb3B0aW9uKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICBSZXNwb25zaXZlLnByb3RvdHlwZS5fcGFkZGluZ0NvbnN0cmFpbnRDb21wYXJlID0gZnVuY3Rpb24gKGV4cHJlc3Npb24sIHJlZ2lvbiwgbm9kZXMsIG9wdGlvbikge1xuICAgICAgICBpZiAocmVnaW9uKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIG5vZGVzXzEgPSBub2RlczsgX2kgPCBub2Rlc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBub2RlID0gbm9kZXNfMVtfaV07XG4gICAgICAgICAgICAgICAgaWYgKGV4cHJlc3Npb24obm9kZSwgcmVnaW9uLCBvcHRpb24pID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX2dyb3VwQ29uc3RyYWludENvbXBhcmUgPSBmdW5jdGlvbiAoZXhwcmVzc2lvbiwgbm9kZXMsIG9wdGlvbikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgYSA9IG5vZGVzW2ldO1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBub2Rlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIGlmIChqICE9PSBpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBiID0gbm9kZXNbal07XG4gICAgICAgICAgICAgICAgICAgIGlmIChleHByZXNzaW9uKGEsIGIsIG9wdGlvbikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICBSZXNwb25zaXZlLnByb3RvdHlwZS5fY29uc3RyYWludEFzc2lnbm1lbnQgPSBmdW5jdGlvbiAoY29uc3RyYWludCwgb3B0aW9uKSB7XG4gICAgICAgIHZhciB0eXBlID0gY29uc3RyYWludC50eXBlLCBleHByZXNzaW9uID0gY29uc3RyYWludC5leHByZXNzaW9uO1xuICAgICAgICB2YXIgbm9kZXMgPSB0aGlzLm5vZGVzLm5vZGVzO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2NoYWluJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NoYWluQ29uc3RyYWludEFzc2lnbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncGFkZGluZycpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYWRkaW5nQ29uc3RyYWludEFzc2lnbihleHByZXNzaW9uLCB0aGlzLnJlZ2lvbiwgbm9kZXMsIG9wdGlvbik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJlc3BvbnNpdmUucHJvdG90eXBlLl9jaGFpbkNvbnN0cmFpbnRBc3NpZ24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX3BhZGRpbmdDb25zdHJhaW50QXNzaWduID0gZnVuY3Rpb24gKGV4cHJlc3Npb24sIHJlZ2lvbiwgbm9kZXMsIG9wdGlvbikge1xuICAgICAgICBpZiAocmVnaW9uKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIG5vZGVzXzIgPSBub2RlczsgX2kgPCBub2Rlc18yLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBub2RlID0gbm9kZXNfMltfaV07XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gZXhwcmVzc2lvbihub2RlLCByZWdpb24sIG9wdGlvbik7XG4gICAgICAgICAgICAgICAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgUmVzcG9uc2l2ZS5wcm90b3R5cGUuX2FwcGx5UnVsZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBydWxlQ2ZnID0gdGhpcy5ydWxlc1t0aGlzLmN1cnJlbnRDb25zdHJhaW50Lm5hbWVdW3RoaXMuaXRlcmF0aW9uSW5kZXhdO1xuICAgICAgICAvLyBpZiAodGhpcy5ydWxlc0xvY2tlci5pbmRleE9mKHJ1bGVDZmcpIDwgMCkge1xuICAgICAgICB2YXIgcnVsZSA9IGluZGV4XzIucnVsZXNMaWJbcnVsZUNmZy5uYW1lXTtcbiAgICAgICAgdmFyIG9wdGlvbiA9IHJ1bGVDZmcub3B0aW9uID8gcnVsZUNmZy5vcHRpb24gOiB7fTtcbiAgICAgICAgdmFyIG5vZGVzID0gdGhpcy5ub2Rlcy5ub2RlcztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgICAgIC8qKiBhcHBseSBydWxl5LiK5LiL5paHICovXG4gICAgICAgICAgICB0aGlzLl9hcHBseVJ1bGUobm9kZS5zaGFwZSwgcnVsZSwgb3B0aW9uLCBpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGlzLnJ1bGVzTG9ja2VyLnB1c2gocnVsZUNmZyk7XG4gICAgICAgIC8vIH1cbiAgICB9O1xuICAgIFJlc3BvbnNpdmUucHJvdG90eXBlLl9hcHBseVJ1bGUgPSBmdW5jdGlvbiAoc2hhcGUsIHJ1bGUsIG9wdGlvbiwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGNmZyA9IHtcbiAgICAgICAgICAgIG5vZGVzOiB0aGlzLm5vZGVzLFxuICAgICAgICAgICAgcmVnaW9uOiB0aGlzLnJlZ2lvbixcbiAgICAgICAgICAgIHBsb3Q6IHRoaXMucGxvdCxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gcnVsZShzaGFwZSwgb3B0aW9uLCBpbmRleCwgdGhpcyk7XG4gICAgICAgIHJ1bGUoc2hhcGUsIG9wdGlvbiwgaW5kZXgsIGNmZyk7XG4gICAgfTtcbiAgICByZXR1cm4gUmVzcG9uc2l2ZTtcbn0oKSk7XG5leHBvcnRzLmRlZmF1bHQgPSBSZXNwb25zaXZlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVzcG9uc2l2ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaXNOb2RlT3ZlcmxhcCA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHRleHRfaGlkZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdGV4dC1oaWRlXCIpKTtcbmZ1bmN0aW9uIGNsZWFyT3ZlcmxhcHBpbmcoc2hhcGUsIG9wdGlvbiwgaW5kZXgsIGNmZykge1xuICAgIHZhciBub2RlcyA9IGNmZy5ub2Rlcy5ub2RlcztcbiAgICB2YXIgY3VycmVudCA9IG5vZGVzW2luZGV4XTtcbiAgICB2YXIgb3ZlcmxhcHBlZCA9IFtdO1xuICAgIC8qKiDmib7liLDmiYDmnInkuI7lvZPliY3ngrlvdmVybGFw55qEbm9kZSAqL1xuICAgIGlmICghY3VycmVudC5zaGFwZS5nZXQoJ2JsYW5rJykpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgICAgIHZhciBfc2hhcGUgPSBub2RlLnNoYXBlO1xuICAgICAgICAgICAgaWYgKGkgIT09IGluZGV4ICYmICFfc2hhcGUuZ2V0KCdibGFuaycpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGlzT3ZlcmxhcCA9IGlzTm9kZU92ZXJsYXAoY3VycmVudCwgbm9kZSk7XG4gICAgICAgICAgICAgICAgaWYgKGlzT3ZlcmxhcCkge1xuICAgICAgICAgICAgICAgICAgICBvdmVybGFwcGVkLnB1c2gobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKiBvdmVybGFw5aSE55CG6YC76L6RICovXG4gICAgaWYgKG92ZXJsYXBwZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBvdmVybGFwcGVkLnB1c2goY3VycmVudCk7XG4gICAgICAgIG92ZXJsYXBwZWQuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgcmV0dXJuIGIudG9wIC0gYS50b3A7XG4gICAgICAgIH0pO1xuICAgICAgICAvKiog6ZqQ6JeP6Zmk5pyA6auY54K55Lul5aSW55qEbm9kZSAqL1xuICAgICAgICB1dGlsXzEuZWFjaChvdmVybGFwcGVkLCBmdW5jdGlvbiAobm9kZSwgaWR4KSB7XG4gICAgICAgICAgICBpZiAoaWR4ID4gMCkge1xuICAgICAgICAgICAgICAgIHZhciBfc2hhcGUgPSBub2RlLnNoYXBlO1xuICAgICAgICAgICAgICAgIHRleHRfaGlkZV8xLmRlZmF1bHQoX3NoYXBlKTtcbiAgICAgICAgICAgICAgICBfc2hhcGUuc2V0KCdibGFuaycsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnRzLmRlZmF1bHQgPSBjbGVhck92ZXJsYXBwaW5nO1xuZnVuY3Rpb24gaXNOb2RlT3ZlcmxhcChub2RlQSwgbm9kZUIpIHtcbiAgICBpZiAobm9kZUEuYm90dG9tIDwgbm9kZUIudG9wIHx8IG5vZGVCLmJvdHRvbSA8IG5vZGVBLnRvcCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChub2RlQS5yaWdodCA8IG5vZGVCLmxlZnQgfHwgbm9kZUIucmlnaHQgPCBub2RlQS5sZWZ0KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5leHBvcnRzLmlzTm9kZU92ZXJsYXAgPSBpc05vZGVPdmVybGFwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xlYXItb3ZlcmxhcHBpbmcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmlzVGltZSA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGZlY2hhXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiZmVjaGFcIikpO1xudmFyIFNFQ09ORCA9IDEwMDA7XG52YXIgTUlOVVRFID0gNjAgKiBTRUNPTkQ7XG52YXIgSE9VUiA9IDYwICogTUlOVVRFO1xudmFyIERBWSA9IDI0ICogSE9VUjtcbnZhciBNT05USCA9IDMxICogREFZO1xudmFyIFlFQVIgPSAzNjUgKiBEQVk7XG5mdW5jdGlvbiBkYXRldGltZVN0cmluZ0FiYnJldmFpdGUoc2hhcGUsIG9wdGlvbiwgaW5kZXgsIGNmZykge1xuICAgIHZhciBub2RlcyA9IGNmZy5ub2Rlcy5ub2RlcztcbiAgICB2YXIgY2FtcGFyZVRleHQ7XG4gICAgaWYgKGluZGV4ID09PSBub2Rlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGNhbXBhcmVUZXh0ID0gbm9kZXNbaW5kZXggLSAxXS5zaGFwZS5nZXQoJ2RlbGVnYXRlT2JqZWN0JykuaXRlbS5uYW1lO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY2FtcGFyZVRleHQgPSBub2Rlc1tpbmRleCArIDFdLnNoYXBlLmdldCgnZGVsZWdhdGVPYmplY3QnKS5pdGVtLm5hbWU7XG4gICAgfVxuICAgIHZhciBjb21wYXJlID0gbmV3IERhdGUoY2FtcGFyZVRleHQpO1xuICAgIC8qKiDojrflj5bml7bpl7TlkajmnJ/lkozml7bpl7Tpl7TpmpQgKi9cbiAgICB2YXIgdGV4dCA9IHNoYXBlLmdldCgnZGVsZWdhdGVPYmplY3QnKS5pdGVtLm5hbWU7XG4gICAgdmFyIGN1cnJlbnQgPSBuZXcgRGF0ZSh0ZXh0KTtcbiAgICB2YXIgc3RhcnRUZXh0ID0gbm9kZXNbMF0uc2hhcGUuZ2V0KCdkZWxlZ2F0ZU9iamVjdCcpLml0ZW0ubmFtZTtcbiAgICB2YXIgc3RhcnQgPSBuZXcgRGF0ZShzdGFydFRleHQpO1xuICAgIHZhciBlbmRUZXh0ID0gbm9kZXNbbm9kZXMubGVuZ3RoIC0gMV0uc2hhcGUuZ2V0KCdkZWxlZ2F0ZU9iamVjdCcpLml0ZW0ubmFtZTtcbiAgICB2YXIgZW5kID0gbmV3IERhdGUoZW5kVGV4dCk7XG4gICAgdmFyIHRpbWVEdXJhdGlvbiA9IGdldERhdGVUaW1lTW9kZShzdGFydCwgZW5kKTtcbiAgICB2YXIgdGltZUN5Y2xlID0gZ2V0RGF0ZVRpbWVNb2RlKGN1cnJlbnQsIGNvbXBhcmUpOyAvLyB0aW1lIGZyZXF1ZW5jeVxuICAgIC8vIOWmguaenGR1cmF0aW9u5ZKMZnJlcXVlbmN55Zyo5ZCM5LiA5Yy66Ze0XG4gICAgaWYgKHRpbWVEdXJhdGlvbiA9PT0gdGltZUN5Y2xlKSB7XG4gICAgICAgIGlmIChpbmRleCAhPT0gMCAmJiBpbmRleCAhPT0gbm9kZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IHNhbWVTZWN0aW9uRm9ybWF0dGVyKHRpbWVEdXJhdGlvbik7XG4gICAgICAgICAgICBzaGFwZS5hdHRyKCd0ZXh0JywgZmVjaGFfMS5kZWZhdWx0LmZvcm1hdChjdXJyZW50LCBmb3JtYXR0ZXIpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpbmRleCAhPT0gMCkge1xuICAgICAgICB2YXIgcHJldmlvdXNUZXh0ID0gbm9kZXNbaW5kZXggLSAxXS5zaGFwZS5nZXQoJ2RlbGVnYXRlT2JqZWN0JykuaXRlbS5uYW1lO1xuICAgICAgICB2YXIgcHJldmlvdXMgPSBuZXcgRGF0ZShwcmV2aW91c1RleHQpO1xuICAgICAgICB2YXIgaXNBYmJyZXZpYXRlID0gbmVlZEFiYnJldmFpdGUodGltZUR1cmF0aW9uLCBjdXJyZW50LCBwcmV2aW91cyk7XG4gICAgICAgIGlmIChpc0FiYnJldmlhdGUpIHtcbiAgICAgICAgICAgIHZhciBmb3JtYXR0ZXIgPSBnZXRBYmJyZXZhaXRlRm9ybWF0dGVyKHRpbWVEdXJhdGlvbiwgdGltZUN5Y2xlKTtcbiAgICAgICAgICAgIHNoYXBlLmF0dHIoJ3RleHQnLCBmZWNoYV8xLmRlZmF1bHQuZm9ybWF0KGN1cnJlbnQsIGZvcm1hdHRlcikpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy5kZWZhdWx0ID0gZGF0ZXRpbWVTdHJpbmdBYmJyZXZhaXRlO1xuZnVuY3Rpb24gbmVlZEFiYnJldmFpdGUobW9kZSwgY3VycmVudCwgcHJldmlvdXMpIHtcbiAgICB2YXIgY3VycmVudFN0YW1wID0gZ2V0VGltZShjdXJyZW50LCBtb2RlKTtcbiAgICB2YXIgcHJldmlvdXNTdGFtcCA9IGdldFRpbWUocHJldmlvdXMsIG1vZGUpO1xuICAgIGlmIChjdXJyZW50U3RhbXAgIT09IHByZXZpb3VzU3RhbXApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGdldERhdGVUaW1lTW9kZShhLCBiKSB7XG4gICAgdmFyIG1vZGU7XG4gICAgdmFyIGRpc3QgPSBNYXRoLmFicyhhIC0gYik7XG4gICAgdmFyIG1hcHBlciA9IHtcbiAgICAgICAgbWludXRlOiBbTUlOVVRFLCBIT1VSXSxcbiAgICAgICAgaG91cjogW0hPVVIsIERBWV0sXG4gICAgICAgIGRheTogW0RBWSwgTU9OVEhdLFxuICAgICAgICBtb250aDogW01PTlRILCBZRUFSXSxcbiAgICAgICAgeWVhcjogW1lFQVIsIEluZmluaXR5XSxcbiAgICB9O1xuICAgIHV0aWxfMS5lYWNoKG1hcHBlciwgZnVuY3Rpb24gKHJhbmdlLCBrZXkpIHtcbiAgICAgICAgaWYgKGRpc3QgPj0gcmFuZ2VbMF0gJiYgZGlzdCA8IHJhbmdlWzFdKSB7XG4gICAgICAgICAgICBtb2RlID0ga2V5O1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGU7XG59XG5mdW5jdGlvbiBnZXRBYmJyZXZhaXRlRm9ybWF0dGVyKGR1cmF0aW9uLCBjeWNsZSkge1xuICAgIHZhciB0aW1lcyA9IFsneWVhcicsICdtb250aCcsICdkYXknLCAnaG91cicsICdtaW51dGUnXTtcbiAgICB2YXIgZm9ybWF0dGVycyA9IFsnWVlZWScsICdNTScsICdERCcsICdISCcsICdNTSddO1xuICAgIHZhciBzdGFydEluZGV4ID0gdGltZXMuaW5kZXhPZihkdXJhdGlvbikgKyAxO1xuICAgIHZhciBlbmRJbmRleCA9IHRpbWVzLmluZGV4T2YoY3ljbGUpO1xuICAgIHZhciBmb3JtYXR0ZXIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gc3RhcnRJbmRleDsgaSA8PSBlbmRJbmRleDsgaSsrKSB7XG4gICAgICAgIGZvcm1hdHRlciArPSBmb3JtYXR0ZXJzW2ldO1xuICAgICAgICBpZiAoaSA8IGVuZEluZGV4KSB7XG4gICAgICAgICAgICBmb3JtYXR0ZXIgKz0gJy0nO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZXI7XG59XG5mdW5jdGlvbiBzYW1lU2VjdGlvbkZvcm1hdHRlcihtb2RlKSB7XG4gICAgdmFyIHRpbWVzID0gWyd5ZWFyJywgJ21vbnRoJywgJ2RheScsICdob3VyJywgJ21pbnV0ZSddO1xuICAgIHZhciBmb3JtYXR0ZXJzID0gWydZWVlZJywgJ01NJywgJ0REJywgJ0hIJywgJ01NJ107XG4gICAgdmFyIGluZGV4ID0gdGltZXMuaW5kZXhPZihtb2RlKTtcbiAgICB2YXIgZm9ybWF0dGVyID0gZm9ybWF0dGVyc1tpbmRleF07XG4gICAgcmV0dXJuIGZvcm1hdHRlcjtcbn1cbmZ1bmN0aW9uIGdldFRpbWUoZGF0ZSwgbW9kZSkge1xuICAgIGlmIChtb2RlID09PSAneWVhcicpIHtcbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICB9XG4gICAgaWYgKG1vZGUgPT09ICdtb250aCcpIHtcbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0TW9udGgoKSArIDE7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAnZGF5Jykge1xuICAgICAgICByZXR1cm4gZGF0ZS5nZXREYXkoKSArIDE7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAnaG91cicpIHtcbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKSArIDE7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAnbWludXRlJykge1xuICAgICAgICByZXR1cm4gZGF0ZS5nZXRNaW51dGVzKCkgKyAxO1xuICAgIH1cbn1cbi8qdHNsaW50OmRpc2FibGUqL1xuZnVuY3Rpb24gaXNUaW1lKHN0cmluZykge1xuICAgIHZhciBob3VybWluRXhwID0gL14oPzooPzpbMC0yXVswLTNdKXwoPzpbMDFdXFxkKSk6WzAtNV1cXGQkLztcbiAgICB2YXIgaG91cm1pblNlY0V4cCA9IC9eKD86KD86WzAtMl1bMC0zXSl8KD86WzAxXVxcZCkpKD86OlswLTVdXFxkKXsyfSQvO1xuICAgIHJldHVybiBob3VybWluRXhwLnRlc3Qoc3RyaW5nKSB8fCBob3VybWluU2VjRXhwLnRlc3Qoc3RyaW5nKTtcbn1cbmV4cG9ydHMuaXNUaW1lID0gaXNUaW1lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0ZXRpbWUtc3RyaW5nLWFiYnJldmFpdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgbWF0aF8xID0gcmVxdWlyZShcIi4uLy4uL21hdGhcIik7XG52YXIgdW5pdE1hcHBlciA9IHtcbiAgICBrOiB7IG51bWJlcjogMWUzLCBpbmRleDogMCB9LFxuICAgIG06IHsgbnVtYmVyOiAxZTYsIGluZGV4OiAxIH0sXG4gICAgYjogeyBudW1iZXI6IDFlOSwgaW5kZXg6IDIgfSxcbiAgICB0OiB7IG51bWJlcjogMWUxMiwgaW5kZXg6IDMgfSxcbn07XG4vLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9NYXJ0aW5NdXphdGtvLzEwNjBmZTU4NGQxN2M3YjljYTZlXG4vLyBodHRwczovL2pidXJyb3dzLndvcmRwcmVzcy5jb20vMjAxNC8xMS8xOC9hYmJyZXZpYXRpbmctbnVtYmVycy9cbi8qdHNsaW50OmRpc2FibGUqL1xuZnVuY3Rpb24gZGlnaXRzQWJicmV2aWF0ZShzaGFwZSwgb3B0aW9uLCBpbmRleCwgY2ZnKSB7XG4gICAgaWYgKCF1dGlsXzEuaGFzKGNmZywgJ25vZGUnKSB8fCAhdXRpbF8xLmhhcyhjZmcubm9kZSwgJ25vZGUnKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBub2RlcyA9IGNmZy5ub2Rlcy5ub2RlcztcbiAgICB2YXIgbnVtYmVyID0gcGFyc2VGbG9hdChzaGFwZS5nZXQoJ29yaWdpbicpLnRleHQpO1xuICAgIGlmIChudW1iZXIgPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAob3B0aW9uLmZvcm1hdHRlcikge1xuICAgICAgICBzaGFwZS5hdHRyKCd0ZXh0Jywgb3B0aW9uLmZvcm1hdHRlcihudW1iZXIpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAob3B0aW9uLnVuaXQpIHtcbiAgICAgICAgdmFyIF9hID0gYWJicmF2YXRlRGlnaXRzQnlVbml0KG9wdGlvbiwgbnVtYmVyKSwgbnVtID0gX2EubnVtLCB1bml0bmFtZSA9IF9hLnVuaXRuYW1lO1xuICAgICAgICBzaGFwZS5hdHRyKCd0ZXh0JywgbnVtICsgdW5pdG5hbWUpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g6Ieq5Yqo5o2i566X6YC76L6RXG4gICAgICAgIC8vIOagueaNruS4reS9jeaVsOW+l+WIsOaNoueul+WNleS9jVxuICAgICAgICB2YXIgbnVtYmVycyA9IGV4dHJhY3ROdW1iZXJzKG5vZGVzKTtcbiAgICAgICAgdmFyIG1lZGlhbiA9IG1hdGhfMS5nZXRNZWRpYW4obnVtYmVycyk7XG4gICAgICAgIHZhciB1bml0bmFtZSA9IGdldFVuaXRCeU51bWJlcihtZWRpYW4pO1xuICAgICAgICAvL+agueaNruaVsOWAvOeahGludGVydmFs6K6h566X5o2i566X5ZCO5L+d55WZ55qE5rWu54K55pWwXG4gICAgICAgIHZhciB1bml0TnVtYmVyID0gdW5pdE1hcHBlclt1bml0bmFtZV0ubnVtYmVyO1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSBnZXRMaW5lYXJOb2Rlc0ludGVydmFsKG5vZGVzKTtcbiAgICAgICAgdmFyIGRlY2ltYWwgPSBnZXREaWdpdHNEZWNpbWFsKGludGVydmFsLCB1bml0TnVtYmVyKTtcbiAgICAgICAgdmFyIG51bSA9IGFiYnJhdmF0ZURpZ2l0c0J5VW5pdCh7IHVuaXQ6IHVuaXRuYW1lLCBkZWNpbWFsOiBkZWNpbWFsIH0sIG51bWJlcikubnVtO1xuICAgICAgICBzaGFwZS5hdHRyKCd0ZXh0JywgbnVtICsgdW5pdG5hbWUpO1xuICAgIH1cbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGRpZ2l0c0FiYnJldmlhdGU7XG5mdW5jdGlvbiBhYmJyYXZhdGVEaWdpdHNCeVVuaXQob3B0aW9uLCBudW1iZXIpIHtcbiAgICB2YXIgdW5pdHMgPSBbJ2snLCAnbScsICdiJywgJ3QnXTtcbiAgICB2YXIgbnVtO1xuICAgIHZhciB1bml0bmFtZTtcbiAgICBpZiAob3B0aW9uLnVuaXQgPT09ICdhdXRvJykge1xuICAgICAgICAvKiogYXV0byBmb3JtYXR0IGstbS1iLXQgKi9cbiAgICAgICAgdmFyIG9yZGVyID0gTWF0aC5mbG9vcihNYXRoLmxvZyhudW1iZXIpIC8gTWF0aC5sb2coMTAwMCkpO1xuICAgICAgICB1bml0bmFtZSA9IHVuaXRzW29yZGVyIC0gMV07XG4gICAgICAgIG51bSA9IChudW1iZXIgLyBNYXRoLnBvdygxMDAwLCBvcmRlcikpLnRvRml4ZWQob3B0aW9uLmRlY2ltYWwpO1xuICAgIH1cbiAgICBlbHNlIGlmIChvcHRpb24udW5pdCkge1xuICAgICAgICB2YXIgdW5pdCA9IHVuaXRNYXBwZXJbb3B0aW9uLnVuaXRdO1xuICAgICAgICB1bml0bmFtZSA9IG9wdGlvbi51bml0O1xuICAgICAgICBudW0gPSAobnVtYmVyIC8gdW5pdC5udW1iZXIpLnRvRml4ZWQob3B0aW9uLmRlY2ltYWwpO1xuICAgIH1cbiAgICByZXR1cm4geyBudW06IG51bSwgdW5pdG5hbWU6IHVuaXRuYW1lIH07XG59XG5mdW5jdGlvbiBnZXRVbml0QnlOdW1iZXIobnVtYmVyKSB7XG4gICAgdmFyIHVuaXRzID0gWydrJywgJ20nLCAnYicsICd0J107XG4gICAgdmFyIG9yZGVyID0gTWF0aC5mbG9vcihNYXRoLmxvZyhudW1iZXIpIC8gTWF0aC5sb2coMTAwMCkpO1xuICAgIHJldHVybiB1bml0c1tvcmRlciAtIDFdO1xufVxuZnVuY3Rpb24gZXh0cmFjdE51bWJlcnMobm9kZXMpIHtcbiAgICB2YXIgbnVtYmVycyA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKG5vZGVzLCBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICB2YXIgbiA9IG5vZGU7XG4gICAgICAgIHZhciBudW1iZXIgPSBwYXJzZUZsb2F0KG4uc2hhcGUuZ2V0KCdvcmlnaW4nKS50ZXh0KTtcbiAgICAgICAgbnVtYmVycy5wdXNoKG51bWJlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuIG51bWJlcnM7XG59XG5mdW5jdGlvbiBnZXRMaW5lYXJOb2Rlc0ludGVydmFsKG5vZGVzKSB7XG4gICAgaWYgKG5vZGVzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgIHZhciBhID0gcGFyc2VGbG9hdChub2Rlc1swXS5zaGFwZS5nZXQoJ29yaWdpbicpLnRleHQpO1xuICAgICAgICB2YXIgYiA9IHBhcnNlRmxvYXQobm9kZXNbMV0uc2hhcGUuZ2V0KCdvcmlnaW4nKS50ZXh0KTtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG5mdW5jdGlvbiBnZXREaWdpdHNEZWNpbWFsKGludGVydmFsLCB1bml0TnVtYmVyKSB7XG4gICAgdmFyIHVuaXRCaXQgPSBNYXRoLmZsb29yKE1hdGgubG9nMTAodW5pdE51bWJlcikpO1xuICAgIGlmIChpbnRlcnZhbCA+PSB1bml0TnVtYmVyKSB7XG4gICAgICAgIHZhciByZW1haW5kZXIgPSBpbnRlcnZhbCAlIHVuaXROdW1iZXI7XG4gICAgICAgIGlmIChyZW1haW5kZXIgPiAwKSB7XG4gICAgICAgICAgICB2YXIgcmVtYWluZGVyQml0ID0gTWF0aC5mbG9vcihNYXRoLmxvZzEwKHJlbWFpbmRlcikpO1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHJlbWFpbmRlckJpdCAtIHVuaXRCaXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgaW50ZXJ2YWxCaXQgPSBNYXRoLmZsb29yKE1hdGgubG9nMTAoaW50ZXJ2YWwpKTtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKGludGVydmFsQml0IC0gdW5pdEJpdCk7XG4gICAgfVxuICAgIHJldHVybiAwO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGlnaXRzLWFiYnJldmlhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyUmVzcG9uc2l2ZVJ1bGUgPSBleHBvcnRzLnJ1bGVzTGliID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgY2xlYXJfb3ZlcmxhcHBpbmdfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL2NsZWFyLW92ZXJsYXBwaW5nXCIpKTtcbnZhciBkYXRldGltZV9zdHJpbmdfYWJicmV2YWl0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZGF0ZXRpbWUtc3RyaW5nLWFiYnJldmFpdGVcIikpO1xudmFyIGRpZ2l0c19hYmJyZXZpYXRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9kaWdpdHMtYWJicmV2aWF0ZVwiKSk7XG52YXIgbm9kZV9qaXR0ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL25vZGUtaml0dGVyXCIpKTtcbnZhciBub2RlX2ppdHRlcl91cHdhcmRfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL25vZGUtaml0dGVyLXVwd2FyZFwiKSk7XG52YXIgbm9kZXNfcmVzYW1wbGluZ18xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbm9kZXMtcmVzYW1wbGluZ1wiKSk7XG52YXIgbm9kZXNfcmVzYW1wbGluZ19ieV9hYmJyZXZhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL25vZGVzLXJlc2FtcGxpbmctYnktYWJicmV2YXRlXCIpKTtcbnZhciBub2Rlc19yZXNhbXBsaW5nX2J5X2NoYW5nZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vbm9kZXMtcmVzYW1wbGluZy1ieS1jaGFuZ2VcIikpO1xudmFyIG5vZGVzX3Jlc2FtcGxpbmdfYnlfc3RhdGVfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL25vZGVzLXJlc2FtcGxpbmctYnktc3RhdGVcIikpO1xudmFyIHJvYnVzdF9hYmJyZXZhaXRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi9yb2J1c3QtYWJicmV2YWl0ZVwiKSk7XG52YXIgdGV4dF9hYmJyZXZpYXRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi90ZXh0LWFiYnJldmlhdGVcIikpO1xudmFyIHRleHRfaGlkZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdGV4dC1oaWRlXCIpKTtcbnZhciB0ZXh0X3JvdGF0aW9uXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi90ZXh0LXJvdGF0aW9uXCIpKTtcbnZhciB0ZXh0X3dyYXBwZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCIuL3RleHQtd3JhcHBlclwiKSk7XG5leHBvcnRzLnJ1bGVzTGliID0ge1xuICAgIHRleHRXcmFwcGVyOiB0ZXh0X3dyYXBwZXJfMS5kZWZhdWx0LFxuICAgIHRleHRSb3RhdGlvbjogdGV4dF9yb3RhdGlvbl8xLmRlZmF1bHQsXG4gICAgdGV4dEFiYnJldmlhdGU6IHRleHRfYWJicmV2aWF0ZV8xLmRlZmF1bHQsXG4gICAgdGV4dEhpZGU6IHRleHRfaGlkZV8xLmRlZmF1bHQsXG4gICAgZGlnaXRzQWJicmV2aWF0ZTogZGlnaXRzX2FiYnJldmlhdGVfMS5kZWZhdWx0LFxuICAgIGRhdGV0aW1lU3RyaW5nQWJicmV2YWl0ZTogZGF0ZXRpbWVfc3RyaW5nX2FiYnJldmFpdGVfMS5kZWZhdWx0LFxuICAgIHJvYnVzdEFiYnJldmFpdGU6IHJvYnVzdF9hYmJyZXZhaXRlXzEuZGVmYXVsdCxcbiAgICBub2Rlc1Jlc2FtcGxpbmc6IG5vZGVzX3Jlc2FtcGxpbmdfMS5kZWZhdWx0LFxuICAgIG5vZGVzUmVzYW1wbGluZ0J5QWJicmV2YXRlOiBub2Rlc19yZXNhbXBsaW5nX2J5X2FiYnJldmF0ZV8xLmRlZmF1bHQsXG4gICAgbm9kZXNSZXNhbXBsaW5nQnlDaGFuZ2U6IG5vZGVzX3Jlc2FtcGxpbmdfYnlfY2hhbmdlXzEuZGVmYXVsdCxcbiAgICBub2Rlc1Jlc2FtcGxpbmdCeVN0YXRlOiBub2Rlc19yZXNhbXBsaW5nX2J5X3N0YXRlXzEuZGVmYXVsdCxcbiAgICBub2RlSml0dGVyOiBub2RlX2ppdHRlcl8xLmRlZmF1bHQsXG4gICAgbm9kZUppdHRlclVwd2FyZDogbm9kZV9qaXR0ZXJfdXB3YXJkXzEuZGVmYXVsdCxcbiAgICBjbGVhck92ZXJsYXBwaW5nOiBjbGVhcl9vdmVybGFwcGluZ18xLmRlZmF1bHQsXG59O1xuZnVuY3Rpb24gcmVnaXN0ZXJSZXNwb25zaXZlUnVsZShuYW1lLCBtZXRob2QpIHtcbiAgICAvLyB0b2RvOiDpmLLmraLopobnm5ZcbiAgICBleHBvcnRzLnJ1bGVzTGliW25hbWVdID0gbWV0aG9kO1xufVxuZXhwb3J0cy5yZWdpc3RlclJlc3BvbnNpdmVSdWxlID0gcmVnaXN0ZXJSZXNwb25zaXZlUnVsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNsZWFyX292ZXJsYXBwaW5nXzEgPSByZXF1aXJlKFwiLi9jbGVhci1vdmVybGFwcGluZ1wiKTtcbi8qKiDlm77lvaLlkJHkuIrmipblvIDlubbmi4nnur8gKi9cbi8vIHRvZG8g5YWB6K646K6+572ub2Zmc2V05ZKM5ouJ57q/5qC35byPXG5mdW5jdGlvbiBub2RlSml0dGVyVXB3YXJkKHNoYXBlLCBvcHRpb24sIGluZGV4LCBjZmcpIHtcbiAgICB2YXIgbm9kZXMgPSBjZmcubm9kZXMubm9kZXM7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGN1cnJlbnQgPSBub2Rlc1tpbmRleF07XG4gICAgdmFyIHByZXZpb3VzID0gbm9kZXNbaW5kZXggLSAxXTtcbiAgICBpZiAoY2xlYXJfb3ZlcmxhcHBpbmdfMS5pc05vZGVPdmVybGFwKGN1cnJlbnQsIHByZXZpb3VzKSkge1xuICAgICAgICB2YXIgZWxlbWVudCA9IGNmZy5wbG90LnZpZXcuZ2VvbWV0cmllc1swXS5lbGVtZW50c1swXTtcbiAgICAgICAgdmFyIHkgPSBwcmV2aW91cy50b3AgLSBjdXJyZW50LmhlaWdodCAvIDI7XG4gICAgICAgIHZhciBvZmZzZXQgPSAxMDtcbiAgICAgICAgaWYgKHkgLSBvZmZzZXQgPiBjZmcucmVnaW9uLnRvcCkge1xuICAgICAgICAgICAgLy8g5Y+W5YiwbGFiZWzlr7nlupTnmoRlbGVtZW50LXNoYXBlXG4gICAgICAgICAgICB2YXIgb3JpZ2luXzEgPSBjdXJyZW50LnNoYXBlLmdldCgnb3JpZ2luJyk7XG4gICAgICAgICAgICB2YXIgc2hhcGVJZCA9IGVsZW1lbnQuZ2V0U2hhcGVJZChvcmlnaW5fMSk7XG4gICAgICAgICAgICB2YXIgc2hhcGVzID0gZWxlbWVudC5nZXRTaGFwZXMoKTtcbiAgICAgICAgICAgIHZhciBzaGFwZUJib3ggPSBnZXRTaGFwZUJ5SWQoc2hhcGVJZCwgc2hhcGVzKS5nZXQoJ2JveCcpO1xuICAgICAgICAgICAgdmFyIG9yaWdpblggPSBzaGFwZUJib3gubGVmdCArIHNoYXBlQmJveC53aWR0aCAvIDI7XG4gICAgICAgICAgICB2YXIgb3JpZ2luWSA9IHNoYXBlQmJveC50b3A7XG4gICAgICAgICAgICAvLyDmi4nnur9cbiAgICAgICAgICAgIHZhciBjb250YWluZXIgPSBlbGVtZW50LmdldCgnbGFiZWxDb250cm9sbGVyJykubGFiZWxzQ29udGFpbmVyO1xuICAgICAgICAgICAgdmFyIGxhYmVsTGluZSA9IGNvbnRhaW5lci5hZGRTaGFwZSgncGF0aCcsIHtcbiAgICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBbJ00nLCBvcmlnaW5YLCBvcmlnaW5ZXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsnTCcsIGN1cnJlbnQuc2hhcGUuYXR0cigneCcpLCB5XSxcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAnI2NjYycsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvKiog5L+d5a2YbGFiZWxMaW5l5ZKMbGFiZWzliJ3lp4vkvY3nva7kv6Hmga8gKi9cbiAgICAgICAgICAgIHZhciBvcmlnaW5fcG9zaXRpb24gPSB7IHg6IHNoYXBlLmF0dHIoJ3gnKSwgeTogc2hhcGUuYXR0cigneScpIH07XG4gICAgICAgICAgICAvLyDmm7TmlrDmoIfnrb7kvY3nva7vvIzlkIzmraXmm7TmlrBub2RlXG4gICAgICAgICAgICBjdXJyZW50LnNoYXBlLmF0dHIoJ3knLCB5IC0gb2Zmc2V0KTtcbiAgICAgICAgICAgIG5vZGVzW2luZGV4XSA9IGNmZy5ub2Rlcy5tZWFzdXJlKGN1cnJlbnQuc2hhcGUpO1xuICAgICAgICAgICAgbm9kZXNbaW5kZXhdLmxpbmUgPSBsYWJlbExpbmU7XG4gICAgICAgICAgICBub2Rlc1tpbmRleF0ub3JpZ2luX3Bvc2l0aW9uID0gb3JpZ2luX3Bvc2l0aW9uO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy5kZWZhdWx0ID0gbm9kZUppdHRlclVwd2FyZDtcbmZ1bmN0aW9uIGdldFNoYXBlQnlJZChzaGFwZUlkLCBzaGFwZXMpIHtcbiAgICB2YXIgdGFyZ2V0O1xuICAgIHV0aWxfMS5lYWNoKHNoYXBlcywgZnVuY3Rpb24gKHNoYXBlKSB7XG4gICAgICAgIHZhciBzID0gc2hhcGU7XG4gICAgICAgIHZhciBpZCA9IHMuZ2V0KCdpZCcpO1xuICAgICAgICBpZiAoaWQgPT09IHNoYXBlSWQpIHtcbiAgICAgICAgICAgIHRhcmdldCA9IHM7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bm9kZS1qaXR0ZXItdXB3YXJkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIG1hdGhfMSA9IHJlcXVpcmUoXCIuLi8uLi9tYXRoXCIpO1xuLyoqIOWbvuW9ouWcqOawtOW5s+aIluWeguebtOaWueWQkeaKluW8gCAqL1xuZnVuY3Rpb24gbm9kZUppdHRlcihzaGFwZSwgaW5kZXgsIGNmZykge1xuICAgIHZhciBub2RlcyA9IGNmZy5ub2Rlcy5ub2RlcztcbiAgICBpZiAoaW5kZXggPT09IG5vZGVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgY3VycmVudCA9IG5vZGVzW2luZGV4XTtcbiAgICB2YXIgbmV4dCA9IG5vZGVzW2luZGV4ICsgMV07XG4gICAgdmFyIGRpciA9IGFsaWduRGlyZWN0aW9uKGN1cnJlbnQsIG5leHQpLmRpcjtcbiAgICB2YXIgc3RhcnRQb2ludCA9IHNoYXBlLmdldCgnc3RhcnRQb2ludCcpO1xuICAgIGlmIChkaXIgPT09ICd4Jykge1xuICAgICAgICBzaGFwZS5hdHRyKCd5Jywgc3RhcnRQb2ludC55ICsgMjApO1xuICAgIH1cbn1cbmV4cG9ydHMuZGVmYXVsdCA9IG5vZGVKaXR0ZXI7XG5mdW5jdGlvbiBhbGlnbkRpcmVjdGlvbihub2RlQSwgbm9kZUIpIHtcbiAgICB2YXIgZGlyO1xuICAgIC8qKiDorqHnrpfkuKTkuKpub2RlIOS4reW/g+eCueWQkemHj+eahOinkuW6piAqL1xuICAgIHZhciB2ZWN0b3IgPSB7IHg6IG5vZGVCLmNlbnRlclggLSBub2RlQS5jZW50ZXJYLCB5OiBub2RlQi5jZW50ZXJZIC0gbm9kZUEuY2VudGVyWSB9O1xuICAgIHZhciBtYWcgPSBNYXRoLnNxcnQodmVjdG9yLnggKiB2ZWN0b3IueCArIHZlY3Rvci55ICogdmVjdG9yLnkpO1xuICAgIHZhciB2ZWN0b3JfaG9yaXpvbnRhbCA9IHsgeDogMTAsIHk6IDAgfTsgLy8g5rC05bmz5pa55ZCR5ZCR6YePXG4gICAgLyp0c2xpbnQ6ZGlzYWJsZSovXG4gICAgdmFyIG1hZ19ob3Jpem9udGFsID0gTWF0aC5zcXJ0KHZlY3Rvcl9ob3Jpem9udGFsLnggKiB2ZWN0b3JfaG9yaXpvbnRhbC54ICsgdmVjdG9yX2hvcml6b250YWwueSAqIHZlY3Rvcl9ob3Jpem9udGFsLnkpO1xuICAgIHZhciBkb3QgPSBtYXRoXzEuZG90UHJvZHVjdDJEKHZlY3RvciwgdmVjdG9yX2hvcml6b250YWwpO1xuICAgIHZhciBhbmdsZSA9ICgoZG90IC8gKG1hZyAqIG1hZ19ob3Jpem9udGFsKSkgKiAxODApIC8gTWF0aC5QSTtcbiAgICBpZiAoYW5nbGUgPCAwKVxuICAgICAgICBhbmdsZSA9IDM2MCAtIGFuZ2xlO1xuICAgIGFuZ2xlID0gYWRqdXN0QW5nbGUoYW5nbGUpOyAvLyDlsIbop5Lluqbku44wLTM2MOi9rOaNouWIsDAtOTBcbiAgICAvKiog6K6h566X5Lik5Liqbm9kZeWcqHjjgIF55Lik5Liq5pa55ZCR5LiK55qE6Led56a7ICovXG4gICAgdmFyIGRpc3RYID0gTWF0aC5hYnMobm9kZUEuY2VudGVyWCAtIG5vZGVCLmNlbnRlclgpO1xuICAgIHZhciBkaXN0WSA9IE1hdGguYWJzKG5vZGVBLmNlbnRlclkgLSBub2RlQi5jZW50ZXJZKTtcbiAgICBpZiAoYW5nbGUgPiA0NSkge1xuICAgICAgICBkaXIgPSAneCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKGFuZ2xlIDwgNDUpIHtcbiAgICAgICAgZGlyID0gJ3knO1xuICAgIH1cbiAgICByZXR1cm4geyBkaXI6IGRpciwgZGlzdFg6IGRpc3RYLCBkaXN0WTogZGlzdFkgfTtcbn1cbmZ1bmN0aW9uIGFkanVzdEFuZ2xlKGFuZ2xlKSB7XG4gICAgaWYgKGFuZ2xlID4gOTAgJiYgYW5nbGUgPD0gMTgwKSB7XG4gICAgICAgIHJldHVybiAxODAgLSBhbmdsZTtcbiAgICB9XG4gICAgaWYgKGFuZ2xlID4gMTgwICYmIGFuZ2xlIDwgMjcwKSB7XG4gICAgICAgIHJldHVybiBhbmdsZSAtIDE4MDtcbiAgICB9XG4gICAgcmV0dXJuIDM2MCAtIGFuZ2xlO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bm9kZS1qaXR0ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciBub2Rlc19yZXNhbXBsaW5nXzEgPSByZXF1aXJlKFwiLi9ub2Rlcy1yZXNhbXBsaW5nXCIpO1xudmFyIHRleHRfaGlkZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdGV4dC1oaWRlXCIpKTtcbmZ1bmN0aW9uIG5vZGVzUmVzYW1wbGluZ0J5QWJicmV2YXRlKHNoYXBlLCBvcHRpb24sIGluZGV4LCBjZmcpIHtcbiAgICB2YXIgbm9kZXMgPSBjZmcubm9kZXMubm9kZXM7XG4gICAgaWYgKG5vZGVzX3Jlc2FtcGxpbmdfMS5pc0tlZXAob3B0aW9uLmtlZXAsIGluZGV4LCBub2RlcykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB7XG4gICAgICAgIHZhciBjdXJyZW50VGV4dCA9IHNoYXBlLmF0dHIoJ3RleHQnKTtcbiAgICAgICAgdmFyIG9yaWdpblRleHQgPSBzaGFwZS5nZXQoJ2RlbGVnYXRlT2JqZWN0JykuaXRlbS5uYW1lO1xuICAgICAgICBpZiAoY3VycmVudFRleHQgIT09IG9yaWdpblRleHQpIHtcbiAgICAgICAgICAgIHRleHRfaGlkZV8xLmRlZmF1bHQoc2hhcGUpO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy5kZWZhdWx0ID0gbm9kZXNSZXNhbXBsaW5nQnlBYmJyZXZhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub2Rlcy1yZXNhbXBsaW5nLWJ5LWFiYnJldmF0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHRleHRfaGlkZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdGV4dC1oaWRlXCIpKTtcbi8qKiDmoLnmja7lj5jljJbov5vooYzmir3moLfvvIzkv53nlZnlj5jljJbovoPlpKfnmoTngrnvvIznsbvkvLzkuo7ngrnnroDljJbnrpfms5UgKi9cbmZ1bmN0aW9uIG5vZGVzUmVzYW1wbGluZ0J5Q2hhbmdlKHNoYXBlLCBvcHRpb24sIGluZGV4LCBjZmcpIHtcbiAgICB2YXIgbm9kZXMgPSBjZmcubm9kZXMubm9kZXM7XG4gICAgdmFyIHRvbGVyYW5jZSA9IGdldEdsb2JhbFRvbGVyYW5jZShub2Rlcyk7XG4gICAgaWYgKGluZGV4IDw9IDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgY3VycmVudCA9IG5vZGVzW2luZGV4XTtcbiAgICAvLyBjb25zdCBwcmV2aW91cyA9IG5vZGVzW2luZGV4LTFdO1xuICAgIHZhciBwcmV2aW91cyA9IGZpbmRQcmV2aW91cyhpbmRleCwgbm9kZXMpO1xuICAgIHZhciBkaXN0WCA9IHByZXZpb3VzLmNlbnRlclggLSBjdXJyZW50LmNlbnRlclg7XG4gICAgdmFyIGRpc3RZID0gcHJldmlvdXMuY2VudGVyWSAtIGN1cnJlbnQuY2VudGVyWTtcbiAgICB2YXIgZGlzdCA9IE1hdGguc3FydChkaXN0WCAqIGRpc3RYICsgZGlzdFkgKiBkaXN0WSk7XG4gICAgaWYgKGRpc3QgPCB0b2xlcmFuY2UpIHtcbiAgICAgICAgdGV4dF9oaWRlXzEuZGVmYXVsdChzaGFwZSk7XG4gICAgICAgIHNoYXBlLnNldCgnYmxhbmsnLCB0cnVlKTtcbiAgICB9XG59XG5leHBvcnRzLmRlZmF1bHQgPSBub2Rlc1Jlc2FtcGxpbmdCeUNoYW5nZTtcbmZ1bmN0aW9uIGZpbmRQcmV2aW91cyhpbmRleCwgbm9kZXMpIHtcbiAgICBmb3IgKHZhciBpID0gaW5kZXggLSAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIHZhciBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmICghbm9kZS5zaGFwZS5nZXQoJ2JsYW5rJykpIHtcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0R2xvYmFsVG9sZXJhbmNlKG5vZGVzKSB7XG4gICAgdmFyIG5vZGVzQ2xvbmUgPSB1dGlsXzEuZGVlcE1peChbXSwgbm9kZXMpO1xuICAgIG5vZGVzQ2xvbmUuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gYi53aWR0aCAtIGEud2lkdGg7XG4gICAgfSk7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobm9kZXNDbG9uZVswXS53aWR0aCk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub2Rlcy1yZXNhbXBsaW5nLWJ5LWNoYW5nZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHRleHRfaGlkZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdGV4dC1oaWRlXCIpKTtcbmZ1bmN0aW9uIG5vZGVzUmVzYW1wbGluZ0J5U3RhdGUoc2hhcGUsIG9wdGlvbiwgaW5kZXgsIGNmZykge1xuICAgIHZhciBub2RlcyA9IGNmZy5ub2Rlcy5ub2RlcztcbiAgICB2YXIgY3VycmVudCA9IG5vZGVzW2luZGV4XTtcbiAgICBpZiAoY3VycmVudC5saW5lKSB7XG4gICAgICAgIGN1cnJlbnQubGluZS5yZW1vdmUoKTtcbiAgICB9XG4gICAgdmFyIGRhdGEgPSBjZmcucGxvdC5pbml0aWFsT3B0aW9ucy5kYXRhO1xuICAgIHZhciBwbG90Q2ZnID0gY2ZnLnBsb3RbY2ZnLnBsb3QudHlwZV0gfHwgY2ZnLnBsb3RbY2ZnLnBsb3QuYmFzZVR5cGVdO1xuICAgIHZhciBmaWVsZCA9IHV0aWxfMS5nZXQocGxvdENmZywgWydsYWJlbCcsICdmaWVsZHMnLCAwXSwgdXRpbF8xLmdldChwbG90Q2ZnLCBbJ3Bvc2l0aW9uJywgJ2ZpZWxkcycsIDFdKSk7XG4gICAgdmFyIHN0YXRlTm9kZXMgPSBnZXRTdGF0ZU5vZGVzKGRhdGEsIGZpZWxkLCBub2Rlcyk7XG4gICAgdmFyIGlzU3RhdGUgPSBmYWxzZTtcbiAgICB1dGlsXzEuZWFjaChzdGF0ZU5vZGVzLCBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGlmIChub2RlLnNoYXBlLmdldCgnb3JpZ2luJykgPT09IGN1cnJlbnQuc2hhcGUuZ2V0KCdvcmlnaW4nKSkge1xuICAgICAgICAgICAgaXNTdGF0ZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoaXNTdGF0ZSkge1xuICAgICAgICBpZiAoY3VycmVudC5vcmlnaW5fcG9zaXRpb24pIHtcbiAgICAgICAgICAgIHZhciBfYSA9IGN1cnJlbnQub3JpZ2luX3Bvc2l0aW9uLCB4ID0gX2EueCwgeSA9IF9hLnk7XG4gICAgICAgICAgICBzaGFwZS5hdHRyKCd4JywgeCk7XG4gICAgICAgICAgICBzaGFwZS5hdHRyKCd5JywgeSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHRleHRfaGlkZV8xLmRlZmF1bHQoc2hhcGUpO1xuICAgIH1cbn1cbmV4cG9ydHMuZGVmYXVsdCA9IG5vZGVzUmVzYW1wbGluZ0J5U3RhdGU7XG5mdW5jdGlvbiBnZXRTdGF0ZU5vZGVzKGRhdGEsIGZpZWxkLCBub2Rlcykge1xuICAgIHZhciBleHRyYWN0X2RhdGEgPSBbXTtcbiAgICB1dGlsXzEuZWFjaChkYXRhLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICBleHRyYWN0X2RhdGEucHVzaChkW2ZpZWxkXSk7XG4gICAgfSk7XG4gICAgZXh0cmFjdF9kYXRhLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICAgIHZhciBtaW4gPSBleHRyYWN0X2RhdGFbMF07XG4gICAgdmFyIG1pbl9ub2RlID0gZ2V0Tm9kZUJ5TnVtYmVyKG5vZGVzLCBmaWVsZCwgbWluKTtcbiAgICB2YXIgbWF4ID0gZXh0cmFjdF9kYXRhW2V4dHJhY3RfZGF0YS5sZW5ndGggLSAxXTtcbiAgICB2YXIgbWF4X25vZGUgPSBnZXROb2RlQnlOdW1iZXIobm9kZXMsIGZpZWxkLCBtYXgpO1xuICAgIHZhciBtZWRpYW4gPSBnZXRNZWRpYW4oZXh0cmFjdF9kYXRhKTtcbiAgICB2YXIgbWVkaWFuX25vZGUgPSBnZXROb2RlQnlOdW1iZXIobm9kZXMsIGZpZWxkLCBtZWRpYW4pO1xuICAgIHJldHVybiB7IG1pbjogbWluX25vZGUsIG1heDogbWF4X25vZGUsIG1lZGlhbjogbWVkaWFuX25vZGUgfTtcbn1cbmZ1bmN0aW9uIGdldE1lZGlhbihhcnJheSkge1xuICAgIHZhciBsaXN0ID0gdXRpbF8xLmNsb25lKGFycmF5KTtcbiAgICBsaXN0LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICAgIHZhciBoYWxmID0gTWF0aC5mbG9vcihsaXN0Lmxlbmd0aCAvIDIpO1xuICAgIGlmIChsaXN0Lmxlbmd0aCAlIDIpIHtcbiAgICAgICAgcmV0dXJuIGxpc3RbaGFsZl07XG4gICAgfVxuICAgIHJldHVybiBsaXN0W2hhbGZdO1xufVxuZnVuY3Rpb24gZ2V0Tm9kZUJ5TnVtYmVyKG5vZGVzLCBmaWVsZCwgbnVtKSB7XG4gICAgZm9yICh2YXIgX2kgPSAwLCBub2Rlc18xID0gbm9kZXM7IF9pIDwgbm9kZXNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIG5vZGUgPSBub2Rlc18xW19pXTtcbiAgICAgICAgdmFyIGQgPSBub2RlLnNoYXBlLmdldCgnb3JpZ2luJylbJ19vcmlnaW4nXTtcbiAgICAgICAgaWYgKGRbZmllbGRdID09PSBudW0pIHtcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bm9kZXMtcmVzYW1wbGluZy1ieS1zdGF0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaXNLZWVwID0gdm9pZCAwO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgdGV4dF9oaWRlXzEgPSB0c2xpYl8xLl9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwiLi90ZXh0LWhpZGVcIikpO1xuZnVuY3Rpb24gbm9kZXNSZXNhbXBsaW5nKHNoYXBlLCBvcHRpb24sIGluZGV4LCBjZmcpIHtcbiAgICB2YXIgbm9kZXMgPSBjZmcubm9kZXMubm9kZXM7XG4gICAgLyoqIG5vZGVMZW5ndGjkuLrlgbbmlbDvvIzliJnlpYfmlbBpbmRleOeahHNoYXBl5L+d55WZ77yM5Y+N5LmL5YiZ5YG25pWwaW5kZXjnmoRzaGFwZeS/neeVmSAqL1xuICAgIHZhciBvZGRLZWVwID0gbm9kZXMubGVuZ3RoICUgMiA9PT0gMCA/IGZhbHNlIDogdHJ1ZTtcbiAgICBpZiAoaXNLZWVwKG9wdGlvbi5rZWVwLCBpbmRleCwgbm9kZXMpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAge1xuICAgICAgICB2YXIgaXNPZGQgPSBpbmRleCAlIDIgPT09IDAgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIGlmICgoIW9kZEtlZXAgJiYgaXNPZGQpIHx8IChvZGRLZWVwICYmICFpc09kZCkpIHtcbiAgICAgICAgICAgIHRleHRfaGlkZV8xLmRlZmF1bHQoc2hhcGUpO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy5kZWZhdWx0ID0gbm9kZXNSZXNhbXBsaW5nO1xuZnVuY3Rpb24gaXNLZWVwKGtlZXBDZmcsIGluZGV4LCBub2Rlcykge1xuICAgIC8qKiDlhYHorrjorr7nva5zdGFydCBlbmQg5oiW5Lu75oSPaW5kZXggKi9cbiAgICB2YXIgY29uZGl0aW9ucyA9IFtdO1xuICAgIHV0aWxfMS5lYWNoKGtlZXBDZmcsIGZ1bmN0aW9uIChjZmcpIHtcbiAgICAgICAgaWYgKGNmZyA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICAgICAgY29uZGl0aW9ucy5wdXNoKGluZGV4ID09PSAwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjZmcgPT09ICdlbmQnKSB7XG4gICAgICAgICAgICBjb25kaXRpb25zLnB1c2goaW5kZXggPT09IG5vZGVzLmxlbmd0aCAtIDEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHV0aWxfMS5pc051bWJlcihjZmcpKSB7XG4gICAgICAgICAgICBjb25kaXRpb25zLnB1c2goaW5kZXggPT09IGNmZyk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIGNvbmRpdGlvbnNfMSA9IGNvbmRpdGlvbnM7IF9pIDwgY29uZGl0aW9uc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgY29uZGl0aW9uID0gY29uZGl0aW9uc18xW19pXTtcbiAgICAgICAgaWYgKGNvbmRpdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZXhwb3J0cy5pc0tlZXAgPSBpc0tlZXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub2Rlcy1yZXNhbXBsaW5nLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgZGF0ZXRpbWVfc3RyaW5nX2FiYnJldmFpdGVfMSA9IHRzbGliXzEuX19pbXBvcnRTdGFyKHJlcXVpcmUoXCIuL2RhdGV0aW1lLXN0cmluZy1hYmJyZXZhaXRlXCIpKTtcbnZhciBkaWdpdHNfYWJicmV2aWF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vZGlnaXRzLWFiYnJldmlhdGVcIikpO1xudmFyIHRleHRfYWJicmV2aWF0ZV8xID0gdHNsaWJfMS5fX2ltcG9ydERlZmF1bHQocmVxdWlyZShcIi4vdGV4dC1hYmJyZXZpYXRlXCIpKTtcbmZ1bmN0aW9uIHJvYnVzdEFiYnJldmFpdGUoc2hhcGUsIG9wdGlvbiwgaW5kZXgsIGNmZykge1xuICAgIHZhciBub2RlcyA9IGNmZy5ub2Rlcy5ub2RlcztcbiAgICB2YXIgdGV4dCA9IHNoYXBlLmF0dHIoJ3RleHQnKTtcbiAgICAvKiog5Yik5patdGV4dOexu+Wei++8miDmlbDlrZfjgIHml7bpl7TjgIHmlofmnKwgKi9cbiAgICB2YXIgaXNudW0gPSAvXlxcZCskLy50ZXN0KHRleHQpO1xuICAgIGlmIChpc251bSkge1xuICAgICAgICBkaWdpdHNfYWJicmV2aWF0ZV8xLmRlZmF1bHQoc2hhcGUsIG9wdGlvbiwgaW5kZXgsIG5vZGVzKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZGF0ZXRpbWVfc3RyaW5nX2FiYnJldmFpdGVfMS5pc1RpbWUodGV4dCkpIHtcbiAgICAgICAgZGF0ZXRpbWVfc3RyaW5nX2FiYnJldmFpdGVfMS5kZWZhdWx0KHNoYXBlLCBvcHRpb24sIGluZGV4LCBub2Rlcyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB0ZXh0X2FiYnJldmlhdGVfMS5kZWZhdWx0KHNoYXBlLCBvcHRpb24pO1xuICAgIH1cbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHJvYnVzdEFiYnJldmFpdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yb2J1c3QtYWJicmV2YWl0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHRleHRBYmJyZXZpYXRlKHNoYXBlLCBvcHRpb24pIHtcbiAgICB2YXIgYWJicmV2aWF0ZUJ5ID0gb3B0aW9uLmFiYnJldmlhdGVCeSA/IG9wdGlvbi5hYmJyZXZpYXRlQnkgOiAnZW5kJztcbiAgICB2YXIgdGV4dCA9IHNoYXBlLmF0dHIoJ3RleHQnKTtcbiAgICB2YXIgYWJicmF2YXRlVGV4dDtcbiAgICBpZiAoYWJicmV2aWF0ZUJ5ID09PSAnZW5kJykge1xuICAgICAgICBhYmJyYXZhdGVUZXh0ID0gdGV4dFswXSArIFwiLi4uXCI7XG4gICAgfVxuICAgIGlmIChhYmJyZXZpYXRlQnkgPT09ICdzdGFydCcpIHtcbiAgICAgICAgYWJicmF2YXRlVGV4dCA9IFwiLi4uXCIgKyB0ZXh0W3RleHQubGVuZ3RoIC0gMV07XG4gICAgfVxuICAgIGlmIChhYmJyZXZpYXRlQnkgPT09ICdtaWRkbGUnKSB7XG4gICAgICAgIGFiYnJhdmF0ZVRleHQgPSB0ZXh0WzBdICsgXCIuLi5cIiArIHRleHRbdGV4dC5sZW5ndGggLSAxXTtcbiAgICB9XG4gICAgc2hhcGUucmVzZXRNYXRyaXgoKTtcbiAgICBzaGFwZS5hdHRyKHtcbiAgICAgICAgdGV4dDogYWJicmF2YXRlVGV4dCxcbiAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgdGV4dEJhc2VsaW5lOiAndG9wJyxcbiAgICB9KTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHRleHRBYmJyZXZpYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC1hYmJyZXZpYXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZnVuY3Rpb24gdGV4dEhpZGUoc2hhcGUpIHtcbiAgICBzaGFwZS5hdHRyKCd0ZXh0JywgJycpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gdGV4dEhpZGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXh0LWhpZGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiB0ZXh0Um90YXRpb24oc2hhcGUsIG9wdGlvbikge1xuICAgIHNoYXBlLnJlc2V0TWF0cml4KCk7XG4gICAgc2hhcGUuYXR0cih7XG4gICAgICAgIHJvdGF0ZTogMzYwIC0gb3B0aW9uLmRlZ3JlZSxcbiAgICAgICAgdGV4dEFsaWduOiAncmlnaHQnLFxuICAgICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgIH0pO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gdGV4dFJvdGF0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC1yb3RhdGlvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHRleHRXcmFwcGVyKHNoYXBlLCBvcHRpb24pIHtcbiAgICB2YXIgdGV4dCA9IHNoYXBlLmF0dHIoJ3RleHQnKTtcbiAgICB2YXIgc3RlcCA9IE1hdGguY2VpbCh0ZXh0Lmxlbmd0aCAvIG9wdGlvbi5saW5lTnVtYmVyKTtcbiAgICB2YXIgd3JhcHBlclRleHQgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IG9wdGlvbi5saW5lTnVtYmVyOyBpKyspIHtcbiAgICAgICAgdmFyIGluZGV4ID0gc3RlcCAqIGk7XG4gICAgICAgIHdyYXBwZXJUZXh0ID0gdGV4dC5zbGljZSgwLCBpbmRleCkgKyBcIlxcblwiICsgdGV4dC5zbGljZShpbmRleCk7XG4gICAgfVxuICAgIHZhciBmb250U2l6ZSA9IHNoYXBlLmF0dHIoJ2ZvbnRTaXplJyk7XG4gICAgc2hhcGUuYXR0cih7XG4gICAgICAgIHRleHQ6IHdyYXBwZXJUZXh0LFxuICAgICAgICBsaW5lSGVpZ2h0OiBmb250U2l6ZSxcbiAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgdGV4dEJhc2VsaW5lOiAndG9wJyxcbiAgICB9KTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHRleHRXcmFwcGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC13cmFwcGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRSZXNwb25zaXZlVGhlbWUgPSBleHBvcnRzLnJlZ2lzdGVyUmVzcG9uc2l2ZVRoZW1lID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGRlZmF1bHRfMSA9IHJlcXVpcmUoXCIuL2RlZmF1bHRcIik7XG4vKipcbiAqIOaJgOacieeahOWTjeW6lOW8j+S4u+mimOmFjee9rlxuICovXG52YXIgUkVTUE9OU0lWRV9USEVNRV9NQVAgPSB7XG4gICAgZGVmYXVsdDogZGVmYXVsdF8xLkRFRkFVTFRfUkVTUE9OU0lWRV9USEVNRSxcbn07XG4vKipcbiAqIOa3u+WKoOS4gOS4quWTjeW6lOW8j+S4u+mimOmFjee9rlxuICogQHBhcmFtIG5hbWVcbiAqIEBwYXJhbSB0aGVtZVxuICovXG5mdW5jdGlvbiByZWdpc3RlclJlc3BvbnNpdmVUaGVtZShuYW1lLCB0aGVtZSkge1xuICAgIFJFU1BPTlNJVkVfVEhFTUVfTUFQW25hbWUudG9Mb3dlckNhc2UoKV0gPSB1dGlsXzEuZGVlcE1peCh7fSwgZGVmYXVsdF8xLkRFRkFVTFRfUkVTUE9OU0lWRV9USEVNRSwgdGhlbWUpO1xufVxuZXhwb3J0cy5yZWdpc3RlclJlc3BvbnNpdmVUaGVtZSA9IHJlZ2lzdGVyUmVzcG9uc2l2ZVRoZW1lO1xuLyoqXG4gKiDojrflj5bkuIDkuKrlk43lupTlvI/kuLvpopjphY3nva7vvIzlpoLmnpzmib7kuI3liLDliJnov5Tlm57pu5jorqRcbiAqIEBwYXJhbSBuYW1lXG4gKi9cbmZ1bmN0aW9uIGdldFJlc3BvbnNpdmVUaGVtZShuYW1lKSB7XG4gICAgdmFyIHRoZW1lID0gUkVTUE9OU0lWRV9USEVNRV9NQVBbbmFtZS50b0xvd2VyQ2FzZSgpXTtcbiAgICByZXR1cm4gdGhlbWUgPyB0aGVtZSA6IGRlZmF1bHRfMS5ERUZBVUxUX1JFU1BPTlNJVkVfVEhFTUU7XG59XG5leHBvcnRzLmdldFJlc3BvbnNpdmVUaGVtZSA9IGdldFJlc3BvbnNpdmVUaGVtZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRoZW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50cnlTZXRTY2FsZU1pblRvWmVybyA9IGV4cG9ydHMuZXh0cmFjdFNjYWxlID0gdm9pZCAwO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNvbmZpZ18xID0gcmVxdWlyZShcIi4uL2ludGVyZmFjZS9jb25maWdcIik7XG5mdW5jdGlvbiBhZGp1c3RUaW1lVGlja0ludGVydmFsKGludGVydmFsKSB7XG4gICAgdmFyIGludGVydmFscyA9IGNvbmZpZ18xLnRpbWVJbnRlcnZhbHM7XG4gICAgdmFyIGludGVydmFsQXJyID0gaW50ZXJ2YWwuc3BsaXQoJyAnKTtcbiAgICB2YXIgYmFzaWNJbnRlcnZhbCA9IGludGVydmFsc1tpbnRlcnZhbEFyclsxXV07XG4gICAgdmFyIGludGVydmFsQ291bnQgPSBwYXJzZUludChpbnRlcnZhbEFyclswXSwgMTApO1xuICAgIHJldHVybiBbYmFzaWNJbnRlcnZhbC5mb3JtYXQsIGludGVydmFsQ291bnQgKiBiYXNpY0ludGVydmFsLnZhbHVlXTtcbn1cbmZ1bmN0aW9uIGV4dHJhY3RTY2FsZShkZXNTY2FsZSwgYXhpc0NvbmZpZykge1xuICAgIGlmICghYXhpc0NvbmZpZykge1xuICAgICAgICByZXR1cm4gZGVzU2NhbGU7XG4gICAgfVxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYXhpc0NvbmZpZywgJ3RpY2tDb3VudCcpKSB7XG4gICAgICAgIGRlc1NjYWxlLnRpY2tDb3VudCA9IGF4aXNDb25maWcudGlja0NvdW50O1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF4aXNDb25maWcsICd0eXBlJykpIHtcbiAgICAgICAgLy8gZml4bWU6IGRhdGVUaW1lIHBsb3TlsYLlpITnkIZcbiAgICAgICAgaWYgKGF4aXNDb25maWcudHlwZSAhPT0gJ2RhdGVUaW1lJykge1xuICAgICAgICAgICAgZGVzU2NhbGUudHlwZSA9IGF4aXNDb25maWcudHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF4aXNDb25maWcsICd0aWNrSW50ZXJ2YWwnKSkge1xuICAgICAgICBpZiAoYXhpc0NvbmZpZy50eXBlID09PSAndGltZScpIHtcbiAgICAgICAgICAgIGRlc1NjYWxlLnRpY2tJbnRlcnZhbCA9IGFkanVzdFRpbWVUaWNrSW50ZXJ2YWwoYXhpc0NvbmZpZy50aWNrSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVzU2NhbGUudGlja0ludGVydmFsID0gYXhpc0NvbmZpZy50aWNrSW50ZXJ2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGF4aXNDb25maWcudHlwZSA9PT0gJ3RpbWUnICYmIGF4aXNDb25maWcubWFzaykge1xuICAgICAgICBkZXNTY2FsZS5tYXNrID0gYXhpc0NvbmZpZy5tYXNrO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF4aXNDb25maWcsICdtaW4nKSkge1xuICAgICAgICBkZXNTY2FsZS5taW4gPSBheGlzQ29uZmlnLm1pbjtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChheGlzQ29uZmlnLCAnbWF4JykpIHtcbiAgICAgICAgZGVzU2NhbGUubWF4ID0gYXhpc0NvbmZpZy5tYXg7XG4gICAgfVxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYXhpc0NvbmZpZywgJ21pbkxpbWl0JykpIHtcbiAgICAgICAgZGVzU2NhbGUubWluTGltaXQgPSBheGlzQ29uZmlnLm1pbkxpbWl0O1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF4aXNDb25maWcsICdtYXhMaW1pdCcpKSB7XG4gICAgICAgIGRlc1NjYWxlLm1heExpbWl0ID0gYXhpc0NvbmZpZy5tYXhMaW1pdDtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChheGlzQ29uZmlnLCAnbmljZScpKSB7XG4gICAgICAgIGRlc1NjYWxlLm5pY2UgPSBheGlzQ29uZmlnLm5pY2U7XG4gICAgfVxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYXhpc0NvbmZpZywgJ2Zvcm1hdHRlcicpKSB7XG4gICAgICAgIGRlc1NjYWxlLmZvcm1hdHRlciA9IGF4aXNDb25maWcuZm9ybWF0dGVyO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF4aXNDb25maWcsICdleHBvbmVudCcpKSB7XG4gICAgICAgIGRlc1NjYWxlLmV4cG9uZW50ID0gYXhpc0NvbmZpZy5leHBvbmVudDtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChheGlzQ29uZmlnLCAnYmFzZScpKSB7XG4gICAgICAgIGRlc1NjYWxlLmJhc2UgPSBheGlzQ29uZmlnLmJhc2U7XG4gICAgfVxuICAgIGlmIChheGlzQ29uZmlnLnRpY2tNZXRob2QpIHtcbiAgICAgICAgZGVzU2NhbGUudGlja01ldGhvZCA9IGF4aXNDb25maWcudGlja01ldGhvZDtcbiAgICB9XG59XG5leHBvcnRzLmV4dHJhY3RTY2FsZSA9IGV4dHJhY3RTY2FsZTtcbmZ1bmN0aW9uIHRyeVNldFNjYWxlTWluVG9aZXJvKGRlc1NjYWxlLCBkYXRhKSB7XG4gICAgdmFyIHZhbGlkRGF0YSA9IHV0aWxfMS5maWx0ZXIoZGF0YSwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHV0aWxfMS5pc051bWJlcih2KTsgfSk7XG4gICAgdmFyIG1pbiA9IE1hdGgubWluLmFwcGx5KE1hdGgsIHZhbGlkRGF0YSk7XG4gICAgdmFyIG1heCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIHZhbGlkRGF0YSk7XG4gICAgaWYgKG1pbiA+IDApIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc05pbChkZXNTY2FsZS5taW4pKSB7XG4gICAgICAgICAgICBkZXNTY2FsZS5taW4gPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKG1heCA8IDApIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc05pbChkZXNTY2FsZS5tYXgpKSB7XG4gICAgICAgICAgICBkZXNTY2FsZS5tYXggPSAwO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy50cnlTZXRTY2FsZU1pblRvWmVybyA9IHRyeVNldFNjYWxlTWluVG9aZXJvO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2NhbGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbi8qKlxuICog5Y+v5o+S5ouU55qE54q25oCB6YeP566h55CG5py6XG4gKi9cbi8vIHRvZG86IOWQjue7rei/mOmcgOimgeWKoOWFpeS6pOS6kuS6kuaWpeeahOe7tOaKpOacuuWItlxudmFyIGV2ZW50X2VtaXR0ZXJfMSA9IHRzbGliXzEuX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJAYW50di9ldmVudC1lbWl0dGVyXCIpKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBTdGF0ZU1hbmFnZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoU3RhdGVNYW5hZ2VyLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFN0YXRlTWFuYWdlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuX3N0YXRlcyA9IHt9O1xuICAgICAgICBfdGhpcy5fc3RhdGVTdGFjayA9IHt9O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFN0YXRlTWFuYWdlci5wcm90b3R5cGUuc2V0U3RhdGUgPSBmdW5jdGlvbiAobmFtZSwgZXhwKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlU3RhY2tbbmFtZV0gPSBleHA7XG4gICAgICAgIHRoaXMuX29uVXBkYXRlKCk7XG4gICAgfTtcbiAgICBTdGF0ZU1hbmFnZXIucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlc1tuYW1lXTtcbiAgICB9O1xuICAgIFN0YXRlTWFuYWdlci5wcm90b3R5cGUuZ2V0QWxsU3RhdGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGVzO1xuICAgIH07XG4gICAgU3RhdGVNYW5hZ2VyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fc3RhdGVzID0ge307XG4gICAgICAgIHRoaXMuX3N0YXRlU3RhY2sgPSB7fTtcbiAgICAgICAgaWYgKHRoaXMuX2NoYW5nZVRpbWVyKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fY2hhbmdlVGltZXIpO1xuICAgICAgICAgICAgdGhpcy5fY2hhbmdlVGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTdGF0ZU1hbmFnZXIucHJvdG90eXBlLl9vblVwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHN0YXRlU3RhY2sgPSB0aGlzLl9zdGF0ZVN0YWNrO1xuICAgICAgICBpZiAodGhpcy5fY2hhbmdlVGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9jaGFuZ2VUaW1lcik7XG4gICAgICAgICAgICB0aGlzLl9jaGFuZ2VUaW1lciA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2hhbmdlVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIGZvciAoY29uc3QgbmFtZSBpbiBzdGF0ZVN0YWNrKSB7XG4gICAgICAgICAgICB1dGlsXzEuZWFjaChzdGF0ZVN0YWNrLCBmdW5jdGlvbiAoZXhwLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXRlID0gc3RhdGVTdGFja1tuYW1lXTtcbiAgICAgICAgICAgICAgICBpZiAoIV90aGlzLl9zdGF0ZXNbbmFtZV0gfHwgX3RoaXMuX3N0YXRlc1tuYW1lXSAhPT0gZXhwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBzdGF0ZXNcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3N0YXRlc1tuYW1lXSA9IGV4cDtcbiAgICAgICAgICAgICAgICAgICAgLy8gZGlzcGF0Y2ggc3RhdGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3RyaWdnZXJFdmVudChuYW1lLCBzdGF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAvLyBjbGVhciBzdGFja1xuICAgICAgICAgICAgX3RoaXMuX3N0YXRlU3RhY2sgPSB7fTtcbiAgICAgICAgfSwgMTYpO1xuICAgIH07XG4gICAgU3RhdGVNYW5hZ2VyLnByb3RvdHlwZS5fdHJpZ2dlckV2ZW50ID0gZnVuY3Rpb24gKG5hbWUsIGV4cCkge1xuICAgICAgICB0aGlzLmVtaXQobmFtZSArIFwiOmNoYW5nZVwiLCB7XG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgZXhwOiBleHAsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIFN0YXRlTWFuYWdlcjtcbn0oZXZlbnRfZW1pdHRlcl8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0YXRlTWFuYWdlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRlLW1hbmFnZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldEVsbGlwc2lzVGV4dCA9IGV4cG9ydHMubWVhc3VyZVRleHRXaWR0aCA9IHZvaWQgMDtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xudmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuLyoqXG4gKiDorqHnrpfmlofmnKzlnKjnlLvluIPkuK3nmoTlrr3luqZcbiAqL1xuZXhwb3J0cy5tZWFzdXJlVGV4dFdpZHRoID0gdXRpbF8xLm1lbW9pemUoZnVuY3Rpb24gKHRleHQsIGZvbnQpIHtcbiAgICBpZiAoZm9udCA9PT0gdm9pZCAwKSB7IGZvbnQgPSB7fTsgfVxuICAgIHZhciBmb250U2l6ZSA9IGZvbnQuZm9udFNpemUsIGZvbnRGYW1pbHkgPSBmb250LmZvbnRGYW1pbHksIGZvbnRXZWlnaHQgPSBmb250LmZvbnRXZWlnaHQsIGZvbnRTdHlsZSA9IGZvbnQuZm9udFN0eWxlLCBmb250VmFyaWFudCA9IGZvbnQuZm9udFZhcmlhbnQ7XG4gICAgY3R4LmZvbnQgPSBbZm9udFN0eWxlLCBmb250VmFyaWFudCwgZm9udFdlaWdodCwgZm9udFNpemUgKyBcInB4XCIsIGZvbnRGYW1pbHldLmpvaW4oJyAnKTtcbiAgICByZXR1cm4gY3R4Lm1lYXN1cmVUZXh0KHV0aWxfMS5pc1N0cmluZyh0ZXh0KSA/IHRleHQgOiAnJykud2lkdGg7XG59LCBmdW5jdGlvbiAodGV4dCwgZm9udCkgeyByZXR1cm4gKGZvbnQgPyB0c2xpYl8xLl9fc3ByZWFkQXJyYXlzKFt0ZXh0XSwgdXRpbF8xLnZhbHVlcyhmb250KSkuam9pbignJykgOiB0ZXh0KTsgfSk7XG4vKipcbiAqIOiOt+WPluaWh+acrOeahCAuLi4g5paH5pys44CCXG4gKiDnrpfms5XvvIjlh4/lsJHmr4/mrKEgbWVhc3VyZVRleHQg55qE6ZW/5bqm77yMbWVhc3VyZVRleHQg55qE5oCn6IO96Lef5a2X56ym5Liy5pe26Ze055u45YWz77yJ77yaXG4gKiAxLiDlhYjpgJrov4cgU1RFUCDpgJDmraXorqHnrpfvvIzmib7liLDmnIDlkI7kuIDkuKrlsI/kuo4gbWF4V2lkdGgg55qE5a2X56ym5LiyXG4gKiAyLiDnhLblkI7lr7nmnIDlkI7ov5nkuKrlrZfnrKbkuLLkuozliIborqHnrpdcbiAqIEBwYXJhbSB0ZXh0IOmcgOimgeiuoeeul+eahOaWh+acrCwg55Sx5LqO5Y6G5Y+y5Y6f5ZugIOmZpOS6huaUr+aMgXN0cmluZ++8jOi/mOaUr+aMgeepuuWAvCxudW1iZXLlkozmlbDnu4TnrYlcbiAqIEBwYXJhbSBtYXhXaWR0aFxuICogQHBhcmFtIGZvbnRcbiAqIFRPRE8g5ZCO57ut5pu05paw55yB55Wl566X5rOVXG4gKi9cbmV4cG9ydHMuZ2V0RWxsaXBzaXNUZXh0ID0gZnVuY3Rpb24gKHRleHQsIG1heFdpZHRoLCBmb250KSB7XG4gICAgdmFyIFNURVAgPSAxNjsgLy8g5q+P5qyhIDE277yM6LCD5Y+C5bel56iL5biIXG4gICAgdmFyIERPVF9XSURUSCA9IGV4cG9ydHMubWVhc3VyZVRleHRXaWR0aCgnLi4uJywgZm9udCk7XG4gICAgdmFyIGxlZnRUZXh0O1xuICAgIGlmICghdXRpbF8xLmlzU3RyaW5nKHRleHQpKSB7XG4gICAgICAgIGxlZnRUZXh0ID0gdXRpbF8xLnRvU3RyaW5nKHRleHQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGVmdFRleHQgPSB0ZXh0O1xuICAgIH1cbiAgICB2YXIgbGVmdFdpZHRoID0gbWF4V2lkdGg7XG4gICAgdmFyIHIgPSBbXTsgLy8g5pyA57uI55qE5YiG5q615a2X56ym5LiyXG4gICAgdmFyIGN1cnJlbnRUZXh0O1xuICAgIHZhciBjdXJyZW50V2lkdGg7XG4gICAgaWYgKGV4cG9ydHMubWVhc3VyZVRleHRXaWR0aCh0ZXh0LCBmb250KSA8PSBtYXhXaWR0aCkge1xuICAgICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG4gICAgLy8g6aaW5YWI6YCa6L+HIHN0ZXAg6K6h566X77yM5om+5Ye65pyA5aSn55qE5pyq6LaF5Ye66ZW/5bqm55qEXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIC8vIOabtOaWsOWtl+espuS4slxuICAgICAgICBjdXJyZW50VGV4dCA9IGxlZnRUZXh0LnN1YnN0cigwLCBTVEVQKTtcbiAgICAgICAgLy8g6K6h566X5a695bqmXG4gICAgICAgIGN1cnJlbnRXaWR0aCA9IGV4cG9ydHMubWVhc3VyZVRleHRXaWR0aChjdXJyZW50VGV4dCwgZm9udCk7XG4gICAgICAgIC8vIOi2heWHuuWJqeS9meWuveW6pu+8jOWImeWBnOatolxuICAgICAgICBpZiAoY3VycmVudFdpZHRoICsgRE9UX1dJRFRIID4gbGVmdFdpZHRoKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFdpZHRoID4gbGVmdFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgci5wdXNoKGN1cnJlbnRUZXh0KTtcbiAgICAgICAgLy8g5rKh5pyJ6LaF5Ye677yM5YiZ6K6h566X5Ymp5L2Z5a695bqmXG4gICAgICAgIGxlZnRXaWR0aCAtPSBjdXJyZW50V2lkdGg7XG4gICAgICAgIGxlZnRUZXh0ID0gbGVmdFRleHQuc3Vic3RyKFNURVApO1xuICAgICAgICAvLyDlrZfnrKbkuLLmlbTkvZPmsqHmnInotoXlh7pcbiAgICAgICAgaWYgKCFsZWZ0VGV4dCkge1xuICAgICAgICAgICAgcmV0dXJuIHIuam9pbignJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8g5pyA5LiL55qE5pyA5ZCO5LiA5LiqIFNURVDvvIzkvb/nlKggMSDpgJLlop7vvIjnlKjkuozliIbmlYjmnpzmm7Tpq5jvvIlcbiAgICAvL2VzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAvLyDmm7TmlrDlrZfnrKbkuLJcbiAgICAgICAgY3VycmVudFRleHQgPSBsZWZ0VGV4dC5zdWJzdHIoMCwgMSk7XG4gICAgICAgIC8vIOiuoeeul+WuveW6plxuICAgICAgICBjdXJyZW50V2lkdGggPSBleHBvcnRzLm1lYXN1cmVUZXh0V2lkdGgoY3VycmVudFRleHQsIGZvbnQpO1xuICAgICAgICAvLyDotoXlh7rliankvZnlrr3luqbvvIzliJnlgZzmraJcbiAgICAgICAgaWYgKGN1cnJlbnRXaWR0aCArIERPVF9XSURUSCA+IGxlZnRXaWR0aCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgci5wdXNoKGN1cnJlbnRUZXh0KTtcbiAgICAgICAgLy8g5rKh5pyJ6LaF5Ye677yM5YiZ6K6h566X5Ymp5L2Z5a695bqmXG4gICAgICAgIGxlZnRXaWR0aCAtPSBjdXJyZW50V2lkdGg7XG4gICAgICAgIGxlZnRUZXh0ID0gbGVmdFRleHQuc3Vic3RyKDEpO1xuICAgICAgICBpZiAoIWxlZnRUZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gci5qb2luKCcnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gci5qb2luKCcnKSArIFwiLi4uXCI7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuY2hlY2tTaGFwZU92ZXJsYXAgPSBleHBvcnRzLmdldE92ZXJsYXBBcmVhID0gZXhwb3J0cy5tb3ZlSW5QYW5lbCA9IGV4cG9ydHMuY2hlY2tPcmlnaW5FcXVhbCA9IGV4cG9ydHMuZm9yRWFjaEVsZW1lbnQgPSBleHBvcnRzLmZvckVhY2hHZW9tZXRyeSA9IGV4cG9ydHMuZ2V0R2VvbWV0cnlTaGFwZXMgPSBleHBvcnRzLmdldEdlb21ldHJ5QnlUeXBlID0gZXhwb3J0cy5nZXRBbGxHZW9tZXRyeUJ5VHlwZSA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBkZXBlbmRlbnRzXzEgPSByZXF1aXJlKFwiLi4vZGVwZW5kZW50c1wiKTtcbmZ1bmN0aW9uIGdldEFsbEdlb21ldHJ5QnlUeXBlKHZpZXcsIHR5cGUpIHtcbiAgICByZXR1cm4gdXRpbF8xLmZpbHRlcih2aWV3Lmdlb21ldHJpZXMsIGZ1bmN0aW9uIChnZW9tZXRyeSkgeyByZXR1cm4gZ2VvbWV0cnkudHlwZSA9PT0gdHlwZTsgfSk7XG59XG5leHBvcnRzLmdldEFsbEdlb21ldHJ5QnlUeXBlID0gZ2V0QWxsR2VvbWV0cnlCeVR5cGU7XG5mdW5jdGlvbiBnZXRHZW9tZXRyeUJ5VHlwZSh2aWV3LCB0eXBlKSB7XG4gICAgcmV0dXJuIHV0aWxfMS5oZWFkKGdldEFsbEdlb21ldHJ5QnlUeXBlKHZpZXcsIHR5cGUpKTtcbn1cbmV4cG9ydHMuZ2V0R2VvbWV0cnlCeVR5cGUgPSBnZXRHZW9tZXRyeUJ5VHlwZTtcbmZ1bmN0aW9uIGdldEdlb21ldHJ5U2hhcGVzKGdlb21ldHJ5KSB7XG4gICAgcmV0dXJuIHV0aWxfMS5tYXAoZ2VvbWV0cnkuZWxlbWVudHMsIGZ1bmN0aW9uIChlbGVtZW50KSB7IHJldHVybiBlbGVtZW50LnNoYXBlOyB9KTtcbn1cbmV4cG9ydHMuZ2V0R2VvbWV0cnlTaGFwZXMgPSBnZXRHZW9tZXRyeVNoYXBlcztcbmZ1bmN0aW9uIGZvckVhY2hHZW9tZXRyeSh2aWV3LCBjYWxsYmFjaykge1xuICAgIHZpZXcuZ2VvbWV0cmllcy5mb3JFYWNoKGNhbGxiYWNrKTtcbn1cbmV4cG9ydHMuZm9yRWFjaEdlb21ldHJ5ID0gZm9yRWFjaEdlb21ldHJ5O1xuZnVuY3Rpb24gZm9yRWFjaEVsZW1lbnQodmlldywgY2FsbGJhY2spIHtcbiAgICB2aWV3Lmdlb21ldHJpZXMuZm9yRWFjaChmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICAgICAgZ2VvbWV0cnkuZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgY2FsbGJhY2soZWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuZXhwb3J0cy5mb3JFYWNoRWxlbWVudCA9IGZvckVhY2hFbGVtZW50O1xuLyoqIOajgOa1i+aYr+WQpuacieWSjOW3suWtmOWcqOeahFNoYXBl5pWw5o2uYOebuOetiWDnmoTmg4XlhrUgKi9cbmZ1bmN0aW9uIGNoZWNrT3JpZ2luRXF1YWwoY3VyLCBkb25lcywgY29tcGFyZSkge1xuICAgIHJldHVybiB1dGlsXzEuc29tZShkb25lcywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmUoZG9uZS5nZXQoZGVwZW5kZW50c18xLk9SSUdJTiksIGN1ci5nZXQoZGVwZW5kZW50c18xLk9SSUdJTikpO1xuICAgIH0pO1xufVxuZXhwb3J0cy5jaGVja09yaWdpbkVxdWFsID0gY2hlY2tPcmlnaW5FcXVhbDtcbi8qKiDlsIZsYWJlbOiwg+aVtOWIsHBhbmVs5YaFICovXG5mdW5jdGlvbiBtb3ZlSW5QYW5lbChzaGFwZSwgcGFuZWwpIHtcbiAgICB2YXIgYm94ID0gc2hhcGUuZ2V0QkJveCgpO1xuICAgIHZhciBkZWx0YVggPSAwO1xuICAgIHZhciBkZWx0YVkgPSAwO1xuICAgIGlmIChib3gubWluWCA8IHBhbmVsLm1pblgpIHtcbiAgICAgICAgZGVsdGFYID0gYm94Lm1pblggLSBwYW5lbC5taW5YO1xuICAgIH1cbiAgICBlbHNlIGlmIChib3gubWF4WCA+IHBhbmVsLm1heFgpIHtcbiAgICAgICAgZGVsdGFYID0gYm94Lm1heFggLSBwYW5lbC5tYXhYO1xuICAgIH1cbiAgICBpZiAoZGVsdGFYKSB7XG4gICAgICAgIHNoYXBlLmF0dHIoJ3gnLCBzaGFwZS5hdHRyKCd4JykgLSBkZWx0YVgpO1xuICAgIH1cbiAgICBpZiAoYm94Lm1pblkgPCBwYW5lbC5taW5ZKSB7XG4gICAgICAgIGRlbHRhWSA9IGJveC5taW5ZIC0gcGFuZWwubWluWTtcbiAgICB9XG4gICAgZWxzZSBpZiAoYm94Lm1heFkgPiBwYW5lbC5tYXhZKSB7XG4gICAgICAgIGRlbHRhWSA9IGJveC5tYXhZIC0gcGFuZWwubWF4WTtcbiAgICB9XG4gICAgaWYgKGRlbHRhWSkge1xuICAgICAgICBzaGFwZS5hdHRyKCd5Jywgc2hhcGUuYXR0cigneScpIC0gZGVsdGFZKTtcbiAgICB9XG59XG5leHBvcnRzLm1vdmVJblBhbmVsID0gbW92ZUluUGFuZWw7XG4vKipcbiAqIOiuoeeul+S4pOS4quefqeW9ouS5i+mXtOeahOWghuWPoOWMuuWfn+mdouenr1xuICovXG5mdW5jdGlvbiBnZXRPdmVybGFwQXJlYShhLCBiLCBtYXJnaW4pIHtcbiAgICBpZiAobWFyZ2luID09PSB2b2lkIDApIHsgbWFyZ2luID0gMDsgfVxuICAgIHZhciB4T3ZlcmxhcCA9IE1hdGgubWF4KDAsIE1hdGgubWluKGEueCArIGEud2lkdGggKyBtYXJnaW4sIGIueCArIGIud2lkdGggKyBtYXJnaW4pIC0gTWF0aC5tYXgoYS54IC0gbWFyZ2luLCBiLnggLSBtYXJnaW4pKTtcbiAgICB2YXIgeU92ZXJsYXAgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihhLnkgKyBhLmhlaWdodCArIG1hcmdpbiwgYi55ICsgYi5oZWlnaHQgKyBtYXJnaW4pIC0gTWF0aC5tYXgoYS55IC0gbWFyZ2luLCBiLnkgLSBtYXJnaW4pKTtcbiAgICByZXR1cm4geE92ZXJsYXAgKiB5T3ZlcmxhcDtcbn1cbmV4cG9ydHMuZ2V0T3ZlcmxhcEFyZWEgPSBnZXRPdmVybGFwQXJlYTtcbi8qKiDmo4DmtYvmmK/lkKblkozlt7LluIPlsYDnmoTloIblj6AgKi9cbmZ1bmN0aW9uIGNoZWNrU2hhcGVPdmVybGFwKGN1ciwgZG9uZXMpIHtcbiAgICB2YXIgYm94ID0gY3VyLmdldEJCb3goKTtcbiAgICByZXR1cm4gdXRpbF8xLnNvbWUoZG9uZXMsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSBkb25lLmdldEJCb3goKTtcbiAgICAgICAgcmV0dXJuIGdldE92ZXJsYXBBcmVhKGJveCwgdGFyZ2V0LCAyKSA+IDA7XG4gICAgfSk7XG59XG5leHBvcnRzLmNoZWNrU2hhcGVPdmVybGFwID0gY2hlY2tTaGFwZU92ZXJsYXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD12aWV3LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24g5omp5bGV5pa55rOV77yM5o+Q5L6bIGdsLW1hdHJpeCDkuLrmj5DkvpvnmoTmlrnms5VcbiAqICovXG52YXIgZ2xfbWF0cml4XzEgPSByZXF1aXJlKFwiZ2wtbWF0cml4XCIpO1xuZnVuY3Rpb24gbGVmdFRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgICB2YXIgdHJhbnNNYXQgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgZ2xfbWF0cml4XzEubWF0My5mcm9tVHJhbnNsYXRpb24odHJhbnNNYXQsIHYpO1xuICAgIHJldHVybiBnbF9tYXRyaXhfMS5tYXQzLm11bHRpcGx5KG91dCwgdHJhbnNNYXQsIGEpO1xufVxuZXhwb3J0cy5sZWZ0VHJhbnNsYXRlID0gbGVmdFRyYW5zbGF0ZTtcbmZ1bmN0aW9uIGxlZnRSb3RhdGUob3V0LCBhLCByYWQpIHtcbiAgICB2YXIgcm90YXRlTWF0ID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgIGdsX21hdHJpeF8xLm1hdDMuZnJvbVJvdGF0aW9uKHJvdGF0ZU1hdCwgcmFkKTtcbiAgICByZXR1cm4gZ2xfbWF0cml4XzEubWF0My5tdWx0aXBseShvdXQsIHJvdGF0ZU1hdCwgYSk7XG59XG5leHBvcnRzLmxlZnRSb3RhdGUgPSBsZWZ0Um90YXRlO1xuZnVuY3Rpb24gbGVmdFNjYWxlKG91dCwgYSwgdikge1xuICAgIHZhciBzY2FsZU1hdCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgICBnbF9tYXRyaXhfMS5tYXQzLmZyb21TY2FsaW5nKHNjYWxlTWF0LCB2KTtcbiAgICByZXR1cm4gZ2xfbWF0cml4XzEubWF0My5tdWx0aXBseShvdXQsIHNjYWxlTWF0LCBhKTtcbn1cbmV4cG9ydHMubGVmdFNjYWxlID0gbGVmdFNjYWxlO1xuZnVuY3Rpb24gbGVmdE11bHRpcGx5KG91dCwgYSwgYTEpIHtcbiAgICByZXR1cm4gZ2xfbWF0cml4XzEubWF0My5tdWx0aXBseShvdXQsIGExLCBhKTtcbn1cbi8qKlxuICog5qC55o2uIGFjdGlvbnMg5p2l5YGaIHRyYW5zZm9ybVxuICogQHBhcmFtIG1cbiAqIEBwYXJhbSBhY3Rpb25zXG4gKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybShtLCBhY3Rpb25zKSB7XG4gICAgdmFyIG1hdHJpeCA9IG0gPyBbXS5jb25jYXQobSkgOiBbMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMV07XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFjdGlvbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGFjdGlvbiA9IGFjdGlvbnNbaV07XG4gICAgICAgIHN3aXRjaCAoYWN0aW9uWzBdKSB7XG4gICAgICAgICAgICBjYXNlICd0JzpcbiAgICAgICAgICAgICAgICBsZWZ0VHJhbnNsYXRlKG1hdHJpeCwgbWF0cml4LCBbYWN0aW9uWzFdLCBhY3Rpb25bMl1dKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3MnOlxuICAgICAgICAgICAgICAgIGxlZnRTY2FsZShtYXRyaXgsIG1hdHJpeCwgW2FjdGlvblsxXSwgYWN0aW9uWzJdXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdyJzpcbiAgICAgICAgICAgICAgICBsZWZ0Um90YXRlKG1hdHJpeCwgbWF0cml4LCBhY3Rpb25bMV0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbSc6XG4gICAgICAgICAgICAgICAgbGVmdE11bHRpcGx5KG1hdHJpeCwgbWF0cml4LCBhY3Rpb25bMV0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWF0cml4O1xufVxuZXhwb3J0cy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4vKipcbiAqIOWQkemHjyB2MSDliLAg5ZCR6YePIHYyIOWkueinkueahOaWueWQkVxuICogQHBhcmFtICB7QXJyYXl9IHYxIOWQkemHj1xuICogQHBhcmFtICB7QXJyYXl9IHYyIOWQkemHj1xuICogQHJldHVybiB7Qm9vbGVhbn0gPj0gMCDpobrml7bpkoggPCAwIOmAhuaXtumSiFxuICovXG5mdW5jdGlvbiBkaXJlY3Rpb24odjEsIHYyKSB7XG4gICAgcmV0dXJuIHYxWzBdICogdjJbMV0gLSB2MlswXSAqIHYxWzFdO1xufVxuZXhwb3J0cy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4vKipcbiAqIOS6jOe7tOWQkemHjyB2MSDliLAgdjIg55qE5aS56KeSXG4gKiBAcGFyYW0gdjFcbiAqIEBwYXJhbSB2MlxuICogQHBhcmFtIGRpcmVjdFxuICovXG5mdW5jdGlvbiBhbmdsZVRvKHYxLCB2MiwgZGlyZWN0KSB7XG4gICAgdmFyIGFuZyA9IGdsX21hdHJpeF8xLnZlYzIuYW5nbGUodjEsIHYyKTtcbiAgICB2YXIgYW5nbGVMYXJnZVRoYW5QSSA9IGRpcmVjdGlvbih2MSwgdjIpID49IDA7XG4gICAgaWYgKGRpcmVjdCkge1xuICAgICAgICBpZiAoYW5nbGVMYXJnZVRoYW5QSSkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguUEkgKiAyIC0gYW5nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmc7XG4gICAgfVxuICAgIGlmIChhbmdsZUxhcmdlVGhhblBJKSB7XG4gICAgICAgIHJldHVybiBhbmc7XG4gICAgfVxuICAgIHJldHVybiBNYXRoLlBJICogMiAtIGFuZztcbn1cbmV4cG9ydHMuYW5nbGVUbyA9IGFuZ2xlVG87XG4vKipcbiAqIOiuoeeul+S6jOe7tOWQkemHj+eahOWeguebtOWQkemHj1xuICogQHBhcmFtIG91dFxuICogQHBhcmFtIHZcbiAqIEBwYXJhbSBmbGFnXG4gKi9cbmZ1bmN0aW9uIHZlcnRpY2FsKG91dCwgdiwgZmxhZykge1xuICAgIGlmIChmbGFnKSB7XG4gICAgICAgIG91dFswXSA9IHZbMV07XG4gICAgICAgIG91dFsxXSA9IC0xICogdlswXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG91dFswXSA9IC0xICogdlsxXTtcbiAgICAgICAgb3V0WzFdID0gdlswXTtcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbn1cbmV4cG9ydHMudmVydGljYWwgPSB2ZXJ0aWNhbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV4dC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBnbF9tYXRyaXhfMSA9IHJlcXVpcmUoXCJnbC1tYXRyaXhcIik7XG5leHBvcnRzLm1hdDMgPSBnbF9tYXRyaXhfMS5tYXQzO1xuZXhwb3J0cy52ZWMyID0gZ2xfbWF0cml4XzEudmVjMjtcbmV4cG9ydHMudmVjMyA9IGdsX21hdHJpeF8xLnZlYzM7XG52YXIgZXh0ID0gcmVxdWlyZShcIi4vZXh0XCIpO1xuZXhwb3J0cy5leHQgPSBleHQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIGh0dHA6Ly9zY2hlcGVycy5jYy9nZXR0aW5nLXRvLXRoZS1wb2ludFxuZnVuY3Rpb24gY2F0bXVsbFJvbTJCZXppZXIoY3JwLCB6KSB7XG4gICAgdmFyIGQgPSBbXTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgZm9yICh2YXIgaSA9IDAsIGlMZW4gPSBjcnAubGVuZ3RoOyBpTGVuIC0gMiAqICF6ID4gaTsgaSArPSAyKSB7XG4gICAgICAgIHZhciBwID0gW3tcbiAgICAgICAgICAgICAgICB4OiArY3JwW2kgLSAyXSxcbiAgICAgICAgICAgICAgICB5OiArY3JwW2kgLSAxXSxcbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICB4OiArY3JwW2ldLFxuICAgICAgICAgICAgICAgIHk6ICtjcnBbaSArIDFdLFxuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgIHg6ICtjcnBbaSArIDJdLFxuICAgICAgICAgICAgICAgIHk6ICtjcnBbaSArIDNdLFxuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgIHg6ICtjcnBbaSArIDRdLFxuICAgICAgICAgICAgICAgIHk6ICtjcnBbaSArIDVdLFxuICAgICAgICAgICAgfV07XG4gICAgICAgIGlmICh6KSB7XG4gICAgICAgICAgICBpZiAoIWkpIHtcbiAgICAgICAgICAgICAgICBwWzBdID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiArY3JwW2lMZW4gLSAyXSxcbiAgICAgICAgICAgICAgICAgICAgeTogK2NycFtpTGVuIC0gMV0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlMZW4gLSA0ID09PSBpKSB7XG4gICAgICAgICAgICAgICAgcFszXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogK2NycFswXSxcbiAgICAgICAgICAgICAgICAgICAgeTogK2NycFsxXSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaUxlbiAtIDIgPT09IGkpIHtcbiAgICAgICAgICAgICAgICBwWzJdID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiArY3JwWzBdLFxuICAgICAgICAgICAgICAgICAgICB5OiArY3JwWzFdLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcFszXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgeDogK2NycFsyXSxcbiAgICAgICAgICAgICAgICAgICAgeTogK2NycFszXSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGlMZW4gLSA0ID09PSBpKSB7XG4gICAgICAgICAgICAgICAgcFszXSA9IHBbMl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghaSkge1xuICAgICAgICAgICAgICAgIHBbMF0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6ICtjcnBbaV0sXG4gICAgICAgICAgICAgICAgICAgIHk6ICtjcnBbaSArIDFdLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZC5wdXNoKFsnQycsXG4gICAgICAgICAgICAoLXBbMF0ueCArIDYgKiBwWzFdLnggKyBwWzJdLngpIC8gNixcbiAgICAgICAgICAgICgtcFswXS55ICsgNiAqIHBbMV0ueSArIHBbMl0ueSkgLyA2LFxuICAgICAgICAgICAgKHBbMV0ueCArIDYgKiBwWzJdLnggLSBwWzNdLngpIC8gNixcbiAgICAgICAgICAgIChwWzFdLnkgKyA2ICogcFsyXS55IC0gcFszXS55KSAvIDYsXG4gICAgICAgICAgICBwWzJdLngsXG4gICAgICAgICAgICBwWzJdLnksXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICByZXR1cm4gZDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGNhdG11bGxSb20yQmV6aWVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2F0bXVsbC1yb20tMi1iZXppZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfZXF1YWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1lcXVhbFwiKTtcbmZ1bmN0aW9uIGdldE1pbkRpZmYoZGVsLCBhZGQsIG1vZGlmeSkge1xuICAgIHZhciB0eXBlID0gbnVsbDtcbiAgICB2YXIgbWluID0gbW9kaWZ5O1xuICAgIGlmIChhZGQgPCBtaW4pIHtcbiAgICAgICAgbWluID0gYWRkO1xuICAgICAgICB0eXBlID0gJ2FkZCc7XG4gICAgfVxuICAgIGlmIChkZWwgPCBtaW4pIHtcbiAgICAgICAgbWluID0gZGVsO1xuICAgICAgICB0eXBlID0gJ2RlbCc7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgIG1pbjogbWluLFxuICAgIH07XG59XG4vKlxuICogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV2ZW5zaHRlaW5fZGlzdGFuY2VcbiAqIOiuoeeul+S4pOadoXBhdGjnmoTnvJbovpHot53nprtcbiAqL1xudmFyIGxldmVuc2h0ZWluRGlzdGFuY2UgPSBmdW5jdGlvbiAoc291cmNlLCB0YXJnZXQpIHtcbiAgICB2YXIgc291cmNlTGVuID0gc291cmNlLmxlbmd0aDtcbiAgICB2YXIgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aDtcbiAgICB2YXIgc291cmNlU2VnbWVudCwgdGFyZ2V0U2VnbWVudDtcbiAgICB2YXIgdGVtcCA9IDA7XG4gICAgaWYgKHNvdXJjZUxlbiA9PT0gMCB8fCB0YXJnZXRMZW4gPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBkaXN0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPD0gc291cmNlTGVuOyBpKyspIHtcbiAgICAgICAgZGlzdFtpXSA9IFtdO1xuICAgICAgICBkaXN0W2ldWzBdID0geyBtaW46IGkgfTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gdGFyZ2V0TGVuOyBqKyspIHtcbiAgICAgICAgZGlzdFswXVtqXSA9IHsgbWluOiBqIH07XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IHNvdXJjZUxlbjsgaSsrKSB7XG4gICAgICAgIHNvdXJjZVNlZ21lbnQgPSBzb3VyY2VbaSAtIDFdO1xuICAgICAgICBmb3IgKHZhciBqID0gMTsgaiA8PSB0YXJnZXRMZW47IGorKykge1xuICAgICAgICAgICAgdGFyZ2V0U2VnbWVudCA9IHRhcmdldFtqIC0gMV07XG4gICAgICAgICAgICBpZiAoaXNfZXF1YWxfMS5kZWZhdWx0KHNvdXJjZVNlZ21lbnQsIHRhcmdldFNlZ21lbnQpKSB7XG4gICAgICAgICAgICAgICAgdGVtcCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ZW1wID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkZWwgPSBkaXN0W2kgLSAxXVtqXS5taW4gKyAxO1xuICAgICAgICAgICAgdmFyIGFkZCA9IGRpc3RbaV1baiAtIDFdLm1pbiArIDE7XG4gICAgICAgICAgICB2YXIgbW9kaWZ5ID0gZGlzdFtpIC0gMV1baiAtIDFdLm1pbiArIHRlbXA7XG4gICAgICAgICAgICBkaXN0W2ldW2pdID0gZ2V0TWluRGlmZihkZWwsIGFkZCwgbW9kaWZ5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGlzdDtcbn07XG5mdW5jdGlvbiBmaWxsUGF0aEJ5RGlmZihzb3VyY2UsIHRhcmdldCkge1xuICAgIHZhciBkaWZmTWF0cml4ID0gbGV2ZW5zaHRlaW5EaXN0YW5jZShzb3VyY2UsIHRhcmdldCk7XG4gICAgdmFyIHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGg7XG4gICAgdmFyIHRhcmdldExlbiA9IHRhcmdldC5sZW5ndGg7XG4gICAgdmFyIGNoYW5nZXMgPSBbXTtcbiAgICB2YXIgaW5kZXggPSAxO1xuICAgIHZhciBtaW5Qb3MgPSAxO1xuICAgIC8vIOWmguaenHNvdXJjZeWSjHRhcmdldOS4jeaYr+WujOWFqOS4jeebuOetiVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBpZiAoZGlmZk1hdHJpeFtzb3VyY2VMZW5dW3RhcmdldExlbl0gIT09IHNvdXJjZUxlbikge1xuICAgICAgICAvLyDojrflj5bku45zb3VyY2XliLB0YXJnZXTmiYDpnIDmlLnliqhcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gc291cmNlTGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBtaW4gPSBkaWZmTWF0cml4W2ldW2ldLm1pbjtcbiAgICAgICAgICAgIG1pblBvcyA9IGk7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gaW5kZXg7IGogPD0gdGFyZ2V0TGVuOyBqKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoZGlmZk1hdHJpeFtpXVtqXS5taW4gPCBtaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgbWluID0gZGlmZk1hdHJpeFtpXVtqXS5taW47XG4gICAgICAgICAgICAgICAgICAgIG1pblBvcyA9IGo7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kZXggPSBtaW5Qb3M7XG4gICAgICAgICAgICBpZiAoZGlmZk1hdHJpeFtpXVtpbmRleF0udHlwZSkge1xuICAgICAgICAgICAgICAgIGNoYW5nZXMucHVzaCh7IGluZGV4OiBpIC0gMSwgdHlwZTogZGlmZk1hdHJpeFtpXVtpbmRleF0udHlwZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyDlr7lzb3VyY2Xov5vooYzlop7liKBwYXRoXG4gICAgICAgIGZvciAodmFyIGkgPSBjaGFuZ2VzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBpbmRleCA9IGNoYW5nZXNbaV0uaW5kZXg7XG4gICAgICAgICAgICBpZiAoY2hhbmdlc1tpXS50eXBlID09PSAnYWRkJykge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3BsaWNlKGluZGV4LCAwLCBbXS5jb25jYXQoc291cmNlW2luZGV4XSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIHNvdXJjZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHNvdXJjZeWwvumDqOihpem9kFxuICAgIHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGg7XG4gICAgaWYgKHNvdXJjZUxlbiA8IHRhcmdldExlbikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8ICh0YXJnZXRMZW4gLSBzb3VyY2VMZW4pOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChzb3VyY2Vbc291cmNlTGVuIC0gMV1bMF0gPT09ICd6JyB8fCBzb3VyY2Vbc291cmNlTGVuIC0gMV1bMF0gPT09ICdaJykge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3BsaWNlKHNvdXJjZUxlbiAtIDIsIDAsIHNvdXJjZVtzb3VyY2VMZW4gLSAyXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgc291cmNlLnB1c2goc291cmNlW3NvdXJjZUxlbiAtIDFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc291cmNlO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZmlsbFBhdGhCeURpZmY7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maWxsLXBhdGgtYnktZGlmZi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGRlY2FzdGVsamF1KHBvaW50cywgdCkge1xuICAgIHZhciBsZWZ0ID0gW107XG4gICAgdmFyIHJpZ2h0ID0gW107XG4gICAgZnVuY3Rpb24gcmVjdXJzZShwb2ludHMsIHQpIHtcbiAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIGxlZnQucHVzaChwb2ludHNbMF0pO1xuICAgICAgICAgICAgcmlnaHQucHVzaChwb2ludHNbMF0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIG1pZGRsZVBvaW50cyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgbGVmdC5wdXNoKHBvaW50c1swXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpID09PSBwb2ludHMubGVuZ3RoIC0gMikge1xuICAgICAgICAgICAgICAgICAgICByaWdodC5wdXNoKHBvaW50c1tpICsgMV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBtaWRkbGVQb2ludHNbaV0gPSBbKDEgLSB0KSAqIHBvaW50c1tpXVswXSArIHQgKiBwb2ludHNbaSArIDFdWzBdLCAoMSAtIHQpICogcG9pbnRzW2ldWzFdICsgdCAqIHBvaW50c1tpICsgMV1bMV1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVjdXJzZShtaWRkbGVQb2ludHMsIHQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChwb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIHJlY3Vyc2UocG9pbnRzLCB0KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgbGVmdDogbGVmdCwgcmlnaHQ6IHJpZ2h0LnJldmVyc2UoKSB9O1xufVxuZnVuY3Rpb24gc3BsaXRDdXJ2ZShzdGFydCwgZW5kLCBjb3VudCkge1xuICAgIHZhciBwb2ludHMgPSBbW3N0YXJ0WzFdLCBzdGFydFsyXV1dO1xuICAgIGNvdW50ID0gY291bnQgfHwgMjtcbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcbiAgICBpZiAoZW5kWzBdID09PSAnQScpIHtcbiAgICAgICAgcG9pbnRzLnB1c2goZW5kWzZdKTtcbiAgICAgICAgcG9pbnRzLnB1c2goZW5kWzddKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZW5kWzBdID09PSAnQycpIHtcbiAgICAgICAgcG9pbnRzLnB1c2goW2VuZFsxXSwgZW5kWzJdXSk7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbM10sIGVuZFs0XV0pO1xuICAgICAgICBwb2ludHMucHVzaChbZW5kWzVdLCBlbmRbNl1dKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZW5kWzBdID09PSAnUycgfHwgZW5kWzBdID09PSAnUScpIHtcbiAgICAgICAgcG9pbnRzLnB1c2goW2VuZFsxXSwgZW5kWzJdXSk7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbM10sIGVuZFs0XV0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcG9pbnRzLnB1c2goW2VuZFsxXSwgZW5kWzJdXSk7XG4gICAgfVxuICAgIHZhciBsZWZ0U2VnbWVudHMgPSBwb2ludHM7XG4gICAgdmFyIHQgPSAxIC8gY291bnQ7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudCAtIDE7IGkrKykge1xuICAgICAgICB2YXIgcnQgPSB0IC8gKDEgLSB0ICogaSk7XG4gICAgICAgIHZhciBzcGxpdCA9IGRlY2FzdGVsamF1KGxlZnRTZWdtZW50cywgcnQpO1xuICAgICAgICBzZWdtZW50cy5wdXNoKHNwbGl0LmxlZnQpO1xuICAgICAgICBsZWZ0U2VnbWVudHMgPSBzcGxpdC5yaWdodDtcbiAgICB9XG4gICAgc2VnbWVudHMucHVzaChsZWZ0U2VnbWVudHMpO1xuICAgIHZhciByZXN1bHQgPSBzZWdtZW50cy5tYXAoZnVuY3Rpb24gKHNlZ21lbnQpIHtcbiAgICAgICAgdmFyIGNtZCA9IFtdO1xuICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAgIGNtZC5wdXNoKCdDJyk7XG4gICAgICAgICAgICBjbWQgPSBjbWQuY29uY2F0KHNlZ21lbnRbMl0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWdtZW50Lmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICAgICAgICBjbWQucHVzaCgnUScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY21kID0gY21kLmNvbmNhdChzZWdtZW50WzFdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGNtZC5wdXNoKCdMJyk7XG4gICAgICAgIH1cbiAgICAgICAgY21kID0gY21kLmNvbmNhdChzZWdtZW50W3NlZ21lbnQubGVuZ3RoIC0gMV0pO1xuICAgICAgICByZXR1cm4gY21kO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBzcGxpdFNlZ21lbnQoc3RhcnQsIGVuZCwgY291bnQpIHtcbiAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIFtbXS5jb25jYXQoc3RhcnQpXTtcbiAgICB9XG4gICAgdmFyIHNlZ21lbnRzID0gW107XG4gICAgaWYgKGVuZFswXSA9PT0gJ0wnIHx8IGVuZFswXSA9PT0gJ0MnIHx8IGVuZFswXSA9PT0gJ1EnKSB7XG4gICAgICAgIHNlZ21lbnRzID0gc2VnbWVudHMuY29uY2F0KHNwbGl0Q3VydmUoc3RhcnQsIGVuZCwgY291bnQpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciB0ZW1wID0gW10uY29uY2F0KHN0YXJ0KTtcbiAgICAgICAgaWYgKHRlbXBbMF0gPT09ICdNJykge1xuICAgICAgICAgICAgdGVtcFswXSA9ICdMJztcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBjb3VudCAtIDE7IGkrKykge1xuICAgICAgICAgICAgc2VnbWVudHMucHVzaCh0ZW1wKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc2VnbWVudHM7XG59XG5mdW5jdGlvbiBmaWxsUGF0aChzb3VyY2UsIHRhcmdldCkge1xuICAgIGlmIChzb3VyY2UubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfVxuICAgIHZhciBzb3VyY2VMZW4gPSBzb3VyY2UubGVuZ3RoIC0gMTtcbiAgICB2YXIgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aCAtIDE7XG4gICAgdmFyIHJhdGlvID0gc291cmNlTGVuIC8gdGFyZ2V0TGVuO1xuICAgIHZhciBzZWdtZW50c1RvRmlsbCA9IFtdO1xuICAgIGlmIChzb3VyY2UubGVuZ3RoID09PSAxICYmIHNvdXJjZVswXVswXSA9PT0gJ00nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFyZ2V0TGVuIC0gc291cmNlTGVuOyBpKyspIHtcbiAgICAgICAgICAgIHNvdXJjZS5wdXNoKHNvdXJjZVswXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YXJnZXRMZW47IGkrKykge1xuICAgICAgICB2YXIgaW5kZXggPSBNYXRoLmZsb29yKHJhdGlvICogaSk7XG4gICAgICAgIHNlZ21lbnRzVG9GaWxsW2luZGV4XSA9IChzZWdtZW50c1RvRmlsbFtpbmRleF0gfHwgMCkgKyAxO1xuICAgIH1cbiAgICB2YXIgZmlsbGVkID0gc2VnbWVudHNUb0ZpbGwucmVkdWNlKGZ1bmN0aW9uIChmaWxsZWQsIGNvdW50LCBpKSB7XG4gICAgICAgIGlmIChpID09PSBzb3VyY2VMZW4pIHtcbiAgICAgICAgICAgIHJldHVybiBmaWxsZWQuY29uY2F0KHNvdXJjZVtzb3VyY2VMZW5dKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsbGVkLmNvbmNhdChzcGxpdFNlZ21lbnQoc291cmNlW2ldLCBzb3VyY2VbaSArIDFdLCBjb3VudCkpO1xuICAgIH0sIFtdKTtcbiAgICBmaWxsZWQudW5zaGlmdChzb3VyY2VbMF0pO1xuICAgIGlmICh0YXJnZXRbdGFyZ2V0TGVuXSA9PT0gJ1onIHx8IHRhcmdldFt0YXJnZXRMZW5dID09PSAneicpIHtcbiAgICAgICAgZmlsbGVkLnB1c2goJ1onKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGxlZDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGZpbGxQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsbC1wYXRoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLypcbiAqIOaKveWPlnBhdGhTZWdtZW505Lit55qE5YWz6ZSu54K5XG4gKiBNLEwsQSxRLEgsVuS4gOS4querr+eCuVxuICogUSwgU+aKveWPluS4gOS4querr+eCue+8jOS4gOS4quaOp+WItueCuVxuICogQ+aKveWPluS4gOS4querr+eCue+8jOS4pOS4quaOp+WItueCuVxuICovXG5mdW5jdGlvbiBfZ2V0U2VnbWVudFBvaW50cyhzZWdtZW50KSB7XG4gICAgdmFyIHBvaW50cyA9IFtdO1xuICAgIHN3aXRjaCAoc2VnbWVudFswXSkge1xuICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzFdLCBzZWdtZW50WzJdXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbNl0sIHNlZ21lbnRbN11dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdRJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzNdLCBzZWdtZW50WzRdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbMV0sIHNlZ21lbnRbMl1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdDJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzVdLCBzZWdtZW50WzZdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbM10sIHNlZ21lbnRbNF1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzNdLCBzZWdtZW50WzRdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbMV0sIHNlZ21lbnRbMV1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzFdLCBzZWdtZW50WzFdXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50cztcbn1cbi8vIOWwhuS4pOS4queCueWdh+WIhuaIkGNvdW505Liq54K5XG5mdW5jdGlvbiBfc3BsaXRQb2ludHMocG9pbnRzLCBmb3JtZXIsIGNvdW50KSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdLmNvbmNhdChwb2ludHMpO1xuICAgIHZhciBpbmRleDtcbiAgICB2YXIgdCA9IDEgLyAoY291bnQgKyAxKTtcbiAgICB2YXIgZm9ybWVyRW5kID0gX2dldFNlZ21lbnRQb2ludHMoZm9ybWVyKVswXTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8PSBjb3VudDsgaSsrKSB7XG4gICAgICAgIHQgKj0gaTtcbiAgICAgICAgaW5kZXggPSBNYXRoLmZsb29yKHBvaW50cy5sZW5ndGggKiB0KTtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICByZXN1bHQudW5zaGlmdChbZm9ybWVyRW5kWzBdICogdCArIHBvaW50c1tpbmRleF1bMF0gKiAoMSAtIHQpLCBmb3JtZXJFbmRbMV0gKiB0ICsgcG9pbnRzW2luZGV4XVsxXSAqICgxIC0gdCldKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdC5zcGxpY2UoaW5kZXgsIDAsIFtmb3JtZXJFbmRbMF0gKiB0ICsgcG9pbnRzW2luZGV4XVswXSAqICgxIC0gdCksIGZvcm1lckVuZFsxXSAqIHQgKyBwb2ludHNbaW5kZXhdWzFdICogKDEgLSB0KV0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBmb3JtYXRQYXRoKGZyb21QYXRoLCB0b1BhdGgpIHtcbiAgICBpZiAoZnJvbVBhdGgubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIGZyb21QYXRoO1xuICAgIH1cbiAgICB2YXIgcG9pbnRzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9QYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChmcm9tUGF0aFtpXVswXSAhPT0gdG9QYXRoW2ldWzBdKSB7XG4gICAgICAgICAgICAvLyDojrflj5Zmcm9tUGF0aOeahHBhdGhTZWdtZW5055qE56uv54K577yM5qC55o2udG9QYXRo55qE5oyH5Luk5a+55YW25pS56YCgXG4gICAgICAgICAgICBwb2ludHMgPSBfZ2V0U2VnbWVudFBvaW50cyhmcm9tUGF0aFtpXSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRvUGF0aFtpXVswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ00nOlxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnTSddLmNvbmNhdChwb2ludHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGhbaV0gPSBbJ0wnXS5jb25jYXQocG9pbnRzWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gW10uY29uY2F0KHRvUGF0aFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldWzZdID0gcG9pbnRzWzBdWzBdO1xuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXVs3XSA9IHBvaW50c1swXVsxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzID0gX3NwbGl0UG9pbnRzKHBvaW50cywgZnJvbVBhdGhbaSAtIDFdLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gWydRJ10uY29uY2F0KHBvaW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFyciwgaSkgeyByZXR1cm4gYXJyLmNvbmNhdChpKTsgfSwgW10pKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnVCc6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gWydUJ10uY29uY2F0KHBvaW50c1swXSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ0MnOlxuICAgICAgICAgICAgICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyA9IF9zcGxpdFBvaW50cyhwb2ludHMsIGZyb21QYXRoW2kgLSAxXSwgMik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IHRvUGF0aFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnQyddLmNvbmNhdChwb2ludHMucmVkdWNlKGZ1bmN0aW9uIChhcnIsIGkpIHsgcmV0dXJuIGFyci5jb25jYXQoaSk7IH0sIFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1MnOlxuICAgICAgICAgICAgICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyA9IF9zcGxpdFBvaW50cyhwb2ludHMsIGZyb21QYXRoW2kgLSAxXSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IHRvUGF0aFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnUyddLmNvbmNhdChwb2ludHMucmVkdWNlKGZ1bmN0aW9uIChhcnIsIGkpIHsgcmV0dXJuIGFyci5jb25jYXQoaSk7IH0sIFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmcm9tUGF0aDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGZvcm1hdFBhdGg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mb3JtYXQtcGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBtb2RfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9tb2RcIik7XG52YXIgdG9fcmFkaWFuXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvdG8tcmFkaWFuXCIpO1xuLy8g5ZCR6YeP6ZW/5bqmXG5mdW5jdGlvbiB2TWFnKHYpIHtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KHZbMF0gKiB2WzBdICsgdlsxXSAqIHZbMV0pO1xufVxuLy8gdS52L3x1fHx2fO+8jOiuoeeul+WkueinkueahOS9meW8puWAvFxuZnVuY3Rpb24gdlJhdGlvKHUsIHYpIHtcbiAgICAvLyDlvZPlrZjlnKjkuIDkuKrlkJHph4/nmoTplb/luqbkuLogMCDml7bvvIzlpLnop5LkuZ/kuLogMO+8jOWNs+WkueinkueahOS9meW8puWAvOS4uiAxXG4gICAgcmV0dXJuIHZNYWcodSkgKiB2TWFnKHYpID8gKHVbMF0gKiB2WzBdICsgdVsxXSAqIHZbMV0pIC8gKHZNYWcodSkgKiB2TWFnKHYpKSA6IDE7XG59XG4vLyDlkJHph4/op5LluqZcbmZ1bmN0aW9uIHZBbmdsZSh1LCB2KSB7XG4gICAgcmV0dXJuICh1WzBdICogdlsxXSA8IHVbMV0gKiB2WzBdID8gLTEgOiAxKSAqIE1hdGguYWNvcyh2UmF0aW8odSwgdikpO1xufVxuLyoqXG4gKiDliKTmlq3kuKTkuKrngrnmmK/lkKbph43lkIjvvIzngrnlnZDmoIfnmoTmoLzlvI/kuLogW3gsIHldXG4gKiBAcGFyYW0ge0FycmF5fSBwb2ludDEg56ys5LiA5Liq54K5XG4gKiBAcGFyYW0ge0FycmF5fSBwb2ludDIg56ys5LqM5Liq54K5XG4gKi9cbmZ1bmN0aW9uIGlzU2FtZVBvaW50KHBvaW50MSwgcG9pbnQyKSB7XG4gICAgcmV0dXJuIHBvaW50MVswXSA9PT0gcG9pbnQyWzBdICYmIHBvaW50MVsxXSA9PT0gcG9pbnQyWzFdO1xufVxuZXhwb3J0cy5pc1NhbWVQb2ludCA9IGlzU2FtZVBvaW50O1xuLy8gQSAwOnJ4IDE6cnkgMjp4LWF4aXMtcm90YXRpb24gMzpsYXJnZS1hcmMtZmxhZyA0OnN3ZWVwLWZsYWcgNTogeCA2OiB5XG5mdW5jdGlvbiBnZXRBcmNQYXJhbXMoc3RhcnRQb2ludCwgcGFyYW1zKSB7XG4gICAgdmFyIHJ4ID0gcGFyYW1zWzFdO1xuICAgIHZhciByeSA9IHBhcmFtc1syXTtcbiAgICB2YXIgeFJvdGF0aW9uID0gbW9kXzEuZGVmYXVsdCh0b19yYWRpYW5fMS5kZWZhdWx0KHBhcmFtc1szXSksIE1hdGguUEkgKiAyKTtcbiAgICB2YXIgYXJjRmxhZyA9IHBhcmFtc1s0XTtcbiAgICB2YXIgc3dlZXBGbGFnID0gcGFyYW1zWzVdO1xuICAgIC8vIOW8p+W9oui1t+eCueWdkOagh1xuICAgIHZhciB4MSA9IHN0YXJ0UG9pbnRbMF07XG4gICAgdmFyIHkxID0gc3RhcnRQb2ludFsxXTtcbiAgICAvLyDlvKflvaLnu4jngrnlnZDmoIdcbiAgICB2YXIgeDIgPSBwYXJhbXNbNl07XG4gICAgdmFyIHkyID0gcGFyYW1zWzddO1xuICAgIHZhciB4cCA9IChNYXRoLmNvcyh4Um90YXRpb24pICogKHgxIC0geDIpKSAvIDIuMCArIChNYXRoLnNpbih4Um90YXRpb24pICogKHkxIC0geTIpKSAvIDIuMDtcbiAgICB2YXIgeXAgPSAoLTEgKiBNYXRoLnNpbih4Um90YXRpb24pICogKHgxIC0geDIpKSAvIDIuMCArIChNYXRoLmNvcyh4Um90YXRpb24pICogKHkxIC0geTIpKSAvIDIuMDtcbiAgICB2YXIgbGFtYmRhID0gKHhwICogeHApIC8gKHJ4ICogcngpICsgKHlwICogeXApIC8gKHJ5ICogcnkpO1xuICAgIGlmIChsYW1iZGEgPiAxKSB7XG4gICAgICAgIHJ4ICo9IE1hdGguc3FydChsYW1iZGEpO1xuICAgICAgICByeSAqPSBNYXRoLnNxcnQobGFtYmRhKTtcbiAgICB9XG4gICAgdmFyIGRpZmYgPSByeCAqIHJ4ICogKHlwICogeXApICsgcnkgKiByeSAqICh4cCAqIHhwKTtcbiAgICB2YXIgZiA9IGRpZmYgPyBNYXRoLnNxcnQoKHJ4ICogcnggKiAocnkgKiByeSkgLSBkaWZmKSAvIGRpZmYpIDogMTtcbiAgICBpZiAoYXJjRmxhZyA9PT0gc3dlZXBGbGFnKSB7XG4gICAgICAgIGYgKj0gLTE7XG4gICAgfVxuICAgIGlmIChpc05hTihmKSkge1xuICAgICAgICBmID0gMDtcbiAgICB9XG4gICAgLy8g5peL6L2s5YmN55qE6LW354K55Z2Q5qCH77yM5LiU5b2T6ZW/5Y2K6L205ZKM55+t5Y2K6L2055qE6ZW/5bqm5Li6IDAg5pe277yM5Z2Q5qCH5oyJICgwLCAwKSDlpITnkIZcbiAgICB2YXIgY3hwID0gcnkgPyAoZiAqIHJ4ICogeXApIC8gcnkgOiAwO1xuICAgIHZhciBjeXAgPSByeCA/IChmICogLXJ5ICogeHApIC8gcnggOiAwO1xuICAgIC8vIOakreWchuWchuW/g+WdkOagh1xuICAgIHZhciBjeCA9ICh4MSArIHgyKSAvIDIuMCArIE1hdGguY29zKHhSb3RhdGlvbikgKiBjeHAgLSBNYXRoLnNpbih4Um90YXRpb24pICogY3lwO1xuICAgIHZhciBjeSA9ICh5MSArIHkyKSAvIDIuMCArIE1hdGguc2luKHhSb3RhdGlvbikgKiBjeHAgKyBNYXRoLmNvcyh4Um90YXRpb24pICogY3lwO1xuICAgIC8vIOi1t+Wni+eCueeahOWNleS9jeWQkemHj1xuICAgIHZhciB1ID0gWyh4cCAtIGN4cCkgLyByeCwgKHlwIC0gY3lwKSAvIHJ5XTtcbiAgICAvLyDnu4jmraLngrnnmoTljZXkvY3lkJHph49cbiAgICB2YXIgdiA9IFsoLTEgKiB4cCAtIGN4cCkgLyByeCwgKC0xICogeXAgLSBjeXApIC8gcnldO1xuICAgIC8vIOiuoeeul+i1t+Wni+eCueWSjOWchuW/g+eahOi/nue6v++8jOS4jiB4IOi9tOato+aWueWQkeeahOWkueinklxuICAgIHZhciB0aGV0YSA9IHZBbmdsZShbMSwgMF0sIHUpO1xuICAgIC8vIOiuoeeul+WchuW8p+i1t+Wni+eCueWSjOe7iOatoueCueS4juakreWchuWchuW/g+i/nue6v+eahOWkueinklxuICAgIHZhciBkVGhldGEgPSB2QW5nbGUodSwgdik7XG4gICAgaWYgKHZSYXRpbyh1LCB2KSA8PSAtMSkge1xuICAgICAgICBkVGhldGEgPSBNYXRoLlBJO1xuICAgIH1cbiAgICBpZiAodlJhdGlvKHUsIHYpID49IDEpIHtcbiAgICAgICAgZFRoZXRhID0gMDtcbiAgICB9XG4gICAgaWYgKHN3ZWVwRmxhZyA9PT0gMCAmJiBkVGhldGEgPiAwKSB7XG4gICAgICAgIGRUaGV0YSA9IGRUaGV0YSAtIDIgKiBNYXRoLlBJO1xuICAgIH1cbiAgICBpZiAoc3dlZXBGbGFnID09PSAxICYmIGRUaGV0YSA8IDApIHtcbiAgICAgICAgZFRoZXRhID0gZFRoZXRhICsgMiAqIE1hdGguUEk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGN4OiBjeCxcbiAgICAgICAgY3k6IGN5LFxuICAgICAgICAvLyDlvKflvaLnmoTotbfngrnlkoznu4jngrnnm7jlkIzml7bvvIzplb/ovbTlkoznn63ovbTnmoTplb/luqbmjIkgMCDlpITnkIZcbiAgICAgICAgcng6IGlzU2FtZVBvaW50KHN0YXJ0UG9pbnQsIFt4MiwgeTJdKSA/IDAgOiByeCxcbiAgICAgICAgcnk6IGlzU2FtZVBvaW50KHN0YXJ0UG9pbnQsIFt4MiwgeTJdKSA/IDAgOiByeSxcbiAgICAgICAgc3RhcnRBbmdsZTogdGhldGEsXG4gICAgICAgIGVuZEFuZ2xlOiB0aGV0YSArIGRUaGV0YSxcbiAgICAgICAgeFJvdGF0aW9uOiB4Um90YXRpb24sXG4gICAgICAgIGFyY0ZsYWc6IGFyY0ZsYWcsXG4gICAgICAgIHN3ZWVwRmxhZzogc3dlZXBGbGFnLFxuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBnZXRBcmNQYXJhbXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXJjLXBhcmFtcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc0JldHdlZW4gPSBmdW5jdGlvbiAodmFsdWUsIG1pbiwgbWF4KSB7IHJldHVybiB2YWx1ZSA+PSBtaW4gJiYgdmFsdWUgPD0gbWF4OyB9O1xuZnVuY3Rpb24gZ2V0TGluZUludGVyc2VjdChwMCwgcDEsIHAyLCBwMykge1xuICAgIHZhciB0b2xlcmFuY2UgPSAwLjAwMTtcbiAgICB2YXIgRSA9IHtcbiAgICAgICAgeDogcDIueCAtIHAwLngsXG4gICAgICAgIHk6IHAyLnkgLSBwMC55LFxuICAgIH07XG4gICAgdmFyIEQwID0ge1xuICAgICAgICB4OiBwMS54IC0gcDAueCxcbiAgICAgICAgeTogcDEueSAtIHAwLnksXG4gICAgfTtcbiAgICB2YXIgRDEgPSB7XG4gICAgICAgIHg6IHAzLnggLSBwMi54LFxuICAgICAgICB5OiBwMy55IC0gcDIueSxcbiAgICB9O1xuICAgIHZhciBrcm9zcyA9IEQwLnggKiBEMS55IC0gRDAueSAqIEQxLng7XG4gICAgdmFyIHNxcktyb3NzID0ga3Jvc3MgKiBrcm9zcztcbiAgICB2YXIgc3FyTGVuMCA9IEQwLnggKiBEMC54ICsgRDAueSAqIEQwLnk7XG4gICAgdmFyIHNxckxlbjEgPSBEMS54ICogRDEueCArIEQxLnkgKiBEMS55O1xuICAgIHZhciBwb2ludCA9IG51bGw7XG4gICAgaWYgKHNxcktyb3NzID4gdG9sZXJhbmNlICogc3FyTGVuMCAqIHNxckxlbjEpIHtcbiAgICAgICAgdmFyIHMgPSAoRS54ICogRDEueSAtIEUueSAqIEQxLngpIC8ga3Jvc3M7XG4gICAgICAgIHZhciB0ID0gKEUueCAqIEQwLnkgLSBFLnkgKiBEMC54KSAvIGtyb3NzO1xuICAgICAgICBpZiAoaXNCZXR3ZWVuKHMsIDAsIDEpICYmIGlzQmV0d2Vlbih0LCAwLCAxKSkge1xuICAgICAgICAgICAgcG9pbnQgPSB7XG4gICAgICAgICAgICAgICAgeDogcDAueCArIHMgKiBEMC54LFxuICAgICAgICAgICAgICAgIHk6IHAwLnkgKyBzICogRDAueSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBvaW50O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0TGluZUludGVyc2VjdDtcbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1saW5lLWludGVyc2VjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBwYXJzZV9wYXRoXzEgPSByZXF1aXJlKFwiLi9wYXJzZS1wYXRoXCIpO1xuZXhwb3J0cy5wYXJzZVBhdGggPSBwYXJzZV9wYXRoXzEuZGVmYXVsdDtcbnZhciBjYXRtdWxsX3JvbV8yX2Jlemllcl8xID0gcmVxdWlyZShcIi4vY2F0bXVsbC1yb20tMi1iZXppZXJcIik7XG5leHBvcnRzLmNhdG11bGxSb20yQmV6aWVyID0gY2F0bXVsbF9yb21fMl9iZXppZXJfMS5kZWZhdWx0O1xudmFyIGZpbGxfcGF0aF8xID0gcmVxdWlyZShcIi4vZmlsbC1wYXRoXCIpO1xuZXhwb3J0cy5maWxsUGF0aCA9IGZpbGxfcGF0aF8xLmRlZmF1bHQ7XG52YXIgZmlsbF9wYXRoX2J5X2RpZmZfMSA9IHJlcXVpcmUoXCIuL2ZpbGwtcGF0aC1ieS1kaWZmXCIpO1xuZXhwb3J0cy5maWxsUGF0aEJ5RGlmZiA9IGZpbGxfcGF0aF9ieV9kaWZmXzEuZGVmYXVsdDtcbnZhciBmb3JtYXRfcGF0aF8xID0gcmVxdWlyZShcIi4vZm9ybWF0LXBhdGhcIik7XG5leHBvcnRzLmZvcm1hdFBhdGggPSBmb3JtYXRfcGF0aF8xLmRlZmF1bHQ7XG52YXIgcGF0aF9pbnRlcnNlY3Rpb25fMSA9IHJlcXVpcmUoXCIuL3BhdGgtaW50ZXJzZWN0aW9uXCIpO1xuZXhwb3J0cy5wYXRoSW50ZXJzZWN0aW9uID0gcGF0aF9pbnRlcnNlY3Rpb25fMS5kZWZhdWx0O1xudmFyIHBhcnNlX3BhdGhfYXJyYXlfMSA9IHJlcXVpcmUoXCIuL3BhcnNlLXBhdGgtYXJyYXlcIik7XG5leHBvcnRzLnBhcnNlUGF0aEFycmF5ID0gcGFyc2VfcGF0aF9hcnJheV8xLmRlZmF1bHQ7XG52YXIgcGFyc2VfcGF0aF9zdHJpbmdfMSA9IHJlcXVpcmUoXCIuL3BhcnNlLXBhdGgtc3RyaW5nXCIpO1xuZXhwb3J0cy5wYXJzZVBhdGhTdHJpbmcgPSBwYXJzZV9wYXRoX3N0cmluZ18xLmRlZmF1bHQ7XG52YXIgcGF0aF8yX2N1cnZlXzEgPSByZXF1aXJlKFwiLi9wYXRoLTItY3VydmVcIik7XG5leHBvcnRzLnBhdGgyQ3VydmUgPSBwYXRoXzJfY3VydmVfMS5kZWZhdWx0O1xudmFyIHBhdGhfMl9hYnNvbHV0ZV8xID0gcmVxdWlyZShcIi4vcGF0aC0yLWFic29sdXRlXCIpO1xuZXhwb3J0cy5wYXRoMkFic29sdXRlID0gcGF0aF8yX2Fic29sdXRlXzEuZGVmYXVsdDtcbnZhciByZWN0X3BhdGhfMSA9IHJlcXVpcmUoXCIuL3JlY3QtcGF0aFwiKTtcbmV4cG9ydHMucmVhY3RQYXRoID0gcmVjdF9wYXRoXzEuZGVmYXVsdDtcbnZhciBnZXRfYXJjX3BhcmFtc18xID0gcmVxdWlyZShcIi4vZ2V0LWFyYy1wYXJhbXNcIik7XG5leHBvcnRzLmdldEFyY1BhcmFtcyA9IGdldF9hcmNfcGFyYW1zXzEuZGVmYXVsdDtcbnZhciBwYXRoXzJfc2VnbWVudHNfMSA9IHJlcXVpcmUoXCIuL3BhdGgtMi1zZWdtZW50c1wiKTtcbmV4cG9ydHMucGF0aDJTZWdtZW50cyA9IHBhdGhfMl9zZWdtZW50c18xLmRlZmF1bHQ7XG52YXIgZ2V0X2xpbmVfaW50ZXJzZWN0XzEgPSByZXF1aXJlKFwiLi9nZXQtbGluZS1pbnRlcnNlY3RcIik7XG5leHBvcnRzLmdldExpbmVJbnRlcnNlY3QgPSBnZXRfbGluZV9pbnRlcnNlY3RfMS5kZWZhdWx0O1xudmFyIGlzX3BvbHlnb25zX2ludGVyc2VjdF8xID0gcmVxdWlyZShcIi4vaXMtcG9seWdvbnMtaW50ZXJzZWN0XCIpO1xuZXhwb3J0cy5pc1BvbHlnb25zSW50ZXJzZWN0ID0gaXNfcG9seWdvbnNfaW50ZXJzZWN0XzEuZGVmYXVsdDtcbnZhciBwb2ludF9pbl9wb2x5Z29uXzEgPSByZXF1aXJlKFwiLi9wb2ludC1pbi1wb2x5Z29uXCIpO1xuZXhwb3J0cy5pc1BvaW50SW5Qb2x5Z29uID0gcG9pbnRfaW5fcG9seWdvbl8xLmRlZmF1bHQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBwb2ludF9pbl9wb2x5Z29uXzEgPSByZXF1aXJlKFwiLi9wb2ludC1pbi1wb2x5Z29uXCIpO1xudmFyIGdldF9saW5lX2ludGVyc2VjdF8xID0gcmVxdWlyZShcIi4vZ2V0LWxpbmUtaW50ZXJzZWN0XCIpO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuZnVuY3Rpb24gcGFyc2VUb0xpbmVzKHBvaW50cykge1xuICAgIHZhciBsaW5lcyA9IFtdO1xuICAgIHZhciBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudCAtIDE7IGkrKykge1xuICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgIHZhciBuZXh0ID0gcG9pbnRzW2kgKyAxXTtcbiAgICAgICAgbGluZXMucHVzaCh7XG4gICAgICAgICAgICBmcm9tOiB7XG4gICAgICAgICAgICAgICAgeDogcG9pbnRbMF0sXG4gICAgICAgICAgICAgICAgeTogcG9pbnRbMV1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0bzoge1xuICAgICAgICAgICAgICAgIHg6IG5leHRbMF0sXG4gICAgICAgICAgICAgICAgeTogbmV4dFsxXVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGxpbmVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdmFyIGZpcnN0ID0gcG9pbnRzWzBdO1xuICAgICAgICB2YXIgbGFzdCA9IHBvaW50c1tjb3VudCAtIDFdO1xuICAgICAgICBsaW5lcy5wdXNoKHtcbiAgICAgICAgICAgIGZyb206IHtcbiAgICAgICAgICAgICAgICB4OiBsYXN0WzBdLFxuICAgICAgICAgICAgICAgIHk6IGxhc3RbMV1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0bzoge1xuICAgICAgICAgICAgICAgIHg6IGZpcnN0WzBdLFxuICAgICAgICAgICAgICAgIHk6IGZpcnN0WzFdXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbGluZXM7XG59XG5mdW5jdGlvbiBsaW5lSW50ZXJzZWN0UG9seWdvbihsaW5lcywgbGluZSkge1xuICAgIHZhciBpc0ludGVyc2VjdCA9IGZhbHNlO1xuICAgIHV0aWxfMS5lYWNoKGxpbmVzLCBmdW5jdGlvbiAobCkge1xuICAgICAgICBpZiAoZ2V0X2xpbmVfaW50ZXJzZWN0XzEuZGVmYXVsdChsLmZyb20sIGwudG8sIGxpbmUuZnJvbSwgbGluZS50bykpIHtcbiAgICAgICAgICAgIGlzSW50ZXJzZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBpc0ludGVyc2VjdDtcbn1cbmZ1bmN0aW9uIGdldEJCb3gocG9pbnRzKSB7XG4gICAgdmFyIHhBcnIgPSBwb2ludHMubWFwKGZ1bmN0aW9uIChwKSB7IHJldHVybiBwWzBdOyB9KTtcbiAgICB2YXIgeUFyciA9IHBvaW50cy5tYXAoZnVuY3Rpb24gKHApIHsgcmV0dXJuIHBbMV07IH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIG1pblg6IE1hdGgubWluLmFwcGx5KG51bGwsIHhBcnIpLFxuICAgICAgICBtYXhYOiBNYXRoLm1heC5hcHBseShudWxsLCB4QXJyKSxcbiAgICAgICAgbWluWTogTWF0aC5taW4uYXBwbHkobnVsbCwgeUFyciksXG4gICAgICAgIG1heFk6IE1hdGgubWF4LmFwcGx5KG51bGwsIHlBcnIpXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGludGVyc2VjdEJCb3goYm94MSwgYm94Mikge1xuICAgIHJldHVybiAhKGJveDIubWluWCA+IGJveDEubWF4WCB8fCBib3gyLm1heFggPCBib3gxLm1pblggfHwgYm94Mi5taW5ZID4gYm94MS5tYXhZIHx8IGJveDIubWF4WSA8IGJveDEubWluWSk7XG59XG5mdW5jdGlvbiBpc1BvbHlnb25zSW50ZXJzZWN0KHBvaW50czEsIHBvaW50czIpIHtcbiAgICAvLyDnqbrmlbDnu4TvvIzmiJbogIXkuIDkuKrngrnov5Tlm54gZmFsc2VcbiAgICBpZiAocG9pbnRzMS5sZW5ndGggPCAyIHx8IHBvaW50czIubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBiYm94MSA9IGdldEJCb3gocG9pbnRzMSk7XG4gICAgdmFyIGJib3gyID0gZ2V0QkJveChwb2ludHMyKTtcbiAgICAvLyDliKTlrprljIXlm7Tnm5LmmK/lkKbnm7jkuqTvvIzmr5TliKTlrprngrnmmK/lkKblnKjlpJrovrnlvaLlhoXopoHlv6vnmoTlpJrvvIzlj6/ku6XnrZvpgInmjonlpKflpJrmlbDmg4XlhrVcbiAgICBpZiAoIWludGVyc2VjdEJCb3goYmJveDEsIGJib3gyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBpc0luID0gZmFsc2U7XG4gICAgLy8g5Yik5a6a54K55piv5ZCm5Zyo5aSa6L655b2i5YaF6YOo77yM5LiA5pem5pyJ5LiA5Liq54K55Zyo5Y+m5LiA5Liq5aSa6L655b2i5YaF77yM5YiZ6L+U5ZueXG4gICAgdXRpbF8xLmVhY2gocG9pbnRzMiwgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIGlmIChwb2ludF9pbl9wb2x5Z29uXzEuZGVmYXVsdChwb2ludHMxLCBwb2ludFswXSwgcG9pbnRbMV0pKSB7XG4gICAgICAgICAgICBpc0luID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChpc0luKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyDkuKTkuKrlpJrovrnlvaLpg73pnIDopoHliKTlrppcbiAgICB1dGlsXzEuZWFjaChwb2ludHMxLCBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgaWYgKHBvaW50X2luX3BvbHlnb25fMS5kZWZhdWx0KHBvaW50czIsIHBvaW50WzBdLCBwb2ludFsxXSkpIHtcbiAgICAgICAgICAgIGlzSW4gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGlzSW4pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHZhciBsaW5lczEgPSBwYXJzZVRvTGluZXMocG9pbnRzMSk7XG4gICAgdmFyIGxpbmVzMiA9IHBhcnNlVG9MaW5lcyhwb2ludHMyKTtcbiAgICB2YXIgaXNJbnRlcnNlY3QgPSBmYWxzZTtcbiAgICB1dGlsXzEuZWFjaChsaW5lczIsIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lSW50ZXJzZWN0UG9seWdvbihsaW5lczEsIGxpbmUpKSB7XG4gICAgICAgICAgICBpc0ludGVyc2VjdCA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaXNJbnRlcnNlY3Q7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBpc1BvbHlnb25zSW50ZXJzZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtcG9seWdvbnMtaW50ZXJzZWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHAycyA9IC8sPyhbYS16XSksPy9naTtcbmZ1bmN0aW9uIHBhcnNlUGF0aEFycmF5KHBhdGgpIHtcbiAgICByZXR1cm4gcGF0aC5qb2luKCcsJykucmVwbGFjZShwMnMsICckMScpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gcGFyc2VQYXRoQXJyYXk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXJzZS1wYXRoLWFycmF5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbC9saWIvaXMtYXJyYXlcIik7XG52YXIgU1BBQ0VTID0gJ1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5JztcbnZhciBQQVRIX0NPTU1BTkQgPSBuZXcgUmVnRXhwKCcoW2Etel0pWycgKyBTUEFDRVMgKyAnLF0qKCgtP1xcXFxkKlxcXFwuP1xcXFxkKig/OmVbXFxcXC0rXT9cXFxcZCspP1snICsgU1BBQ0VTICsgJ10qLD9bJyArIFNQQUNFUyArICddKikrKScsICdpZycpO1xudmFyIFBBVEhfVkFMVUVTID0gbmV3IFJlZ0V4cCgnKC0/XFxcXGQqXFxcXC4/XFxcXGQqKD86ZVtcXFxcLStdP1xcXFxkKyk/KVsnICsgU1BBQ0VTICsgJ10qLD9bJyArIFNQQUNFUyArICddKicsICdpZycpO1xuLy8gUGFyc2VzIGdpdmVuIHBhdGggc3RyaW5nIGludG8gYW4gYXJyYXkgb2YgYXJyYXlzIG9mIHBhdGggc2VnbWVudHNcbmZ1bmN0aW9uIHBhcnNlUGF0aFN0cmluZyhwYXRoU3RyaW5nKSB7XG4gICAgaWYgKCFwYXRoU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAoaXNfYXJyYXlfMS5kZWZhdWx0KHBhdGhTdHJpbmcpKSB7XG4gICAgICAgIHJldHVybiBwYXRoU3RyaW5nO1xuICAgIH1cbiAgICB2YXIgcGFyYW1Db3VudHMgPSB7XG4gICAgICAgIGE6IDcsXG4gICAgICAgIGM6IDYsXG4gICAgICAgIG86IDIsXG4gICAgICAgIGg6IDEsXG4gICAgICAgIGw6IDIsXG4gICAgICAgIG06IDIsXG4gICAgICAgIHI6IDQsXG4gICAgICAgIHE6IDQsXG4gICAgICAgIHM6IDQsXG4gICAgICAgIHQ6IDIsXG4gICAgICAgIHY6IDEsXG4gICAgICAgIHU6IDMsXG4gICAgICAgIHo6IDAsXG4gICAgfTtcbiAgICB2YXIgZGF0YSA9IFtdO1xuICAgIFN0cmluZyhwYXRoU3RyaW5nKS5yZXBsYWNlKFBBVEhfQ09NTUFORCwgZnVuY3Rpb24gKGEsIGIsIGMpIHtcbiAgICAgICAgdmFyIHBhcmFtcyA9IFtdO1xuICAgICAgICB2YXIgbmFtZSA9IGIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgYy5yZXBsYWNlKFBBVEhfVkFMVUVTLCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgYiAmJiBwYXJhbXMucHVzaCgrYik7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAobmFtZSA9PT0gJ20nICYmIHBhcmFtcy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBkYXRhLnB1c2goW2JdLmNvbmNhdChwYXJhbXMuc3BsaWNlKDAsIDIpKSk7XG4gICAgICAgICAgICBuYW1lID0gJ2wnO1xuICAgICAgICAgICAgYiA9IGIgPT09ICdtJyA/ICdsJyA6ICdMJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobmFtZSA9PT0gJ28nICYmIHBhcmFtcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIGRhdGEucHVzaChbYiwgcGFyYW1zWzBdXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hbWUgPT09ICdyJykge1xuICAgICAgICAgICAgZGF0YS5wdXNoKFtiXS5jb25jYXQocGFyYW1zKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3aGlsZSAocGFyYW1zLmxlbmd0aCA+PSBwYXJhbUNvdW50c1tuYW1lXSkge1xuICAgICAgICAgICAgICAgIGRhdGEucHVzaChbYl0uY29uY2F0KHBhcmFtcy5zcGxpY2UoMCwgcGFyYW1Db3VudHNbbmFtZV0pKSk7XG4gICAgICAgICAgICAgICAgaWYgKCFwYXJhbUNvdW50c1tuYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH0pO1xuICAgIHJldHVybiBkYXRhO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gcGFyc2VQYXRoU3RyaW5nO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFyc2UtcGF0aC1zdHJpbmcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZWFjaF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWwvbGliL2VhY2hcIik7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1hcnJheVwiKTtcbnZhciBpc19zdHJpbmdfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsL2xpYi9pcy1zdHJpbmdcIik7XG52YXIgcmVnZXhUYWdzID0gL1tNTEhWUVRDU0FaXShbXk1MSFZRVENTQVpdKikvaWc7XG52YXIgcmVnZXhEb3QgPSAvW15cXHNcXCxdKy9pZztcbmZ1bmN0aW9uIHBhcnNlUGF0aChwKSB7XG4gICAgdmFyIHBhdGggPSBwIHx8IFtdO1xuICAgIGlmIChpc19hcnJheV8xLmRlZmF1bHQocGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfVxuICAgIGlmIChpc19zdHJpbmdfMS5kZWZhdWx0KHBhdGgpKSB7XG4gICAgICAgIHBhdGggPSBwYXRoLm1hdGNoKHJlZ2V4VGFncyk7XG4gICAgICAgIGVhY2hfMS5kZWZhdWx0KHBhdGgsIGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgaXRlbSA9IGl0ZW0ubWF0Y2gocmVnZXhEb3QpO1xuICAgICAgICAgICAgaWYgKGl0ZW1bMF0ubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSBpdGVtWzBdLmNoYXJBdCgwKTtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgaXRlbS5zcGxpY2UoMSwgMCwgaXRlbVswXS5zdWJzdHIoMSkpO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBpdGVtWzBdID0gdGFnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgZWFjaF8xLmRlZmF1bHQoaXRlbSwgZnVuY3Rpb24gKHN1YiwgaSkge1xuICAgICAgICAgICAgICAgIGlmICghaXNOYU4oc3ViKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1baV0gPSArc3ViO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcGF0aFtpbmRleF0gPSBpdGVtO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfVxufVxuZXhwb3J0cy5kZWZhdWx0ID0gcGFyc2VQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFyc2UtcGF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBwYXJzZV9wYXRoX3N0cmluZ18xID0gcmVxdWlyZShcIi4vcGFyc2UtcGF0aC1zdHJpbmdcIik7XG52YXIgUkVHRVhfTUQgPSAvW2Etel0vO1xuZnVuY3Rpb24gdG9TeW1tZXRyeShwLCBjKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgY1swXSArIChjWzBdIC0gcFswXSksXG4gICAgICAgIGNbMV0gKyAoY1sxXSAtIHBbMV0pLFxuICAgIF07XG59XG5mdW5jdGlvbiBwYXRoVG9BYnNvbHV0ZShwYXRoU3RyaW5nKSB7XG4gICAgdmFyIHBhdGhBcnJheSA9IHBhcnNlX3BhdGhfc3RyaW5nXzEuZGVmYXVsdChwYXRoU3RyaW5nKTtcbiAgICBpZiAoIXBhdGhBcnJheSB8fCAhcGF0aEFycmF5Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgWydNJywgMCwgMF0sXG4gICAgICAgIF07XG4gICAgfVxuICAgIHZhciBuZWVkUHJvY2VzcyA9IGZhbHNlOyAvLyDlpoLmnpzlrZjlnKjlsI/lhpnnmoTlkb3ku6TmiJbogIUgVixILFQsUyDliJnpnIDopoHlpITnkIZcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdGhBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY21kID0gcGF0aEFycmF5W2ldWzBdO1xuICAgICAgICAvLyDlpoLmnpzlrZjlnKjnm7jlr7nkvY3nva7nmoTlkb3ku6TvvIzliJnkuK3mlq3ov5Tlm55cbiAgICAgICAgaWYgKFJFR0VYX01ELnRlc3QoY21kKSB8fCBbJ1YnLCAnSCcsICdUJywgJ1MnXS5pbmRleE9mKGNtZCkgPj0gMCkge1xuICAgICAgICAgICAgbmVlZFByb2Nlc3MgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8g5aaC5p6c5LiN5a2Y5Zyo55u45a+55ZG95Luk77yM5YiZ55u05o6l6L+U5ZueXG4gICAgLy8g5aaC5p6c5Zyo5Lia5Yqh5LiK6YO95YaZ57ud5a+56Lev5b6E77yM6L+Z56eN5pa55byP5pyA5b+r77yM5LuF5YGa5LqG5LiA5qyh5qOA5rWLXG4gICAgaWYgKCFuZWVkUHJvY2Vzcykge1xuICAgICAgICByZXR1cm4gcGF0aEFycmF5O1xuICAgIH1cbiAgICB2YXIgcmVzID0gW107XG4gICAgdmFyIHggPSAwO1xuICAgIHZhciB5ID0gMDtcbiAgICB2YXIgbXggPSAwO1xuICAgIHZhciBteSA9IDA7XG4gICAgdmFyIHN0YXJ0ID0gMDtcbiAgICB2YXIgcGEwO1xuICAgIHZhciBkb3RzO1xuICAgIHZhciBmaXJzdCA9IHBhdGhBcnJheVswXTtcbiAgICBpZiAoZmlyc3RbMF0gPT09ICdNJyB8fCBmaXJzdFswXSA9PT0gJ20nKSB7XG4gICAgICAgIHggPSArZmlyc3RbMV07XG4gICAgICAgIHkgPSArZmlyc3RbMl07XG4gICAgICAgIG14ID0geDtcbiAgICAgICAgbXkgPSB5O1xuICAgICAgICBzdGFydCsrO1xuICAgICAgICByZXNbMF0gPSBbJ00nLCB4LCB5XTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgIHZhciBwYSA9IHBhdGhBcnJheVtpXTtcbiAgICAgICAgdmFyIHByZVBhcmFtcyA9IHJlc1tpIC0gMV07IC8vIOWPluWJjeS4gOS4quW3sue7j+WkhOeQhuWQjueahOiKgueCue+8jOWQpuWImeS8muWHuueOsOmXrumimFxuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICB2YXIgY21kID0gcGFbMF07XG4gICAgICAgIHZhciB1cENtZCA9IGNtZC50b1VwcGVyQ2FzZSgpO1xuICAgICAgICBpZiAoY21kICE9PSB1cENtZCkge1xuICAgICAgICAgICAgclswXSA9IHVwQ21kO1xuICAgICAgICAgICAgc3dpdGNoICh1cENtZCkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgICAgICAgICByWzFdID0gcGFbMV07XG4gICAgICAgICAgICAgICAgICAgIHJbMl0gPSBwYVsyXTtcbiAgICAgICAgICAgICAgICAgICAgclszXSA9IHBhWzNdO1xuICAgICAgICAgICAgICAgICAgICByWzRdID0gcGFbNF07XG4gICAgICAgICAgICAgICAgICAgIHJbNV0gPSBwYVs1XTtcbiAgICAgICAgICAgICAgICAgICAgcls2XSA9ICtwYVs2XSArIHg7XG4gICAgICAgICAgICAgICAgICAgIHJbN10gPSArcGFbN10gKyB5O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgICAgICAgICAgclsxXSA9ICtwYVsxXSArIHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICAgICAgICAgICAgICByWzFdID0gK3BhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgICAgIG14ID0gK3BhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgbXkgPSArcGFbMl0gKyB5O1xuICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gZm9yIGxpbnRcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMSwgamogPSBwYS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gK3BhW2pdICsgKChqICUgMikgPyB4IDogeSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgLy8g5aaC5p6c5pys5p2l5bey57uP5aSn5YaZ77yM5YiZ5LiN5aSE55CGXG4gICAgICAgICAgICByID0gcGF0aEFycmF5W2ldO1xuICAgICAgICB9XG4gICAgICAgIC8vIOmcgOimgeWcqOWklumdoue7n+S4gOWBmu+8jOWQjOaXtuWkhOeQhiBWLEgsUyxUIOetieeJueauiuaMh+S7pFxuICAgICAgICBzd2l0Y2ggKHVwQ21kKSB7XG4gICAgICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgICAgICAgICB4ID0gK214O1xuICAgICAgICAgICAgICAgIHkgPSArbXk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdIJzpcbiAgICAgICAgICAgICAgICB4ID0gclsxXTtcbiAgICAgICAgICAgICAgICByID0gWydMJywgeCwgeV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgICAgICB5ID0gclsxXTtcbiAgICAgICAgICAgICAgICByID0gWydMJywgeCwgeV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdUJzpcbiAgICAgICAgICAgICAgICB4ID0gclsxXTtcbiAgICAgICAgICAgICAgICB5ID0gclsyXTtcbiAgICAgICAgICAgICAgICAvLyDku6UgeCwgeSDkuLrkuK3lv4PnmoTvvIzkuIrkuIDkuKrmjqfliLbngrnnmoTlr7nnp7DngrlcbiAgICAgICAgICAgICAgICAvLyDpnIDopoHlgYforr7kuIrkuIDkuKroioLngrnnmoTlkb3ku6TkuLogUVxuICAgICAgICAgICAgICAgIHZhciBzeW1ldHJpY1QgPSB0b1N5bW1ldHJ5KFtwcmVQYXJhbXNbMV0sIHByZVBhcmFtc1syXV0sIFtwcmVQYXJhbXNbM10sIHByZVBhcmFtc1s0XV0pO1xuICAgICAgICAgICAgICAgIHIgPSBbJ1EnLCBzeW1ldHJpY1RbMF0sIHN5bWV0cmljVFsxXSwgeCwgeV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICAgICAgICB4ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgIHkgPSByW3IubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgLy8g5LulIHgseSDkuLrkuK3lv4PvvIzlj5bkuIrkuIDkuKrmjqfliLbngrnvvIxcbiAgICAgICAgICAgICAgICAvLyDpnIDopoHlgYforr7kuIrkuIDkuKrnur/mrrXkuLogQyDmiJbogIUgU1xuICAgICAgICAgICAgICAgIHZhciBsZW5ndGhfMSA9IHByZVBhcmFtcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIHN5bWV0cmljUyA9IHRvU3ltbWV0cnkoW3ByZVBhcmFtc1tsZW5ndGhfMSAtIDRdLCBwcmVQYXJhbXNbbGVuZ3RoXzEgLSAzXV0sIFtwcmVQYXJhbXNbbGVuZ3RoXzEgLSAyXSwgcHJlUGFyYW1zW2xlbmd0aF8xIC0gMV1dKTtcbiAgICAgICAgICAgICAgICByID0gWydDJywgc3ltZXRyaWNTWzBdLCBzeW1ldHJpY1NbMV0sIHJbMV0sIHJbMl0sIHgsIHldO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgbXggPSByW3IubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgICAgbXkgPSByW3IubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgYnJlYWs7IC8vIGZvciBsaW50XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHggPSByW3IubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICByZXMucHVzaChyKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHBhdGhUb0Fic29sdXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC0yLWFic29sdXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHBhdGhfMl9hYnNvbHV0ZV8xID0gcmVxdWlyZShcIi4vcGF0aC0yLWFic29sdXRlXCIpO1xudmFyIGEyYyA9IGZ1bmN0aW9uICh4MSwgeTEsIHJ4LCByeSwgYW5nbGUsIGxhcmdlX2FyY19mbGFnLCBzd2VlcF9mbGFnLCB4MiwgeTIsIHJlY3Vyc2l2ZSkge1xuICAgIC8vIGZvciBtb3JlIGluZm9ybWF0aW9uIG9mIHdoZXJlIHRoaXMgbWF0aCBjYW1lIGZyb20gdmlzaXQ6XG4gICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvaW1wbG5vdGUuaHRtbCNBcmNJbXBsZW1lbnRhdGlvbk5vdGVzXG4gICAgaWYgKHJ4ID09PSByeSkge1xuICAgICAgICByeCArPSAxO1xuICAgIH1cbiAgICB2YXIgXzEyMCA9IChNYXRoLlBJICogMTIwKSAvIDE4MDtcbiAgICB2YXIgcmFkID0gKE1hdGguUEkgLyAxODApICogKCthbmdsZSB8fCAwKTtcbiAgICB2YXIgcmVzID0gW107XG4gICAgdmFyIHh5O1xuICAgIHZhciBmMTtcbiAgICB2YXIgZjI7XG4gICAgdmFyIGN4O1xuICAgIHZhciBjeTtcbiAgICB2YXIgcm90YXRlID0gZnVuY3Rpb24gKHgsIHksIHJhZCkge1xuICAgICAgICB2YXIgWCA9IHggKiBNYXRoLmNvcyhyYWQpIC0geSAqIE1hdGguc2luKHJhZCk7XG4gICAgICAgIHZhciBZID0geCAqIE1hdGguc2luKHJhZCkgKyB5ICogTWF0aC5jb3MocmFkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IFgsXG4gICAgICAgICAgICB5OiBZLFxuICAgICAgICB9O1xuICAgIH07XG4gICAgaWYgKCFyZWN1cnNpdmUpIHtcbiAgICAgICAgeHkgPSByb3RhdGUoeDEsIHkxLCAtcmFkKTtcbiAgICAgICAgeDEgPSB4eS54O1xuICAgICAgICB5MSA9IHh5Lnk7XG4gICAgICAgIHh5ID0gcm90YXRlKHgyLCB5MiwgLXJhZCk7XG4gICAgICAgIHgyID0geHkueDtcbiAgICAgICAgeTIgPSB4eS55O1xuICAgICAgICBpZiAoeDEgPT09IHgyICYmIHkxID09PSB5Mikge1xuICAgICAgICAgICAgLy8g6Iul5byn55qE6LW35aeL54K55ZKM57uI54K56YeN5Y+g5YiZ6ZSZ5byA5LiA54K5XG4gICAgICAgICAgICB4MiArPSAxO1xuICAgICAgICAgICAgeTIgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb25zdCBjb3MgPSBNYXRoLmNvcyhNYXRoLlBJIC8gMTgwICogYW5nbGUpO1xuICAgICAgICAvLyBjb25zdCBzaW4gPSBNYXRoLnNpbihNYXRoLlBJIC8gMTgwICogYW5nbGUpO1xuICAgICAgICB2YXIgeCA9ICh4MSAtIHgyKSAvIDI7XG4gICAgICAgIHZhciB5ID0gKHkxIC0geTIpIC8gMjtcbiAgICAgICAgdmFyIGggPSAoeCAqIHgpIC8gKHJ4ICogcngpICsgKHkgKiB5KSAvIChyeSAqIHJ5KTtcbiAgICAgICAgaWYgKGggPiAxKSB7XG4gICAgICAgICAgICBoID0gTWF0aC5zcXJ0KGgpO1xuICAgICAgICAgICAgcnggPSBoICogcng7XG4gICAgICAgICAgICByeSA9IGggKiByeTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcngyID0gcnggKiByeDtcbiAgICAgICAgdmFyIHJ5MiA9IHJ5ICogcnk7XG4gICAgICAgIHZhciBrID0gKGxhcmdlX2FyY19mbGFnID09PSBzd2VlcF9mbGFnID8gLTEgOiAxKSAqXG4gICAgICAgICAgICBNYXRoLnNxcnQoTWF0aC5hYnMoKHJ4MiAqIHJ5MiAtIHJ4MiAqIHkgKiB5IC0gcnkyICogeCAqIHgpIC8gKHJ4MiAqIHkgKiB5ICsgcnkyICogeCAqIHgpKSk7XG4gICAgICAgIGN4ID0gKGsgKiByeCAqIHkpIC8gcnkgKyAoeDEgKyB4MikgLyAyO1xuICAgICAgICBjeSA9IChrICogLXJ5ICogeCkgLyByeCArICh5MSArIHkyKSAvIDI7XG4gICAgICAgIGYxID0gTWF0aC5hc2luKE51bWJlcigoKHkxIC0gY3kpIC8gcnkpLnRvRml4ZWQoOSkpKTtcbiAgICAgICAgZjIgPSBNYXRoLmFzaW4oTnVtYmVyKCgoeTIgLSBjeSkgLyByeSkudG9GaXhlZCg5KSkpO1xuICAgICAgICBmMSA9IHgxIDwgY3ggPyBNYXRoLlBJIC0gZjEgOiBmMTtcbiAgICAgICAgZjIgPSB4MiA8IGN4ID8gTWF0aC5QSSAtIGYyIDogZjI7XG4gICAgICAgIGYxIDwgMCAmJiAoZjEgPSBNYXRoLlBJICogMiArIGYxKTtcbiAgICAgICAgZjIgPCAwICYmIChmMiA9IE1hdGguUEkgKiAyICsgZjIpO1xuICAgICAgICBpZiAoc3dlZXBfZmxhZyAmJiBmMSA+IGYyKSB7XG4gICAgICAgICAgICBmMSA9IGYxIC0gTWF0aC5QSSAqIDI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzd2VlcF9mbGFnICYmIGYyID4gZjEpIHtcbiAgICAgICAgICAgIGYyID0gZjIgLSBNYXRoLlBJICogMjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZjEgPSByZWN1cnNpdmVbMF07XG4gICAgICAgIGYyID0gcmVjdXJzaXZlWzFdO1xuICAgICAgICBjeCA9IHJlY3Vyc2l2ZVsyXTtcbiAgICAgICAgY3kgPSByZWN1cnNpdmVbM107XG4gICAgfVxuICAgIHZhciBkZiA9IGYyIC0gZjE7XG4gICAgaWYgKE1hdGguYWJzKGRmKSA+IF8xMjApIHtcbiAgICAgICAgdmFyIGYyb2xkID0gZjI7XG4gICAgICAgIHZhciB4Mm9sZCA9IHgyO1xuICAgICAgICB2YXIgeTJvbGQgPSB5MjtcbiAgICAgICAgZjIgPSBmMSArIF8xMjAgKiAoc3dlZXBfZmxhZyAmJiBmMiA+IGYxID8gMSA6IC0xKTtcbiAgICAgICAgeDIgPSBjeCArIHJ4ICogTWF0aC5jb3MoZjIpO1xuICAgICAgICB5MiA9IGN5ICsgcnkgKiBNYXRoLnNpbihmMik7XG4gICAgICAgIHJlcyA9IGEyYyh4MiwgeTIsIHJ4LCByeSwgYW5nbGUsIDAsIHN3ZWVwX2ZsYWcsIHgyb2xkLCB5Mm9sZCwgW2YyLCBmMm9sZCwgY3gsIGN5XSk7XG4gICAgfVxuICAgIGRmID0gZjIgLSBmMTtcbiAgICB2YXIgYzEgPSBNYXRoLmNvcyhmMSk7XG4gICAgdmFyIHMxID0gTWF0aC5zaW4oZjEpO1xuICAgIHZhciBjMiA9IE1hdGguY29zKGYyKTtcbiAgICB2YXIgczIgPSBNYXRoLnNpbihmMik7XG4gICAgdmFyIHQgPSBNYXRoLnRhbihkZiAvIDQpO1xuICAgIHZhciBoeCA9ICg0IC8gMykgKiByeCAqIHQ7XG4gICAgdmFyIGh5ID0gKDQgLyAzKSAqIHJ5ICogdDtcbiAgICB2YXIgbTEgPSBbeDEsIHkxXTtcbiAgICB2YXIgbTIgPSBbeDEgKyBoeCAqIHMxLCB5MSAtIGh5ICogYzFdO1xuICAgIHZhciBtMyA9IFt4MiArIGh4ICogczIsIHkyIC0gaHkgKiBjMl07XG4gICAgdmFyIG00ID0gW3gyLCB5Ml07XG4gICAgbTJbMF0gPSAyICogbTFbMF0gLSBtMlswXTtcbiAgICBtMlsxXSA9IDIgKiBtMVsxXSAtIG0yWzFdO1xuICAgIGlmIChyZWN1cnNpdmUpIHtcbiAgICAgICAgcmV0dXJuIFttMiwgbTMsIG00XS5jb25jYXQocmVzKTtcbiAgICB9XG4gICAgcmVzID0gW20yLCBtMywgbTRdXG4gICAgICAgIC5jb25jYXQocmVzKVxuICAgICAgICAuam9pbigpXG4gICAgICAgIC5zcGxpdCgnLCcpO1xuICAgIHZhciBuZXdyZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSByZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICBuZXdyZXNbaV0gPSBpICUgMiA/IHJvdGF0ZShyZXNbaSAtIDFdLCByZXNbaV0sIHJhZCkueSA6IHJvdGF0ZShyZXNbaV0sIHJlc1tpICsgMV0sIHJhZCkueDtcbiAgICB9XG4gICAgcmV0dXJuIG5ld3Jlcztcbn07XG52YXIgbDJjID0gZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgcmV0dXJuIFt4MSwgeTEsIHgyLCB5MiwgeDIsIHkyXTtcbn07XG52YXIgcTJjID0gZnVuY3Rpb24gKHgxLCB5MSwgYXgsIGF5LCB4MiwgeTIpIHtcbiAgICB2YXIgXzEzID0gMSAvIDM7XG4gICAgdmFyIF8yMyA9IDIgLyAzO1xuICAgIHJldHVybiBbXzEzICogeDEgKyBfMjMgKiBheCwgXzEzICogeTEgKyBfMjMgKiBheSwgXzEzICogeDIgKyBfMjMgKiBheCwgXzEzICogeTIgKyBfMjMgKiBheSwgeDIsIHkyXTtcbn07XG5mdW5jdGlvbiBwYXRoVG9jdXJ2ZShwYXRoLCBwYXRoMikge1xuICAgIHZhciBwID0gcGF0aF8yX2Fic29sdXRlXzEuZGVmYXVsdChwYXRoKTtcbiAgICB2YXIgcDIgPSBwYXRoMiAmJiBwYXRoXzJfYWJzb2x1dGVfMS5kZWZhdWx0KHBhdGgyKTtcbiAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDAsXG4gICAgICAgIGJ4OiAwLFxuICAgICAgICBieTogMCxcbiAgICAgICAgWDogMCxcbiAgICAgICAgWTogMCxcbiAgICAgICAgcXg6IG51bGwsXG4gICAgICAgIHF5OiBudWxsLFxuICAgIH07XG4gICAgdmFyIGF0dHJzMiA9IHtcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogMCxcbiAgICAgICAgYng6IDAsXG4gICAgICAgIGJ5OiAwLFxuICAgICAgICBYOiAwLFxuICAgICAgICBZOiAwLFxuICAgICAgICBxeDogbnVsbCxcbiAgICAgICAgcXk6IG51bGwsXG4gICAgfTtcbiAgICB2YXIgcGNvbXMxID0gW107IC8vIHBhdGggY29tbWFuZHMgb2Ygb3JpZ2luYWwgcGF0aCBwXG4gICAgdmFyIHBjb21zMiA9IFtdOyAvLyBwYXRoIGNvbW1hbmRzIG9mIG9yaWdpbmFsIHBhdGggcDJcbiAgICB2YXIgcGZpcnN0ID0gJyc7IC8vIHRlbXBvcmFyeSBob2xkZXIgZm9yIG9yaWdpbmFsIHBhdGggY29tbWFuZFxuICAgIHZhciBwY29tID0gJyc7IC8vIGhvbGRlciBmb3IgcHJldmlvdXMgcGF0aCBjb21tYW5kIG9mIG9yaWdpbmFsIHBhdGhcbiAgICB2YXIgaWk7XG4gICAgdmFyIHByb2Nlc3NQYXRoID0gZnVuY3Rpb24gKHBhdGgsIGQsIHBjb20pIHtcbiAgICAgICAgdmFyIG54LCBueTtcbiAgICAgICAgaWYgKCFwYXRoKSB7XG4gICAgICAgICAgICByZXR1cm4gWydDJywgZC54LCBkLnksIGQueCwgZC55LCBkLngsIGQueV07XG4gICAgICAgIH1cbiAgICAgICAgIShwYXRoWzBdIGluXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgVDogMSxcbiAgICAgICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgfSkgJiYgKGQucXggPSBkLnF5ID0gbnVsbCk7XG4gICAgICAgIHN3aXRjaCAocGF0aFswXSkge1xuICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgZC5YID0gcGF0aFsxXTtcbiAgICAgICAgICAgICAgICBkLlkgPSBwYXRoWzJdO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChhMmMuYXBwbHkoMCwgW2QueCwgZC55XS5jb25jYXQocGF0aC5zbGljZSgxKSkpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1MnOlxuICAgICAgICAgICAgICAgIGlmIChwY29tID09PSAnQycgfHwgcGNvbSA9PT0gJ1MnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEluIFwiU1wiIGNhc2Ugd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCwgaWYgdGhlIHByZXZpb3VzIGNvbW1hbmQgaXMgQy9TLlxuICAgICAgICAgICAgICAgICAgICBueCA9IGQueCAqIDIgLSBkLmJ4OyAvLyBBbmQgcmVmbGVjdCB0aGUgcHJldmlvdXNcbiAgICAgICAgICAgICAgICAgICAgbnkgPSBkLnkgKiAyIC0gZC5ieTsgLy8gY29tbWFuZCdzIGNvbnRyb2wgcG9pbnQgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgcG9pbnQuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBvciBzb21lIGVsc2Ugb3Igbm90aGluZ1xuICAgICAgICAgICAgICAgICAgICBueCA9IGQueDtcbiAgICAgICAgICAgICAgICAgICAgbnkgPSBkLnk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhdGggPSBbJ0MnLCBueCwgbnldLmNvbmNhdChwYXRoLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgICAgICAgIGlmIChwY29tID09PSAnUScgfHwgcGNvbSA9PT0gJ1QnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEluIFwiVFwiIGNhc2Ugd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCwgaWYgdGhlIHByZXZpb3VzIGNvbW1hbmQgaXMgUS9ULlxuICAgICAgICAgICAgICAgICAgICBkLnF4ID0gZC54ICogMiAtIGQucXg7IC8vIEFuZCBtYWtlIGEgcmVmbGVjdGlvbiBzaW1pbGFyXG4gICAgICAgICAgICAgICAgICAgIGQucXkgPSBkLnkgKiAyIC0gZC5xeTsgLy8gdG8gY2FzZSBcIlNcIi5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG9yIHNvbWV0aGluZyBlbHNlIG9yIG5vdGhpbmdcbiAgICAgICAgICAgICAgICAgICAgZC5xeCA9IGQueDtcbiAgICAgICAgICAgICAgICAgICAgZC5xeSA9IGQueTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChxMmMoZC54LCBkLnksIGQucXgsIGQucXksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgICAgICAgIGQucXggPSBwYXRoWzFdO1xuICAgICAgICAgICAgICAgIGQucXkgPSBwYXRoWzJdO1xuICAgICAgICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQocTJjKGQueCwgZC55LCBwYXRoWzFdLCBwYXRoWzJdLCBwYXRoWzNdLCBwYXRoWzRdKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGwyYyhkLngsIGQueSwgcGF0aFsxXSwgcGF0aFsyXSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnSCc6XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChsMmMoZC54LCBkLnksIHBhdGhbMV0sIGQueSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnVic6XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChsMmMoZC54LCBkLnksIGQueCwgcGF0aFsxXSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnWic6XG4gICAgICAgICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChsMmMoZC54LCBkLnksIGQuWCwgZC5ZKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH07XG4gICAgdmFyIGZpeEFyYyA9IGZ1bmN0aW9uIChwcCwgaSkge1xuICAgICAgICBpZiAocHBbaV0ubGVuZ3RoID4gNykge1xuICAgICAgICAgICAgcHBbaV0uc2hpZnQoKTtcbiAgICAgICAgICAgIHZhciBwaSA9IHBwW2ldO1xuICAgICAgICAgICAgd2hpbGUgKHBpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHBjb21zMVtpXSA9ICdBJzsgLy8gaWYgY3JlYXRlZCBtdWx0aXBsZSBDOnMsIHRoZWlyIG9yaWdpbmFsIHNlZyBpcyBzYXZlZFxuICAgICAgICAgICAgICAgIHAyICYmIChwY29tczJbaV0gPSAnQScpOyAvLyB0aGUgc2FtZSBhcyBhYm92ZVxuICAgICAgICAgICAgICAgIHBwLnNwbGljZShpKyssIDAsIFsnQyddLmNvbmNhdChwaS5zcGxpY2UoMCwgNikpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBwLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIGlpID0gTWF0aC5tYXgocC5sZW5ndGgsIChwMiAmJiBwMi5sZW5ndGgpIHx8IDApO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgZml4TSA9IGZ1bmN0aW9uIChwYXRoMSwgcGF0aDIsIGExLCBhMiwgaSkge1xuICAgICAgICBpZiAocGF0aDEgJiYgcGF0aDIgJiYgcGF0aDFbaV1bMF0gPT09ICdNJyAmJiBwYXRoMltpXVswXSAhPT0gJ00nKSB7XG4gICAgICAgICAgICBwYXRoMi5zcGxpY2UoaSwgMCwgWydNJywgYTIueCwgYTIueV0pO1xuICAgICAgICAgICAgYTEuYnggPSAwO1xuICAgICAgICAgICAgYTEuYnkgPSAwO1xuICAgICAgICAgICAgYTEueCA9IHBhdGgxW2ldWzFdO1xuICAgICAgICAgICAgYTEueSA9IHBhdGgxW2ldWzJdO1xuICAgICAgICAgICAgaWkgPSBNYXRoLm1heChwLmxlbmd0aCwgKHAyICYmIHAyLmxlbmd0aCkgfHwgMCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGlpID0gTWF0aC5tYXgocC5sZW5ndGgsIChwMiAmJiBwMi5sZW5ndGgpIHx8IDApO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaWk7IGkrKykge1xuICAgICAgICBwW2ldICYmIChwZmlyc3QgPSBwW2ldWzBdKTsgLy8gc2F2ZSBjdXJyZW50IHBhdGggY29tbWFuZFxuICAgICAgICBpZiAocGZpcnN0ICE9PSAnQycpIHtcbiAgICAgICAgICAgIC8vIEMgaXMgbm90IHNhdmVkIHlldCwgYmVjYXVzZSBpdCBtYXkgYmUgcmVzdWx0IG9mIGNvbnZlcnNpb25cbiAgICAgICAgICAgIHBjb21zMVtpXSA9IHBmaXJzdDsgLy8gU2F2ZSBjdXJyZW50IHBhdGggY29tbWFuZFxuICAgICAgICAgICAgaSAmJiAocGNvbSA9IHBjb21zMVtpIC0gMV0pOyAvLyBHZXQgcHJldmlvdXMgcGF0aCBjb21tYW5kIHBjb21cbiAgICAgICAgfVxuICAgICAgICBwW2ldID0gcHJvY2Vzc1BhdGgocFtpXSwgYXR0cnMsIHBjb20pOyAvLyBQcmV2aW91cyBwYXRoIGNvbW1hbmQgaXMgaW5wdXR0ZWQgdG8gcHJvY2Vzc1BhdGhcbiAgICAgICAgaWYgKHBjb21zMVtpXSAhPT0gJ0EnICYmIHBmaXJzdCA9PT0gJ0MnKVxuICAgICAgICAgICAgcGNvbXMxW2ldID0gJ0MnOyAvLyBBIGlzIHRoZSBvbmx5IGNvbW1hbmRcbiAgICAgICAgLy8gd2hpY2ggbWF5IHByb2R1Y2UgbXVsdGlwbGUgQzpzXG4gICAgICAgIC8vIHNvIHdlIGhhdmUgdG8gbWFrZSBzdXJlIHRoYXQgQyBpcyBhbHNvIEMgaW4gb3JpZ2luYWwgcGF0aFxuICAgICAgICBmaXhBcmMocCwgaSk7IC8vIGZpeEFyYyBhZGRzIGFsc28gdGhlIHJpZ2h0IGFtb3VudCBvZiBBOnMgdG8gcGNvbXMxXG4gICAgICAgIGlmIChwMikge1xuICAgICAgICAgICAgLy8gdGhlIHNhbWUgcHJvY2VkdXJlcyBpcyBkb25lIHRvIHAyXG4gICAgICAgICAgICBwMltpXSAmJiAocGZpcnN0ID0gcDJbaV1bMF0pO1xuICAgICAgICAgICAgaWYgKHBmaXJzdCAhPT0gJ0MnKSB7XG4gICAgICAgICAgICAgICAgcGNvbXMyW2ldID0gcGZpcnN0O1xuICAgICAgICAgICAgICAgIGkgJiYgKHBjb20gPSBwY29tczJbaSAtIDFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHAyW2ldID0gcHJvY2Vzc1BhdGgocDJbaV0sIGF0dHJzMiwgcGNvbSk7XG4gICAgICAgICAgICBpZiAocGNvbXMyW2ldICE9PSAnQScgJiYgcGZpcnN0ID09PSAnQycpIHtcbiAgICAgICAgICAgICAgICBwY29tczJbaV0gPSAnQyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaXhBcmMocDIsIGkpO1xuICAgICAgICB9XG4gICAgICAgIGZpeE0ocCwgcDIsIGF0dHJzLCBhdHRyczIsIGkpO1xuICAgICAgICBmaXhNKHAyLCBwLCBhdHRyczIsIGF0dHJzLCBpKTtcbiAgICAgICAgdmFyIHNlZyA9IHBbaV07XG4gICAgICAgIHZhciBzZWcyID0gcDIgJiYgcDJbaV07XG4gICAgICAgIHZhciBzZWdsZW4gPSBzZWcubGVuZ3RoO1xuICAgICAgICB2YXIgc2VnMmxlbiA9IHAyICYmIHNlZzIubGVuZ3RoO1xuICAgICAgICBhdHRycy54ID0gc2VnW3NlZ2xlbiAtIDJdO1xuICAgICAgICBhdHRycy55ID0gc2VnW3NlZ2xlbiAtIDFdO1xuICAgICAgICBhdHRycy5ieCA9IHBhcnNlRmxvYXQoc2VnW3NlZ2xlbiAtIDRdKSB8fCBhdHRycy54O1xuICAgICAgICBhdHRycy5ieSA9IHBhcnNlRmxvYXQoc2VnW3NlZ2xlbiAtIDNdKSB8fCBhdHRycy55O1xuICAgICAgICBhdHRyczIuYnggPSBwMiAmJiAocGFyc2VGbG9hdChzZWcyW3NlZzJsZW4gLSA0XSkgfHwgYXR0cnMyLngpO1xuICAgICAgICBhdHRyczIuYnkgPSBwMiAmJiAocGFyc2VGbG9hdChzZWcyW3NlZzJsZW4gLSAzXSkgfHwgYXR0cnMyLnkpO1xuICAgICAgICBhdHRyczIueCA9IHAyICYmIHNlZzJbc2VnMmxlbiAtIDJdO1xuICAgICAgICBhdHRyczIueSA9IHAyICYmIHNlZzJbc2VnMmxlbiAtIDFdO1xuICAgIH1cbiAgICByZXR1cm4gcDIgPyBbcCwgcDJdIDogcDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHBhdGhUb2N1cnZlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGF0aC0yLWN1cnZlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGdldF9hcmNfcGFyYW1zXzEgPSByZXF1aXJlKFwiLi9nZXQtYXJjLXBhcmFtc1wiKTtcbnZhciBnZXRfYXJjX3BhcmFtc18yID0gcmVxdWlyZShcIi4vZ2V0LWFyYy1wYXJhbXNcIik7XG52YXIgcGFyc2VfcGF0aF8xID0gcmVxdWlyZShcIi4vcGFyc2UtcGF0aFwiKTtcbi8vIOeCueWvueensFxuZnVuY3Rpb24gdG9TeW1tZXRyeShwb2ludCwgY2VudGVyKSB7XG4gICAgcmV0dXJuIFtjZW50ZXJbMF0gKyAoY2VudGVyWzBdIC0gcG9pbnRbMF0pLCBjZW50ZXJbMV0gKyAoY2VudGVyWzFdIC0gcG9pbnRbMV0pXTtcbn1cbmZ1bmN0aW9uIGdldFNlZ21lbnRzKHBhdGgpIHtcbiAgICBwYXRoID0gcGFyc2VfcGF0aF8xLmRlZmF1bHQocGF0aCk7XG4gICAgdmFyIHNlZ21lbnRzID0gW107XG4gICAgdmFyIGN1cnJlbnRQb2ludCA9IG51bGw7IC8vIOW9k+WJjeWbvuW9olxuICAgIHZhciBuZXh0UGFyYW1zID0gbnVsbDsgLy8g5LiL5LiA6IqC54K555qEIHBhdGgg5Y+C5pWwXG4gICAgdmFyIHN0YXJ0TW92ZVBvaW50ID0gbnVsbDsgLy8g5byA5aeLIE0g55qE54K577yM5Y+v6IO95Lya5pyJ5aSa5LiqXG4gICAgdmFyIGxhc3RTdGFydE1vdmVQb2ludEluZGV4ID0gMDsgLy8g5pyA6L+R5LiA5Liq5byA5aeL54K5IE0g55qE57Si5byVXG4gICAgdmFyIGNvdW50ID0gcGF0aC5sZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgIHZhciBwYXJhbXMgPSBwYXRoW2ldO1xuICAgICAgICBuZXh0UGFyYW1zID0gcGF0aFtpICsgMV07XG4gICAgICAgIHZhciBjb21tYW5kID0gcGFyYW1zWzBdO1xuICAgICAgICAvLyDmlbDlrablrprkuYnkuIrnmoTlj4LmlbDvvIzkvr/kuo7lkI7pnaLnmoTorqHnrpdcbiAgICAgICAgdmFyIHNlZ21lbnQgPSB7XG4gICAgICAgICAgICBjb21tYW5kOiBjb21tYW5kLFxuICAgICAgICAgICAgcHJlUG9pbnQ6IGN1cnJlbnRQb2ludCxcbiAgICAgICAgICAgIHBhcmFtczogcGFyYW1zLFxuICAgICAgICAgICAgc3RhcnRUYW5nZW50OiBudWxsLFxuICAgICAgICAgICAgZW5kVGFuZ2VudDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgc3dpdGNoIChjb21tYW5kKSB7XG4gICAgICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgICAgICBzdGFydE1vdmVQb2ludCA9IFtwYXJhbXNbMV0sIHBhcmFtc1syXV07XG4gICAgICAgICAgICAgICAgbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgdmFyIGFyY1BhcmFtcyA9IGdldF9hcmNfcGFyYW1zXzEuZGVmYXVsdChjdXJyZW50UG9pbnQsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgc2VnbWVudFsnYXJjUGFyYW1zJ10gPSBhcmNQYXJhbXM7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb21tYW5kID09PSAnWicpIHtcbiAgICAgICAgICAgIC8vIOacieS6hiBaIOWQju+8jOW9k+WJjeiKgueCueS7juW8gOWniyBNIOeahOeCueW8gOWni1xuICAgICAgICAgICAgY3VycmVudFBvaW50ID0gc3RhcnRNb3ZlUG9pbnQ7XG4gICAgICAgICAgICAvLyDlpoLmnpzlvZPliY3ngrnnmoTlkb3ku6TkuLogWu+8jOebuOW9k+S6juW9k+WJjeeCueS4uuacgOi/keS4gOS4qiBNIOeCue+8jOWImeS4i+S4gOS4queCueebtOaOpeaMh+WQkeacgOi/keS4gOS4qiBNIOeCueeahOS4i+S4gOS4queCuVxuICAgICAgICAgICAgbmV4dFBhcmFtcyA9IHBhdGhbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXggKyAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsZW4gPSBwYXJhbXMubGVuZ3RoO1xuICAgICAgICAgICAgY3VycmVudFBvaW50ID0gW3BhcmFtc1tsZW4gLSAyXSwgcGFyYW1zW2xlbiAtIDFdXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV4dFBhcmFtcyAmJiBuZXh0UGFyYW1zWzBdID09PSAnWicpIHtcbiAgICAgICAgICAgIC8vIOWmguaenOS4i+S4gOS4queCueeahOWRveS7pOS4uiBa77yM5YiZ5LiL5LiA5Liq54K555u05o6l5oyH5ZCR5pyA6L+R5LiA5LiqIE0g54K5XG4gICAgICAgICAgICBuZXh0UGFyYW1zID0gcGF0aFtsYXN0U3RhcnRNb3ZlUG9pbnRJbmRleF07XG4gICAgICAgICAgICBpZiAoc2VnbWVudHNbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5LiL5LiA5Liq54K555qE5ZG95Luk5Li6IFrvvIzliJnmnIDov5HkuIDkuKogTSDngrnnmoTliY3kuIDkuKrngrnkuLrlvZPliY3ngrlcbiAgICAgICAgICAgICAgICBzZWdtZW50c1tsYXN0U3RhcnRNb3ZlUG9pbnRJbmRleF0ucHJlUG9pbnQgPSBjdXJyZW50UG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2VnbWVudFsnY3VycmVudFBvaW50J10gPSBjdXJyZW50UG9pbnQ7XG4gICAgICAgIC8vIOWmguaenOW9k+WJjeeCueS4juacgOi/keS4gOS4qiBNIOeCueebuOWQjO+8jOWImeacgOi/keS4gOS4qiBNIOeCueeahOWJjeS4gOS4queCueS4uuW9k+WJjeeCueeahOWJjeS4gOS4queCuVxuICAgICAgICBpZiAoc2VnbWVudHNbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXhdICYmXG4gICAgICAgICAgICBnZXRfYXJjX3BhcmFtc18yLmlzU2FtZVBvaW50KGN1cnJlbnRQb2ludCwgc2VnbWVudHNbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXhdLmN1cnJlbnRQb2ludCkpIHtcbiAgICAgICAgICAgIHNlZ21lbnRzW2xhc3RTdGFydE1vdmVQb2ludEluZGV4XS5wcmVQb2ludCA9IHNlZ21lbnQucHJlUG9pbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5leHRQb2ludCA9IG5leHRQYXJhbXMgPyBbbmV4dFBhcmFtc1tuZXh0UGFyYW1zLmxlbmd0aCAtIDJdLCBuZXh0UGFyYW1zW25leHRQYXJhbXMubGVuZ3RoIC0gMV1dIDogbnVsbDtcbiAgICAgICAgc2VnbWVudFsnbmV4dFBvaW50J10gPSBuZXh0UG9pbnQ7XG4gICAgICAgIC8vIEFkZCBzdGFydFRhbmdlbnQgYW5kIGVuZFRhbmdlbnRcbiAgICAgICAgdmFyIHByZVBvaW50ID0gc2VnbWVudC5wcmVQb2ludDtcbiAgICAgICAgaWYgKFsnTCcsICdIJywgJ1YnXS5pbmNsdWRlcyhjb21tYW5kKSkge1xuICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBjdXJyZW50UG9pbnRbMF0sIHByZVBvaW50WzFdIC0gY3VycmVudFBvaW50WzFdXTtcbiAgICAgICAgICAgIHNlZ21lbnQuZW5kVGFuZ2VudCA9IFtjdXJyZW50UG9pbnRbMF0gLSBwcmVQb2ludFswXSwgY3VycmVudFBvaW50WzFdIC0gcHJlUG9pbnRbMV1dO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQgPT09ICdRJykge1xuICAgICAgICAgICAgLy8g5LqM5qyh6LSd5aGe5bCU5puy57q/5Y+q5pyJ5LiA5Liq5o6n5Yi254K5XG4gICAgICAgICAgICB2YXIgY3AgPSBbcGFyYW1zWzFdLCBwYXJhbXNbMl1dO1xuICAgICAgICAgICAgLy8g5LqM5qyh6LSd5aGe5bCU5puy57q/55qE57uI54K55Li6IGN1cnJlbnRQb2ludFxuICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBjcFswXSwgcHJlUG9pbnRbMV0gLSBjcFsxXV07XG4gICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gY3BbMF0sIGN1cnJlbnRQb2ludFsxXSAtIGNwWzFdXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb21tYW5kID09PSAnVCcpIHtcbiAgICAgICAgICAgIHZhciBwcmVTZWdtZW50ID0gc2VnbWVudHNbaSAtIDFdO1xuICAgICAgICAgICAgdmFyIGNwID0gdG9TeW1tZXRyeShwcmVTZWdtZW50LmN1cnJlbnRQb2ludCwgcHJlUG9pbnQpO1xuICAgICAgICAgICAgaWYgKHByZVNlZ21lbnQuY29tbWFuZCA9PT0gJ1EnKSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudC5jb21tYW5kID0gJ1EnO1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuc3RhcnRUYW5nZW50ID0gW3ByZVBvaW50WzBdIC0gY3BbMF0sIHByZVBvaW50WzFdIC0gY3BbMV1dO1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuZW5kVGFuZ2VudCA9IFtjdXJyZW50UG9pbnRbMF0gLSBjcFswXSwgY3VycmVudFBvaW50WzFdIC0gY3BbMV1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudC5jb21tYW5kID0gJ1RMJztcbiAgICAgICAgICAgICAgICBzZWdtZW50LnN0YXJ0VGFuZ2VudCA9IFtwcmVQb2ludFswXSAtIGN1cnJlbnRQb2ludFswXSwgcHJlUG9pbnRbMV0gLSBjdXJyZW50UG9pbnRbMV1dO1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuZW5kVGFuZ2VudCA9IFtjdXJyZW50UG9pbnRbMF0gLSBwcmVQb2ludFswXSwgY3VycmVudFBvaW50WzFdIC0gcHJlUG9pbnRbMV1dO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQgPT09ICdDJykge1xuICAgICAgICAgICAgLy8g5LiJ5qyh6LSd5aGe5bCU5puy57q/5pyJ5Lik5Liq5o6n5Yi254K5XG4gICAgICAgICAgICB2YXIgY3AxID0gW3BhcmFtc1sxXSwgcGFyYW1zWzJdXTtcbiAgICAgICAgICAgIHZhciBjcDIgPSBbcGFyYW1zWzNdLCBwYXJhbXNbNF1dO1xuICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBjcDFbMF0sIHByZVBvaW50WzFdIC0gY3AxWzFdXTtcbiAgICAgICAgICAgIHNlZ21lbnQuZW5kVGFuZ2VudCA9IFtjdXJyZW50UG9pbnRbMF0gLSBjcDJbMF0sIGN1cnJlbnRQb2ludFsxXSAtIGNwMlsxXV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZCA9PT0gJ1MnKSB7XG4gICAgICAgICAgICB2YXIgcHJlU2VnbWVudCA9IHNlZ21lbnRzW2kgLSAxXTtcbiAgICAgICAgICAgIHZhciBjcDEgPSB0b1N5bW1ldHJ5KHByZVNlZ21lbnQuY3VycmVudFBvaW50LCBwcmVQb2ludCk7XG4gICAgICAgICAgICB2YXIgY3AyID0gW3BhcmFtc1sxXSwgcGFyYW1zWzJdXTtcbiAgICAgICAgICAgIGlmIChwcmVTZWdtZW50LmNvbW1hbmQgPT09ICdDJykge1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuY29tbWFuZCA9ICdDJzsgLy8g5bCGIFMg5ZG95Luk5Y+Y5o2i5Li6IEMg5ZG95LukXG4gICAgICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBjcDFbMF0sIHByZVBvaW50WzFdIC0gY3AxWzFdXTtcbiAgICAgICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gY3AyWzBdLCBjdXJyZW50UG9pbnRbMV0gLSBjcDJbMV1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudC5jb21tYW5kID0gJ1NRJzsgLy8g5bCGIFMg5ZG95Luk5Y+Y5o2i5Li6IFNRIOWRveS7pFxuICAgICAgICAgICAgICAgIHNlZ21lbnQuc3RhcnRUYW5nZW50ID0gW3ByZVBvaW50WzBdIC0gY3AyWzBdLCBwcmVQb2ludFsxXSAtIGNwMlsxXV07XG4gICAgICAgICAgICAgICAgc2VnbWVudC5lbmRUYW5nZW50ID0gW2N1cnJlbnRQb2ludFswXSAtIGNwMlswXSwgY3VycmVudFBvaW50WzFdIC0gY3AyWzFdXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb21tYW5kID09PSAnQScpIHtcbiAgICAgICAgICAgIHZhciBkID0gMC4wMDE7XG4gICAgICAgICAgICB2YXIgX2EgPSBzZWdtZW50WydhcmNQYXJhbXMnXSB8fCB7fSwgX2IgPSBfYS5jeCwgY3ggPSBfYiA9PT0gdm9pZCAwID8gMCA6IF9iLCBfYyA9IF9hLmN5LCBjeSA9IF9jID09PSB2b2lkIDAgPyAwIDogX2MsIF9kID0gX2EucngsIHJ4ID0gX2QgPT09IHZvaWQgMCA/IDAgOiBfZCwgX2UgPSBfYS5yeSwgcnkgPSBfZSA9PT0gdm9pZCAwID8gMCA6IF9lLCBfZiA9IF9hLnN3ZWVwRmxhZywgc3dlZXBGbGFnID0gX2YgPT09IHZvaWQgMCA/IDAgOiBfZiwgX2cgPSBfYS5zdGFydEFuZ2xlLCBzdGFydEFuZ2xlID0gX2cgPT09IHZvaWQgMCA/IDAgOiBfZywgX2ggPSBfYS5lbmRBbmdsZSwgZW5kQW5nbGUgPSBfaCA9PT0gdm9pZCAwID8gMCA6IF9oO1xuICAgICAgICAgICAgaWYgKHN3ZWVwRmxhZyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGQgKj0gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZHgxID0gcnggKiBNYXRoLmNvcyhzdGFydEFuZ2xlIC0gZCkgKyBjeDtcbiAgICAgICAgICAgIHZhciBkeTEgPSByeSAqIE1hdGguc2luKHN0YXJ0QW5nbGUgLSBkKSArIGN5O1xuICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbZHgxIC0gc3RhcnRNb3ZlUG9pbnRbMF0sIGR5MSAtIHN0YXJ0TW92ZVBvaW50WzFdXTtcbiAgICAgICAgICAgIHZhciBkeDIgPSByeCAqIE1hdGguY29zKHN0YXJ0QW5nbGUgKyBlbmRBbmdsZSArIGQpICsgY3g7XG4gICAgICAgICAgICB2YXIgZHkyID0gcnkgKiBNYXRoLnNpbihzdGFydEFuZ2xlICsgZW5kQW5nbGUgLSBkKSArIGN5O1xuICAgICAgICAgICAgc2VnbWVudC5lbmRUYW5nZW50ID0gW3ByZVBvaW50WzBdIC0gZHgyLCBwcmVQb2ludFsxXSAtIGR5Ml07XG4gICAgICAgIH1cbiAgICAgICAgc2VnbWVudHMucHVzaChzZWdtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHNlZ21lbnRzO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0U2VnbWVudHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXRoLTItc2VnbWVudHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgcmVjdF9wYXRoXzEgPSByZXF1aXJlKFwiLi9yZWN0LXBhdGhcIik7XG52YXIgcGF0aF8yX2N1cnZlXzEgPSByZXF1aXJlKFwiLi9wYXRoLTItY3VydmVcIik7XG52YXIgYmFzZTMgPSBmdW5jdGlvbiAodCwgcDEsIHAyLCBwMywgcDQpIHtcbiAgICB2YXIgdDEgPSAtMyAqIHAxICsgOSAqIHAyIC0gOSAqIHAzICsgMyAqIHA0O1xuICAgIHZhciB0MiA9IHQgKiB0MSArIDYgKiBwMSAtIDEyICogcDIgKyA2ICogcDM7XG4gICAgcmV0dXJuIHQgKiB0MiAtIDMgKiBwMSArIDMgKiBwMjtcbn07XG52YXIgYmV6bGVuID0gZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeikge1xuICAgIGlmICh6ID09PSBudWxsKSB7XG4gICAgICAgIHogPSAxO1xuICAgIH1cbiAgICB6ID0geiA+IDEgPyAxIDogeiA8IDAgPyAwIDogejtcbiAgICB2YXIgejIgPSB6IC8gMjtcbiAgICB2YXIgbiA9IDEyO1xuICAgIHZhciBUdmFsdWVzID0gWy0wLjEyNTIsIDAuMTI1MiwgLTAuMzY3OCwgMC4zNjc4LCAtMC41ODczLCAwLjU4NzMsIC0wLjc2OTksIDAuNzY5OSwgLTAuOTA0MSwgMC45MDQxLCAtMC45ODE2LCAwLjk4MTZdO1xuICAgIHZhciBDdmFsdWVzID0gWzAuMjQ5MSwgMC4yNDkxLCAwLjIzMzUsIDAuMjMzNSwgMC4yMDMyLCAwLjIwMzIsIDAuMTYwMSwgMC4xNjAxLCAwLjEwNjksIDAuMTA2OSwgMC4wNDcyLCAwLjA0NzJdO1xuICAgIHZhciBzdW0gPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIHZhciBjdCA9IHoyICogVHZhbHVlc1tpXSArIHoyO1xuICAgICAgICB2YXIgeGJhc2UgPSBiYXNlMyhjdCwgeDEsIHgyLCB4MywgeDQpO1xuICAgICAgICB2YXIgeWJhc2UgPSBiYXNlMyhjdCwgeTEsIHkyLCB5MywgeTQpO1xuICAgICAgICB2YXIgY29tYiA9IHhiYXNlICogeGJhc2UgKyB5YmFzZSAqIHliYXNlO1xuICAgICAgICBzdW0gKz0gQ3ZhbHVlc1tpXSAqIE1hdGguc3FydChjb21iKTtcbiAgICB9XG4gICAgcmV0dXJuIHoyICogc3VtO1xufTtcbnZhciBjdXJ2ZURpbSA9IGZ1bmN0aW9uICh4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgICB2YXIgdHZhbHVlcyA9IFtdO1xuICAgIHZhciBib3VuZHMgPSBbXG4gICAgICAgIFtdLFxuICAgICAgICBbXSxcbiAgICBdO1xuICAgIHZhciBhO1xuICAgIHZhciBiO1xuICAgIHZhciBjO1xuICAgIHZhciB0O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjsgKytpKSB7XG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgICBiID0gNiAqIHgwIC0gMTIgKiB4MSArIDYgKiB4MjtcbiAgICAgICAgICAgIGEgPSAtMyAqIHgwICsgOSAqIHgxIC0gOSAqIHgyICsgMyAqIHgzO1xuICAgICAgICAgICAgYyA9IDMgKiB4MSAtIDMgKiB4MDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGIgPSA2ICogeTAgLSAxMiAqIHkxICsgNiAqIHkyO1xuICAgICAgICAgICAgYSA9IC0zICogeTAgKyA5ICogeTEgLSA5ICogeTIgKyAzICogeTM7XG4gICAgICAgICAgICBjID0gMyAqIHkxIC0gMyAqIHkwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChNYXRoLmFicyhhKSA8IDFlLTEyKSB7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoYikgPCAxZS0xMikge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdCA9IC1jIC8gYjtcbiAgICAgICAgICAgIGlmICh0ID4gMCAmJiB0IDwgMSkge1xuICAgICAgICAgICAgICAgIHR2YWx1ZXMucHVzaCh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiMmFjID0gYiAqIGIgLSA0ICogYyAqIGE7XG4gICAgICAgIHZhciBzcXJ0YjJhYyA9IE1hdGguc3FydChiMmFjKTtcbiAgICAgICAgaWYgKGIyYWMgPCAwKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdDEgPSAoLWIgKyBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuICAgICAgICBpZiAodDEgPiAwICYmIHQxIDwgMSkge1xuICAgICAgICAgICAgdHZhbHVlcy5wdXNoKHQxKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdDIgPSAoLWIgLSBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuICAgICAgICBpZiAodDIgPiAwICYmIHQyIDwgMSkge1xuICAgICAgICAgICAgdHZhbHVlcy5wdXNoKHQyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgaiA9IHR2YWx1ZXMubGVuZ3RoO1xuICAgIHZhciBqbGVuID0gajtcbiAgICB2YXIgbXQ7XG4gICAgd2hpbGUgKGotLSkge1xuICAgICAgICB0ID0gdHZhbHVlc1tqXTtcbiAgICAgICAgbXQgPSAxIC0gdDtcbiAgICAgICAgYm91bmRzWzBdW2pdID0gKG10ICogbXQgKiBtdCAqIHgwKSArICgzICogbXQgKiBtdCAqIHQgKiB4MSkgKyAoMyAqIG10ICogdCAqIHQgKiB4MikgKyAodCAqIHQgKiB0ICogeDMpO1xuICAgICAgICBib3VuZHNbMV1bal0gPSAobXQgKiBtdCAqIG10ICogeTApICsgKDMgKiBtdCAqIG10ICogdCAqIHkxKSArICgzICogbXQgKiB0ICogdCAqIHkyKSArICh0ICogdCAqIHQgKiB5Myk7XG4gICAgfVxuICAgIGJvdW5kc1swXVtqbGVuXSA9IHgwO1xuICAgIGJvdW5kc1sxXVtqbGVuXSA9IHkwO1xuICAgIGJvdW5kc1swXVtqbGVuICsgMV0gPSB4MztcbiAgICBib3VuZHNbMV1bamxlbiArIDFdID0geTM7XG4gICAgYm91bmRzWzBdLmxlbmd0aCA9IGJvdW5kc1sxXS5sZW5ndGggPSBqbGVuICsgMjtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW46IHtcbiAgICAgICAgICAgIHg6IE1hdGgubWluLmFwcGx5KDAsIGJvdW5kc1swXSksXG4gICAgICAgICAgICB5OiBNYXRoLm1pbi5hcHBseSgwLCBib3VuZHNbMV0pLFxuICAgICAgICB9LFxuICAgICAgICBtYXg6IHtcbiAgICAgICAgICAgIHg6IE1hdGgubWF4LmFwcGx5KDAsIGJvdW5kc1swXSksXG4gICAgICAgICAgICB5OiBNYXRoLm1heC5hcHBseSgwLCBib3VuZHNbMV0pLFxuICAgICAgICB9LFxuICAgIH07XG59O1xudmFyIGludGVyc2VjdCA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIHtcbiAgICBpZiAoTWF0aC5tYXgoeDEsIHgyKSA8IE1hdGgubWluKHgzLCB4NCkgfHxcbiAgICAgICAgTWF0aC5taW4oeDEsIHgyKSA+IE1hdGgubWF4KHgzLCB4NCkgfHxcbiAgICAgICAgTWF0aC5tYXgoeTEsIHkyKSA8IE1hdGgubWluKHkzLCB5NCkgfHxcbiAgICAgICAgTWF0aC5taW4oeTEsIHkyKSA+IE1hdGgubWF4KHkzLCB5NCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgbnggPSAoeDEgKiB5MiAtIHkxICogeDIpICogKHgzIC0geDQpIC0gKHgxIC0geDIpICogKHgzICogeTQgLSB5MyAqIHg0KTtcbiAgICB2YXIgbnkgPSAoeDEgKiB5MiAtIHkxICogeDIpICogKHkzIC0geTQpIC0gKHkxIC0geTIpICogKHgzICogeTQgLSB5MyAqIHg0KTtcbiAgICB2YXIgZGVub21pbmF0b3IgPSAoeDEgLSB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgLSB4NCk7XG4gICAgaWYgKCFkZW5vbWluYXRvcikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBweCA9IG54IC8gZGVub21pbmF0b3I7XG4gICAgdmFyIHB5ID0gbnkgLyBkZW5vbWluYXRvcjtcbiAgICB2YXIgcHgyID0gK3B4LnRvRml4ZWQoMik7XG4gICAgdmFyIHB5MiA9ICtweS50b0ZpeGVkKDIpO1xuICAgIGlmIChweDIgPCArTWF0aC5taW4oeDEsIHgyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB4MiA+ICtNYXRoLm1heCh4MSwgeDIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHgyIDwgK01hdGgubWluKHgzLCB4NCkudG9GaXhlZCgyKSB8fFxuICAgICAgICBweDIgPiArTWF0aC5tYXgoeDMsIHg0KS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB5MiA8ICtNYXRoLm1pbih5MSwgeTIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHkyID4gK01hdGgubWF4KHkxLCB5MikudG9GaXhlZCgyKSB8fFxuICAgICAgICBweTIgPCArTWF0aC5taW4oeTMsIHk0KS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB5MiA+ICtNYXRoLm1heCh5MywgeTQpLnRvRml4ZWQoMikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBweCxcbiAgICAgICAgeTogcHksXG4gICAgfTtcbn07XG52YXIgaXNQb2ludEluc2lkZUJCb3ggPSBmdW5jdGlvbiAoYmJveCwgeCwgeSkge1xuICAgIHJldHVybiB4ID49IGJib3gueCAmJlxuICAgICAgICB4IDw9IGJib3gueCArIGJib3gud2lkdGggJiZcbiAgICAgICAgeSA+PSBiYm94LnkgJiZcbiAgICAgICAgeSA8PSBiYm94LnkgKyBiYm94LmhlaWdodDtcbn07XG52YXIgYm94ID0gZnVuY3Rpb24gKHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcbiAgICBpZiAoeCA9PT0gbnVsbCkge1xuICAgICAgICB4ID0geSA9IHdpZHRoID0gaGVpZ2h0ID0gMDtcbiAgICB9XG4gICAgaWYgKHkgPT09IG51bGwpIHtcbiAgICAgICAgeSA9IHgueTtcbiAgICAgICAgd2lkdGggPSB4LndpZHRoO1xuICAgICAgICBoZWlnaHQgPSB4LmhlaWdodDtcbiAgICAgICAgeCA9IHgueDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICB3OiB3aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgIGg6IGhlaWdodCxcbiAgICAgICAgeDI6IHggKyB3aWR0aCxcbiAgICAgICAgeTI6IHkgKyBoZWlnaHQsXG4gICAgICAgIGN4OiB4ICsgd2lkdGggLyAyLFxuICAgICAgICBjeTogeSArIGhlaWdodCAvIDIsXG4gICAgICAgIHIxOiBNYXRoLm1pbih3aWR0aCwgaGVpZ2h0KSAvIDIsXG4gICAgICAgIHIyOiBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSAvIDIsXG4gICAgICAgIHIwOiBNYXRoLnNxcnQod2lkdGggKiB3aWR0aCArIGhlaWdodCAqIGhlaWdodCkgLyAyLFxuICAgICAgICBwYXRoOiByZWN0X3BhdGhfMS5kZWZhdWx0KHgsIHksIHdpZHRoLCBoZWlnaHQpLFxuICAgICAgICB2YjogW3gsIHksIHdpZHRoLCBoZWlnaHRdLmpvaW4oJyAnKSxcbiAgICB9O1xufTtcbnZhciBpc0JCb3hJbnRlcnNlY3QgPSBmdW5jdGlvbiAoYmJveDEsIGJib3gyKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGJib3gxID0gYm94KGJib3gxKTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgYmJveDIgPSBib3goYmJveDIpO1xuICAgIHJldHVybiBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueSkgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDIsIGJib3gxLngyLCBiYm94MS55KSB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueTIpIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55KSB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MSwgYmJveDIueDIsIGJib3gyLnkpIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55MikgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngyLCBiYm94Mi55MikgfHwgKGJib3gxLnggPCBiYm94Mi54MiAmJiBiYm94MS54ID4gYmJveDIueCB8fCBiYm94Mi54IDwgYmJveDEueDIgJiYgYmJveDIueCA+IGJib3gxLngpICYmIChiYm94MS55IDwgYmJveDIueTIgJiYgYmJveDEueSA+IGJib3gyLnkgfHwgYmJveDIueSA8IGJib3gxLnkyICYmIGJib3gyLnkgPiBiYm94MS55KTtcbn07XG52YXIgYmV6aWVyQkJveCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSkge1xuICAgIGlmICghdXRpbF8xLmlzQXJyYXkocDF4KSkge1xuICAgICAgICBwMXggPSBbcDF4LCBwMXksIGMxeCwgYzF5LCBjMngsIGMyeSwgcDJ4LCBwMnldO1xuICAgIH1cbiAgICB2YXIgYmJveCA9IGN1cnZlRGltLmFwcGx5KG51bGwsIHAxeCk7XG4gICAgcmV0dXJuIGJveChiYm94Lm1pbi54LCBiYm94Lm1pbi55LCBiYm94Lm1heC54IC0gYmJveC5taW4ueCwgYmJveC5tYXgueSAtIGJib3gubWluLnkpO1xufTtcbnZhciBmaW5kRG90c0F0U2VnbWVudCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdCkge1xuICAgIHZhciB0MSA9IDEgLSB0O1xuICAgIHZhciB0MTMgPSBNYXRoLnBvdyh0MSwgMyk7XG4gICAgdmFyIHQxMiA9IE1hdGgucG93KHQxLCAyKTtcbiAgICB2YXIgdDIgPSB0ICogdDtcbiAgICB2YXIgdDMgPSB0MiAqIHQ7XG4gICAgdmFyIHggPSB0MTMgKiBwMXggKyB0MTIgKiAzICogdCAqIGMxeCArIHQxICogMyAqIHQgKiB0ICogYzJ4ICsgdDMgKiBwMng7XG4gICAgdmFyIHkgPSB0MTMgKiBwMXkgKyB0MTIgKiAzICogdCAqIGMxeSArIHQxICogMyAqIHQgKiB0ICogYzJ5ICsgdDMgKiBwMnk7XG4gICAgdmFyIG14ID0gcDF4ICsgMiAqIHQgKiAoYzF4IC0gcDF4KSArIHQyICogKGMyeCAtIDIgKiBjMXggKyBwMXgpO1xuICAgIHZhciBteSA9IHAxeSArIDIgKiB0ICogKGMxeSAtIHAxeSkgKyB0MiAqIChjMnkgLSAyICogYzF5ICsgcDF5KTtcbiAgICB2YXIgbnggPSBjMXggKyAyICogdCAqIChjMnggLSBjMXgpICsgdDIgKiAocDJ4IC0gMiAqIGMyeCArIGMxeCk7XG4gICAgdmFyIG55ID0gYzF5ICsgMiAqIHQgKiAoYzJ5IC0gYzF5KSArIHQyICogKHAyeSAtIDIgKiBjMnkgKyBjMXkpO1xuICAgIHZhciBheCA9IHQxICogcDF4ICsgdCAqIGMxeDtcbiAgICB2YXIgYXkgPSB0MSAqIHAxeSArIHQgKiBjMXk7XG4gICAgdmFyIGN4ID0gdDEgKiBjMnggKyB0ICogcDJ4O1xuICAgIHZhciBjeSA9IHQxICogYzJ5ICsgdCAqIHAyeTtcbiAgICB2YXIgYWxwaGEgPSAoOTAgLSBNYXRoLmF0YW4yKG14IC0gbngsIG15IC0gbnkpICogMTgwIC8gTWF0aC5QSSk7XG4gICAgLy8gKG14ID4gbnggfHwgbXkgPCBueSkgJiYgKGFscGhhICs9IDE4MCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeSxcbiAgICAgICAgbToge1xuICAgICAgICAgICAgeDogbXgsXG4gICAgICAgICAgICB5OiBteSxcbiAgICAgICAgfSxcbiAgICAgICAgbjoge1xuICAgICAgICAgICAgeDogbngsXG4gICAgICAgICAgICB5OiBueSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RhcnQ6IHtcbiAgICAgICAgICAgIHg6IGF4LFxuICAgICAgICAgICAgeTogYXksXG4gICAgICAgIH0sXG4gICAgICAgIGVuZDoge1xuICAgICAgICAgICAgeDogY3gsXG4gICAgICAgICAgICB5OiBjeSxcbiAgICAgICAgfSxcbiAgICAgICAgYWxwaGE6IGFscGhhLFxuICAgIH07XG59O1xudmFyIGludGVySGVscGVyID0gZnVuY3Rpb24gKGJlejEsIGJlejIsIGp1c3RDb3VudCkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB2YXIgYmJveDEgPSBiZXppZXJCQm94KGJlejEpO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB2YXIgYmJveDIgPSBiZXppZXJCQm94KGJlejIpO1xuICAgIGlmICghaXNCQm94SW50ZXJzZWN0KGJib3gxLCBiYm94MikpIHtcbiAgICAgICAgcmV0dXJuIGp1c3RDb3VudCA/IDAgOiBbXTtcbiAgICB9XG4gICAgdmFyIGwxID0gYmV6bGVuLmFwcGx5KDAsIGJlejEpO1xuICAgIHZhciBsMiA9IGJlemxlbi5hcHBseSgwLCBiZXoyKTtcbiAgICB2YXIgbjEgPSB+fihsMSAvIDgpO1xuICAgIHZhciBuMiA9IH5+KGwyIC8gOCk7XG4gICAgdmFyIGRvdHMxID0gW107XG4gICAgdmFyIGRvdHMyID0gW107XG4gICAgdmFyIHh5ID0ge307XG4gICAgdmFyIHJlcyA9IGp1c3RDb3VudCA/IDAgOiBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4xICsgMTsgaSsrKSB7XG4gICAgICAgIHZhciBkID0gZmluZERvdHNBdFNlZ21lbnQuYXBwbHkoMCwgYmV6MS5jb25jYXQoaSAvIG4xKSk7XG4gICAgICAgIGRvdHMxLnB1c2goe1xuICAgICAgICAgICAgeDogZC54LFxuICAgICAgICAgICAgeTogZC55LFxuICAgICAgICAgICAgdDogaSAvIG4xLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuMiArIDE7IGkrKykge1xuICAgICAgICB2YXIgZCA9IGZpbmREb3RzQXRTZWdtZW50LmFwcGx5KDAsIGJlejIuY29uY2F0KGkgLyBuMikpO1xuICAgICAgICBkb3RzMi5wdXNoKHtcbiAgICAgICAgICAgIHg6IGQueCxcbiAgICAgICAgICAgIHk6IGQueSxcbiAgICAgICAgICAgIHQ6IGkgLyBuMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjE7IGkrKykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG4yOyBqKyspIHtcbiAgICAgICAgICAgIHZhciBkaSA9IGRvdHMxW2ldO1xuICAgICAgICAgICAgdmFyIGRpMSA9IGRvdHMxW2kgKyAxXTtcbiAgICAgICAgICAgIHZhciBkaiA9IGRvdHMyW2pdO1xuICAgICAgICAgICAgdmFyIGRqMSA9IGRvdHMyW2ogKyAxXTtcbiAgICAgICAgICAgIHZhciBjaSA9IE1hdGguYWJzKGRpMS54IC0gZGkueCkgPCAwLjAwMSA/ICd5JyA6ICd4JztcbiAgICAgICAgICAgIHZhciBjaiA9IE1hdGguYWJzKGRqMS54IC0gZGoueCkgPCAwLjAwMSA/ICd5JyA6ICd4JztcbiAgICAgICAgICAgIHZhciBpcyA9IGludGVyc2VjdChkaS54LCBkaS55LCBkaTEueCwgZGkxLnksIGRqLngsIGRqLnksIGRqMS54LCBkajEueSk7XG4gICAgICAgICAgICBpZiAoaXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoeHlbaXMueC50b0ZpeGVkKDQpXSA9PT0gaXMueS50b0ZpeGVkKDQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB4eVtpcy54LnRvRml4ZWQoNCldID0gaXMueS50b0ZpeGVkKDQpO1xuICAgICAgICAgICAgICAgIHZhciB0MSA9IGRpLnQgKyBNYXRoLmFicygoaXNbY2ldIC0gZGlbY2ldKSAvIChkaTFbY2ldIC0gZGlbY2ldKSkgKiAoZGkxLnQgLSBkaS50KTtcbiAgICAgICAgICAgICAgICB2YXIgdDIgPSBkai50ICsgTWF0aC5hYnMoKGlzW2NqXSAtIGRqW2NqXSkgLyAoZGoxW2NqXSAtIGRqW2NqXSkpICogKGRqMS50IC0gZGoudCk7XG4gICAgICAgICAgICAgICAgaWYgKHQxID49IDAgJiYgdDEgPD0gMSAmJiB0MiA+PSAwICYmIHQyIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGp1c3RDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzKys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaXMueCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpcy55LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQxOiB0MSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MjogdDIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcbnZhciBpbnRlclBhdGhIZWxwZXIgPSBmdW5jdGlvbiAocGF0aDEsIHBhdGgyLCBqdXN0Q291bnQpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcGF0aDEgPSBwYXRoXzJfY3VydmVfMS5kZWZhdWx0KHBhdGgxKTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcGF0aDIgPSBwYXRoXzJfY3VydmVfMS5kZWZhdWx0KHBhdGgyKTtcbiAgICB2YXIgeDE7XG4gICAgdmFyIHkxO1xuICAgIHZhciB4MjtcbiAgICB2YXIgeTI7XG4gICAgdmFyIHgxbTtcbiAgICB2YXIgeTFtO1xuICAgIHZhciB4Mm07XG4gICAgdmFyIHkybTtcbiAgICB2YXIgYmV6MTtcbiAgICB2YXIgYmV6MjtcbiAgICB2YXIgcmVzID0ganVzdENvdW50ID8gMCA6IFtdO1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHBhdGgxLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgdmFyIHBpID0gcGF0aDFbaV07XG4gICAgICAgIGlmIChwaVswXSA9PT0gJ00nKSB7XG4gICAgICAgICAgICB4MSA9IHgxbSA9IHBpWzFdO1xuICAgICAgICAgICAgeTEgPSB5MW0gPSBwaVsyXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwaVswXSA9PT0gJ0MnKSB7XG4gICAgICAgICAgICAgICAgYmV6MSA9IFt4MSwgeTFdLmNvbmNhdChwaS5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgeDEgPSBiZXoxWzZdO1xuICAgICAgICAgICAgICAgIHkxID0gYmV6MVs3XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJlejEgPSBbeDEsIHkxLCB4MSwgeTEsIHgxbSwgeTFtLCB4MW0sIHkxbV07XG4gICAgICAgICAgICAgICAgeDEgPSB4MW07XG4gICAgICAgICAgICAgICAgeTEgPSB5MW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMCwgamogPSBwYXRoMi5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBqID0gcGF0aDJbal07XG4gICAgICAgICAgICAgICAgaWYgKHBqWzBdID09PSAnTScpIHtcbiAgICAgICAgICAgICAgICAgICAgeDIgPSB4Mm0gPSBwalsxXTtcbiAgICAgICAgICAgICAgICAgICAgeTIgPSB5Mm0gPSBwalsyXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwalswXSA9PT0gJ0MnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiZXoyID0gW3gyLCB5Ml0uY29uY2F0KHBqLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHgyID0gYmV6Mls2XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHkyID0gYmV6Mls3XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyLCB4MiwgeTIsIHgybSwgeTJtLCB4Mm0sIHkybV07XG4gICAgICAgICAgICAgICAgICAgICAgICB4MiA9IHgybTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHkyID0geTJtO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnRyID0gaW50ZXJIZWxwZXIoYmV6MSwgYmV6MiwganVzdENvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGp1c3RDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzICs9IGludHI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrID0gMCwga2sgPSBpbnRyLmxlbmd0aDsgayA8IGtrOyBrKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRyW2tdLnNlZ21lbnQxID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRyW2tdLnNlZ21lbnQyID0gajtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRyW2tdLmJlejEgPSBiZXoxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uYmV6MiA9IGJlejI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgPSByZXMuY29uY2F0KGludHIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59O1xuZnVuY3Rpb24gcGF0aEludGVyc2VjdGlvbihwYXRoMSwgcGF0aDIpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIGludGVyUGF0aEhlbHBlcihwYXRoMSwgcGF0aDIpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gcGF0aEludGVyc2VjdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhdGgtaW50ZXJzZWN0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOWIpOaWreeCueaYr+WQpuWcqOWkmui+ueW9ouWGhVxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIOWkmui+ueW9oueahOWwhOe6v+ajgOa1i++8jOWPguiAg++8mmh0dHBzOi8vYmxvZy5jc2RuLm5ldC9XaWxsaWFtU3VuMDEyMi9hcnRpY2xlL2RldGFpbHMvNzc5OTQ1MjZcbnZhciB0b2xlcmFuY2UgPSAxZS02O1xuLy8g5LiJ5oCB5Ye95pWw77yM5Yik5pat5Lik5LiqZG91Ymxl5ZyoZXBz57K+5bqm5LiL55qE5aSn5bCP5YWz57O7XG5mdW5jdGlvbiBkY21wKHgpIHtcbiAgICBpZiAoTWF0aC5hYnMoeCkgPCB0b2xlcmFuY2UpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiB4IDwgMCA/IC0xIDogMTtcbn1cbi8vIOWIpOaWreeCuVHmmK/lkKblnKhwMeWSjHAy55qE57q/5q615LiKXG5mdW5jdGlvbiBvblNlZ21lbnQocDEsIHAyLCBxKSB7XG4gICAgaWYgKChxWzBdIC0gcDFbMF0pICogKHAyWzFdIC0gcDFbMV0pID09PSAocDJbMF0gLSBwMVswXSkgKiAocVsxXSAtIHAxWzFdKSAmJlxuICAgICAgICBNYXRoLm1pbihwMVswXSwgcDJbMF0pIDw9IHFbMF0gJiZcbiAgICAgICAgcVswXSA8PSBNYXRoLm1heChwMVswXSwgcDJbMF0pICYmXG4gICAgICAgIE1hdGgubWluKHAxWzFdLCBwMlsxXSkgPD0gcVsxXSAmJlxuICAgICAgICBxWzFdIDw9IE1hdGgubWF4KHAxWzFdLCBwMlsxXSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8vIOWIpOaWreeCuVDlnKjlpJrovrnlvaLlhoUt5bCE57q/5rOVXG5mdW5jdGlvbiBpc0luUG9seWdvbihwb2ludHMsIHgsIHkpIHtcbiAgICB2YXIgaXNIaXQgPSBmYWxzZTtcbiAgICB2YXIgbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgaWYgKG4gPD0gMikge1xuICAgICAgICAvLyBzdmcg5Lit54K55bCP5LqOIDMg5Liq5pe277yM5LiN5pi+56S677yM5Lmf5peg5rOV6KKr5ou+5Y+WXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIHAxID0gcG9pbnRzW2ldO1xuICAgICAgICB2YXIgcDIgPSBwb2ludHNbKGkgKyAxKSAlIG5dO1xuICAgICAgICBpZiAob25TZWdtZW50KHAxLCBwMiwgW3gsIHldKSkge1xuICAgICAgICAgICAgLy8g54K55Zyo5aSa6L655b2i5LiA5p2h6L655LiKXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyDliY3kuIDkuKrliKTmlq1taW4ocDFbMV0scDJbMV0pPFAueTw9bWF4KHAxWzFdLHAyWzFdKVxuICAgICAgICAvLyDlkI7kuIDkuKrliKTmlq3ooqvmtYvngrkg5ZyoIOWwhOe6v+S4jui+ueS6pOeCuSDnmoTlt6bovrlcbiAgICAgICAgaWYgKGRjbXAocDFbMV0gLSB5KSA+IDAgIT09IGRjbXAocDJbMV0gLSB5KSA+IDAgJiZcbiAgICAgICAgICAgIGRjbXAoeCAtICgoeSAtIHAxWzFdKSAqIChwMVswXSAtIHAyWzBdKSkgLyAocDFbMV0gLSBwMlsxXSkgLSBwMVswXSkgPCAwKSB7XG4gICAgICAgICAgICBpc0hpdCA9ICFpc0hpdDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNIaXQ7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBpc0luUG9seWdvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvaW50LWluLXBvbHlnb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiByZWN0UGF0aCh4LCB5LCB3LCBoLCByKSB7XG4gICAgaWYgKHIpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIFsnTScsICt4ICsgKCtyKSwgeV0sXG4gICAgICAgICAgICBbJ2wnLCB3IC0gciAqIDIsIDBdLFxuICAgICAgICAgICAgWydhJywgciwgciwgMCwgMCwgMSwgciwgcl0sXG4gICAgICAgICAgICBbJ2wnLCAwLCBoIC0gciAqIDJdLFxuICAgICAgICAgICAgWydhJywgciwgciwgMCwgMCwgMSwgLXIsIHJdLFxuICAgICAgICAgICAgWydsJywgciAqIDIgLSB3LCAwXSxcbiAgICAgICAgICAgIFsnYScsIHIsIHIsIDAsIDAsIDEsIC1yLCAtcl0sXG4gICAgICAgICAgICBbJ2wnLCAwLCByICogMiAtIGhdLFxuICAgICAgICAgICAgWydhJywgciwgciwgMCwgMCwgMSwgciwgLXJdLFxuICAgICAgICAgICAgWyd6J10sXG4gICAgICAgIF07XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICAgIFsnTScsIHgsIHldLFxuICAgICAgICBbJ2wnLCB3LCAwXSxcbiAgICAgICAgWydsJywgMCwgaF0sXG4gICAgICAgIFsnbCcsIC13LCAwXSxcbiAgICAgICAgWyd6J10sXG4gICAgXTtcbiAgICAvLyByZXMucGFyc2VQYXRoQXJyYXkgPSBwYXJzZVBhdGhBcnJheTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHJlY3RQYXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVjdC1wYXRoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIHJlZ2lzdGVyXzEgPSByZXF1aXJlKFwiLi90aWNrLW1ldGhvZC9yZWdpc3RlclwiKTtcbnZhciBTY2FsZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTY2FsZShjZmcpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOW6pumHj+eahOexu+Wei1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy50eXBlID0gJ2Jhc2UnO1xuICAgICAgICAvKipcbiAgICAgICAgICog5piv5ZCm5YiG57G757G75Z6L55qE5bqm6YePXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzQ2F0ZWdvcnkgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOaYr+WQpue6v+aAp+W6pumHj++8jOaciWxpbmVhciwgdGltZSDluqbph49cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNMaW5lYXIgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOaYr+WQpui/nue7reexu+Wei+eahOW6pumHj++8jGxpbmVhcix0aW1lLGxvZywgcG93LCBxdWFudGlsZSwgcXVhbnRpemUg6YO95pSv5oyBXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzQ29udGludW91cyA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICog5piv5ZCm5piv5bi46YeP55qE5bqm6YeP77yM5Lyg5YWl5ZKM5Lyg5Ye65LiA6Ie0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzSWRlbnRpdHkgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52YWx1ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5yYW5nZSA9IFswLCAxXTtcbiAgICAgICAgdGhpcy50aWNrcyA9IFtdO1xuICAgICAgICB0aGlzLl9fY2ZnX18gPSBjZmc7XG4gICAgICAgIHRoaXMuaW5pdENmZygpO1xuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG4gICAgLy8g5a+55LqO5Y6f5aeL5YC855qE5b+F6KaB6L2s5o2i77yM5aaC5YiG57G744CB5pe26Ze05a2X5q616ZyA6L2s5o2i5oiQ5pWw5YC877yM55SodHJhbnNmb3JtL21hcOWRveWQjeWPr+iDveabtOWlvVxuICAgIFNjYWxlLnByb3RvdHlwZS50cmFuc2xhdGUgPSBmdW5jdGlvbiAodikge1xuICAgICAgICByZXR1cm4gdjtcbiAgICB9O1xuICAgIC8qKiDph43mlrDliJ3lp4vljJYgKi9cbiAgICBTY2FsZS5wcm90b3R5cGUuY2hhbmdlID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICAvLyDopobnm5bphY3nva7pobnvvIzogIzkuI3mm7/ku6NcbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLl9fY2ZnX18sIGNmZyk7XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH07XG4gICAgU2NhbGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLl9fY2ZnX18pO1xuICAgIH07XG4gICAgLyoqIOiOt+WPluWdkOagh+i9tOmcgOimgeeahHRpY2tzICovXG4gICAgU2NhbGUucHJvdG90eXBlLmdldFRpY2tzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICByZXR1cm4gdXRpbF8xLm1hcCh0aGlzLnRpY2tzLCBmdW5jdGlvbiAodGljaywgaWR4KSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzT2JqZWN0KHRpY2spKSB7XG4gICAgICAgICAgICAgICAgLy8g5LuF5b2T56ym5ZCIVGlja+exu+Wei+aXtuaJjeacieaEj+S5iVxuICAgICAgICAgICAgICAgIHJldHVybiB0aWNrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBfdGhpcy5nZXRUZXh0KHRpY2ssIGlkeCksXG4gICAgICAgICAgICAgICAgdGlja1ZhbHVlOiB0aWNrLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBfdGhpcy5zY2FsZSh0aWNrKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqIOiOt+WPllRpY2vnmoTmoLzlvI/ljJbnu5PmnpwgKi9cbiAgICBTY2FsZS5wcm90b3R5cGUuZ2V0VGV4dCA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgIHZhciBmb3JtYXR0ZXIgPSB0aGlzLmZvcm1hdHRlcjtcbiAgICAgICAgdmFyIHJlcyA9IGZvcm1hdHRlciA/IGZvcm1hdHRlcih2YWx1ZSwga2V5KSA6IHZhbHVlO1xuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKHJlcykgfHwgIXV0aWxfMS5pc0Z1bmN0aW9uKHJlcy50b1N0cmluZykpIHtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzLnRvU3RyaW5nKCk7XG4gICAgfTtcbiAgICAvLyDojrflj5bphY3nva7pobnkuK3nmoTlgLzvvIzlvZPliY0gc2NhbGUg5LiK55qE5YC85Y+v6IO95Lya6KKr5L+u5pS5XG4gICAgU2NhbGUucHJvdG90eXBlLmdldENvbmZpZyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19jZmdfX1trZXldO1xuICAgIH07XG4gICAgLy8gc2NhbGXliJ3lp4vljJZcbiAgICBTY2FsZS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdXRpbF8xLmFzc2lnbih0aGlzLCB0aGlzLl9fY2ZnX18pO1xuICAgICAgICB0aGlzLnNldERvbWFpbigpO1xuICAgICAgICBpZiAodXRpbF8xLmlzRW1wdHkodGhpcy5nZXRDb25maWcoJ3RpY2tzJykpKSB7XG4gICAgICAgICAgICB0aGlzLnRpY2tzID0gdGhpcy5jYWxjdWxhdGVUaWNrcygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDlrZDnsbvkuIropobnm5bmn5DkupvlsZ7mgKfvvIzkuI3og73nm7TmjqXlnKjnsbvkuIrlo7DmmI7vvIzlkKbliJnkvJrooqvopobnm5ZcbiAgICBTY2FsZS5wcm90b3R5cGUuaW5pdENmZyA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICBTY2FsZS5wcm90b3R5cGUuc2V0RG9tYWluID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgIFNjYWxlLnByb3RvdHlwZS5jYWxjdWxhdGVUaWNrcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpY2tNZXRob2QgPSB0aGlzLnRpY2tNZXRob2Q7XG4gICAgICAgIHZhciB0aWNrcyA9IFtdO1xuICAgICAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHRpY2tNZXRob2QpKSB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gcmVnaXN0ZXJfMS5nZXRUaWNrTWV0aG9kKHRpY2tNZXRob2QpO1xuICAgICAgICAgICAgaWYgKCFtZXRob2QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIG1ldGhvZCB0byB0byBjYWxjdWxhdGUgdGlja3MhJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aWNrcyA9IG1ldGhvZCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh1dGlsXzEuaXNGdW5jdGlvbih0aWNrTWV0aG9kKSkge1xuICAgICAgICAgICAgdGlja3MgPSB0aWNrTWV0aG9kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aWNrcztcbiAgICB9O1xuICAgIC8vIHJhbmdlIOeahOacgOWwj+WAvFxuICAgIFNjYWxlLnByb3RvdHlwZS5yYW5nZU1pbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5oZWFkKHRoaXMucmFuZ2UpO1xuICAgIH07XG4gICAgLy8gcmFuZ2Ug55qE5pyA5aSn5YC8XG4gICAgU2NhbGUucHJvdG90eXBlLnJhbmdlTWF4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmxhc3QodGhpcy5yYW5nZSk7XG4gICAgfTtcbiAgICAvKiog5a6a5LmJ5Z+f6L2sIDB+MSAqL1xuICAgIFNjYWxlLnByb3RvdHlwZS5jYWxjUGVyY2VudCA9IGZ1bmN0aW9uICh2YWx1ZSwgbWluLCBtYXgpIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc051bWJlcih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiAodmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE5hTjtcbiAgICB9O1xuICAgIC8qKiAwfjHovazlrprkuYnln58gKi9cbiAgICBTY2FsZS5wcm90b3R5cGUuY2FsY1ZhbHVlID0gZnVuY3Rpb24gKHBlcmNlbnQsIG1pbiwgbWF4KSB7XG4gICAgICAgIHJldHVybiBtaW4gKyBwZXJjZW50ICogKG1heCAtIG1pbik7XG4gICAgfTtcbiAgICByZXR1cm4gU2NhbGU7XG59KCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gU2NhbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG4vKipcbiAqIOWIhuexu+W6pumHj1xuICogQGNsYXNzXG4gKi9cbnZhciBDYXRlZ29yeSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhDYXRlZ29yeSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBDYXRlZ29yeSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnY2F0JztcbiAgICAgICAgX3RoaXMuaXNDYXRlZ29yeSA9IHRydWU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgaW5kZXggPSB1dGlsXzEuaW5kZXhPZih0aGlzLnZhbHVlcywgdmFsdWUpO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8xLmlzTnVtYmVyKHZhbHVlKSA/IHZhbHVlIDogTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICB9O1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgb3JkZXIgPSB0aGlzLnRyYW5zbGF0ZSh2YWx1ZSk7XG4gICAgICAgIC8vIOWIhuexu+aVsOaNruWFgeiuuCAwLjUg6IyD5Zu05YaF6LCD5pW0XG4gICAgICAgIC8vIGlmIChvcmRlciA8IHRoaXMubWluIC0gMC41IHx8IG9yZGVyID4gdGhpcy5tYXggKyAwLjUpIHtcbiAgICAgICAgLy8gICByZXR1cm4gTmFOO1xuICAgICAgICAvLyB9XG4gICAgICAgIHZhciBwZXJjZW50ID0gdGhpcy5jYWxjUGVyY2VudChvcmRlciwgdGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsY1ZhbHVlKHBlcmNlbnQsIHRoaXMucmFuZ2VNaW4oKSwgdGhpcy5yYW5nZU1heCgpKTtcbiAgICB9O1xuICAgIENhdGVnb3J5LnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbiAoc2NhbGVkVmFsdWUpIHtcbiAgICAgICAgdmFyIGRvbWFpblJhbmdlID0gdGhpcy5tYXggLSB0aGlzLm1pbjtcbiAgICAgICAgdmFyIHBlcmNlbnQgPSB0aGlzLmNhbGNQZXJjZW50KHNjYWxlZFZhbHVlLCB0aGlzLnJhbmdlTWluKCksIHRoaXMucmFuZ2VNYXgoKSk7XG4gICAgICAgIHZhciBpZHggPSBNYXRoLnJvdW5kKGRvbWFpblJhbmdlICogcGVyY2VudCkgKyB0aGlzLm1pbjtcbiAgICAgICAgaWYgKGlkeCA8IHRoaXMubWluIHx8IGlkeCA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlc1tpZHhdO1xuICAgIH07XG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAxOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHYgPSB2YWx1ZTtcbiAgICAgICAgLy8gdmFsdWXkuLppbmRleFxuICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKHZhbHVlKSAmJiAhdGhpcy52YWx1ZXMuaW5jbHVkZXModmFsdWUpKSB7XG4gICAgICAgICAgICB2ID0gdGhpcy52YWx1ZXNbdl07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZ2V0VGV4dC5hcHBseSh0aGlzLCB0c2xpYl8xLl9fc3ByZWFkQXJyYXlzKFt2XSwgYXJncykpO1xuICAgIH07XG4gICAgLy8g5aSN5YaZ5bGe5oCnXG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLmluaXRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMudGlja01ldGhvZCA9ICdjYXQnO1xuICAgIH07XG4gICAgLy8g6K6+572uIG1pbiwgbWF4XG4gICAgQ2F0ZWdvcnkucHJvdG90eXBlLnNldERvbWFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8g55So5oi35pyJ5Y+v6IO96K6+572uIG1pblxuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKHRoaXMuZ2V0Q29uZmlnKCdtaW4nKSkpIHtcbiAgICAgICAgICAgIHRoaXMubWluID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXRpbF8xLmlzTmlsKHRoaXMuZ2V0Q29uZmlnKCdtYXgnKSkpIHtcbiAgICAgICAgICAgIHZhciBzaXplID0gdGhpcy52YWx1ZXMubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5tYXggPSBzaXplID4gMSA/IHNpemUgLSAxIDogc2l6ZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIENhdGVnb3J5O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ2F0ZWdvcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgdGltZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvdGltZVwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuLyoqXG4gKiDml7bpl7TliIbnsbvluqbph49cbiAqIEBjbGFzc1xuICovXG52YXIgVGltZUNhdCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUaW1lQ2F0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRpbWVDYXQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3RpbWVDYXQnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIFRpbWVDYXQucHJvdG90eXBlLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YWx1ZSA9IHRpbWVfMS50b1RpbWVTdGFtcCh2YWx1ZSk7XG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMudmFsdWVzLmluZGV4T2YodmFsdWUpO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzTnVtYmVyKHZhbHVlKSAmJiB2YWx1ZSA8IHRoaXMudmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IE5hTjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDnlLHkuo7ml7bpl7TnsbvlnovmlbDmja7pnIDopoHovazmjaLkuIDkuIvvvIzmiYDku6XlpI3lhpkgZ2V0VGV4dFxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIFRpbWVDYXQucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbiAodmFsdWUsIHRpY2tJbmRleCkge1xuICAgICAgICB2YXIgaW5kZXggPSB0aGlzLnRyYW5zbGF0ZSh2YWx1ZSk7XG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy52YWx1ZXNbaW5kZXhdO1xuICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IHRoaXMuZm9ybWF0dGVyO1xuICAgICAgICAgICAgcmVzdWx0ID0gZm9ybWF0dGVyID8gZm9ybWF0dGVyKHJlc3VsdCwgdGlja0luZGV4KSA6IHRpbWVfMS50aW1lRm9ybWF0KHJlc3VsdCwgdGhpcy5tYXNrKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgVGltZUNhdC5wcm90b3R5cGUuaW5pdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy50aWNrTWV0aG9kID0gJ3RpbWUtY2F0JztcbiAgICAgICAgdGhpcy5tYXNrID0gJ1lZWVktTU0tREQnO1xuICAgICAgICB0aGlzLnRpY2tDb3VudCA9IDc7IC8vIOS4gOiIrOaXtumXtOaVsOaNruS8muaYvuekuiA377yMIDE077yMIDMwIOWkqeeahOaVsOWtl1xuICAgIH07XG4gICAgVGltZUNhdC5wcm90b3R5cGUuc2V0RG9tYWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsdWVzID0gdGhpcy52YWx1ZXM7XG4gICAgICAgIC8vIOmSiOWvueaXtumXtOWIhuexu+exu+Wei++8jOS8muWwhuaXtumXtOe7n+S4gOi9rOaNouS4uuaXtumXtOaIs1xuICAgICAgICB1dGlsXzEuZWFjaCh2YWx1ZXMsIGZ1bmN0aW9uICh2LCBpKSB7XG4gICAgICAgICAgICB2YWx1ZXNbaV0gPSB0aW1lXzEudG9UaW1lU3RhbXAodik7XG4gICAgICAgIH0pO1xuICAgICAgICB2YWx1ZXMuc29ydChmdW5jdGlvbiAodjEsIHYyKSB7XG4gICAgICAgICAgICByZXR1cm4gdjEgLSB2MjtcbiAgICAgICAgfSk7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2V0RG9tYWluLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICByZXR1cm4gVGltZUNhdDtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFRpbWVDYXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG4vKipcbiAqIOi/nue7reW6pumHj+eahOWfuuexu1xuICogQGNsYXNzXG4gKi9cbnZhciBDb250aW51b3VzID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKENvbnRpbnVvdXMsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQ29udGludW91cygpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmlzQ29udGludW91cyA9IHRydWU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQ29udGludW91cy5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHV0aWxfMS5pc05pbCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJhbmdlTWluID0gdGhpcy5yYW5nZU1pbigpO1xuICAgICAgICB2YXIgcmFuZ2VNYXggPSB0aGlzLnJhbmdlTWF4KCk7XG4gICAgICAgIHZhciBtYXggPSB0aGlzLm1heDtcbiAgICAgICAgdmFyIG1pbiA9IHRoaXMubWluO1xuICAgICAgICBpZiAobWF4ID09PSBtaW4pIHtcbiAgICAgICAgICAgIHJldHVybiByYW5nZU1pbjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGVyY2VudCA9IHRoaXMuZ2V0U2NhbGVQZXJjZW50KHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHJhbmdlTWluICsgcGVyY2VudCAqIChyYW5nZU1heCAtIHJhbmdlTWluKTtcbiAgICB9O1xuICAgIENvbnRpbnVvdXMucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdC5jYWxsKHRoaXMpO1xuICAgICAgICAvLyBpbml0IOWujOaIkOWQjuS/neivgSBtaW4sIG1heCDljIXlkKsgdGlja3Mg55qE6IyD5Zu0XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgICAgIHZhciBmaXJzdFRpY2sgPSB1dGlsXzEuaGVhZCh0aWNrcyk7XG4gICAgICAgIHZhciBsYXN0VGljayA9IHV0aWxfMS5sYXN0KHRpY2tzKTtcbiAgICAgICAgaWYgKGZpcnN0VGljayA8IHRoaXMubWluKSB7XG4gICAgICAgICAgICB0aGlzLm1pbiA9IGZpcnN0VGljaztcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFzdFRpY2sgPiB0aGlzLm1heCkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSBsYXN0VGljaztcbiAgICAgICAgfVxuICAgICAgICAvLyBzdHJpY3QtbGltaXQg5pa55byPXG4gICAgICAgIGlmICghdXRpbF8xLmlzTmlsKHRoaXMubWluTGltaXQpKSB7XG4gICAgICAgICAgICB0aGlzLm1pbiA9IGZpcnN0VGljaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXV0aWxfMS5pc05pbCh0aGlzLm1heExpbWl0KSkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSBsYXN0VGljaztcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGludW91cy5wcm90b3R5cGUuc2V0RG9tYWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX2EgPSB1dGlsXzEuZ2V0UmFuZ2UodGhpcy52YWx1ZXMpLCBtaW4gPSBfYS5taW4sIG1heCA9IF9hLm1heDtcbiAgICAgICAgaWYgKHV0aWxfMS5pc05pbCh0aGlzLm1pbikpIHtcbiAgICAgICAgICAgIHRoaXMubWluID0gbWluO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1dGlsXzEuaXNOaWwodGhpcy5tYXgpKSB7XG4gICAgICAgICAgICB0aGlzLm1heCA9IG1heDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5taW4gPiB0aGlzLm1heCkge1xuICAgICAgICAgICAgdGhpcy5taW4gPSBtaW47XG4gICAgICAgICAgICB0aGlzLm1heCA9IG1heDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGludW91cy5wcm90b3R5cGUuY2FsY3VsYXRlVGlja3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0aWNrcyA9IF9zdXBlci5wcm90b3R5cGUuY2FsY3VsYXRlVGlja3MuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKCF0aGlzLm5pY2UpIHtcbiAgICAgICAgICAgIHRpY2tzID0gdXRpbF8xLmZpbHRlcih0aWNrcywgZnVuY3Rpb24gKHRpY2spIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGljayA+PSBfdGhpcy5taW4gJiYgdGljayA8PSBfdGhpcy5tYXg7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfTtcbiAgICAvLyDorqHnrpfljp/lp4vlgLzlgLzljaDnmoTnmb7liIbmr5RcbiAgICBDb250aW51b3VzLnByb3RvdHlwZS5nZXRTY2FsZVBlcmNlbnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIG1heCA9IHRoaXMubWF4O1xuICAgICAgICB2YXIgbWluID0gdGhpcy5taW47XG4gICAgICAgIHJldHVybiAodmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gICAgfTtcbiAgICBDb250aW51b3VzLnByb3RvdHlwZS5nZXRJbnZlcnRQZXJjZW50ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiAodmFsdWUgLSB0aGlzLnJhbmdlTWluKCkpIC8gKHRoaXMucmFuZ2VNYXgoKSAtIHRoaXMucmFuZ2VNaW4oKSk7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGludW91cztcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IENvbnRpbnVvdXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbi8qKlxuICog57q/5oCn5bqm6YePXG4gKiBAY2xhc3NcbiAqL1xudmFyIExpbmVhciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhMaW5lYXIsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTGluZWFyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdsaW5lYXInO1xuICAgICAgICBfdGhpcy5pc0xpbmVhciA9IHRydWU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgTGluZWFyLnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHBlcmNlbnQgPSB0aGlzLmdldEludmVydFBlcmNlbnQodmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5taW4gKyBwZXJjZW50ICogKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICAgIH07XG4gICAgTGluZWFyLnByb3RvdHlwZS5pbml0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnRpY2tNZXRob2QgPSAnd2lsa2luc29uLWV4dGVuZGVkJztcbiAgICAgICAgdGhpcy5uaWNlID0gZmFsc2U7XG4gICAgfTtcbiAgICByZXR1cm4gTGluZWFyO1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gTGluZWFyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGluZWFyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgbWF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0aFwiKTtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuLyoqXG4gKiBMb2cg5bqm6YeP77yM5aSE55CG6Z2e5Z2H5YyA5YiG5biDXG4gKi9cbnZhciBMb2cgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgdHNsaWJfMS5fX2V4dGVuZHMoTG9nLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIExvZygpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAnbG9nJztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKi9cbiAgICBMb2cucHJvdG90eXBlLmludmVydCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgYmFzZSA9IHRoaXMuYmFzZTtcbiAgICAgICAgdmFyIG1heCA9IG1hdGhfMS5sb2coYmFzZSwgdGhpcy5tYXgpO1xuICAgICAgICB2YXIgcmFuZ2VNaW4gPSB0aGlzLnJhbmdlTWluKCk7XG4gICAgICAgIHZhciByYW5nZSA9IHRoaXMucmFuZ2VNYXgoKSAtIHJhbmdlTWluO1xuICAgICAgICB2YXIgbWluO1xuICAgICAgICB2YXIgcG9zaXRpdmVNaW4gPSB0aGlzLnBvc2l0aXZlTWluO1xuICAgICAgICBpZiAocG9zaXRpdmVNaW4pIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWluID0gbWF0aF8xLmxvZyhiYXNlLCBwb3NpdGl2ZU1pbiAvIGJhc2UpO1xuICAgICAgICAgICAgdmFyIGFwcGVuZFBlcmNlbnQgPSAoMSAvIChtYXggLSBtaW4pKSAqIHJhbmdlOyAvLyAwIOWIsCBwb3NpdGl2ZU1pbueahOWNoOavlFxuICAgICAgICAgICAgaWYgKHZhbHVlIDwgYXBwZW5kUGVyY2VudCkge1xuICAgICAgICAgICAgICAgIC8vIOiQveWIsCAwIC0gcG9zaXRpdmVNaW4g5LmL6Ze0XG4gICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSAvIGFwcGVuZFBlcmNlbnQpICogcG9zaXRpdmVNaW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtaW4gPSBtYXRoXzEubG9nKGJhc2UsIHRoaXMubWluKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGVyY2VudCA9ICh2YWx1ZSAtIHJhbmdlTWluKSAvIHJhbmdlO1xuICAgICAgICB2YXIgdG1wID0gcGVyY2VudCAqIChtYXggLSBtaW4pICsgbWluO1xuICAgICAgICByZXR1cm4gTWF0aC5wb3coYmFzZSwgdG1wKTtcbiAgICB9O1xuICAgIExvZy5wcm90b3R5cGUuaW5pdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy50aWNrTWV0aG9kID0gJ2xvZyc7XG4gICAgICAgIHRoaXMuYmFzZSA9IDEwO1xuICAgICAgICB0aGlzLnRpY2tDb3VudCA9IDY7XG4gICAgICAgIHRoaXMubmljZSA9IHRydWU7XG4gICAgfTtcbiAgICAvLyDorr7nva5cbiAgICBMb2cucHJvdG90eXBlLnNldERvbWFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5zZXREb21haW4uY2FsbCh0aGlzKTtcbiAgICAgICAgdmFyIG1pbiA9IHRoaXMubWluO1xuICAgICAgICBpZiAobWluIDwgMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXaGVuIHlvdSB1c2UgbG9nIHNjYWxlLCB0aGUgbWluaW11bSB2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvIScpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaW4gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMucG9zaXRpdmVNaW4gPSBtYXRoXzEuZ2V0TG9nUG9zaXRpdmVNaW4odGhpcy52YWx1ZXMsIHRoaXMuYmFzZSwgdGhpcy5tYXgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyDmoLnmja7lvZPliY3lgLzojrflj5bljaDmr5RcbiAgICBMb2cucHJvdG90eXBlLmdldFNjYWxlUGVyY2VudCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbWF4ID0gdGhpcy5tYXg7XG4gICAgICAgIHZhciBtaW4gPSB0aGlzLm1pbjtcbiAgICAgICAgaWYgKG1heCA9PT0gbWluKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICAvLyDlpoLmnpzlgLzlsI/kuo7nrYnkuo4w77yM5YiZ5oyJ54WnMOWkhOeQhlxuICAgICAgICBpZiAodmFsdWUgPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJhc2UgPSB0aGlzLmJhc2U7XG4gICAgICAgIHZhciBwb3NpdGl2ZU1pbiA9IHRoaXMucG9zaXRpdmVNaW47XG4gICAgICAgIC8vIOWmguaenG1pbiA9PSAwLCDliJnmoLnmja7mr5Qw5aSn55qE5pyA5bCP5YC877yM6K6h566X5q+U5L6L5YWz57O744CC6L+Z5Liq5pyA5bCP5YC85L2c5Li65Z2Q5qCH6L205LiK55qE56ys5LqM5LiqdGlja++8jOesrOS4gOS4quaYrzDkvYbmmK/kuI3mmL7npLpcbiAgICAgICAgaWYgKHBvc2l0aXZlTWluKSB7XG4gICAgICAgICAgICBtaW4gPSAocG9zaXRpdmVNaW4gKiAxKSAvIGJhc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHBlcmNlbnQ7XG4gICAgICAgIC8vIOWmguaenOaVsOWAvOWwj+S6juasoeWwj+WAvO+8jOmCo+S5iOWwseiuoeeulyB2YWx1ZSAvIOasoeWwj+WAvCDljaDmlbTkvZPnmoTmr5TkvotcbiAgICAgICAgaWYgKHZhbHVlIDwgcG9zaXRpdmVNaW4pIHtcbiAgICAgICAgICAgIHBlcmNlbnQgPSB2YWx1ZSAvIHBvc2l0aXZlTWluIC8gKG1hdGhfMS5sb2coYmFzZSwgbWF4KSAtIG1hdGhfMS5sb2coYmFzZSwgbWluKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBwZXJjZW50ID0gKG1hdGhfMS5sb2coYmFzZSwgdmFsdWUpIC0gbWF0aF8xLmxvZyhiYXNlLCBtaW4pKSAvIChtYXRoXzEubG9nKGJhc2UsIG1heCkgLSBtYXRoXzEubG9nKGJhc2UsIG1pbikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwZXJjZW50O1xuICAgIH07XG4gICAgcmV0dXJuIExvZztcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IExvZztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxvZy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0c2xpYl8xID0gcmVxdWlyZShcInRzbGliXCIpO1xudmFyIG1hdGhfMSA9IHJlcXVpcmUoXCIuLi91dGlsL21hdGhcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbi8qKlxuICogUG93IOW6pumHj++8jOWkhOeQhumdnuWdh+WMgOWIhuW4g1xuICovXG52YXIgUG93ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFBvdywgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBQb3coKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3Bvdyc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQG92ZXJyaWRlXG4gICAgICovXG4gICAgUG93LnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHBlcmNlbnQgPSB0aGlzLmdldEludmVydFBlcmNlbnQodmFsdWUpO1xuICAgICAgICB2YXIgZXhwb25lbnQgPSB0aGlzLmV4cG9uZW50O1xuICAgICAgICB2YXIgbWF4ID0gbWF0aF8xLmNhbEJhc2UoZXhwb25lbnQsIHRoaXMubWF4KTtcbiAgICAgICAgdmFyIG1pbiA9IG1hdGhfMS5jYWxCYXNlKGV4cG9uZW50LCB0aGlzLm1pbik7XG4gICAgICAgIHZhciB0bXAgPSBwZXJjZW50ICogKG1heCAtIG1pbikgKyBtaW47XG4gICAgICAgIHZhciBmYWN0b3IgPSB0bXAgPj0gMCA/IDEgOiAtMTtcbiAgICAgICAgcmV0dXJuIE1hdGgucG93KHRtcCwgZXhwb25lbnQpICogZmFjdG9yO1xuICAgIH07XG4gICAgUG93LnByb3RvdHlwZS5pbml0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnRpY2tNZXRob2QgPSAncG93JztcbiAgICAgICAgdGhpcy5leHBvbmVudCA9IDI7XG4gICAgICAgIHRoaXMudGlja0NvdW50ID0gNTtcbiAgICAgICAgdGhpcy5uaWNlID0gdHJ1ZTtcbiAgICB9O1xuICAgIC8vIOiOt+WPluW6pumHj+iuoeeul+aXtu+8jHZhbHVl5Y2g55qE5a6a5LmJ5Z+f55m+5YiG5q+UXG4gICAgUG93LnByb3RvdHlwZS5nZXRTY2FsZVBlcmNlbnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIG1heCA9IHRoaXMubWF4O1xuICAgICAgICB2YXIgbWluID0gdGhpcy5taW47XG4gICAgICAgIGlmIChtYXggPT09IG1pbikge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGV4cG9uZW50ID0gdGhpcy5leHBvbmVudDtcbiAgICAgICAgdmFyIHBlcmNlbnQgPSAobWF0aF8xLmNhbEJhc2UoZXhwb25lbnQsIHZhbHVlKSAtIG1hdGhfMS5jYWxCYXNlKGV4cG9uZW50LCBtaW4pKSAvIChtYXRoXzEuY2FsQmFzZShleHBvbmVudCwgbWF4KSAtIG1hdGhfMS5jYWxCYXNlKGV4cG9uZW50LCBtaW4pKTtcbiAgICAgICAgcmV0dXJuIHBlcmNlbnQ7XG4gICAgfTtcbiAgICByZXR1cm4gUG93O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gUG93O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cG93LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgcXVhbnRpemVfMSA9IHJlcXVpcmUoXCIuL3F1YW50aXplXCIpO1xudmFyIFF1YW50aWxlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKFF1YW50aWxlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFF1YW50aWxlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdxdWFudGlsZSc7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUXVhbnRpbGUucHJvdG90eXBlLmluaXRDZmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMudGlja01ldGhvZCA9ICdxdWFudGlsZSc7XG4gICAgICAgIHRoaXMudGlja0NvdW50ID0gNTtcbiAgICAgICAgdGhpcy5uaWNlID0gdHJ1ZTtcbiAgICB9O1xuICAgIHJldHVybiBRdWFudGlsZTtcbn0ocXVhbnRpemVfMS5kZWZhdWx0KSk7XG5leHBvcnRzLmRlZmF1bHQgPSBRdWFudGlsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXF1YW50aWxlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4vYmFzZVwiKTtcbi8qKlxuICog5YiG5q615bqm6YePXG4gKi9cbnZhciBRdWFudGl6ZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhRdWFudGl6ZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBRdWFudGl6ZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGUgPSAncXVhbnRpemUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFF1YW50aXplLnByb3RvdHlwZS5pbnZlcnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHRpY2tzID0gdGhpcy50aWNrcztcbiAgICAgICAgdmFyIGxlbmd0aCA9IHRpY2tzLmxlbmd0aDtcbiAgICAgICAgdmFyIHBlcmNlbnQgPSB0aGlzLmdldEludmVydFBlcmNlbnQodmFsdWUpO1xuICAgICAgICB2YXIgbWluSW5kZXggPSBNYXRoLmZsb29yKHBlcmNlbnQgKiAobGVuZ3RoIC0gMSkpO1xuICAgICAgICAvLyDmnIDlkI7kuIDkuKpcbiAgICAgICAgaWYgKG1pbkluZGV4ID49IGxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlsXzEubGFzdCh0aWNrcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g6LaF5Ye65bem6L6555WM77yMIOWImeWPluesrOS4gOS4qlxuICAgICAgICBpZiAobWluSW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbF8xLmhlYWQodGlja3MpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtaW5UaWNrID0gdGlja3NbbWluSW5kZXhdO1xuICAgICAgICB2YXIgbmV4dFRpY2sgPSB0aWNrc1ttaW5JbmRleCArIDFdO1xuICAgICAgICAvLyDmr5TlvZPliY3lgLzlsI/nmoQgdGljayDlnKjluqbph4/kuIrnmoTljaDmr5RcbiAgICAgICAgdmFyIG1pbkluZGV4UGVyY2VudCA9IG1pbkluZGV4IC8gKGxlbmd0aCAtIDEpO1xuICAgICAgICB2YXIgbWF4SW5kZXhQZXJjZW50ID0gKG1pbkluZGV4ICsgMSkgLyAobGVuZ3RoIC0gMSk7XG4gICAgICAgIHJldHVybiBtaW5UaWNrICsgKHBlcmNlbnQgLSBtaW5JbmRleFBlcmNlbnQpIC8gKG1heEluZGV4UGVyY2VudCAtIG1pbkluZGV4UGVyY2VudCkgKiAobmV4dFRpY2sgLSBtaW5UaWNrKTtcbiAgICB9O1xuICAgIFF1YW50aXplLnByb3RvdHlwZS5pbml0Q2ZnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnRpY2tNZXRob2QgPSAnci1wcmV0dHknO1xuICAgICAgICB0aGlzLnRpY2tDb3VudCA9IDU7XG4gICAgICAgIHRoaXMubmljZSA9IHRydWU7XG4gICAgfTtcbiAgICBRdWFudGl6ZS5wcm90b3R5cGUuY2FsY3VsYXRlVGlja3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aWNrcyA9IF9zdXBlci5wcm90b3R5cGUuY2FsY3VsYXRlVGlja3MuY2FsbCh0aGlzKTtcbiAgICAgICAgaWYgKCF0aGlzLm5pY2UpIHsgLy8g5aaC5p6cIG5pY2UgPSBmYWxzZSAs6KGl5YWFIG1pbiwgbWF4XG4gICAgICAgICAgICBpZiAodXRpbF8xLmxhc3QodGlja3MpICE9PSB0aGlzLm1heCkge1xuICAgICAgICAgICAgICAgIHRpY2tzLnB1c2godGhpcy5tYXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHV0aWxfMS5oZWFkKHRpY2tzKSAhPT0gdGhpcy5taW4pIHtcbiAgICAgICAgICAgICAgICB0aWNrcy51bnNoaWZ0KHRoaXMubWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfTtcbiAgICAvLyDorqHnrpflvZPliY3lgLzlnKjliLvluqbkuK3nmoTljaDmr5RcbiAgICBRdWFudGl6ZS5wcm90b3R5cGUuZ2V0U2NhbGVQZXJjZW50ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgICAgIC8vIOi2heWHuuW3pui+ueeVjFxuICAgICAgICBpZiAodmFsdWUgPCB1dGlsXzEuaGVhZCh0aWNrcykpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIOi2heWHuuWPs+i+ueeVjFxuICAgICAgICBpZiAodmFsdWUgPiB1dGlsXzEubGFzdCh0aWNrcykpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtaW5JbmRleCA9IDA7XG4gICAgICAgIHV0aWxfMS5lYWNoKHRpY2tzLCBmdW5jdGlvbiAodGljaywgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+PSB0aWNrKSB7XG4gICAgICAgICAgICAgICAgbWluSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtaW5JbmRleCAvICh0aWNrcy5sZW5ndGggLSAxKTtcbiAgICB9O1xuICAgIHJldHVybiBRdWFudGl6ZTtcbn0oYmFzZV8xLmRlZmF1bHQpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IFF1YW50aXplO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cXVhbnRpemUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdHNsaWJfMSA9IHJlcXVpcmUoXCJ0c2xpYlwiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciB0aW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aW1lXCIpO1xudmFyIGxpbmVhcl8xID0gcmVxdWlyZShcIi4vbGluZWFyXCIpO1xuLyoqXG4gKiDml7bpl7Tluqbph49cbiAqIEBjbGFzc1xuICovXG52YXIgVGltZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICB0c2xpYl8xLl9fZXh0ZW5kcyhUaW1lLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRpbWUoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlID0gJ3RpbWUnO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIFRpbWUucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG4gICAgICAgIHZhciBudW1iZXJWYWx1ZSA9IHRoaXMudHJhbnNsYXRlKHZhbHVlKTtcbiAgICAgICAgdmFyIGZvcm1hdHRlciA9IHRoaXMuZm9ybWF0dGVyO1xuICAgICAgICByZXR1cm4gZm9ybWF0dGVyID8gZm9ybWF0dGVyKG51bWJlclZhbHVlLCBpbmRleCkgOiB0aW1lXzEudGltZUZvcm1hdChudW1iZXJWYWx1ZSwgdGhpcy5tYXNrKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIFRpbWUucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciB2ID0gdmFsdWU7XG4gICAgICAgIGlmICh1dGlsXzEuaXNTdHJpbmcodikgfHwgdXRpbF8xLmlzRGF0ZSh2KSkge1xuICAgICAgICAgICAgdiA9IHRoaXMudHJhbnNsYXRlKHYpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLnNjYWxlLmNhbGwodGhpcywgdik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiDlsIbml7bpl7TovazmjaLmiJDmlbDlrZdcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKi9cbiAgICBUaW1lLnByb3RvdHlwZS50cmFuc2xhdGUgPSBmdW5jdGlvbiAodikge1xuICAgICAgICByZXR1cm4gdGltZV8xLnRvVGltZVN0YW1wKHYpO1xuICAgIH07XG4gICAgVGltZS5wcm90b3R5cGUuaW5pdENmZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy50aWNrTWV0aG9kID0gJ3RpbWUtcHJldHR5JztcbiAgICAgICAgdGhpcy5tYXNrID0gJ1lZWVktTU0tREQnO1xuICAgICAgICB0aGlzLnRpY2tDb3VudCA9IDc7XG4gICAgICAgIHRoaXMubmljZSA9IGZhbHNlO1xuICAgIH07XG4gICAgVGltZS5wcm90b3R5cGUuc2V0RG9tYWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsdWVzID0gdGhpcy52YWx1ZXM7XG4gICAgICAgIC8vIOaYr+WQpuiuvue9ruS6hiBtaW4sIG1heO+8jOiAjOS4jeaYr+ebtOaOpeWPliB0aGlzLm1pbiwgdGhpcy5tYXhcbiAgICAgICAgdmFyIG1pbkNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCdtaW4nKTtcbiAgICAgICAgdmFyIG1heENvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCdtYXgnKTtcbiAgICAgICAgLy8g5aaC5p6c6K6+572u5LqGIG1pbixtYXgg5YiZ6L2s5o2i5oiQ5pe26Ze05oizXG4gICAgICAgIGlmICghdXRpbF8xLmlzTmlsKG1pbkNvbmZpZykgfHwgIXV0aWxfMS5pc051bWJlcihtaW5Db25maWcpKSB7XG4gICAgICAgICAgICB0aGlzLm1pbiA9IHRoaXMudHJhbnNsYXRlKHRoaXMubWluKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXV0aWxfMS5pc05pbChtYXhDb25maWcpIHx8ICF1dGlsXzEuaXNOdW1iZXIobWF4Q29uZmlnKSkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSB0aGlzLnRyYW5zbGF0ZSh0aGlzLm1heCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5rKh5pyJ6K6+572uIG1pbiwgbWF4IOaXtlxuICAgICAgICBpZiAodmFsdWVzICYmIHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIOmHjeaWsOiuoeeul+acgOWkp+acgOWwj+WAvFxuICAgICAgICAgICAgdmFyIHRpbWVTdGFtcHNfMSA9IFtdO1xuICAgICAgICAgICAgdmFyIG1pbl8xID0gSW5maW5pdHk7IC8vIOacgOWwj+WAvFxuICAgICAgICAgICAgdmFyIHNlY29uZE1pbl8xID0gbWluXzE7IC8vIOasoeWwj+WAvFxuICAgICAgICAgICAgdmFyIG1heF8xID0gMDtcbiAgICAgICAgICAgIC8vIOS9v+eUqOS4gOS4quW+queOr++8jOiuoeeul21pbixtYXgsc2Vjb25kTWluXG4gICAgICAgICAgICB1dGlsXzEuZWFjaCh2YWx1ZXMsIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgdmFyIHRpbWVTdGFtcCA9IHRpbWVfMS50b1RpbWVTdGFtcCh2KTtcbiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odGltZVN0YW1wKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBUaW1lOiBcIiArIHYgKyBcIiBpbiB0aW1lIHNjYWxlIVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1pbl8xID4gdGltZVN0YW1wKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlY29uZE1pbl8xID0gbWluXzE7XG4gICAgICAgICAgICAgICAgICAgIG1pbl8xID0gdGltZVN0YW1wO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzZWNvbmRNaW5fMSA+IHRpbWVTdGFtcCkge1xuICAgICAgICAgICAgICAgICAgICBzZWNvbmRNaW5fMSA9IHRpbWVTdGFtcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1heF8xIDwgdGltZVN0YW1wKSB7XG4gICAgICAgICAgICAgICAgICAgIG1heF8xID0gdGltZVN0YW1wO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aW1lU3RhbXBzXzEucHVzaCh0aW1lU3RhbXApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyDlrZjlnKjlpJrkuKrlgLzml7bvvIzorr7nva7mnIDlsI/pl7Tot51cbiAgICAgICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWluVGlja0ludGVydmFsID0gc2Vjb25kTWluXzEgLSBtaW5fMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1dGlsXzEuaXNOaWwobWluQ29uZmlnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWluID0gbWluXzE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXRpbF8xLmlzTmlsKG1heENvbmZpZykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1heCA9IG1heF8xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gVGltZTtcbn0obGluZWFyXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gVGltZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRpbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyU2NhbGUgPSBleHBvcnRzLmdldFNjYWxlID0gZXhwb3J0cy5TY2FsZSA9IHZvaWQgMDtcbnZhciBiYXNlXzEgPSByZXF1aXJlKFwiLi9iYXNlXCIpO1xuZXhwb3J0cy5TY2FsZSA9IGJhc2VfMS5kZWZhdWx0O1xudmFyIG1hcCA9IHt9O1xuZnVuY3Rpb24gZ2V0Q2xhc3Moa2V5KSB7XG4gICAgcmV0dXJuIG1hcFtrZXldO1xufVxuZXhwb3J0cy5nZXRTY2FsZSA9IGdldENsYXNzO1xuZnVuY3Rpb24gcmVnaXN0ZXJDbGFzcyhrZXksIGNscykge1xuICAgIGlmIChnZXRDbGFzcyhrZXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInR5cGUgJ1wiICsga2V5ICsgXCInIGV4aXN0ZWQuXCIpO1xuICAgIH1cbiAgICBtYXBba2V5XSA9IGNscztcbn1cbmV4cG9ydHMucmVnaXN0ZXJTY2FsZSA9IHJlZ2lzdGVyQ2xhc3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mYWN0b3J5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRzbGliXzEgPSByZXF1aXJlKFwidHNsaWJcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgYmFzZV8xID0gcmVxdWlyZShcIi4uL2Jhc2VcIik7XG4vKipcbiAqIGlkZW50aXR5IHNjYWxl5Y6f5YiZ5LiK5piv5a6a5LmJ5Z+f5ZKM5YC85Z+f5LiA6Ie077yMc2NhbGUvaW52ZXJ05pa55rOV5Lmf5piv5LiA6Ie055qEXG4gKiDlj4LogINS55qE5a6e546w77yaaHR0cHM6Ly9naXRodWIuY29tL3ItbGliL3NjYWxlcy9ibG9iL21hc3Rlci9SL3BhbC1pZGVudGl0eS5yXG4gKiDlj4LogINkM+eahOWunueOsO+8iOWBmuS6huS4i+i9rOWei++8ie+8mmh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1zY2FsZS9ibG9iL21hc3Rlci9zcmMvaWRlbnRpdHkuanNcbiAqL1xudmFyIElkZW50aXR5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIHRzbGliXzEuX19leHRlbmRzKElkZW50aXR5LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIElkZW50aXR5KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHlwZSA9ICdpZGVudGl0eSc7XG4gICAgICAgIF90aGlzLmlzSWRlbnRpdHkgPSB0cnVlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIElkZW50aXR5LnByb3RvdHlwZS5jYWxjdWxhdGVUaWNrcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVzO1xuICAgIH07XG4gICAgSWRlbnRpdHkucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIOWmguaenOS8oOWFpeeahOWAvOS4jeetieS6jiBpZGVudGl0eSDnmoTlgLzvvIzliJnnm7TmjqXov5Tlm57vvIznlKjkuo7kuIDnu7Tlm77ml7bnmoQgZG9kZ2VcbiAgICAgICAgaWYgKHRoaXMudmFsdWVzWzBdICE9PSB2YWx1ZSAmJiB1dGlsXzEuaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucmFuZ2VbMF07XG4gICAgfTtcbiAgICBJZGVudGl0eS5wcm90b3R5cGUuaW52ZXJ0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciByYW5nZSA9IHRoaXMucmFuZ2U7XG4gICAgICAgIGlmICh2YWx1ZSA8IHJhbmdlWzBdIHx8IHZhbHVlID4gcmFuZ2VbMV0pIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVzWzBdO1xuICAgIH07XG4gICAgcmV0dXJuIElkZW50aXR5O1xufShiYXNlXzEuZGVmYXVsdCkpO1xuZXhwb3J0cy5kZWZhdWx0ID0gSWRlbnRpdHk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucmVnaXN0ZXJUaWNrTWV0aG9kID0gZXhwb3J0cy5nZXRUaWNrTWV0aG9kID0gZXhwb3J0cy5yZWdpc3RlclNjYWxlID0gZXhwb3J0cy5nZXRTY2FsZSA9IGV4cG9ydHMuU2NhbGUgPSBleHBvcnRzLlF1YW50aXplID0gZXhwb3J0cy5RdWFudGlsZSA9IGV4cG9ydHMuVGltZUNhdCA9IGV4cG9ydHMuVGltZSA9IGV4cG9ydHMuUG93ID0gZXhwb3J0cy5Mb2cgPSBleHBvcnRzLkxpbmVhciA9IGV4cG9ydHMuSWRlbnRpdHkgPSBleHBvcnRzLkNhdGVnb3J5ID0gdm9pZCAwO1xudmFyIGJhc2VfMSA9IHJlcXVpcmUoXCIuL2Jhc2VcIik7XG5leHBvcnRzLlNjYWxlID0gYmFzZV8xLmRlZmF1bHQ7XG52YXIgYmFzZV8yID0gcmVxdWlyZShcIi4vY2F0ZWdvcnkvYmFzZVwiKTtcbmV4cG9ydHMuQ2F0ZWdvcnkgPSBiYXNlXzIuZGVmYXVsdDtcbnZhciB0aW1lXzEgPSByZXF1aXJlKFwiLi9jYXRlZ29yeS90aW1lXCIpO1xuZXhwb3J0cy5UaW1lQ2F0ID0gdGltZV8xLmRlZmF1bHQ7XG52YXIgbGluZWFyXzEgPSByZXF1aXJlKFwiLi9jb250aW51b3VzL2xpbmVhclwiKTtcbmV4cG9ydHMuTGluZWFyID0gbGluZWFyXzEuZGVmYXVsdDtcbnZhciBsb2dfMSA9IHJlcXVpcmUoXCIuL2NvbnRpbnVvdXMvbG9nXCIpO1xuZXhwb3J0cy5Mb2cgPSBsb2dfMS5kZWZhdWx0O1xudmFyIHBvd18xID0gcmVxdWlyZShcIi4vY29udGludW91cy9wb3dcIik7XG5leHBvcnRzLlBvdyA9IHBvd18xLmRlZmF1bHQ7XG52YXIgdGltZV8yID0gcmVxdWlyZShcIi4vY29udGludW91cy90aW1lXCIpO1xuZXhwb3J0cy5UaW1lID0gdGltZV8yLmRlZmF1bHQ7XG52YXIgcXVhbnRpemVfMSA9IHJlcXVpcmUoXCIuL2NvbnRpbnVvdXMvcXVhbnRpemVcIik7XG5leHBvcnRzLlF1YW50aXplID0gcXVhbnRpemVfMS5kZWZhdWx0O1xudmFyIHF1YW50aWxlXzEgPSByZXF1aXJlKFwiLi9jb250aW51b3VzL3F1YW50aWxlXCIpO1xuZXhwb3J0cy5RdWFudGlsZSA9IHF1YW50aWxlXzEuZGVmYXVsdDtcbnZhciBmYWN0b3J5XzEgPSByZXF1aXJlKFwiLi9mYWN0b3J5XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0U2NhbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY3RvcnlfMS5nZXRTY2FsZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyU2NhbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY3RvcnlfMS5yZWdpc3RlclNjYWxlOyB9IH0pO1xudmFyIGluZGV4XzEgPSByZXF1aXJlKFwiLi9pZGVudGl0eS9pbmRleFwiKTtcbmV4cG9ydHMuSWRlbnRpdHkgPSBpbmRleF8xLmRlZmF1bHQ7XG52YXIgaW5kZXhfMiA9IHJlcXVpcmUoXCIuL3RpY2stbWV0aG9kL2luZGV4XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0VGlja01ldGhvZFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaW5kZXhfMi5nZXRUaWNrTWV0aG9kOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVnaXN0ZXJUaWNrTWV0aG9kXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbmRleF8yLnJlZ2lzdGVyVGlja01ldGhvZDsgfSB9KTtcbmZhY3RvcnlfMS5yZWdpc3RlclNjYWxlKCdjYXQnLCBiYXNlXzIuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJTY2FsZSgnY2F0ZWdvcnknLCBiYXNlXzIuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJTY2FsZSgnaWRlbnRpdHknLCBpbmRleF8xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyU2NhbGUoJ2xpbmVhcicsIGxpbmVhcl8xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyU2NhbGUoJ2xvZycsIGxvZ18xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyU2NhbGUoJ3BvdycsIHBvd18xLmRlZmF1bHQpO1xuZmFjdG9yeV8xLnJlZ2lzdGVyU2NhbGUoJ3RpbWUnLCB0aW1lXzIuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJTY2FsZSgndGltZUNhdCcsIHRpbWVfMS5kZWZhdWx0KTtcbmZhY3RvcnlfMS5yZWdpc3RlclNjYWxlKCdxdWFudGl6ZScsIHF1YW50aXplXzEuZGVmYXVsdCk7XG5mYWN0b3J5XzEucmVnaXN0ZXJTY2FsZSgncXVhbnRpbGUnLCBxdWFudGlsZV8xLmRlZmF1bHQpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZXh0ZW5kZWRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL2V4dGVuZGVkXCIpO1xuLyoqXG4gKiDorqHnrpfliIbnsbsgdGlja3NcbiAqIEBwYXJhbSBjZmcg5bqm6YeP55qE6YWN572u6aG5XG4gKiBAcmV0dXJucyDorqHnrpflkI7nmoQgdGlja3NcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlQ2F0VGlja3MoY2ZnKSB7XG4gICAgdmFyIHZhbHVlcyA9IGNmZy52YWx1ZXMsIHRpY2tJbnRlcnZhbCA9IGNmZy50aWNrSW50ZXJ2YWwsIHRpY2tDb3VudCA9IGNmZy50aWNrQ291bnQ7XG4gICAgdmFyIHRpY2tzID0gdmFsdWVzO1xuICAgIGlmICh1dGlsXzEuaXNOdW1iZXIodGlja0ludGVydmFsKSkge1xuICAgICAgICByZXR1cm4gdXRpbF8xLmZpbHRlcih0aWNrcywgZnVuY3Rpb24gKF9fLCBpKSB7IHJldHVybiBpICUgdGlja0ludGVydmFsID09PSAwOyB9KTtcbiAgICB9XG4gICAgdmFyIG1pbiA9IGNmZy5taW4sIG1heCA9IGNmZy5tYXg7XG4gICAgaWYgKHV0aWxfMS5pc05pbChtaW4pKSB7XG4gICAgICAgIG1pbiA9IDA7XG4gICAgfVxuICAgIGlmICh1dGlsXzEuaXNOaWwobWF4KSkge1xuICAgICAgICBtYXggPSB2YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICB9XG4gICAgaWYgKHV0aWxfMS5pc051bWJlcih0aWNrQ291bnQpICYmIHRpY2tDb3VudCA8IG1heCAtIG1pbikge1xuICAgICAgICAvLyDnroDljZXov4fmu6TvvIzpg6jliIbmg4XlhrXkuIvlsI/mlbDnmoTlgI3mlbDkuZ/lj6/ku6XmmK/mlbTmlbBcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1zaGFkb3dlZC12YXJpYWJsZVxuICAgICAgICB2YXIgdGlja3NfMSA9IGV4dGVuZGVkXzEuZGVmYXVsdChtaW4sIG1heCwgdGlja0NvdW50LCBmYWxzZSwgWzEsIDIsIDUsIDMsIDQsIDcsIDYsIDgsIDldKS50aWNrcztcbiAgICAgICAgdmFyIHZhbGlkID0gdXRpbF8xLmZpbHRlcih0aWNrc18xLCBmdW5jdGlvbiAodGljaykgeyByZXR1cm4gdGljayA+PSBtaW4gJiYgdGljayA8PSBtYXg7IH0pO1xuICAgICAgICByZXR1cm4gdmFsaWQubWFwKGZ1bmN0aW9uIChpbmRleCkgeyByZXR1cm4gdmFsdWVzW2luZGV4XTsgfSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZXMuc2xpY2UobWluLCBtYXggKyAxKTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGNhbGN1bGF0ZUNhdFRpY2tzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2F0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGQzX2xpbmVhcl8xID0gcmVxdWlyZShcIi4uL3V0aWwvZDMtbGluZWFyXCIpO1xudmFyIGludGVydmFsXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9pbnRlcnZhbFwiKTtcbnZhciBzdHJpY3RfbGltaXRfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3N0cmljdC1saW1pdFwiKTtcbmZ1bmN0aW9uIGQzTGluZWFyVGlja01ldGhvZChjZmcpIHtcbiAgICB2YXIgbWluID0gY2ZnLm1pbiwgbWF4ID0gY2ZnLm1heCwgdGlja0ludGVydmFsID0gY2ZnLnRpY2tJbnRlcnZhbCwgbWluTGltaXQgPSBjZmcubWluTGltaXQsIG1heExpbWl0ID0gY2ZnLm1heExpbWl0O1xuICAgIHZhciB0aWNrcyA9IGQzX2xpbmVhcl8xLmRlZmF1bHQoY2ZnKTtcbiAgICBpZiAoIXV0aWxfMS5pc05pbChtaW5MaW1pdCkgfHwgIXV0aWxfMS5pc05pbChtYXhMaW1pdCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmljdF9saW1pdF8xLmRlZmF1bHQoY2ZnLCB1dGlsXzEuaGVhZCh0aWNrcyksIHV0aWxfMS5sYXN0KHRpY2tzKSk7XG4gICAgfVxuICAgIGlmICh0aWNrSW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIGludGVydmFsXzEuZGVmYXVsdChtaW4sIG1heCwgdGlja0ludGVydmFsKS50aWNrcztcbiAgICB9XG4gICAgcmV0dXJuIHRpY2tzO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZDNMaW5lYXJUaWNrTWV0aG9kO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZDMtbGluZWFyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5yZWdpc3RlclRpY2tNZXRob2QgPSBleHBvcnRzLmdldFRpY2tNZXRob2QgPSB2b2lkIDA7XG52YXIgY2F0XzEgPSByZXF1aXJlKFwiLi9jYXRcIik7XG52YXIgZDNfbGluZWFyXzEgPSByZXF1aXJlKFwiLi9kMy1saW5lYXJcIik7XG52YXIgbGluZWFyXzEgPSByZXF1aXJlKFwiLi9saW5lYXJcIik7XG52YXIgbG9nXzEgPSByZXF1aXJlKFwiLi9sb2dcIik7XG52YXIgcG93XzEgPSByZXF1aXJlKFwiLi9wb3dcIik7XG52YXIgcXVhbnRpbGVfMSA9IHJlcXVpcmUoXCIuL3F1YW50aWxlXCIpO1xudmFyIHJfcHJldHRyeV8xID0gcmVxdWlyZShcIi4vci1wcmV0dHJ5XCIpO1xudmFyIHJlZ2lzdGVyXzEgPSByZXF1aXJlKFwiLi9yZWdpc3RlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFRpY2tNZXRob2RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJlZ2lzdGVyXzEuZ2V0VGlja01ldGhvZDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInJlZ2lzdGVyVGlja01ldGhvZFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2Q7IH0gfSk7XG52YXIgdGltZV8xID0gcmVxdWlyZShcIi4vdGltZVwiKTtcbnZhciB0aW1lX2NhdF8xID0gcmVxdWlyZShcIi4vdGltZS1jYXRcIik7XG52YXIgdGltZV9wcmV0dHlfMSA9IHJlcXVpcmUoXCIuL3RpbWUtcHJldHR5XCIpO1xucmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2QoJ2NhdCcsIGNhdF8xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2QoJ3RpbWUtY2F0JywgdGltZV9jYXRfMS5kZWZhdWx0KTtcbnJlZ2lzdGVyXzEucmVnaXN0ZXJUaWNrTWV0aG9kKCd3aWxraW5zb24tZXh0ZW5kZWQnLCBsaW5lYXJfMS5kZWZhdWx0KTtcbnJlZ2lzdGVyXzEucmVnaXN0ZXJUaWNrTWV0aG9kKCdyLXByZXR0eScsIHJfcHJldHRyeV8xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2QoJ3RpbWUnLCB0aW1lXzEuZGVmYXVsdCk7XG5yZWdpc3Rlcl8xLnJlZ2lzdGVyVGlja01ldGhvZCgndGltZS1wcmV0dHknLCB0aW1lX3ByZXR0eV8xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2QoJ2xvZycsIGxvZ18xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2QoJ3BvdycsIHBvd18xLmRlZmF1bHQpO1xucmVnaXN0ZXJfMS5yZWdpc3RlclRpY2tNZXRob2QoJ3F1YW50aWxlJywgcXVhbnRpbGVfMS5kZWZhdWx0KTtcbnJlZ2lzdGVyXzEucmVnaXN0ZXJUaWNrTWV0aG9kKCdkMy1saW5lYXInLCBkM19saW5lYXJfMS5kZWZhdWx0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGV4dGVuZGVkXzEgPSByZXF1aXJlKFwiLi4vdXRpbC9leHRlbmRlZFwiKTtcbnZhciBpbnRlcnZhbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvaW50ZXJ2YWxcIik7XG52YXIgc3RyaWN0X2xpbWl0XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9zdHJpY3QtbGltaXRcIik7XG4vKipcbiAqIOiuoeeul+e6v+aAp+eahCB0aWNrc++8jOS9v+eUqCB3aWxraW5zb24gZXh0ZW5kZWQg5pa55rOVXG4gKiBAcGFyYW0gY2ZnIOW6pumHj+eahOmFjee9rumhuVxuICogQHJldHVybnMg6K6h566X5ZCO55qEIHRpY2tzXG4gKi9cbmZ1bmN0aW9uIGxpbmVhcihjZmcpIHtcbiAgICB2YXIgbWluID0gY2ZnLm1pbiwgbWF4ID0gY2ZnLm1heCwgdGlja0NvdW50ID0gY2ZnLnRpY2tDb3VudCwgbmljZSA9IGNmZy5uaWNlLCB0aWNrSW50ZXJ2YWwgPSBjZmcudGlja0ludGVydmFsLCBtaW5MaW1pdCA9IGNmZy5taW5MaW1pdCwgbWF4TGltaXQgPSBjZmcubWF4TGltaXQ7XG4gICAgdmFyIHRpY2tzID0gZXh0ZW5kZWRfMS5kZWZhdWx0KG1pbiwgbWF4LCB0aWNrQ291bnQsIG5pY2UpLnRpY2tzO1xuICAgIGlmICghdXRpbF8xLmlzTmlsKG1pbkxpbWl0KSB8fCAhdXRpbF8xLmlzTmlsKG1heExpbWl0KSkge1xuICAgICAgICByZXR1cm4gc3RyaWN0X2xpbWl0XzEuZGVmYXVsdChjZmcsIHV0aWxfMS5oZWFkKHRpY2tzKSwgdXRpbF8xLmxhc3QodGlja3MpKTtcbiAgICB9XG4gICAgaWYgKHRpY2tJbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWxfMS5kZWZhdWx0KG1pbiwgbWF4LCB0aWNrSW50ZXJ2YWwpLnRpY2tzO1xuICAgIH1cbiAgICByZXR1cm4gdGlja3M7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBsaW5lYXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lYXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbWF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0aFwiKTtcbi8qKlxuICog6K6h566XIGxvZyDnmoQgdGlja3PvvIzogIPomZEgbWluID0gMCDnmoTlnLrmma9cbiAqIEBwYXJhbSBjZmcg5bqm6YeP55qE6YWN572u6aG5XG4gKiBAcmV0dXJucyDorqHnrpflkI7nmoQgdGlja3NcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlTG9nVGlja3MoY2ZnKSB7XG4gICAgdmFyIGJhc2UgPSBjZmcuYmFzZSwgdGlja0NvdW50ID0gY2ZnLnRpY2tDb3VudCwgbWluID0gY2ZnLm1pbiwgbWF4ID0gY2ZnLm1heCwgdmFsdWVzID0gY2ZnLnZhbHVlcztcbiAgICB2YXIgbWluVGljaztcbiAgICB2YXIgbWF4VGljayA9IG1hdGhfMS5sb2coYmFzZSwgbWF4KTtcbiAgICBpZiAobWluID4gMCkge1xuICAgICAgICBtaW5UaWNrID0gTWF0aC5mbG9vcihtYXRoXzEubG9nKGJhc2UsIG1pbikpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIHBvc2l0aXZlTWluID0gbWF0aF8xLmdldExvZ1Bvc2l0aXZlTWluKHZhbHVlcywgYmFzZSwgbWF4KTtcbiAgICAgICAgbWluVGljayA9IE1hdGguZmxvb3IobWF0aF8xLmxvZyhiYXNlLCBwb3NpdGl2ZU1pbikpO1xuICAgIH1cbiAgICB2YXIgY291bnQgPSBtYXhUaWNrIC0gbWluVGljaztcbiAgICB2YXIgYXZnID0gTWF0aC5jZWlsKGNvdW50IC8gdGlja0NvdW50KTtcbiAgICB2YXIgdGlja3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gbWluVGljazsgaSA8IG1heFRpY2sgKyBhdmc7IGkgPSBpICsgYXZnKSB7XG4gICAgICAgIHRpY2tzLnB1c2goTWF0aC5wb3coYmFzZSwgaSkpO1xuICAgIH1cbiAgICBpZiAobWluIDw9IDApIHtcbiAgICAgICAgLy8g5pyA5bCP5YC8IDw9IDAg5pe25pi+56S6IDBcbiAgICAgICAgdGlja3MudW5zaGlmdCgwKTtcbiAgICB9XG4gICAgcmV0dXJuIHRpY2tzO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gY2FsY3VsYXRlTG9nVGlja3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sb2cuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbWF0aF8xID0gcmVxdWlyZShcIi4uL3V0aWwvbWF0aFwiKTtcbnZhciBwcmV0dHlfMSA9IHJlcXVpcmUoXCIuLi91dGlsL3ByZXR0eVwiKTtcbi8qKlxuICog6K6h566XIFBvdyDnmoQgdGlja3NcbiAqIEBwYXJhbSBjZmcg5bqm6YeP55qE6YWN572u6aG5XG4gKiBAcmV0dXJucyDorqHnrpflkI7nmoQgdGlja3NcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlUG93VGlja3MoY2ZnKSB7XG4gICAgdmFyIGV4cG9uZW50ID0gY2ZnLmV4cG9uZW50LCB0aWNrQ291bnQgPSBjZmcudGlja0NvdW50O1xuICAgIHZhciBtYXggPSBNYXRoLmNlaWwobWF0aF8xLmNhbEJhc2UoZXhwb25lbnQsIGNmZy5tYXgpKTtcbiAgICB2YXIgbWluID0gTWF0aC5mbG9vcihtYXRoXzEuY2FsQmFzZShleHBvbmVudCwgY2ZnLm1pbikpO1xuICAgIHZhciB0aWNrcyA9IHByZXR0eV8xLmRlZmF1bHQobWluLCBtYXgsIHRpY2tDb3VudCkudGlja3M7XG4gICAgcmV0dXJuIHRpY2tzLm1hcChmdW5jdGlvbiAodGljaykge1xuICAgICAgICB2YXIgZmFjdG9yID0gdGljayA+PSAwID8gMSA6IC0xO1xuICAgICAgICByZXR1cm4gTWF0aC5wb3codGljaywgZXhwb25lbnQpICogZmFjdG9yO1xuICAgIH0pO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gY2FsY3VsYXRlUG93VGlja3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb3cuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vKipcbiAqIOiuoeeul+WHoOWIhuS9jSBodHRwczovL2dpdGh1Yi5jb20vc2ltcGxlLXN0YXRpc3RpY3Mvc2ltcGxlLXN0YXRpc3RpY3MvYmxvYi9tYXN0ZXIvc3JjL3F1YW50aWxlX3NvcnRlZC5qc1xuICogQHBhcmFtIHggIOaVsOe7hFxuICogQHBhcmFtIHAgIOeZvuWIhuavlFxuICovXG5mdW5jdGlvbiBxdWFudGlsZVNvcnRlZCh4LCBwKSB7XG4gICAgdmFyIGlkeCA9IHgubGVuZ3RoICogcDtcbiAgICAvKmlmICh4Lmxlbmd0aCA9PT0gMCkgeyAvLyDlvZPliY3lnLrmma/ov5nkupvmnaHku7bkuI3lj6/og73lkb3kuK1cbiAgICAgIHRocm93IG5ldyBFcnJvcigncXVhbnRpbGUgcmVxdWlyZXMgYXQgbGVhc3Qgb25lIHZhbHVlLicpO1xuICAgIH0gZWxzZSBpZiAocCA8IDAgfHwgcCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncXVhbnRpbGVzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxJyk7XG4gICAgfSBlbHNlICovXG4gICAgaWYgKHAgPT09IDEpIHtcbiAgICAgICAgLy8gSWYgcCBpcyAxLCBkaXJlY3RseSByZXR1cm4gdGhlIGxhc3QgZWxlbWVudFxuICAgICAgICByZXR1cm4geFt4Lmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgICBlbHNlIGlmIChwID09PSAwKSB7XG4gICAgICAgIC8vIElmIHAgaXMgMCwgZGlyZWN0bHkgcmV0dXJuIHRoZSBmaXJzdCBlbGVtZW50XG4gICAgICAgIHJldHVybiB4WzBdO1xuICAgIH1cbiAgICBlbHNlIGlmIChpZHggJSAxICE9PSAwKSB7XG4gICAgICAgIC8vIElmIHAgaXMgbm90IGludGVnZXIsIHJldHVybiB0aGUgbmV4dCBlbGVtZW50IGluIGFycmF5XG4gICAgICAgIHJldHVybiB4W01hdGguY2VpbChpZHgpIC0gMV07XG4gICAgfVxuICAgIGVsc2UgaWYgKHgubGVuZ3RoICUgMiA9PT0gMCkge1xuICAgICAgICAvLyBJZiB0aGUgbGlzdCBoYXMgZXZlbi1sZW5ndGgsIHdlJ2xsIHRha2UgdGhlIGF2ZXJhZ2Ugb2YgdGhpcyBudW1iZXJcbiAgICAgICAgLy8gYW5kIHRoZSBuZXh0IHZhbHVlLCBpZiB0aGVyZSBpcyBvbmVcbiAgICAgICAgcmV0dXJuICh4W2lkeCAtIDFdICsgeFtpZHhdKSAvIDI7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBGaW5hbGx5LCBpbiB0aGUgc2ltcGxlIGNhc2Ugb2YgYW4gaW50ZWdlciB2YWx1ZVxuICAgICAgICAvLyB3aXRoIGFuIG9kZC1sZW5ndGggbGlzdCwgcmV0dXJuIHRoZSB4IHZhbHVlIGF0IHRoZSBpbmRleC5cbiAgICAgICAgcmV0dXJuIHhbaWR4XTtcbiAgICB9XG59XG5mdW5jdGlvbiBjYWxjdWxhdGVUaWNrcyhjZmcpIHtcbiAgICB2YXIgdGlja0NvdW50ID0gY2ZnLnRpY2tDb3VudCwgdmFsdWVzID0gY2ZnLnZhbHVlcztcbiAgICBpZiAoIXZhbHVlcyB8fCAhdmFsdWVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHZhciBzb3J0ZWQgPSB2YWx1ZXMuc2xpY2UoKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBhIC0gYjtcbiAgICB9KTtcbiAgICB2YXIgdGlja3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRpY2tDb3VudDsgaSsrKSB7XG4gICAgICAgIHZhciBwID0gaSAvICh0aWNrQ291bnQgLSAxKTtcbiAgICAgICAgdGlja3MucHVzaChxdWFudGlsZVNvcnRlZChzb3J0ZWQsIHApKTtcbiAgICB9XG4gICAgcmV0dXJuIHRpY2tzO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gY2FsY3VsYXRlVGlja3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1xdWFudGlsZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiQGFudHYvdXRpbFwiKTtcbnZhciBpbnRlcnZhbF8xID0gcmVxdWlyZShcIi4uL3V0aWwvaW50ZXJ2YWxcIik7XG52YXIgcHJldHR5XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9wcmV0dHlcIik7XG52YXIgc3RyaWN0X2xpbWl0XzEgPSByZXF1aXJlKFwiLi4vdXRpbC9zdHJpY3QtbGltaXRcIik7XG4vKipcbiAqIOiuoeeul+e6v+aAp+eahCB0aWNrc++8jOS9v+eUqCBSJ3MgcHJldHR5IOaWueazlVxuICogQHBhcmFtIGNmZyDluqbph4/nmoTphY3nva7poblcbiAqIEByZXR1cm5zIOiuoeeul+WQjueahCB0aWNrc1xuICovXG5mdW5jdGlvbiBsaW5lYXJQcmV0dHkoY2ZnKSB7XG4gICAgdmFyIG1pbiA9IGNmZy5taW4sIG1heCA9IGNmZy5tYXgsIHRpY2tDb3VudCA9IGNmZy50aWNrQ291bnQsIHRpY2tJbnRlcnZhbCA9IGNmZy50aWNrSW50ZXJ2YWwsIG1pbkxpbWl0ID0gY2ZnLm1pbkxpbWl0LCBtYXhMaW1pdCA9IGNmZy5tYXhMaW1pdDtcbiAgICB2YXIgdGlja3MgPSBwcmV0dHlfMS5kZWZhdWx0KG1pbiwgbWF4LCB0aWNrQ291bnQpLnRpY2tzO1xuICAgIGlmICghdXRpbF8xLmlzTmlsKG1pbkxpbWl0KSB8fCAhdXRpbF8xLmlzTmlsKG1heExpbWl0KSkge1xuICAgICAgICByZXR1cm4gc3RyaWN0X2xpbWl0XzEuZGVmYXVsdChjZmcsIHV0aWxfMS5oZWFkKHRpY2tzKSwgdXRpbF8xLmxhc3QodGlja3MpKTtcbiAgICB9XG4gICAgaWYgKHRpY2tJbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWxfMS5kZWZhdWx0KG1pbiwgbWF4LCB0aWNrSW50ZXJ2YWwpLnRpY2tzO1xuICAgIH1cbiAgICByZXR1cm4gdGlja3M7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBsaW5lYXJQcmV0dHk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yLXByZXR0cnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlZ2lzdGVyVGlja01ldGhvZCA9IGV4cG9ydHMuZ2V0VGlja01ldGhvZCA9IHZvaWQgMDtcbnZhciBtZXRob2RDYWNoZSA9IHt9O1xuLyoqXG4gKiDojrflj5borqHnrpcgdGlja3Mg55qE5pa55rOVXG4gKiBAcGFyYW0ga2V5IOmUruWAvFxuICogQHJldHVybnMg6K6h566XIHRpY2tzIOeahOaWueazlVxuICovXG5mdW5jdGlvbiBnZXRUaWNrTWV0aG9kKGtleSkge1xuICAgIHJldHVybiBtZXRob2RDYWNoZVtrZXldO1xufVxuZXhwb3J0cy5nZXRUaWNrTWV0aG9kID0gZ2V0VGlja01ldGhvZDtcbi8qKlxuICog5rOo5YaM6K6h566XIHRpY2tzIOeahOaWueazlVxuICogQHBhcmFtIGtleSDplK7lgLxcbiAqIEBwYXJhbSBtZXRob2Qg5pa55rOVXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyVGlja01ldGhvZChrZXksIG1ldGhvZCkge1xuICAgIG1ldGhvZENhY2hlW2tleV0gPSBtZXRob2Q7XG59XG5leHBvcnRzLnJlZ2lzdGVyVGlja01ldGhvZCA9IHJlZ2lzdGVyVGlja01ldGhvZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlZ2lzdGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xudmFyIGNhdF8xID0gcmVxdWlyZShcIi4vY2F0XCIpO1xuLyoqXG4gKiDorqHnrpfml7bpl7TliIbnsbvnmoQgdGlja3MsIOS/neWktO+8jOS/neWwvlxuICogQHBhcmFtIGNmZyDluqbph4/nmoTphY3nva7poblcbiAqIEByZXR1cm5zIOiuoeeul+WQjueahCB0aWNrc1xuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVUaW1lQ2F0VGlja3MoY2ZnKSB7XG4gICAgdmFyIHRpY2tzID0gY2F0XzEuZGVmYXVsdChjZmcpO1xuICAgIHZhciBsYXN0VmFsdWUgPSB1dGlsXzEubGFzdChjZmcudmFsdWVzKTtcbiAgICBpZiAobGFzdFZhbHVlICE9PSB1dGlsXzEubGFzdCh0aWNrcykpIHtcbiAgICAgICAgdGlja3MucHVzaChsYXN0VmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGlja3M7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBjYWxjdWxhdGVUaW1lQ2F0VGlja3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aW1lLWNhdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0aW1lXzEgPSByZXF1aXJlKFwiLi4vdXRpbC90aW1lXCIpO1xuZnVuY3Rpb24gZ2V0WWVhcihkYXRlKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUpLmdldEZ1bGxZZWFyKCk7XG59XG5mdW5jdGlvbiBjcmVhdGVZZWFyKHllYXIpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoeWVhciwgMCwgMSkuZ2V0VGltZSgpO1xufVxuZnVuY3Rpb24gZ2V0TW9udGgoZGF0ZSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKS5nZXRNb250aCgpO1xufVxuZnVuY3Rpb24gZGlmZk1vbnRoKG1pbiwgbWF4KSB7XG4gICAgdmFyIG1pblllYXIgPSBnZXRZZWFyKG1pbik7XG4gICAgdmFyIG1heFllYXIgPSBnZXRZZWFyKG1heCk7XG4gICAgdmFyIG1pbk1vbnRoID0gZ2V0TW9udGgobWluKTtcbiAgICB2YXIgbWF4TW9udGggPSBnZXRNb250aChtYXgpO1xuICAgIHJldHVybiAobWF4WWVhciAtIG1pblllYXIpICogMTIgKyAoKG1heE1vbnRoIC0gbWluTW9udGgpICUgMTIpO1xufVxuZnVuY3Rpb24gY3JlYXRNb250aCh5ZWFyLCBtb250aCkge1xuICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSkuZ2V0VGltZSgpO1xufVxuZnVuY3Rpb24gZGlmZkRheShtaW4sIG1heCkge1xuICAgIHJldHVybiBNYXRoLmNlaWwoKG1heCAtIG1pbikgLyB0aW1lXzEuREFZKTtcbn1cbmZ1bmN0aW9uIGRpZmZIb3VyKG1pbiwgbWF4KSB7XG4gICAgcmV0dXJuIE1hdGguY2VpbCgobWF4IC0gbWluKSAvIHRpbWVfMS5IT1VSKTtcbn1cbmZ1bmN0aW9uIGRpZmZNaW51cyhtaW4sIG1heCkge1xuICAgIHJldHVybiBNYXRoLmNlaWwoKG1heCAtIG1pbikgLyAoNjAgKiAxMDAwKSk7XG59XG4vKipcbiAqIOiuoeeulyB0aW1lIOeahCB0aWNrc++8jOWvuSBtb250aCwgeWVhciDov5vooYwgcHJldHR5IOWkhOeQhlxuICogQHBhcmFtIGNmZyDluqbph4/nmoTphY3nva7poblcbiAqIEByZXR1cm5zIOiuoeeul+WQjueahCB0aWNrc1xuICovXG5mdW5jdGlvbiB0aW1lUHJldHR5KGNmZykge1xuICAgIHZhciBtaW4gPSBjZmcubWluLCBtYXggPSBjZmcubWF4LCBtaW5UaWNrSW50ZXJ2YWwgPSBjZmcubWluVGlja0ludGVydmFsO1xuICAgIHZhciB0aWNrSW50ZXJ2YWwgPSBjZmcudGlja0ludGVydmFsO1xuICAgIHZhciB0aWNrQ291bnQgPSBjZmcudGlja0NvdW50O1xuICAgIHZhciB0aWNrcyA9IFtdO1xuICAgIC8vIOaMh+WumiB0aWNrSW50ZXJ2YWwg5ZCOIHRpY2tDb3VudCDkuI3nlJ/mlYjvvIzpnIDopoHph43mlrDorqHnrpdcbiAgICBpZiAoIXRpY2tJbnRlcnZhbCkge1xuICAgICAgICB0aWNrSW50ZXJ2YWwgPSAobWF4IC0gbWluKSAvIHRpY2tDb3VudDtcbiAgICAgICAgLy8g5aaC5p6c6K6+572u5LqG5pyA5bCP6Ze06Led77yM5YiZ5L2/55So5pyA5bCP6Ze06LedXG4gICAgICAgIGlmIChtaW5UaWNrSW50ZXJ2YWwgJiYgdGlja0ludGVydmFsIDwgbWluVGlja0ludGVydmFsKSB7XG4gICAgICAgICAgICB0aWNrSW50ZXJ2YWwgPSBtaW5UaWNrSW50ZXJ2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIG1pblllYXIgPSBnZXRZZWFyKG1pbik7XG4gICAgLy8g5aaC5p6c6Ze06Led5aSn5LqOIDEg5bm077yM5YiZ5bCG5byA5aeL5pel5pyf5LuO5pW05bm05byA5aeLXG4gICAgaWYgKHRpY2tJbnRlcnZhbCA+IHRpbWVfMS5ZRUFSKSB7XG4gICAgICAgIHZhciBtYXhZZWFyID0gZ2V0WWVhcihtYXgpO1xuICAgICAgICB2YXIgeWVhckludGVydmFsID0gTWF0aC5jZWlsKHRpY2tJbnRlcnZhbCAvIHRpbWVfMS5ZRUFSKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IG1pblllYXI7IGkgPD0gbWF4WWVhciArIHllYXJJbnRlcnZhbDsgaSA9IGkgKyB5ZWFySW50ZXJ2YWwpIHtcbiAgICAgICAgICAgIHRpY2tzLnB1c2goY3JlYXRlWWVhcihpKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAodGlja0ludGVydmFsID4gdGltZV8xLk1PTlRIKSB7XG4gICAgICAgIC8vIOWkp+S6juaciOaXtlxuICAgICAgICB2YXIgbW9udGhJbnRlcnZhbCA9IE1hdGguY2VpbCh0aWNrSW50ZXJ2YWwgLyB0aW1lXzEuTU9OVEgpO1xuICAgICAgICB2YXIgbW1Nb3RoID0gZ2V0TW9udGgobWluKTtcbiAgICAgICAgdmFyIGRNb250aHMgPSBkaWZmTW9udGgobWluLCBtYXgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBkTW9udGhzICsgbW9udGhJbnRlcnZhbDsgaSA9IGkgKyBtb250aEludGVydmFsKSB7XG4gICAgICAgICAgICB0aWNrcy5wdXNoKGNyZWF0TW9udGgobWluWWVhciwgaSArIG1tTW90aCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHRpY2tJbnRlcnZhbCA+IHRpbWVfMS5EQVkpIHtcbiAgICAgICAgLy8g5aSn5LqO5aSpXG4gICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUobWluKTtcbiAgICAgICAgdmFyIHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgIHZhciBtb250aCA9IGRhdGUuZ2V0TW9udGgoKTtcbiAgICAgICAgdmFyIG1kYXkgPSBkYXRlLmdldERhdGUoKTtcbiAgICAgICAgdmFyIGRheSA9IE1hdGguY2VpbCh0aWNrSW50ZXJ2YWwgLyB0aW1lXzEuREFZKTtcbiAgICAgICAgdmFyIGRkYXlzID0gZGlmZkRheShtaW4sIG1heCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGRheXMgKyBkYXk7IGkgPSBpICsgZGF5KSB7XG4gICAgICAgICAgICB0aWNrcy5wdXNoKG5ldyBEYXRlKHllYXIsIG1vbnRoLCBtZGF5ICsgaSkuZ2V0VGltZSgpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmICh0aWNrSW50ZXJ2YWwgPiB0aW1lXzEuSE9VUikge1xuICAgICAgICAvLyDlpKfkuo7lsI/ml7ZcbiAgICAgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZShtaW4pO1xuICAgICAgICB2YXIgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgdmFyIG1vbnRoID0gZGF0ZS5nZXRNb250aCgpO1xuICAgICAgICB2YXIgZGF5ID0gZGF0ZS5nZXREYXRlKCk7XG4gICAgICAgIHZhciBob3VyID0gZGF0ZS5nZXRIb3VycygpO1xuICAgICAgICB2YXIgaG91cnMgPSBNYXRoLmNlaWwodGlja0ludGVydmFsIC8gdGltZV8xLkhPVVIpO1xuICAgICAgICB2YXIgZEhvdXJzID0gZGlmZkhvdXIobWluLCBtYXgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBkSG91cnMgKyBob3VyczsgaSA9IGkgKyBob3Vycykge1xuICAgICAgICAgICAgdGlja3MucHVzaChuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5LCBob3VyICsgaSkuZ2V0VGltZSgpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmICh0aWNrSW50ZXJ2YWwgPiB0aW1lXzEuTUlOVVRFKSB7XG4gICAgICAgIC8vIOWkp+S6juWIhumSn1xuICAgICAgICB2YXIgZE1pbnVzID0gZGlmZk1pbnVzKG1pbiwgbWF4KTtcbiAgICAgICAgdmFyIG1pbnV0ZXMgPSBNYXRoLmNlaWwodGlja0ludGVydmFsIC8gdGltZV8xLk1JTlVURSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IGRNaW51cyArIG1pbnV0ZXM7IGkgPSBpICsgbWludXRlcykge1xuICAgICAgICAgICAgdGlja3MucHVzaChtaW4gKyBpICogdGltZV8xLk1JTlVURSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIOWwj+S6juWIhumSn1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSB0aWNrSW50ZXJ2YWw7XG4gICAgICAgIGlmIChpbnRlcnZhbCA8IHRpbWVfMS5TRUNPTkQpIHtcbiAgICAgICAgICAgIGludGVydmFsID0gdGltZV8xLlNFQ09ORDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbWluU2Vjb25kID0gTWF0aC5mbG9vcihtaW4gLyB0aW1lXzEuU0VDT05EKSAqIHRpbWVfMS5TRUNPTkQ7XG4gICAgICAgIHZhciBkU2Vjb25kcyA9IE1hdGguY2VpbCgobWF4IC0gbWluKSAvIHRpbWVfMS5TRUNPTkQpO1xuICAgICAgICB2YXIgc2Vjb25kcyA9IE1hdGguY2VpbChpbnRlcnZhbCAvIHRpbWVfMS5TRUNPTkQpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRTZWNvbmRzICsgc2Vjb25kczsgaSA9IGkgKyBzZWNvbmRzKSB7XG4gICAgICAgICAgICB0aWNrcy5wdXNoKG1pblNlY29uZCArIGkgKiB0aW1lXzEuU0VDT05EKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGlja3M7XG59XG5leHBvcnRzLmRlZmF1bHQgPSB0aW1lUHJldHR5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGltZS1wcmV0dHkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdGltZV8xID0gcmVxdWlyZShcIi4uL3V0aWwvdGltZVwiKTtcbmZ1bmN0aW9uIGNhbGN1bGF0ZVRpbWVUaWNrcyhjZmcpIHtcbiAgICB2YXIgbWluID0gY2ZnLm1pbiwgbWF4ID0gY2ZnLm1heCwgbWluVGlja0ludGVydmFsID0gY2ZnLm1pblRpY2tJbnRlcnZhbDtcbiAgICB2YXIgdGlja0ludGVydmFsID0gY2ZnLnRpY2tJbnRlcnZhbDtcbiAgICB2YXIgdGlja0NvdW50ID0gY2ZnLnRpY2tDb3VudDtcbiAgICAvLyDmjIflrpogdGlja0ludGVydmFsIOWQjiB0aWNrQ291bnQg5LiN55Sf5pWI77yM6ZyA6KaB6YeN5paw6K6h566XXG4gICAgaWYgKHRpY2tJbnRlcnZhbCkge1xuICAgICAgICB0aWNrQ291bnQgPSBNYXRoLmNlaWwoKG1heCAtIG1pbikgLyB0aWNrSW50ZXJ2YWwpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdGlja0ludGVydmFsID0gdGltZV8xLmdldFRpY2tJbnRlcnZhbChtaW4sIG1heCwgdGlja0NvdW50KVsxXTtcbiAgICAgICAgdmFyIGNvdW50ID0gKG1heCAtIG1pbikgLyB0aWNrSW50ZXJ2YWw7XG4gICAgICAgIHZhciByYXRpbyA9IGNvdW50IC8gdGlja0NvdW50O1xuICAgICAgICBpZiAocmF0aW8gPiAxKSB7XG4gICAgICAgICAgICB0aWNrSW50ZXJ2YWwgPSB0aWNrSW50ZXJ2YWwgKiBNYXRoLmNlaWwocmF0aW8pO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWmguaenOiuvue9ruS6huacgOWwj+mXtOi3ne+8jOWImeS9v+eUqOacgOWwj+mXtOi3nVxuICAgICAgICBpZiAobWluVGlja0ludGVydmFsICYmIHRpY2tJbnRlcnZhbCA8IG1pblRpY2tJbnRlcnZhbCkge1xuICAgICAgICAgICAgdGlja0ludGVydmFsID0gbWluVGlja0ludGVydmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciB0aWNrcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSBtaW47IGkgPCBtYXggKyB0aWNrSW50ZXJ2YWw7IGkgKz0gdGlja0ludGVydmFsKSB7XG4gICAgICAgIHRpY2tzLnB1c2goaSk7XG4gICAgfVxuICAgIHJldHVybiB0aWNrcztcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGNhbGN1bGF0ZVRpbWVUaWNrcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRpbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIOS6jOWIhuWPs+S+p+afpeaJvlxuICogaHR0cHM6Ly9naXRodWIuY29tL2QzL2QzLWFycmF5L2Jsb2IvbWFzdGVyL3NyYy9iaXNlY3Rvci5qc1xuICovXG5mdW5jdGlvbiBkZWZhdWx0XzEoZ2V0dGVyKSB7XG4gICAgLyoqXG4gICAgICogeDog55uu5qCH5YC8XG4gICAgICogbG86IOi1t+Wni+S9jee9rlxuICAgICAqIGhpOiDnu5PmnZ/kvY3nva5cbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGEsIHgsIF9sbywgX2hpKSB7XG4gICAgICAgIHZhciBsbyA9IHV0aWxfMS5pc05pbChfbG8pID8gMCA6IF9sbztcbiAgICAgICAgdmFyIGhpID0gdXRpbF8xLmlzTmlsKF9oaSkgPyBhLmxlbmd0aCA6IF9oaTtcbiAgICAgICAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICAgICAgICAgIHZhciBtaWQgPSAobG8gKyBoaSkgPj4+IDE7XG4gICAgICAgICAgICBpZiAoZ2V0dGVyKGFbbWlkXSkgPiB4KSB7XG4gICAgICAgICAgICAgICAgaGkgPSBtaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsbyA9IG1pZCArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxvO1xuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBkZWZhdWx0XzE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXNlY3Rvci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuRDNMaW5lYXIgPSB2b2lkIDA7XG5mdW5jdGlvbiBkM0xpbmVhcihjZmcpIHtcbiAgICB2YXIgbWluID0gY2ZnLm1pbiwgbWF4ID0gY2ZnLm1heCwgbmljZSA9IGNmZy5uaWNlLCB0aWNrQ291bnQgPSBjZmcudGlja0NvdW50O1xuICAgIHZhciBsaW5lYXIgPSBuZXcgRDNMaW5lYXIoKTtcbiAgICBsaW5lYXIuZG9tYWluKFttaW4sIG1heF0pO1xuICAgIGlmIChuaWNlKSB7XG4gICAgICAgIGxpbmVhci5uaWNlKHRpY2tDb3VudCk7XG4gICAgfVxuICAgIHJldHVybiBsaW5lYXIudGlja3ModGlja0NvdW50KTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGQzTGluZWFyO1xudmFyIERFRkFVTFRfQ09VTlQgPSA1O1xudmFyIGUxMCA9IE1hdGguc3FydCg1MCk7XG52YXIgZTUgPSBNYXRoLnNxcnQoMTApO1xudmFyIGUyID0gTWF0aC5zcXJ0KDIpO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2QzL2QzLXNjYWxlXG52YXIgRDNMaW5lYXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRDNMaW5lYXIoKSB7XG4gICAgICAgIHRoaXMuX2RvbWFpbiA9IFswLCAxXTtcbiAgICB9XG4gICAgRDNMaW5lYXIucHJvdG90eXBlLmRvbWFpbiA9IGZ1bmN0aW9uIChkb21haW4pIHtcbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgdGhpcy5fZG9tYWluID0gQXJyYXkuZnJvbShkb21haW4sIE51bWJlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZG9tYWluLnNsaWNlKCk7XG4gICAgfTtcbiAgICBEM0xpbmVhci5wcm90b3R5cGUubmljZSA9IGZ1bmN0aW9uIChjb3VudCkge1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICBpZiAoY291bnQgPT09IHZvaWQgMCkgeyBjb3VudCA9IERFRkFVTFRfQ09VTlQ7IH1cbiAgICAgICAgdmFyIGQgPSB0aGlzLl9kb21haW4uc2xpY2UoKTtcbiAgICAgICAgdmFyIGkwID0gMDtcbiAgICAgICAgdmFyIGkxID0gdGhpcy5fZG9tYWluLmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuX2RvbWFpbltpMF07XG4gICAgICAgIHZhciBzdG9wID0gdGhpcy5fZG9tYWluW2kxXTtcbiAgICAgICAgdmFyIHN0ZXA7XG4gICAgICAgIGlmIChzdG9wIDwgc3RhcnQpIHtcbiAgICAgICAgICAgIF9hID0gW3N0b3AsIHN0YXJ0XSwgc3RhcnQgPSBfYVswXSwgc3RvcCA9IF9hWzFdO1xuICAgICAgICAgICAgX2IgPSBbaTEsIGkwXSwgaTAgPSBfYlswXSwgaTEgPSBfYlsxXTtcbiAgICAgICAgfVxuICAgICAgICBzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpO1xuICAgICAgICBpZiAoc3RlcCA+IDApIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gTWF0aC5mbG9vcihzdGFydCAvIHN0ZXApICogc3RlcDtcbiAgICAgICAgICAgIHN0b3AgPSBNYXRoLmNlaWwoc3RvcCAvIHN0ZXApICogc3RlcDtcbiAgICAgICAgICAgIHN0ZXAgPSB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RlcCA8IDApIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gTWF0aC5jZWlsKHN0YXJ0ICogc3RlcCkgLyBzdGVwO1xuICAgICAgICAgICAgc3RvcCA9IE1hdGguZmxvb3Ioc3RvcCAqIHN0ZXApIC8gc3RlcDtcbiAgICAgICAgICAgIHN0ZXAgPSB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0ZXAgPiAwKSB7XG4gICAgICAgICAgICBkW2kwXSA9IE1hdGguZmxvb3Ioc3RhcnQgLyBzdGVwKSAqIHN0ZXA7XG4gICAgICAgICAgICBkW2kxXSA9IE1hdGguY2VpbChzdG9wIC8gc3RlcCkgKiBzdGVwO1xuICAgICAgICAgICAgdGhpcy5kb21haW4oZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RlcCA8IDApIHtcbiAgICAgICAgICAgIGRbaTBdID0gTWF0aC5jZWlsKHN0YXJ0ICogc3RlcCkgLyBzdGVwO1xuICAgICAgICAgICAgZFtpMV0gPSBNYXRoLmZsb29yKHN0b3AgKiBzdGVwKSAvIHN0ZXA7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbihkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIEQzTGluZWFyLnByb3RvdHlwZS50aWNrcyA9IGZ1bmN0aW9uIChjb3VudCkge1xuICAgICAgICBpZiAoY291bnQgPT09IHZvaWQgMCkgeyBjb3VudCA9IERFRkFVTFRfQ09VTlQ7IH1cbiAgICAgICAgcmV0dXJuIGQzQXJyYXlUaWNrcyh0aGlzLl9kb21haW5bMF0sIHRoaXMuX2RvbWFpblt0aGlzLl9kb21haW4ubGVuZ3RoIC0gMV0sIGNvdW50IHx8IERFRkFVTFRfQ09VTlQpO1xuICAgIH07XG4gICAgcmV0dXJuIEQzTGluZWFyO1xufSgpKTtcbmV4cG9ydHMuRDNMaW5lYXIgPSBEM0xpbmVhcjtcbmZ1bmN0aW9uIGQzQXJyYXlUaWNrcyhzdGFydCwgc3RvcCwgY291bnQpIHtcbiAgICB2YXIgcmV2ZXJzZTtcbiAgICB2YXIgaSA9IC0xO1xuICAgIHZhciBuO1xuICAgIHZhciB0aWNrcztcbiAgICB2YXIgc3RlcDtcbiAgICAoc3RvcCA9ICtzdG9wKSwgKHN0YXJ0ID0gK3N0YXJ0KSwgKGNvdW50ID0gK2NvdW50KTtcbiAgICBpZiAoc3RhcnQgPT09IHN0b3AgJiYgY291bnQgPiAwKSB7XG4gICAgICAgIHJldHVybiBbc3RhcnRdO1xuICAgIH1cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBpZiAoKHJldmVyc2UgPSBzdG9wIDwgc3RhcnQpKSB7XG4gICAgICAgIChuID0gc3RhcnQpLCAoc3RhcnQgPSBzdG9wKSwgKHN0b3AgPSBuKTtcbiAgICB9XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gICAgaWYgKChzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpKSA9PT0gMCB8fCAhaXNGaW5pdGUoc3RlcCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBpZiAoc3RlcCA+IDApIHtcbiAgICAgICAgc3RhcnQgPSBNYXRoLmNlaWwoc3RhcnQgLyBzdGVwKTtcbiAgICAgICAgc3RvcCA9IE1hdGguZmxvb3Ioc3RvcCAvIHN0ZXApO1xuICAgICAgICB0aWNrcyA9IG5ldyBBcnJheSgobiA9IE1hdGguY2VpbChzdG9wIC0gc3RhcnQgKyAxKSkpO1xuICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgICAgdGlja3NbaV0gPSAoc3RhcnQgKyBpKSAqIHN0ZXA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0gTWF0aC5mbG9vcihzdGFydCAqIHN0ZXApO1xuICAgICAgICBzdG9wID0gTWF0aC5jZWlsKHN0b3AgKiBzdGVwKTtcbiAgICAgICAgdGlja3MgPSBuZXcgQXJyYXkoKG4gPSBNYXRoLmNlaWwoc3RhcnQgLSBzdG9wICsgMSkpKTtcbiAgICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgICAgIHRpY2tzW2ldID0gKHN0YXJ0IC0gaSkgLyBzdGVwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHRpY2tzLnJldmVyc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRpY2tzO1xufVxuZnVuY3Rpb24gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpIHtcbiAgICB2YXIgc3RlcCA9IChzdG9wIC0gc3RhcnQpIC8gTWF0aC5tYXgoMCwgY291bnQpO1xuICAgIHZhciBwb3dlciA9IE1hdGguZmxvb3IoTWF0aC5sb2coc3RlcCkgLyBNYXRoLkxOMTApO1xuICAgIHZhciBlcnJvciA9IHN0ZXAgLyBNYXRoLnBvdygxMCwgcG93ZXIpO1xuICAgIHJldHVybiBwb3dlciA+PSAwXG4gICAgICAgID8gKGVycm9yID49IGUxMCA/IDEwIDogZXJyb3IgPj0gZTUgPyA1IDogZXJyb3IgPj0gZTIgPyAyIDogMSkgKiBNYXRoLnBvdygxMCwgcG93ZXIpXG4gICAgICAgIDogLU1hdGgucG93KDEwLCAtcG93ZXIpIC8gKGVycm9yID49IGUxMCA/IDEwIDogZXJyb3IgPj0gZTUgPyA1IDogZXJyb3IgPj0gZTIgPyAyIDogMSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kMy1saW5lYXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkFMTF9RID0gZXhwb3J0cy5ERUZBVUxUX1EgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG5leHBvcnRzLkRFRkFVTFRfUSA9IFsxLCA1LCAyLCAyLjUsIDQsIDNdO1xuZXhwb3J0cy5BTExfUSA9IFsxLCA1LCAyLCAyLjUsIDQsIDMsIDEuNSwgNywgNiwgOCwgOV07XG52YXIgZXBzID0gTnVtYmVyLkVQU0lMT04gKiAxMDA7XG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80NDY3NTM5L2phdmFzY3JpcHQtbW9kdWxvLWdpdmVzLWEtbmVnYXRpdmUtcmVzdWx0LWZvci1uZWdhdGl2ZS1udW1iZXJzXG5mdW5jdGlvbiBtb2QobiwgbSkge1xuICAgIHJldHVybiAoKG4gJSBtKSArIG0pICUgbTtcbn1cbmZ1bmN0aW9uIHNpbXBsaWNpdHkocSwgUSwgaiwgbG1pbiwgbG1heCwgbHN0ZXApIHtcbiAgICB2YXIgbiA9IHV0aWxfMS5zaXplKFEpO1xuICAgIHZhciBpID0gdXRpbF8xLmluZGV4T2YoUSwgcSk7XG4gICAgdmFyIHYgPSAwO1xuICAgIHZhciBtID0gbW9kKGxtaW4sIGxzdGVwKTtcbiAgICBpZiAoKG0gPCBlcHMgfHwgbHN0ZXAgLSBtIDwgZXBzKSAmJiBsbWluIDw9IDAgJiYgbG1heCA+PSAwKSB7XG4gICAgICAgIHYgPSAxO1xuICAgIH1cbiAgICByZXR1cm4gMSAtIGkgLyAobiAtIDEpIC0gaiArIHY7XG59XG5mdW5jdGlvbiBzaW1wbGljaXR5TWF4KHEsIFEsIGopIHtcbiAgICB2YXIgbiA9IHV0aWxfMS5zaXplKFEpO1xuICAgIHZhciBpID0gdXRpbF8xLmluZGV4T2YoUSwgcSk7XG4gICAgdmFyIHYgPSAxO1xuICAgIHJldHVybiAxIC0gaSAvIChuIC0gMSkgLSBqICsgdjtcbn1cbmZ1bmN0aW9uIGRlbnNpdHkoaywgbSwgZG1pbiwgZG1heCwgbG1pbiwgbG1heCkge1xuICAgIHZhciByID0gKGsgLSAxKSAvIChsbWF4IC0gbG1pbik7XG4gICAgdmFyIHJ0ID0gKG0gLSAxKSAvIChNYXRoLm1heChsbWF4LCBkbWF4KSAtIE1hdGgubWluKGRtaW4sIGxtaW4pKTtcbiAgICByZXR1cm4gMiAtIE1hdGgubWF4KHIgLyBydCwgcnQgLyByKTtcbn1cbmZ1bmN0aW9uIGRlbnNpdHlNYXgoaywgbSkge1xuICAgIGlmIChrID49IG0pIHtcbiAgICAgICAgcmV0dXJuIDIgLSAoayAtIDEpIC8gKG0gLSAxKTtcbiAgICB9XG4gICAgcmV0dXJuIDE7XG59XG5mdW5jdGlvbiBjb3ZlcmFnZShkbWluLCBkbWF4LCBsbWluLCBsbWF4KSB7XG4gICAgdmFyIHJhbmdlID0gZG1heCAtIGRtaW47XG4gICAgcmV0dXJuIDEgLSAoMC41ICogKE1hdGgucG93KGRtYXggLSBsbWF4LCAyKSArIE1hdGgucG93KGRtaW4gLSBsbWluLCAyKSkpIC8gTWF0aC5wb3coMC4xICogcmFuZ2UsIDIpO1xufVxuZnVuY3Rpb24gY292ZXJhZ2VNYXgoZG1pbiwgZG1heCwgc3Bhbikge1xuICAgIHZhciByYW5nZSA9IGRtYXggLSBkbWluO1xuICAgIGlmIChzcGFuID4gcmFuZ2UpIHtcbiAgICAgICAgdmFyIGhhbGYgPSAoc3BhbiAtIHJhbmdlKSAvIDI7XG4gICAgICAgIHJldHVybiAxIC0gTWF0aC5wb3coaGFsZiwgMikgLyBNYXRoLnBvdygwLjEgKiByYW5nZSwgMik7XG4gICAgfVxuICAgIHJldHVybiAxO1xufVxuZnVuY3Rpb24gbGVnaWJpbGl0eSgpIHtcbiAgICByZXR1cm4gMTtcbn1cbi8qKlxuICogQW4gRXh0ZW5zaW9uIG9mIFdpbGtpbnNvbidzIEFsZ29yaXRobSBmb3IgUG9zaXRpb24gVGljayBMYWJlbHMgb24gQXhlc1xuICogaHR0cHM6Ly93d3cueXVxdWUuY29tL3ByZXZpZXcveXVxdWUvMC8yMDE5L3BkZi8xODUzMTcvMTU0Njk5OTE1MDg1OC00NWMzYjljMi00ZTg2LTQyMjMtYmYxYS04YTczMmU4MTk1ZWQucGRmXG4gKiBAcGFyYW0gZG1pbiDmnIDlsI/lgLxcbiAqIEBwYXJhbSBkbWF4IOacgOWkp+WAvFxuICogQHBhcmFtIG0gdGlja+S4quaVsFxuICogQHBhcmFtIG9ubHlMb29zZSDmmK/lkKblhYHorrjmianlsZVtaW7jgIFtYXjvvIzkuI3nu53lr7nlvLrliLbvvIzkvovlpoJbMywgOTddXG4gKiBAcGFyYW0gUSBuaWNlIG51bWJlcnPpm4blkIhcbiAqIEBwYXJhbSB3IOWbm+S4quS8mOWMlue7hOS7tueahOadg+mHjVxuICovXG5mdW5jdGlvbiBleHRlbmRlZChkbWluLCBkbWF4LCBtLCBvbmx5TG9vc2UsIFEsIHcpIHtcbiAgICBpZiAobSA9PT0gdm9pZCAwKSB7IG0gPSA1OyB9XG4gICAgaWYgKG9ubHlMb29zZSA9PT0gdm9pZCAwKSB7IG9ubHlMb29zZSA9IHRydWU7IH1cbiAgICBpZiAoUSA9PT0gdm9pZCAwKSB7IFEgPSBleHBvcnRzLkRFRkFVTFRfUTsgfVxuICAgIGlmICh3ID09PSB2b2lkIDApIHsgdyA9IFswLjI1LCAwLjIsIDAuNSwgMC4wNV07IH1cbiAgICBpZiAoZG1pbiA9PT0gZG1heCB8fCBtID09PSAxKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtaW46IGRtaW4sXG4gICAgICAgICAgICBtYXg6IGRtYXgsXG4gICAgICAgICAgICB0aWNrczogW2RtaW5dLFxuICAgICAgICB9O1xuICAgIH1cbiAgICB2YXIgYmVzdCA9IHtcbiAgICAgICAgc2NvcmU6IC0yLFxuICAgICAgICBsbWluOiAwLFxuICAgICAgICBsbWF4OiAwLFxuICAgICAgICBsc3RlcDogMCxcbiAgICB9O1xuICAgIHZhciBqID0gMTtcbiAgICB3aGlsZSAoaiA8IEluZmluaXR5KSB7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgUV8xID0gUTsgX2kgPCBRXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgcSA9IFFfMVtfaV07XG4gICAgICAgICAgICB2YXIgc20gPSBzaW1wbGljaXR5TWF4KHEsIFEsIGopO1xuICAgICAgICAgICAgaWYgKE51bWJlci5pc05hTihzbSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05hTicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHdbMF0gKiBzbSArIHdbMV0gKyB3WzJdICsgd1szXSA8IGJlc3Quc2NvcmUpIHtcbiAgICAgICAgICAgICAgICBqID0gSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgayA9IDI7XG4gICAgICAgICAgICB3aGlsZSAoayA8IEluZmluaXR5KSB7XG4gICAgICAgICAgICAgICAgdmFyIGRtID0gZGVuc2l0eU1heChrLCBtKTtcbiAgICAgICAgICAgICAgICBpZiAod1swXSAqIHNtICsgd1sxXSArIHdbMl0gKiBkbSArIHdbM10gPCBiZXN0LnNjb3JlKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZGVsdGEgPSAoZG1heCAtIGRtaW4pIC8gKGsgKyAxKSAvIGogLyBxO1xuICAgICAgICAgICAgICAgIHZhciB6ID0gTWF0aC5jZWlsKE1hdGgubG9nMTAoZGVsdGEpKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAoeiA8IEluZmluaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGVwID0gaiAqIHEgKiBNYXRoLnBvdygxMCwgeik7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjbSA9IGNvdmVyYWdlTWF4KGRtaW4sIGRtYXgsIHN0ZXAgKiAoayAtIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdbMF0gKiBzbSArIHdbMV0gKiBjbSArIHdbMl0gKiBkbSArIHdbM10gPCBiZXN0LnNjb3JlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YXIgbWluU3RhcnQgPSBNYXRoLmZsb29yKGRtYXggLyBzdGVwKSAqIGogLSAoayAtIDEpICogajtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1heFN0YXJ0ID0gTWF0aC5jZWlsKGRtaW4gLyBzdGVwKSAqIGo7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtaW5TdGFydCA+IG1heFN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB6ID0geiArIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBzdGFydCA9IG1pblN0YXJ0OyBzdGFydCA8PSBtYXhTdGFydDsgc3RhcnQgPSBzdGFydCArIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsbWluID0gc3RhcnQgKiAoc3RlcCAvIGopO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxtYXggPSBsbWluICsgc3RlcCAqIChrIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbHN0ZXAgPSBzdGVwO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBzaW1wbGljaXR5KHEsIFEsIGosIGxtaW4sIGxtYXgsIGxzdGVwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gY292ZXJhZ2UoZG1pbiwgZG1heCwgbG1pbiwgbG1heCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZyA9IGRlbnNpdHkoaywgbSwgZG1pbiwgZG1heCwgbG1pbiwgbG1heCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbCA9IGxlZ2liaWxpdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY29yZSA9IHdbMF0gKiBzICsgd1sxXSAqIGMgKyB3WzJdICogZyArIHdbM10gKiBsO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjb3JlID4gYmVzdC5zY29yZSAmJiAoIW9ubHlMb29zZSB8fCAobG1pbiA8PSBkbWluICYmIGxtYXggPj0gZG1heCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdC5sbWluID0gbG1pbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0LmxtYXggPSBsbWF4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3QubHN0ZXAgPSBsc3RlcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0LnNjb3JlID0gc2NvcmU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgeiA9IHogKyAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBrID0gayArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaiA9IGogKyAxO1xuICAgIH1cbiAgICAvLyDmraXplb/kuLrmta7ngrnmlbDml7blpITnkIbnsr7luqZcbiAgICB2YXIgdG9GaXhlZCA9IE51bWJlci5pc0ludGVnZXIoYmVzdC5sc3RlcCkgPyAwIDogTWF0aC5jZWlsKE1hdGguYWJzKE1hdGgubG9nMTAoYmVzdC5sc3RlcCkpKTtcbiAgICB2YXIgcmFuZ2UgPSBbXTtcbiAgICBmb3IgKHZhciB0aWNrID0gYmVzdC5sbWluOyB0aWNrIDw9IGJlc3QubG1heDsgdGljayArPSBiZXN0LmxzdGVwKSB7XG4gICAgICAgIHJhbmdlLnB1c2godGljayk7XG4gICAgfVxuICAgIHZhciB0aWNrcyA9IHRvRml4ZWQgPyB1dGlsXzEubWFwKHJhbmdlLCBmdW5jdGlvbiAoeCkgeyByZXR1cm4gTnVtYmVyLnBhcnNlRmxvYXQoeC50b0ZpeGVkKHRvRml4ZWQpKTsgfSkgOiByYW5nZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW46IE1hdGgubWluKGRtaW4sIHV0aWxfMS5oZWFkKHRpY2tzKSksXG4gICAgICAgIG1heDogTWF0aC5tYXgoZG1heCwgdXRpbF8xLmxhc3QodGlja3MpKSxcbiAgICAgICAgdGlja3M6IHRpY2tzLFxuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBleHRlbmRlZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV4dGVuZGVkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoXCJAYW50di91dGlsXCIpO1xuZnVuY3Rpb24gc25hcE11bHRpcGxlKHYsIGJhc2UsIHNuYXBUeXBlKSB7XG4gICAgdmFyIGRpdjtcbiAgICBpZiAoc25hcFR5cGUgPT09ICdjZWlsJykge1xuICAgICAgICBkaXYgPSBNYXRoLmNlaWwodiAvIGJhc2UpO1xuICAgIH1cbiAgICBlbHNlIGlmIChzbmFwVHlwZSA9PT0gJ2Zsb29yJykge1xuICAgICAgICBkaXYgPSBNYXRoLmZsb29yKHYgLyBiYXNlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRpdiA9IE1hdGgucm91bmQodiAvIGJhc2UpO1xuICAgIH1cbiAgICByZXR1cm4gZGl2ICogYmFzZTtcbn1cbmZ1bmN0aW9uIGludGVydmFsVGlja3MobWluLCBtYXgsIGludGVydmFsKSB7XG4gICAgLy8g5Y+Y5oiQIGludGVydmFsIOeahOWAjeaVsFxuICAgIHZhciBtaW5UaWNrID0gc25hcE11bHRpcGxlKG1pbiwgaW50ZXJ2YWwsICdmbG9vcicpO1xuICAgIHZhciBtYXhUaWNrID0gc25hcE11bHRpcGxlKG1heCwgaW50ZXJ2YWwsICdjZWlsJyk7XG4gICAgLy8g57uf5LiA5bCP5pWw5L2N5pWwXG4gICAgbWluVGljayA9IHV0aWxfMS5maXhlZEJhc2UobWluVGljaywgaW50ZXJ2YWwpO1xuICAgIG1heFRpY2sgPSB1dGlsXzEuZml4ZWRCYXNlKG1heFRpY2ssIGludGVydmFsKTtcbiAgICB2YXIgdGlja3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gbWluVGljazsgaSA8PSBtYXhUaWNrOyBpID0gaSArIGludGVydmFsKSB7XG4gICAgICAgIHZhciB0aWNrVmFsdWUgPSB1dGlsXzEuZml4ZWRCYXNlKGksIGludGVydmFsKTsgLy8g6Ziy5q2i5rWu54K55pWw5Yqg5rOV5Ye6546w6Zeu6aKYXG4gICAgICAgIHRpY2tzLnB1c2godGlja1ZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluOiBtaW5UaWNrLFxuICAgICAgICBtYXg6IG1heFRpY2ssXG4gICAgICAgIHRpY2tzOiB0aWNrc1xuICAgIH07XG59XG5leHBvcnRzLmRlZmF1bHQgPSBpbnRlcnZhbFRpY2tzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJ2YWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmdldExvZ1Bvc2l0aXZlTWluID0gZXhwb3J0cy5sb2cgPSBleHBvcnRzLmNhbEJhc2UgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vLyDmsYLku6Vh5Li65qyh5bmC77yM57uT5p6c5Li6YueahOWfuuaVsO+8jOWmgiB4Xl5hID0gYjvmsYJ4XG4vLyDomb3nhLbmlbDlrabkuIogYiDkuI3mlK/mjIHotJ/mlbDvvIzkvYbmmK/ov5nph4zpnIDopoHmlK/mjIEg6LSf5pWwXG5mdW5jdGlvbiBjYWxCYXNlKGEsIGIpIHtcbiAgICB2YXIgZSA9IE1hdGguRTtcbiAgICB2YXIgdmFsdWU7XG4gICAgaWYgKGIgPj0gMCkge1xuICAgICAgICB2YWx1ZSA9IE1hdGgucG93KGUsIE1hdGgubG9nKGIpIC8gYSk7IC8vIOS9v+eUqOaNouW6leWFrOW8j+axguW6lVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSBNYXRoLnBvdyhlLCBNYXRoLmxvZygtYikgLyBhKSAqIC0xOyAvLyDkvb/nlKjmjaLlupXlhazlvI/msYLlupVcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuZXhwb3J0cy5jYWxCYXNlID0gY2FsQmFzZTtcbmZ1bmN0aW9uIGxvZyhhLCBiKSB7XG4gICAgaWYgKGEgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIHJldHVybiBNYXRoLmxvZyhiKSAvIE1hdGgubG9nKGEpO1xufVxuZXhwb3J0cy5sb2cgPSBsb2c7XG5mdW5jdGlvbiBnZXRMb2dQb3NpdGl2ZU1pbih2YWx1ZXMsIGJhc2UsIG1heCkge1xuICAgIGlmICh1dGlsXzEuaXNOaWwobWF4KSkge1xuICAgICAgICBtYXggPSBNYXRoLm1heC5hcHBseShudWxsLCB2YWx1ZXMpO1xuICAgIH1cbiAgICB2YXIgcG9zaXRpdmVNaW4gPSBtYXg7XG4gICAgdXRpbF8xLmVhY2godmFsdWVzLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlID4gMCAmJiB2YWx1ZSA8IHBvc2l0aXZlTWluKSB7XG4gICAgICAgICAgICBwb3NpdGl2ZU1pbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHBvc2l0aXZlTWluID09PSBtYXgpIHtcbiAgICAgICAgcG9zaXRpdmVNaW4gPSBtYXggLyBiYXNlO1xuICAgIH1cbiAgICBpZiAocG9zaXRpdmVNaW4gPiAxKSB7XG4gICAgICAgIHBvc2l0aXZlTWluID0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHBvc2l0aXZlTWluO1xufVxuZXhwb3J0cy5nZXRMb2dQb3NpdGl2ZU1pbiA9IGdldExvZ1Bvc2l0aXZlTWluO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWF0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHByZXR0eShtaW4sIG1heCwgbikge1xuICAgIGlmIChuID09PSB2b2lkIDApIHsgbiA9IDU7IH1cbiAgICB2YXIgcmVzID0ge1xuICAgICAgICBtYXg6IDAsXG4gICAgICAgIG1pbjogMCxcbiAgICAgICAgdGlja3M6IFtdLFxuICAgIH07XG4gICAgLypcbiAgICAgIFIgcHJldHR5OlxuICAgICAgaHR0cHM6Ly9zdm4uci1wcm9qZWN0Lm9yZy9SL3RydW5rL3NyYy9hcHBsL3ByZXR0eS5jXG4gICAgICBodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvYmFzZS92ZXJzaW9ucy8zLjUuMi90b3BpY3MvcHJldHR5XG4gICAgICAqL1xuICAgIHZhciBoID0gMS41OyAvLyBoaWdoLnUuYmlhc1xuICAgIHZhciBoNSA9IDAuNSArIDEuNSAqIGg7IC8vIHU1LmJpYXNcbiAgICAvLyDlj43mraPmiJHkuZ/kuI3kvJrosIPlj4LvvIzot7Pov4fmiYDmnInliKTmlq3mraXpqqRcbiAgICB2YXIgZCA9IG1heCAtIG1pbjtcbiAgICB2YXIgYyA9IGQgLyBuO1xuICAgIC8vIOW9k2TpnZ7luLjlsI/nmoTml7blgJnop6blj5HvvIzkvYbkvLzkuY7msqHku4DkuYjnlKhcbiAgICAvLyBjb25zdCBtaW5fbiA9IE1hdGguZmxvb3IobiAvIDMpO1xuICAgIC8vIGNvbnN0IHNocmlua19zbWwgPSBNYXRoLnBvdygyLCA1KTtcbiAgICAvLyBpZiAoTWF0aC5sb2cxMChkKSA8IC0yKSB7XG4gICAgLy8gICBjID0gKF8ubWF4KFsgTWF0aC5hYnMobWF4KSwgTWF0aC5hYnMobWluKSBdKSAqIHNocmlua19zbWwpIC8gbWluX247XG4gICAgLy8gfVxuICAgIHZhciBiYXNlID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoTWF0aC5sb2cxMChjKSkpO1xuICAgIHZhciB0b0ZpeGVkID0gYmFzZSA8IDEgPyBNYXRoLmNlaWwoTWF0aC5hYnMoTWF0aC5sb2cxMChiYXNlKSkpIDogMDtcbiAgICB2YXIgdW5pdCA9IGJhc2U7XG4gICAgaWYgKDIgKiBiYXNlIC0gYyA8IGggKiAoYyAtIHVuaXQpKSB7XG4gICAgICAgIHVuaXQgPSAyICogYmFzZTtcbiAgICAgICAgaWYgKDUgKiBiYXNlIC0gYyA8IGg1ICogKGMgLSB1bml0KSkge1xuICAgICAgICAgICAgdW5pdCA9IDUgKiBiYXNlO1xuICAgICAgICAgICAgaWYgKDEwICogYmFzZSAtIGMgPCBoICogKGMgLSB1bml0KSkge1xuICAgICAgICAgICAgICAgIHVuaXQgPSAxMCAqIGJhc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIG51ID0gTWF0aC5jZWlsKG1heCAvIHVuaXQpO1xuICAgIHZhciBucyA9IE1hdGguZmxvb3IobWluIC8gdW5pdCk7XG4gICAgcmVzLm1heCA9IE1hdGgubWF4KG51ICogdW5pdCwgbWF4KTtcbiAgICByZXMubWluID0gTWF0aC5taW4obnMgKiB1bml0LCBtaW4pO1xuICAgIHZhciB4ID0gTnVtYmVyLnBhcnNlRmxvYXQoKG5zICogdW5pdCkudG9GaXhlZCh0b0ZpeGVkKSk7XG4gICAgd2hpbGUgKHggPCBtYXgpIHtcbiAgICAgICAgcmVzLnRpY2tzLnB1c2goeCk7XG4gICAgICAgIHggKz0gdW5pdDtcbiAgICAgICAgaWYgKHRvRml4ZWQpIHtcbiAgICAgICAgICAgIHggPSBOdW1iZXIucGFyc2VGbG9hdCh4LnRvRml4ZWQodG9GaXhlZCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlcy50aWNrcy5wdXNoKHgpO1xuICAgIHJldHVybiByZXM7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBwcmV0dHk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wcmV0dHkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG4vKipcbiAqIOaMieeFp+e7meWumueahCBtaW5MaW1pdC9tYXhMaW1pdC90aWNrQ291bnQg5Z2H5YyA6K6h566X5Ye65Yi75bqmIHRpY2tzXG4gKlxuICogQHBhcmFtIGNmZyBTY2FsZSDphY3nva7poblcbiAqIEByZXR1cm4gdGlja3NcbiAqL1xuZnVuY3Rpb24gc3RyaWN0TGltaXQoY2ZnLCBkZWZhdWx0TWluLCBkZWZhdWx0TWF4KSB7XG4gICAgdmFyIF9hO1xuICAgIHZhciBtaW5MaW1pdCA9IGNmZy5taW5MaW1pdCwgbWF4TGltaXQgPSBjZmcubWF4TGltaXQsIG1pbiA9IGNmZy5taW4sIG1heCA9IGNmZy5tYXgsIF9iID0gY2ZnLnRpY2tDb3VudCwgdGlja0NvdW50ID0gX2IgPT09IHZvaWQgMCA/IDUgOiBfYjtcbiAgICB2YXIgdGlja01pbiA9IHV0aWxfMS5pc05pbChtaW5MaW1pdCkgPyAodXRpbF8xLmlzTmlsKGRlZmF1bHRNaW4pID8gbWluIDogZGVmYXVsdE1pbikgOiBtaW5MaW1pdDtcbiAgICB2YXIgdGlja01heCA9IHV0aWxfMS5pc05pbChtYXhMaW1pdCkgPyAodXRpbF8xLmlzTmlsKGRlZmF1bHRNYXgpID8gbWF4IDogZGVmYXVsdE1heCkgOiBtYXhMaW1pdDtcbiAgICBpZiAodGlja01pbiA+IHRpY2tNYXgpIHtcbiAgICAgICAgX2EgPSBbdGlja01pbiwgdGlja01heF0sIHRpY2tNYXggPSBfYVswXSwgdGlja01pbiA9IF9hWzFdO1xuICAgIH1cbiAgICBpZiAodGlja0NvdW50IDw9IDIpIHtcbiAgICAgICAgcmV0dXJuIFt0aWNrTWluLCB0aWNrTWF4XTtcbiAgICB9XG4gICAgdmFyIHN0ZXAgPSAodGlja01heCAtIHRpY2tNaW4pIC8gKHRpY2tDb3VudCAtIDEpO1xuICAgIHZhciB0aWNrcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGlja0NvdW50OyBpKyspIHtcbiAgICAgICAgdGlja3MucHVzaCh0aWNrTWluICsgc3RlcCAqIGkpO1xuICAgIH1cbiAgICByZXR1cm4gdGlja3M7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzdHJpY3RMaW1pdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0cmljdC1saW1pdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0VGlja0ludGVydmFsID0gZXhwb3J0cy5ZRUFSID0gZXhwb3J0cy5NT05USCA9IGV4cG9ydHMuREFZID0gZXhwb3J0cy5IT1VSID0gZXhwb3J0cy5NSU5VVEUgPSBleHBvcnRzLlNFQ09ORCA9IGV4cG9ydHMudG9UaW1lU3RhbXAgPSBleHBvcnRzLnRpbWVGb3JtYXQgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIkBhbnR2L3V0aWxcIik7XG52YXIgZmVjaGFfMSA9IHJlcXVpcmUoXCJmZWNoYVwiKTtcbnZhciBmZWNoYTEgPSByZXF1aXJlKFwiZmVjaGFcIik7XG52YXIgYmlzZWN0b3JfMSA9IHJlcXVpcmUoXCIuL2Jpc2VjdG9yXCIpO1xudmFyIEZPUk1BVF9NRVRIT0QgPSAnZm9ybWF0JztcbmZ1bmN0aW9uIHRpbWVGb3JtYXQodGltZSwgbWFzaykge1xuICAgIHZhciBtZXRob2QgPSBmZWNoYTFbRk9STUFUX01FVEhPRF0gfHwgZmVjaGFfMS5kZWZhdWx0W0ZPUk1BVF9NRVRIT0RdO1xuICAgIHJldHVybiBtZXRob2QodGltZSwgbWFzayk7XG59XG5leHBvcnRzLnRpbWVGb3JtYXQgPSB0aW1lRm9ybWF0O1xuLyoqXG4gKiDovazmjaLmiJDml7bpl7TmiLNcbiAqIEBwYXJhbSB2YWx1ZSDml7bpl7TlgLxcbiAqL1xuZnVuY3Rpb24gdG9UaW1lU3RhbXAodmFsdWUpIHtcbiAgICBpZiAodXRpbF8xLmlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICBpZiAodmFsdWUuaW5kZXhPZignVCcpID4gMCkge1xuICAgICAgICAgICAgdmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZSkuZ2V0VGltZSgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gbmV3IERhdGUoJzIwMTAvMDEvMTAnKSDlkowgbmV3IERhdGUoJzIwMTAtMDEtMTAnKSDnmoTlt67liKvlnKjkuo46XG4gICAgICAgICAgICAvLyDlpoLmnpzku4XmnInlubTmnIjml6Xml7bvvIzliY3ogIXmmK/luKbmnInml7bljLrnmoQ6IEZyaSBKYW4gMTAgMjAyMCAwMjo0MDoxMyBHTVQrMDgwMCAo5Lit5Zu95qCH5YeG5pe26Ze0KVxuICAgICAgICAgICAgLy8g5ZCO6ICF5Lya5qC85byP5YyW5oiQIFN1biBKYW4gMTAgMjAxMCAwODowMDowMCBHTVQrMDgwMCAo5Lit5Zu95qCH5YeG5pe26Ze0KVxuICAgICAgICAgICAgdmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZS5yZXBsYWNlKC8tL2dpLCAnLycpKS5nZXRUaW1lKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHV0aWxfMS5pc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUuZ2V0VGltZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5leHBvcnRzLnRvVGltZVN0YW1wID0gdG9UaW1lU3RhbXA7XG52YXIgU0VDT05EID0gMTAwMDtcbmV4cG9ydHMuU0VDT05EID0gU0VDT05EO1xudmFyIE1JTlVURSA9IDYwICogU0VDT05EO1xuZXhwb3J0cy5NSU5VVEUgPSBNSU5VVEU7XG52YXIgSE9VUiA9IDYwICogTUlOVVRFO1xuZXhwb3J0cy5IT1VSID0gSE9VUjtcbnZhciBEQVkgPSAyNCAqIEhPVVI7XG5leHBvcnRzLkRBWSA9IERBWTtcbnZhciBNT05USCA9IERBWSAqIDMxO1xuZXhwb3J0cy5NT05USCA9IE1PTlRIO1xudmFyIFlFQVIgPSBEQVkgKiAzNjU7XG5leHBvcnRzLllFQVIgPSBZRUFSO1xudmFyIGludGVydmFscyA9IFtcbiAgICBbJ0hIOm1tOnNzJywgU0VDT05EXSxcbiAgICBbJ0hIOm1tOnNzJywgU0VDT05EICogMTBdLFxuICAgIFsnSEg6bW06c3MnLCBTRUNPTkQgKiAzMF0sXG4gICAgWydISDptbScsIE1JTlVURV0sXG4gICAgWydISDptbScsIE1JTlVURSAqIDEwXSxcbiAgICBbJ0hIOm1tJywgTUlOVVRFICogMzBdLFxuICAgIFsnSEgnLCBIT1VSXSxcbiAgICBbJ0hIJywgSE9VUiAqIDZdLFxuICAgIFsnSEgnLCBIT1VSICogMTJdLFxuICAgIFsnWVlZWS1NTS1ERCcsIERBWV0sXG4gICAgWydZWVlZLU1NLUREJywgREFZICogNF0sXG4gICAgWydZWVlZLVdXJywgREFZICogN10sXG4gICAgWydZWVlZLU1NJywgTU9OVEhdLFxuICAgIFsnWVlZWS1NTScsIE1PTlRIICogNF0sXG4gICAgWydZWVlZLU1NJywgTU9OVEggKiA2XSxcbiAgICBbJ1lZWVknLCBEQVkgKiAzODBdLFxuXTtcbmZ1bmN0aW9uIGdldFRpY2tJbnRlcnZhbChtaW4sIG1heCwgdGlja0NvdW50KSB7XG4gICAgdmFyIHRhcmdldCA9IChtYXggLSBtaW4pIC8gdGlja0NvdW50O1xuICAgIHZhciBpZHggPSBiaXNlY3Rvcl8xLmRlZmF1bHQoZnVuY3Rpb24gKG8pIHsgcmV0dXJuIG9bMV07IH0pKGludGVydmFscywgdGFyZ2V0KSAtIDE7XG4gICAgdmFyIGludGVydmFsID0gaW50ZXJ2YWxzW2lkeF07XG4gICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgaW50ZXJ2YWwgPSBpbnRlcnZhbHNbMF07XG4gICAgfVxuICAgIGVsc2UgaWYgKGlkeCA+PSBpbnRlcnZhbHMubGVuZ3RoKSB7XG4gICAgICAgIGludGVydmFsID0gdXRpbF8xLmxhc3QoaW50ZXJ2YWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIGludGVydmFsO1xufVxuZXhwb3J0cy5nZXRUaWNrSW50ZXJ2YWwgPSBnZXRUaWNrSW50ZXJ2YWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aW1lLmpzLm1hcCIsIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBnbG9iYWwsIGRlZmluZSwgU3lzdGVtLCBSZWZsZWN0LCBQcm9taXNlICovXHJcbnZhciBfX2V4dGVuZHM7XHJcbnZhciBfX2Fzc2lnbjtcclxudmFyIF9fcmVzdDtcclxudmFyIF9fZGVjb3JhdGU7XHJcbnZhciBfX3BhcmFtO1xyXG52YXIgX19tZXRhZGF0YTtcclxudmFyIF9fYXdhaXRlcjtcclxudmFyIF9fZ2VuZXJhdG9yO1xyXG52YXIgX19leHBvcnRTdGFyO1xyXG52YXIgX192YWx1ZXM7XHJcbnZhciBfX3JlYWQ7XHJcbnZhciBfX3NwcmVhZDtcclxudmFyIF9fc3ByZWFkQXJyYXlzO1xyXG52YXIgX19hd2FpdDtcclxudmFyIF9fYXN5bmNHZW5lcmF0b3I7XHJcbnZhciBfX2FzeW5jRGVsZWdhdG9yO1xyXG52YXIgX19hc3luY1ZhbHVlcztcclxudmFyIF9fbWFrZVRlbXBsYXRlT2JqZWN0O1xyXG52YXIgX19pbXBvcnRTdGFyO1xyXG52YXIgX19pbXBvcnREZWZhdWx0O1xyXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldDtcclxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQ7XHJcbnZhciBfX2NyZWF0ZUJpbmRpbmc7XHJcbihmdW5jdGlvbiAoZmFjdG9yeSkge1xyXG4gICAgdmFyIHJvb3QgPSB0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgPyBzZWxmIDogdHlwZW9mIHRoaXMgPT09IFwib2JqZWN0XCIgPyB0aGlzIDoge307XHJcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcclxuICAgICAgICBkZWZpbmUoXCJ0c2xpYlwiLCBbXCJleHBvcnRzXCJdLCBmdW5jdGlvbiAoZXhwb3J0cykgeyBmYWN0b3J5KGNyZWF0ZUV4cG9ydGVyKHJvb3QsIGNyZWF0ZUV4cG9ydGVyKGV4cG9ydHMpKSk7IH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgICBmYWN0b3J5KGNyZWF0ZUV4cG9ydGVyKHJvb3QsIGNyZWF0ZUV4cG9ydGVyKG1vZHVsZS5leHBvcnRzKSkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgZmFjdG9yeShjcmVhdGVFeHBvcnRlcihyb290KSk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBjcmVhdGVFeHBvcnRlcihleHBvcnRzLCBwcmV2aW91cykge1xyXG4gICAgICAgIGlmIChleHBvcnRzICE9PSByb290KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoaWQsIHYpIHsgcmV0dXJuIGV4cG9ydHNbaWRdID0gcHJldmlvdXMgPyBwcmV2aW91cyhpZCwgdikgOiB2OyB9O1xyXG4gICAgfVxyXG59KVxyXG4oZnVuY3Rpb24gKGV4cG9ydGVyKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG5cclxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH07XHJcblxyXG4gICAgX19yZXN0ID0gZnVuY3Rpb24gKHMsIGUpIHtcclxuICAgICAgICB2YXIgdCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgICAgICB0W3BdID0gc1twXTtcclxuICAgICAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2RlY29yYXRlID0gZnVuY3Rpb24gKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICAgICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgICAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICAgICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxuICAgIH07XHJcblxyXG4gICAgX19wYXJhbSA9IGZ1bmN0aW9uIChwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxuICAgIH07XHJcblxyXG4gICAgX19tZXRhZGF0YSA9IGZ1bmN0aW9uIChtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXdhaXRlciA9IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgICAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgICAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2dlbmVyYXRvciA9IGZ1bmN0aW9uICh0aGlzQXJnLCBib2R5KSB7XHJcbiAgICAgICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgICAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgICAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fZXhwb3J0U3RhciA9IGZ1bmN0aW9uKG0sIG8pIHtcclxuICAgICAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgICAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9KTtcclxuICAgIH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICAgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgICAgICBvW2syXSA9IG1ba107XHJcbiAgICB9KTtcclxuXHJcbiAgICBfX3ZhbHVlcyA9IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgICAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgICAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIH07XHJcblxyXG4gICAgX19yZWFkID0gZnVuY3Rpb24gKG8sIG4pIHtcclxuICAgICAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICAgICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgICAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICAgICAgZmluYWxseSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFyO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3NwcmVhZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgICAgIHJldHVybiBhcjtcclxuICAgIH07XHJcblxyXG4gICAgX19zcHJlYWRBcnJheXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICAgICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgICAgIHJldHVybiByO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2F3YWl0ID0gZnVuY3Rpb24gKHYpIHtcclxuICAgICAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxuICAgIH07XHJcblxyXG4gICAgX19hc3luY0dlbmVyYXRvciA9IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICAgICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7ICB9XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgICAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXN5bmNEZWxlZ2F0b3IgPSBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBpLCBwO1xyXG4gICAgICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICAgICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX2FzeW5jVmFsdWVzID0gZnVuY3Rpb24gKG8pIHtcclxuICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICAgICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgICAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fbWFrZVRlbXBsYXRlT2JqZWN0ID0gZnVuY3Rpb24gKGNvb2tlZCwgcmF3KSB7XHJcbiAgICAgICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgICAgICByZXR1cm4gY29va2VkO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG4gICAgfSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICAgICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2ltcG9ydFN0YXIgPSBmdW5jdGlvbiAobW9kKSB7XHJcbiAgICAgICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgICAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICAgICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgICAgIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG4gICAgX19pbXBvcnREZWZhdWx0ID0gZnVuY3Rpb24gKG1vZCkge1xyXG4gICAgICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgXCJkZWZhdWx0XCI6IG1vZCB9O1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gZnVuY3Rpb24gKHJlY2VpdmVyLCBwcml2YXRlTWFwKSB7XHJcbiAgICAgICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImF0dGVtcHRlZCB0byBnZXQgcHJpdmF0ZSBmaWVsZCBvbiBub24taW5zdGFuY2VcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwcml2YXRlTWFwLmdldChyZWNlaXZlcik7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQgPSBmdW5jdGlvbiAocmVjZWl2ZXIsIHByaXZhdGVNYXAsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImF0dGVtcHRlZCB0byBzZXQgcHJpdmF0ZSBmaWVsZCBvbiBub24taW5zdGFuY2VcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHByaXZhdGVNYXAuc2V0KHJlY2VpdmVyLCB2YWx1ZSk7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICBleHBvcnRlcihcIl9fZXh0ZW5kc1wiLCBfX2V4dGVuZHMpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2Fzc2lnblwiLCBfX2Fzc2lnbik7XHJcbiAgICBleHBvcnRlcihcIl9fcmVzdFwiLCBfX3Jlc3QpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2RlY29yYXRlXCIsIF9fZGVjb3JhdGUpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3BhcmFtXCIsIF9fcGFyYW0pO1xyXG4gICAgZXhwb3J0ZXIoXCJfX21ldGFkYXRhXCIsIF9fbWV0YWRhdGEpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2F3YWl0ZXJcIiwgX19hd2FpdGVyKTtcclxuICAgIGV4cG9ydGVyKFwiX19nZW5lcmF0b3JcIiwgX19nZW5lcmF0b3IpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2V4cG9ydFN0YXJcIiwgX19leHBvcnRTdGFyKTtcclxuICAgIGV4cG9ydGVyKFwiX19jcmVhdGVCaW5kaW5nXCIsIF9fY3JlYXRlQmluZGluZyk7XHJcbiAgICBleHBvcnRlcihcIl9fdmFsdWVzXCIsIF9fdmFsdWVzKTtcclxuICAgIGV4cG9ydGVyKFwiX19yZWFkXCIsIF9fcmVhZCk7XHJcbiAgICBleHBvcnRlcihcIl9fc3ByZWFkXCIsIF9fc3ByZWFkKTtcclxuICAgIGV4cG9ydGVyKFwiX19zcHJlYWRBcnJheXNcIiwgX19zcHJlYWRBcnJheXMpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2F3YWl0XCIsIF9fYXdhaXQpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2FzeW5jR2VuZXJhdG9yXCIsIF9fYXN5bmNHZW5lcmF0b3IpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2FzeW5jRGVsZWdhdG9yXCIsIF9fYXN5bmNEZWxlZ2F0b3IpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2FzeW5jVmFsdWVzXCIsIF9fYXN5bmNWYWx1ZXMpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX21ha2VUZW1wbGF0ZU9iamVjdFwiLCBfX21ha2VUZW1wbGF0ZU9iamVjdCk7XHJcbiAgICBleHBvcnRlcihcIl9faW1wb3J0U3RhclwiLCBfX2ltcG9ydFN0YXIpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2ltcG9ydERlZmF1bHRcIiwgX19pbXBvcnREZWZhdWx0KTtcclxuICAgIGV4cG9ydGVyKFwiX19jbGFzc1ByaXZhdGVGaWVsZEdldFwiLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KTtcclxuICAgIGV4cG9ydGVyKFwiX19jbGFzc1ByaXZhdGVGaWVsZFNldFwiLCBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KTtcclxufSk7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIG1peF8xID0gcmVxdWlyZShcIi4vbWl4XCIpO1xudmFyIGlzX2Z1bmN0aW9uXzEgPSByZXF1aXJlKFwiLi9pcy1mdW5jdGlvblwiKTtcbnZhciBhdWdtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgYXJnc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICB2YXIgYyA9IGFyZ3NbMF07XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBvYmogPSBhcmdzW2ldO1xuICAgICAgICBpZiAoaXNfZnVuY3Rpb25fMS5kZWZhdWx0KG9iaikpIHtcbiAgICAgICAgICAgIG9iaiA9IG9iai5wcm90b3R5cGU7XG4gICAgICAgIH1cbiAgICAgICAgbWl4XzEuZGVmYXVsdChjLnByb3RvdHlwZSwgb2JqKTtcbiAgICB9XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gYXVnbWVudDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1Z21lbnQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vKipcbiAqIGstdiDlrZjlgqhcbiAqL1xudmFyIGRlZmF1bHRfMSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBkZWZhdWx0XzEoKSB7XG4gICAgICAgIHRoaXMubWFwID0ge307XG4gICAgfVxuICAgIGRlZmF1bHRfMS5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXBba2V5XSAhPT0gdW5kZWZpbmVkO1xuICAgIH07XG4gICAgZGVmYXVsdF8xLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5LCBkZWYpIHtcbiAgICAgICAgdmFyIHYgPSB0aGlzLm1hcFtrZXldO1xuICAgICAgICByZXR1cm4gdiA9PT0gdW5kZWZpbmVkID8gZGVmIDogdjtcbiAgICB9O1xuICAgIGRlZmF1bHRfMS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5tYXBba2V5XSA9IHZhbHVlO1xuICAgIH07XG4gICAgZGVmYXVsdF8xLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5tYXAgPSB7fTtcbiAgICB9O1xuICAgIGRlZmF1bHRfMS5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBkZWxldGUgdGhpcy5tYXBba2V5XTtcbiAgICB9O1xuICAgIGRlZmF1bHRfMS5wcm90b3R5cGUuc2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMubWFwKS5sZW5ndGg7XG4gICAgfTtcbiAgICByZXR1cm4gZGVmYXVsdF8xO1xufSgpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IGRlZmF1bHRfMTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNhY2hlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGNsYW1wID0gZnVuY3Rpb24gKGEsIG1pbiwgbWF4KSB7XG4gICAgaWYgKGEgPCBtaW4pIHtcbiAgICAgICAgcmV0dXJuIG1pbjtcbiAgICB9XG4gICAgZWxzZSBpZiAoYSA+IG1heCkge1xuICAgICAgICByZXR1cm4gbWF4O1xuICAgIH1cbiAgICByZXR1cm4gYTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBjbGFtcDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsYW1wLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZnVuY3Rpb24gY2FuY2VsQW5pbWF0aW9uRnJhbWUoaGFuZGxlcikge1xuICAgIHZhciBtZXRob2QgPSB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgd2luZG93LndlYmtpdENhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgd2luZG93Lm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgd2luZG93Lm1zQ2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgY2xlYXJUaW1lb3V0O1xuICAgIG1ldGhvZChoYW5kbGVyKTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGNhbmNlbEFuaW1hdGlvbkZyYW1lO1xuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xlYXItYW5pbWF0aW9uLWZyYW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBjbG9uZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIHZhciByc3Q7XG4gICAgaWYgKGlzX2FycmF5XzEuZGVmYXVsdChvYmopKSB7XG4gICAgICAgIHJzdCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqW2ldID09PSAnb2JqZWN0JyAmJiBvYmpbaV0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJzdFtpXSA9IGNsb25lKG9ialtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByc3RbaV0gPSBvYmpbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJzdCA9IHt9O1xuICAgICAgICBmb3IgKHZhciBrIGluIG9iaikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmpba10gPT09ICdvYmplY3QnICYmIG9ialtrXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcnN0W2tdID0gY2xvbmUob2JqW2tdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJzdFtrXSA9IG9ialtrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcnN0O1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGNsb25lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xvbmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXktbGlrZVwiKTtcbnZhciBjb250YWlucyA9IGZ1bmN0aW9uIChhcnIsIHZhbHVlKSB7XG4gICAgaWYgKCFpc19hcnJheV9saWtlXzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGFyci5pbmRleE9mKHZhbHVlKSA+IC0xO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGNvbnRhaW5zO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udGFpbnMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICB2YXIgdGltZW91dDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29udGV4dCA9IHRoaXMsIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIHZhciBsYXRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIHtcbiAgICAgICAgICAgICAgICBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2YXIgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhdGltZW91dDtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCk7XG4gICAgICAgIGlmIChjYWxsTm93KSB7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGRlYm91bmNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVib3VuY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5XCIpO1xudmFyIGlzX3BsYWluX29iamVjdF8xID0gcmVxdWlyZShcIi4vaXMtcGxhaW4tb2JqZWN0XCIpO1xudmFyIE1BWF9NSVhfTEVWRUwgPSA1O1xuZnVuY3Rpb24gX2RlZXBNaXgoZGlzdCwgc3JjLCBsZXZlbCwgbWF4TGV2ZWwpIHtcbiAgICBsZXZlbCA9IGxldmVsIHx8IDA7XG4gICAgbWF4TGV2ZWwgPSBtYXhMZXZlbCB8fCBNQVhfTUlYX0xFVkVMO1xuICAgIGZvciAodmFyIGtleSBpbiBzcmMpIHtcbiAgICAgICAgaWYgKHNyYy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBzcmNba2V5XTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiBpc19wbGFpbl9vYmplY3RfMS5kZWZhdWx0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmICghaXNfcGxhaW5fb2JqZWN0XzEuZGVmYXVsdChkaXN0W2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3Rba2V5XSA9IHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobGV2ZWwgPCBtYXhMZXZlbCkge1xuICAgICAgICAgICAgICAgICAgICBfZGVlcE1peChkaXN0W2tleV0sIHZhbHVlLCBsZXZlbCArIDEsIG1heExldmVsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3Rba2V5XSA9IHNyY1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzX2FycmF5XzEuZGVmYXVsdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBkaXN0W2tleV0gPSBbXTtcbiAgICAgICAgICAgICAgICBkaXN0W2tleV0gPSBkaXN0W2tleV0uY29uY2F0KHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkaXN0W2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIHRvZG8g6YeN5YaZXG52YXIgZGVlcE1peCA9IGZ1bmN0aW9uIChyc3QpIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIGFyZ3NbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBfZGVlcE1peChyc3QsIGFyZ3NbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gcnN0O1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGRlZXBNaXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWVwLW1peC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBmaWx0ZXJfMSA9IHJlcXVpcmUoXCIuL2ZpbHRlclwiKTtcbnZhciBjb250YWluc18xID0gcmVxdWlyZShcIi4vY29udGFpbnNcIik7XG4vKipcbiAqIEZsYXR0ZW5zIGBhcnJheWAgYSBzaW5nbGUgbGV2ZWwgZGVlcC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnIgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICogQHJldHVybiB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICogZGlmZmVyZW5jZShbMiwgMV0sIFsyLCAzXSk7ICAvLyA9PiBbMV1cbiAqL1xudmFyIGRpZmZlcmVuY2UgPSBmdW5jdGlvbiAoYXJyLCB2YWx1ZXMpIHtcbiAgICBpZiAodmFsdWVzID09PSB2b2lkIDApIHsgdmFsdWVzID0gW107IH1cbiAgICByZXR1cm4gZmlsdGVyXzEuZGVmYXVsdChhcnIsIGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gIWNvbnRhaW5zXzEuZGVmYXVsdCh2YWx1ZXMsIHZhbHVlKTsgfSk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gZGlmZmVyZW5jZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpZmZlcmVuY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5XCIpO1xudmFyIGlzX29iamVjdF8xID0gcmVxdWlyZShcIi4vaXMtb2JqZWN0XCIpO1xuZnVuY3Rpb24gZWFjaChlbGVtZW50cywgZnVuYykge1xuICAgIGlmICghZWxlbWVudHMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcnN0O1xuICAgIGlmIChpc19hcnJheV8xLmRlZmF1bHQoZWxlbWVudHMpKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgcnN0ID0gZnVuYyhlbGVtZW50c1tpXSwgaSk7XG4gICAgICAgICAgICBpZiAocnN0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzX29iamVjdF8xLmRlZmF1bHQoZWxlbWVudHMpKSB7XG4gICAgICAgIGZvciAodmFyIGsgaW4gZWxlbWVudHMpIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50cy5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICAgICAgICAgIHJzdCA9IGZ1bmMoZWxlbWVudHNba10sIGspO1xuICAgICAgICAgICAgICAgIGlmIChyc3QgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGVhY2g7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lYWNoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBpc19zdHJpbmdfMSA9IHJlcXVpcmUoXCIuL2lzLXN0cmluZ1wiKTtcbmZ1bmN0aW9uIGVuZHNXaXRoKGFyciwgZSkge1xuICAgIHJldHVybiAoaXNfYXJyYXlfMS5kZWZhdWx0KGFycikgfHwgaXNfc3RyaW5nXzEuZGVmYXVsdChhcnIpKSA/IGFyclthcnIubGVuZ3RoIC0gMV0gPT09IGUgOiBmYWxzZTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGVuZHNXaXRoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZW5kcy13aXRoLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDlj6ropoHmnInkuIDkuKrkuI3mu6HotrPmnaHku7blsLHov5Tlm54gZmFsc2VcbiAqIEBwYXJhbSBhcnJcbiAqIEBwYXJhbSBmdW5jXG4gKi9cbnZhciBldmVyeSA9IGZ1bmN0aW9uIChhcnIsIGZ1bmMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWZ1bmMoYXJyW2ldLCBpKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gZXZlcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVyeS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBtaXhfMSA9IHJlcXVpcmUoXCIuL21peFwiKTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG52YXIgZXh0ZW5kID0gZnVuY3Rpb24gKHN1YmNsYXNzLCBzdXBlcmNsYXNzLCBvdmVycmlkZXMsIHN0YXRpY092ZXJyaWRlcykge1xuICAgIC8vIOWmguaenOWPquaPkOS+m+eItuexu+aehOmAoOWHveaVsO+8jOWImeiHquWKqOeUn+aIkOWtkOexu+aehOmAoOWHveaVsFxuICAgIGlmICghaXNfZnVuY3Rpb25fMS5kZWZhdWx0KHN1cGVyY2xhc3MpKSB7XG4gICAgICAgIG92ZXJyaWRlcyA9IHN1cGVyY2xhc3M7XG4gICAgICAgIHN1cGVyY2xhc3MgPSBzdWJjbGFzcztcbiAgICAgICAgc3ViY2xhc3MgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgfVxuICAgIHZhciBjcmVhdGUgPSBPYmplY3QuY3JlYXRlID9cbiAgICAgICAgZnVuY3Rpb24gKHByb3RvLCBjKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShwcm90bywge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBjXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gOlxuICAgICAgICBmdW5jdGlvbiAocHJvdG8sIGMpIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIFRtcCgpIHsgfVxuICAgICAgICAgICAgVG1wLnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgICAgICAgdmFyIG8gPSBuZXcgVG1wKCk7XG4gICAgICAgICAgICBvLmNvbnN0cnVjdG9yID0gYztcbiAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICB9O1xuICAgIHZhciBzdXBlck9iaiA9IGNyZWF0ZShzdXBlcmNsYXNzLnByb3RvdHlwZSwgc3ViY2xhc3MpOyAvLyBuZXcgc3VwZXJjbGFzcygpLC8v5a6e5L6L5YyW54i257G75L2c5Li65a2Q57G755qEcHJvdG90eXBlXG4gICAgc3ViY2xhc3MucHJvdG90eXBlID0gbWl4XzEuZGVmYXVsdChzdXBlck9iaiwgc3ViY2xhc3MucHJvdG90eXBlKTsgLy8g5oyH5a6a5a2Q57G755qEcHJvdG90eXBlXG4gICAgc3ViY2xhc3Muc3VwZXJjbGFzcyA9IGNyZWF0ZShzdXBlcmNsYXNzLnByb3RvdHlwZSwgc3VwZXJjbGFzcyk7XG4gICAgbWl4XzEuZGVmYXVsdChzdXBlck9iaiwgb3ZlcnJpZGVzKTtcbiAgICBtaXhfMS5kZWZhdWx0KHN1YmNsYXNzLCBzdGF0aWNPdmVycmlkZXMpO1xuICAgIHJldHVybiBzdWJjbGFzcztcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBleHRlbmQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1leHRlbmQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXktbGlrZVwiKTtcbnZhciBmaWx0ZXIgPSBmdW5jdGlvbiAoYXJyLCBmdW5jKSB7XG4gICAgaWYgKCFpc19hcnJheV9saWtlXzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgYXJyLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJbaW5kZXhdO1xuICAgICAgICBpZiAoZnVuYyh2YWx1ZSwgaW5kZXgpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBmaWx0ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maWx0ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5mdW5jdGlvbiBmaW5kSW5kZXgoYXJyLCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgIGlmIChmcm9tSW5kZXggPT09IHZvaWQgMCkgeyBmcm9tSW5kZXggPSAwOyB9XG4gICAgZm9yICh2YXIgaSA9IGZyb21JbmRleDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocHJlZGljYXRlKGFycltpXSwgaSkpIHtcbiAgICAgICAgICAgIC8vIOaJvuWIsOe7iOatouW+queOr1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZmluZEluZGV4O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmluZC1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG52YXIgaXNfbWF0Y2hfMSA9IHJlcXVpcmUoXCIuL2lzLW1hdGNoXCIpO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBpc19wbGFpbl9vYmplY3RfMSA9IHJlcXVpcmUoXCIuL2lzLXBsYWluLW9iamVjdFwiKTtcbmZ1bmN0aW9uIGZpbmQoYXJyLCBwcmVkaWNhdGUpIHtcbiAgICBpZiAoIWlzX2FycmF5XzEuZGVmYXVsdChhcnIpKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB2YXIgX3ByZWRpY2F0ZTtcbiAgICBpZiAoaXNfZnVuY3Rpb25fMS5kZWZhdWx0KHByZWRpY2F0ZSkpIHtcbiAgICAgICAgX3ByZWRpY2F0ZSA9IHByZWRpY2F0ZTtcbiAgICB9XG4gICAgaWYgKGlzX3BsYWluX29iamVjdF8xLmRlZmF1bHQocHJlZGljYXRlKSkge1xuICAgICAgICBfcHJlZGljYXRlID0gZnVuY3Rpb24gKGEpIHsgcmV0dXJuIGlzX21hdGNoXzEuZGVmYXVsdChhLCBwcmVkaWNhdGUpOyB9O1xuICAgIH1cbiAgICBpZiAoX3ByZWRpY2F0ZSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKF9wcmVkaWNhdGUoYXJyW2ldKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcnJbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBmaW5kO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmluZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbnZhciBpc19hcnJheV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXlcIik7XG52YXIgZmlyc3RWYWx1ZSA9IGZ1bmN0aW9uIChkYXRhLCBuYW1lKSB7XG4gICAgdmFyIHJzdCA9IG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBvYmogPSBkYXRhW2ldO1xuICAgICAgICB2YXIgdmFsdWUgPSBvYmpbbmFtZV07XG4gICAgICAgIGlmICghaXNfbmlsXzEuZGVmYXVsdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmIChpc19hcnJheV8xLmRlZmF1bHQodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcnN0ID0gdmFsdWVbMF07IC8vIHRvZG8g6L+Z6YeM5piv5ZCm5bqU6K+l5L2/55So6YCS5b2S77yM6LCD55SoIGZpcnN0VmFsdWUgQOe7neS6kVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcnN0ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcnN0O1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGZpcnN0VmFsdWU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maXJzdC12YWx1ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBmaXhlZEJhc2UgPSBmdW5jdGlvbiAodiwgYmFzZSkge1xuICAgIHZhciBzdHIgPSBiYXNlLnRvU3RyaW5nKCk7XG4gICAgdmFyIGluZGV4ID0gc3RyLmluZGV4T2YoJy4nKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHYpO1xuICAgIH1cbiAgICB2YXIgbGVuZ3RoID0gc3RyLnN1YnN0cihpbmRleCArIDEpLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoID4gMjApIHtcbiAgICAgICAgbGVuZ3RoID0gMjA7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZUZsb2F0KHYudG9GaXhlZChsZW5ndGgpKTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBmaXhlZEJhc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maXhlZC1iYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbi8qKlxuICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyciBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAqIEBwYXJhbSB7QXJyYXl9IHJlc3VsdCBUaGUgYXJyYXkgdG8gcmV0dXJuLlxuICogQHJldHVybiB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZsYXR0ZW5EZWVwKFsxLCBbMiwgWzMsIFs0XV0sIDVdXSk7ICAvLyA9PiBbMSwgMiwgMywgNCwgNV1cbiAqL1xudmFyIGZsYXR0ZW5EZWVwID0gZnVuY3Rpb24gKGFyciwgcmVzdWx0KSB7XG4gICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSB7IHJlc3VsdCA9IFtdOyB9XG4gICAgaWYgKCFpc19hcnJheV8xLmRlZmF1bHQoYXJyKSkge1xuICAgICAgICByZXN1bHQucHVzaChhcnIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGZsYXR0ZW5EZWVwKGFycltpXSwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGZsYXR0ZW5EZWVwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmxhdHRlbi1kZWVwLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbi8qKlxuICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyciBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAqIEByZXR1cm4ge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBmbGF0dGVuKFsxLCBbMiwgWzMsIFs0XV0sIDVdXSk7ICAvLyA9PiBbMSwgMiwgWzMsIFs0XV0sIDVdXG4gKi9cbnZhciBmbGF0dGVuID0gZnVuY3Rpb24gKGFycikge1xuICAgIGlmICghaXNfYXJyYXlfMS5kZWZhdWx0KGFycikpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICB2YXIgcnN0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcnN0ID0gcnN0LmNvbmNhdChhcnJbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gcnN0O1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGZsYXR0ZW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mbGF0dGVuLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGVhY2hfMSA9IHJlcXVpcmUoXCIuL2VhY2hcIik7XG5leHBvcnRzLmRlZmF1bHQgPSBlYWNoXzEuZGVmYXVsdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZvci1pbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19hcnJheV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXlcIik7XG52YXIgZ2V0UmFuZ2UgPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gICAgLy8g5a2Y5ZyoIE5hTiDml7bvvIxtaW4sbWF4IOWIpOWumuS8muWHuumXrumimFxuICAgIHZhciBmaWx0ZXJWYWx1ZXMgPSB2YWx1ZXMuZmlsdGVyKGZ1bmN0aW9uICh2KSB7IHJldHVybiAhaXNOYU4odik7IH0pO1xuICAgIGlmICghZmlsdGVyVmFsdWVzLmxlbmd0aCkgeyAvLyDlpoLmnpzmsqHmnInmlbDlgLzliJnnm7TmjqXov5Tlm54wXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDAsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpc19hcnJheV8xLmRlZmF1bHQodmFsdWVzWzBdKSkge1xuICAgICAgICB2YXIgdG1wID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0bXAgPSB0bXAuY29uY2F0KHZhbHVlc1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgZmlsdGVyVmFsdWVzID0gdG1wO1xuICAgIH1cbiAgICB2YXIgbWF4ID0gTWF0aC5tYXguYXBwbHkobnVsbCwgZmlsdGVyVmFsdWVzKTtcbiAgICB2YXIgbWluID0gTWF0aC5taW4uYXBwbHkobnVsbCwgZmlsdGVyVmFsdWVzKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW46IG1pbixcbiAgICAgICAgbWF4OiBtYXgsXG4gICAgfTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBnZXRSYW5nZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1yYW5nZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xudmFyIGdldFR5cGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWx1ZSkucmVwbGFjZSgvXlxcW29iamVjdCAvLCAnJykucmVwbGFjZSgvXSQvLCAnJyk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0VHlwZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC10eXBlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDojrflj5blsIHoo4XnmoTkuovku7ZcbiAqIEBwcm90ZWN0ZWRcbiAqIEBwYXJhbSAge09iamVjdH0gb2JqICAg5a+56LGhXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGFjdGlvbiDkuovku7blkI3np7BcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSAgICAgICAg6L+U5Zue5LqL5Lu25aSE55CG5Ye95pWwXG4gKi9cbmZ1bmN0aW9uIGdldFdyYXBCZWhhdmlvcihvYmosIGFjdGlvbikge1xuICAgIHJldHVybiBvYmpbJ193cmFwXycgKyBhY3Rpb25dO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0V3JhcEJlaGF2aW9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXdyYXAtYmVoYXZpb3IuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfc3RyaW5nXzEgPSByZXF1aXJlKFwiLi9pcy1zdHJpbmdcIik7XG4vKipcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kZXZlbG9waXQvZGx2L2Jsb2IvbWFzdGVyL2luZGV4LmpzXG4gKiBAcGFyYW0gb2JqXG4gKiBAcGFyYW0ga2V5XG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlXG4gKi9cbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAob2JqLCBrZXksIGRlZmF1bHRWYWx1ZSkge1xuICAgIHZhciBwID0gMDtcbiAgICB2YXIga2V5QXJyID0gaXNfc3RyaW5nXzEuZGVmYXVsdChrZXkpID8ga2V5LnNwbGl0KCcuJykgOiBrZXk7XG4gICAgd2hpbGUgKG9iaiAmJiBwIDwga2V5QXJyLmxlbmd0aCkge1xuICAgICAgICBvYmogPSBvYmpba2V5QXJyW3ArK11dO1xuICAgIH1cbiAgICByZXR1cm4gKG9iaiA9PT0gdW5kZWZpbmVkIHx8IHAgPCBrZXlBcnIubGVuZ3RoKSA/IGRlZmF1bHRWYWx1ZSA6IG9iajtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gZ3JvdXBCeShkYXRhLCBjb25kaXRpb24pIHtcbiAgICBpZiAoIWNvbmRpdGlvbiB8fCAhaXNfYXJyYXlfMS5kZWZhdWx0KGRhdGEpKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIC8vIOWFvOWuueaWueazleWSjCDlrZfnrKbkuLLnmoTlhpnms5VcbiAgICB2YXIgcHJlZGljYXRlID0gaXNfZnVuY3Rpb25fMS5kZWZhdWx0KGNvbmRpdGlvbikgPyBjb25kaXRpb24gOiBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbVtjb25kaXRpb25dOyB9O1xuICAgIHZhciBrZXk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBpdGVtID0gZGF0YVtpXTtcbiAgICAgICAga2V5ID0gcHJlZGljYXRlKGl0ZW0pO1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgICAgIHJlc3VsdFtrZXldLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IFtpdGVtXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZ3JvdXBCeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdyb3VwLWJ5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG52YXIgZ3JvdXBfYnlfMSA9IHJlcXVpcmUoXCIuL2dyb3VwLWJ5XCIpO1xudmFyIGdyb3VwVG9NYXAgPSBmdW5jdGlvbiAoZGF0YSwgY29uZGl0aW9uKSB7XG4gICAgaWYgKCFjb25kaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIDA6IGRhdGEsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmICghaXNfZnVuY3Rpb25fMS5kZWZhdWx0KGNvbmRpdGlvbikpIHtcbiAgICAgICAgdmFyIHBhcmFtc0NvbmRpdGlvbl8xID0gaXNfYXJyYXlfMS5kZWZhdWx0KGNvbmRpdGlvbikgPyBjb25kaXRpb24gOiBjb25kaXRpb24ucmVwbGFjZSgvXFxzKy9nLCAnJykuc3BsaXQoJyonKTtcbiAgICAgICAgY29uZGl0aW9uID0gZnVuY3Rpb24gKHJvdykge1xuICAgICAgICAgICAgdmFyIHVuaXF1ZSA9ICdfJzsgLy8g6YG/5YWN5Ye6546w5pWw5a2X5L2c5Li6S2V555qE5oOF5Ya177yM5Lya6L+b6KGM5oyJ54Wn5pWw5a2X55qE5o6S5bqPXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHBhcmFtc0NvbmRpdGlvbl8xLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgICAgIHVuaXF1ZSArPSByb3dbcGFyYW1zQ29uZGl0aW9uXzFbaV1dICYmIHJvd1twYXJhbXNDb25kaXRpb25fMVtpXV0udG9TdHJpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB1bmlxdWU7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHZhciBncm91cHMgPSBncm91cF9ieV8xLmRlZmF1bHQoZGF0YSwgY29uZGl0aW9uKTtcbiAgICByZXR1cm4gZ3JvdXBzO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGdyb3VwVG9NYXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncm91cC10by1tYXAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZ3JvdXBfdG9fbWFwXzEgPSByZXF1aXJlKFwiLi9ncm91cC10by1tYXBcIik7XG5leHBvcnRzLmRlZmF1bHQgPSAoZnVuY3Rpb24gKGRhdGEsIGNvbmRpdGlvbikge1xuICAgIGlmICghY29uZGl0aW9uKSB7XG4gICAgICAgIC8vIOayoeacieadoeS7tu+8jOWImeiHqui6q+aUueaIkOaVsOe7hFxuICAgICAgICByZXR1cm4gW2RhdGFdO1xuICAgIH1cbiAgICB2YXIgZ3JvdXBzID0gZ3JvdXBfdG9fbWFwXzEuZGVmYXVsdChkYXRhLCBjb25kaXRpb24pO1xuICAgIHZhciBhcnJheSA9IFtdO1xuICAgIGZvciAodmFyIGkgaW4gZ3JvdXBzKSB7XG4gICAgICAgIGFycmF5LnB1c2goZ3JvdXBzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ncm91cC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBoYXNfMSA9IHJlcXVpcmUoXCIuL2hhc1wiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IGhhc18xLmRlZmF1bHQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1oYXMta2V5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGNvbnRhaW5zXzEgPSByZXF1aXJlKFwiLi9jb250YWluc1wiKTtcbnZhciB2YWx1ZXNfMSA9IHJlcXVpcmUoXCIuL3ZhbHVlc1wiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAob2JqLCB2YWx1ZSkgeyByZXR1cm4gY29udGFpbnNfMS5kZWZhdWx0KHZhbHVlc18xLmRlZmF1bHQob2JqKSwgdmFsdWUpOyB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhhcy12YWx1ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAob2JqLCBrZXkpIHsgcmV0dXJuIG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpOyB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhhcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19hcnJheV9saWtlXzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheS1saWtlXCIpO1xuZnVuY3Rpb24gaGVhZChvKSB7XG4gICAgaWYgKGlzX2FycmF5X2xpa2VfMS5kZWZhdWx0KG8pKSB7XG4gICAgICAgIHJldHVybiBvWzBdO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gaGVhZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhlYWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRlZmF1bHQgPSAoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHY7IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWRlbnRpdHkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXktbGlrZVwiKTtcbnZhciBpbmRleE9mID0gZnVuY3Rpb24gKGFyciwgb2JqKSB7XG4gICAgaWYgKCFpc19hcnJheV9saWtlXzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgdmFyIG0gPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZjtcbiAgICBpZiAobSkge1xuICAgICAgICByZXR1cm4gbS5jYWxsKGFyciwgb2JqKTtcbiAgICB9XG4gICAgdmFyIGluZGV4ID0gLTE7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGFycltpXSA9PT0gb2JqKSB7XG4gICAgICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaW5kZXg7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaW5kZXhPZjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LW9mLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLy8gYXJyYXlcbnZhciBjb250YWluc18xID0gcmVxdWlyZShcIi4vY29udGFpbnNcIik7XG5leHBvcnRzLmNvbnRhaW5zID0gY29udGFpbnNfMS5kZWZhdWx0O1xuZXhwb3J0cy5pbmNsdWRlcyA9IGNvbnRhaW5zXzEuZGVmYXVsdDtcbnZhciBkaWZmZXJlbmNlXzEgPSByZXF1aXJlKFwiLi9kaWZmZXJlbmNlXCIpO1xuZXhwb3J0cy5kaWZmZXJlbmNlID0gZGlmZmVyZW5jZV8xLmRlZmF1bHQ7XG52YXIgZmluZF8xID0gcmVxdWlyZShcIi4vZmluZFwiKTtcbmV4cG9ydHMuZmluZCA9IGZpbmRfMS5kZWZhdWx0O1xudmFyIGZpbmRfaW5kZXhfMSA9IHJlcXVpcmUoXCIuL2ZpbmQtaW5kZXhcIik7XG5leHBvcnRzLmZpbmRJbmRleCA9IGZpbmRfaW5kZXhfMS5kZWZhdWx0O1xudmFyIGZpcnN0X3ZhbHVlXzEgPSByZXF1aXJlKFwiLi9maXJzdC12YWx1ZVwiKTtcbmV4cG9ydHMuZmlyc3RWYWx1ZSA9IGZpcnN0X3ZhbHVlXzEuZGVmYXVsdDtcbnZhciBmbGF0dGVuXzEgPSByZXF1aXJlKFwiLi9mbGF0dGVuXCIpO1xuZXhwb3J0cy5mbGF0dGVuID0gZmxhdHRlbl8xLmRlZmF1bHQ7XG52YXIgZmxhdHRlbl9kZWVwXzEgPSByZXF1aXJlKFwiLi9mbGF0dGVuLWRlZXBcIik7XG5leHBvcnRzLmZsYXR0ZW5EZWVwID0gZmxhdHRlbl9kZWVwXzEuZGVmYXVsdDtcbnZhciBnZXRfcmFuZ2VfMSA9IHJlcXVpcmUoXCIuL2dldC1yYW5nZVwiKTtcbmV4cG9ydHMuZ2V0UmFuZ2UgPSBnZXRfcmFuZ2VfMS5kZWZhdWx0O1xudmFyIHB1bGxfMSA9IHJlcXVpcmUoXCIuL3B1bGxcIik7XG5leHBvcnRzLnB1bGwgPSBwdWxsXzEuZGVmYXVsdDtcbnZhciBwdWxsX2F0XzEgPSByZXF1aXJlKFwiLi9wdWxsLWF0XCIpO1xuZXhwb3J0cy5wdWxsQXQgPSBwdWxsX2F0XzEuZGVmYXVsdDtcbnZhciByZWR1Y2VfMSA9IHJlcXVpcmUoXCIuL3JlZHVjZVwiKTtcbmV4cG9ydHMucmVkdWNlID0gcmVkdWNlXzEuZGVmYXVsdDtcbnZhciByZW1vdmVfMSA9IHJlcXVpcmUoXCIuL3JlbW92ZVwiKTtcbmV4cG9ydHMucmVtb3ZlID0gcmVtb3ZlXzEuZGVmYXVsdDtcbnZhciBzb3J0X2J5XzEgPSByZXF1aXJlKFwiLi9zb3J0LWJ5XCIpO1xuZXhwb3J0cy5zb3J0QnkgPSBzb3J0X2J5XzEuZGVmYXVsdDtcbnZhciB1bmlvbl8xID0gcmVxdWlyZShcIi4vdW5pb25cIik7XG5leHBvcnRzLnVuaW9uID0gdW5pb25fMS5kZWZhdWx0O1xudmFyIHVuaXFfMSA9IHJlcXVpcmUoXCIuL3VuaXFcIik7XG5leHBvcnRzLnVuaXEgPSB1bmlxXzEuZGVmYXVsdDtcbnZhciB2YWx1ZXNfb2Zfa2V5XzEgPSByZXF1aXJlKFwiLi92YWx1ZXMtb2Yta2V5XCIpO1xuZXhwb3J0cy52YWx1ZXNPZktleSA9IHZhbHVlc19vZl9rZXlfMS5kZWZhdWx0O1xudmFyIGhlYWRfMSA9IHJlcXVpcmUoXCIuL2hlYWRcIik7XG5leHBvcnRzLmhlYWQgPSBoZWFkXzEuZGVmYXVsdDtcbnZhciBsYXN0XzEgPSByZXF1aXJlKFwiLi9sYXN0XCIpO1xuZXhwb3J0cy5sYXN0ID0gbGFzdF8xLmRlZmF1bHQ7XG52YXIgc3RhcnRzX3dpdGhfMSA9IHJlcXVpcmUoXCIuL3N0YXJ0cy13aXRoXCIpO1xuZXhwb3J0cy5zdGFydHNXaXRoID0gc3RhcnRzX3dpdGhfMS5kZWZhdWx0O1xudmFyIGVuZHNfd2l0aF8xID0gcmVxdWlyZShcIi4vZW5kcy13aXRoXCIpO1xuZXhwb3J0cy5lbmRzV2l0aCA9IGVuZHNfd2l0aF8xLmRlZmF1bHQ7XG52YXIgZmlsdGVyXzEgPSByZXF1aXJlKFwiLi9maWx0ZXJcIik7XG5leHBvcnRzLmZpbHRlciA9IGZpbHRlcl8xLmRlZmF1bHQ7XG52YXIgZXZlcnlfMSA9IHJlcXVpcmUoXCIuL2V2ZXJ5XCIpO1xuZXhwb3J0cy5ldmVyeSA9IGV2ZXJ5XzEuZGVmYXVsdDtcbnZhciBzb21lXzEgPSByZXF1aXJlKFwiLi9zb21lXCIpO1xuZXhwb3J0cy5zb21lID0gc29tZV8xLmRlZmF1bHQ7XG52YXIgZ3JvdXBfMSA9IHJlcXVpcmUoXCIuL2dyb3VwXCIpO1xuZXhwb3J0cy5ncm91cCA9IGdyb3VwXzEuZGVmYXVsdDtcbnZhciBncm91cF9ieV8xID0gcmVxdWlyZShcIi4vZ3JvdXAtYnlcIik7XG5leHBvcnRzLmdyb3VwQnkgPSBncm91cF9ieV8xLmRlZmF1bHQ7XG52YXIgZ3JvdXBfdG9fbWFwXzEgPSByZXF1aXJlKFwiLi9ncm91cC10by1tYXBcIik7XG5leHBvcnRzLmdyb3VwVG9NYXAgPSBncm91cF90b19tYXBfMS5kZWZhdWx0O1xuLy8gZXZlbnRcbnZhciBnZXRfd3JhcF9iZWhhdmlvcl8xID0gcmVxdWlyZShcIi4vZ2V0LXdyYXAtYmVoYXZpb3JcIik7XG5leHBvcnRzLmdldFdyYXBCZWhhdmlvciA9IGdldF93cmFwX2JlaGF2aW9yXzEuZGVmYXVsdDtcbnZhciB3cmFwX2JlaGF2aW9yXzEgPSByZXF1aXJlKFwiLi93cmFwLWJlaGF2aW9yXCIpO1xuZXhwb3J0cy53cmFwQmVoYXZpb3IgPSB3cmFwX2JlaGF2aW9yXzEuZGVmYXVsdDtcbi8vIGZvcm1hdFxudmFyIG51bWJlcjJjb2xvcl8xID0gcmVxdWlyZShcIi4vbnVtYmVyMmNvbG9yXCIpO1xuZXhwb3J0cy5udW1iZXIyY29sb3IgPSBudW1iZXIyY29sb3JfMS5kZWZhdWx0O1xudmFyIHBhcnNlX3JhZGl1c18xID0gcmVxdWlyZShcIi4vcGFyc2UtcmFkaXVzXCIpO1xuZXhwb3J0cy5wYXJzZVJhZGl1cyA9IHBhcnNlX3JhZGl1c18xLmRlZmF1bHQ7XG4vLyBtYXRoXG52YXIgY2xhbXBfMSA9IHJlcXVpcmUoXCIuL2NsYW1wXCIpO1xuZXhwb3J0cy5jbGFtcCA9IGNsYW1wXzEuZGVmYXVsdDtcbnZhciBmaXhlZF9iYXNlXzEgPSByZXF1aXJlKFwiLi9maXhlZC1iYXNlXCIpO1xuZXhwb3J0cy5maXhlZEJhc2UgPSBmaXhlZF9iYXNlXzEuZGVmYXVsdDtcbnZhciBpc19kZWNpbWFsXzEgPSByZXF1aXJlKFwiLi9pcy1kZWNpbWFsXCIpO1xuZXhwb3J0cy5pc0RlY2ltYWwgPSBpc19kZWNpbWFsXzEuZGVmYXVsdDtcbnZhciBpc19ldmVuXzEgPSByZXF1aXJlKFwiLi9pcy1ldmVuXCIpO1xuZXhwb3J0cy5pc0V2ZW4gPSBpc19ldmVuXzEuZGVmYXVsdDtcbnZhciBpc19pbnRlZ2VyXzEgPSByZXF1aXJlKFwiLi9pcy1pbnRlZ2VyXCIpO1xuZXhwb3J0cy5pc0ludGVnZXIgPSBpc19pbnRlZ2VyXzEuZGVmYXVsdDtcbnZhciBpc19uZWdhdGl2ZV8xID0gcmVxdWlyZShcIi4vaXMtbmVnYXRpdmVcIik7XG5leHBvcnRzLmlzTmVnYXRpdmUgPSBpc19uZWdhdGl2ZV8xLmRlZmF1bHQ7XG52YXIgaXNfbnVtYmVyX2VxdWFsXzEgPSByZXF1aXJlKFwiLi9pcy1udW1iZXItZXF1YWxcIik7XG5leHBvcnRzLmlzTnVtYmVyRXF1YWwgPSBpc19udW1iZXJfZXF1YWxfMS5kZWZhdWx0O1xudmFyIGlzX29kZF8xID0gcmVxdWlyZShcIi4vaXMtb2RkXCIpO1xuZXhwb3J0cy5pc09kZCA9IGlzX29kZF8xLmRlZmF1bHQ7XG52YXIgaXNfcG9zaXRpdmVfMSA9IHJlcXVpcmUoXCIuL2lzLXBvc2l0aXZlXCIpO1xuZXhwb3J0cy5pc1Bvc2l0aXZlID0gaXNfcG9zaXRpdmVfMS5kZWZhdWx0O1xudmFyIG1heF9ieV8xID0gcmVxdWlyZShcIi4vbWF4LWJ5XCIpO1xuZXhwb3J0cy5tYXhCeSA9IG1heF9ieV8xLmRlZmF1bHQ7XG52YXIgbWluX2J5XzEgPSByZXF1aXJlKFwiLi9taW4tYnlcIik7XG5leHBvcnRzLm1pbkJ5ID0gbWluX2J5XzEuZGVmYXVsdDtcbnZhciBtb2RfMSA9IHJlcXVpcmUoXCIuL21vZFwiKTtcbmV4cG9ydHMubW9kID0gbW9kXzEuZGVmYXVsdDtcbnZhciB0b19kZWdyZWVfMSA9IHJlcXVpcmUoXCIuL3RvLWRlZ3JlZVwiKTtcbmV4cG9ydHMudG9EZWdyZWUgPSB0b19kZWdyZWVfMS5kZWZhdWx0O1xudmFyIHRvX2ludGVnZXJfMSA9IHJlcXVpcmUoXCIuL3RvLWludGVnZXJcIik7XG5leHBvcnRzLnRvSW50ZWdlciA9IHRvX2ludGVnZXJfMS5kZWZhdWx0O1xudmFyIHRvX3JhZGlhbl8xID0gcmVxdWlyZShcIi4vdG8tcmFkaWFuXCIpO1xuZXhwb3J0cy50b1JhZGlhbiA9IHRvX3JhZGlhbl8xLmRlZmF1bHQ7XG4vLyBvYmplY3RcbnZhciBmb3JfaW5fMSA9IHJlcXVpcmUoXCIuL2Zvci1pblwiKTtcbmV4cG9ydHMuZm9ySW4gPSBmb3JfaW5fMS5kZWZhdWx0O1xudmFyIGhhc18xID0gcmVxdWlyZShcIi4vaGFzXCIpO1xuZXhwb3J0cy5oYXMgPSBoYXNfMS5kZWZhdWx0O1xudmFyIGhhc19rZXlfMSA9IHJlcXVpcmUoXCIuL2hhcy1rZXlcIik7XG5leHBvcnRzLmhhc0tleSA9IGhhc19rZXlfMS5kZWZhdWx0O1xudmFyIGhhc192YWx1ZV8xID0gcmVxdWlyZShcIi4vaGFzLXZhbHVlXCIpO1xuZXhwb3J0cy5oYXNWYWx1ZSA9IGhhc192YWx1ZV8xLmRlZmF1bHQ7XG52YXIga2V5c18xID0gcmVxdWlyZShcIi4va2V5c1wiKTtcbmV4cG9ydHMua2V5cyA9IGtleXNfMS5kZWZhdWx0O1xudmFyIGlzX21hdGNoXzEgPSByZXF1aXJlKFwiLi9pcy1tYXRjaFwiKTtcbmV4cG9ydHMuaXNNYXRjaCA9IGlzX21hdGNoXzEuZGVmYXVsdDtcbnZhciB2YWx1ZXNfMSA9IHJlcXVpcmUoXCIuL3ZhbHVlc1wiKTtcbmV4cG9ydHMudmFsdWVzID0gdmFsdWVzXzEuZGVmYXVsdDtcbi8vIHN0cmluZ1xudmFyIGxvd2VyX2Nhc2VfMSA9IHJlcXVpcmUoXCIuL2xvd2VyLWNhc2VcIik7XG5leHBvcnRzLmxvd2VyQ2FzZSA9IGxvd2VyX2Nhc2VfMS5kZWZhdWx0O1xudmFyIGxvd2VyX2ZpcnN0XzEgPSByZXF1aXJlKFwiLi9sb3dlci1maXJzdFwiKTtcbmV4cG9ydHMubG93ZXJGaXJzdCA9IGxvd2VyX2ZpcnN0XzEuZGVmYXVsdDtcbnZhciBzdWJzdGl0dXRlXzEgPSByZXF1aXJlKFwiLi9zdWJzdGl0dXRlXCIpO1xuZXhwb3J0cy5zdWJzdGl0dXRlID0gc3Vic3RpdHV0ZV8xLmRlZmF1bHQ7XG52YXIgdXBwZXJfY2FzZV8xID0gcmVxdWlyZShcIi4vdXBwZXItY2FzZVwiKTtcbmV4cG9ydHMudXBwZXJDYXNlID0gdXBwZXJfY2FzZV8xLmRlZmF1bHQ7XG52YXIgdXBwZXJfZmlyc3RfMSA9IHJlcXVpcmUoXCIuL3VwcGVyLWZpcnN0XCIpO1xuZXhwb3J0cy51cHBlckZpcnN0ID0gdXBwZXJfZmlyc3RfMS5kZWZhdWx0O1xuLy8gdHlwZVxudmFyIGdldF90eXBlXzEgPSByZXF1aXJlKFwiLi9nZXQtdHlwZVwiKTtcbmV4cG9ydHMuZ2V0VHlwZSA9IGdldF90eXBlXzEuZGVmYXVsdDtcbnZhciBpc19hcmd1bWVudHNfMSA9IHJlcXVpcmUoXCIuL2lzLWFyZ3VtZW50c1wiKTtcbmV4cG9ydHMuaXNBcmd1bWVudHMgPSBpc19hcmd1bWVudHNfMS5kZWZhdWx0O1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbmV4cG9ydHMuaXNBcnJheSA9IGlzX2FycmF5XzEuZGVmYXVsdDtcbnZhciBpc19hcnJheV9saWtlXzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheS1saWtlXCIpO1xuZXhwb3J0cy5pc0FycmF5TGlrZSA9IGlzX2FycmF5X2xpa2VfMS5kZWZhdWx0O1xudmFyIGlzX2Jvb2xlYW5fMSA9IHJlcXVpcmUoXCIuL2lzLWJvb2xlYW5cIik7XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzX2Jvb2xlYW5fMS5kZWZhdWx0O1xudmFyIGlzX2RhdGVfMSA9IHJlcXVpcmUoXCIuL2lzLWRhdGVcIik7XG5leHBvcnRzLmlzRGF0ZSA9IGlzX2RhdGVfMS5kZWZhdWx0O1xudmFyIGlzX2Vycm9yXzEgPSByZXF1aXJlKFwiLi9pcy1lcnJvclwiKTtcbmV4cG9ydHMuaXNFcnJvciA9IGlzX2Vycm9yXzEuZGVmYXVsdDtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc19mdW5jdGlvbl8xLmRlZmF1bHQ7XG52YXIgaXNfZmluaXRlXzEgPSByZXF1aXJlKFwiLi9pcy1maW5pdGVcIik7XG5leHBvcnRzLmlzRmluaXRlID0gaXNfZmluaXRlXzEuZGVmYXVsdDtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbmV4cG9ydHMuaXNOaWwgPSBpc19uaWxfMS5kZWZhdWx0O1xudmFyIGlzX251bGxfMSA9IHJlcXVpcmUoXCIuL2lzLW51bGxcIik7XG5leHBvcnRzLmlzTnVsbCA9IGlzX251bGxfMS5kZWZhdWx0O1xudmFyIGlzX251bWJlcl8xID0gcmVxdWlyZShcIi4vaXMtbnVtYmVyXCIpO1xuZXhwb3J0cy5pc051bWJlciA9IGlzX251bWJlcl8xLmRlZmF1bHQ7XG52YXIgaXNfb2JqZWN0XzEgPSByZXF1aXJlKFwiLi9pcy1vYmplY3RcIik7XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNfb2JqZWN0XzEuZGVmYXVsdDtcbnZhciBpc19vYmplY3RfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtb2JqZWN0LWxpa2VcIik7XG5leHBvcnRzLmlzT2JqZWN0TGlrZSA9IGlzX29iamVjdF9saWtlXzEuZGVmYXVsdDtcbnZhciBpc19wbGFpbl9vYmplY3RfMSA9IHJlcXVpcmUoXCIuL2lzLXBsYWluLW9iamVjdFwiKTtcbmV4cG9ydHMuaXNQbGFpbk9iamVjdCA9IGlzX3BsYWluX29iamVjdF8xLmRlZmF1bHQ7XG52YXIgaXNfcHJvdG90eXBlXzEgPSByZXF1aXJlKFwiLi9pcy1wcm90b3R5cGVcIik7XG5leHBvcnRzLmlzUHJvdG90eXBlID0gaXNfcHJvdG90eXBlXzEuZGVmYXVsdDtcbnZhciBpc19yZWdfZXhwXzEgPSByZXF1aXJlKFwiLi9pcy1yZWctZXhwXCIpO1xuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzX3JlZ19leHBfMS5kZWZhdWx0O1xudmFyIGlzX3N0cmluZ18xID0gcmVxdWlyZShcIi4vaXMtc3RyaW5nXCIpO1xuZXhwb3J0cy5pc1N0cmluZyA9IGlzX3N0cmluZ18xLmRlZmF1bHQ7XG52YXIgaXNfdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtdHlwZVwiKTtcbmV4cG9ydHMuaXNUeXBlID0gaXNfdHlwZV8xLmRlZmF1bHQ7XG52YXIgaXNfdW5kZWZpbmVkXzEgPSByZXF1aXJlKFwiLi9pcy11bmRlZmluZWRcIik7XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNfdW5kZWZpbmVkXzEuZGVmYXVsdDtcbnZhciBpc19lbGVtZW50XzEgPSByZXF1aXJlKFwiLi9pcy1lbGVtZW50XCIpO1xuZXhwb3J0cy5pc0VsZW1lbnQgPSBpc19lbGVtZW50XzEuZGVmYXVsdDtcbnZhciByZXF1ZXN0X2FuaW1hdGlvbl9mcmFtZV8xID0gcmVxdWlyZShcIi4vcmVxdWVzdC1hbmltYXRpb24tZnJhbWVcIik7XG5leHBvcnRzLnJlcXVlc3RBbmltYXRpb25GcmFtZSA9IHJlcXVlc3RfYW5pbWF0aW9uX2ZyYW1lXzEuZGVmYXVsdDtcbnZhciBjbGVhcl9hbmltYXRpb25fZnJhbWVfMSA9IHJlcXVpcmUoXCIuL2NsZWFyLWFuaW1hdGlvbi1mcmFtZVwiKTtcbmV4cG9ydHMuY2xlYXJBbmltYXRpb25GcmFtZSA9IGNsZWFyX2FuaW1hdGlvbl9mcmFtZV8xLmRlZmF1bHQ7XG4vLyBvdGhlclxudmFyIGF1Z21lbnRfMSA9IHJlcXVpcmUoXCIuL2F1Z21lbnRcIik7XG5leHBvcnRzLmF1Z21lbnQgPSBhdWdtZW50XzEuZGVmYXVsdDtcbnZhciBjbG9uZV8xID0gcmVxdWlyZShcIi4vY2xvbmVcIik7XG5leHBvcnRzLmNsb25lID0gY2xvbmVfMS5kZWZhdWx0O1xudmFyIGRlYm91bmNlXzEgPSByZXF1aXJlKFwiLi9kZWJvdW5jZVwiKTtcbmV4cG9ydHMuZGVib3VuY2UgPSBkZWJvdW5jZV8xLmRlZmF1bHQ7XG52YXIgbWVtb2l6ZV8xID0gcmVxdWlyZShcIi4vbWVtb2l6ZVwiKTtcbmV4cG9ydHMubWVtb2l6ZSA9IG1lbW9pemVfMS5kZWZhdWx0O1xudmFyIGRlZXBfbWl4XzEgPSByZXF1aXJlKFwiLi9kZWVwLW1peFwiKTtcbmV4cG9ydHMuZGVlcE1peCA9IGRlZXBfbWl4XzEuZGVmYXVsdDtcbnZhciBlYWNoXzEgPSByZXF1aXJlKFwiLi9lYWNoXCIpO1xuZXhwb3J0cy5lYWNoID0gZWFjaF8xLmRlZmF1bHQ7XG52YXIgZXh0ZW5kXzEgPSByZXF1aXJlKFwiLi9leHRlbmRcIik7XG5leHBvcnRzLmV4dGVuZCA9IGV4dGVuZF8xLmRlZmF1bHQ7XG52YXIgaW5kZXhfb2ZfMSA9IHJlcXVpcmUoXCIuL2luZGV4LW9mXCIpO1xuZXhwb3J0cy5pbmRleE9mID0gaW5kZXhfb2ZfMS5kZWZhdWx0O1xudmFyIGlzX2VtcHR5XzEgPSByZXF1aXJlKFwiLi9pcy1lbXB0eVwiKTtcbmV4cG9ydHMuaXNFbXB0eSA9IGlzX2VtcHR5XzEuZGVmYXVsdDtcbnZhciBpc19lcXVhbF8xID0gcmVxdWlyZShcIi4vaXMtZXF1YWxcIik7XG5leHBvcnRzLmlzRXF1YWwgPSBpc19lcXVhbF8xLmRlZmF1bHQ7XG52YXIgaXNfZXF1YWxfd2l0aF8xID0gcmVxdWlyZShcIi4vaXMtZXF1YWwtd2l0aFwiKTtcbmV4cG9ydHMuaXNFcXVhbFdpdGggPSBpc19lcXVhbF93aXRoXzEuZGVmYXVsdDtcbnZhciBtYXBfMSA9IHJlcXVpcmUoXCIuL21hcFwiKTtcbmV4cG9ydHMubWFwID0gbWFwXzEuZGVmYXVsdDtcbnZhciBtYXBfdmFsdWVzXzEgPSByZXF1aXJlKFwiLi9tYXAtdmFsdWVzXCIpO1xuZXhwb3J0cy5tYXBWYWx1ZXMgPSBtYXBfdmFsdWVzXzEuZGVmYXVsdDtcbnZhciBtaXhfMSA9IHJlcXVpcmUoXCIuL21peFwiKTtcbmV4cG9ydHMubWl4ID0gbWl4XzEuZGVmYXVsdDtcbmV4cG9ydHMuYXNzaWduID0gbWl4XzEuZGVmYXVsdDtcbnZhciBnZXRfMSA9IHJlcXVpcmUoXCIuL2dldFwiKTtcbmV4cG9ydHMuZ2V0ID0gZ2V0XzEuZGVmYXVsdDtcbnZhciBzZXRfMSA9IHJlcXVpcmUoXCIuL3NldFwiKTtcbmV4cG9ydHMuc2V0ID0gc2V0XzEuZGVmYXVsdDtcbnZhciBwaWNrXzEgPSByZXF1aXJlKFwiLi9waWNrXCIpO1xuZXhwb3J0cy5waWNrID0gcGlja18xLmRlZmF1bHQ7XG52YXIgdGhyb3R0bGVfMSA9IHJlcXVpcmUoXCIuL3Rocm90dGxlXCIpO1xuZXhwb3J0cy50aHJvdHRsZSA9IHRocm90dGxlXzEuZGVmYXVsdDtcbnZhciB0b19hcnJheV8xID0gcmVxdWlyZShcIi4vdG8tYXJyYXlcIik7XG5leHBvcnRzLnRvQXJyYXkgPSB0b19hcnJheV8xLmRlZmF1bHQ7XG52YXIgdG9fc3RyaW5nXzEgPSByZXF1aXJlKFwiLi90by1zdHJpbmdcIik7XG5leHBvcnRzLnRvU3RyaW5nID0gdG9fc3RyaW5nXzEuZGVmYXVsdDtcbnZhciB1bmlxdWVfaWRfMSA9IHJlcXVpcmUoXCIuL3VuaXF1ZS1pZFwiKTtcbmV4cG9ydHMudW5pcXVlSWQgPSB1bmlxdWVfaWRfMS5kZWZhdWx0O1xudmFyIG5vb3BfMSA9IHJlcXVpcmUoXCIuL25vb3BcIik7XG5leHBvcnRzLm5vb3AgPSBub29wXzEuZGVmYXVsdDtcbnZhciBpZGVudGl0eV8xID0gcmVxdWlyZShcIi4vaWRlbnRpdHlcIik7XG5leHBvcnRzLmlkZW50aXR5ID0gaWRlbnRpdHlfMS5kZWZhdWx0O1xudmFyIHNpemVfMSA9IHJlcXVpcmUoXCIuL3NpemVcIik7XG5leHBvcnRzLnNpemUgPSBzaXplXzEuZGVmYXVsdDtcbi8vIOS4jeefpemBk+S4uuS7gOS5iO+8jOmcgOimgeaKiui/meS4qiBleHBvcnTvvIzkuI3nhLYgdHMg5Lya5oql57G75Z6L6ZSZ6K+vXG52YXIgY2FjaGVfMSA9IHJlcXVpcmUoXCIuL2NhY2hlXCIpO1xuZXhwb3J0cy5DYWNoZSA9IGNhY2hlXzEuZGVmYXVsdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDmmK/lkKbmmK/lj4LmlbDnsbvlnotcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsdWUg5rWL6K+V55qE5YC8XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG52YXIgaXNfdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtdHlwZVwiKTtcbnZhciBpc0FyZ3VtZW50cyA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc190eXBlXzEuZGVmYXVsdCh2YWx1ZSwgJ0FyZ3VtZW50cycpO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzQXJndW1lbnRzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYXJndW1lbnRzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzQXJyYXlMaWtlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLyoqXG4gICAgICogaXNBcnJheUxpa2UoWzEsIDIsIDNdKSA9PiB0cnVlXG4gICAgICogaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbikgPT4gdHJ1ZVxuICAgICAqIGlzQXJyYXlMaWtlKCdhYmMnKSA9PiB0cnVlXG4gICAgICogaXNBcnJheUxpa2UoRnVuY3Rpb24pID0+IGZhbHNlXG4gICAgICovXG4gICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJyAmJiBpc0Zpbml0ZSh2YWx1ZS5sZW5ndGgpO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzQXJyYXlMaWtlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYXJyYXktbGlrZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc190eXBlXzEgPSByZXF1aXJlKFwiLi9pcy10eXBlXCIpO1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5ID9cbiAgICAgICAgQXJyYXkuaXNBcnJheSh2YWx1ZSkgOlxuICAgICAgICBpc190eXBlXzEuZGVmYXVsdCh2YWx1ZSwgJ0FycmF5Jyk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFycmF5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDmmK/lkKbmmK/luIPlsJTnsbvlnotcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsdWUg5rWL6K+V55qE5YC8XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG52YXIgaXNfdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtdHlwZVwiKTtcbnZhciBpc0Jvb2xlYW4gPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNfdHlwZV8xLmRlZmF1bHQodmFsdWUsICdCb29sZWFuJyk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNCb29sZWFuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYm9vbGVhbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc190eXBlXzEgPSByZXF1aXJlKFwiLi9pcy10eXBlXCIpO1xudmFyIGlzRGF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc190eXBlXzEuZGVmYXVsdCh2YWx1ZSwgJ0RhdGUnKTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc0RhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1kYXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX251bWJlcl8xID0gcmVxdWlyZShcIi4vaXMtbnVtYmVyXCIpO1xudmFyIGlzRGVjaW1hbCA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICByZXR1cm4gaXNfbnVtYmVyXzEuZGVmYXVsdChudW0pICYmIG51bSAlIDEgIT09IDA7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNEZWNpbWFsO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZGVjaW1hbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKlxuICog5Yik5pat5piv5ZCmSFRNTOWFg+e0oFxuICogQHJldHVybiB7Qm9vbGVhbn0g5piv5ZCmSFRNTOWFg+e0oFxuICovXG52YXIgaXNFbGVtZW50ID0gZnVuY3Rpb24gKG8pIHtcbiAgICByZXR1cm4gbyBpbnN0YW5jZW9mIEVsZW1lbnQgfHwgbyBpbnN0YW5jZW9mIEhUTUxEb2N1bWVudDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc0VsZW1lbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1lbGVtZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX25pbF8xID0gcmVxdWlyZShcIi4vaXMtbmlsXCIpO1xudmFyIGlzX2FycmF5X2xpa2VfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5LWxpa2VcIik7XG52YXIgZ2V0X3R5cGVfMSA9IHJlcXVpcmUoXCIuL2dldC10eXBlXCIpO1xudmFyIGlzX3Byb3RvdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtcHJvdG90eXBlXCIpO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbmZ1bmN0aW9uIGlzRW1wdHkodmFsdWUpIHtcbiAgICAvKipcbiAgICAgKiBpc0VtcHR5KG51bGwpID0+IHRydWVcbiAgICAgKiBpc0VtcHR5KCkgPT4gdHJ1ZVxuICAgICAqIGlzRW1wdHkodHJ1ZSkgPT4gdHJ1ZVxuICAgICAqIGlzRW1wdHkoMSkgPT4gdHJ1ZVxuICAgICAqIGlzRW1wdHkoWzEsIDIsIDNdKSA9PiBmYWxzZVxuICAgICAqIGlzRW1wdHkoJ2FiYycpID0+IGZhbHNlXG4gICAgICogaXNFbXB0eSh7IGE6IDEgfSkgPT4gZmFsc2VcbiAgICAgKi9cbiAgICBpZiAoaXNfbmlsXzEuZGVmYXVsdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChpc19hcnJheV9saWtlXzEuZGVmYXVsdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuICF2YWx1ZS5sZW5ndGg7XG4gICAgfVxuICAgIHZhciB0eXBlID0gZ2V0X3R5cGVfMS5kZWZhdWx0KHZhbHVlKTtcbiAgICBpZiAodHlwZSA9PT0gJ01hcCcgfHwgdHlwZSA9PT0gJ1NldCcpIHtcbiAgICAgICAgcmV0dXJuICF2YWx1ZS5zaXplO1xuICAgIH1cbiAgICBpZiAoaXNfcHJvdG90eXBlXzEuZGVmYXVsdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuICFPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoO1xuICAgIH1cbiAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGlzRW1wdHk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1lbXB0eS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG52YXIgaXNfZXF1YWxfMSA9IHJlcXVpcmUoXCIuL2lzLWVxdWFsXCIpO1xuLyoqXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIGlzR3JlZXRpbmcodmFsdWUpIHtcbiAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAqIH1cbiAqXG4gKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSkge1xuICogICBpZiAoaXNHcmVldGluZyhvYmpWYWx1ZSkgJiYgaXNHcmVldGluZyhvdGhWYWx1ZSkpIHtcbiAqICAgICByZXR1cm4gdHJ1ZTtcbiAqICAgfVxuICogfVxuICpcbiAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICogdmFyIG90aGVyID0gWydoaScsICdnb29kYnllJ107XG4gKlxuICogaXNFcXVhbFdpdGgoYXJyYXksIG90aGVyLCBjdXN0b21pemVyKTsgIC8vID0+IHRydWVcbiAqL1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uICh2YWx1ZSwgb3RoZXIsIGZuKSB7XG4gICAgaWYgKCFpc19mdW5jdGlvbl8xLmRlZmF1bHQoZm4pKSB7XG4gICAgICAgIHJldHVybiBpc19lcXVhbF8xLmRlZmF1bHQodmFsdWUsIG90aGVyKTtcbiAgICB9XG4gICAgcmV0dXJuICEhZm4odmFsdWUsIG90aGVyKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZXF1YWwtd2l0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19vYmplY3RfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtb2JqZWN0LWxpa2VcIik7XG52YXIgaXNfYXJyYXlfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXktbGlrZVwiKTtcbnZhciBpc19zdHJpbmdfMSA9IHJlcXVpcmUoXCIuL2lzLXN0cmluZ1wiKTtcbnZhciBpc0VxdWFsID0gZnVuY3Rpb24gKHZhbHVlLCBvdGhlcikge1xuICAgIGlmICh2YWx1ZSA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICghdmFsdWUgfHwgIW90aGVyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGlzX3N0cmluZ18xLmRlZmF1bHQodmFsdWUpIHx8IGlzX3N0cmluZ18xLmRlZmF1bHQob3RoZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGlzX2FycmF5X2xpa2VfMS5kZWZhdWx0KHZhbHVlKSB8fCBpc19hcnJheV9saWtlXzEuZGVmYXVsdChvdGhlcikpIHtcbiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCAhPT0gb3RoZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJzdCA9IHRydWU7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHJzdCA9IGlzRXF1YWwodmFsdWVbaV0sIG90aGVyW2ldKTtcbiAgICAgICAgICAgIGlmICghcnN0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9XG4gICAgaWYgKGlzX29iamVjdF9saWtlXzEuZGVmYXVsdCh2YWx1ZSkgfHwgaXNfb2JqZWN0X2xpa2VfMS5kZWZhdWx0KG90aGVyKSkge1xuICAgICAgICB2YXIgdmFsdWVLZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICAgICAgICB2YXIgb3RoZXJLZXlzID0gT2JqZWN0LmtleXMob3RoZXIpO1xuICAgICAgICBpZiAodmFsdWVLZXlzLmxlbmd0aCAhPT0gb3RoZXJLZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciByc3QgPSB0cnVlO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcnN0ID0gaXNFcXVhbCh2YWx1ZVt2YWx1ZUtleXNbaV1dLCBvdGhlclt2YWx1ZUtleXNbaV1dKTtcbiAgICAgICAgICAgIGlmICghcnN0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzRXF1YWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1lcXVhbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKlxuICog5piv5ZCm5piv5Y+C5pWw57G75Z6LXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlIOa1i+ivleeahOWAvFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xudmFyIGlzX3R5cGVfMSA9IHJlcXVpcmUoXCIuL2lzLXR5cGVcIik7XG52YXIgaXNFcnJvciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc190eXBlXzEuZGVmYXVsdCh2YWx1ZSwgJ0Vycm9yJyk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNFcnJvcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWVycm9yLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX251bWJlcl8xID0gcmVxdWlyZShcIi4vaXMtbnVtYmVyXCIpO1xudmFyIGlzRXZlbiA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICByZXR1cm4gaXNfbnVtYmVyXzEuZGVmYXVsdChudW0pICYmIG51bSAlIDIgPT09IDA7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNFdmVuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZXZlbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKlxuICog5Yik5pat5piv5ZCm5Li65pyJ6ZmQ5pWwXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG52YXIgaXNfbnVtYmVyXzEgPSByZXF1aXJlKFwiLi9pcy1udW1iZXJcIik7XG5mdW5jdGlvbiBkZWZhdWx0XzEodmFsdWUpIHtcbiAgICByZXR1cm4gaXNfbnVtYmVyXzEuZGVmYXVsdCh2YWx1ZSkgJiYgaXNGaW5pdGUodmFsdWUpO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gZGVmYXVsdF8xO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZmluaXRlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLyoqXG4gKiDmmK/lkKbkuLrlh73mlbBcbiAqIEBwYXJhbSAgeyp9IGZuIOWvueixoVxuICogQHJldHVybiB7Qm9vbGVhbn0gIOaYr+WQpuWHveaVsFxuICovXG52YXIgaXNfdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtdHlwZVwiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNfdHlwZV8xLmRlZmF1bHQodmFsdWUsICdGdW5jdGlvbicpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1mdW5jdGlvbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19udW1iZXJfMSA9IHJlcXVpcmUoXCIuL2lzLW51bWJlclwiKTtcbnZhciBpc0ludGVnZXIgPSBOdW1iZXIuaXNJbnRlZ2VyID8gTnVtYmVyLmlzSW50ZWdlciA6IGZ1bmN0aW9uIChudW0pIHtcbiAgICByZXR1cm4gaXNfbnVtYmVyXzEuZGVmYXVsdChudW0pICYmIG51bSAlIDEgPT09IDA7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNJbnRlZ2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtaW50ZWdlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbnZhciBrZXlzXzEgPSByZXF1aXJlKFwiLi9rZXlzXCIpO1xuZnVuY3Rpb24gaXNNYXRjaChvYmosIGF0dHJzKSB7XG4gICAgdmFyIF9rZXlzID0ga2V5c18xLmRlZmF1bHQoYXR0cnMpO1xuICAgIHZhciBsZW5ndGggPSBfa2V5cy5sZW5ndGg7XG4gICAgaWYgKGlzX25pbF8xLmRlZmF1bHQob2JqKSlcbiAgICAgICAgcmV0dXJuICFsZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICB2YXIga2V5ID0gX2tleXNbaV07XG4gICAgICAgIGlmIChhdHRyc1trZXldICE9PSBvYmpba2V5XSB8fCAhKGtleSBpbiBvYmopKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBpc01hdGNoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbWF0Y2guanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfbnVtYmVyXzEgPSByZXF1aXJlKFwiLi9pcy1udW1iZXJcIik7XG52YXIgaXNOZWdhdGl2ZSA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICByZXR1cm4gaXNfbnVtYmVyXzEuZGVmYXVsdChudW0pICYmIG51bSA8IDA7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNOZWdhdGl2ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5lZ2F0aXZlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuLy8gaXNGaW5pdGUsXG52YXIgaXNOaWwgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvKipcbiAgICAgKiBpc05pbChudWxsKSA9PiB0cnVlXG4gICAgICogaXNOaWwoKSA9PiB0cnVlXG4gICAgICovXG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQ7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNOaWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uaWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNOdWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzTnVsbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW51bGwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgUFJFQ0lTSU9OID0gMC4wMDAwMTsgLy8gbnVtYmVycyBsZXNzIHRoYW4gdGhpcyBpcyBjb25zaWRlcmVkIGFzIDBcbmZ1bmN0aW9uIGlzTnVtYmVyRXF1YWwoYSwgYiwgcHJlY2lzaW9uKSB7XG4gICAgaWYgKHByZWNpc2lvbiA9PT0gdm9pZCAwKSB7IHByZWNpc2lvbiA9IFBSRUNJU0lPTjsgfVxuICAgIHJldHVybiBNYXRoLmFicygoYSAtIGIpKSA8IHByZWNpc2lvbjtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGlzTnVtYmVyRXF1YWw7XG47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1udW1iZXItZXF1YWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vKipcbiAqIOWIpOaWreaYr+WQpuaVsOWtl1xuICogQHJldHVybiB7Qm9vbGVhbn0g5piv5ZCm5pWw5a2XXG4gKi9cbnZhciBpc190eXBlXzEgPSByZXF1aXJlKFwiLi9pcy10eXBlXCIpO1xudmFyIGlzTnVtYmVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGlzX3R5cGVfMS5kZWZhdWx0KHZhbHVlLCAnTnVtYmVyJyk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNOdW1iZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1udW1iZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNPYmplY3RMaWtlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLyoqXG4gICAgICogaXNPYmplY3RMaWtlKHt9KSA9PiB0cnVlXG4gICAgICogaXNPYmplY3RMaWtlKFsxLCAyLCAzXSkgPT4gdHJ1ZVxuICAgICAqIGlzT2JqZWN0TGlrZShGdW5jdGlvbikgPT4gZmFsc2VcbiAgICAgKiBpc09iamVjdExpa2UobnVsbCkgPT4gZmFsc2VcbiAgICAgKi9cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc09iamVjdExpa2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1vYmplY3QtbGlrZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvKipcbiAgICAgKiBpc09iamVjdCh7fSkgPT4gdHJ1ZVxuICAgICAqIGlzT2JqZWN0KFsxLCAyLCAzXSkgPT4gdHJ1ZVxuICAgICAqIGlzT2JqZWN0KEZ1bmN0aW9uKSA9PiB0cnVlXG4gICAgICogaXNPYmplY3QobnVsbCkgPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZSA9PT0gJ29iamVjdCcgfHwgdHlwZSA9PT0gJ2Z1bmN0aW9uJztcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtb2JqZWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX251bWJlcl8xID0gcmVxdWlyZShcIi4vaXMtbnVtYmVyXCIpO1xudmFyIGlzT2RkID0gZnVuY3Rpb24gKG51bSkge1xuICAgIHJldHVybiBpc19udW1iZXJfMS5kZWZhdWx0KG51bSkgJiYgbnVtICUgMiAhPT0gMDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc09kZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW9kZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19vYmplY3RfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtb2JqZWN0LWxpa2VcIik7XG52YXIgaXNfdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtdHlwZVwiKTtcbnZhciBpc1BsYWluT2JqZWN0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLyoqXG4gICAgICogaXNPYmplY3RMaWtlKG5ldyBGb28pID0+IGZhbHNlXG4gICAgICogaXNPYmplY3RMaWtlKFsxLCAyLCAzXSkgPT4gZmFsc2VcbiAgICAgKiBpc09iamVjdExpa2UoeyB4OiAwLCB5OiAwIH0pID0+IHRydWVcbiAgICAgKiBpc09iamVjdExpa2UoT2JqZWN0LmNyZWF0ZShudWxsKSkgPT4gdHJ1ZVxuICAgICAqL1xuICAgIGlmICghaXNfb2JqZWN0X2xpa2VfMS5kZWZhdWx0KHZhbHVlKSB8fCAhaXNfdHlwZV8xLmRlZmF1bHQodmFsdWUsICdPYmplY3QnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB2YXIgcHJvdG8gPSB2YWx1ZTtcbiAgICB3aGlsZSAoT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKSAhPT0gbnVsbCkge1xuICAgICAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpID09PSBwcm90bztcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc1BsYWluT2JqZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtcGxhaW4tb2JqZWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX251bWJlcl8xID0gcmVxdWlyZShcIi4vaXMtbnVtYmVyXCIpO1xudmFyIGlzUG9zaXRpdmUgPSBmdW5jdGlvbiAobnVtKSB7XG4gICAgcmV0dXJuIGlzX251bWJlcl8xLmRlZmF1bHQobnVtKSAmJiBudW0gPiAwO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzUG9zaXRpdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wb3NpdGl2ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG52YXIgaXNQcm90b3R5cGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yO1xuICAgIHZhciBwcm90byA9ICh0eXBlb2YgQ3RvciA9PT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG4gICAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc1Byb3RvdHlwZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXByb3RvdHlwZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc190eXBlXzEgPSByZXF1aXJlKFwiLi9pcy10eXBlXCIpO1xudmFyIGlzUmVnRXhwID0gZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiBpc190eXBlXzEuZGVmYXVsdChzdHIsICdSZWdFeHAnKTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc1JlZ0V4cDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXJlZy1leHAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfdHlwZV8xID0gcmVxdWlyZShcIi4vaXMtdHlwZVwiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAoc3RyKSB7XG4gICAgcmV0dXJuIGlzX3R5cGVfMS5kZWZhdWx0KHN0ciwgJ1N0cmluZycpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1zdHJpbmcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcbnZhciBpc1R5cGUgPSBmdW5jdGlvbiAodmFsdWUsIHR5cGUpIHsgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCAnICsgdHlwZSArICddJzsgfTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzVHlwZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXR5cGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNVbmRlZmluZWQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBpc1VuZGVmaW5lZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXVuZGVmaW5lZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBlYWNoXzEgPSByZXF1aXJlKFwiLi9lYWNoXCIpO1xudmFyIGlzX2Z1bmN0aW9uXzEgPSByZXF1aXJlKFwiLi9pcy1mdW5jdGlvblwiKTtcbnZhciBrZXlzID0gT2JqZWN0LmtleXMgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBPYmplY3Qua2V5cyhvYmopOyB9IDogZnVuY3Rpb24gKG9iaikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICBlYWNoXzEuZGVmYXVsdChvYmosIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgIGlmICghKGlzX2Z1bmN0aW9uXzEuZGVmYXVsdChvYmopICYmIGtleSA9PT0gJ3Byb3RvdHlwZScpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBrZXlzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9a2V5cy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19hcnJheV9saWtlXzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheS1saWtlXCIpO1xuZnVuY3Rpb24gbGFzdChvKSB7XG4gICAgaWYgKGlzX2FycmF5X2xpa2VfMS5kZWZhdWx0KG8pKSB7XG4gICAgICAgIHZhciBhcnIgPSBvO1xuICAgICAgICByZXR1cm4gYXJyW2Fyci5sZW5ndGggLSAxXTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGxhc3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sYXN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRvX3N0cmluZ18xID0gcmVxdWlyZShcIi4vdG8tc3RyaW5nXCIpO1xudmFyIGxvd2VyQ2FzZSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gdG9fc3RyaW5nXzEuZGVmYXVsdChzdHIpLnRvTG93ZXJDYXNlKCk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gbG93ZXJDYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bG93ZXItY2FzZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciB0b19zdHJpbmdfMSA9IHJlcXVpcmUoXCIuL3RvLXN0cmluZ1wiKTtcbnZhciBsb3dlckZpcnN0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIHN0ciA9IHRvX3N0cmluZ18xLmRlZmF1bHQodmFsdWUpO1xuICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzdHIuc3Vic3RyaW5nKDEpO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IGxvd2VyRmlyc3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sb3dlci1maXJzdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbnZhciBpc19vYmplY3RfMSA9IHJlcXVpcmUoXCIuL2lzLW9iamVjdFwiKTtcbnZhciBpZGVudGl0eSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiB2OyB9O1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uIChvYmplY3QsIGZ1bmMpIHtcbiAgICBpZiAoZnVuYyA9PT0gdm9pZCAwKSB7IGZ1bmMgPSBpZGVudGl0eTsgfVxuICAgIHZhciByID0ge307XG4gICAgaWYgKGlzX29iamVjdF8xLmRlZmF1bHQob2JqZWN0KSAmJiAhaXNfbmlsXzEuZGVmYXVsdChvYmplY3QpKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKG9iamVjdCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICByW2tleV0gPSBmdW5jKG9iamVjdFtrZXldLCBrZXkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHI7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1hcC12YWx1ZXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfbGlrZV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXktbGlrZVwiKTtcbnZhciBtYXAgPSBmdW5jdGlvbiAoYXJyLCBmdW5jKSB7XG4gICAgaWYgKCFpc19hcnJheV9saWtlXzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBhcnIubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycltpbmRleF07XG4gICAgICAgIHJlc3VsdC5wdXNoKGZ1bmModmFsdWUsIGluZGV4KSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gbWFwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWFwLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGVhY2hfMSA9IHJlcXVpcmUoXCIuL2VhY2hcIik7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5XCIpO1xudmFyIGlzX2Z1bmN0aW9uXzEgPSByZXF1aXJlKFwiLi9pcy1mdW5jdGlvblwiKTtcbi8qKlxuICogQHBhcmFtIHtBcnJheX0gYXJyIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICogQHJldHVybiB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDEgfSwgeyAnbic6IDIgfV07XG4gKlxuICogbWF4Qnkob2JqZWN0cywgZnVuY3Rpb24obykgeyByZXR1cm4gby5uOyB9KTtcbiAqIC8vID0+IHsgJ24nOiAyIH1cbiAqXG4gKiBtYXhCeShvYmplY3RzLCAnbicpO1xuICogLy8gPT4geyAnbic6IDIgfVxuICovXG5leHBvcnRzLmRlZmF1bHQgPSAoZnVuY3Rpb24gKGFyciwgZm4pIHtcbiAgICBpZiAoIWlzX2FycmF5XzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHZhciBtYXggPSBhcnJbMF07XG4gICAgdmFyIG1heERhdGE7XG4gICAgaWYgKGlzX2Z1bmN0aW9uXzEuZGVmYXVsdChmbikpIHtcbiAgICAgICAgbWF4RGF0YSA9IGZuKGFyclswXSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBtYXhEYXRhID0gYXJyWzBdW2ZuXTtcbiAgICB9XG4gICAgdmFyIGRhdGE7XG4gICAgZWFjaF8xLmRlZmF1bHQoYXJyLCBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIGlmIChpc19mdW5jdGlvbl8xLmRlZmF1bHQoZm4pKSB7XG4gICAgICAgICAgICBkYXRhID0gZm4odmFsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRhdGEgPSB2YWxbZm5dO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhID4gbWF4RGF0YSkge1xuICAgICAgICAgICAgbWF4ID0gdmFsO1xuICAgICAgICAgICAgbWF4RGF0YSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbWF4O1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXgtYnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfZnVuY3Rpb25fMSA9IHJlcXVpcmUoXCIuL2lzLWZ1bmN0aW9uXCIpO1xuLyoqXG4gKiBfLm1lbW9pemUoY2FsQ29sb3IpO1xuICogXy5tZW1vaXplKGNhbENvbG9yLCAoLi4uYXJncykgPT4gYXJnc1swXSk7XG4gKiBAcGFyYW0gZlxuICogQHBhcmFtIHJlc29sdmVyXG4gKi9cbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAoZiwgcmVzb2x2ZXIpIHtcbiAgICBpZiAoIWlzX2Z1bmN0aW9uXzEuZGVmYXVsdChmKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuICAgIHZhciBtZW1vaXplZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICAvLyDkvb/nlKjmlrnms5XmnoTpgKAga2V577yM5aaC5p6c5LiN5a2Y5ZyoIHJlc29sdmVy77yM5YiZ55u05o6l5Y+W56ys5LiA5Liq5Y+C5pWw5L2c5Li6IGtleVxuICAgICAgICB2YXIga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF07XG4gICAgICAgIHZhciBjYWNoZSA9IG1lbW9pemVkLmNhY2hlO1xuICAgICAgICBpZiAoY2FjaGUuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gZi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgLy8g57yT5a2Y6LW35p2lXG4gICAgICAgIGNhY2hlLnNldChrZXksIHJlc3VsdCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICBtZW1vaXplZC5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgICByZXR1cm4gbWVtb2l6ZWQ7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lbW9pemUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZWFjaF8xID0gcmVxdWlyZShcIi4vZWFjaFwiKTtcbnZhciBpc19hcnJheV8xID0gcmVxdWlyZShcIi4vaXMtYXJyYXlcIik7XG52YXIgaXNfZnVuY3Rpb25fMSA9IHJlcXVpcmUoXCIuL2lzLWZ1bmN0aW9uXCIpO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnIgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcmV0dXJuIHsqfSBSZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogMSB9LCB7ICduJzogMiB9XTtcbiAqXG4gKiBtaW5CeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICogLy8gPT4geyAnbic6IDEgfVxuICpcbiAqIG1pbkJ5KG9iamVjdHMsICduJyk7XG4gKiAvLyA9PiB7ICduJzogMSB9XG4gKi9cbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAoYXJyLCBmbikge1xuICAgIGlmICghaXNfYXJyYXlfMS5kZWZhdWx0KGFycikpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIG1pbiA9IGFyclswXTtcbiAgICB2YXIgbWluRGF0YTtcbiAgICBpZiAoaXNfZnVuY3Rpb25fMS5kZWZhdWx0KGZuKSkge1xuICAgICAgICBtaW5EYXRhID0gZm4oYXJyWzBdKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG1pbkRhdGEgPSBhcnJbMF1bZm5dO1xuICAgIH1cbiAgICB2YXIgZGF0YTtcbiAgICBlYWNoXzEuZGVmYXVsdChhcnIsIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKGlzX2Z1bmN0aW9uXzEuZGVmYXVsdChmbikpIHtcbiAgICAgICAgICAgIGRhdGEgPSBmbih2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGF0YSA9IHZhbFtmbl07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEgPCBtaW5EYXRhKSB7XG4gICAgICAgICAgICBtaW4gPSB2YWw7XG4gICAgICAgICAgICBtaW5EYXRhID0gZGF0YTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBtaW47XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbi1ieS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIEZJWE1FOiBNdXRhYmxlIHBhcmFtIHNob3VsZCBiZSBmb3JiaWRkZW4gaW4gc3RhdGljIGxhbmcuXG5mdW5jdGlvbiBfbWl4KGRpc3QsIG9iaikge1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGtleSAhPT0gJ2NvbnN0cnVjdG9yJyAmJiBvYmpba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkaXN0W2tleV0gPSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIG1peChkaXN0LCBzcmMxLCBzcmMyLCBzcmMzKSB7XG4gICAgaWYgKHNyYzEpXG4gICAgICAgIF9taXgoZGlzdCwgc3JjMSk7XG4gICAgaWYgKHNyYzIpXG4gICAgICAgIF9taXgoZGlzdCwgc3JjMik7XG4gICAgaWYgKHNyYzMpXG4gICAgICAgIF9taXgoZGlzdCwgc3JjMyk7XG4gICAgcmV0dXJuIGRpc3Q7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBtaXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbW9kID0gZnVuY3Rpb24gKG4sIG0pIHtcbiAgICByZXR1cm4gKChuICUgbSkgKyBtKSAlIG07XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gbW9kO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bW9kLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uICgpIHsgfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub29wLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIG51bUNvbG9yQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIG51bWJlclRvQ29sb3IobnVtKSB7XG4gICAgLy8g5aKe5Yqg57yT5a2YXG4gICAgdmFyIGNvbG9yID0gbnVtQ29sb3JDYWNoZVtudW1dO1xuICAgIGlmICghY29sb3IpIHtcbiAgICAgICAgdmFyIHN0ciA9IG51bS50b1N0cmluZygxNik7XG4gICAgICAgIGZvciAodmFyIGkgPSBzdHIubGVuZ3RoOyBpIDwgNjsgaSsrKSB7XG4gICAgICAgICAgICBzdHIgPSAnMCcgKyBzdHI7XG4gICAgICAgIH1cbiAgICAgICAgY29sb3IgPSAnIycgKyBzdHI7XG4gICAgICAgIG51bUNvbG9yQ2FjaGVbbnVtXSA9IGNvbG9yO1xuICAgIH1cbiAgICByZXR1cm4gY29sb3I7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBudW1iZXJUb0NvbG9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bnVtYmVyMmNvbG9yLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbmZ1bmN0aW9uIHBhcnNlUmFkaXVzKHJhZGl1cykge1xuICAgIHZhciByMSA9IDAsIHIyID0gMCwgcjMgPSAwLCByNCA9IDA7XG4gICAgaWYgKGlzX2FycmF5XzEuZGVmYXVsdChyYWRpdXMpKSB7XG4gICAgICAgIGlmIChyYWRpdXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByMSA9IHIyID0gcjMgPSByNCA9IHJhZGl1c1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChyYWRpdXMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICByMSA9IHIzID0gcmFkaXVzWzBdO1xuICAgICAgICAgICAgcjIgPSByNCA9IHJhZGl1c1sxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChyYWRpdXMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICByMSA9IHJhZGl1c1swXTtcbiAgICAgICAgICAgIHIyID0gcjQgPSByYWRpdXNbMV07XG4gICAgICAgICAgICByMyA9IHJhZGl1c1syXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHIxID0gcmFkaXVzWzBdO1xuICAgICAgICAgICAgcjIgPSByYWRpdXNbMV07XG4gICAgICAgICAgICByMyA9IHJhZGl1c1syXTtcbiAgICAgICAgICAgIHI0ID0gcmFkaXVzWzNdO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByMSA9IHIyID0gcjMgPSByNCA9IHJhZGl1cztcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcjE6IHIxLFxuICAgICAgICByMjogcjIsXG4gICAgICAgIHIzOiByMyxcbiAgICAgICAgcjQ6IHI0XG4gICAgfTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHBhcnNlUmFkaXVzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFyc2UtcmFkaXVzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGVhY2hfMSA9IHJlcXVpcmUoXCIuL2VhY2hcIik7XG52YXIgaXNfcGxhaW5fb2JqZWN0XzEgPSByZXF1aXJlKFwiLi9pcy1wbGFpbi1vYmplY3RcIik7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICBpZiAob2JqZWN0ID09PSBudWxsIHx8ICFpc19wbGFpbl9vYmplY3RfMS5kZWZhdWx0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgZWFjaF8xLmRlZmF1bHQoa2V5cywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgICAgICAgIHJlc3VsdFtrZXldID0gb2JqZWN0W2tleV07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1waWNrLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5X2xpa2VfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5LWxpa2VcIik7XG52YXIgc3BsaWNlID0gQXJyYXkucHJvdG90eXBlLnNwbGljZTtcbnZhciBwdWxsQXQgPSBmdW5jdGlvbiBwdWxsQXQoYXJyLCBpbmRleGVzKSB7XG4gICAgaWYgKCFpc19hcnJheV9saWtlXzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdmFyIGxlbmd0aCA9IGFyciA/IGluZGV4ZXMubGVuZ3RoIDogMDtcbiAgICB2YXIgbGFzdCA9IGxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBwcmV2aW91cyA9IHZvaWQgMDtcbiAgICAgICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgICAgICBpZiAobGVuZ3RoID09PSBsYXN0IHx8IGluZGV4ICE9PSBwcmV2aW91cykge1xuICAgICAgICAgICAgcHJldmlvdXMgPSBpbmRleDtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKGFyciwgaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnI7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gcHVsbEF0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cHVsbC1hdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBhcnJQcm90b3R5cGUgPSBBcnJheS5wcm90b3R5cGU7XG52YXIgc3BsaWNlID0gYXJyUHJvdG90eXBlLnNwbGljZTtcbnZhciBpbmRleE9mID0gYXJyUHJvdG90eXBlLmluZGV4T2Y7XG52YXIgcHVsbCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAxOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pIC0gMV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaV07XG4gICAgICAgIHZhciBmcm9tSW5kZXggPSAtMTtcbiAgICAgICAgd2hpbGUgKChmcm9tSW5kZXggPSBpbmRleE9mLmNhbGwoYXJyLCB2YWx1ZSkpID4gLTEpIHtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKGFyciwgZnJvbUluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IHB1bGw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wdWxsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGVhY2hfMSA9IHJlcXVpcmUoXCIuL2VhY2hcIik7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5XCIpO1xudmFyIGlzX3BsYWluX29iamVjdF8xID0gcmVxdWlyZShcIi4vaXMtcGxhaW4tb2JqZWN0XCIpO1xudmFyIHJlZHVjZSA9IGZ1bmN0aW9uIChhcnIsIGZuLCBpbml0KSB7XG4gICAgaWYgKCFpc19hcnJheV8xLmRlZmF1bHQoYXJyKSAmJiAhaXNfcGxhaW5fb2JqZWN0XzEuZGVmYXVsdChhcnIpKSB7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSBpbml0O1xuICAgIGVhY2hfMS5kZWZhdWx0KGFyciwgZnVuY3Rpb24gKGRhdGEsIGkpIHtcbiAgICAgICAgcmVzdWx0ID0gZm4ocmVzdWx0LCBkYXRhLCBpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IHJlZHVjZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlZHVjZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19hcnJheV9saWtlXzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheS1saWtlXCIpO1xudmFyIHB1bGxfYXRfMSA9IHJlcXVpcmUoXCIuL3B1bGwtYXRcIik7XG52YXIgcmVtb3ZlID0gZnVuY3Rpb24gKGFyciwgcHJlZGljYXRlKSB7XG4gICAgLyoqXG4gICAgICogY29uc3QgYXJyID0gWzEsIDIsIDMsIDRdXG4gICAgICogY29uc3QgZXZlbnMgPSByZW1vdmUoYXJyLCBuID0+IG4gJSAyID09IDApXG4gICAgICogY29uc29sZS5sb2coYXJyKSAvLyA9PiBbMSwgM11cbiAgICAgKiBjb25zb2xlLmxvZyhldmVucykgLy8gPT4gWzIsIDRdXG4gICAgICovXG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIGlmICghaXNfYXJyYXlfbGlrZV8xLmRlZmF1bHQoYXJyKSkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICB2YXIgaSA9IC0xO1xuICAgIHZhciBpbmRleGVzID0gW107XG4gICAgdmFyIGxlbmd0aCA9IGFyci5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJbaV07XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGksIGFycikpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIGluZGV4ZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwdWxsX2F0XzEuZGVmYXVsdChhcnIsIGluZGV4ZXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gcmVtb3ZlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVtb3ZlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZnVuY3Rpb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZuKSB7XG4gICAgdmFyIG1ldGhvZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHdpbmRvdy5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGYsIDE2KTtcbiAgICAgICAgfTtcbiAgICByZXR1cm4gbWV0aG9kKGZuKTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZTtcbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlcXVlc3QtYW5pbWF0aW9uLWZyYW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX29iamVjdF8xID0gcmVxdWlyZShcIi4vaXMtb2JqZWN0XCIpO1xudmFyIGlzX3N0cmluZ18xID0gcmVxdWlyZShcIi4vaXMtc3RyaW5nXCIpO1xudmFyIGlzX251bWJlcl8xID0gcmVxdWlyZShcIi4vaXMtbnVtYmVyXCIpO1xuLyoqXG4gKiBodHRwczovL2dpdGh1Yi5jb20vZGV2ZWxvcGl0L2Rsdi9ibG9iL21hc3Rlci9pbmRleC5qc1xuICogQHBhcmFtIG9ialxuICogQHBhcmFtIHBhdGhcbiAqIEBwYXJhbSB2YWx1ZVxuICovXG5leHBvcnRzLmRlZmF1bHQgPSAoZnVuY3Rpb24gKG9iaiwgcGF0aCwgdmFsdWUpIHtcbiAgICB2YXIgbyA9IG9iajtcbiAgICB2YXIga2V5QXJyID0gaXNfc3RyaW5nXzEuZGVmYXVsdChwYXRoKSA/IHBhdGguc3BsaXQoJy4nKSA6IHBhdGg7XG4gICAga2V5QXJyLmZvckVhY2goZnVuY3Rpb24gKGtleSwgaWR4KSB7XG4gICAgICAgIC8vIOS4jeaYr+acgOWQjuS4gOS4qlxuICAgICAgICBpZiAoaWR4IDwga2V5QXJyLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGlmICghaXNfb2JqZWN0XzEuZGVmYXVsdChvW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgb1trZXldID0gaXNfbnVtYmVyXzEuZGVmYXVsdChrZXlBcnJbaWR4ICsgMV0pID8gW10gOiB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG8gPSBvW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBvW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbnZhciBpc19hcnJheV9saWtlXzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheS1saWtlXCIpO1xuZnVuY3Rpb24gc2l6ZShvKSB7XG4gICAgaWYgKGlzX25pbF8xLmRlZmF1bHQobykpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGlmIChpc19hcnJheV9saWtlXzEuZGVmYXVsdChvKSkge1xuICAgICAgICByZXR1cm4gby5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhvKS5sZW5ndGg7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzaXplO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2l6ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKlxuICog5Y+q6KaB5pyJ5LiA5Liq5ruh6Laz5p2h5Lu25bCx6L+U5ZueIHRydWVcbiAqIEBwYXJhbSBhcnJcbiAqIEBwYXJhbSBmdW5jXG4gKi9cbnZhciBzb21lID0gZnVuY3Rpb24gKGFyciwgZnVuYykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChmdW5jKGFycltpXSwgaSkpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IHNvbWU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zb21lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBpc19zdHJpbmdfMSA9IHJlcXVpcmUoXCIuL2lzLXN0cmluZ1wiKTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG5mdW5jdGlvbiBzb3J0QnkoYXJyLCBrZXkpIHtcbiAgICB2YXIgY29tcGFyZXI7XG4gICAgaWYgKGlzX2Z1bmN0aW9uXzEuZGVmYXVsdChrZXkpKSB7XG4gICAgICAgIGNvbXBhcmVyID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGtleShhKSAtIGtleShiKTsgfTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBrZXlzXzEgPSBbXTtcbiAgICAgICAgaWYgKGlzX3N0cmluZ18xLmRlZmF1bHQoa2V5KSkge1xuICAgICAgICAgICAga2V5c18xLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc19hcnJheV8xLmRlZmF1bHQoa2V5KSkge1xuICAgICAgICAgICAga2V5c18xID0ga2V5O1xuICAgICAgICB9XG4gICAgICAgIGNvbXBhcmVyID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5c18xLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIHByb3AgPSBrZXlzXzFbaV07XG4gICAgICAgICAgICAgICAgaWYgKGFbcHJvcF0gPiBiW3Byb3BdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYVtwcm9wXSA8IGJbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBhcnIuc29ydChjb21wYXJlcik7XG4gICAgcmV0dXJuIGFycjtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHNvcnRCeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNvcnQtYnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaXNfYXJyYXlfMSA9IHJlcXVpcmUoXCIuL2lzLWFycmF5XCIpO1xudmFyIGlzX3N0cmluZ18xID0gcmVxdWlyZShcIi4vaXMtc3RyaW5nXCIpO1xuZnVuY3Rpb24gc3RhcnRzV2l0aChhcnIsIGUpIHtcbiAgICByZXR1cm4gKGlzX2FycmF5XzEuZGVmYXVsdChhcnIpIHx8IGlzX3N0cmluZ18xLmRlZmF1bHQoYXJyKSkgPyBhcnJbMF0gPT09IGUgOiBmYWxzZTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IHN0YXJ0c1dpdGg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGFydHMtd2l0aC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIHN1YnN0aXR1dGUoc3RyLCBvKSB7XG4gICAgaWYgKCFzdHIgfHwgIW8pIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcP1xceyhbXnt9XSspXFx9L2csIGZ1bmN0aW9uIChtYXRjaCwgbmFtZSkge1xuICAgICAgICBpZiAobWF0Y2guY2hhckF0KDApID09PSAnXFxcXCcpIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRjaC5zbGljZSgxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKG9bbmFtZV0gPT09IHVuZGVmaW5lZCkgPyAnJyA6IG9bbmFtZV07XG4gICAgfSk7XG59XG5leHBvcnRzLmRlZmF1bHQgPSBzdWJzdGl0dXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3Vic3RpdHV0ZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgIHZhciB0aW1lb3V0LCBjb250ZXh0LCBhcmdzLCByZXN1bHQ7XG4gICAgdmFyIHByZXZpb3VzID0gMDtcbiAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHByZXZpb3VzID0gb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSA/IDAgOiBEYXRlLm5vdygpO1xuICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgaWYgKCF0aW1lb3V0KVxuICAgICAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgIH07XG4gICAgdmFyIHRocm90dGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGlmICghcHJldmlvdXMgJiYgb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSlcbiAgICAgICAgICAgIHByZXZpb3VzID0gbm93O1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gd2FpdCAtIChub3cgLSBwcmV2aW91cyk7XG4gICAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBpZiAocmVtYWluaW5nIDw9IDAgfHwgcmVtYWluaW5nID4gd2FpdCkge1xuICAgICAgICAgICAgaWYgKHRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgICAgICBpZiAoIXRpbWVvdXQpXG4gICAgICAgICAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0aW1lb3V0ICYmIG9wdGlvbnMudHJhaWxpbmcgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgdGhyb3R0bGVkLmNhbmNlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICBwcmV2aW91cyA9IDA7XG4gICAgICAgIHRpbWVvdXQgPSBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gdGhyb3R0bGVkO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aHJvdHRsZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19hcnJheV9saWtlXzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheS1saWtlXCIpO1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc19hcnJheV9saWtlXzEuZGVmYXVsdCh2YWx1ZSkgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh2YWx1ZSkgOiBbXTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8tYXJyYXkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgREVHUkVFID0gMTgwIC8gTWF0aC5QSTtcbnZhciB0b0RlZ3JlZSA9IGZ1bmN0aW9uIChyYWRpYW4pIHtcbiAgICByZXR1cm4gREVHUkVFICogcmFkaWFuO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IHRvRGVncmVlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8tZGVncmVlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gcGFyc2VJbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10by1pbnRlZ2VyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIFJBRElBTiA9IE1hdGguUEkgLyAxODA7XG52YXIgdG9SYWRpYW4gPSBmdW5jdGlvbiAoZGVncmVlKSB7XG4gICAgcmV0dXJuIFJBRElBTiAqIGRlZ3JlZTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSB0b1JhZGlhbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRvLXJhZGlhbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAoaXNfbmlsXzEuZGVmYXVsdCh2YWx1ZSkpXG4gICAgICAgIHJldHVybiAnJztcbiAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8tc3RyaW5nLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHVuaXFfMSA9IHJlcXVpcmUoXCIuL3VuaXFcIik7XG52YXIgdW5pb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNvdXJjZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICBzb3VyY2VzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiB1bmlxXzEuZGVmYXVsdChbXS5jb25jYXQuYXBwbHkoW10sIHNvdXJjZXMpKTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSB1bmlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVuaW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGNvbnRhaW5zXzEgPSByZXF1aXJlKFwiLi9jb250YWluc1wiKTtcbnZhciBlYWNoXzEgPSByZXF1aXJlKFwiLi9lYWNoXCIpO1xudmFyIHVuaXEgPSBmdW5jdGlvbiAoYXJyKSB7XG4gICAgdmFyIHJlc3VsdEFyciA9IFtdO1xuICAgIGVhY2hfMS5kZWZhdWx0KGFyciwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgaWYgKCFjb250YWluc18xLmRlZmF1bHQocmVzdWx0QXJyLCBpdGVtKSkge1xuICAgICAgICAgICAgcmVzdWx0QXJyLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0QXJyO1xufTtcbmV4cG9ydHMuZGVmYXVsdCA9IHVuaXE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11bmlxLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIG1hcCA9IHt9O1xuZXhwb3J0cy5kZWZhdWx0ID0gKGZ1bmN0aW9uIChwcmVmaXgpIHtcbiAgICBwcmVmaXggPSBwcmVmaXggfHwgJ2cnO1xuICAgIGlmICghbWFwW3ByZWZpeF0pIHtcbiAgICAgICAgbWFwW3ByZWZpeF0gPSAxO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbWFwW3ByZWZpeF0gKz0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHByZWZpeCArIG1hcFtwcmVmaXhdO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11bmlxdWUtaWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgdG9fc3RyaW5nXzEgPSByZXF1aXJlKFwiLi90by1zdHJpbmdcIik7XG52YXIgdXBwZXJDYXNlID0gZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiB0b19zdHJpbmdfMS5kZWZhdWx0KHN0cikudG9VcHBlckNhc2UoKTtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSB1cHBlckNhc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11cHBlci1jYXNlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIHRvX3N0cmluZ18xID0gcmVxdWlyZShcIi4vdG8tc3RyaW5nXCIpO1xudmFyIHVwcGVyRmlyc3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgc3RyID0gdG9fc3RyaW5nXzEuZGVmYXVsdCh2YWx1ZSk7XG4gICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zdWJzdHJpbmcoMSk7XG59O1xuZXhwb3J0cy5kZWZhdWx0ID0gdXBwZXJGaXJzdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVwcGVyLWZpcnN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIGlzX2FycmF5XzEgPSByZXF1aXJlKFwiLi9pcy1hcnJheVwiKTtcbnZhciBpc19uaWxfMSA9IHJlcXVpcmUoXCIuL2lzLW5pbFwiKTtcbmV4cG9ydHMuZGVmYXVsdCA9IChmdW5jdGlvbiAoZGF0YSwgbmFtZSkge1xuICAgIHZhciByc3QgPSBbXTtcbiAgICB2YXIgdG1wTWFwID0ge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBvYmogPSBkYXRhW2ldO1xuICAgICAgICB2YXIgdmFsdWUgPSBvYmpbbmFtZV07XG4gICAgICAgIGlmICghaXNfbmlsXzEuZGVmYXVsdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIGZsYXR0ZW5cbiAgICAgICAgICAgIGlmICghaXNfYXJyYXlfMS5kZWZhdWx0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsdWUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsID0gdmFsdWVbal07XG4gICAgICAgICAgICAgICAgLy8gdW5pcXVlXG4gICAgICAgICAgICAgICAgaWYgKCF0bXBNYXBbdmFsXSkge1xuICAgICAgICAgICAgICAgICAgICByc3QucHVzaCh2YWwpO1xuICAgICAgICAgICAgICAgICAgICB0bXBNYXBbdmFsXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByc3Q7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZhbHVlcy1vZi1rZXkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZWFjaF8xID0gcmVxdWlyZShcIi4vZWFjaFwiKTtcbnZhciBpc19mdW5jdGlvbl8xID0gcmVxdWlyZShcIi4vaXMtZnVuY3Rpb25cIik7XG4vLyBAdHMtaWdub3JlXG52YXIgdmFsdWVzID0gT2JqZWN0LnZhbHVlcyA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIE9iamVjdC52YWx1ZXMob2JqKTsgfSA6IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgZWFjaF8xLmRlZmF1bHQob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICBpZiAoIShpc19mdW5jdGlvbl8xLmRlZmF1bHQob2JqKSAmJiBrZXkgPT09ICdwcm90b3R5cGUnKSkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5leHBvcnRzLmRlZmF1bHQgPSB2YWx1ZXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD12YWx1ZXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vKipcbiAqIOWwgeijheS6i+S7tu+8jOS+v+S6juS9v+eUqOS4iuS4i+aWh3RoaXMs5ZKM5L6/5LqO6Kej6Zmk5LqL5Lu25pe25L2/55SoXG4gKiBAcHJvdGVjdGVkXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9iaiAgIOWvueixoVxuICogQHBhcmFtICB7U3RyaW5nfSBhY3Rpb24g5LqL5Lu25ZCN56ewXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gICAgICAgIOi/lOWbnuS6i+S7tuWkhOeQhuWHveaVsFxuICovXG5mdW5jdGlvbiB3cmFwQmVoYXZpb3Iob2JqLCBhY3Rpb24pIHtcbiAgICBpZiAob2JqWydfd3JhcF8nICsgYWN0aW9uXSkge1xuICAgICAgICByZXR1cm4gb2JqWydfd3JhcF8nICsgYWN0aW9uXTtcbiAgICB9XG4gICAgdmFyIG1ldGhvZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIG9ialthY3Rpb25dKGUpO1xuICAgIH07XG4gICAgb2JqWydfd3JhcF8nICsgYWN0aW9uXSA9IG1ldGhvZDtcbiAgICByZXR1cm4gbWV0aG9kO1xufVxuZXhwb3J0cy5kZWZhdWx0ID0gd3JhcEJlaGF2aW9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1iZWhhdmlvci5qcy5tYXAiLCIvLyBodHRwczovL2QzanMub3JnL2QzLWNvbG9yLyB2MS40LjEgQ29weXJpZ2h0IDIwMjAgTWlrZSBCb3N0b2NrXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xudHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG50eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbihnbG9iYWwgPSBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwuZDMgPSBnbG9iYWwuZDMgfHwge30pKTtcbn0odGhpcywgZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBkZWZpbmUoY29uc3RydWN0b3IsIGZhY3RvcnksIHByb3RvdHlwZSkge1xuICBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBmYWN0b3J5LnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgcHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY29uc3RydWN0b3I7XG59XG5cbmZ1bmN0aW9uIGV4dGVuZChwYXJlbnQsIGRlZmluaXRpb24pIHtcbiAgdmFyIHByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUocGFyZW50LnByb3RvdHlwZSk7XG4gIGZvciAodmFyIGtleSBpbiBkZWZpbml0aW9uKSBwcm90b3R5cGVba2V5XSA9IGRlZmluaXRpb25ba2V5XTtcbiAgcmV0dXJuIHByb3RvdHlwZTtcbn1cblxuZnVuY3Rpb24gQ29sb3IoKSB7fVxuXG52YXIgZGFya2VyID0gMC43O1xudmFyIGJyaWdodGVyID0gMSAvIGRhcmtlcjtcblxudmFyIHJlSSA9IFwiXFxcXHMqKFsrLV0/XFxcXGQrKVxcXFxzKlwiLFxuICAgIHJlTiA9IFwiXFxcXHMqKFsrLV0/XFxcXGQqXFxcXC4/XFxcXGQrKD86W2VFXVsrLV0/XFxcXGQrKT8pXFxcXHMqXCIsXG4gICAgcmVQID0gXCJcXFxccyooWystXT9cXFxcZCpcXFxcLj9cXFxcZCsoPzpbZUVdWystXT9cXFxcZCspPyklXFxcXHMqXCIsXG4gICAgcmVIZXggPSAvXiMoWzAtOWEtZl17Myw4fSkkLyxcbiAgICByZVJnYkludGVnZXIgPSBuZXcgUmVnRXhwKFwiXnJnYlxcXFwoXCIgKyBbcmVJLCByZUksIHJlSV0gKyBcIlxcXFwpJFwiKSxcbiAgICByZVJnYlBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXnJnYlxcXFwoXCIgKyBbcmVQLCByZVAsIHJlUF0gKyBcIlxcXFwpJFwiKSxcbiAgICByZVJnYmFJbnRlZ2VyID0gbmV3IFJlZ0V4cChcIl5yZ2JhXFxcXChcIiArIFtyZUksIHJlSSwgcmVJLCByZU5dICsgXCJcXFxcKSRcIiksXG4gICAgcmVSZ2JhUGVyY2VudCA9IG5ldyBSZWdFeHAoXCJecmdiYVxcXFwoXCIgKyBbcmVQLCByZVAsIHJlUCwgcmVOXSArIFwiXFxcXCkkXCIpLFxuICAgIHJlSHNsUGVyY2VudCA9IG5ldyBSZWdFeHAoXCJeaHNsXFxcXChcIiArIFtyZU4sIHJlUCwgcmVQXSArIFwiXFxcXCkkXCIpLFxuICAgIHJlSHNsYVBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXmhzbGFcXFxcKFwiICsgW3JlTiwgcmVQLCByZVAsIHJlTl0gKyBcIlxcXFwpJFwiKTtcblxudmFyIG5hbWVkID0ge1xuICBhbGljZWJsdWU6IDB4ZjBmOGZmLFxuICBhbnRpcXVld2hpdGU6IDB4ZmFlYmQ3LFxuICBhcXVhOiAweDAwZmZmZixcbiAgYXF1YW1hcmluZTogMHg3ZmZmZDQsXG4gIGF6dXJlOiAweGYwZmZmZixcbiAgYmVpZ2U6IDB4ZjVmNWRjLFxuICBiaXNxdWU6IDB4ZmZlNGM0LFxuICBibGFjazogMHgwMDAwMDAsXG4gIGJsYW5jaGVkYWxtb25kOiAweGZmZWJjZCxcbiAgYmx1ZTogMHgwMDAwZmYsXG4gIGJsdWV2aW9sZXQ6IDB4OGEyYmUyLFxuICBicm93bjogMHhhNTJhMmEsXG4gIGJ1cmx5d29vZDogMHhkZWI4ODcsXG4gIGNhZGV0Ymx1ZTogMHg1ZjllYTAsXG4gIGNoYXJ0cmV1c2U6IDB4N2ZmZjAwLFxuICBjaG9jb2xhdGU6IDB4ZDI2OTFlLFxuICBjb3JhbDogMHhmZjdmNTAsXG4gIGNvcm5mbG93ZXJibHVlOiAweDY0OTVlZCxcbiAgY29ybnNpbGs6IDB4ZmZmOGRjLFxuICBjcmltc29uOiAweGRjMTQzYyxcbiAgY3lhbjogMHgwMGZmZmYsXG4gIGRhcmtibHVlOiAweDAwMDA4YixcbiAgZGFya2N5YW46IDB4MDA4YjhiLFxuICBkYXJrZ29sZGVucm9kOiAweGI4ODYwYixcbiAgZGFya2dyYXk6IDB4YTlhOWE5LFxuICBkYXJrZ3JlZW46IDB4MDA2NDAwLFxuICBkYXJrZ3JleTogMHhhOWE5YTksXG4gIGRhcmtraGFraTogMHhiZGI3NmIsXG4gIGRhcmttYWdlbnRhOiAweDhiMDA4YixcbiAgZGFya29saXZlZ3JlZW46IDB4NTU2YjJmLFxuICBkYXJrb3JhbmdlOiAweGZmOGMwMCxcbiAgZGFya29yY2hpZDogMHg5OTMyY2MsXG4gIGRhcmtyZWQ6IDB4OGIwMDAwLFxuICBkYXJrc2FsbW9uOiAweGU5OTY3YSxcbiAgZGFya3NlYWdyZWVuOiAweDhmYmM4ZixcbiAgZGFya3NsYXRlYmx1ZTogMHg0ODNkOGIsXG4gIGRhcmtzbGF0ZWdyYXk6IDB4MmY0ZjRmLFxuICBkYXJrc2xhdGVncmV5OiAweDJmNGY0ZixcbiAgZGFya3R1cnF1b2lzZTogMHgwMGNlZDEsXG4gIGRhcmt2aW9sZXQ6IDB4OTQwMGQzLFxuICBkZWVwcGluazogMHhmZjE0OTMsXG4gIGRlZXBza3libHVlOiAweDAwYmZmZixcbiAgZGltZ3JheTogMHg2OTY5NjksXG4gIGRpbWdyZXk6IDB4Njk2OTY5LFxuICBkb2RnZXJibHVlOiAweDFlOTBmZixcbiAgZmlyZWJyaWNrOiAweGIyMjIyMixcbiAgZmxvcmFsd2hpdGU6IDB4ZmZmYWYwLFxuICBmb3Jlc3RncmVlbjogMHgyMjhiMjIsXG4gIGZ1Y2hzaWE6IDB4ZmYwMGZmLFxuICBnYWluc2Jvcm86IDB4ZGNkY2RjLFxuICBnaG9zdHdoaXRlOiAweGY4ZjhmZixcbiAgZ29sZDogMHhmZmQ3MDAsXG4gIGdvbGRlbnJvZDogMHhkYWE1MjAsXG4gIGdyYXk6IDB4ODA4MDgwLFxuICBncmVlbjogMHgwMDgwMDAsXG4gIGdyZWVueWVsbG93OiAweGFkZmYyZixcbiAgZ3JleTogMHg4MDgwODAsXG4gIGhvbmV5ZGV3OiAweGYwZmZmMCxcbiAgaG90cGluazogMHhmZjY5YjQsXG4gIGluZGlhbnJlZDogMHhjZDVjNWMsXG4gIGluZGlnbzogMHg0YjAwODIsXG4gIGl2b3J5OiAweGZmZmZmMCxcbiAga2hha2k6IDB4ZjBlNjhjLFxuICBsYXZlbmRlcjogMHhlNmU2ZmEsXG4gIGxhdmVuZGVyYmx1c2g6IDB4ZmZmMGY1LFxuICBsYXduZ3JlZW46IDB4N2NmYzAwLFxuICBsZW1vbmNoaWZmb246IDB4ZmZmYWNkLFxuICBsaWdodGJsdWU6IDB4YWRkOGU2LFxuICBsaWdodGNvcmFsOiAweGYwODA4MCxcbiAgbGlnaHRjeWFuOiAweGUwZmZmZixcbiAgbGlnaHRnb2xkZW5yb2R5ZWxsb3c6IDB4ZmFmYWQyLFxuICBsaWdodGdyYXk6IDB4ZDNkM2QzLFxuICBsaWdodGdyZWVuOiAweDkwZWU5MCxcbiAgbGlnaHRncmV5OiAweGQzZDNkMyxcbiAgbGlnaHRwaW5rOiAweGZmYjZjMSxcbiAgbGlnaHRzYWxtb246IDB4ZmZhMDdhLFxuICBsaWdodHNlYWdyZWVuOiAweDIwYjJhYSxcbiAgbGlnaHRza3libHVlOiAweDg3Y2VmYSxcbiAgbGlnaHRzbGF0ZWdyYXk6IDB4Nzc4ODk5LFxuICBsaWdodHNsYXRlZ3JleTogMHg3Nzg4OTksXG4gIGxpZ2h0c3RlZWxibHVlOiAweGIwYzRkZSxcbiAgbGlnaHR5ZWxsb3c6IDB4ZmZmZmUwLFxuICBsaW1lOiAweDAwZmYwMCxcbiAgbGltZWdyZWVuOiAweDMyY2QzMixcbiAgbGluZW46IDB4ZmFmMGU2LFxuICBtYWdlbnRhOiAweGZmMDBmZixcbiAgbWFyb29uOiAweDgwMDAwMCxcbiAgbWVkaXVtYXF1YW1hcmluZTogMHg2NmNkYWEsXG4gIG1lZGl1bWJsdWU6IDB4MDAwMGNkLFxuICBtZWRpdW1vcmNoaWQ6IDB4YmE1NWQzLFxuICBtZWRpdW1wdXJwbGU6IDB4OTM3MGRiLFxuICBtZWRpdW1zZWFncmVlbjogMHgzY2IzNzEsXG4gIG1lZGl1bXNsYXRlYmx1ZTogMHg3YjY4ZWUsXG4gIG1lZGl1bXNwcmluZ2dyZWVuOiAweDAwZmE5YSxcbiAgbWVkaXVtdHVycXVvaXNlOiAweDQ4ZDFjYyxcbiAgbWVkaXVtdmlvbGV0cmVkOiAweGM3MTU4NSxcbiAgbWlkbmlnaHRibHVlOiAweDE5MTk3MCxcbiAgbWludGNyZWFtOiAweGY1ZmZmYSxcbiAgbWlzdHlyb3NlOiAweGZmZTRlMSxcbiAgbW9jY2FzaW46IDB4ZmZlNGI1LFxuICBuYXZham93aGl0ZTogMHhmZmRlYWQsXG4gIG5hdnk6IDB4MDAwMDgwLFxuICBvbGRsYWNlOiAweGZkZjVlNixcbiAgb2xpdmU6IDB4ODA4MDAwLFxuICBvbGl2ZWRyYWI6IDB4NmI4ZTIzLFxuICBvcmFuZ2U6IDB4ZmZhNTAwLFxuICBvcmFuZ2VyZWQ6IDB4ZmY0NTAwLFxuICBvcmNoaWQ6IDB4ZGE3MGQ2LFxuICBwYWxlZ29sZGVucm9kOiAweGVlZThhYSxcbiAgcGFsZWdyZWVuOiAweDk4ZmI5OCxcbiAgcGFsZXR1cnF1b2lzZTogMHhhZmVlZWUsXG4gIHBhbGV2aW9sZXRyZWQ6IDB4ZGI3MDkzLFxuICBwYXBheWF3aGlwOiAweGZmZWZkNSxcbiAgcGVhY2hwdWZmOiAweGZmZGFiOSxcbiAgcGVydTogMHhjZDg1M2YsXG4gIHBpbms6IDB4ZmZjMGNiLFxuICBwbHVtOiAweGRkYTBkZCxcbiAgcG93ZGVyYmx1ZTogMHhiMGUwZTYsXG4gIHB1cnBsZTogMHg4MDAwODAsXG4gIHJlYmVjY2FwdXJwbGU6IDB4NjYzMzk5LFxuICByZWQ6IDB4ZmYwMDAwLFxuICByb3N5YnJvd246IDB4YmM4ZjhmLFxuICByb3lhbGJsdWU6IDB4NDE2OWUxLFxuICBzYWRkbGVicm93bjogMHg4YjQ1MTMsXG4gIHNhbG1vbjogMHhmYTgwNzIsXG4gIHNhbmR5YnJvd246IDB4ZjRhNDYwLFxuICBzZWFncmVlbjogMHgyZThiNTcsXG4gIHNlYXNoZWxsOiAweGZmZjVlZSxcbiAgc2llbm5hOiAweGEwNTIyZCxcbiAgc2lsdmVyOiAweGMwYzBjMCxcbiAgc2t5Ymx1ZTogMHg4N2NlZWIsXG4gIHNsYXRlYmx1ZTogMHg2YTVhY2QsXG4gIHNsYXRlZ3JheTogMHg3MDgwOTAsXG4gIHNsYXRlZ3JleTogMHg3MDgwOTAsXG4gIHNub3c6IDB4ZmZmYWZhLFxuICBzcHJpbmdncmVlbjogMHgwMGZmN2YsXG4gIHN0ZWVsYmx1ZTogMHg0NjgyYjQsXG4gIHRhbjogMHhkMmI0OGMsXG4gIHRlYWw6IDB4MDA4MDgwLFxuICB0aGlzdGxlOiAweGQ4YmZkOCxcbiAgdG9tYXRvOiAweGZmNjM0NyxcbiAgdHVycXVvaXNlOiAweDQwZTBkMCxcbiAgdmlvbGV0OiAweGVlODJlZSxcbiAgd2hlYXQ6IDB4ZjVkZWIzLFxuICB3aGl0ZTogMHhmZmZmZmYsXG4gIHdoaXRlc21va2U6IDB4ZjVmNWY1LFxuICB5ZWxsb3c6IDB4ZmZmZjAwLFxuICB5ZWxsb3dncmVlbjogMHg5YWNkMzJcbn07XG5cbmRlZmluZShDb2xvciwgY29sb3IsIHtcbiAgY29weTogZnVuY3Rpb24oY2hhbm5lbHMpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgdGhpcy5jb25zdHJ1Y3RvciwgdGhpcywgY2hhbm5lbHMpO1xuICB9LFxuICBkaXNwbGF5YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucmdiKCkuZGlzcGxheWFibGUoKTtcbiAgfSxcbiAgaGV4OiBjb2xvcl9mb3JtYXRIZXgsIC8vIERlcHJlY2F0ZWQhIFVzZSBjb2xvci5mb3JtYXRIZXguXG4gIGZvcm1hdEhleDogY29sb3JfZm9ybWF0SGV4LFxuICBmb3JtYXRIc2w6IGNvbG9yX2Zvcm1hdEhzbCxcbiAgZm9ybWF0UmdiOiBjb2xvcl9mb3JtYXRSZ2IsXG4gIHRvU3RyaW5nOiBjb2xvcl9mb3JtYXRSZ2Jcbn0pO1xuXG5mdW5jdGlvbiBjb2xvcl9mb3JtYXRIZXgoKSB7XG4gIHJldHVybiB0aGlzLnJnYigpLmZvcm1hdEhleCgpO1xufVxuXG5mdW5jdGlvbiBjb2xvcl9mb3JtYXRIc2woKSB7XG4gIHJldHVybiBoc2xDb252ZXJ0KHRoaXMpLmZvcm1hdEhzbCgpO1xufVxuXG5mdW5jdGlvbiBjb2xvcl9mb3JtYXRSZ2IoKSB7XG4gIHJldHVybiB0aGlzLnJnYigpLmZvcm1hdFJnYigpO1xufVxuXG5mdW5jdGlvbiBjb2xvcihmb3JtYXQpIHtcbiAgdmFyIG0sIGw7XG4gIGZvcm1hdCA9IChmb3JtYXQgKyBcIlwiKS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIChtID0gcmVIZXguZXhlYyhmb3JtYXQpKSA/IChsID0gbVsxXS5sZW5ndGgsIG0gPSBwYXJzZUludChtWzFdLCAxNiksIGwgPT09IDYgPyByZ2JuKG0pIC8vICNmZjAwMDBcbiAgICAgIDogbCA9PT0gMyA/IG5ldyBSZ2IoKG0gPj4gOCAmIDB4ZikgfCAobSA+PiA0ICYgMHhmMCksIChtID4+IDQgJiAweGYpIHwgKG0gJiAweGYwKSwgKChtICYgMHhmKSA8PCA0KSB8IChtICYgMHhmKSwgMSkgLy8gI2YwMFxuICAgICAgOiBsID09PSA4ID8gcmdiYShtID4+IDI0ICYgMHhmZiwgbSA+PiAxNiAmIDB4ZmYsIG0gPj4gOCAmIDB4ZmYsIChtICYgMHhmZikgLyAweGZmKSAvLyAjZmYwMDAwMDBcbiAgICAgIDogbCA9PT0gNCA/IHJnYmEoKG0gPj4gMTIgJiAweGYpIHwgKG0gPj4gOCAmIDB4ZjApLCAobSA+PiA4ICYgMHhmKSB8IChtID4+IDQgJiAweGYwKSwgKG0gPj4gNCAmIDB4ZikgfCAobSAmIDB4ZjApLCAoKChtICYgMHhmKSA8PCA0KSB8IChtICYgMHhmKSkgLyAweGZmKSAvLyAjZjAwMFxuICAgICAgOiBudWxsKSAvLyBpbnZhbGlkIGhleFxuICAgICAgOiAobSA9IHJlUmdiSW50ZWdlci5leGVjKGZvcm1hdCkpID8gbmV3IFJnYihtWzFdLCBtWzJdLCBtWzNdLCAxKSAvLyByZ2IoMjU1LCAwLCAwKVxuICAgICAgOiAobSA9IHJlUmdiUGVyY2VudC5leGVjKGZvcm1hdCkpID8gbmV3IFJnYihtWzFdICogMjU1IC8gMTAwLCBtWzJdICogMjU1IC8gMTAwLCBtWzNdICogMjU1IC8gMTAwLCAxKSAvLyByZ2IoMTAwJSwgMCUsIDAlKVxuICAgICAgOiAobSA9IHJlUmdiYUludGVnZXIuZXhlYyhmb3JtYXQpKSA/IHJnYmEobVsxXSwgbVsyXSwgbVszXSwgbVs0XSkgLy8gcmdiYSgyNTUsIDAsIDAsIDEpXG4gICAgICA6IChtID0gcmVSZ2JhUGVyY2VudC5leGVjKGZvcm1hdCkpID8gcmdiYShtWzFdICogMjU1IC8gMTAwLCBtWzJdICogMjU1IC8gMTAwLCBtWzNdICogMjU1IC8gMTAwLCBtWzRdKSAvLyByZ2IoMTAwJSwgMCUsIDAlLCAxKVxuICAgICAgOiAobSA9IHJlSHNsUGVyY2VudC5leGVjKGZvcm1hdCkpID8gaHNsYShtWzFdLCBtWzJdIC8gMTAwLCBtWzNdIC8gMTAwLCAxKSAvLyBoc2woMTIwLCA1MCUsIDUwJSlcbiAgICAgIDogKG0gPSByZUhzbGFQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyBoc2xhKG1bMV0sIG1bMl0gLyAxMDAsIG1bM10gLyAxMDAsIG1bNF0pIC8vIGhzbGEoMTIwLCA1MCUsIDUwJSwgMSlcbiAgICAgIDogbmFtZWQuaGFzT3duUHJvcGVydHkoZm9ybWF0KSA/IHJnYm4obmFtZWRbZm9ybWF0XSkgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICAgIDogZm9ybWF0ID09PSBcInRyYW5zcGFyZW50XCIgPyBuZXcgUmdiKE5hTiwgTmFOLCBOYU4sIDApXG4gICAgICA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIHJnYm4obikge1xuICByZXR1cm4gbmV3IFJnYihuID4+IDE2ICYgMHhmZiwgbiA+PiA4ICYgMHhmZiwgbiAmIDB4ZmYsIDEpO1xufVxuXG5mdW5jdGlvbiByZ2JhKHIsIGcsIGIsIGEpIHtcbiAgaWYgKGEgPD0gMCkgciA9IGcgPSBiID0gTmFOO1xuICByZXR1cm4gbmV3IFJnYihyLCBnLCBiLCBhKTtcbn1cblxuZnVuY3Rpb24gcmdiQ29udmVydChvKSB7XG4gIGlmICghKG8gaW5zdGFuY2VvZiBDb2xvcikpIG8gPSBjb2xvcihvKTtcbiAgaWYgKCFvKSByZXR1cm4gbmV3IFJnYjtcbiAgbyA9IG8ucmdiKCk7XG4gIHJldHVybiBuZXcgUmdiKG8uciwgby5nLCBvLmIsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIHJnYihyLCBnLCBiLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gcmdiQ29udmVydChyKSA6IG5ldyBSZ2IociwgZywgYiwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBSZ2IociwgZywgYiwgb3BhY2l0eSkge1xuICB0aGlzLnIgPSArcjtcbiAgdGhpcy5nID0gK2c7XG4gIHRoaXMuYiA9ICtiO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKFJnYiwgcmdiLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gYnJpZ2h0ZXIgOiBNYXRoLnBvdyhicmlnaHRlciwgayk7XG4gICAgcmV0dXJuIG5ldyBSZ2IodGhpcy5yICogaywgdGhpcy5nICogaywgdGhpcy5iICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgZGFya2VyOiBmdW5jdGlvbihrKSB7XG4gICAgayA9IGsgPT0gbnVsbCA/IGRhcmtlciA6IE1hdGgucG93KGRhcmtlciwgayk7XG4gICAgcmV0dXJuIG5ldyBSZ2IodGhpcy5yICogaywgdGhpcy5nICogaywgdGhpcy5iICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgcmdiOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAoLTAuNSA8PSB0aGlzLnIgJiYgdGhpcy5yIDwgMjU1LjUpXG4gICAgICAgICYmICgtMC41IDw9IHRoaXMuZyAmJiB0aGlzLmcgPCAyNTUuNSlcbiAgICAgICAgJiYgKC0wLjUgPD0gdGhpcy5iICYmIHRoaXMuYiA8IDI1NS41KVxuICAgICAgICAmJiAoMCA8PSB0aGlzLm9wYWNpdHkgJiYgdGhpcy5vcGFjaXR5IDw9IDEpO1xuICB9LFxuICBoZXg6IHJnYl9mb3JtYXRIZXgsIC8vIERlcHJlY2F0ZWQhIFVzZSBjb2xvci5mb3JtYXRIZXguXG4gIGZvcm1hdEhleDogcmdiX2Zvcm1hdEhleCxcbiAgZm9ybWF0UmdiOiByZ2JfZm9ybWF0UmdiLFxuICB0b1N0cmluZzogcmdiX2Zvcm1hdFJnYlxufSkpO1xuXG5mdW5jdGlvbiByZ2JfZm9ybWF0SGV4KCkge1xuICByZXR1cm4gXCIjXCIgKyBoZXgodGhpcy5yKSArIGhleCh0aGlzLmcpICsgaGV4KHRoaXMuYik7XG59XG5cbmZ1bmN0aW9uIHJnYl9mb3JtYXRSZ2IoKSB7XG4gIHZhciBhID0gdGhpcy5vcGFjaXR5OyBhID0gaXNOYU4oYSkgPyAxIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgYSkpO1xuICByZXR1cm4gKGEgPT09IDEgPyBcInJnYihcIiA6IFwicmdiYShcIilcbiAgICAgICsgTWF0aC5tYXgoMCwgTWF0aC5taW4oMjU1LCBNYXRoLnJvdW5kKHRoaXMucikgfHwgMCkpICsgXCIsIFwiXG4gICAgICArIE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgTWF0aC5yb3VuZCh0aGlzLmcpIHx8IDApKSArIFwiLCBcIlxuICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5iKSB8fCAwKSlcbiAgICAgICsgKGEgPT09IDEgPyBcIilcIiA6IFwiLCBcIiArIGEgKyBcIilcIik7XG59XG5cbmZ1bmN0aW9uIGhleCh2YWx1ZSkge1xuICB2YWx1ZSA9IE1hdGgubWF4KDAsIE1hdGgubWluKDI1NSwgTWF0aC5yb3VuZCh2YWx1ZSkgfHwgMCkpO1xuICByZXR1cm4gKHZhbHVlIDwgMTYgPyBcIjBcIiA6IFwiXCIpICsgdmFsdWUudG9TdHJpbmcoMTYpO1xufVxuXG5mdW5jdGlvbiBoc2xhKGgsIHMsIGwsIGEpIHtcbiAgaWYgKGEgPD0gMCkgaCA9IHMgPSBsID0gTmFOO1xuICBlbHNlIGlmIChsIDw9IDAgfHwgbCA+PSAxKSBoID0gcyA9IE5hTjtcbiAgZWxzZSBpZiAocyA8PSAwKSBoID0gTmFOO1xuICByZXR1cm4gbmV3IEhzbChoLCBzLCBsLCBhKTtcbn1cblxuZnVuY3Rpb24gaHNsQ29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgSHNsKSByZXR1cm4gbmV3IEhzbChvLmgsIG8ucywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0gY29sb3Iobyk7XG4gIGlmICghbykgcmV0dXJuIG5ldyBIc2w7XG4gIGlmIChvIGluc3RhbmNlb2YgSHNsKSByZXR1cm4gbztcbiAgbyA9IG8ucmdiKCk7XG4gIHZhciByID0gby5yIC8gMjU1LFxuICAgICAgZyA9IG8uZyAvIDI1NSxcbiAgICAgIGIgPSBvLmIgLyAyNTUsXG4gICAgICBtaW4gPSBNYXRoLm1pbihyLCBnLCBiKSxcbiAgICAgIG1heCA9IE1hdGgubWF4KHIsIGcsIGIpLFxuICAgICAgaCA9IE5hTixcbiAgICAgIHMgPSBtYXggLSBtaW4sXG4gICAgICBsID0gKG1heCArIG1pbikgLyAyO1xuICBpZiAocykge1xuICAgIGlmIChyID09PSBtYXgpIGggPSAoZyAtIGIpIC8gcyArIChnIDwgYikgKiA2O1xuICAgIGVsc2UgaWYgKGcgPT09IG1heCkgaCA9IChiIC0gcikgLyBzICsgMjtcbiAgICBlbHNlIGggPSAociAtIGcpIC8gcyArIDQ7XG4gICAgcyAvPSBsIDwgMC41ID8gbWF4ICsgbWluIDogMiAtIG1heCAtIG1pbjtcbiAgICBoICo9IDYwO1xuICB9IGVsc2Uge1xuICAgIHMgPSBsID4gMCAmJiBsIDwgMSA/IDAgOiBoO1xuICB9XG4gIHJldHVybiBuZXcgSHNsKGgsIHMsIGwsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGhzbChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaHNsQ29udmVydChoKSA6IG5ldyBIc2woaCwgcywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBIc2woaCwgcywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5zID0gK3M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKEhzbCwgaHNsLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gYnJpZ2h0ZXIgOiBNYXRoLnBvdyhicmlnaHRlciwgayk7XG4gICAgcmV0dXJuIG5ldyBIc2wodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBkYXJrZXIgOiBNYXRoLnBvdyhkYXJrZXIsIGspO1xuICAgIHJldHVybiBuZXcgSHNsKHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoID0gdGhpcy5oICUgMzYwICsgKHRoaXMuaCA8IDApICogMzYwLFxuICAgICAgICBzID0gaXNOYU4oaCkgfHwgaXNOYU4odGhpcy5zKSA/IDAgOiB0aGlzLnMsXG4gICAgICAgIGwgPSB0aGlzLmwsXG4gICAgICAgIG0yID0gbCArIChsIDwgMC41ID8gbCA6IDEgLSBsKSAqIHMsXG4gICAgICAgIG0xID0gMiAqIGwgLSBtMjtcbiAgICByZXR1cm4gbmV3IFJnYihcbiAgICAgIGhzbDJyZ2IoaCA+PSAyNDAgPyBoIC0gMjQwIDogaCArIDEyMCwgbTEsIG0yKSxcbiAgICAgIGhzbDJyZ2IoaCwgbTEsIG0yKSxcbiAgICAgIGhzbDJyZ2IoaCA8IDEyMCA/IGggKyAyNDAgOiBoIC0gMTIwLCBtMSwgbTIpLFxuICAgICAgdGhpcy5vcGFjaXR5XG4gICAgKTtcbiAgfSxcbiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAoMCA8PSB0aGlzLnMgJiYgdGhpcy5zIDw9IDEgfHwgaXNOYU4odGhpcy5zKSlcbiAgICAgICAgJiYgKDAgPD0gdGhpcy5sICYmIHRoaXMubCA8PSAxKVxuICAgICAgICAmJiAoMCA8PSB0aGlzLm9wYWNpdHkgJiYgdGhpcy5vcGFjaXR5IDw9IDEpO1xuICB9LFxuICBmb3JtYXRIc2w6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhID0gdGhpcy5vcGFjaXR5OyBhID0gaXNOYU4oYSkgPyAxIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgYSkpO1xuICAgIHJldHVybiAoYSA9PT0gMSA/IFwiaHNsKFwiIDogXCJoc2xhKFwiKVxuICAgICAgICArICh0aGlzLmggfHwgMCkgKyBcIiwgXCJcbiAgICAgICAgKyAodGhpcy5zIHx8IDApICogMTAwICsgXCIlLCBcIlxuICAgICAgICArICh0aGlzLmwgfHwgMCkgKiAxMDAgKyBcIiVcIlxuICAgICAgICArIChhID09PSAxID8gXCIpXCIgOiBcIiwgXCIgKyBhICsgXCIpXCIpO1xuICB9XG59KSk7XG5cbi8qIEZyb20gRnZEIDEzLjM3LCBDU1MgQ29sb3IgTW9kdWxlIExldmVsIDMgKi9cbmZ1bmN0aW9uIGhzbDJyZ2IoaCwgbTEsIG0yKSB7XG4gIHJldHVybiAoaCA8IDYwID8gbTEgKyAobTIgLSBtMSkgKiBoIC8gNjBcbiAgICAgIDogaCA8IDE4MCA/IG0yXG4gICAgICA6IGggPCAyNDAgPyBtMSArIChtMiAtIG0xKSAqICgyNDAgLSBoKSAvIDYwXG4gICAgICA6IG0xKSAqIDI1NTtcbn1cblxudmFyIGRlZzJyYWQgPSBNYXRoLlBJIC8gMTgwO1xudmFyIHJhZDJkZWcgPSAxODAgLyBNYXRoLlBJO1xuXG4vLyBodHRwczovL29ic2VydmFibGVocS5jb20vQG1ib3N0b2NrL2xhYi1hbmQtcmdiXG52YXIgSyA9IDE4LFxuICAgIFhuID0gMC45NjQyMixcbiAgICBZbiA9IDEsXG4gICAgWm4gPSAwLjgyNTIxLFxuICAgIHQwID0gNCAvIDI5LFxuICAgIHQxID0gNiAvIDI5LFxuICAgIHQyID0gMyAqIHQxICogdDEsXG4gICAgdDMgPSB0MSAqIHQxICogdDE7XG5cbmZ1bmN0aW9uIGxhYkNvbnZlcnQobykge1xuICBpZiAobyBpbnN0YW5jZW9mIExhYikgcmV0dXJuIG5ldyBMYWIoby5sLCBvLmEsIG8uYiwgby5vcGFjaXR5KTtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIY2wpIHJldHVybiBoY2wybGFiKG8pO1xuICBpZiAoIShvIGluc3RhbmNlb2YgUmdiKSkgbyA9IHJnYkNvbnZlcnQobyk7XG4gIHZhciByID0gcmdiMmxyZ2Ioby5yKSxcbiAgICAgIGcgPSByZ2IybHJnYihvLmcpLFxuICAgICAgYiA9IHJnYjJscmdiKG8uYiksXG4gICAgICB5ID0geHl6MmxhYigoMC4yMjI1MDQ1ICogciArIDAuNzE2ODc4NiAqIGcgKyAwLjA2MDYxNjkgKiBiKSAvIFluKSwgeCwgejtcbiAgaWYgKHIgPT09IGcgJiYgZyA9PT0gYikgeCA9IHogPSB5OyBlbHNlIHtcbiAgICB4ID0geHl6MmxhYigoMC40MzYwNzQ3ICogciArIDAuMzg1MDY0OSAqIGcgKyAwLjE0MzA4MDQgKiBiKSAvIFhuKTtcbiAgICB6ID0geHl6MmxhYigoMC4wMTM5MzIyICogciArIDAuMDk3MTA0NSAqIGcgKyAwLjcxNDE3MzMgKiBiKSAvIFpuKTtcbiAgfVxuICByZXR1cm4gbmV3IExhYigxMTYgKiB5IC0gMTYsIDUwMCAqICh4IC0geSksIDIwMCAqICh5IC0geiksIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGdyYXkobCwgb3BhY2l0eSkge1xuICByZXR1cm4gbmV3IExhYihsLCAwLCAwLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGxhYihsLCBhLCBiLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gbGFiQ29udmVydChsKSA6IG5ldyBMYWIobCwgYSwgYiwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBMYWIobCwgYSwgYiwgb3BhY2l0eSkge1xuICB0aGlzLmwgPSArbDtcbiAgdGhpcy5hID0gK2E7XG4gIHRoaXMuYiA9ICtiO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKExhYiwgbGFiLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gbmV3IExhYih0aGlzLmwgKyBLICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5hLCB0aGlzLmIsIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgTGFiKHRoaXMubCAtIEsgKiAoayA9PSBudWxsID8gMSA6IGspLCB0aGlzLmEsIHRoaXMuYiwgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgcmdiOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgeSA9ICh0aGlzLmwgKyAxNikgLyAxMTYsXG4gICAgICAgIHggPSBpc05hTih0aGlzLmEpID8geSA6IHkgKyB0aGlzLmEgLyA1MDAsXG4gICAgICAgIHogPSBpc05hTih0aGlzLmIpID8geSA6IHkgLSB0aGlzLmIgLyAyMDA7XG4gICAgeCA9IFhuICogbGFiMnh5eih4KTtcbiAgICB5ID0gWW4gKiBsYWIyeHl6KHkpO1xuICAgIHogPSBabiAqIGxhYjJ4eXooeik7XG4gICAgcmV0dXJuIG5ldyBSZ2IoXG4gICAgICBscmdiMnJnYiggMy4xMzM4NTYxICogeCAtIDEuNjE2ODY2NyAqIHkgLSAwLjQ5MDYxNDYgKiB6KSxcbiAgICAgIGxyZ2IycmdiKC0wLjk3ODc2ODQgKiB4ICsgMS45MTYxNDE1ICogeSArIDAuMDMzNDU0MCAqIHopLFxuICAgICAgbHJnYjJyZ2IoIDAuMDcxOTQ1MyAqIHggLSAwLjIyODk5MTQgKiB5ICsgMS40MDUyNDI3ICogeiksXG4gICAgICB0aGlzLm9wYWNpdHlcbiAgICApO1xuICB9XG59KSk7XG5cbmZ1bmN0aW9uIHh5ejJsYWIodCkge1xuICByZXR1cm4gdCA+IHQzID8gTWF0aC5wb3codCwgMSAvIDMpIDogdCAvIHQyICsgdDA7XG59XG5cbmZ1bmN0aW9uIGxhYjJ4eXoodCkge1xuICByZXR1cm4gdCA+IHQxID8gdCAqIHQgKiB0IDogdDIgKiAodCAtIHQwKTtcbn1cblxuZnVuY3Rpb24gbHJnYjJyZ2IoeCkge1xuICByZXR1cm4gMjU1ICogKHggPD0gMC4wMDMxMzA4ID8gMTIuOTIgKiB4IDogMS4wNTUgKiBNYXRoLnBvdyh4LCAxIC8gMi40KSAtIDAuMDU1KTtcbn1cblxuZnVuY3Rpb24gcmdiMmxyZ2IoeCkge1xuICByZXR1cm4gKHggLz0gMjU1KSA8PSAwLjA0MDQ1ID8geCAvIDEyLjkyIDogTWF0aC5wb3coKHggKyAwLjA1NSkgLyAxLjA1NSwgMi40KTtcbn1cblxuZnVuY3Rpb24gaGNsQ29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgSGNsKSByZXR1cm4gbmV3IEhjbChvLmgsIG8uYywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgTGFiKSkgbyA9IGxhYkNvbnZlcnQobyk7XG4gIGlmIChvLmEgPT09IDAgJiYgby5iID09PSAwKSByZXR1cm4gbmV3IEhjbChOYU4sIDAgPCBvLmwgJiYgby5sIDwgMTAwID8gMCA6IE5hTiwgby5sLCBvLm9wYWNpdHkpO1xuICB2YXIgaCA9IE1hdGguYXRhbjIoby5iLCBvLmEpICogcmFkMmRlZztcbiAgcmV0dXJuIG5ldyBIY2woaCA8IDAgPyBoICsgMzYwIDogaCwgTWF0aC5zcXJ0KG8uYSAqIG8uYSArIG8uYiAqIG8uYiksIG8ubCwgby5vcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gbGNoKGwsIGMsIGgsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBoY2xDb252ZXJ0KGwpIDogbmV3IEhjbChoLCBjLCBsLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGhjbChoLCBjLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaGNsQ29udmVydChoKSA6IG5ldyBIY2woaCwgYywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBIY2woaCwgYywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5jID0gK2M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZnVuY3Rpb24gaGNsMmxhYihvKSB7XG4gIGlmIChpc05hTihvLmgpKSByZXR1cm4gbmV3IExhYihvLmwsIDAsIDAsIG8ub3BhY2l0eSk7XG4gIHZhciBoID0gby5oICogZGVnMnJhZDtcbiAgcmV0dXJuIG5ldyBMYWIoby5sLCBNYXRoLmNvcyhoKSAqIG8uYywgTWF0aC5zaW4oaCkgKiBvLmMsIG8ub3BhY2l0eSk7XG59XG5cbmRlZmluZShIY2wsIGhjbCwgZXh0ZW5kKENvbG9yLCB7XG4gIGJyaWdodGVyOiBmdW5jdGlvbihrKSB7XG4gICAgcmV0dXJuIG5ldyBIY2wodGhpcy5oLCB0aGlzLmMsIHRoaXMubCArIEsgKiAoayA9PSBudWxsID8gMSA6IGspLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICByZXR1cm4gbmV3IEhjbCh0aGlzLmgsIHRoaXMuYywgdGhpcy5sIC0gSyAqIChrID09IG51bGwgPyAxIDogayksIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGhjbDJsYWIodGhpcykucmdiKCk7XG4gIH1cbn0pKTtcblxudmFyIEEgPSAtMC4xNDg2MSxcbiAgICBCID0gKzEuNzgyNzcsXG4gICAgQyA9IC0wLjI5MjI3LFxuICAgIEQgPSAtMC45MDY0OSxcbiAgICBFID0gKzEuOTcyOTQsXG4gICAgRUQgPSBFICogRCxcbiAgICBFQiA9IEUgKiBCLFxuICAgIEJDX0RBID0gQiAqIEMgLSBEICogQTtcblxuZnVuY3Rpb24gY3ViZWhlbGl4Q29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgQ3ViZWhlbGl4KSByZXR1cm4gbmV3IEN1YmVoZWxpeChvLmgsIG8ucywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgUmdiKSkgbyA9IHJnYkNvbnZlcnQobyk7XG4gIHZhciByID0gby5yIC8gMjU1LFxuICAgICAgZyA9IG8uZyAvIDI1NSxcbiAgICAgIGIgPSBvLmIgLyAyNTUsXG4gICAgICBsID0gKEJDX0RBICogYiArIEVEICogciAtIEVCICogZykgLyAoQkNfREEgKyBFRCAtIEVCKSxcbiAgICAgIGJsID0gYiAtIGwsXG4gICAgICBrID0gKEUgKiAoZyAtIGwpIC0gQyAqIGJsKSAvIEQsXG4gICAgICBzID0gTWF0aC5zcXJ0KGsgKiBrICsgYmwgKiBibCkgLyAoRSAqIGwgKiAoMSAtIGwpKSwgLy8gTmFOIGlmIGw9MCBvciBsPTFcbiAgICAgIGggPSBzID8gTWF0aC5hdGFuMihrLCBibCkgKiByYWQyZGVnIC0gMTIwIDogTmFOO1xuICByZXR1cm4gbmV3IEN1YmVoZWxpeChoIDwgMCA/IGggKyAzNjAgOiBoLCBzLCBsLCBvLm9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBjdWJlaGVsaXgoaCwgcywgbCwgb3BhY2l0eSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IGN1YmVoZWxpeENvbnZlcnQoaCkgOiBuZXcgQ3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkgPT0gbnVsbCA/IDEgOiBvcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gQ3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkpIHtcbiAgdGhpcy5oID0gK2g7XG4gIHRoaXMucyA9ICtzO1xuICB0aGlzLmwgPSArbDtcbiAgdGhpcy5vcGFjaXR5ID0gK29wYWNpdHk7XG59XG5cbmRlZmluZShDdWJlaGVsaXgsIGN1YmVoZWxpeCwgZXh0ZW5kKENvbG9yLCB7XG4gIGJyaWdodGVyOiBmdW5jdGlvbihrKSB7XG4gICAgayA9IGsgPT0gbnVsbCA/IGJyaWdodGVyIDogTWF0aC5wb3coYnJpZ2h0ZXIsIGspO1xuICAgIHJldHVybiBuZXcgQ3ViZWhlbGl4KHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gZGFya2VyIDogTWF0aC5wb3coZGFya2VyLCBrKTtcbiAgICByZXR1cm4gbmV3IEN1YmVoZWxpeCh0aGlzLmgsIHRoaXMucywgdGhpcy5sICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgcmdiOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgaCA9IGlzTmFOKHRoaXMuaCkgPyAwIDogKHRoaXMuaCArIDEyMCkgKiBkZWcycmFkLFxuICAgICAgICBsID0gK3RoaXMubCxcbiAgICAgICAgYSA9IGlzTmFOKHRoaXMucykgPyAwIDogdGhpcy5zICogbCAqICgxIC0gbCksXG4gICAgICAgIGNvc2ggPSBNYXRoLmNvcyhoKSxcbiAgICAgICAgc2luaCA9IE1hdGguc2luKGgpO1xuICAgIHJldHVybiBuZXcgUmdiKFxuICAgICAgMjU1ICogKGwgKyBhICogKEEgKiBjb3NoICsgQiAqIHNpbmgpKSxcbiAgICAgIDI1NSAqIChsICsgYSAqIChDICogY29zaCArIEQgKiBzaW5oKSksXG4gICAgICAyNTUgKiAobCArIGEgKiAoRSAqIGNvc2gpKSxcbiAgICAgIHRoaXMub3BhY2l0eVxuICAgICk7XG4gIH1cbn0pKTtcblxuZXhwb3J0cy5jb2xvciA9IGNvbG9yO1xuZXhwb3J0cy5jdWJlaGVsaXggPSBjdWJlaGVsaXg7XG5leHBvcnRzLmdyYXkgPSBncmF5O1xuZXhwb3J0cy5oY2wgPSBoY2w7XG5leHBvcnRzLmhzbCA9IGhzbDtcbmV4cG9ydHMubGFiID0gbGFiO1xuZXhwb3J0cy5sY2ggPSBsY2g7XG5leHBvcnRzLnJnYiA9IHJnYjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxufSkpO1xuIiwiLy8gaHR0cHM6Ly9kM2pzLm9yZy9kMy1lYXNlLyB2MS4wLjcgQ29weXJpZ2h0IDIwMjAgTWlrZSBCb3N0b2NrXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xudHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG50eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbihnbG9iYWwgPSBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwuZDMgPSBnbG9iYWwuZDMgfHwge30pKTtcbn0odGhpcywgZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBsaW5lYXIodCkge1xuICByZXR1cm4gK3Q7XG59XG5cbmZ1bmN0aW9uIHF1YWRJbih0KSB7XG4gIHJldHVybiB0ICogdDtcbn1cblxuZnVuY3Rpb24gcXVhZE91dCh0KSB7XG4gIHJldHVybiB0ICogKDIgLSB0KTtcbn1cblxuZnVuY3Rpb24gcXVhZEluT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gdCAqIHQgOiAtLXQgKiAoMiAtIHQpICsgMSkgLyAyO1xufVxuXG5mdW5jdGlvbiBjdWJpY0luKHQpIHtcbiAgcmV0dXJuIHQgKiB0ICogdDtcbn1cblxuZnVuY3Rpb24gY3ViaWNPdXQodCkge1xuICByZXR1cm4gLS10ICogdCAqIHQgKyAxO1xufVxuXG5mdW5jdGlvbiBjdWJpY0luT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gdCAqIHQgKiB0IDogKHQgLT0gMikgKiB0ICogdCArIDIpIC8gMjtcbn1cblxudmFyIGV4cG9uZW50ID0gMztcblxudmFyIHBvbHlJbiA9IChmdW5jdGlvbiBjdXN0b20oZSkge1xuICBlID0gK2U7XG5cbiAgZnVuY3Rpb24gcG9seUluKHQpIHtcbiAgICByZXR1cm4gTWF0aC5wb3codCwgZSk7XG4gIH1cblxuICBwb2x5SW4uZXhwb25lbnQgPSBjdXN0b207XG5cbiAgcmV0dXJuIHBvbHlJbjtcbn0pKGV4cG9uZW50KTtcblxudmFyIHBvbHlPdXQgPSAoZnVuY3Rpb24gY3VzdG9tKGUpIHtcbiAgZSA9ICtlO1xuXG4gIGZ1bmN0aW9uIHBvbHlPdXQodCkge1xuICAgIHJldHVybiAxIC0gTWF0aC5wb3coMSAtIHQsIGUpO1xuICB9XG5cbiAgcG9seU91dC5leHBvbmVudCA9IGN1c3RvbTtcblxuICByZXR1cm4gcG9seU91dDtcbn0pKGV4cG9uZW50KTtcblxudmFyIHBvbHlJbk91dCA9IChmdW5jdGlvbiBjdXN0b20oZSkge1xuICBlID0gK2U7XG5cbiAgZnVuY3Rpb24gcG9seUluT3V0KHQpIHtcbiAgICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyBNYXRoLnBvdyh0LCBlKSA6IDIgLSBNYXRoLnBvdygyIC0gdCwgZSkpIC8gMjtcbiAgfVxuXG4gIHBvbHlJbk91dC5leHBvbmVudCA9IGN1c3RvbTtcblxuICByZXR1cm4gcG9seUluT3V0O1xufSkoZXhwb25lbnQpO1xuXG52YXIgcGkgPSBNYXRoLlBJLFxuICAgIGhhbGZQaSA9IHBpIC8gMjtcblxuZnVuY3Rpb24gc2luSW4odCkge1xuICByZXR1cm4gKCt0ID09PSAxKSA/IDEgOiAxIC0gTWF0aC5jb3ModCAqIGhhbGZQaSk7XG59XG5cbmZ1bmN0aW9uIHNpbk91dCh0KSB7XG4gIHJldHVybiBNYXRoLnNpbih0ICogaGFsZlBpKTtcbn1cblxuZnVuY3Rpb24gc2luSW5PdXQodCkge1xuICByZXR1cm4gKDEgLSBNYXRoLmNvcyhwaSAqIHQpKSAvIDI7XG59XG5cbi8vIHRwbXQgaXMgdHdvIHBvd2VyIG1pbnVzIHRlbiB0aW1lcyB0IHNjYWxlZCB0byBbMCwxXVxuZnVuY3Rpb24gdHBtdCh4KSB7XG4gIHJldHVybiAoTWF0aC5wb3coMiwgLTEwICogeCkgLSAwLjAwMDk3NjU2MjUpICogMS4wMDA5Nzc1MTcxMDY1NDk0O1xufVxuXG5mdW5jdGlvbiBleHBJbih0KSB7XG4gIHJldHVybiB0cG10KDEgLSArdCk7XG59XG5cbmZ1bmN0aW9uIGV4cE91dCh0KSB7XG4gIHJldHVybiAxIC0gdHBtdCh0KTtcbn1cblxuZnVuY3Rpb24gZXhwSW5PdXQodCkge1xuICByZXR1cm4gKCh0ICo9IDIpIDw9IDEgPyB0cG10KDEgLSB0KSA6IDIgLSB0cG10KHQgLSAxKSkgLyAyO1xufVxuXG5mdW5jdGlvbiBjaXJjbGVJbih0KSB7XG4gIHJldHVybiAxIC0gTWF0aC5zcXJ0KDEgLSB0ICogdCk7XG59XG5cbmZ1bmN0aW9uIGNpcmNsZU91dCh0KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoMSAtIC0tdCAqIHQpO1xufVxuXG5mdW5jdGlvbiBjaXJjbGVJbk91dCh0KSB7XG4gIHJldHVybiAoKHQgKj0gMikgPD0gMSA/IDEgLSBNYXRoLnNxcnQoMSAtIHQgKiB0KSA6IE1hdGguc3FydCgxIC0gKHQgLT0gMikgKiB0KSArIDEpIC8gMjtcbn1cblxudmFyIGIxID0gNCAvIDExLFxuICAgIGIyID0gNiAvIDExLFxuICAgIGIzID0gOCAvIDExLFxuICAgIGI0ID0gMyAvIDQsXG4gICAgYjUgPSA5IC8gMTEsXG4gICAgYjYgPSAxMCAvIDExLFxuICAgIGI3ID0gMTUgLyAxNixcbiAgICBiOCA9IDIxIC8gMjIsXG4gICAgYjkgPSA2MyAvIDY0LFxuICAgIGIwID0gMSAvIGIxIC8gYjE7XG5cbmZ1bmN0aW9uIGJvdW5jZUluKHQpIHtcbiAgcmV0dXJuIDEgLSBib3VuY2VPdXQoMSAtIHQpO1xufVxuXG5mdW5jdGlvbiBib3VuY2VPdXQodCkge1xuICByZXR1cm4gKHQgPSArdCkgPCBiMSA/IGIwICogdCAqIHQgOiB0IDwgYjMgPyBiMCAqICh0IC09IGIyKSAqIHQgKyBiNCA6IHQgPCBiNiA/IGIwICogKHQgLT0gYjUpICogdCArIGI3IDogYjAgKiAodCAtPSBiOCkgKiB0ICsgYjk7XG59XG5cbmZ1bmN0aW9uIGJvdW5jZUluT3V0KHQpIHtcbiAgcmV0dXJuICgodCAqPSAyKSA8PSAxID8gMSAtIGJvdW5jZU91dCgxIC0gdCkgOiBib3VuY2VPdXQodCAtIDEpICsgMSkgLyAyO1xufVxuXG52YXIgb3ZlcnNob290ID0gMS43MDE1ODtcblxudmFyIGJhY2tJbiA9IChmdW5jdGlvbiBjdXN0b20ocykge1xuICBzID0gK3M7XG5cbiAgZnVuY3Rpb24gYmFja0luKHQpIHtcbiAgICByZXR1cm4gKHQgPSArdCkgKiB0ICogKHMgKiAodCAtIDEpICsgdCk7XG4gIH1cblxuICBiYWNrSW4ub3ZlcnNob290ID0gY3VzdG9tO1xuXG4gIHJldHVybiBiYWNrSW47XG59KShvdmVyc2hvb3QpO1xuXG52YXIgYmFja091dCA9IChmdW5jdGlvbiBjdXN0b20ocykge1xuICBzID0gK3M7XG5cbiAgZnVuY3Rpb24gYmFja091dCh0KSB7XG4gICAgcmV0dXJuIC0tdCAqIHQgKiAoKHQgKyAxKSAqIHMgKyB0KSArIDE7XG4gIH1cblxuICBiYWNrT3V0Lm92ZXJzaG9vdCA9IGN1c3RvbTtcblxuICByZXR1cm4gYmFja091dDtcbn0pKG92ZXJzaG9vdCk7XG5cbnZhciBiYWNrSW5PdXQgPSAoZnVuY3Rpb24gY3VzdG9tKHMpIHtcbiAgcyA9ICtzO1xuXG4gIGZ1bmN0aW9uIGJhY2tJbk91dCh0KSB7XG4gICAgcmV0dXJuICgodCAqPSAyKSA8IDEgPyB0ICogdCAqICgocyArIDEpICogdCAtIHMpIDogKHQgLT0gMikgKiB0ICogKChzICsgMSkgKiB0ICsgcykgKyAyKSAvIDI7XG4gIH1cblxuICBiYWNrSW5PdXQub3ZlcnNob290ID0gY3VzdG9tO1xuXG4gIHJldHVybiBiYWNrSW5PdXQ7XG59KShvdmVyc2hvb3QpO1xuXG52YXIgdGF1ID0gMiAqIE1hdGguUEksXG4gICAgYW1wbGl0dWRlID0gMSxcbiAgICBwZXJpb2QgPSAwLjM7XG5cbnZhciBlbGFzdGljSW4gPSAoZnVuY3Rpb24gY3VzdG9tKGEsIHApIHtcbiAgdmFyIHMgPSBNYXRoLmFzaW4oMSAvIChhID0gTWF0aC5tYXgoMSwgYSkpKSAqIChwIC89IHRhdSk7XG5cbiAgZnVuY3Rpb24gZWxhc3RpY0luKHQpIHtcbiAgICByZXR1cm4gYSAqIHRwbXQoLSgtLXQpKSAqIE1hdGguc2luKChzIC0gdCkgLyBwKTtcbiAgfVxuXG4gIGVsYXN0aWNJbi5hbXBsaXR1ZGUgPSBmdW5jdGlvbihhKSB7IHJldHVybiBjdXN0b20oYSwgcCAqIHRhdSk7IH07XG4gIGVsYXN0aWNJbi5wZXJpb2QgPSBmdW5jdGlvbihwKSB7IHJldHVybiBjdXN0b20oYSwgcCk7IH07XG5cbiAgcmV0dXJuIGVsYXN0aWNJbjtcbn0pKGFtcGxpdHVkZSwgcGVyaW9kKTtcblxudmFyIGVsYXN0aWNPdXQgPSAoZnVuY3Rpb24gY3VzdG9tKGEsIHApIHtcbiAgdmFyIHMgPSBNYXRoLmFzaW4oMSAvIChhID0gTWF0aC5tYXgoMSwgYSkpKSAqIChwIC89IHRhdSk7XG5cbiAgZnVuY3Rpb24gZWxhc3RpY091dCh0KSB7XG4gICAgcmV0dXJuIDEgLSBhICogdHBtdCh0ID0gK3QpICogTWF0aC5zaW4oKHQgKyBzKSAvIHApO1xuICB9XG5cbiAgZWxhc3RpY091dC5hbXBsaXR1ZGUgPSBmdW5jdGlvbihhKSB7IHJldHVybiBjdXN0b20oYSwgcCAqIHRhdSk7IH07XG4gIGVsYXN0aWNPdXQucGVyaW9kID0gZnVuY3Rpb24ocCkgeyByZXR1cm4gY3VzdG9tKGEsIHApOyB9O1xuXG4gIHJldHVybiBlbGFzdGljT3V0O1xufSkoYW1wbGl0dWRlLCBwZXJpb2QpO1xuXG52YXIgZWxhc3RpY0luT3V0ID0gKGZ1bmN0aW9uIGN1c3RvbShhLCBwKSB7XG4gIHZhciBzID0gTWF0aC5hc2luKDEgLyAoYSA9IE1hdGgubWF4KDEsIGEpKSkgKiAocCAvPSB0YXUpO1xuXG4gIGZ1bmN0aW9uIGVsYXN0aWNJbk91dCh0KSB7XG4gICAgcmV0dXJuICgodCA9IHQgKiAyIC0gMSkgPCAwXG4gICAgICAgID8gYSAqIHRwbXQoLXQpICogTWF0aC5zaW4oKHMgLSB0KSAvIHApXG4gICAgICAgIDogMiAtIGEgKiB0cG10KHQpICogTWF0aC5zaW4oKHMgKyB0KSAvIHApKSAvIDI7XG4gIH1cblxuICBlbGFzdGljSW5PdXQuYW1wbGl0dWRlID0gZnVuY3Rpb24oYSkgeyByZXR1cm4gY3VzdG9tKGEsIHAgKiB0YXUpOyB9O1xuICBlbGFzdGljSW5PdXQucGVyaW9kID0gZnVuY3Rpb24ocCkgeyByZXR1cm4gY3VzdG9tKGEsIHApOyB9O1xuXG4gIHJldHVybiBlbGFzdGljSW5PdXQ7XG59KShhbXBsaXR1ZGUsIHBlcmlvZCk7XG5cbmV4cG9ydHMuZWFzZUJhY2sgPSBiYWNrSW5PdXQ7XG5leHBvcnRzLmVhc2VCYWNrSW4gPSBiYWNrSW47XG5leHBvcnRzLmVhc2VCYWNrSW5PdXQgPSBiYWNrSW5PdXQ7XG5leHBvcnRzLmVhc2VCYWNrT3V0ID0gYmFja091dDtcbmV4cG9ydHMuZWFzZUJvdW5jZSA9IGJvdW5jZU91dDtcbmV4cG9ydHMuZWFzZUJvdW5jZUluID0gYm91bmNlSW47XG5leHBvcnRzLmVhc2VCb3VuY2VJbk91dCA9IGJvdW5jZUluT3V0O1xuZXhwb3J0cy5lYXNlQm91bmNlT3V0ID0gYm91bmNlT3V0O1xuZXhwb3J0cy5lYXNlQ2lyY2xlID0gY2lyY2xlSW5PdXQ7XG5leHBvcnRzLmVhc2VDaXJjbGVJbiA9IGNpcmNsZUluO1xuZXhwb3J0cy5lYXNlQ2lyY2xlSW5PdXQgPSBjaXJjbGVJbk91dDtcbmV4cG9ydHMuZWFzZUNpcmNsZU91dCA9IGNpcmNsZU91dDtcbmV4cG9ydHMuZWFzZUN1YmljID0gY3ViaWNJbk91dDtcbmV4cG9ydHMuZWFzZUN1YmljSW4gPSBjdWJpY0luO1xuZXhwb3J0cy5lYXNlQ3ViaWNJbk91dCA9IGN1YmljSW5PdXQ7XG5leHBvcnRzLmVhc2VDdWJpY091dCA9IGN1YmljT3V0O1xuZXhwb3J0cy5lYXNlRWxhc3RpYyA9IGVsYXN0aWNPdXQ7XG5leHBvcnRzLmVhc2VFbGFzdGljSW4gPSBlbGFzdGljSW47XG5leHBvcnRzLmVhc2VFbGFzdGljSW5PdXQgPSBlbGFzdGljSW5PdXQ7XG5leHBvcnRzLmVhc2VFbGFzdGljT3V0ID0gZWxhc3RpY091dDtcbmV4cG9ydHMuZWFzZUV4cCA9IGV4cEluT3V0O1xuZXhwb3J0cy5lYXNlRXhwSW4gPSBleHBJbjtcbmV4cG9ydHMuZWFzZUV4cEluT3V0ID0gZXhwSW5PdXQ7XG5leHBvcnRzLmVhc2VFeHBPdXQgPSBleHBPdXQ7XG5leHBvcnRzLmVhc2VMaW5lYXIgPSBsaW5lYXI7XG5leHBvcnRzLmVhc2VQb2x5ID0gcG9seUluT3V0O1xuZXhwb3J0cy5lYXNlUG9seUluID0gcG9seUluO1xuZXhwb3J0cy5lYXNlUG9seUluT3V0ID0gcG9seUluT3V0O1xuZXhwb3J0cy5lYXNlUG9seU91dCA9IHBvbHlPdXQ7XG5leHBvcnRzLmVhc2VRdWFkID0gcXVhZEluT3V0O1xuZXhwb3J0cy5lYXNlUXVhZEluID0gcXVhZEluO1xuZXhwb3J0cy5lYXNlUXVhZEluT3V0ID0gcXVhZEluT3V0O1xuZXhwb3J0cy5lYXNlUXVhZE91dCA9IHF1YWRPdXQ7XG5leHBvcnRzLmVhc2VTaW4gPSBzaW5Jbk91dDtcbmV4cG9ydHMuZWFzZVNpbkluID0gc2luSW47XG5leHBvcnRzLmVhc2VTaW5Jbk91dCA9IHNpbkluT3V0O1xuZXhwb3J0cy5lYXNlU2luT3V0ID0gc2luT3V0O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG59KSk7XG4iLCIvLyBodHRwczovL2QzanMub3JnL2QzLWludGVycG9sYXRlLyB2MS40LjAgQ29weXJpZ2h0IDIwMTkgTWlrZSBCb3N0b2NrXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xudHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzLCByZXF1aXJlKCdkMy1jb2xvcicpKSA6XG50eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJywgJ2QzLWNvbG9yJ10sIGZhY3RvcnkpIDpcbihnbG9iYWwgPSBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwuZDMgPSBnbG9iYWwuZDMgfHwge30sIGdsb2JhbC5kMykpO1xufSh0aGlzLCBmdW5jdGlvbiAoZXhwb3J0cywgZDNDb2xvcikgeyAndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIGJhc2lzKHQxLCB2MCwgdjEsIHYyLCB2Mykge1xuICB2YXIgdDIgPSB0MSAqIHQxLCB0MyA9IHQyICogdDE7XG4gIHJldHVybiAoKDEgLSAzICogdDEgKyAzICogdDIgLSB0MykgKiB2MFxuICAgICAgKyAoNCAtIDYgKiB0MiArIDMgKiB0MykgKiB2MVxuICAgICAgKyAoMSArIDMgKiB0MSArIDMgKiB0MiAtIDMgKiB0MykgKiB2MlxuICAgICAgKyB0MyAqIHYzKSAvIDY7XG59XG5cbmZ1bmN0aW9uIGJhc2lzJDEodmFsdWVzKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGkgPSB0IDw9IDAgPyAodCA9IDApIDogdCA+PSAxID8gKHQgPSAxLCBuIC0gMSkgOiBNYXRoLmZsb29yKHQgKiBuKSxcbiAgICAgICAgdjEgPSB2YWx1ZXNbaV0sXG4gICAgICAgIHYyID0gdmFsdWVzW2kgKyAxXSxcbiAgICAgICAgdjAgPSBpID4gMCA/IHZhbHVlc1tpIC0gMV0gOiAyICogdjEgLSB2MixcbiAgICAgICAgdjMgPSBpIDwgbiAtIDEgPyB2YWx1ZXNbaSArIDJdIDogMiAqIHYyIC0gdjE7XG4gICAgcmV0dXJuIGJhc2lzKCh0IC0gaSAvIG4pICogbiwgdjAsIHYxLCB2MiwgdjMpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBiYXNpc0Nsb3NlZCh2YWx1ZXMpIHtcbiAgdmFyIG4gPSB2YWx1ZXMubGVuZ3RoO1xuICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgIHZhciBpID0gTWF0aC5mbG9vcigoKHQgJT0gMSkgPCAwID8gKyt0IDogdCkgKiBuKSxcbiAgICAgICAgdjAgPSB2YWx1ZXNbKGkgKyBuIC0gMSkgJSBuXSxcbiAgICAgICAgdjEgPSB2YWx1ZXNbaSAlIG5dLFxuICAgICAgICB2MiA9IHZhbHVlc1soaSArIDEpICUgbl0sXG4gICAgICAgIHYzID0gdmFsdWVzWyhpICsgMikgJSBuXTtcbiAgICByZXR1cm4gYmFzaXMoKHQgLSBpIC8gbikgKiBuLCB2MCwgdjEsIHYyLCB2Myk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbnN0YW50KHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufVxuXG5mdW5jdGlvbiBsaW5lYXIoYSwgZCkge1xuICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBhICsgdCAqIGQ7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGV4cG9uZW50aWFsKGEsIGIsIHkpIHtcbiAgcmV0dXJuIGEgPSBNYXRoLnBvdyhhLCB5KSwgYiA9IE1hdGgucG93KGIsIHkpIC0gYSwgeSA9IDEgLyB5LCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIE1hdGgucG93KGEgKyB0ICogYiwgeSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGh1ZShhLCBiKSB7XG4gIHZhciBkID0gYiAtIGE7XG4gIHJldHVybiBkID8gbGluZWFyKGEsIGQgPiAxODAgfHwgZCA8IC0xODAgPyBkIC0gMzYwICogTWF0aC5yb3VuZChkIC8gMzYwKSA6IGQpIDogY29uc3RhbnQoaXNOYU4oYSkgPyBiIDogYSk7XG59XG5cbmZ1bmN0aW9uIGdhbW1hKHkpIHtcbiAgcmV0dXJuICh5ID0gK3kpID09PSAxID8gbm9nYW1tYSA6IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gYiAtIGEgPyBleHBvbmVudGlhbChhLCBiLCB5KSA6IGNvbnN0YW50KGlzTmFOKGEpID8gYiA6IGEpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBub2dhbW1hKGEsIGIpIHtcbiAgdmFyIGQgPSBiIC0gYTtcbiAgcmV0dXJuIGQgPyBsaW5lYXIoYSwgZCkgOiBjb25zdGFudChpc05hTihhKSA/IGIgOiBhKTtcbn1cblxudmFyIHJnYiA9IChmdW5jdGlvbiByZ2JHYW1tYSh5KSB7XG4gIHZhciBjb2xvciA9IGdhbW1hKHkpO1xuXG4gIGZ1bmN0aW9uIHJnYihzdGFydCwgZW5kKSB7XG4gICAgdmFyIHIgPSBjb2xvcigoc3RhcnQgPSBkM0NvbG9yLnJnYihzdGFydCkpLnIsIChlbmQgPSBkM0NvbG9yLnJnYihlbmQpKS5yKSxcbiAgICAgICAgZyA9IGNvbG9yKHN0YXJ0LmcsIGVuZC5nKSxcbiAgICAgICAgYiA9IGNvbG9yKHN0YXJ0LmIsIGVuZC5iKSxcbiAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBzdGFydC5yID0gcih0KTtcbiAgICAgIHN0YXJ0LmcgPSBnKHQpO1xuICAgICAgc3RhcnQuYiA9IGIodCk7XG4gICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICAgIHJldHVybiBzdGFydCArIFwiXCI7XG4gICAgfTtcbiAgfVxuXG4gIHJnYi5nYW1tYSA9IHJnYkdhbW1hO1xuXG4gIHJldHVybiByZ2I7XG59KSgxKTtcblxuZnVuY3Rpb24gcmdiU3BsaW5lKHNwbGluZSkge1xuICByZXR1cm4gZnVuY3Rpb24oY29sb3JzKSB7XG4gICAgdmFyIG4gPSBjb2xvcnMubGVuZ3RoLFxuICAgICAgICByID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBnID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBiID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBpLCBjb2xvcjtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBjb2xvciA9IGQzQ29sb3IucmdiKGNvbG9yc1tpXSk7XG4gICAgICByW2ldID0gY29sb3IuciB8fCAwO1xuICAgICAgZ1tpXSA9IGNvbG9yLmcgfHwgMDtcbiAgICAgIGJbaV0gPSBjb2xvci5iIHx8IDA7XG4gICAgfVxuICAgIHIgPSBzcGxpbmUocik7XG4gICAgZyA9IHNwbGluZShnKTtcbiAgICBiID0gc3BsaW5lKGIpO1xuICAgIGNvbG9yLm9wYWNpdHkgPSAxO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBjb2xvci5yID0gcih0KTtcbiAgICAgIGNvbG9yLmcgPSBnKHQpO1xuICAgICAgY29sb3IuYiA9IGIodCk7XG4gICAgICByZXR1cm4gY29sb3IgKyBcIlwiO1xuICAgIH07XG4gIH07XG59XG5cbnZhciByZ2JCYXNpcyA9IHJnYlNwbGluZShiYXNpcyQxKTtcbnZhciByZ2JCYXNpc0Nsb3NlZCA9IHJnYlNwbGluZShiYXNpc0Nsb3NlZCk7XG5cbmZ1bmN0aW9uIG51bWJlckFycmF5KGEsIGIpIHtcbiAgaWYgKCFiKSBiID0gW107XG4gIHZhciBuID0gYSA/IE1hdGgubWluKGIubGVuZ3RoLCBhLmxlbmd0aCkgOiAwLFxuICAgICAgYyA9IGIuc2xpY2UoKSxcbiAgICAgIGk7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgY1tpXSA9IGFbaV0gKiAoMSAtIHQpICsgYltpXSAqIHQ7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyQXJyYXkoeCkge1xuICByZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KHgpICYmICEoeCBpbnN0YW5jZW9mIERhdGFWaWV3KTtcbn1cblxuZnVuY3Rpb24gYXJyYXkoYSwgYikge1xuICByZXR1cm4gKGlzTnVtYmVyQXJyYXkoYikgPyBudW1iZXJBcnJheSA6IGdlbmVyaWNBcnJheSkoYSwgYik7XG59XG5cbmZ1bmN0aW9uIGdlbmVyaWNBcnJheShhLCBiKSB7XG4gIHZhciBuYiA9IGIgPyBiLmxlbmd0aCA6IDAsXG4gICAgICBuYSA9IGEgPyBNYXRoLm1pbihuYiwgYS5sZW5ndGgpIDogMCxcbiAgICAgIHggPSBuZXcgQXJyYXkobmEpLFxuICAgICAgYyA9IG5ldyBBcnJheShuYiksXG4gICAgICBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuYTsgKytpKSB4W2ldID0gdmFsdWUoYVtpXSwgYltpXSk7XG4gIGZvciAoOyBpIDwgbmI7ICsraSkgY1tpXSA9IGJbaV07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbmE7ICsraSkgY1tpXSA9IHhbaV0odCk7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRhdGUoYSwgYikge1xuICB2YXIgZCA9IG5ldyBEYXRlO1xuICByZXR1cm4gYSA9ICthLCBiID0gK2IsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gZC5zZXRUaW1lKGEgKiAoMSAtIHQpICsgYiAqIHQpLCBkO1xuICB9O1xufVxuXG5mdW5jdGlvbiBudW1iZXIoYSwgYikge1xuICByZXR1cm4gYSA9ICthLCBiID0gK2IsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gYSAqICgxIC0gdCkgKyBiICogdDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gb2JqZWN0KGEsIGIpIHtcbiAgdmFyIGkgPSB7fSxcbiAgICAgIGMgPSB7fSxcbiAgICAgIGs7XG5cbiAgaWYgKGEgPT09IG51bGwgfHwgdHlwZW9mIGEgIT09IFwib2JqZWN0XCIpIGEgPSB7fTtcbiAgaWYgKGIgPT09IG51bGwgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIpIGIgPSB7fTtcblxuICBmb3IgKGsgaW4gYikge1xuICAgIGlmIChrIGluIGEpIHtcbiAgICAgIGlba10gPSB2YWx1ZShhW2tdLCBiW2tdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY1trXSA9IGJba107XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBmb3IgKGsgaW4gaSkgY1trXSA9IGlba10odCk7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59XG5cbnZhciByZUEgPSAvWy0rXT8oPzpcXGQrXFwuP1xcZCp8XFwuP1xcZCspKD86W2VFXVstK10/XFxkKyk/L2csXG4gICAgcmVCID0gbmV3IFJlZ0V4cChyZUEuc291cmNlLCBcImdcIik7XG5cbmZ1bmN0aW9uIHplcm8oYikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGI7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG9uZShiKSB7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGIodCkgKyBcIlwiO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdHJpbmcoYSwgYikge1xuICB2YXIgYmkgPSByZUEubGFzdEluZGV4ID0gcmVCLmxhc3RJbmRleCA9IDAsIC8vIHNjYW4gaW5kZXggZm9yIG5leHQgbnVtYmVyIGluIGJcbiAgICAgIGFtLCAvLyBjdXJyZW50IG1hdGNoIGluIGFcbiAgICAgIGJtLCAvLyBjdXJyZW50IG1hdGNoIGluIGJcbiAgICAgIGJzLCAvLyBzdHJpbmcgcHJlY2VkaW5nIGN1cnJlbnQgbnVtYmVyIGluIGIsIGlmIGFueVxuICAgICAgaSA9IC0xLCAvLyBpbmRleCBpbiBzXG4gICAgICBzID0gW10sIC8vIHN0cmluZyBjb25zdGFudHMgYW5kIHBsYWNlaG9sZGVyc1xuICAgICAgcSA9IFtdOyAvLyBudW1iZXIgaW50ZXJwb2xhdG9yc1xuXG4gIC8vIENvZXJjZSBpbnB1dHMgdG8gc3RyaW5ncy5cbiAgYSA9IGEgKyBcIlwiLCBiID0gYiArIFwiXCI7XG5cbiAgLy8gSW50ZXJwb2xhdGUgcGFpcnMgb2YgbnVtYmVycyBpbiBhICYgYi5cbiAgd2hpbGUgKChhbSA9IHJlQS5leGVjKGEpKVxuICAgICAgJiYgKGJtID0gcmVCLmV4ZWMoYikpKSB7XG4gICAgaWYgKChicyA9IGJtLmluZGV4KSA+IGJpKSB7IC8vIGEgc3RyaW5nIHByZWNlZGVzIHRoZSBuZXh0IG51bWJlciBpbiBiXG4gICAgICBicyA9IGIuc2xpY2UoYmksIGJzKTtcbiAgICAgIGlmIChzW2ldKSBzW2ldICs9IGJzOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgICAgZWxzZSBzWysraV0gPSBicztcbiAgICB9XG4gICAgaWYgKChhbSA9IGFtWzBdKSA9PT0gKGJtID0gYm1bMF0pKSB7IC8vIG51bWJlcnMgaW4gYSAmIGIgbWF0Y2hcbiAgICAgIGlmIChzW2ldKSBzW2ldICs9IGJtOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgICAgZWxzZSBzWysraV0gPSBibTtcbiAgICB9IGVsc2UgeyAvLyBpbnRlcnBvbGF0ZSBub24tbWF0Y2hpbmcgbnVtYmVyc1xuICAgICAgc1srK2ldID0gbnVsbDtcbiAgICAgIHEucHVzaCh7aTogaSwgeDogbnVtYmVyKGFtLCBibSl9KTtcbiAgICB9XG4gICAgYmkgPSByZUIubGFzdEluZGV4O1xuICB9XG5cbiAgLy8gQWRkIHJlbWFpbnMgb2YgYi5cbiAgaWYgKGJpIDwgYi5sZW5ndGgpIHtcbiAgICBicyA9IGIuc2xpY2UoYmkpO1xuICAgIGlmIChzW2ldKSBzW2ldICs9IGJzOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgIGVsc2Ugc1srK2ldID0gYnM7XG4gIH1cblxuICAvLyBTcGVjaWFsIG9wdGltaXphdGlvbiBmb3Igb25seSBhIHNpbmdsZSBtYXRjaC5cbiAgLy8gT3RoZXJ3aXNlLCBpbnRlcnBvbGF0ZSBlYWNoIG9mIHRoZSBudW1iZXJzIGFuZCByZWpvaW4gdGhlIHN0cmluZy5cbiAgcmV0dXJuIHMubGVuZ3RoIDwgMiA/IChxWzBdXG4gICAgICA/IG9uZShxWzBdLngpXG4gICAgICA6IHplcm8oYikpXG4gICAgICA6IChiID0gcS5sZW5ndGgsIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IGI7ICsraSkgc1sobyA9IHFbaV0pLmldID0gby54KHQpO1xuICAgICAgICAgIHJldHVybiBzLmpvaW4oXCJcIik7XG4gICAgICAgIH0pO1xufVxuXG5mdW5jdGlvbiB2YWx1ZShhLCBiKSB7XG4gIHZhciB0ID0gdHlwZW9mIGIsIGM7XG4gIHJldHVybiBiID09IG51bGwgfHwgdCA9PT0gXCJib29sZWFuXCIgPyBjb25zdGFudChiKVxuICAgICAgOiAodCA9PT0gXCJudW1iZXJcIiA/IG51bWJlclxuICAgICAgOiB0ID09PSBcInN0cmluZ1wiID8gKChjID0gZDNDb2xvci5jb2xvcihiKSkgPyAoYiA9IGMsIHJnYikgOiBzdHJpbmcpXG4gICAgICA6IGIgaW5zdGFuY2VvZiBkM0NvbG9yLmNvbG9yID8gcmdiXG4gICAgICA6IGIgaW5zdGFuY2VvZiBEYXRlID8gZGF0ZVxuICAgICAgOiBpc051bWJlckFycmF5KGIpID8gbnVtYmVyQXJyYXlcbiAgICAgIDogQXJyYXkuaXNBcnJheShiKSA/IGdlbmVyaWNBcnJheVxuICAgICAgOiB0eXBlb2YgYi52YWx1ZU9mICE9PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIGIudG9TdHJpbmcgIT09IFwiZnVuY3Rpb25cIiB8fCBpc05hTihiKSA/IG9iamVjdFxuICAgICAgOiBudW1iZXIpKGEsIGIpO1xufVxuXG5mdW5jdGlvbiBkaXNjcmV0ZShyYW5nZSkge1xuICB2YXIgbiA9IHJhbmdlLmxlbmd0aDtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gcmFuZ2VbTWF0aC5tYXgoMCwgTWF0aC5taW4obiAtIDEsIE1hdGguZmxvb3IodCAqIG4pKSldO1xuICB9O1xufVxuXG5mdW5jdGlvbiBodWUkMShhLCBiKSB7XG4gIHZhciBpID0gaHVlKCthLCArYik7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgdmFyIHggPSBpKHQpO1xuICAgIHJldHVybiB4IC0gMzYwICogTWF0aC5mbG9vcih4IC8gMzYwKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcm91bmQoYSwgYikge1xuICByZXR1cm4gYSA9ICthLCBiID0gK2IsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChhICogKDEgLSB0KSArIGIgKiB0KTtcbiAgfTtcbn1cblxudmFyIGRlZ3JlZXMgPSAxODAgLyBNYXRoLlBJO1xuXG52YXIgaWRlbnRpdHkgPSB7XG4gIHRyYW5zbGF0ZVg6IDAsXG4gIHRyYW5zbGF0ZVk6IDAsXG4gIHJvdGF0ZTogMCxcbiAgc2tld1g6IDAsXG4gIHNjYWxlWDogMSxcbiAgc2NhbGVZOiAxXG59O1xuXG5mdW5jdGlvbiBkZWNvbXBvc2UoYSwgYiwgYywgZCwgZSwgZikge1xuICB2YXIgc2NhbGVYLCBzY2FsZVksIHNrZXdYO1xuICBpZiAoc2NhbGVYID0gTWF0aC5zcXJ0KGEgKiBhICsgYiAqIGIpKSBhIC89IHNjYWxlWCwgYiAvPSBzY2FsZVg7XG4gIGlmIChza2V3WCA9IGEgKiBjICsgYiAqIGQpIGMgLT0gYSAqIHNrZXdYLCBkIC09IGIgKiBza2V3WDtcbiAgaWYgKHNjYWxlWSA9IE1hdGguc3FydChjICogYyArIGQgKiBkKSkgYyAvPSBzY2FsZVksIGQgLz0gc2NhbGVZLCBza2V3WCAvPSBzY2FsZVk7XG4gIGlmIChhICogZCA8IGIgKiBjKSBhID0gLWEsIGIgPSAtYiwgc2tld1ggPSAtc2tld1gsIHNjYWxlWCA9IC1zY2FsZVg7XG4gIHJldHVybiB7XG4gICAgdHJhbnNsYXRlWDogZSxcbiAgICB0cmFuc2xhdGVZOiBmLFxuICAgIHJvdGF0ZTogTWF0aC5hdGFuMihiLCBhKSAqIGRlZ3JlZXMsXG4gICAgc2tld1g6IE1hdGguYXRhbihza2V3WCkgKiBkZWdyZWVzLFxuICAgIHNjYWxlWDogc2NhbGVYLFxuICAgIHNjYWxlWTogc2NhbGVZXG4gIH07XG59XG5cbnZhciBjc3NOb2RlLFxuICAgIGNzc1Jvb3QsXG4gICAgY3NzVmlldyxcbiAgICBzdmdOb2RlO1xuXG5mdW5jdGlvbiBwYXJzZUNzcyh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IFwibm9uZVwiKSByZXR1cm4gaWRlbnRpdHk7XG4gIGlmICghY3NzTm9kZSkgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJESVZcIiksIGNzc1Jvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGNzc1ZpZXcgPSBkb2N1bWVudC5kZWZhdWx0VmlldztcbiAgY3NzTm9kZS5zdHlsZS50cmFuc2Zvcm0gPSB2YWx1ZTtcbiAgdmFsdWUgPSBjc3NWaWV3LmdldENvbXB1dGVkU3R5bGUoY3NzUm9vdC5hcHBlbmRDaGlsZChjc3NOb2RlKSwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShcInRyYW5zZm9ybVwiKTtcbiAgY3NzUm9vdC5yZW1vdmVDaGlsZChjc3NOb2RlKTtcbiAgdmFsdWUgPSB2YWx1ZS5zbGljZSg3LCAtMSkuc3BsaXQoXCIsXCIpO1xuICByZXR1cm4gZGVjb21wb3NlKCt2YWx1ZVswXSwgK3ZhbHVlWzFdLCArdmFsdWVbMl0sICt2YWx1ZVszXSwgK3ZhbHVlWzRdLCArdmFsdWVbNV0pO1xufVxuXG5mdW5jdGlvbiBwYXJzZVN2Zyh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIGlkZW50aXR5O1xuICBpZiAoIXN2Z05vZGUpIHN2Z05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcImdcIik7XG4gIHN2Z05vZGUuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIHZhbHVlKTtcbiAgaWYgKCEodmFsdWUgPSBzdmdOb2RlLnRyYW5zZm9ybS5iYXNlVmFsLmNvbnNvbGlkYXRlKCkpKSByZXR1cm4gaWRlbnRpdHk7XG4gIHZhbHVlID0gdmFsdWUubWF0cml4O1xuICByZXR1cm4gZGVjb21wb3NlKHZhbHVlLmEsIHZhbHVlLmIsIHZhbHVlLmMsIHZhbHVlLmQsIHZhbHVlLmUsIHZhbHVlLmYpO1xufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZVRyYW5zZm9ybShwYXJzZSwgcHhDb21tYSwgcHhQYXJlbiwgZGVnUGFyZW4pIHtcblxuICBmdW5jdGlvbiBwb3Aocykge1xuICAgIHJldHVybiBzLmxlbmd0aCA/IHMucG9wKCkgKyBcIiBcIiA6IFwiXCI7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2xhdGUoeGEsIHlhLCB4YiwgeWIsIHMsIHEpIHtcbiAgICBpZiAoeGEgIT09IHhiIHx8IHlhICE9PSB5Yikge1xuICAgICAgdmFyIGkgPSBzLnB1c2goXCJ0cmFuc2xhdGUoXCIsIG51bGwsIHB4Q29tbWEsIG51bGwsIHB4UGFyZW4pO1xuICAgICAgcS5wdXNoKHtpOiBpIC0gNCwgeDogbnVtYmVyKHhhLCB4Yil9LCB7aTogaSAtIDIsIHg6IG51bWJlcih5YSwgeWIpfSk7XG4gICAgfSBlbHNlIGlmICh4YiB8fCB5Yikge1xuICAgICAgcy5wdXNoKFwidHJhbnNsYXRlKFwiICsgeGIgKyBweENvbW1hICsgeWIgKyBweFBhcmVuKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByb3RhdGUoYSwgYiwgcywgcSkge1xuICAgIGlmIChhICE9PSBiKSB7XG4gICAgICBpZiAoYSAtIGIgPiAxODApIGIgKz0gMzYwOyBlbHNlIGlmIChiIC0gYSA+IDE4MCkgYSArPSAzNjA7IC8vIHNob3J0ZXN0IHBhdGhcbiAgICAgIHEucHVzaCh7aTogcy5wdXNoKHBvcChzKSArIFwicm90YXRlKFwiLCBudWxsLCBkZWdQYXJlbikgLSAyLCB4OiBudW1iZXIoYSwgYil9KTtcbiAgICB9IGVsc2UgaWYgKGIpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInJvdGF0ZShcIiArIGIgKyBkZWdQYXJlbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2tld1goYSwgYiwgcywgcSkge1xuICAgIGlmIChhICE9PSBiKSB7XG4gICAgICBxLnB1c2goe2k6IHMucHVzaChwb3AocykgKyBcInNrZXdYKFwiLCBudWxsLCBkZWdQYXJlbikgLSAyLCB4OiBudW1iZXIoYSwgYil9KTtcbiAgICB9IGVsc2UgaWYgKGIpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInNrZXdYKFwiICsgYiArIGRlZ1BhcmVuKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzY2FsZSh4YSwgeWEsIHhiLCB5YiwgcywgcSkge1xuICAgIGlmICh4YSAhPT0geGIgfHwgeWEgIT09IHliKSB7XG4gICAgICB2YXIgaSA9IHMucHVzaChwb3AocykgKyBcInNjYWxlKFwiLCBudWxsLCBcIixcIiwgbnVsbCwgXCIpXCIpO1xuICAgICAgcS5wdXNoKHtpOiBpIC0gNCwgeDogbnVtYmVyKHhhLCB4Yil9LCB7aTogaSAtIDIsIHg6IG51bWJlcih5YSwgeWIpfSk7XG4gICAgfSBlbHNlIGlmICh4YiAhPT0gMSB8fCB5YiAhPT0gMSkge1xuICAgICAgcy5wdXNoKHBvcChzKSArIFwic2NhbGUoXCIgKyB4YiArIFwiLFwiICsgeWIgKyBcIilcIik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgcyA9IFtdLCAvLyBzdHJpbmcgY29uc3RhbnRzIGFuZCBwbGFjZWhvbGRlcnNcbiAgICAgICAgcSA9IFtdOyAvLyBudW1iZXIgaW50ZXJwb2xhdG9yc1xuICAgIGEgPSBwYXJzZShhKSwgYiA9IHBhcnNlKGIpO1xuICAgIHRyYW5zbGF0ZShhLnRyYW5zbGF0ZVgsIGEudHJhbnNsYXRlWSwgYi50cmFuc2xhdGVYLCBiLnRyYW5zbGF0ZVksIHMsIHEpO1xuICAgIHJvdGF0ZShhLnJvdGF0ZSwgYi5yb3RhdGUsIHMsIHEpO1xuICAgIHNrZXdYKGEuc2tld1gsIGIuc2tld1gsIHMsIHEpO1xuICAgIHNjYWxlKGEuc2NhbGVYLCBhLnNjYWxlWSwgYi5zY2FsZVgsIGIuc2NhbGVZLCBzLCBxKTtcbiAgICBhID0gYiA9IG51bGw7IC8vIGdjXG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBpID0gLTEsIG4gPSBxLmxlbmd0aCwgbztcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBzWyhvID0gcVtpXSkuaV0gPSBvLngodCk7XG4gICAgICByZXR1cm4gcy5qb2luKFwiXCIpO1xuICAgIH07XG4gIH07XG59XG5cbnZhciBpbnRlcnBvbGF0ZVRyYW5zZm9ybUNzcyA9IGludGVycG9sYXRlVHJhbnNmb3JtKHBhcnNlQ3NzLCBcInB4LCBcIiwgXCJweClcIiwgXCJkZWcpXCIpO1xudmFyIGludGVycG9sYXRlVHJhbnNmb3JtU3ZnID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2VTdmcsIFwiLCBcIiwgXCIpXCIsIFwiKVwiKTtcblxudmFyIHJobyA9IE1hdGguU1FSVDIsXG4gICAgcmhvMiA9IDIsXG4gICAgcmhvNCA9IDQsXG4gICAgZXBzaWxvbjIgPSAxZS0xMjtcblxuZnVuY3Rpb24gY29zaCh4KSB7XG4gIHJldHVybiAoKHggPSBNYXRoLmV4cCh4KSkgKyAxIC8geCkgLyAyO1xufVxuXG5mdW5jdGlvbiBzaW5oKHgpIHtcbiAgcmV0dXJuICgoeCA9IE1hdGguZXhwKHgpKSAtIDEgLyB4KSAvIDI7XG59XG5cbmZ1bmN0aW9uIHRhbmgoeCkge1xuICByZXR1cm4gKCh4ID0gTWF0aC5leHAoMiAqIHgpKSAtIDEpIC8gKHggKyAxKTtcbn1cblxuLy8gcDAgPSBbdXgwLCB1eTAsIHcwXVxuLy8gcDEgPSBbdXgxLCB1eTEsIHcxXVxuZnVuY3Rpb24gem9vbShwMCwgcDEpIHtcbiAgdmFyIHV4MCA9IHAwWzBdLCB1eTAgPSBwMFsxXSwgdzAgPSBwMFsyXSxcbiAgICAgIHV4MSA9IHAxWzBdLCB1eTEgPSBwMVsxXSwgdzEgPSBwMVsyXSxcbiAgICAgIGR4ID0gdXgxIC0gdXgwLFxuICAgICAgZHkgPSB1eTEgLSB1eTAsXG4gICAgICBkMiA9IGR4ICogZHggKyBkeSAqIGR5LFxuICAgICAgaSxcbiAgICAgIFM7XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGZvciB1MCDiiYUgdTEuXG4gIGlmIChkMiA8IGVwc2lsb24yKSB7XG4gICAgUyA9IE1hdGgubG9nKHcxIC8gdzApIC8gcmhvO1xuICAgIGkgPSBmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB1eDAgKyB0ICogZHgsXG4gICAgICAgIHV5MCArIHQgKiBkeSxcbiAgICAgICAgdzAgKiBNYXRoLmV4cChyaG8gKiB0ICogUylcbiAgICAgIF07XG4gICAgfTtcbiAgfVxuXG4gIC8vIEdlbmVyYWwgY2FzZS5cbiAgZWxzZSB7XG4gICAgdmFyIGQxID0gTWF0aC5zcXJ0KGQyKSxcbiAgICAgICAgYjAgPSAodzEgKiB3MSAtIHcwICogdzAgKyByaG80ICogZDIpIC8gKDIgKiB3MCAqIHJobzIgKiBkMSksXG4gICAgICAgIGIxID0gKHcxICogdzEgLSB3MCAqIHcwIC0gcmhvNCAqIGQyKSAvICgyICogdzEgKiByaG8yICogZDEpLFxuICAgICAgICByMCA9IE1hdGgubG9nKE1hdGguc3FydChiMCAqIGIwICsgMSkgLSBiMCksXG4gICAgICAgIHIxID0gTWF0aC5sb2coTWF0aC5zcXJ0KGIxICogYjEgKyAxKSAtIGIxKTtcbiAgICBTID0gKHIxIC0gcjApIC8gcmhvO1xuICAgIGkgPSBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgcyA9IHQgKiBTLFxuICAgICAgICAgIGNvc2hyMCA9IGNvc2gocjApLFxuICAgICAgICAgIHUgPSB3MCAvIChyaG8yICogZDEpICogKGNvc2hyMCAqIHRhbmgocmhvICogcyArIHIwKSAtIHNpbmgocjApKTtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHV4MCArIHUgKiBkeCxcbiAgICAgICAgdXkwICsgdSAqIGR5LFxuICAgICAgICB3MCAqIGNvc2hyMCAvIGNvc2gocmhvICogcyArIHIwKVxuICAgICAgXTtcbiAgICB9O1xuICB9XG5cbiAgaS5kdXJhdGlvbiA9IFMgKiAxMDAwO1xuXG4gIHJldHVybiBpO1xufVxuXG5mdW5jdGlvbiBoc2woaHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgdmFyIGggPSBodWUoKHN0YXJ0ID0gZDNDb2xvci5oc2woc3RhcnQpKS5oLCAoZW5kID0gZDNDb2xvci5oc2woZW5kKSkuaCksXG4gICAgICAgIHMgPSBub2dhbW1hKHN0YXJ0LnMsIGVuZC5zKSxcbiAgICAgICAgbCA9IG5vZ2FtbWEoc3RhcnQubCwgZW5kLmwpLFxuICAgICAgICBvcGFjaXR5ID0gbm9nYW1tYShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHN0YXJ0LmggPSBoKHQpO1xuICAgICAgc3RhcnQucyA9IHModCk7XG4gICAgICBzdGFydC5sID0gbCh0KTtcbiAgICAgIHN0YXJ0Lm9wYWNpdHkgPSBvcGFjaXR5KHQpO1xuICAgICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgICB9O1xuICB9XG59XG5cbnZhciBoc2wkMSA9IGhzbChodWUpO1xudmFyIGhzbExvbmcgPSBoc2wobm9nYW1tYSk7XG5cbmZ1bmN0aW9uIGxhYihzdGFydCwgZW5kKSB7XG4gIHZhciBsID0gbm9nYW1tYSgoc3RhcnQgPSBkM0NvbG9yLmxhYihzdGFydCkpLmwsIChlbmQgPSBkM0NvbG9yLmxhYihlbmQpKS5sKSxcbiAgICAgIGEgPSBub2dhbW1hKHN0YXJ0LmEsIGVuZC5hKSxcbiAgICAgIGIgPSBub2dhbW1hKHN0YXJ0LmIsIGVuZC5iKSxcbiAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBzdGFydC5sID0gbCh0KTtcbiAgICBzdGFydC5hID0gYSh0KTtcbiAgICBzdGFydC5iID0gYih0KTtcbiAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICB9O1xufVxuXG5mdW5jdGlvbiBoY2woaHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgdmFyIGggPSBodWUoKHN0YXJ0ID0gZDNDb2xvci5oY2woc3RhcnQpKS5oLCAoZW5kID0gZDNDb2xvci5oY2woZW5kKSkuaCksXG4gICAgICAgIGMgPSBub2dhbW1hKHN0YXJ0LmMsIGVuZC5jKSxcbiAgICAgICAgbCA9IG5vZ2FtbWEoc3RhcnQubCwgZW5kLmwpLFxuICAgICAgICBvcGFjaXR5ID0gbm9nYW1tYShzdGFydC5vcGFjaXR5LCBlbmQub3BhY2l0eSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHN0YXJ0LmggPSBoKHQpO1xuICAgICAgc3RhcnQuYyA9IGModCk7XG4gICAgICBzdGFydC5sID0gbCh0KTtcbiAgICAgIHN0YXJ0Lm9wYWNpdHkgPSBvcGFjaXR5KHQpO1xuICAgICAgcmV0dXJuIHN0YXJ0ICsgXCJcIjtcbiAgICB9O1xuICB9XG59XG5cbnZhciBoY2wkMSA9IGhjbChodWUpO1xudmFyIGhjbExvbmcgPSBoY2wobm9nYW1tYSk7XG5cbmZ1bmN0aW9uIGN1YmVoZWxpeChodWUpIHtcbiAgcmV0dXJuIChmdW5jdGlvbiBjdWJlaGVsaXhHYW1tYSh5KSB7XG4gICAgeSA9ICt5O1xuXG4gICAgZnVuY3Rpb24gY3ViZWhlbGl4KHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBoID0gaHVlKChzdGFydCA9IGQzQ29sb3IuY3ViZWhlbGl4KHN0YXJ0KSkuaCwgKGVuZCA9IGQzQ29sb3IuY3ViZWhlbGl4KGVuZCkpLmgpLFxuICAgICAgICAgIHMgPSBub2dhbW1hKHN0YXJ0LnMsIGVuZC5zKSxcbiAgICAgICAgICBsID0gbm9nYW1tYShzdGFydC5sLCBlbmQubCksXG4gICAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgc3RhcnQuaCA9IGgodCk7XG4gICAgICAgIHN0YXJ0LnMgPSBzKHQpO1xuICAgICAgICBzdGFydC5sID0gbChNYXRoLnBvdyh0LCB5KSk7XG4gICAgICAgIHN0YXJ0Lm9wYWNpdHkgPSBvcGFjaXR5KHQpO1xuICAgICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjdWJlaGVsaXguZ2FtbWEgPSBjdWJlaGVsaXhHYW1tYTtcblxuICAgIHJldHVybiBjdWJlaGVsaXg7XG4gIH0pKDEpO1xufVxuXG52YXIgY3ViZWhlbGl4JDEgPSBjdWJlaGVsaXgoaHVlKTtcbnZhciBjdWJlaGVsaXhMb25nID0gY3ViZWhlbGl4KG5vZ2FtbWEpO1xuXG5mdW5jdGlvbiBwaWVjZXdpc2UoaW50ZXJwb2xhdGUsIHZhbHVlcykge1xuICB2YXIgaSA9IDAsIG4gPSB2YWx1ZXMubGVuZ3RoIC0gMSwgdiA9IHZhbHVlc1swXSwgSSA9IG5ldyBBcnJheShuIDwgMCA/IDAgOiBuKTtcbiAgd2hpbGUgKGkgPCBuKSBJW2ldID0gaW50ZXJwb2xhdGUodiwgdiA9IHZhbHVlc1srK2ldKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgaSA9IE1hdGgubWF4KDAsIE1hdGgubWluKG4gLSAxLCBNYXRoLmZsb29yKHQgKj0gbikpKTtcbiAgICByZXR1cm4gSVtpXSh0IC0gaSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHF1YW50aXplKGludGVycG9sYXRvciwgbikge1xuICB2YXIgc2FtcGxlcyA9IG5ldyBBcnJheShuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIHNhbXBsZXNbaV0gPSBpbnRlcnBvbGF0b3IoaSAvIChuIC0gMSkpO1xuICByZXR1cm4gc2FtcGxlcztcbn1cblxuZXhwb3J0cy5pbnRlcnBvbGF0ZSA9IHZhbHVlO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZUFycmF5ID0gYXJyYXk7XG5leHBvcnRzLmludGVycG9sYXRlQmFzaXMgPSBiYXNpcyQxO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZUJhc2lzQ2xvc2VkID0gYmFzaXNDbG9zZWQ7XG5leHBvcnRzLmludGVycG9sYXRlQ3ViZWhlbGl4ID0gY3ViZWhlbGl4JDE7XG5leHBvcnRzLmludGVycG9sYXRlQ3ViZWhlbGl4TG9uZyA9IGN1YmVoZWxpeExvbmc7XG5leHBvcnRzLmludGVycG9sYXRlRGF0ZSA9IGRhdGU7XG5leHBvcnRzLmludGVycG9sYXRlRGlzY3JldGUgPSBkaXNjcmV0ZTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIY2wgPSBoY2wkMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIY2xMb25nID0gaGNsTG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVIc2wgPSBoc2wkMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVIc2xMb25nID0gaHNsTG9uZztcbmV4cG9ydHMuaW50ZXJwb2xhdGVIdWUgPSBodWUkMTtcbmV4cG9ydHMuaW50ZXJwb2xhdGVMYWIgPSBsYWI7XG5leHBvcnRzLmludGVycG9sYXRlTnVtYmVyID0gbnVtYmVyO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZU51bWJlckFycmF5ID0gbnVtYmVyQXJyYXk7XG5leHBvcnRzLmludGVycG9sYXRlT2JqZWN0ID0gb2JqZWN0O1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJnYiA9IHJnYjtcbmV4cG9ydHMuaW50ZXJwb2xhdGVSZ2JCYXNpcyA9IHJnYkJhc2lzO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJnYkJhc2lzQ2xvc2VkID0gcmdiQmFzaXNDbG9zZWQ7XG5leHBvcnRzLmludGVycG9sYXRlUm91bmQgPSByb3VuZDtcbmV4cG9ydHMuaW50ZXJwb2xhdGVTdHJpbmcgPSBzdHJpbmc7XG5leHBvcnRzLmludGVycG9sYXRlVHJhbnNmb3JtQ3NzID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3M7XG5leHBvcnRzLmludGVycG9sYXRlVHJhbnNmb3JtU3ZnID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm1Tdmc7XG5leHBvcnRzLmludGVycG9sYXRlWm9vbSA9IHpvb207XG5leHBvcnRzLnBpZWNld2lzZSA9IHBpZWNld2lzZTtcbmV4cG9ydHMucXVhbnRpemUgPSBxdWFudGl6ZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxufSkpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0hhcnJ5U3RldmVucy9kMy1yZWdyZXNzaW9uI3JlYWRtZSBWZXJzaW9uIDEuMy41LiBDb3B5cmlnaHQgMjAyMCBIYXJyeSBTdGV2ZW5zLlxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuICAoZ2xvYmFsID0gZ2xvYmFsIHx8IHNlbGYsIGZhY3RvcnkoZ2xvYmFsLmQzID0gZ2xvYmFsLmQzIHx8IHt9KSk7XG59KHRoaXMsIGZ1bmN0aW9uIChleHBvcnRzKSB7ICd1c2Ugc3RyaWN0JztcblxuICBmdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHtcbiAgICByZXR1cm4gX2FycmF5V2l0aEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgfHwgX25vbkl0ZXJhYmxlUmVzdCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBhcnI7XG4gIH1cblxuICBmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB7XG4gICAgdmFyIF9hcnIgPSBbXTtcbiAgICB2YXIgX24gPSB0cnVlO1xuICAgIHZhciBfZCA9IGZhbHNlO1xuICAgIHZhciBfZSA9IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKHZhciBfaSA9IGFycltTeW1ib2wuaXRlcmF0b3JdKCksIF9zOyAhKF9uID0gKF9zID0gX2kubmV4dCgpKS5kb25lKTsgX24gPSB0cnVlKSB7XG4gICAgICAgIF9hcnIucHVzaChfcy52YWx1ZSk7XG5cbiAgICAgICAgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgX2QgPSB0cnVlO1xuICAgICAgX2UgPSBlcnI7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghX24gJiYgX2lbXCJyZXR1cm5cIl0gIT0gbnVsbCkgX2lbXCJyZXR1cm5cIl0oKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChfZCkgdGhyb3cgX2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIF9hcnI7XG4gIH1cblxuICBmdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlXCIpO1xuICB9XG5cbiAgLy8gQWRhcHRlZCBmcm9tIHZlZ2Etc3RhdGlzdGljcyBieSBKZWZmcmV5IEhlZXJcbiAgLy8gTGljZW5zZTogaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS9ibG9iL2YwNThiMDk5ZGVjYWQ5ZGI3ODMwMTQwNWRkMGQyZTlkOGJhM2Q1MWEvTElDRU5TRVxuICAvLyBTb3VyY2U6IGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EvYmxvYi9mMDU4YjA5OWRlY2FkOWRiNzgzMDE0MDVkZDBkMmU5ZDhiYTNkNTFhL3BhY2thZ2VzL3ZlZ2Etc3RhdGlzdGljcy9zcmMvcmVncmVzc2lvbi9wb2ludHMuanNcbiAgZnVuY3Rpb24gcG9pbnRzKGRhdGEsIHgsIHksIHNvcnQpIHtcbiAgICBkYXRhID0gZGF0YS5maWx0ZXIoZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB1ID0geChkKSxcbiAgICAgICAgICB2ID0geShkKTtcbiAgICAgIHJldHVybiB1ICE9IG51bGwgJiYgaXNGaW5pdGUodSkgJiYgdiAhPSBudWxsICYmIGlzRmluaXRlKHYpO1xuICAgIH0pO1xuXG4gICAgaWYgKHNvcnQpIHtcbiAgICAgIGRhdGEuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4geChhKSAtIHgoYik7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICBYID0gbmV3IEZsb2F0NjRBcnJheShuKSxcbiAgICAgICAgWSA9IG5ldyBGbG9hdDY0QXJyYXkobik7IC8vIGV4dHJhY3QgdmFsdWVzLCBjYWxjdWxhdGUgbWVhbnNcblxuICAgIHZhciB1eCA9IDAsXG4gICAgICAgIHV5ID0gMCxcbiAgICAgICAgeHYsXG4gICAgICAgIHl2LFxuICAgICAgICBkO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOykge1xuICAgICAgZCA9IGRhdGFbaV07XG4gICAgICBYW2ldID0geHYgPSAreChkKTtcbiAgICAgIFlbaV0gPSB5diA9ICt5KGQpO1xuICAgICAgKytpO1xuICAgICAgdXggKz0gKHh2IC0gdXgpIC8gaTtcbiAgICAgIHV5ICs9ICh5diAtIHV5KSAvIGk7XG4gICAgfSAvLyBtZWFuIGNlbnRlciB0aGUgZGF0YVxuXG5cbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbjsgKytfaSkge1xuICAgICAgWFtfaV0gLT0gdXg7XG4gICAgICBZW19pXSAtPSB1eTtcbiAgICB9XG5cbiAgICByZXR1cm4gW1gsIFksIHV4LCB1eV07XG4gIH1cbiAgZnVuY3Rpb24gdmlzaXRQb2ludHMoZGF0YSwgeCwgeSwgY2IpIHtcbiAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IGRhdGEubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICB2YXIgZCA9IGRhdGFbaV0sXG4gICAgICAgICAgZHggPSAreChkKSxcbiAgICAgICAgICBkeSA9ICt5KGQpO1xuXG4gICAgICBpZiAoZHggIT0gbnVsbCAmJiBpc0Zpbml0ZShkeCkgJiYgZHkgIT0gbnVsbCAmJiBpc0Zpbml0ZShkeSkpIHtcbiAgICAgICAgY2IoZHgsIGR5LCBpdGVyYXRpb25zKyspO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHJldHVybiB0aGUgY29lZmZpY2llbnQgb2YgZGV0ZXJtaW5hdGlvbiwgb3IgUiBzcXVhcmVkLlxuXG4gIGZ1bmN0aW9uIGRldGVybWluYXRpb24oZGF0YSwgeCwgeSwgdVksIHByZWRpY3QpIHtcbiAgICB2YXIgU1NFID0gMCxcbiAgICAgICAgU1NUID0gMDtcbiAgICB2aXNpdFBvaW50cyhkYXRhLCB4LCB5LCBmdW5jdGlvbiAoZHgsIGR5KSB7XG4gICAgICB2YXIgc3NlID0gZHkgLSBwcmVkaWN0KGR4KSxcbiAgICAgICAgICBzc3QgPSBkeSAtIHVZO1xuICAgICAgU1NFICs9IHNzZSAqIHNzZTtcbiAgICAgIFNTVCArPSBzc3QgKiBzc3Q7XG4gICAgfSk7XG4gICAgcmV0dXJuIDEgLSBTU0UgLyBTU1Q7XG4gIH1cblxuICAvLyBSZXR1cm5zIHRoZSBhbmdsZSBvZiBhIGxpbmUgaW4gZGVncmVlcy5cbiAgZnVuY3Rpb24gYW5nbGUobGluZSkge1xuICAgIHJldHVybiBNYXRoLmF0YW4yKGxpbmVbMV1bMV0gLSBsaW5lWzBdWzFdLCBsaW5lWzFdWzBdIC0gbGluZVswXVswXSkgKiAxODAgLyBNYXRoLlBJO1xuICB9IC8vIFJldHVybnMgdGhlIG1pZHBvaW50IG9mIGEgbGluZS5cblxuICBmdW5jdGlvbiBtaWRwb2ludChsaW5lKSB7XG4gICAgcmV0dXJuIFsobGluZVswXVswXSArIGxpbmVbMV1bMF0pIC8gMiwgKGxpbmVbMF1bMV0gKyBsaW5lWzFdWzFdKSAvIDJdO1xuICB9XG5cbiAgLy8gcmV0dXJucyBhIHNtb290aCBsaW5lLlxuXG4gIGZ1bmN0aW9uIGludGVycG9zZSh4bWluLCB4bWF4LCBwcmVkaWN0KSB7XG4gICAgdmFyIGwgPSBNYXRoLmxvZyh4bWF4IC0geG1pbikgKiBNYXRoLkxPRzEwRSArIDEgfCAwO1xuICAgIHZhciBwcmVjaXNpb24gPSAxICogTWF0aC5wb3coMTAsIC1sIC8gMiAtIDEpLFxuICAgICAgICBtYXhJdGVyID0gMWU0O1xuICAgIHZhciBwb2ludHMgPSBbcHgoeG1pbiksIHB4KHhtYXgpXSxcbiAgICAgICAgaXRlciA9IDA7XG5cbiAgICB3aGlsZSAoZmluZChwb2ludHMpICYmIGl0ZXIgPCBtYXhJdGVyKSB7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvaW50cztcblxuICAgIGZ1bmN0aW9uIHB4KHgpIHtcbiAgICAgIHJldHVybiBbeCwgcHJlZGljdCh4KV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmluZChwb2ludHMpIHtcbiAgICAgIGl0ZXIrKztcbiAgICAgIHZhciBuID0gcG9pbnRzLmxlbmd0aDtcbiAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4gLSAxOyBpKyspIHtcbiAgICAgICAgdmFyIHAwID0gcG9pbnRzW2ldLFxuICAgICAgICAgICAgcDEgPSBwb2ludHNbaSArIDFdLFxuICAgICAgICAgICAgbSA9IG1pZHBvaW50KFtwMCwgcDFdKSxcbiAgICAgICAgICAgIG1wID0gcHgobVswXSksXG4gICAgICAgICAgICBhMCA9IGFuZ2xlKFtwMCwgbV0pLFxuICAgICAgICAgICAgYTEgPSBhbmdsZShbcDAsIG1wXSksXG4gICAgICAgICAgICBhID0gTWF0aC5hYnMoYTAgLSBhMSk7XG5cbiAgICAgICAgaWYgKGEgPiBwcmVjaXNpb24pIHtcbiAgICAgICAgICBwb2ludHMuc3BsaWNlKGkgKyAxLCAwLCBtcCk7XG4gICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmb3VuZDtcbiAgICB9XG4gIH1cblxuICAvLyBPcmRpbmFyeSBMZWFzdCBTcXVhcmVzIGZyb20gdmVnYS1zdGF0aXN0aWNzIGJ5IEplZmZyZXkgSGVlclxuICAvLyBMaWNlbnNlOiBodHRwczovL2dpdGh1Yi5jb20vdmVnYS92ZWdhL2Jsb2IvZjA1OGIwOTlkZWNhZDlkYjc4MzAxNDA1ZGQwZDJlOWQ4YmEzZDUxYS9MSUNFTlNFXG4gIC8vIFNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL3ZlZ2EvdmVnYS9ibG9iL2YwNThiMDk5ZGVjYWQ5ZGI3ODMwMTQwNWRkMGQyZTlkOGJhM2Q1MWEvcGFja2FnZXMvdmVnYS1zdGF0aXN0aWNzL3NyYy9yZWdyZXNzaW9uL29scy5qc1xuICBmdW5jdGlvbiBvbHModVgsIHVZLCB1WFksIHVYMikge1xuICAgIHZhciBkZWx0YSA9IHVYMiAtIHVYICogdVgsXG4gICAgICAgIHNsb3BlID0gTWF0aC5hYnMoZGVsdGEpIDwgMWUtMjQgPyAwIDogKHVYWSAtIHVYICogdVkpIC8gZGVsdGEsXG4gICAgICAgIGludGVyY2VwdCA9IHVZIC0gc2xvcGUgKiB1WDtcbiAgICByZXR1cm4gW2ludGVyY2VwdCwgc2xvcGVdO1xuICB9XG5cbiAgZnVuY3Rpb24gZXhwb25lbnRpYWwgKCkge1xuICAgIHZhciB4ID0gZnVuY3Rpb24geChkKSB7XG4gICAgICByZXR1cm4gZFswXTtcbiAgICB9LFxuICAgICAgICB5ID0gZnVuY3Rpb24geShkKSB7XG4gICAgICByZXR1cm4gZFsxXTtcbiAgICB9LFxuICAgICAgICBkb21haW47XG5cbiAgICBmdW5jdGlvbiBleHBvbmVudGlhbChkYXRhKSB7XG4gICAgICB2YXIgbiA9IDAsXG4gICAgICAgICAgWSA9IDAsXG4gICAgICAgICAgWUwgPSAwLFxuICAgICAgICAgIFhZID0gMCxcbiAgICAgICAgICBYWUwgPSAwLFxuICAgICAgICAgIFgyWSA9IDAsXG4gICAgICAgICAgeG1pbiA9IGRvbWFpbiA/ICtkb21haW5bMF0gOiBJbmZpbml0eSxcbiAgICAgICAgICB4bWF4ID0gZG9tYWluID8gK2RvbWFpblsxXSA6IC1JbmZpbml0eTtcbiAgICAgIHZpc2l0UG9pbnRzKGRhdGEsIHgsIHksIGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICAgICAgdmFyIGx5ID0gTWF0aC5sb2coZHkpLFxuICAgICAgICAgICAgeHkgPSBkeCAqIGR5O1xuICAgICAgICArK247XG4gICAgICAgIFkgKz0gKGR5IC0gWSkgLyBuO1xuICAgICAgICBYWSArPSAoeHkgLSBYWSkgLyBuO1xuICAgICAgICBYMlkgKz0gKGR4ICogeHkgLSBYMlkpIC8gbjtcbiAgICAgICAgWUwgKz0gKGR5ICogbHkgLSBZTCkgLyBuO1xuICAgICAgICBYWUwgKz0gKHh5ICogbHkgLSBYWUwpIC8gbjtcblxuICAgICAgICBpZiAoIWRvbWFpbikge1xuICAgICAgICAgIGlmIChkeCA8IHhtaW4pIHhtaW4gPSBkeDtcbiAgICAgICAgICBpZiAoZHggPiB4bWF4KSB4bWF4ID0gZHg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgX29scyA9IG9scyhYWSAvIFksIFlMIC8gWSwgWFlMIC8gWSwgWDJZIC8gWSksXG4gICAgICAgICAgX29sczIgPSBfc2xpY2VkVG9BcnJheShfb2xzLCAyKSxcbiAgICAgICAgICBhID0gX29sczJbMF0sXG4gICAgICAgICAgYiA9IF9vbHMyWzFdO1xuXG4gICAgICBhID0gTWF0aC5leHAoYSk7XG5cbiAgICAgIHZhciBmbiA9IGZ1bmN0aW9uIGZuKHgpIHtcbiAgICAgICAgcmV0dXJuIGEgKiBNYXRoLmV4cChiICogeCk7XG4gICAgICB9LFxuICAgICAgICAgIG91dCA9IGludGVycG9zZSh4bWluLCB4bWF4LCBmbik7XG5cbiAgICAgIG91dC5hID0gYTtcbiAgICAgIG91dC5iID0gYjtcbiAgICAgIG91dC5wcmVkaWN0ID0gZm47XG4gICAgICBvdXQuclNxdWFyZWQgPSBkZXRlcm1pbmF0aW9uKGRhdGEsIHgsIHksIFksIGZuKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgZXhwb25lbnRpYWwuZG9tYWluID0gZnVuY3Rpb24gKGFycikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gYXJyLCBleHBvbmVudGlhbCkgOiBkb21haW47XG4gICAgfTtcblxuICAgIGV4cG9uZW50aWFsLnggPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSBmbiwgZXhwb25lbnRpYWwpIDogeDtcbiAgICB9O1xuXG4gICAgZXhwb25lbnRpYWwueSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IGZuLCBleHBvbmVudGlhbCkgOiB5O1xuICAgIH07XG5cbiAgICByZXR1cm4gZXhwb25lbnRpYWw7XG4gIH1cblxuICBmdW5jdGlvbiBsaW5lYXIgKCkge1xuICAgIHZhciB4ID0gZnVuY3Rpb24geChkKSB7XG4gICAgICByZXR1cm4gZFswXTtcbiAgICB9LFxuICAgICAgICB5ID0gZnVuY3Rpb24geShkKSB7XG4gICAgICByZXR1cm4gZFsxXTtcbiAgICB9LFxuICAgICAgICBkb21haW47XG5cbiAgICBmdW5jdGlvbiBsaW5lYXIoZGF0YSkge1xuICAgICAgdmFyIG4gPSAwLFxuICAgICAgICAgIFggPSAwLFxuICAgICAgICAgIC8vIHN1bSBvZiB4XG4gICAgICBZID0gMCxcbiAgICAgICAgICAvLyBzdW0gb2YgeVxuICAgICAgWFkgPSAwLFxuICAgICAgICAgIC8vIHN1bSBvZiB4ICogeVxuICAgICAgWDIgPSAwLFxuICAgICAgICAgIC8vIHN1bSBvZiB4ICogeFxuICAgICAgeG1pbiA9IGRvbWFpbiA/ICtkb21haW5bMF0gOiBJbmZpbml0eSxcbiAgICAgICAgICB4bWF4ID0gZG9tYWluID8gK2RvbWFpblsxXSA6IC1JbmZpbml0eTtcbiAgICAgIHZpc2l0UG9pbnRzKGRhdGEsIHgsIHksIGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICAgICAgKytuO1xuICAgICAgICBYICs9IChkeCAtIFgpIC8gbjtcbiAgICAgICAgWSArPSAoZHkgLSBZKSAvIG47XG4gICAgICAgIFhZICs9IChkeCAqIGR5IC0gWFkpIC8gbjtcbiAgICAgICAgWDIgKz0gKGR4ICogZHggLSBYMikgLyBuO1xuXG4gICAgICAgIGlmICghZG9tYWluKSB7XG4gICAgICAgICAgaWYgKGR4IDwgeG1pbikgeG1pbiA9IGR4O1xuICAgICAgICAgIGlmIChkeCA+IHhtYXgpIHhtYXggPSBkeDtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBfb2xzID0gb2xzKFgsIFksIFhZLCBYMiksXG4gICAgICAgICAgX29sczIgPSBfc2xpY2VkVG9BcnJheShfb2xzLCAyKSxcbiAgICAgICAgICBpbnRlcmNlcHQgPSBfb2xzMlswXSxcbiAgICAgICAgICBzbG9wZSA9IF9vbHMyWzFdLFxuICAgICAgICAgIGZuID0gZnVuY3Rpb24gZm4oeCkge1xuICAgICAgICByZXR1cm4gc2xvcGUgKiB4ICsgaW50ZXJjZXB0O1xuICAgICAgfSxcbiAgICAgICAgICBvdXQgPSBbW3htaW4sIGZuKHhtaW4pXSwgW3htYXgsIGZuKHhtYXgpXV07XG5cbiAgICAgIG91dC5hID0gc2xvcGU7XG4gICAgICBvdXQuYiA9IGludGVyY2VwdDtcbiAgICAgIG91dC5wcmVkaWN0ID0gZm47XG4gICAgICBvdXQuclNxdWFyZWQgPSBkZXRlcm1pbmF0aW9uKGRhdGEsIHgsIHksIFksIGZuKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgbGluZWFyLmRvbWFpbiA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbiA9IGFyciwgbGluZWFyKSA6IGRvbWFpbjtcbiAgICB9O1xuXG4gICAgbGluZWFyLnggPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSBmbiwgbGluZWFyKSA6IHg7XG4gICAgfTtcblxuICAgIGxpbmVhci55ID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gZm4sIGxpbmVhcikgOiB5O1xuICAgIH07XG5cbiAgICByZXR1cm4gbGluZWFyO1xuICB9XG5cbiAgLy8gUmV0dXJucyB0aGUgbWVkaXVtIHZhbHVlIG9mIGFuIGFycmF5IG9mIG51bWJlcnMuXG4gIGZ1bmN0aW9uIG1lZGlhbihhcnIpIHtcbiAgICBhcnIuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICAgIHZhciBpID0gYXJyLmxlbmd0aCAvIDI7XG4gICAgcmV0dXJuIGkgJSAxID09PSAwID8gKGFycltpIC0gMV0gKyBhcnJbaV0pIC8gMiA6IGFycltNYXRoLmZsb29yKGkpXTtcbiAgfVxuXG4gIHZhciBtYXhpdGVycyA9IDIsXG4gICAgICBlcHNpbG9uID0gMWUtMTI7XG4gIGZ1bmN0aW9uIGxvZXNzICgpIHtcbiAgICB2YXIgeCA9IGZ1bmN0aW9uIHgoZCkge1xuICAgICAgcmV0dXJuIGRbMF07XG4gICAgfSxcbiAgICAgICAgeSA9IGZ1bmN0aW9uIHkoZCkge1xuICAgICAgcmV0dXJuIGRbMV07XG4gICAgfSxcbiAgICAgICAgYmFuZHdpZHRoID0gLjM7XG5cbiAgICBmdW5jdGlvbiBsb2VzcyhkYXRhKSB7XG4gICAgICB2YXIgX3BvaW50cyA9IHBvaW50cyhkYXRhLCB4LCB5LCB0cnVlKSxcbiAgICAgICAgICBfcG9pbnRzMiA9IF9zbGljZWRUb0FycmF5KF9wb2ludHMsIDQpLFxuICAgICAgICAgIHh2ID0gX3BvaW50czJbMF0sXG4gICAgICAgICAgeXYgPSBfcG9pbnRzMlsxXSxcbiAgICAgICAgICB1eCA9IF9wb2ludHMyWzJdLFxuICAgICAgICAgIHV5ID0gX3BvaW50czJbM10sXG4gICAgICAgICAgbiA9IHh2Lmxlbmd0aCxcbiAgICAgICAgICBidyA9IE1hdGgubWF4KDIsIH5+KGJhbmR3aWR0aCAqIG4pKSxcbiAgICAgICAgICB5aGF0ID0gbmV3IEZsb2F0NjRBcnJheShuKSxcbiAgICAgICAgICByZXNpZHVhbHMgPSBuZXcgRmxvYXQ2NEFycmF5KG4pLFxuICAgICAgICAgIHJvYnVzdFdlaWdodHMgPSBuZXcgRmxvYXQ2NEFycmF5KG4pLmZpbGwoMSk7XG5cbiAgICAgIGZvciAodmFyIGl0ZXIgPSAtMTsgKytpdGVyIDw9IG1heGl0ZXJzOykge1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSBbMCwgYncgLSAxXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgICAgIHZhciBkeCA9IHh2W2ldLFxuICAgICAgICAgICAgICBpMCA9IGludGVydmFsWzBdLFxuICAgICAgICAgICAgICBpMSA9IGludGVydmFsWzFdLFxuICAgICAgICAgICAgICBlZGdlID0gZHggLSB4dltpMF0gPiB4dltpMV0gLSBkeCA/IGkwIDogaTE7XG4gICAgICAgICAgdmFyIFcgPSAwLFxuICAgICAgICAgICAgICBYID0gMCxcbiAgICAgICAgICAgICAgWSA9IDAsXG4gICAgICAgICAgICAgIFhZID0gMCxcbiAgICAgICAgICAgICAgWDIgPSAwLFxuICAgICAgICAgICAgICBkZW5vbSA9IDEgLyBNYXRoLmFicyh4dltlZGdlXSAtIGR4IHx8IDEpOyAvLyBBdm9pZCBzaW5ndWxhcml0eVxuXG4gICAgICAgICAgZm9yICh2YXIgayA9IGkwOyBrIDw9IGkxOyArK2spIHtcbiAgICAgICAgICAgIHZhciB4ayA9IHh2W2tdLFxuICAgICAgICAgICAgICAgIHlrID0geXZba10sXG4gICAgICAgICAgICAgICAgdyA9IHRyaWN1YmUoTWF0aC5hYnMoZHggLSB4aykgKiBkZW5vbSkgKiByb2J1c3RXZWlnaHRzW2tdLFxuICAgICAgICAgICAgICAgIHhrdyA9IHhrICogdztcbiAgICAgICAgICAgIFcgKz0gdztcbiAgICAgICAgICAgIFggKz0geGt3O1xuICAgICAgICAgICAgWSArPSB5ayAqIHc7XG4gICAgICAgICAgICBYWSArPSB5ayAqIHhrdztcbiAgICAgICAgICAgIFgyICs9IHhrICogeGt3O1xuICAgICAgICAgIH0gLy8gTGluZWFyIHJlZ3Jlc3Npb24gZml0XG5cblxuICAgICAgICAgIHZhciBfb2xzID0gb2xzKFggLyBXLCBZIC8gVywgWFkgLyBXLCBYMiAvIFcpLFxuICAgICAgICAgICAgICBfb2xzMiA9IF9zbGljZWRUb0FycmF5KF9vbHMsIDIpLFxuICAgICAgICAgICAgICBhID0gX29sczJbMF0sXG4gICAgICAgICAgICAgIGIgPSBfb2xzMlsxXTtcblxuICAgICAgICAgIHloYXRbaV0gPSBhICsgYiAqIGR4O1xuICAgICAgICAgIHJlc2lkdWFsc1tpXSA9IE1hdGguYWJzKHl2W2ldIC0geWhhdFtpXSk7XG4gICAgICAgICAgdXBkYXRlSW50ZXJ2YWwoeHYsIGkgKyAxLCBpbnRlcnZhbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXRlciA9PT0gbWF4aXRlcnMpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtZWRpYW5SZXNpZHVhbCA9IG1lZGlhbihyZXNpZHVhbHMpO1xuICAgICAgICBpZiAoTWF0aC5hYnMobWVkaWFuUmVzaWR1YWwpIDwgZXBzaWxvbikgYnJlYWs7XG5cbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBhcmcsIF93OyBfaSA8IG47ICsrX2kpIHtcbiAgICAgICAgICBhcmcgPSByZXNpZHVhbHNbX2ldIC8gKDYgKiBtZWRpYW5SZXNpZHVhbCk7IC8vIERlZmF1bHQgdG8gZXBzaWxvbiAocmF0aGVyIHRoYW4gemVybykgZm9yIGxhcmdlIGRldmlhdGlvbnNcbiAgICAgICAgICAvLyBLZWVwaW5nIHdlaWdodHMgdGlueSBidXQgbm9uLXplcm8gcHJldmVudHMgc2luZ3VsYXJpdGVzXG5cbiAgICAgICAgICByb2J1c3RXZWlnaHRzW19pXSA9IGFyZyA+PSAxID8gZXBzaWxvbiA6IChfdyA9IDEgLSBhcmcgKiBhcmcpICogX3c7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dCh4diwgeWhhdCwgdXgsIHV5KTtcbiAgICB9XG5cbiAgICBsb2Vzcy5iYW5kd2lkdGggPSBmdW5jdGlvbiAoYncpIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGJhbmR3aWR0aCA9IGJ3LCBsb2VzcykgOiBiYW5kd2lkdGg7XG4gICAgfTtcblxuICAgIGxvZXNzLnggPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSBmbiwgbG9lc3MpIDogeDtcbiAgICB9O1xuXG4gICAgbG9lc3MueSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IGZuLCBsb2VzcykgOiB5O1xuICAgIH07XG5cbiAgICByZXR1cm4gbG9lc3M7XG4gIH0gLy8gV2VpZ2h0aW5nIGtlcm5lbCBmb3IgbG9jYWwgcmVncmVzc2lvblxuXG4gIGZ1bmN0aW9uIHRyaWN1YmUoeCkge1xuICAgIHJldHVybiAoeCA9IDEgLSB4ICogeCAqIHgpICogeCAqIHg7XG4gIH0gLy8gQWR2YW5jZSBzbGlkaW5nIHdpbmRvdyBpbnRlcnZhbCBvZiBuZWFyZXN0IG5laWdoYm9yc1xuXG5cbiAgZnVuY3Rpb24gdXBkYXRlSW50ZXJ2YWwoeHYsIGksIGludGVydmFsKSB7XG4gICAgdmFyIHZhbCA9IHh2W2ldLFxuICAgICAgICBsZWZ0ID0gaW50ZXJ2YWxbMF0sXG4gICAgICAgIHJpZ2h0ID0gaW50ZXJ2YWxbMV0gKyAxO1xuICAgIGlmIChyaWdodCA+PSB4di5sZW5ndGgpIHJldHVybjsgLy8gU3RlcCByaWdodCBpZiBkaXN0YW5jZSB0byBuZXcgcmlnaHQgZWRnZSBpcyA8PSBkaXN0YW5jZSB0byBvbGQgbGVmdCBlZGdlXG4gICAgLy8gU3RlcCB3aGVuIGRpc3RhbmNlIGlzIGVxdWFsIHRvIGVuc3VyZSBtb3ZlbWVudCBvdmVyIGR1cGxpY2F0ZSB4IHZhbHVlc1xuXG4gICAgd2hpbGUgKGkgPiBsZWZ0ICYmIHh2W3JpZ2h0XSAtIHZhbCA8PSB2YWwgLSB4dltsZWZ0XSkge1xuICAgICAgaW50ZXJ2YWxbMF0gPSArK2xlZnQ7XG4gICAgICBpbnRlcnZhbFsxXSA9IHJpZ2h0O1xuICAgICAgKytyaWdodDtcbiAgICB9XG4gIH0gLy8gR2VuZXJhdGUgc21vb3RoZWQgb3V0cHV0IHBvaW50c1xuICAvLyBBdmVyYWdlIHBvaW50cyB3aXRoIHJlcGVhdGVkIHggdmFsdWVzXG5cblxuICBmdW5jdGlvbiBvdXRwdXQoeHYsIHloYXQsIHV4LCB1eSkge1xuICAgIHZhciBuID0geHYubGVuZ3RoLFxuICAgICAgICBvdXQgPSBbXTtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIGNudCA9IDAsXG4gICAgICAgIHByZXYgPSBbXSxcbiAgICAgICAgdjtcblxuICAgIGZvciAoOyBpIDwgbjsgKytpKSB7XG4gICAgICB2ID0geHZbaV0gKyB1eDtcblxuICAgICAgaWYgKHByZXZbMF0gPT09IHYpIHtcbiAgICAgICAgLy8gQXZlcmFnZSBvdXRwdXQgdmFsdWVzIHZpYSBvbmxpbmUgdXBkYXRlXG4gICAgICAgIHByZXZbMV0gKz0gKHloYXRbaV0gLSBwcmV2WzFdKSAvICsrY250O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQWRkIG5ldyBvdXRwdXQgcG9pbnRcbiAgICAgICAgY250ID0gMDtcbiAgICAgICAgcHJldlsxXSArPSB1eTtcbiAgICAgICAgcHJldiA9IFt2LCB5aGF0W2ldXTtcbiAgICAgICAgb3V0LnB1c2gocHJldik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJldlsxXSArPSB1eTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgZnVuY3Rpb24gbG9nYXJpdGhtaWMgKCkge1xuICAgIHZhciB4ID0gZnVuY3Rpb24geChkKSB7XG4gICAgICByZXR1cm4gZFswXTtcbiAgICB9LFxuICAgICAgICB5ID0gZnVuY3Rpb24geShkKSB7XG4gICAgICByZXR1cm4gZFsxXTtcbiAgICB9LFxuICAgICAgICBkb21haW47XG5cbiAgICBmdW5jdGlvbiBsb2dhcml0aG1pYyhkYXRhKSB7XG4gICAgICB2YXIgbiA9IDAsXG4gICAgICAgICAgWCA9IDAsXG4gICAgICAgICAgWSA9IDAsXG4gICAgICAgICAgWFkgPSAwLFxuICAgICAgICAgIFgyID0gMCxcbiAgICAgICAgICB4bWluID0gZG9tYWluID8gK2RvbWFpblswXSA6IEluZmluaXR5LFxuICAgICAgICAgIHhtYXggPSBkb21haW4gPyArZG9tYWluWzFdIDogLUluZmluaXR5O1xuICAgICAgdmlzaXRQb2ludHMoZGF0YSwgeCwgeSwgZnVuY3Rpb24gKGR4LCBkeSkge1xuICAgICAgICB2YXIgbHggPSBNYXRoLmxvZyhkeCk7XG4gICAgICAgICsrbjtcbiAgICAgICAgWCArPSAobHggLSBYKSAvIG47XG4gICAgICAgIFkgKz0gKGR5IC0gWSkgLyBuO1xuICAgICAgICBYWSArPSAobHggKiBkeSAtIFhZKSAvIG47XG4gICAgICAgIFgyICs9IChseCAqIGx4IC0gWDIpIC8gbjtcblxuICAgICAgICBpZiAoIWRvbWFpbikge1xuICAgICAgICAgIGlmIChkeCA8IHhtaW4pIHhtaW4gPSBkeDtcbiAgICAgICAgICBpZiAoZHggPiB4bWF4KSB4bWF4ID0gZHg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgX29scyA9IG9scyhYLCBZLCBYWSwgWDIpLFxuICAgICAgICAgIF9vbHMyID0gX3NsaWNlZFRvQXJyYXkoX29scywgMiksXG4gICAgICAgICAgaW50ZXJjZXB0ID0gX29sczJbMF0sXG4gICAgICAgICAgc2xvcGUgPSBfb2xzMlsxXSxcbiAgICAgICAgICBmbiA9IGZ1bmN0aW9uIGZuKHgpIHtcbiAgICAgICAgcmV0dXJuIHNsb3BlICogTWF0aC5sb2coeCkgKyBpbnRlcmNlcHQ7XG4gICAgICB9LFxuICAgICAgICAgIG91dCA9IGludGVycG9zZSh4bWluLCB4bWF4LCBmbik7XG5cbiAgICAgIG91dC5hID0gc2xvcGU7XG4gICAgICBvdXQuYiA9IGludGVyY2VwdDtcbiAgICAgIG91dC5wcmVkaWN0ID0gZm47XG4gICAgICBvdXQuclNxdWFyZWQgPSBkZXRlcm1pbmF0aW9uKGRhdGEsIHgsIHksIFksIGZuKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgbG9nYXJpdGhtaWMuZG9tYWluID0gZnVuY3Rpb24gKGFycikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZG9tYWluID0gYXJyLCBsb2dhcml0aG1pYykgOiBkb21haW47XG4gICAgfTtcblxuICAgIGxvZ2FyaXRobWljLnggPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSBmbiwgbG9nYXJpdGhtaWMpIDogeDtcbiAgICB9O1xuXG4gICAgbG9nYXJpdGhtaWMueSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IGZuLCBsb2dhcml0aG1pYykgOiB5O1xuICAgIH07XG5cbiAgICByZXR1cm4gbG9nYXJpdGhtaWM7XG4gIH1cblxuICBmdW5jdGlvbiBxdWFkICgpIHtcbiAgICB2YXIgeCA9IGZ1bmN0aW9uIHgoZCkge1xuICAgICAgcmV0dXJuIGRbMF07XG4gICAgfSxcbiAgICAgICAgeSA9IGZ1bmN0aW9uIHkoZCkge1xuICAgICAgcmV0dXJuIGRbMV07XG4gICAgfSxcbiAgICAgICAgZG9tYWluO1xuXG4gICAgZnVuY3Rpb24gcXVhZHJhdGljKGRhdGEpIHtcbiAgICAgIHZhciBfcG9pbnRzID0gcG9pbnRzKGRhdGEsIHgsIHkpLFxuICAgICAgICAgIF9wb2ludHMyID0gX3NsaWNlZFRvQXJyYXkoX3BvaW50cywgNCksXG4gICAgICAgICAgeHYgPSBfcG9pbnRzMlswXSxcbiAgICAgICAgICB5diA9IF9wb2ludHMyWzFdLFxuICAgICAgICAgIHV4ID0gX3BvaW50czJbMl0sXG4gICAgICAgICAgdXkgPSBfcG9pbnRzMlszXSxcbiAgICAgICAgICBuID0geHYubGVuZ3RoO1xuXG4gICAgICB2YXIgWDIgPSAwLFxuICAgICAgICAgIFgzID0gMCxcbiAgICAgICAgICBYNCA9IDAsXG4gICAgICAgICAgWFkgPSAwLFxuICAgICAgICAgIFgyWSA9IDAsXG4gICAgICAgICAgaSxcbiAgICAgICAgICBkeCxcbiAgICAgICAgICBkeSxcbiAgICAgICAgICB4MjtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IG47KSB7XG4gICAgICAgIGR4ID0geHZbaV07XG4gICAgICAgIGR5ID0geXZbaSsrXTtcbiAgICAgICAgeDIgPSBkeCAqIGR4O1xuICAgICAgICBYMiArPSAoeDIgLSBYMikgLyBpO1xuICAgICAgICBYMyArPSAoeDIgKiBkeCAtIFgzKSAvIGk7XG4gICAgICAgIFg0ICs9ICh4MiAqIHgyIC0gWDQpIC8gaTtcbiAgICAgICAgWFkgKz0gKGR4ICogZHkgLSBYWSkgLyBpO1xuICAgICAgICBYMlkgKz0gKHgyICogZHkgLSBYMlkpIC8gaTtcbiAgICAgIH1cblxuICAgICAgdmFyIFkgPSAwLFxuICAgICAgICAgIG4wID0gMCxcbiAgICAgICAgICB4bWluID0gZG9tYWluID8gK2RvbWFpblswXSA6IEluZmluaXR5LFxuICAgICAgICAgIHhtYXggPSBkb21haW4gPyArZG9tYWluWzFdIDogLUluZmluaXR5O1xuICAgICAgdmlzaXRQb2ludHMoZGF0YSwgeCwgeSwgZnVuY3Rpb24gKGR4LCBkeSkge1xuICAgICAgICBuMCsrO1xuICAgICAgICBZICs9IChkeSAtIFkpIC8gbjA7XG5cbiAgICAgICAgaWYgKCFkb21haW4pIHtcbiAgICAgICAgICBpZiAoZHggPCB4bWluKSB4bWluID0gZHg7XG4gICAgICAgICAgaWYgKGR4ID4geG1heCkgeG1heCA9IGR4O1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIFgyWDIgPSBYNCAtIFgyICogWDIsXG4gICAgICAgICAgZCA9IFgyICogWDJYMiAtIFgzICogWDMsXG4gICAgICAgICAgYSA9IChYMlkgKiBYMiAtIFhZICogWDMpIC8gZCxcbiAgICAgICAgICBiID0gKFhZICogWDJYMiAtIFgyWSAqIFgzKSAvIGQsXG4gICAgICAgICAgYyA9IC1hICogWDIsXG4gICAgICAgICAgZm4gPSBmdW5jdGlvbiBmbih4KSB7XG4gICAgICAgIHggPSB4IC0gdXg7XG4gICAgICAgIHJldHVybiBhICogeCAqIHggKyBiICogeCArIGMgKyB1eTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBvdXQgPSBpbnRlcnBvc2UoeG1pbiwgeG1heCwgZm4pO1xuICAgICAgb3V0LmEgPSBhO1xuICAgICAgb3V0LmIgPSBiIC0gMiAqIGEgKiB1eDtcbiAgICAgIG91dC5jID0gYyAtIGIgKiB1eCArIGEgKiB1eCAqIHV4ICsgdXk7XG4gICAgICBvdXQucHJlZGljdCA9IGZuO1xuICAgICAgb3V0LnJTcXVhcmVkID0gZGV0ZXJtaW5hdGlvbihkYXRhLCB4LCB5LCBZLCBmbik7XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIHF1YWRyYXRpYy5kb21haW4gPSBmdW5jdGlvbiAoYXJyKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBhcnIsIHF1YWRyYXRpYykgOiBkb21haW47XG4gICAgfTtcblxuICAgIHF1YWRyYXRpYy54ID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gZm4sIHF1YWRyYXRpYykgOiB4O1xuICAgIH07XG5cbiAgICBxdWFkcmF0aWMueSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IGZuLCBxdWFkcmF0aWMpIDogeTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHF1YWRyYXRpYztcbiAgfVxuXG4gIC8vIFNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL1RvbS1BbGV4YW5kZXIvcmVncmVzc2lvbi1qcy9ibG9iL21hc3Rlci9zcmMvcmVncmVzc2lvbi5qcyNMMjQ2XG4gIC8vIExpY2Vuc2U6IGh0dHBzOi8vZ2l0aHViLmNvbS9Ub20tQWxleGFuZGVyL3JlZ3Jlc3Npb24tanMvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICAvLyAuLi53aXRoIGlkZWFzIGZyb20gdmVnYS1zdGF0aXN0aWNzIGJ5IEplZmZyZXkgSGVlclxuICAvLyBTb3VyY2U6IGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EvYmxvYi9mMjFjYjg3OTJiNGUwY2JlMmIxYTNmZDQ0YjBmNWRiMzcwZGJhYWRiL3BhY2thZ2VzL3ZlZ2Etc3RhdGlzdGljcy9zcmMvcmVncmVzc2lvbi9wb2x5LmpzXG4gIC8vIExpY2Vuc2U6IGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EvYmxvYi9mMDU4YjA5OWRlY2FkOWRiNzgzMDE0MDVkZDBkMmU5ZDhiYTNkNTFhL0xJQ0VOU0VcblxuICBmdW5jdGlvbiBwb2x5bm9taWFsICgpIHtcbiAgICB2YXIgeCA9IGZ1bmN0aW9uIHgoZCkge1xuICAgICAgcmV0dXJuIGRbMF07XG4gICAgfSxcbiAgICAgICAgeSA9IGZ1bmN0aW9uIHkoZCkge1xuICAgICAgcmV0dXJuIGRbMV07XG4gICAgfSxcbiAgICAgICAgb3JkZXIgPSAzLFxuICAgICAgICBkb21haW47XG5cbiAgICBmdW5jdGlvbiBwb2x5bm9taWFsKGRhdGEpIHtcbiAgICAgIC8vIFVzZSBtb3JlIGVmZmljaWVudCBtZXRob2RzIGZvciBsb3dlciBvcmRlcnNcbiAgICAgIGlmIChvcmRlciA9PT0gMSkge1xuICAgICAgICB2YXIgbyA9IGxpbmVhcigpLngoeCkueSh5KS5kb21haW4oZG9tYWluKShkYXRhKTtcbiAgICAgICAgby5jb2VmZmljaWVudHMgPSBbby5iLCBvLmFdO1xuICAgICAgICBkZWxldGUgby5hO1xuICAgICAgICBkZWxldGUgby5iO1xuICAgICAgICByZXR1cm4gbztcbiAgICAgIH1cblxuICAgICAgaWYgKG9yZGVyID09PSAyKSB7XG4gICAgICAgIHZhciBfbyA9IHF1YWQoKS54KHgpLnkoeSkuZG9tYWluKGRvbWFpbikoZGF0YSk7XG5cbiAgICAgICAgX28uY29lZmZpY2llbnRzID0gW19vLmMsIF9vLmIsIF9vLmFdO1xuICAgICAgICBkZWxldGUgX28uYTtcbiAgICAgICAgZGVsZXRlIF9vLmI7XG4gICAgICAgIGRlbGV0ZSBfby5jO1xuICAgICAgICByZXR1cm4gX287XG4gICAgICB9XG5cbiAgICAgIHZhciBfcG9pbnRzID0gcG9pbnRzKGRhdGEsIHgsIHkpLFxuICAgICAgICAgIF9wb2ludHMyID0gX3NsaWNlZFRvQXJyYXkoX3BvaW50cywgNCksXG4gICAgICAgICAgeHYgPSBfcG9pbnRzMlswXSxcbiAgICAgICAgICB5diA9IF9wb2ludHMyWzFdLFxuICAgICAgICAgIHV4ID0gX3BvaW50czJbMl0sXG4gICAgICAgICAgdXkgPSBfcG9pbnRzMlszXSxcbiAgICAgICAgICBuID0geHYubGVuZ3RoLFxuICAgICAgICAgIGxocyA9IFtdLFxuICAgICAgICAgIHJocyA9IFtdLFxuICAgICAgICAgIGsgPSBvcmRlciArIDE7XG5cbiAgICAgIHZhciBZID0gMCxcbiAgICAgICAgICBuMCA9IDAsXG4gICAgICAgICAgeG1pbiA9IGRvbWFpbiA/ICtkb21haW5bMF0gOiBJbmZpbml0eSxcbiAgICAgICAgICB4bWF4ID0gZG9tYWluID8gK2RvbWFpblsxXSA6IC1JbmZpbml0eTtcbiAgICAgIHZpc2l0UG9pbnRzKGRhdGEsIHgsIHksIGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICAgICAgKytuMDtcbiAgICAgICAgWSArPSAoZHkgLSBZKSAvIG4wO1xuXG4gICAgICAgIGlmICghZG9tYWluKSB7XG4gICAgICAgICAgaWYgKGR4IDwgeG1pbikgeG1pbiA9IGR4O1xuICAgICAgICAgIGlmIChkeCA+IHhtYXgpIHhtYXggPSBkeDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB2YXIgaSwgaiwgbCwgdiwgYztcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGs7ICsraSkge1xuICAgICAgICBmb3IgKGwgPSAwLCB2ID0gMDsgbCA8IG47ICsrbCkge1xuICAgICAgICAgIHYgKz0gTWF0aC5wb3coeHZbbF0sIGkpICogeXZbbF07XG4gICAgICAgIH1cblxuICAgICAgICBsaHMucHVzaCh2KTtcbiAgICAgICAgYyA9IG5ldyBGbG9hdDY0QXJyYXkoayk7XG5cbiAgICAgICAgZm9yIChqID0gMDsgaiA8IGs7ICsraikge1xuICAgICAgICAgIGZvciAobCA9IDAsIHYgPSAwOyBsIDwgbjsgKytsKSB7XG4gICAgICAgICAgICB2ICs9IE1hdGgucG93KHh2W2xdLCBpICsgaik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY1tqXSA9IHY7XG4gICAgICAgIH1cblxuICAgICAgICByaHMucHVzaChjKTtcbiAgICAgIH1cblxuICAgICAgcmhzLnB1c2gobGhzKTtcblxuICAgICAgdmFyIGNvZWYgPSBnYXVzc2lhbkVsaW1pbmF0aW9uKHJocyksXG4gICAgICAgICAgZm4gPSBmdW5jdGlvbiBmbih4KSB7XG4gICAgICAgIHggLT0gdXg7XG4gICAgICAgIHZhciB5ID0gdXkgKyBjb2VmWzBdICsgY29lZlsxXSAqIHggKyBjb2VmWzJdICogeCAqIHg7XG5cbiAgICAgICAgZm9yIChpID0gMzsgaSA8IGs7ICsraSkge1xuICAgICAgICAgIHkgKz0gY29lZltpXSAqIE1hdGgucG93KHgsIGkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHk7XG4gICAgICB9LFxuICAgICAgICAgIG91dCA9IGludGVycG9zZSh4bWluLCB4bWF4LCBmbik7XG5cbiAgICAgIG91dC5jb2VmZmljaWVudHMgPSB1bmNlbnRlcihrLCBjb2VmLCAtdXgsIHV5KTtcbiAgICAgIG91dC5wcmVkaWN0ID0gZm47XG4gICAgICBvdXQuclNxdWFyZWQgPSBkZXRlcm1pbmF0aW9uKGRhdGEsIHgsIHksIFksIGZuKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgcG9seW5vbWlhbC5kb21haW4gPSBmdW5jdGlvbiAoYXJyKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBhcnIsIHBvbHlub21pYWwpIDogZG9tYWluO1xuICAgIH07XG5cbiAgICBwb2x5bm9taWFsLnggPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSBmbiwgcG9seW5vbWlhbCkgOiB4O1xuICAgIH07XG5cbiAgICBwb2x5bm9taWFsLnkgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSBmbiwgcG9seW5vbWlhbCkgOiB5O1xuICAgIH07XG5cbiAgICBwb2x5bm9taWFsLm9yZGVyID0gZnVuY3Rpb24gKG4pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKG9yZGVyID0gbiwgcG9seW5vbWlhbCkgOiBvcmRlcjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHBvbHlub21pYWw7XG4gIH1cblxuICBmdW5jdGlvbiB1bmNlbnRlcihrLCBhLCB4LCB5KSB7XG4gICAgdmFyIHogPSBBcnJheShrKTtcbiAgICB2YXIgaSwgaiwgdiwgYzsgLy8gaW5pdGlhbGl6ZSB0byB6ZXJvXG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgazsgKytpKSB7XG4gICAgICB6W2ldID0gMDtcbiAgICB9IC8vIHBvbHlub21pYWwgZXhwYW5zaW9uXG5cblxuICAgIGZvciAoaSA9IGsgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdiA9IGFbaV07XG4gICAgICBjID0gMTtcbiAgICAgIHpbaV0gKz0gdjtcblxuICAgICAgZm9yIChqID0gMTsgaiA8PSBpOyArK2opIHtcbiAgICAgICAgYyAqPSAoaSArIDEgLSBqKSAvIGo7IC8vIGJpbm9taWFsIGNvZWZmaWNlbnRcblxuICAgICAgICB6W2kgLSBqXSArPSB2ICogTWF0aC5wb3coeCwgaikgKiBjO1xuICAgICAgfVxuICAgIH0gLy8gYmlhcyB0ZXJtXG5cblxuICAgIHpbMF0gKz0geTtcbiAgICByZXR1cm4gejtcbiAgfSAvLyBHaXZlbiBhbiBhcnJheSBmb3IgYSB0d28tZGltZW5zaW9uYWwgbWF0cml4IGFuZCB0aGUgcG9seW5vbWlhbCBvcmRlcixcbiAgLy8gc29sdmUgQSAqIHggPSBiIHVzaW5nIEdhdXNzaWFuIGVsaW1pbmF0aW9uLlxuXG5cbiAgZnVuY3Rpb24gZ2F1c3NpYW5FbGltaW5hdGlvbihtYXRyaXgpIHtcbiAgICB2YXIgbiA9IG1hdHJpeC5sZW5ndGggLSAxLFxuICAgICAgICBjb2VmID0gW107XG4gICAgdmFyIGksIGosIGssIHIsIHQ7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICByID0gaTsgLy8gbWF4IHJvd1xuXG4gICAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47ICsraikge1xuICAgICAgICBpZiAoTWF0aC5hYnMobWF0cml4W2ldW2pdKSA+IE1hdGguYWJzKG1hdHJpeFtpXVtyXSkpIHtcbiAgICAgICAgICByID0gajtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGsgPSBpOyBrIDwgbiArIDE7ICsraykge1xuICAgICAgICB0ID0gbWF0cml4W2tdW2ldO1xuICAgICAgICBtYXRyaXhba11baV0gPSBtYXRyaXhba11bcl07XG4gICAgICAgIG1hdHJpeFtrXVtyXSA9IHQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgKytqKSB7XG4gICAgICAgIGZvciAoayA9IG47IGsgPj0gaTsgay0tKSB7XG4gICAgICAgICAgbWF0cml4W2tdW2pdIC09IG1hdHJpeFtrXVtpXSAqIG1hdHJpeFtpXVtqXSAvIG1hdHJpeFtpXVtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaiA9IG4gLSAxOyBqID49IDA7IC0taikge1xuICAgICAgdCA9IDA7XG5cbiAgICAgIGZvciAoayA9IGogKyAxOyBrIDwgbjsgKytrKSB7XG4gICAgICAgIHQgKz0gbWF0cml4W2tdW2pdICogY29lZltrXTtcbiAgICAgIH1cblxuICAgICAgY29lZltqXSA9IChtYXRyaXhbbl1bal0gLSB0KSAvIG1hdHJpeFtqXVtqXTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29lZjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBvd2VyICgpIHtcbiAgICB2YXIgeCA9IGZ1bmN0aW9uIHgoZCkge1xuICAgICAgcmV0dXJuIGRbMF07XG4gICAgfSxcbiAgICAgICAgeSA9IGZ1bmN0aW9uIHkoZCkge1xuICAgICAgcmV0dXJuIGRbMV07XG4gICAgfSxcbiAgICAgICAgZG9tYWluO1xuXG4gICAgZnVuY3Rpb24gcG93ZXIoZGF0YSkge1xuICAgICAgdmFyIG4gPSAwLFxuICAgICAgICAgIFggPSAwLFxuICAgICAgICAgIFkgPSAwLFxuICAgICAgICAgIFhZID0gMCxcbiAgICAgICAgICBYMiA9IDAsXG4gICAgICAgICAgWVMgPSAwLFxuICAgICAgICAgIHhtaW4gPSBkb21haW4gPyArZG9tYWluWzBdIDogSW5maW5pdHksXG4gICAgICAgICAgeG1heCA9IGRvbWFpbiA/ICtkb21haW5bMV0gOiAtSW5maW5pdHk7XG4gICAgICB2aXNpdFBvaW50cyhkYXRhLCB4LCB5LCBmdW5jdGlvbiAoZHgsIGR5KSB7XG4gICAgICAgIHZhciBseCA9IE1hdGgubG9nKGR4KSxcbiAgICAgICAgICAgIGx5ID0gTWF0aC5sb2coZHkpO1xuICAgICAgICArK247XG4gICAgICAgIFggKz0gKGx4IC0gWCkgLyBuO1xuICAgICAgICBZICs9IChseSAtIFkpIC8gbjtcbiAgICAgICAgWFkgKz0gKGx4ICogbHkgLSBYWSkgLyBuO1xuICAgICAgICBYMiArPSAobHggKiBseCAtIFgyKSAvIG47XG4gICAgICAgIFlTICs9IChkeSAtIFlTKSAvIG47XG5cbiAgICAgICAgaWYgKCFkb21haW4pIHtcbiAgICAgICAgICBpZiAoZHggPCB4bWluKSB4bWluID0gZHg7XG4gICAgICAgICAgaWYgKGR4ID4geG1heCkgeG1heCA9IGR4O1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIF9vbHMgPSBvbHMoWCwgWSwgWFksIFgyKSxcbiAgICAgICAgICBfb2xzMiA9IF9zbGljZWRUb0FycmF5KF9vbHMsIDIpLFxuICAgICAgICAgIGEgPSBfb2xzMlswXSxcbiAgICAgICAgICBiID0gX29sczJbMV07XG5cbiAgICAgIGEgPSBNYXRoLmV4cChhKTtcblxuICAgICAgdmFyIGZuID0gZnVuY3Rpb24gZm4oeCkge1xuICAgICAgICByZXR1cm4gYSAqIE1hdGgucG93KHgsIGIpO1xuICAgICAgfSxcbiAgICAgICAgICBvdXQgPSBpbnRlcnBvc2UoeG1pbiwgeG1heCwgZm4pO1xuXG4gICAgICBvdXQuYSA9IGE7XG4gICAgICBvdXQuYiA9IGI7XG4gICAgICBvdXQucHJlZGljdCA9IGZuO1xuICAgICAgb3V0LnJTcXVhcmVkID0gZGV0ZXJtaW5hdGlvbihkYXRhLCB4LCB5LCBZUywgZm4pO1xuICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG5cbiAgICBwb3dlci5kb21haW4gPSBmdW5jdGlvbiAoYXJyKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBhcnIsIHBvd2VyKSA6IGRvbWFpbjtcbiAgICB9O1xuXG4gICAgcG93ZXIueCA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeCA9IGZuLCBwb3dlcikgOiB4O1xuICAgIH07XG5cbiAgICBwb3dlci55ID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gZm4sIHBvd2VyKSA6IHk7XG4gICAgfTtcblxuICAgIHJldHVybiBwb3dlcjtcbiAgfVxuXG4gIGV4cG9ydHMucmVncmVzc2lvbkV4cCA9IGV4cG9uZW50aWFsO1xuICBleHBvcnRzLnJlZ3Jlc3Npb25MaW5lYXIgPSBsaW5lYXI7XG4gIGV4cG9ydHMucmVncmVzc2lvbkxvZXNzID0gbG9lc3M7XG4gIGV4cG9ydHMucmVncmVzc2lvbkxvZyA9IGxvZ2FyaXRobWljO1xuICBleHBvcnRzLnJlZ3Jlc3Npb25Qb2x5ID0gcG9seW5vbWlhbDtcbiAgZXhwb3J0cy5yZWdyZXNzaW9uUG93ID0gcG93ZXI7XG4gIGV4cG9ydHMucmVncmVzc2lvblF1YWQgPSBxdWFkO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbn0pKTtcbiIsIi8vIGh0dHBzOi8vZDNqcy5vcmcvZDMtdGltZXIvIHYxLjAuMTAgQ29weXJpZ2h0IDIwMTkgTWlrZSBCb3N0b2NrXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xudHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG50eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbihnbG9iYWwgPSBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwuZDMgPSBnbG9iYWwuZDMgfHwge30pKTtcbn0odGhpcywgZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG52YXIgZnJhbWUgPSAwLCAvLyBpcyBhbiBhbmltYXRpb24gZnJhbWUgcGVuZGluZz9cbiAgICB0aW1lb3V0ID0gMCwgLy8gaXMgYSB0aW1lb3V0IHBlbmRpbmc/XG4gICAgaW50ZXJ2YWwgPSAwLCAvLyBhcmUgYW55IHRpbWVycyBhY3RpdmU/XG4gICAgcG9rZURlbGF5ID0gMTAwMCwgLy8gaG93IGZyZXF1ZW50bHkgd2UgY2hlY2sgZm9yIGNsb2NrIHNrZXdcbiAgICB0YXNrSGVhZCxcbiAgICB0YXNrVGFpbCxcbiAgICBjbG9ja0xhc3QgPSAwLFxuICAgIGNsb2NrTm93ID0gMCxcbiAgICBjbG9ja1NrZXcgPSAwLFxuICAgIGNsb2NrID0gdHlwZW9mIHBlcmZvcm1hbmNlID09PSBcIm9iamVjdFwiICYmIHBlcmZvcm1hbmNlLm5vdyA/IHBlcmZvcm1hbmNlIDogRGF0ZSxcbiAgICBzZXRGcmFtZSA9IHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSA/IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUuYmluZCh3aW5kb3cpIDogZnVuY3Rpb24oZikgeyBzZXRUaW1lb3V0KGYsIDE3KTsgfTtcblxuZnVuY3Rpb24gbm93KCkge1xuICByZXR1cm4gY2xvY2tOb3cgfHwgKHNldEZyYW1lKGNsZWFyTm93KSwgY2xvY2tOb3cgPSBjbG9jay5ub3coKSArIGNsb2NrU2tldyk7XG59XG5cbmZ1bmN0aW9uIGNsZWFyTm93KCkge1xuICBjbG9ja05vdyA9IDA7XG59XG5cbmZ1bmN0aW9uIFRpbWVyKCkge1xuICB0aGlzLl9jYWxsID1cbiAgdGhpcy5fdGltZSA9XG4gIHRoaXMuX25leHQgPSBudWxsO1xufVxuXG5UaW1lci5wcm90b3R5cGUgPSB0aW1lci5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBUaW1lcixcbiAgcmVzdGFydDogZnVuY3Rpb24oY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FsbGJhY2sgaXMgbm90IGEgZnVuY3Rpb25cIik7XG4gICAgdGltZSA9ICh0aW1lID09IG51bGwgPyBub3coKSA6ICt0aW1lKSArIChkZWxheSA9PSBudWxsID8gMCA6ICtkZWxheSk7XG4gICAgaWYgKCF0aGlzLl9uZXh0ICYmIHRhc2tUYWlsICE9PSB0aGlzKSB7XG4gICAgICBpZiAodGFza1RhaWwpIHRhc2tUYWlsLl9uZXh0ID0gdGhpcztcbiAgICAgIGVsc2UgdGFza0hlYWQgPSB0aGlzO1xuICAgICAgdGFza1RhaWwgPSB0aGlzO1xuICAgIH1cbiAgICB0aGlzLl9jYWxsID0gY2FsbGJhY2s7XG4gICAgdGhpcy5fdGltZSA9IHRpbWU7XG4gICAgc2xlZXAoKTtcbiAgfSxcbiAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2NhbGwpIHtcbiAgICAgIHRoaXMuX2NhbGwgPSBudWxsO1xuICAgICAgdGhpcy5fdGltZSA9IEluZmluaXR5O1xuICAgICAgc2xlZXAoKTtcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHRpbWVyKGNhbGxiYWNrLCBkZWxheSwgdGltZSkge1xuICB2YXIgdCA9IG5ldyBUaW1lcjtcbiAgdC5yZXN0YXJ0KGNhbGxiYWNrLCBkZWxheSwgdGltZSk7XG4gIHJldHVybiB0O1xufVxuXG5mdW5jdGlvbiB0aW1lckZsdXNoKCkge1xuICBub3coKTsgLy8gR2V0IHRoZSBjdXJyZW50IHRpbWUsIGlmIG5vdCBhbHJlYWR5IHNldC5cbiAgKytmcmFtZTsgLy8gUHJldGVuZCB3ZeKAmXZlIHNldCBhbiBhbGFybSwgaWYgd2UgaGF2ZW7igJl0IGFscmVhZHkuXG4gIHZhciB0ID0gdGFza0hlYWQsIGU7XG4gIHdoaWxlICh0KSB7XG4gICAgaWYgKChlID0gY2xvY2tOb3cgLSB0Ll90aW1lKSA+PSAwKSB0Ll9jYWxsLmNhbGwobnVsbCwgZSk7XG4gICAgdCA9IHQuX25leHQ7XG4gIH1cbiAgLS1mcmFtZTtcbn1cblxuZnVuY3Rpb24gd2FrZSgpIHtcbiAgY2xvY2tOb3cgPSAoY2xvY2tMYXN0ID0gY2xvY2subm93KCkpICsgY2xvY2tTa2V3O1xuICBmcmFtZSA9IHRpbWVvdXQgPSAwO1xuICB0cnkge1xuICAgIHRpbWVyRmx1c2goKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBmcmFtZSA9IDA7XG4gICAgbmFwKCk7XG4gICAgY2xvY2tOb3cgPSAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBva2UoKSB7XG4gIHZhciBub3cgPSBjbG9jay5ub3coKSwgZGVsYXkgPSBub3cgLSBjbG9ja0xhc3Q7XG4gIGlmIChkZWxheSA+IHBva2VEZWxheSkgY2xvY2tTa2V3IC09IGRlbGF5LCBjbG9ja0xhc3QgPSBub3c7XG59XG5cbmZ1bmN0aW9uIG5hcCgpIHtcbiAgdmFyIHQwLCB0MSA9IHRhc2tIZWFkLCB0MiwgdGltZSA9IEluZmluaXR5O1xuICB3aGlsZSAodDEpIHtcbiAgICBpZiAodDEuX2NhbGwpIHtcbiAgICAgIGlmICh0aW1lID4gdDEuX3RpbWUpIHRpbWUgPSB0MS5fdGltZTtcbiAgICAgIHQwID0gdDEsIHQxID0gdDEuX25leHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHQyID0gdDEuX25leHQsIHQxLl9uZXh0ID0gbnVsbDtcbiAgICAgIHQxID0gdDAgPyB0MC5fbmV4dCA9IHQyIDogdGFza0hlYWQgPSB0MjtcbiAgICB9XG4gIH1cbiAgdGFza1RhaWwgPSB0MDtcbiAgc2xlZXAodGltZSk7XG59XG5cbmZ1bmN0aW9uIHNsZWVwKHRpbWUpIHtcbiAgaWYgKGZyYW1lKSByZXR1cm47IC8vIFNvb25lc3QgYWxhcm0gYWxyZWFkeSBzZXQsIG9yIHdpbGwgYmUuXG4gIGlmICh0aW1lb3V0KSB0aW1lb3V0ID0gY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICB2YXIgZGVsYXkgPSB0aW1lIC0gY2xvY2tOb3c7IC8vIFN0cmljdGx5IGxlc3MgdGhhbiBpZiB3ZSByZWNvbXB1dGVkIGNsb2NrTm93LlxuICBpZiAoZGVsYXkgPiAyNCkge1xuICAgIGlmICh0aW1lIDwgSW5maW5pdHkpIHRpbWVvdXQgPSBzZXRUaW1lb3V0KHdha2UsIHRpbWUgLSBjbG9jay5ub3coKSAtIGNsb2NrU2tldyk7XG4gICAgaWYgKGludGVydmFsKSBpbnRlcnZhbCA9IGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICB9IGVsc2Uge1xuICAgIGlmICghaW50ZXJ2YWwpIGNsb2NrTGFzdCA9IGNsb2NrLm5vdygpLCBpbnRlcnZhbCA9IHNldEludGVydmFsKHBva2UsIHBva2VEZWxheSk7XG4gICAgZnJhbWUgPSAxLCBzZXRGcmFtZSh3YWtlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB0aW1lb3V0JDEoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gIHZhciB0ID0gbmV3IFRpbWVyO1xuICBkZWxheSA9IGRlbGF5ID09IG51bGwgPyAwIDogK2RlbGF5O1xuICB0LnJlc3RhcnQoZnVuY3Rpb24oZWxhcHNlZCkge1xuICAgIHQuc3RvcCgpO1xuICAgIGNhbGxiYWNrKGVsYXBzZWQgKyBkZWxheSk7XG4gIH0sIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59XG5cbmZ1bmN0aW9uIGludGVydmFsJDEoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gIHZhciB0ID0gbmV3IFRpbWVyLCB0b3RhbCA9IGRlbGF5O1xuICBpZiAoZGVsYXkgPT0gbnVsbCkgcmV0dXJuIHQucmVzdGFydChjYWxsYmFjaywgZGVsYXksIHRpbWUpLCB0O1xuICBkZWxheSA9ICtkZWxheSwgdGltZSA9IHRpbWUgPT0gbnVsbCA/IG5vdygpIDogK3RpbWU7XG4gIHQucmVzdGFydChmdW5jdGlvbiB0aWNrKGVsYXBzZWQpIHtcbiAgICBlbGFwc2VkICs9IHRvdGFsO1xuICAgIHQucmVzdGFydCh0aWNrLCB0b3RhbCArPSBkZWxheSwgdGltZSk7XG4gICAgY2FsbGJhY2soZWxhcHNlZCk7XG4gIH0sIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59XG5cbmV4cG9ydHMuaW50ZXJ2YWwgPSBpbnRlcnZhbCQxO1xuZXhwb3J0cy5ub3cgPSBub3c7XG5leHBvcnRzLnRpbWVvdXQgPSB0aW1lb3V0JDE7XG5leHBvcnRzLnRpbWVyID0gdGltZXI7XG5leHBvcnRzLnRpbWVyRmx1c2ggPSB0aW1lckZsdXNoO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG59KSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX3NwcmVhZEFycmF5cyA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheXMpIHx8IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgICAgcltrXSA9IGFbal07XG4gICAgcmV0dXJuIHI7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIEJyb3dzZXJJbmZvID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJyb3dzZXJJbmZvKG5hbWUsIHZlcnNpb24sIG9zKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247XG4gICAgICAgIHRoaXMub3MgPSBvcztcbiAgICAgICAgdGhpcy50eXBlID0gJ2Jyb3dzZXInO1xuICAgIH1cbiAgICByZXR1cm4gQnJvd3NlckluZm87XG59KCkpO1xuZXhwb3J0cy5Ccm93c2VySW5mbyA9IEJyb3dzZXJJbmZvO1xudmFyIE5vZGVJbmZvID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIE5vZGVJbmZvKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcbiAgICAgICAgdGhpcy50eXBlID0gJ25vZGUnO1xuICAgICAgICB0aGlzLm5hbWUgPSAnbm9kZSc7XG4gICAgICAgIHRoaXMub3MgPSBwcm9jZXNzLnBsYXRmb3JtO1xuICAgIH1cbiAgICByZXR1cm4gTm9kZUluZm87XG59KCkpO1xuZXhwb3J0cy5Ob2RlSW5mbyA9IE5vZGVJbmZvO1xudmFyIFNlYXJjaEJvdERldmljZUluZm8gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gU2VhcmNoQm90RGV2aWNlSW5mbyhuYW1lLCB2ZXJzaW9uLCBvcywgYm90KSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247XG4gICAgICAgIHRoaXMub3MgPSBvcztcbiAgICAgICAgdGhpcy5ib3QgPSBib3Q7XG4gICAgICAgIHRoaXMudHlwZSA9ICdib3QtZGV2aWNlJztcbiAgICB9XG4gICAgcmV0dXJuIFNlYXJjaEJvdERldmljZUluZm87XG59KCkpO1xuZXhwb3J0cy5TZWFyY2hCb3REZXZpY2VJbmZvID0gU2VhcmNoQm90RGV2aWNlSW5mbztcbnZhciBCb3RJbmZvID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJvdEluZm8oKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdib3QnO1xuICAgICAgICB0aGlzLmJvdCA9IHRydWU7IC8vIE5PVEU6IGRlcHJlY2F0ZWQgdGVzdCBuYW1lIGluc3RlYWRcbiAgICAgICAgdGhpcy5uYW1lID0gJ2JvdCc7XG4gICAgICAgIHRoaXMudmVyc2lvbiA9IG51bGw7XG4gICAgICAgIHRoaXMub3MgPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gQm90SW5mbztcbn0oKSk7XG5leHBvcnRzLkJvdEluZm8gPSBCb3RJbmZvO1xudmFyIFJlYWN0TmF0aXZlSW5mbyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBSZWFjdE5hdGl2ZUluZm8oKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyZWFjdC1uYXRpdmUnO1xuICAgICAgICB0aGlzLm5hbWUgPSAncmVhY3QtbmF0aXZlJztcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5vcyA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBSZWFjdE5hdGl2ZUluZm87XG59KCkpO1xuZXhwb3J0cy5SZWFjdE5hdGl2ZUluZm8gPSBSZWFjdE5hdGl2ZUluZm87XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG52YXIgU0VBUkNIQk9YX1VBX1JFR0VYID0gL2FsZXhhfGJvdHxjcmF3bChlcnxpbmcpfGZhY2Vib29rZXh0ZXJuYWxoaXR8ZmVlZGJ1cm5lcnxnb29nbGUgd2ViIHByZXZpZXd8bmFnaW9zfHBvc3RyYW5rfHBpbmdkb218c2x1cnB8c3BpZGVyfHlhaG9vIXx5YW5kZXgvO1xudmFyIFNFQVJDSEJPVF9PU19SRUdFWCA9IC8obnVoa3xHb29nbGVib3R8WWFtbXlib3R8T3BlbmJvdHxTbHVycHxNU05Cb3R8QXNrXFwgSmVldmVzXFwvVGVvbWF8aWFfYXJjaGl2ZXIpLztcbnZhciBSRVFVSVJFRF9WRVJTSU9OX1BBUlRTID0gMztcbnZhciB1c2VyQWdlbnRSdWxlcyA9IFtcbiAgICBbJ2FvbCcsIC9BT0xTaGllbGRcXC8oWzAtOVxcLl9dKykvXSxcbiAgICBbJ2VkZ2UnLCAvRWRnZVxcLyhbMC05XFwuX10rKS9dLFxuICAgIFsnZWRnZS1pb3MnLCAvRWRnaU9TXFwvKFswLTlcXC5fXSspL10sXG4gICAgWyd5YW5kZXhicm93c2VyJywgL1lhQnJvd3NlclxcLyhbMC05XFwuX10rKS9dLFxuICAgIFsna2FrYW90YWxrJywgL0tBS0FPVEFMS1xccyhbMC05XFwuXSspL10sXG4gICAgWydzYW1zdW5nJywgL1NhbXN1bmdCcm93c2VyXFwvKFswLTlcXC5dKykvXSxcbiAgICBbJ3NpbGsnLCAvXFxiU2lsa1xcLyhbMC05Ll8tXSspXFxiL10sXG4gICAgWydtaXVpJywgL01pdWlCcm93c2VyXFwvKFswLTlcXC5dKykkL10sXG4gICAgWydiZWFrZXInLCAvQmVha2VyQnJvd3NlclxcLyhbMC05XFwuXSspL10sXG4gICAgWydlZGdlLWNocm9taXVtJywgL0VkZ1xcLyhbMC05XFwuXSspL10sXG4gICAgW1xuICAgICAgICAnY2hyb21pdW0td2VidmlldycsXG4gICAgICAgIC8oPyFDaHJvbS4qT1BSKXd2XFwpLipDaHJvbSg/OmV8aXVtKVxcLyhbMC05XFwuXSspKDo/XFxzfCQpLyxcbiAgICBdLFxuICAgIFsnY2hyb21lJywgLyg/IUNocm9tLipPUFIpQ2hyb20oPzplfGl1bSlcXC8oWzAtOVxcLl0rKSg6P1xcc3wkKS9dLFxuICAgIFsncGhhbnRvbWpzJywgL1BoYW50b21KU1xcLyhbMC05XFwuXSspKDo/XFxzfCQpL10sXG4gICAgWydjcmlvcycsIC9DcmlPU1xcLyhbMC05XFwuXSspKDo/XFxzfCQpL10sXG4gICAgWydmaXJlZm94JywgL0ZpcmVmb3hcXC8oWzAtOVxcLl0rKSg/Olxcc3wkKS9dLFxuICAgIFsnZnhpb3MnLCAvRnhpT1NcXC8oWzAtOVxcLl0rKS9dLFxuICAgIFsnb3BlcmEtbWluaScsIC9PcGVyYSBNaW5pLipWZXJzaW9uXFwvKFswLTlcXC5dKykvXSxcbiAgICBbJ29wZXJhJywgL09wZXJhXFwvKFswLTlcXC5dKykoPzpcXHN8JCkvXSxcbiAgICBbJ29wZXJhJywgL09QUlxcLyhbMC05XFwuXSspKDo/XFxzfCQpL10sXG4gICAgWydpZScsIC9UcmlkZW50XFwvN1xcLjAuKnJ2XFw6KFswLTlcXC5dKykuKlxcKS4qR2Vja28kL10sXG4gICAgWydpZScsIC9NU0lFXFxzKFswLTlcXC5dKyk7LipUcmlkZW50XFwvWzQtN10uMC9dLFxuICAgIFsnaWUnLCAvTVNJRVxccyg3XFwuMCkvXSxcbiAgICBbJ2JiMTAnLCAvQkIxMDtcXHNUb3VjaC4qVmVyc2lvblxcLyhbMC05XFwuXSspL10sXG4gICAgWydhbmRyb2lkJywgL0FuZHJvaWRcXHMoWzAtOVxcLl0rKS9dLFxuICAgIFsnaW9zJywgL1ZlcnNpb25cXC8oWzAtOVxcLl9dKykuKk1vYmlsZS4qU2FmYXJpLiovXSxcbiAgICBbJ3NhZmFyaScsIC9WZXJzaW9uXFwvKFswLTlcXC5fXSspLipTYWZhcmkvXSxcbiAgICBbJ2ZhY2Vib29rJywgL0ZCQVZcXC8oWzAtOVxcLl0rKS9dLFxuICAgIFsnaW5zdGFncmFtJywgL0luc3RhZ3JhbVxccyhbMC05XFwuXSspL10sXG4gICAgWydpb3Mtd2VidmlldycsIC9BcHBsZVdlYktpdFxcLyhbMC05XFwuXSspLipNb2JpbGUvXSxcbiAgICBbJ2lvcy13ZWJ2aWV3JywgL0FwcGxlV2ViS2l0XFwvKFswLTlcXC5dKykuKkdlY2tvXFwpJC9dLFxuICAgIFsnc2VhcmNoYm90JywgU0VBUkNIQk9YX1VBX1JFR0VYXSxcbl07XG52YXIgb3BlcmF0aW5nU3lzdGVtUnVsZXMgPSBbXG4gICAgWydpT1MnLCAvaVAoaG9uZXxvZHxhZCkvXSxcbiAgICBbJ0FuZHJvaWQgT1MnLCAvQW5kcm9pZC9dLFxuICAgIFsnQmxhY2tCZXJyeSBPUycsIC9CbGFja0JlcnJ5fEJCMTAvXSxcbiAgICBbJ1dpbmRvd3MgTW9iaWxlJywgL0lFTW9iaWxlL10sXG4gICAgWydBbWF6b24gT1MnLCAvS2luZGxlL10sXG4gICAgWydXaW5kb3dzIDMuMTEnLCAvV2luMTYvXSxcbiAgICBbJ1dpbmRvd3MgOTUnLCAvKFdpbmRvd3MgOTUpfChXaW45NSl8KFdpbmRvd3NfOTUpL10sXG4gICAgWydXaW5kb3dzIDk4JywgLyhXaW5kb3dzIDk4KXwoV2luOTgpL10sXG4gICAgWydXaW5kb3dzIDIwMDAnLCAvKFdpbmRvd3MgTlQgNS4wKXwoV2luZG93cyAyMDAwKS9dLFxuICAgIFsnV2luZG93cyBYUCcsIC8oV2luZG93cyBOVCA1LjEpfChXaW5kb3dzIFhQKS9dLFxuICAgIFsnV2luZG93cyBTZXJ2ZXIgMjAwMycsIC8oV2luZG93cyBOVCA1LjIpL10sXG4gICAgWydXaW5kb3dzIFZpc3RhJywgLyhXaW5kb3dzIE5UIDYuMCkvXSxcbiAgICBbJ1dpbmRvd3MgNycsIC8oV2luZG93cyBOVCA2LjEpL10sXG4gICAgWydXaW5kb3dzIDgnLCAvKFdpbmRvd3MgTlQgNi4yKS9dLFxuICAgIFsnV2luZG93cyA4LjEnLCAvKFdpbmRvd3MgTlQgNi4zKS9dLFxuICAgIFsnV2luZG93cyAxMCcsIC8oV2luZG93cyBOVCAxMC4wKS9dLFxuICAgIFsnV2luZG93cyBNRScsIC9XaW5kb3dzIE1FL10sXG4gICAgWydPcGVuIEJTRCcsIC9PcGVuQlNEL10sXG4gICAgWydTdW4gT1MnLCAvU3VuT1MvXSxcbiAgICBbJ0Nocm9tZSBPUycsIC9Dck9TL10sXG4gICAgWydMaW51eCcsIC8oTGludXgpfChYMTEpL10sXG4gICAgWydNYWMgT1MnLCAvKE1hY19Qb3dlclBDKXwoTWFjaW50b3NoKS9dLFxuICAgIFsnUU5YJywgL1FOWC9dLFxuICAgIFsnQmVPUycsIC9CZU9TL10sXG4gICAgWydPUy8yJywgL09TXFwvMi9dLFxuXTtcbmZ1bmN0aW9uIGRldGVjdCh1c2VyQWdlbnQpIHtcbiAgICBpZiAoISF1c2VyQWdlbnQpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlVXNlckFnZW50KHVzZXJBZ2VudCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVhY3ROYXRpdmVJbmZvKCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gcGFyc2VVc2VyQWdlbnQobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gICAgfVxuICAgIHJldHVybiBnZXROb2RlVmVyc2lvbigpO1xufVxuZXhwb3J0cy5kZXRlY3QgPSBkZXRlY3Q7XG5mdW5jdGlvbiBtYXRjaFVzZXJBZ2VudCh1YSkge1xuICAgIC8vIG9wdGVkIGZvciB1c2luZyByZWR1Y2UgaGVyZSByYXRoZXIgdGhhbiBBcnJheSNmaXJzdCB3aXRoIGEgcmVnZXgudGVzdCBjYWxsXG4gICAgLy8gdGhpcyBpcyBwcmltYXJpbHkgYmVjYXVzZSB1c2luZyB0aGUgcmVkdWNlIHdlIG9ubHkgcGVyZm9ybSB0aGUgcmVnZXhcbiAgICAvLyBleGVjdXRpb24gb25jZSByYXRoZXIgdGhhbiBvbmNlIGZvciB0aGUgdGVzdCBhbmQgZm9yIHRoZSBleGVjIGFnYWluIGJlbG93XG4gICAgLy8gcHJvYmFibHkgc29tZXRoaW5nIHRoYXQgbmVlZHMgdG8gYmUgYmVuY2htYXJrZWQgdGhvdWdoXG4gICAgcmV0dXJuICh1YSAhPT0gJycgJiZcbiAgICAgICAgdXNlckFnZW50UnVsZXMucmVkdWNlKGZ1bmN0aW9uIChtYXRjaGVkLCBfYSkge1xuICAgICAgICAgICAgdmFyIGJyb3dzZXIgPSBfYVswXSwgcmVnZXggPSBfYVsxXTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdWFNYXRjaCA9IHJlZ2V4LmV4ZWModWEpO1xuICAgICAgICAgICAgcmV0dXJuICEhdWFNYXRjaCAmJiBbYnJvd3NlciwgdWFNYXRjaF07XG4gICAgICAgIH0sIGZhbHNlKSk7XG59XG5mdW5jdGlvbiBicm93c2VyTmFtZSh1YSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hVc2VyQWdlbnQodWEpO1xuICAgIHJldHVybiBkYXRhID8gZGF0YVswXSA6IG51bGw7XG59XG5leHBvcnRzLmJyb3dzZXJOYW1lID0gYnJvd3Nlck5hbWU7XG5mdW5jdGlvbiBwYXJzZVVzZXJBZ2VudCh1YSkge1xuICAgIHZhciBtYXRjaGVkUnVsZSA9IG1hdGNoVXNlckFnZW50KHVhKTtcbiAgICBpZiAoIW1hdGNoZWRSdWxlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbmFtZSA9IG1hdGNoZWRSdWxlWzBdLCBtYXRjaCA9IG1hdGNoZWRSdWxlWzFdO1xuICAgIGlmIChuYW1lID09PSAnc2VhcmNoYm90Jykge1xuICAgICAgICByZXR1cm4gbmV3IEJvdEluZm8oKTtcbiAgICB9XG4gICAgdmFyIHZlcnNpb25QYXJ0cyA9IG1hdGNoWzFdICYmIG1hdGNoWzFdLnNwbGl0KC9bLl9dLykuc2xpY2UoMCwgMyk7XG4gICAgaWYgKHZlcnNpb25QYXJ0cykge1xuICAgICAgICBpZiAodmVyc2lvblBhcnRzLmxlbmd0aCA8IFJFUVVJUkVEX1ZFUlNJT05fUEFSVFMpIHtcbiAgICAgICAgICAgIHZlcnNpb25QYXJ0cyA9IF9fc3ByZWFkQXJyYXlzKHZlcnNpb25QYXJ0cywgY3JlYXRlVmVyc2lvblBhcnRzKFJFUVVJUkVEX1ZFUlNJT05fUEFSVFMgLSB2ZXJzaW9uUGFydHMubGVuZ3RoKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZlcnNpb25QYXJ0cyA9IFtdO1xuICAgIH1cbiAgICB2YXIgdmVyc2lvbiA9IHZlcnNpb25QYXJ0cy5qb2luKCcuJyk7XG4gICAgdmFyIG9zID0gZGV0ZWN0T1ModWEpO1xuICAgIHZhciBzZWFyY2hCb3RNYXRjaCA9IFNFQVJDSEJPVF9PU19SRUdFWC5leGVjKHVhKTtcbiAgICBpZiAoc2VhcmNoQm90TWF0Y2ggJiYgc2VhcmNoQm90TWF0Y2hbMV0pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTZWFyY2hCb3REZXZpY2VJbmZvKG5hbWUsIHZlcnNpb24sIG9zLCBzZWFyY2hCb3RNYXRjaFsxXSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQnJvd3NlckluZm8obmFtZSwgdmVyc2lvbiwgb3MpO1xufVxuZXhwb3J0cy5wYXJzZVVzZXJBZ2VudCA9IHBhcnNlVXNlckFnZW50O1xuZnVuY3Rpb24gZGV0ZWN0T1ModWEpIHtcbiAgICBmb3IgKHZhciBpaSA9IDAsIGNvdW50ID0gb3BlcmF0aW5nU3lzdGVtUnVsZXMubGVuZ3RoOyBpaSA8IGNvdW50OyBpaSsrKSB7XG4gICAgICAgIHZhciBfYSA9IG9wZXJhdGluZ1N5c3RlbVJ1bGVzW2lpXSwgb3MgPSBfYVswXSwgcmVnZXggPSBfYVsxXTtcbiAgICAgICAgdmFyIG1hdGNoID0gcmVnZXguZXhlYyh1YSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgcmV0dXJuIG9zO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZXhwb3J0cy5kZXRlY3RPUyA9IGRldGVjdE9TO1xuZnVuY3Rpb24gZ2V0Tm9kZVZlcnNpb24oKSB7XG4gICAgdmFyIGlzTm9kZSA9IHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb247XG4gICAgcmV0dXJuIGlzTm9kZSA/IG5ldyBOb2RlSW5mbyhwcm9jZXNzLnZlcnNpb24uc2xpY2UoMSkpIDogbnVsbDtcbn1cbmV4cG9ydHMuZ2V0Tm9kZVZlcnNpb24gPSBnZXROb2RlVmVyc2lvbjtcbmZ1bmN0aW9uIGNyZWF0ZVZlcnNpb25QYXJ0cyhjb3VudCkge1xuICAgIHZhciBvdXRwdXQgPSBbXTtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgY291bnQ7IGlpKyspIHtcbiAgICAgICAgb3V0cHV0LnB1c2goJzAnKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbn1cbiIsIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IGZhY3RvcnkoZXhwb3J0cykgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJ10sIGZhY3RvcnkpIDpcbiAgKGZhY3RvcnkoKGdsb2JhbC5mZWNoYSA9IHt9KSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIHZhciB0b2tlbiA9IC9kezEsNH18TXsxLDR9fFlZKD86WVkpP3xTezEsM318RG98Wlp8WnwoW0hoTXNEbV0pXFwxP3xbYUFdfFwiW15cIl0qXCJ8J1teJ10qJy9nO1xuICB2YXIgdHdvRGlnaXRzT3B0aW9uYWwgPSBcIlsxLTldXFxcXGQ/XCI7XG4gIHZhciB0d29EaWdpdHMgPSBcIlxcXFxkXFxcXGRcIjtcbiAgdmFyIHRocmVlRGlnaXRzID0gXCJcXFxcZHszfVwiO1xuICB2YXIgZm91ckRpZ2l0cyA9IFwiXFxcXGR7NH1cIjtcbiAgdmFyIHdvcmQgPSBcIlteXFxcXHNdK1wiO1xuICB2YXIgbGl0ZXJhbCA9IC9cXFsoW15dKj8pXFxdL2dtO1xuICBmdW5jdGlvbiBzaG9ydGVuKGFyciwgc0xlbikge1xuICAgICAgdmFyIG5ld0FyciA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFyci5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIG5ld0Fyci5wdXNoKGFycltpXS5zdWJzdHIoMCwgc0xlbikpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0FycjtcbiAgfVxuICB2YXIgbW9udGhVcGRhdGUgPSBmdW5jdGlvbiAoYXJyTmFtZSkgeyByZXR1cm4gZnVuY3Rpb24gKHYsIGkxOG4pIHtcbiAgICAgIHZhciBsb3dlckNhc2VBcnIgPSBpMThuW2Fyck5hbWVdLm1hcChmdW5jdGlvbiAodikgeyByZXR1cm4gdi50b0xvd2VyQ2FzZSgpOyB9KTtcbiAgICAgIHZhciBpbmRleCA9IGxvd2VyQ2FzZUFyci5pbmRleE9mKHYudG9Mb3dlckNhc2UoKSk7XG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICB9OyB9O1xuICBmdW5jdGlvbiBhc3NpZ24ob3JpZ09iaikge1xuICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgYXJnc1tfaSAtIDFdID0gYXJndW1lbnRzW19pXTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIF9hID0gMCwgYXJnc18xID0gYXJnczsgX2EgPCBhcmdzXzEubGVuZ3RoOyBfYSsrKSB7XG4gICAgICAgICAgdmFyIG9iaiA9IGFyZ3NfMVtfYV07XG4gICAgICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlIGV4XG4gICAgICAgICAgICAgIG9yaWdPYmpba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvcmlnT2JqO1xuICB9XG4gIHZhciBkYXlOYW1lcyA9IFtcbiAgICAgIFwiU3VuZGF5XCIsXG4gICAgICBcIk1vbmRheVwiLFxuICAgICAgXCJUdWVzZGF5XCIsXG4gICAgICBcIldlZG5lc2RheVwiLFxuICAgICAgXCJUaHVyc2RheVwiLFxuICAgICAgXCJGcmlkYXlcIixcbiAgICAgIFwiU2F0dXJkYXlcIlxuICBdO1xuICB2YXIgbW9udGhOYW1lcyA9IFtcbiAgICAgIFwiSmFudWFyeVwiLFxuICAgICAgXCJGZWJydWFyeVwiLFxuICAgICAgXCJNYXJjaFwiLFxuICAgICAgXCJBcHJpbFwiLFxuICAgICAgXCJNYXlcIixcbiAgICAgIFwiSnVuZVwiLFxuICAgICAgXCJKdWx5XCIsXG4gICAgICBcIkF1Z3VzdFwiLFxuICAgICAgXCJTZXB0ZW1iZXJcIixcbiAgICAgIFwiT2N0b2JlclwiLFxuICAgICAgXCJOb3ZlbWJlclwiLFxuICAgICAgXCJEZWNlbWJlclwiXG4gIF07XG4gIHZhciBtb250aE5hbWVzU2hvcnQgPSBzaG9ydGVuKG1vbnRoTmFtZXMsIDMpO1xuICB2YXIgZGF5TmFtZXNTaG9ydCA9IHNob3J0ZW4oZGF5TmFtZXMsIDMpO1xuICB2YXIgZGVmYXVsdEkxOG4gPSB7XG4gICAgICBkYXlOYW1lc1Nob3J0OiBkYXlOYW1lc1Nob3J0LFxuICAgICAgZGF5TmFtZXM6IGRheU5hbWVzLFxuICAgICAgbW9udGhOYW1lc1Nob3J0OiBtb250aE5hbWVzU2hvcnQsXG4gICAgICBtb250aE5hbWVzOiBtb250aE5hbWVzLFxuICAgICAgYW1QbTogW1wiYW1cIiwgXCJwbVwiXSxcbiAgICAgIERvRm46IGZ1bmN0aW9uIChkYXlPZk1vbnRoKSB7XG4gICAgICAgICAgcmV0dXJuIChkYXlPZk1vbnRoICtcbiAgICAgICAgICAgICAgW1widGhcIiwgXCJzdFwiLCBcIm5kXCIsIFwicmRcIl1bZGF5T2ZNb250aCAlIDEwID4gM1xuICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICA6ICgoZGF5T2ZNb250aCAtIChkYXlPZk1vbnRoICUgMTApICE9PSAxMCA/IDEgOiAwKSAqIGRheU9mTW9udGgpICUgMTBdKTtcbiAgICAgIH1cbiAgfTtcbiAgdmFyIGdsb2JhbEkxOG4gPSBhc3NpZ24oe30sIGRlZmF1bHRJMThuKTtcbiAgdmFyIHNldEdsb2JhbERhdGVJMThuID0gZnVuY3Rpb24gKGkxOG4pIHtcbiAgICAgIHJldHVybiAoZ2xvYmFsSTE4biA9IGFzc2lnbihnbG9iYWxJMThuLCBpMThuKSk7XG4gIH07XG4gIHZhciByZWdleEVzY2FwZSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvW3xcXFxceygpW14kKyo/Li1dL2csIFwiXFxcXCQmXCIpO1xuICB9O1xuICB2YXIgcGFkID0gZnVuY3Rpb24gKHZhbCwgbGVuKSB7XG4gICAgICBpZiAobGVuID09PSB2b2lkIDApIHsgbGVuID0gMjsgfVxuICAgICAgdmFsID0gU3RyaW5nKHZhbCk7XG4gICAgICB3aGlsZSAodmFsLmxlbmd0aCA8IGxlbikge1xuICAgICAgICAgIHZhbCA9IFwiMFwiICsgdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbDtcbiAgfTtcbiAgdmFyIGZvcm1hdEZsYWdzID0ge1xuICAgICAgRDogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIFN0cmluZyhkYXRlT2JqLmdldERhdGUoKSk7IH0sXG4gICAgICBERDogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIHBhZChkYXRlT2JqLmdldERhdGUoKSk7IH0sXG4gICAgICBEbzogZnVuY3Rpb24gKGRhdGVPYmosIGkxOG4pIHtcbiAgICAgICAgICByZXR1cm4gaTE4bi5Eb0ZuKGRhdGVPYmouZ2V0RGF0ZSgpKTtcbiAgICAgIH0sXG4gICAgICBkOiBmdW5jdGlvbiAoZGF0ZU9iaikgeyByZXR1cm4gU3RyaW5nKGRhdGVPYmouZ2V0RGF5KCkpOyB9LFxuICAgICAgZGQ6IGZ1bmN0aW9uIChkYXRlT2JqKSB7IHJldHVybiBwYWQoZGF0ZU9iai5nZXREYXkoKSk7IH0sXG4gICAgICBkZGQ6IGZ1bmN0aW9uIChkYXRlT2JqLCBpMThuKSB7XG4gICAgICAgICAgcmV0dXJuIGkxOG4uZGF5TmFtZXNTaG9ydFtkYXRlT2JqLmdldERheSgpXTtcbiAgICAgIH0sXG4gICAgICBkZGRkOiBmdW5jdGlvbiAoZGF0ZU9iaiwgaTE4bikge1xuICAgICAgICAgIHJldHVybiBpMThuLmRheU5hbWVzW2RhdGVPYmouZ2V0RGF5KCldO1xuICAgICAgfSxcbiAgICAgIE06IGZ1bmN0aW9uIChkYXRlT2JqKSB7IHJldHVybiBTdHJpbmcoZGF0ZU9iai5nZXRNb250aCgpICsgMSk7IH0sXG4gICAgICBNTTogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIHBhZChkYXRlT2JqLmdldE1vbnRoKCkgKyAxKTsgfSxcbiAgICAgIE1NTTogZnVuY3Rpb24gKGRhdGVPYmosIGkxOG4pIHtcbiAgICAgICAgICByZXR1cm4gaTE4bi5tb250aE5hbWVzU2hvcnRbZGF0ZU9iai5nZXRNb250aCgpXTtcbiAgICAgIH0sXG4gICAgICBNTU1NOiBmdW5jdGlvbiAoZGF0ZU9iaiwgaTE4bikge1xuICAgICAgICAgIHJldHVybiBpMThuLm1vbnRoTmFtZXNbZGF0ZU9iai5nZXRNb250aCgpXTtcbiAgICAgIH0sXG4gICAgICBZWTogZnVuY3Rpb24gKGRhdGVPYmopIHtcbiAgICAgICAgICByZXR1cm4gcGFkKFN0cmluZyhkYXRlT2JqLmdldEZ1bGxZZWFyKCkpLCA0KS5zdWJzdHIoMik7XG4gICAgICB9LFxuICAgICAgWVlZWTogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIHBhZChkYXRlT2JqLmdldEZ1bGxZZWFyKCksIDQpOyB9LFxuICAgICAgaDogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIFN0cmluZyhkYXRlT2JqLmdldEhvdXJzKCkgJSAxMiB8fCAxMik7IH0sXG4gICAgICBoaDogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIHBhZChkYXRlT2JqLmdldEhvdXJzKCkgJSAxMiB8fCAxMik7IH0sXG4gICAgICBIOiBmdW5jdGlvbiAoZGF0ZU9iaikgeyByZXR1cm4gU3RyaW5nKGRhdGVPYmouZ2V0SG91cnMoKSk7IH0sXG4gICAgICBISDogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIHBhZChkYXRlT2JqLmdldEhvdXJzKCkpOyB9LFxuICAgICAgbTogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIFN0cmluZyhkYXRlT2JqLmdldE1pbnV0ZXMoKSk7IH0sXG4gICAgICBtbTogZnVuY3Rpb24gKGRhdGVPYmopIHsgcmV0dXJuIHBhZChkYXRlT2JqLmdldE1pbnV0ZXMoKSk7IH0sXG4gICAgICBzOiBmdW5jdGlvbiAoZGF0ZU9iaikgeyByZXR1cm4gU3RyaW5nKGRhdGVPYmouZ2V0U2Vjb25kcygpKTsgfSxcbiAgICAgIHNzOiBmdW5jdGlvbiAoZGF0ZU9iaikgeyByZXR1cm4gcGFkKGRhdGVPYmouZ2V0U2Vjb25kcygpKTsgfSxcbiAgICAgIFM6IGZ1bmN0aW9uIChkYXRlT2JqKSB7XG4gICAgICAgICAgcmV0dXJuIFN0cmluZyhNYXRoLnJvdW5kKGRhdGVPYmouZ2V0TWlsbGlzZWNvbmRzKCkgLyAxMDApKTtcbiAgICAgIH0sXG4gICAgICBTUzogZnVuY3Rpb24gKGRhdGVPYmopIHtcbiAgICAgICAgICByZXR1cm4gcGFkKE1hdGgucm91bmQoZGF0ZU9iai5nZXRNaWxsaXNlY29uZHMoKSAvIDEwKSwgMik7XG4gICAgICB9LFxuICAgICAgU1NTOiBmdW5jdGlvbiAoZGF0ZU9iaikgeyByZXR1cm4gcGFkKGRhdGVPYmouZ2V0TWlsbGlzZWNvbmRzKCksIDMpOyB9LFxuICAgICAgYTogZnVuY3Rpb24gKGRhdGVPYmosIGkxOG4pIHtcbiAgICAgICAgICByZXR1cm4gZGF0ZU9iai5nZXRIb3VycygpIDwgMTIgPyBpMThuLmFtUG1bMF0gOiBpMThuLmFtUG1bMV07XG4gICAgICB9LFxuICAgICAgQTogZnVuY3Rpb24gKGRhdGVPYmosIGkxOG4pIHtcbiAgICAgICAgICByZXR1cm4gZGF0ZU9iai5nZXRIb3VycygpIDwgMTJcbiAgICAgICAgICAgICAgPyBpMThuLmFtUG1bMF0udG9VcHBlckNhc2UoKVxuICAgICAgICAgICAgICA6IGkxOG4uYW1QbVsxXS50b1VwcGVyQ2FzZSgpO1xuICAgICAgfSxcbiAgICAgIFpaOiBmdW5jdGlvbiAoZGF0ZU9iaikge1xuICAgICAgICAgIHZhciBvZmZzZXQgPSBkYXRlT2JqLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgICAgICAgcmV0dXJuICgob2Zmc2V0ID4gMCA/IFwiLVwiIDogXCIrXCIpICtcbiAgICAgICAgICAgICAgcGFkKE1hdGguZmxvb3IoTWF0aC5hYnMob2Zmc2V0KSAvIDYwKSAqIDEwMCArIChNYXRoLmFicyhvZmZzZXQpICUgNjApLCA0KSk7XG4gICAgICB9LFxuICAgICAgWjogZnVuY3Rpb24gKGRhdGVPYmopIHtcbiAgICAgICAgICB2YXIgb2Zmc2V0ID0gZGF0ZU9iai5nZXRUaW1lem9uZU9mZnNldCgpO1xuICAgICAgICAgIHJldHVybiAoKG9mZnNldCA+IDAgPyBcIi1cIiA6IFwiK1wiKSArXG4gICAgICAgICAgICAgIHBhZChNYXRoLmZsb29yKE1hdGguYWJzKG9mZnNldCkgLyA2MCksIDIpICtcbiAgICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgICBwYWQoTWF0aC5hYnMob2Zmc2V0KSAlIDYwLCAyKSk7XG4gICAgICB9XG4gIH07XG4gIHZhciBtb250aFBhcnNlID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuICt2IC0gMTsgfTtcbiAgdmFyIGVtcHR5RGlnaXRzID0gW251bGwsIHR3b0RpZ2l0c09wdGlvbmFsXTtcbiAgdmFyIGVtcHR5V29yZCA9IFtudWxsLCB3b3JkXTtcbiAgdmFyIGFtUG0gPSBbXG4gICAgICBcImlzUG1cIixcbiAgICAgIHdvcmQsXG4gICAgICBmdW5jdGlvbiAodiwgaTE4bikge1xuICAgICAgICAgIHZhciB2YWwgPSB2LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgaWYgKHZhbCA9PT0gaTE4bi5hbVBtWzBdKSB7XG4gICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmICh2YWwgPT09IGkxOG4uYW1QbVsxXSkge1xuICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gIF07XG4gIHZhciB0aW1lem9uZU9mZnNldCA9IFtcbiAgICAgIFwidGltZXpvbmVPZmZzZXRcIixcbiAgICAgIFwiW15cXFxcc10qP1tcXFxcK1xcXFwtXVxcXFxkXFxcXGQ6P1xcXFxkXFxcXGR8W15cXFxcc10qP1o/XCIsXG4gICAgICBmdW5jdGlvbiAodikge1xuICAgICAgICAgIHZhciBwYXJ0cyA9ICh2ICsgXCJcIikubWF0Y2goLyhbKy1dfFxcZFxcZCkvZ2kpO1xuICAgICAgICAgIGlmIChwYXJ0cykge1xuICAgICAgICAgICAgICB2YXIgbWludXRlcyA9ICtwYXJ0c1sxXSAqIDYwICsgcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHBhcnRzWzBdID09PSBcIitcIiA/IG1pbnV0ZXMgOiAtbWludXRlcztcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gIF07XG4gIHZhciBwYXJzZUZsYWdzID0ge1xuICAgICAgRDogW1wiZGF5XCIsIHR3b0RpZ2l0c09wdGlvbmFsXSxcbiAgICAgIEREOiBbXCJkYXlcIiwgdHdvRGlnaXRzXSxcbiAgICAgIERvOiBbXCJkYXlcIiwgdHdvRGlnaXRzT3B0aW9uYWwgKyB3b3JkLCBmdW5jdGlvbiAodikgeyByZXR1cm4gcGFyc2VJbnQodiwgMTApOyB9XSxcbiAgICAgIE06IFtcIm1vbnRoXCIsIHR3b0RpZ2l0c09wdGlvbmFsLCBtb250aFBhcnNlXSxcbiAgICAgIE1NOiBbXCJtb250aFwiLCB0d29EaWdpdHMsIG1vbnRoUGFyc2VdLFxuICAgICAgWVk6IFtcbiAgICAgICAgICBcInllYXJcIixcbiAgICAgICAgICB0d29EaWdpdHMsXG4gICAgICAgICAgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICAgIHZhciBjZW50ID0gKyhcIlwiICsgbm93LmdldEZ1bGxZZWFyKCkpLnN1YnN0cigwLCAyKTtcbiAgICAgICAgICAgICAgcmV0dXJuICsoXCJcIiArICgrdiA+IDY4ID8gY2VudCAtIDEgOiBjZW50KSArIHYpO1xuICAgICAgICAgIH1cbiAgICAgIF0sXG4gICAgICBoOiBbXCJob3VyXCIsIHR3b0RpZ2l0c09wdGlvbmFsLCB1bmRlZmluZWQsIFwiaXNQbVwiXSxcbiAgICAgIGhoOiBbXCJob3VyXCIsIHR3b0RpZ2l0cywgdW5kZWZpbmVkLCBcImlzUG1cIl0sXG4gICAgICBIOiBbXCJob3VyXCIsIHR3b0RpZ2l0c09wdGlvbmFsXSxcbiAgICAgIEhIOiBbXCJob3VyXCIsIHR3b0RpZ2l0c10sXG4gICAgICBtOiBbXCJtaW51dGVcIiwgdHdvRGlnaXRzT3B0aW9uYWxdLFxuICAgICAgbW06IFtcIm1pbnV0ZVwiLCB0d29EaWdpdHNdLFxuICAgICAgczogW1wic2Vjb25kXCIsIHR3b0RpZ2l0c09wdGlvbmFsXSxcbiAgICAgIHNzOiBbXCJzZWNvbmRcIiwgdHdvRGlnaXRzXSxcbiAgICAgIFlZWVk6IFtcInllYXJcIiwgZm91ckRpZ2l0c10sXG4gICAgICBTOiBbXCJtaWxsaXNlY29uZFwiLCBcIlxcXFxkXCIsIGZ1bmN0aW9uICh2KSB7IHJldHVybiArdiAqIDEwMDsgfV0sXG4gICAgICBTUzogW1wibWlsbGlzZWNvbmRcIiwgdHdvRGlnaXRzLCBmdW5jdGlvbiAodikgeyByZXR1cm4gK3YgKiAxMDsgfV0sXG4gICAgICBTU1M6IFtcIm1pbGxpc2Vjb25kXCIsIHRocmVlRGlnaXRzXSxcbiAgICAgIGQ6IGVtcHR5RGlnaXRzLFxuICAgICAgZGQ6IGVtcHR5RGlnaXRzLFxuICAgICAgZGRkOiBlbXB0eVdvcmQsXG4gICAgICBkZGRkOiBlbXB0eVdvcmQsXG4gICAgICBNTU06IFtcIm1vbnRoXCIsIHdvcmQsIG1vbnRoVXBkYXRlKFwibW9udGhOYW1lc1Nob3J0XCIpXSxcbiAgICAgIE1NTU06IFtcIm1vbnRoXCIsIHdvcmQsIG1vbnRoVXBkYXRlKFwibW9udGhOYW1lc1wiKV0sXG4gICAgICBhOiBhbVBtLFxuICAgICAgQTogYW1QbSxcbiAgICAgIFpaOiB0aW1lem9uZU9mZnNldCxcbiAgICAgIFo6IHRpbWV6b25lT2Zmc2V0XG4gIH07XG4gIC8vIFNvbWUgY29tbW9uIGZvcm1hdCBzdHJpbmdzXG4gIHZhciBnbG9iYWxNYXNrcyA9IHtcbiAgICAgIGRlZmF1bHQ6IFwiZGRkIE1NTSBERCBZWVlZIEhIOm1tOnNzXCIsXG4gICAgICBzaG9ydERhdGU6IFwiTS9EL1lZXCIsXG4gICAgICBtZWRpdW1EYXRlOiBcIk1NTSBELCBZWVlZXCIsXG4gICAgICBsb25nRGF0ZTogXCJNTU1NIEQsIFlZWVlcIixcbiAgICAgIGZ1bGxEYXRlOiBcImRkZGQsIE1NTU0gRCwgWVlZWVwiLFxuICAgICAgaXNvRGF0ZTogXCJZWVlZLU1NLUREXCIsXG4gICAgICBpc29EYXRlVGltZTogXCJZWVlZLU1NLUREVEhIOm1tOnNzWlwiLFxuICAgICAgc2hvcnRUaW1lOiBcIkhIOm1tXCIsXG4gICAgICBtZWRpdW1UaW1lOiBcIkhIOm1tOnNzXCIsXG4gICAgICBsb25nVGltZTogXCJISDptbTpzcy5TU1NcIlxuICB9O1xuICB2YXIgc2V0R2xvYmFsRGF0ZU1hc2tzID0gZnVuY3Rpb24gKG1hc2tzKSB7IHJldHVybiBhc3NpZ24oZ2xvYmFsTWFza3MsIG1hc2tzKTsgfTtcbiAgLyoqKlxuICAgKiBGb3JtYXQgYSBkYXRlXG4gICAqIEBtZXRob2QgZm9ybWF0XG4gICAqIEBwYXJhbSB7RGF0ZXxudW1iZXJ9IGRhdGVPYmpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1hc2sgRm9ybWF0IG9mIHRoZSBkYXRlLCBpLmUuICdtbS1kZC15eScgb3IgJ3Nob3J0RGF0ZSdcbiAgICogQHJldHVybnMge3N0cmluZ30gRm9ybWF0dGVkIGRhdGUgc3RyaW5nXG4gICAqL1xuICB2YXIgZm9ybWF0ID0gZnVuY3Rpb24gKGRhdGVPYmosIG1hc2ssIGkxOG4pIHtcbiAgICAgIGlmIChtYXNrID09PSB2b2lkIDApIHsgbWFzayA9IGdsb2JhbE1hc2tzW1wiZGVmYXVsdFwiXTsgfVxuICAgICAgaWYgKGkxOG4gPT09IHZvaWQgMCkgeyBpMThuID0ge307IH1cbiAgICAgIGlmICh0eXBlb2YgZGF0ZU9iaiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIGRhdGVPYmogPSBuZXcgRGF0ZShkYXRlT2JqKTtcbiAgICAgIH1cbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0ZU9iaikgIT09IFwiW29iamVjdCBEYXRlXVwiIHx8XG4gICAgICAgICAgaXNOYU4oZGF0ZU9iai5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBEYXRlIHBhc3MgdG8gZm9ybWF0XCIpO1xuICAgICAgfVxuICAgICAgbWFzayA9IGdsb2JhbE1hc2tzW21hc2tdIHx8IG1hc2s7XG4gICAgICB2YXIgbGl0ZXJhbHMgPSBbXTtcbiAgICAgIC8vIE1ha2UgbGl0ZXJhbHMgaW5hY3RpdmUgYnkgcmVwbGFjaW5nIHRoZW0gd2l0aCBAQEBcbiAgICAgIG1hc2sgPSBtYXNrLnJlcGxhY2UobGl0ZXJhbCwgZnVuY3Rpb24gKCQwLCAkMSkge1xuICAgICAgICAgIGxpdGVyYWxzLnB1c2goJDEpO1xuICAgICAgICAgIHJldHVybiBcIkBAQFwiO1xuICAgICAgfSk7XG4gICAgICB2YXIgY29tYmluZWRJMThuU2V0dGluZ3MgPSBhc3NpZ24oYXNzaWduKHt9LCBnbG9iYWxJMThuKSwgaTE4bik7XG4gICAgICAvLyBBcHBseSBmb3JtYXR0aW5nIHJ1bGVzXG4gICAgICBtYXNrID0gbWFzay5yZXBsYWNlKHRva2VuLCBmdW5jdGlvbiAoJDApIHtcbiAgICAgICAgICByZXR1cm4gZm9ybWF0RmxhZ3NbJDBdKGRhdGVPYmosIGNvbWJpbmVkSTE4blNldHRpbmdzKTtcbiAgICAgIH0pO1xuICAgICAgLy8gSW5saW5lIGxpdGVyYWwgdmFsdWVzIGJhY2sgaW50byB0aGUgZm9ybWF0dGVkIHZhbHVlXG4gICAgICByZXR1cm4gbWFzay5yZXBsYWNlKC9AQEAvZywgZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbHMuc2hpZnQoKTsgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBQYXJzZSBhIGRhdGUgc3RyaW5nIGludG8gYSBKYXZhc2NyaXB0IERhdGUgb2JqZWN0IC9cbiAgICogQG1ldGhvZCBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0ZVN0ciBEYXRlIHN0cmluZ1xuICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IERhdGUgcGFyc2UgZm9ybWF0XG4gICAqIEBwYXJhbSB7aTE4bn0gSTE4blNldHRpbmdzT3B0aW9uYWwgRnVsbCBvciBzdWJzZXQgb2YgSTE4TiBzZXR0aW5nc1xuICAgKiBAcmV0dXJucyB7RGF0ZXxudWxsfSBSZXR1cm5zIERhdGUgb2JqZWN0LiBSZXR1cm5zIG51bGwgd2hhdCBkYXRlIHN0cmluZyBpcyBpbnZhbGlkIG9yIGRvZXNuJ3QgbWF0Y2ggZm9ybWF0XG4gICAqL1xuICBmdW5jdGlvbiBwYXJzZShkYXRlU3RyLCBmb3JtYXQsIGkxOG4pIHtcbiAgICAgIGlmIChpMThuID09PSB2b2lkIDApIHsgaTE4biA9IHt9OyB9XG4gICAgICBpZiAodHlwZW9mIGZvcm1hdCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZm9ybWF0IGluIGZlY2hhIHBhcnNlXCIpO1xuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBmb3JtYXQgaXMgYWN0dWFsbHkgYSBtYXNrXG4gICAgICBmb3JtYXQgPSBnbG9iYWxNYXNrc1tmb3JtYXRdIHx8IGZvcm1hdDtcbiAgICAgIC8vIEF2b2lkIHJlZ3VsYXIgZXhwcmVzc2lvbiBkZW5pYWwgb2Ygc2VydmljZSwgZmFpbCBlYXJseSBmb3IgcmVhbGx5IGxvbmcgc3RyaW5nc1xuICAgICAgLy8gaHR0cHM6Ly93d3cub3dhc3Aub3JnL2luZGV4LnBocC9SZWd1bGFyX2V4cHJlc3Npb25fRGVuaWFsX29mX1NlcnZpY2VfLV9SZURvU1xuICAgICAgaWYgKGRhdGVTdHIubGVuZ3RoID4gMTAwMCkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gRGVmYXVsdCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSB5ZWFyLlxuICAgICAgdmFyIHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICAgIHZhciBkYXRlSW5mbyA9IHtcbiAgICAgICAgICB5ZWFyOiB0b2RheS5nZXRGdWxsWWVhcigpLFxuICAgICAgICAgIG1vbnRoOiAwLFxuICAgICAgICAgIGRheTogMSxcbiAgICAgICAgICBob3VyOiAwLFxuICAgICAgICAgIG1pbnV0ZTogMCxcbiAgICAgICAgICBzZWNvbmQ6IDAsXG4gICAgICAgICAgbWlsbGlzZWNvbmQ6IDAsXG4gICAgICAgICAgaXNQbTogbnVsbCxcbiAgICAgICAgICB0aW1lem9uZU9mZnNldDogbnVsbFxuICAgICAgfTtcbiAgICAgIHZhciBwYXJzZUluZm8gPSBbXTtcbiAgICAgIHZhciBsaXRlcmFscyA9IFtdO1xuICAgICAgLy8gUmVwbGFjZSBhbGwgdGhlIGxpdGVyYWxzIHdpdGggQEBALiBIb3BlZnVsbHkgYSBzdHJpbmcgdGhhdCB3b24ndCBleGlzdCBpbiB0aGUgZm9ybWF0XG4gICAgICB2YXIgbmV3Rm9ybWF0ID0gZm9ybWF0LnJlcGxhY2UobGl0ZXJhbCwgZnVuY3Rpb24gKCQwLCAkMSkge1xuICAgICAgICAgIGxpdGVyYWxzLnB1c2gocmVnZXhFc2NhcGUoJDEpKTtcbiAgICAgICAgICByZXR1cm4gXCJAQEBcIjtcbiAgICAgIH0pO1xuICAgICAgdmFyIHNwZWNpZmllZEZpZWxkcyA9IHt9O1xuICAgICAgdmFyIHJlcXVpcmVkRmllbGRzID0ge307XG4gICAgICAvLyBDaGFuZ2UgZXZlcnkgdG9rZW4gdGhhdCB3ZSBmaW5kIGludG8gdGhlIGNvcnJlY3QgcmVnZXhcbiAgICAgIG5ld0Zvcm1hdCA9IHJlZ2V4RXNjYXBlKG5ld0Zvcm1hdCkucmVwbGFjZSh0b2tlbiwgZnVuY3Rpb24gKCQwKSB7XG4gICAgICAgICAgdmFyIGluZm8gPSBwYXJzZUZsYWdzWyQwXTtcbiAgICAgICAgICB2YXIgZmllbGQgPSBpbmZvWzBdLCByZWdleCA9IGluZm9bMV0sIHJlcXVpcmVkRmllbGQgPSBpbmZvWzNdO1xuICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBwZXJzb24gaGFzIHNwZWNpZmllZCB0aGUgc2FtZSBmaWVsZCB0d2ljZS4gVGhpcyB3aWxsIGxlYWQgdG8gY29uZnVzaW5nIHJlc3VsdHMuXG4gICAgICAgICAgaWYgKHNwZWNpZmllZEZpZWxkc1tmaWVsZF0pIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBmb3JtYXQuIFwiICsgZmllbGQgKyBcIiBzcGVjaWZpZWQgdHdpY2UgaW4gZm9ybWF0XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzcGVjaWZpZWRGaWVsZHNbZmllbGRdID0gdHJ1ZTtcbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBhcmUgYW55IHJlcXVpcmVkIGZpZWxkcy4gRm9yIGluc3RhbmNlLCAxMiBob3VyIHRpbWUgcmVxdWlyZXMgQU0vUE0gc3BlY2lmaWVkXG4gICAgICAgICAgaWYgKHJlcXVpcmVkRmllbGQpIHtcbiAgICAgICAgICAgICAgcmVxdWlyZWRGaWVsZHNbcmVxdWlyZWRGaWVsZF0gPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXJzZUluZm8ucHVzaChpbmZvKTtcbiAgICAgICAgICByZXR1cm4gXCIoXCIgKyByZWdleCArIFwiKVwiO1xuICAgICAgfSk7XG4gICAgICAvLyBDaGVjayBhbGwgdGhlIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudFxuICAgICAgT2JqZWN0LmtleXMocmVxdWlyZWRGaWVsZHMpLmZvckVhY2goZnVuY3Rpb24gKGZpZWxkKSB7XG4gICAgICAgICAgaWYgKCFzcGVjaWZpZWRGaWVsZHNbZmllbGRdKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZm9ybWF0LiBcIiArIGZpZWxkICsgXCIgaXMgcmVxdWlyZWQgaW4gc3BlY2lmaWVkIGZvcm1hdFwiKTtcbiAgICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIEFkZCBiYWNrIGFsbCB0aGUgbGl0ZXJhbHMgYWZ0ZXJcbiAgICAgIG5ld0Zvcm1hdCA9IG5ld0Zvcm1hdC5yZXBsYWNlKC9AQEAvZywgZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbHMuc2hpZnQoKTsgfSk7XG4gICAgICAvLyBDaGVjayBpZiB0aGUgZGF0ZSBzdHJpbmcgbWF0Y2hlcyB0aGUgZm9ybWF0LiBJZiBpdCBkb2Vzbid0IHJldHVybiBudWxsXG4gICAgICB2YXIgbWF0Y2hlcyA9IGRhdGVTdHIubWF0Y2gobmV3IFJlZ0V4cChuZXdGb3JtYXQsIFwiaVwiKSk7XG4gICAgICBpZiAoIW1hdGNoZXMpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHZhciBjb21iaW5lZEkxOG5TZXR0aW5ncyA9IGFzc2lnbihhc3NpZ24oe30sIGdsb2JhbEkxOG4pLCBpMThuKTtcbiAgICAgIC8vIEZvciBlYWNoIG1hdGNoLCBjYWxsIHRoZSBwYXJzZXIgZnVuY3Rpb24gZm9yIHRoYXQgZGF0ZSBwYXJ0XG4gICAgICBmb3IgKHZhciBpID0gMTsgaSA8IG1hdGNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgX2EgPSBwYXJzZUluZm9baSAtIDFdLCBmaWVsZCA9IF9hWzBdLCBwYXJzZXIgPSBfYVsyXTtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBwYXJzZXJcbiAgICAgICAgICAgICAgPyBwYXJzZXIobWF0Y2hlc1tpXSwgY29tYmluZWRJMThuU2V0dGluZ3MpXG4gICAgICAgICAgICAgIDogK21hdGNoZXNbaV07XG4gICAgICAgICAgLy8gSWYgdGhlIHBhcnNlciBjYW4ndCBtYWtlIHNlbnNlIG9mIHRoZSB2YWx1ZSwgcmV0dXJuIG51bGxcbiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF0ZUluZm9bZmllbGRdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoZGF0ZUluZm8uaXNQbSA9PT0gMSAmJiBkYXRlSW5mby5ob3VyICE9IG51bGwgJiYgK2RhdGVJbmZvLmhvdXIgIT09IDEyKSB7XG4gICAgICAgICAgZGF0ZUluZm8uaG91ciA9ICtkYXRlSW5mby5ob3VyICsgMTI7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChkYXRlSW5mby5pc1BtID09PSAwICYmICtkYXRlSW5mby5ob3VyID09PSAxMikge1xuICAgICAgICAgIGRhdGVJbmZvLmhvdXIgPSAwO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGVXaXRob3V0VFogPSBuZXcgRGF0ZShkYXRlSW5mby55ZWFyLCBkYXRlSW5mby5tb250aCwgZGF0ZUluZm8uZGF5LCBkYXRlSW5mby5ob3VyLCBkYXRlSW5mby5taW51dGUsIGRhdGVJbmZvLnNlY29uZCwgZGF0ZUluZm8ubWlsbGlzZWNvbmQpO1xuICAgICAgdmFyIHZhbGlkYXRlRmllbGRzID0gW1xuICAgICAgICAgIFtcIm1vbnRoXCIsIFwiZ2V0TW9udGhcIl0sXG4gICAgICAgICAgW1wiZGF5XCIsIFwiZ2V0RGF0ZVwiXSxcbiAgICAgICAgICBbXCJob3VyXCIsIFwiZ2V0SG91cnNcIl0sXG4gICAgICAgICAgW1wibWludXRlXCIsIFwiZ2V0TWludXRlc1wiXSxcbiAgICAgICAgICBbXCJzZWNvbmRcIiwgXCJnZXRTZWNvbmRzXCJdXG4gICAgICBdO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHZhbGlkYXRlRmllbGRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgLy8gQ2hlY2sgdG8gbWFrZSBzdXJlIHRoZSBkYXRlIGZpZWxkIGlzIHdpdGhpbiB0aGUgYWxsb3dlZCByYW5nZS4gSmF2YXNjcmlwdCBkYXRlcyBhbGxvd3MgdmFsdWVzXG4gICAgICAgICAgLy8gb3V0c2lkZSB0aGUgYWxsb3dlZCByYW5nZS4gSWYgdGhlIHZhbHVlcyBkb24ndCBtYXRjaCB0aGUgdmFsdWUgd2FzIGludmFsaWRcbiAgICAgICAgICBpZiAoc3BlY2lmaWVkRmllbGRzW3ZhbGlkYXRlRmllbGRzW2ldWzBdXSAmJlxuICAgICAgICAgICAgICBkYXRlSW5mb1t2YWxpZGF0ZUZpZWxkc1tpXVswXV0gIT09IGRhdGVXaXRob3V0VFpbdmFsaWRhdGVGaWVsZHNbaV1bMV1dKCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRhdGVJbmZvLnRpbWV6b25lT2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gZGF0ZVdpdGhvdXRUWjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyhkYXRlSW5mby55ZWFyLCBkYXRlSW5mby5tb250aCwgZGF0ZUluZm8uZGF5LCBkYXRlSW5mby5ob3VyLCBkYXRlSW5mby5taW51dGUgLSBkYXRlSW5mby50aW1lem9uZU9mZnNldCwgZGF0ZUluZm8uc2Vjb25kLCBkYXRlSW5mby5taWxsaXNlY29uZCkpO1xuICB9XG4gIHZhciBmZWNoYSA9IHtcbiAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgcGFyc2U6IHBhcnNlLFxuICAgICAgZGVmYXVsdEkxOG46IGRlZmF1bHRJMThuLFxuICAgICAgc2V0R2xvYmFsRGF0ZUkxOG46IHNldEdsb2JhbERhdGVJMThuLFxuICAgICAgc2V0R2xvYmFsRGF0ZU1hc2tzOiBzZXRHbG9iYWxEYXRlTWFza3NcbiAgfTtcblxuICBleHBvcnRzLmFzc2lnbiA9IGFzc2lnbjtcbiAgZXhwb3J0cy5kZWZhdWx0ID0gZmVjaGE7XG4gIGV4cG9ydHMuZm9ybWF0ID0gZm9ybWF0O1xuICBleHBvcnRzLnBhcnNlID0gcGFyc2U7XG4gIGV4cG9ydHMuZGVmYXVsdEkxOG4gPSBkZWZhdWx0STE4bjtcbiAgZXhwb3J0cy5zZXRHbG9iYWxEYXRlSTE4biA9IHNldEdsb2JhbERhdGVJMThuO1xuICBleHBvcnRzLnNldEdsb2JhbERhdGVNYXNrcyA9IHNldEdsb2JhbERhdGVNYXNrcztcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG59KSkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmVjaGEudW1kLmpzLm1hcFxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLnNldE1hdHJpeEFycmF5VHlwZSA9IHNldE1hdHJpeEFycmF5VHlwZTtcbmV4cG9ydHMudG9SYWRpYW4gPSB0b1JhZGlhbjtcbmV4cG9ydHMuZXF1YWxzID0gZXF1YWxzO1xuZXhwb3J0cy5SQU5ET00gPSBleHBvcnRzLkFSUkFZX1RZUEUgPSBleHBvcnRzLkVQU0lMT04gPSB2b2lkIDA7XG5cbi8qKlxyXG4gKiBDb21tb24gdXRpbGl0aWVzXHJcbiAqIEBtb2R1bGUgZ2xNYXRyaXhcclxuICovXG4vLyBDb25maWd1cmF0aW9uIENvbnN0YW50c1xudmFyIEVQU0lMT04gPSAwLjAwMDAwMTtcbmV4cG9ydHMuRVBTSUxPTiA9IEVQU0lMT047XG52YXIgQVJSQVlfVFlQRSA9IHR5cGVvZiBGbG9hdDMyQXJyYXkgIT09ICd1bmRlZmluZWQnID8gRmxvYXQzMkFycmF5IDogQXJyYXk7XG5leHBvcnRzLkFSUkFZX1RZUEUgPSBBUlJBWV9UWVBFO1xudmFyIFJBTkRPTSA9IE1hdGgucmFuZG9tO1xuLyoqXHJcbiAqIFNldHMgdGhlIHR5cGUgb2YgYXJyYXkgdXNlZCB3aGVuIGNyZWF0aW5nIG5ldyB2ZWN0b3JzIGFuZCBtYXRyaWNlc1xyXG4gKlxyXG4gKiBAcGFyYW0ge0Zsb2F0MzJBcnJheUNvbnN0cnVjdG9yIHwgQXJyYXlDb25zdHJ1Y3Rvcn0gdHlwZSBBcnJheSB0eXBlLCBzdWNoIGFzIEZsb2F0MzJBcnJheSBvciBBcnJheVxyXG4gKi9cblxuZXhwb3J0cy5SQU5ET00gPSBSQU5ET007XG5cbmZ1bmN0aW9uIHNldE1hdHJpeEFycmF5VHlwZSh0eXBlKSB7XG4gIGV4cG9ydHMuQVJSQVlfVFlQRSA9IEFSUkFZX1RZUEUgPSB0eXBlO1xufVxuXG52YXIgZGVncmVlID0gTWF0aC5QSSAvIDE4MDtcbi8qKlxyXG4gKiBDb252ZXJ0IERlZ3JlZSBUbyBSYWRpYW5cclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IGEgQW5nbGUgaW4gRGVncmVlc1xyXG4gKi9cblxuZnVuY3Rpb24gdG9SYWRpYW4oYSkge1xuICByZXR1cm4gYSAqIGRlZ3JlZTtcbn1cbi8qKlxyXG4gKiBUZXN0cyB3aGV0aGVyIG9yIG5vdCB0aGUgYXJndW1lbnRzIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSB2YWx1ZSwgd2l0aGluIGFuIGFic29sdXRlXHJcbiAqIG9yIHJlbGF0aXZlIHRvbGVyYW5jZSBvZiBnbE1hdHJpeC5FUFNJTE9OIChhbiBhYnNvbHV0ZSB0b2xlcmFuY2UgaXMgdXNlZCBmb3IgdmFsdWVzIGxlc3NcclxuICogdGhhbiBvciBlcXVhbCB0byAxLjAsIGFuZCBhIHJlbGF0aXZlIHRvbGVyYW5jZSBpcyB1c2VkIGZvciBsYXJnZXIgdmFsdWVzKVxyXG4gKlxyXG4gKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgbnVtYmVyIHRvIHRlc3QuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgbnVtYmVyIHRvIHRlc3QuXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBudW1iZXJzIGFyZSBhcHByb3hpbWF0ZWx5IGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBNYXRoLmFicyhhIC0gYikgPD0gRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYSksIE1hdGguYWJzKGIpKTtcbn1cblxuaWYgKCFNYXRoLmh5cG90KSBNYXRoLmh5cG90ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgeSA9IDAsXG4gICAgICBpID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICB3aGlsZSAoaS0tKSB7XG4gICAgeSArPSBhcmd1bWVudHNbaV0gKiBhcmd1bWVudHNbaV07XG4gIH1cblxuICByZXR1cm4gTWF0aC5zcXJ0KHkpO1xufTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiOyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2Yob2JqKTsgfVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy52ZWM0ID0gZXhwb3J0cy52ZWMzID0gZXhwb3J0cy52ZWMyID0gZXhwb3J0cy5xdWF0MiA9IGV4cG9ydHMucXVhdCA9IGV4cG9ydHMubWF0NCA9IGV4cG9ydHMubWF0MyA9IGV4cG9ydHMubWF0MmQgPSBleHBvcnRzLm1hdDIgPSBleHBvcnRzLmdsTWF0cml4ID0gdm9pZCAwO1xuXG52YXIgZ2xNYXRyaXggPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9jb21tb24uanNcIikpO1xuXG5leHBvcnRzLmdsTWF0cml4ID0gZ2xNYXRyaXg7XG5cbnZhciBtYXQyID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vbWF0Mi5qc1wiKSk7XG5cbmV4cG9ydHMubWF0MiA9IG1hdDI7XG5cbnZhciBtYXQyZCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL21hdDJkLmpzXCIpKTtcblxuZXhwb3J0cy5tYXQyZCA9IG1hdDJkO1xuXG52YXIgbWF0MyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL21hdDMuanNcIikpO1xuXG5leHBvcnRzLm1hdDMgPSBtYXQzO1xuXG52YXIgbWF0NCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL21hdDQuanNcIikpO1xuXG5leHBvcnRzLm1hdDQgPSBtYXQ0O1xuXG52YXIgcXVhdCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL3F1YXQuanNcIikpO1xuXG5leHBvcnRzLnF1YXQgPSBxdWF0O1xuXG52YXIgcXVhdDIgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9xdWF0Mi5qc1wiKSk7XG5cbmV4cG9ydHMucXVhdDIgPSBxdWF0MjtcblxudmFyIHZlYzIgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi92ZWMyLmpzXCIpKTtcblxuZXhwb3J0cy52ZWMyID0gdmVjMjtcblxudmFyIHZlYzMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi92ZWMzLmpzXCIpKTtcblxuZXhwb3J0cy52ZWMzID0gdmVjMztcblxudmFyIHZlYzQgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi92ZWM0LmpzXCIpKTtcblxuZXhwb3J0cy52ZWM0ID0gdmVjNDtcblxuZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCkgeyBpZiAodHlwZW9mIFdlYWtNYXAgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG51bGw7IHZhciBjYWNoZSA9IG5ldyBXZWFrTWFwKCk7IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSA9IGZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgcmV0dXJuIGNhY2hlOyB9OyByZXR1cm4gY2FjaGU7IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBpZiAob2JqID09PSBudWxsIHx8IF90eXBlb2Yob2JqKSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHsgcmV0dXJuIHsgXCJkZWZhdWx0XCI6IG9iaiB9OyB9IHZhciBjYWNoZSA9IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpOyBpZiAoY2FjaGUgJiYgY2FjaGUuaGFzKG9iaikpIHsgcmV0dXJuIGNhY2hlLmdldChvYmopOyB9IHZhciBuZXdPYmogPSB7fTsgdmFyIGhhc1Byb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7IHZhciBkZXNjID0gaGFzUHJvcGVydHlEZXNjcmlwdG9yID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSkgOiBudWxsOyBpZiAoZGVzYyAmJiAoZGVzYy5nZXQgfHwgZGVzYy5zZXQpKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdPYmosIGtleSwgZGVzYyk7IH0gZWxzZSB7IG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSB9IG5ld09ialtcImRlZmF1bHRcIl0gPSBvYmo7IGlmIChjYWNoZSkgeyBjYWNoZS5zZXQob2JqLCBuZXdPYmopOyB9IHJldHVybiBuZXdPYmo7IH0iLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiOyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2Yob2JqKTsgfVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5jcmVhdGUgPSBjcmVhdGU7XG5leHBvcnRzLmNsb25lID0gY2xvbmU7XG5leHBvcnRzLmNvcHkgPSBjb3B5O1xuZXhwb3J0cy5pZGVudGl0eSA9IGlkZW50aXR5O1xuZXhwb3J0cy5mcm9tVmFsdWVzID0gZnJvbVZhbHVlcztcbmV4cG9ydHMuc2V0ID0gc2V0O1xuZXhwb3J0cy50cmFuc3Bvc2UgPSB0cmFuc3Bvc2U7XG5leHBvcnRzLmludmVydCA9IGludmVydDtcbmV4cG9ydHMuYWRqb2ludCA9IGFkam9pbnQ7XG5leHBvcnRzLmRldGVybWluYW50ID0gZGV0ZXJtaW5hbnQ7XG5leHBvcnRzLm11bHRpcGx5ID0gbXVsdGlwbHk7XG5leHBvcnRzLnJvdGF0ZSA9IHJvdGF0ZTtcbmV4cG9ydHMuc2NhbGUgPSBzY2FsZTtcbmV4cG9ydHMuZnJvbVJvdGF0aW9uID0gZnJvbVJvdGF0aW9uO1xuZXhwb3J0cy5mcm9tU2NhbGluZyA9IGZyb21TY2FsaW5nO1xuZXhwb3J0cy5zdHIgPSBzdHI7XG5leHBvcnRzLmZyb2IgPSBmcm9iO1xuZXhwb3J0cy5MRFUgPSBMRFU7XG5leHBvcnRzLmFkZCA9IGFkZDtcbmV4cG9ydHMuc3VidHJhY3QgPSBzdWJ0cmFjdDtcbmV4cG9ydHMuZXhhY3RFcXVhbHMgPSBleGFjdEVxdWFscztcbmV4cG9ydHMuZXF1YWxzID0gZXF1YWxzO1xuZXhwb3J0cy5tdWx0aXBseVNjYWxhciA9IG11bHRpcGx5U2NhbGFyO1xuZXhwb3J0cy5tdWx0aXBseVNjYWxhckFuZEFkZCA9IG11bHRpcGx5U2NhbGFyQW5kQWRkO1xuZXhwb3J0cy5zdWIgPSBleHBvcnRzLm11bCA9IHZvaWQgMDtcblxudmFyIGdsTWF0cml4ID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vY29tbW9uLmpzXCIpKTtcblxuZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCkgeyBpZiAodHlwZW9mIFdlYWtNYXAgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG51bGw7IHZhciBjYWNoZSA9IG5ldyBXZWFrTWFwKCk7IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSA9IGZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgcmV0dXJuIGNhY2hlOyB9OyByZXR1cm4gY2FjaGU7IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBpZiAob2JqID09PSBudWxsIHx8IF90eXBlb2Yob2JqKSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHsgcmV0dXJuIHsgXCJkZWZhdWx0XCI6IG9iaiB9OyB9IHZhciBjYWNoZSA9IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpOyBpZiAoY2FjaGUgJiYgY2FjaGUuaGFzKG9iaikpIHsgcmV0dXJuIGNhY2hlLmdldChvYmopOyB9IHZhciBuZXdPYmogPSB7fTsgdmFyIGhhc1Byb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7IHZhciBkZXNjID0gaGFzUHJvcGVydHlEZXNjcmlwdG9yID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSkgOiBudWxsOyBpZiAoZGVzYyAmJiAoZGVzYy5nZXQgfHwgZGVzYy5zZXQpKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdPYmosIGtleSwgZGVzYyk7IH0gZWxzZSB7IG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSB9IG5ld09ialtcImRlZmF1bHRcIl0gPSBvYmo7IGlmIChjYWNoZSkgeyBjYWNoZS5zZXQob2JqLCBuZXdPYmopOyB9IHJldHVybiBuZXdPYmo7IH1cblxuLyoqXHJcbiAqIDJ4MiBNYXRyaXhcclxuICogQG1vZHVsZSBtYXQyXHJcbiAqL1xuXG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyBpZGVudGl0eSBtYXQyXHJcbiAqXHJcbiAqIEByZXR1cm5zIHttYXQyfSBhIG5ldyAyeDIgbWF0cml4XHJcbiAqL1xuZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICB9XG5cbiAgb3V0WzBdID0gMTtcbiAgb3V0WzNdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDIgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgbWF0cml4IHRvIGNsb25lXHJcbiAqIEByZXR1cm5zIHttYXQyfSBhIG5ldyAyeDIgbWF0cml4XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBtYXQyIHRvIGFub3RoZXJcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge21hdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNldCBhIG1hdDIgdG8gdGhlIGlkZW50aXR5IG1hdHJpeFxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZSBhIG5ldyBtYXQyIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xyXG4gKlxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDEgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMSlcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMCBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAyKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDMpXHJcbiAqIEByZXR1cm5zIHttYXQyfSBvdXQgQSBuZXcgMngyIG1hdHJpeFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tVmFsdWVzKG0wMCwgbTAxLCBtMTAsIG0xMSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG4gIG91dFswXSA9IG0wMDtcbiAgb3V0WzFdID0gbTAxO1xuICBvdXRbMl0gPSBtMTA7XG4gIG91dFszXSA9IG0xMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBtYXQyIHRvIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMCBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAwKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTAgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMilcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMSBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAxIHBvc2l0aW9uIChpbmRleCAzKVxyXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNldChvdXQsIG0wMCwgbTAxLCBtMTAsIG0xMSkge1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTEwO1xuICBvdXRbM10gPSBtMTE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNwb3NlIHRoZSB2YWx1ZXMgb2YgYSBtYXQyXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNwb3NlKG91dCwgYSkge1xuICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlXG4gIC8vIHNvbWUgdmFsdWVzXG4gIGlmIChvdXQgPT09IGEpIHtcbiAgICB2YXIgYTEgPSBhWzFdO1xuICAgIG91dFsxXSA9IGFbMl07XG4gICAgb3V0WzJdID0gYTE7XG4gIH0gZWxzZSB7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzJdO1xuICAgIG91dFsyXSA9IGFbMV07XG4gICAgb3V0WzNdID0gYVszXTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogSW52ZXJ0cyBhIG1hdDJcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge21hdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBpbnZlcnQob3V0LCBhKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM107IC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcblxuICB2YXIgZGV0ID0gYTAgKiBhMyAtIGEyICogYTE7XG5cbiAgaWYgKCFkZXQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGRldCA9IDEuMCAvIGRldDtcbiAgb3V0WzBdID0gYTMgKiBkZXQ7XG4gIG91dFsxXSA9IC1hMSAqIGRldDtcbiAgb3V0WzJdID0gLWEyICogZGV0O1xuICBvdXRbM10gPSBhMCAqIGRldDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBhZGp1Z2F0ZSBvZiBhIG1hdDJcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge21hdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBhZGpvaW50KG91dCwgYSkge1xuICAvLyBDYWNoaW5nIHRoaXMgdmFsdWUgaXMgbmVzc2VjYXJ5IGlmIG91dCA9PSBhXG4gIHZhciBhMCA9IGFbMF07XG4gIG91dFswXSA9IGFbM107XG4gIG91dFsxXSA9IC1hWzFdO1xuICBvdXRbMl0gPSAtYVsyXTtcbiAgb3V0WzNdID0gYTA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgZGV0ZXJtaW5hbnQgb2YgYSBtYXQyXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRldGVybWluYW50IG9mIGFcclxuICovXG5cblxuZnVuY3Rpb24gZGV0ZXJtaW5hbnQoYSkge1xuICByZXR1cm4gYVswXSAqIGFbM10gLSBhWzJdICogYVsxXTtcbn1cbi8qKlxyXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQyJ3NcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM107XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl0sXG4gICAgICBiMyA9IGJbM107XG4gIG91dFswXSA9IGEwICogYjAgKyBhMiAqIGIxO1xuICBvdXRbMV0gPSBhMSAqIGIwICsgYTMgKiBiMTtcbiAgb3V0WzJdID0gYTAgKiBiMiArIGEyICogYjM7XG4gIG91dFszXSA9IGExICogYjIgKyBhMyAqIGIzO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBtYXQyIGJ5IHRoZSBnaXZlbiBhbmdsZVxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZShvdXQsIGEsIHJhZCkge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdO1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYTAgKiBjICsgYTIgKiBzO1xuICBvdXRbMV0gPSBhMSAqIGMgKyBhMyAqIHM7XG4gIG91dFsyXSA9IGEwICogLXMgKyBhMiAqIGM7XG4gIG91dFszXSA9IGExICogLXMgKyBhMyAqIGM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2NhbGVzIHRoZSBtYXQyIGJ5IHRoZSBkaW1lbnNpb25zIGluIHRoZSBnaXZlbiB2ZWMyXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IHRoZSB2ZWMyIHRvIHNjYWxlIHRoZSBtYXRyaXggYnlcclxuICogQHJldHVybnMge21hdDJ9IG91dFxyXG4gKiovXG5cblxuZnVuY3Rpb24gc2NhbGUob3V0LCBhLCB2KSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM107XG4gIHZhciB2MCA9IHZbMF0sXG4gICAgICB2MSA9IHZbMV07XG4gIG91dFswXSA9IGEwICogdjA7XG4gIG91dFsxXSA9IGExICogdjA7XG4gIG91dFsyXSA9IGEyICogdjE7XG4gIG91dFszXSA9IGEzICogdjE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgZ2l2ZW4gYW5nbGVcclxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XHJcbiAqXHJcbiAqICAgICBtYXQyLmlkZW50aXR5KGRlc3QpO1xyXG4gKiAgICAgbWF0Mi5yb3RhdGUoZGVzdCwgZGVzdCwgcmFkKTtcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgbWF0MiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21Sb3RhdGlvbihvdXQsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYztcbiAgb3V0WzFdID0gcztcbiAgb3V0WzJdID0gLXM7XG4gIG91dFszXSA9IGM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHNjYWxpbmdcclxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XHJcbiAqXHJcbiAqICAgICBtYXQyLmlkZW50aXR5KGRlc3QpO1xyXG4gKiAgICAgbWF0Mi5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJ9IG91dCBtYXQyIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IFNjYWxpbmcgdmVjdG9yXHJcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVNjYWxpbmcob3V0LCB2KSB7XG4gIG91dFswXSA9IHZbMF07XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IHZbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG1hdDJcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgbWF0cml4IHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1hdHJpeFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJtYXQyKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIsIFwiICsgYVszXSArIFwiKVwiO1xufVxuLyoqXHJcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQyXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBhIHRoZSBtYXRyaXggdG8gY2FsY3VsYXRlIEZyb2Jlbml1cyBub3JtIG9mXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IEZyb2Jlbml1cyBub3JtXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb2IoYSkge1xuICByZXR1cm4gTWF0aC5oeXBvdChhWzBdLCBhWzFdLCBhWzJdLCBhWzNdKTtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIEwsIEQgYW5kIFUgbWF0cmljZXMgKExvd2VyIHRyaWFuZ3VsYXIsIERpYWdvbmFsIGFuZCBVcHBlciB0cmlhbmd1bGFyKSBieSBmYWN0b3JpemluZyB0aGUgaW5wdXQgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBMIHRoZSBsb3dlciB0cmlhbmd1bGFyIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gRCB0aGUgZGlhZ29uYWwgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyfSBVIHRoZSB1cHBlciB0cmlhbmd1bGFyIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgaW5wdXQgbWF0cml4IHRvIGZhY3Rvcml6ZVxyXG4gKi9cblxuXG5mdW5jdGlvbiBMRFUoTCwgRCwgVSwgYSkge1xuICBMWzJdID0gYVsyXSAvIGFbMF07XG4gIFVbMF0gPSBhWzBdO1xuICBVWzFdID0gYVsxXTtcbiAgVVszXSA9IGFbM10gLSBMWzJdICogVVsxXTtcbiAgcmV0dXJuIFtMLCBELCBVXTtcbn1cbi8qKlxyXG4gKiBBZGRzIHR3byBtYXQyJ3NcclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTdWJ0cmFjdHMgbWF0cml4IGIgZnJvbSBtYXRyaXggYVxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge21hdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSBUaGUgZmlyc3QgbWF0cml4LlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdO1xufVxuLyoqXHJcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIG1hdHJpY2VzIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgVGhlIGZpcnN0IG1hdHJpeC5cclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGIgVGhlIHNlY29uZCBtYXRyaXguXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpICYmIE1hdGguYWJzKGEzIC0gYjMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEzKSwgTWF0aC5hYnMoYjMpKTtcbn1cbi8qKlxyXG4gKiBNdWx0aXBseSBlYWNoIGVsZW1lbnQgb2YgdGhlIG1hdHJpeCBieSBhIHNjYWxhci5cclxuICpcclxuICogQHBhcmFtIHttYXQyfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJ9IGEgdGhlIG1hdHJpeCB0byBzY2FsZVxyXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIG1hdHJpeCdzIGVsZW1lbnRzIGJ5XHJcbiAqIEByZXR1cm5zIHttYXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXIob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEFkZHMgdHdvIG1hdDIncyBhZnRlciBtdWx0aXBseWluZyBlYWNoIGVsZW1lbnQgb2YgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYidzIGVsZW1lbnRzIGJ5IGJlZm9yZSBhZGRpbmdcclxuICogQHJldHVybnMge21hdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtdWx0aXBseVNjYWxhckFuZEFkZChvdXQsIGEsIGIsIHNjYWxlKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdICogc2NhbGU7XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdICogc2NhbGU7XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdICogc2NhbGU7XG4gIG91dFszXSA9IGFbM10gKyBiWzNdICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayBtYXQyLm11bHRpcGx5fVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxudmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0Mi5zdWJ0cmFjdH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLm11bCA9IG11bDtcbnZhciBzdWIgPSBzdWJ0cmFjdDtcbmV4cG9ydHMuc3ViID0gc3ViOyIsIlwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBfdHlwZW9mKG9iaikgeyBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZihvYmopOyB9XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNyZWF0ZSA9IGNyZWF0ZTtcbmV4cG9ydHMuY2xvbmUgPSBjbG9uZTtcbmV4cG9ydHMuY29weSA9IGNvcHk7XG5leHBvcnRzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5leHBvcnRzLmZyb21WYWx1ZXMgPSBmcm9tVmFsdWVzO1xuZXhwb3J0cy5zZXQgPSBzZXQ7XG5leHBvcnRzLmludmVydCA9IGludmVydDtcbmV4cG9ydHMuZGV0ZXJtaW5hbnQgPSBkZXRlcm1pbmFudDtcbmV4cG9ydHMubXVsdGlwbHkgPSBtdWx0aXBseTtcbmV4cG9ydHMucm90YXRlID0gcm90YXRlO1xuZXhwb3J0cy5zY2FsZSA9IHNjYWxlO1xuZXhwb3J0cy50cmFuc2xhdGUgPSB0cmFuc2xhdGU7XG5leHBvcnRzLmZyb21Sb3RhdGlvbiA9IGZyb21Sb3RhdGlvbjtcbmV4cG9ydHMuZnJvbVNjYWxpbmcgPSBmcm9tU2NhbGluZztcbmV4cG9ydHMuZnJvbVRyYW5zbGF0aW9uID0gZnJvbVRyYW5zbGF0aW9uO1xuZXhwb3J0cy5zdHIgPSBzdHI7XG5leHBvcnRzLmZyb2IgPSBmcm9iO1xuZXhwb3J0cy5hZGQgPSBhZGQ7XG5leHBvcnRzLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG5leHBvcnRzLm11bHRpcGx5U2NhbGFyID0gbXVsdGlwbHlTY2FsYXI7XG5leHBvcnRzLm11bHRpcGx5U2NhbGFyQW5kQWRkID0gbXVsdGlwbHlTY2FsYXJBbmRBZGQ7XG5leHBvcnRzLmV4YWN0RXF1YWxzID0gZXhhY3RFcXVhbHM7XG5leHBvcnRzLmVxdWFscyA9IGVxdWFscztcbmV4cG9ydHMuc3ViID0gZXhwb3J0cy5tdWwgPSB2b2lkIDA7XG5cbnZhciBnbE1hdHJpeCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsOyB2YXIgY2FjaGUgPSBuZXcgV2Vha01hcCgpOyBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUgPSBmdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IHJldHVybiBjYWNoZTsgfTsgcmV0dXJuIGNhY2hlOyB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gaWYgKG9iaiA9PT0gbnVsbCB8fCBfdHlwZW9mKG9iaikgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSB7IHJldHVybiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfSB2YXIgY2FjaGUgPSBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKTsgaWYgKGNhY2hlICYmIGNhY2hlLmhhcyhvYmopKSB7IHJldHVybiBjYWNoZS5nZXQob2JqKTsgfSB2YXIgbmV3T2JqID0ge307IHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgeyB2YXIgZGVzYyA9IGhhc1Byb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDogbnVsbDsgaWYgKGRlc2MgJiYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpOyB9IGVsc2UgeyBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gfSBuZXdPYmpbXCJkZWZhdWx0XCJdID0gb2JqOyBpZiAoY2FjaGUpIHsgY2FjaGUuc2V0KG9iaiwgbmV3T2JqKTsgfSByZXR1cm4gbmV3T2JqOyB9XG5cbi8qKlxyXG4gKiAyeDMgTWF0cml4XHJcbiAqIEBtb2R1bGUgbWF0MmRcclxuICogQGRlc2NyaXB0aW9uXHJcbiAqIEEgbWF0MmQgY29udGFpbnMgc2l4IGVsZW1lbnRzIGRlZmluZWQgYXM6XHJcbiAqIDxwcmU+XHJcbiAqIFthLCBiLFxyXG4gKiAgYywgZCxcclxuICogIHR4LCB0eV1cclxuICogPC9wcmU+XHJcbiAqIFRoaXMgaXMgYSBzaG9ydCBmb3JtIGZvciB0aGUgM3gzIG1hdHJpeDpcclxuICogPHByZT5cclxuICogW2EsIGIsIDAsXHJcbiAqICBjLCBkLCAwLFxyXG4gKiAgdHgsIHR5LCAxXVxyXG4gKiA8L3ByZT5cclxuICogVGhlIGxhc3QgY29sdW1uIGlzIGlnbm9yZWQgc28gdGhlIGFycmF5IGlzIHNob3J0ZXIgYW5kIG9wZXJhdGlvbnMgYXJlIGZhc3Rlci5cclxuICovXG5cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDJkXHJcbiAqXHJcbiAqIEByZXR1cm5zIHttYXQyZH0gYSBuZXcgMngzIG1hdHJpeFxyXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDYpO1xuXG4gIGlmIChnbE1hdHJpeC5BUlJBWV9UWVBFICE9IEZsb2F0MzJBcnJheSkge1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbNF0gPSAwO1xuICAgIG91dFs1XSA9IDA7XG4gIH1cblxuICBvdXRbMF0gPSAxO1xuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgbWF0MmQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBtYXRyaXhcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIG1hdHJpeCB0byBjbG9uZVxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IGEgbmV3IDJ4MyBtYXRyaXhcclxuICovXG5cblxuZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNik7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIG91dFs0XSA9IGFbNF07XG4gIG91dFs1XSA9IGFbNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIG1hdDJkIHRvIGFub3RoZXJcclxuICpcclxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgc291cmNlIG1hdHJpeFxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNldCBhIG1hdDJkIHRvIHRoZSBpZGVudGl0eSBtYXRyaXhcclxuICpcclxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZSBhIG5ldyBtYXQyZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IGEgQ29tcG9uZW50IEEgKGluZGV4IDApXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIENvbXBvbmVudCBCIChpbmRleCAxKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gYyBDb21wb25lbnQgQyAoaW5kZXggMilcclxuICogQHBhcmFtIHtOdW1iZXJ9IGQgQ29tcG9uZW50IEQgKGluZGV4IDMpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eCBDb21wb25lbnQgVFggKGluZGV4IDQpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eSBDb21wb25lbnQgVFkgKGluZGV4IDUpXHJcbiAqIEByZXR1cm5zIHttYXQyZH0gQSBuZXcgbWF0MmRcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVZhbHVlcyhhLCBiLCBjLCBkLCB0eCwgdHkpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDYpO1xuICBvdXRbMF0gPSBhO1xuICBvdXRbMV0gPSBiO1xuICBvdXRbMl0gPSBjO1xuICBvdXRbM10gPSBkO1xuICBvdXRbNF0gPSB0eDtcbiAgb3V0WzVdID0gdHk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgbWF0MmQgdG8gdGhlIGdpdmVuIHZhbHVlc1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtOdW1iZXJ9IGEgQ29tcG9uZW50IEEgKGluZGV4IDApXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIENvbXBvbmVudCBCIChpbmRleCAxKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gYyBDb21wb25lbnQgQyAoaW5kZXggMilcclxuICogQHBhcmFtIHtOdW1iZXJ9IGQgQ29tcG9uZW50IEQgKGluZGV4IDMpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eCBDb21wb25lbnQgVFggKGluZGV4IDQpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eSBDb21wb25lbnQgVFkgKGluZGV4IDUpXHJcbiAqIEByZXR1cm5zIHttYXQyZH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNldChvdXQsIGEsIGIsIGMsIGQsIHR4LCB0eSkge1xuICBvdXRbMF0gPSBhO1xuICBvdXRbMV0gPSBiO1xuICBvdXRbMl0gPSBjO1xuICBvdXRbM10gPSBkO1xuICBvdXRbNF0gPSB0eDtcbiAgb3V0WzVdID0gdHk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogSW52ZXJ0cyBhIG1hdDJkXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaW52ZXJ0KG91dCwgYSkge1xuICB2YXIgYWEgPSBhWzBdLFxuICAgICAgYWIgPSBhWzFdLFxuICAgICAgYWMgPSBhWzJdLFxuICAgICAgYWQgPSBhWzNdO1xuICB2YXIgYXR4ID0gYVs0XSxcbiAgICAgIGF0eSA9IGFbNV07XG4gIHZhciBkZXQgPSBhYSAqIGFkIC0gYWIgKiBhYztcblxuICBpZiAoIWRldCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGV0ID0gMS4wIC8gZGV0O1xuICBvdXRbMF0gPSBhZCAqIGRldDtcbiAgb3V0WzFdID0gLWFiICogZGV0O1xuICBvdXRbMl0gPSAtYWMgKiBkZXQ7XG4gIG91dFszXSA9IGFhICogZGV0O1xuICBvdXRbNF0gPSAoYWMgKiBhdHkgLSBhZCAqIGF0eCkgKiBkZXQ7XG4gIG91dFs1XSA9IChhYiAqIGF0eCAtIGFhICogYXR5KSAqIGRldDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBkZXRlcm1pbmFudCBvZiBhIG1hdDJkXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgc291cmNlIG1hdHJpeFxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkZXRlcm1pbmFudCBvZiBhXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGRldGVybWluYW50KGEpIHtcbiAgcmV0dXJuIGFbMF0gKiBhWzNdIC0gYVsxXSAqIGFbMl07XG59XG4vKipcclxuICogTXVsdGlwbGllcyB0d28gbWF0MmQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM10sXG4gICAgICBhNCA9IGFbNF0sXG4gICAgICBhNSA9IGFbNV07XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl0sXG4gICAgICBiMyA9IGJbM10sXG4gICAgICBiNCA9IGJbNF0sXG4gICAgICBiNSA9IGJbNV07XG4gIG91dFswXSA9IGEwICogYjAgKyBhMiAqIGIxO1xuICBvdXRbMV0gPSBhMSAqIGIwICsgYTMgKiBiMTtcbiAgb3V0WzJdID0gYTAgKiBiMiArIGEyICogYjM7XG4gIG91dFszXSA9IGExICogYjIgKyBhMyAqIGIzO1xuICBvdXRbNF0gPSBhMCAqIGI0ICsgYTIgKiBiNSArIGE0O1xuICBvdXRbNV0gPSBhMSAqIGI0ICsgYTMgKiBiNSArIGE1O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBtYXQyZCBieSB0aGUgZ2l2ZW4gYW5nbGVcclxuICpcclxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGUob3V0LCBhLCByYWQpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXSxcbiAgICAgIGE0ID0gYVs0XSxcbiAgICAgIGE1ID0gYVs1XTtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGEwICogYyArIGEyICogcztcbiAgb3V0WzFdID0gYTEgKiBjICsgYTMgKiBzO1xuICBvdXRbMl0gPSBhMCAqIC1zICsgYTIgKiBjO1xuICBvdXRbM10gPSBhMSAqIC1zICsgYTMgKiBjO1xuICBvdXRbNF0gPSBhNDtcbiAgb3V0WzVdID0gYTU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2NhbGVzIHRoZSBtYXQyZCBieSB0aGUgZGltZW5zaW9ucyBpbiB0aGUgZ2l2ZW4gdmVjMlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBtYXRyaXggdG8gdHJhbnNsYXRlXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IHRoZSB2ZWMyIHRvIHNjYWxlIHRoZSBtYXRyaXggYnlcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICoqL1xuXG5cbmZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgdikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdO1xuICB2YXIgdjAgPSB2WzBdLFxuICAgICAgdjEgPSB2WzFdO1xuICBvdXRbMF0gPSBhMCAqIHYwO1xuICBvdXRbMV0gPSBhMSAqIHYwO1xuICBvdXRbMl0gPSBhMiAqIHYxO1xuICBvdXRbM10gPSBhMyAqIHYxO1xuICBvdXRbNF0gPSBhNDtcbiAgb3V0WzVdID0gYTU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNsYXRlcyB0aGUgbWF0MmQgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcclxuICpcclxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgbWF0cml4IHRvIHRyYW5zbGF0ZVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gdiB0aGUgdmVjMiB0byB0cmFuc2xhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxyXG4gKiovXG5cblxuZnVuY3Rpb24gdHJhbnNsYXRlKG91dCwgYSwgdikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdO1xuICB2YXIgdjAgPSB2WzBdLFxuICAgICAgdjEgPSB2WzFdO1xuICBvdXRbMF0gPSBhMDtcbiAgb3V0WzFdID0gYTE7XG4gIG91dFsyXSA9IGEyO1xuICBvdXRbM10gPSBhMztcbiAgb3V0WzRdID0gYTAgKiB2MCArIGEyICogdjEgKyBhNDtcbiAgb3V0WzVdID0gYTEgKiB2MCArIGEzICogdjEgKyBhNTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZVxyXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcclxuICpcclxuICogICAgIG1hdDJkLmlkZW50aXR5KGRlc3QpO1xyXG4gKiAgICAgbWF0MmQucm90YXRlKGRlc3QsIGRlc3QsIHJhZCk7XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCBtYXQyZCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgYyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IHM7XG4gIG91dFsyXSA9IC1zO1xuICBvdXRbM10gPSBjO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciBzY2FsaW5nXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0MmQuaWRlbnRpdHkoZGVzdCk7XHJcbiAqICAgICBtYXQyZC5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgbWF0MmQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IHYgU2NhbGluZyB2ZWN0b3JcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVNjYWxpbmcob3V0LCB2KSB7XG4gIG91dFswXSA9IHZbMF07XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IHZbMV07XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IDA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHRyYW5zbGF0aW9uXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0MmQuaWRlbnRpdHkoZGVzdCk7XHJcbiAqICAgICBtYXQyZC50cmFuc2xhdGUoZGVzdCwgZGVzdCwgdmVjKTtcclxuICpcclxuICogQHBhcmFtIHttYXQyZH0gb3V0IG1hdDJkIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tVHJhbnNsYXRpb24ob3V0LCB2KSB7XG4gIG91dFswXSA9IDE7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDE7XG4gIG91dFs0XSA9IHZbMF07XG4gIG91dFs1XSA9IHZbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG1hdDJkXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSBtYXRyaXggdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXHJcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWF0cml4XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHN0cihhKSB7XG4gIHJldHVybiBcIm1hdDJkKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIsIFwiICsgYVszXSArIFwiLCBcIiArIGFbNF0gKyBcIiwgXCIgKyBhWzVdICsgXCIpXCI7XG59XG4vKipcclxuICogUmV0dXJucyBGcm9iZW5pdXMgbm9ybSBvZiBhIG1hdDJkXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgbWF0cml4IHRvIGNhbGN1bGF0ZSBGcm9iZW5pdXMgbm9ybSBvZlxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBGcm9iZW5pdXMgbm9ybVxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9iKGEpIHtcbiAgcmV0dXJuIE1hdGguaHlwb3QoYVswXSwgYVsxXSwgYVsyXSwgYVszXSwgYVs0XSwgYVs1XSwgMSk7XG59XG4vKipcclxuICogQWRkcyB0d28gbWF0MmQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFN1YnRyYWN0cyBtYXRyaXggYiBmcm9tIG1hdHJpeCBhXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0MmR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7bWF0MmR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIG91dFs0XSA9IGFbNF0gLSBiWzRdO1xuICBvdXRbNV0gPSBhWzVdIC0gYls1XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBNdWx0aXBseSBlYWNoIGVsZW1lbnQgb2YgdGhlIG1hdHJpeCBieSBhIHNjYWxhci5cclxuICpcclxuICogQHBhcmFtIHttYXQyZH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSB0aGUgbWF0cml4IHRvIHNjYWxlXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgbWF0cml4J3MgZWxlbWVudHMgYnlcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXIob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICBvdXRbNF0gPSBhWzRdICogYjtcbiAgb3V0WzVdID0gYVs1XSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQWRkcyB0d28gbWF0MmQncyBhZnRlciBtdWx0aXBseWluZyBlYWNoIGVsZW1lbnQgb2YgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDJkfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYidzIGVsZW1lbnRzIGJ5IGJlZm9yZSBhZGRpbmdcclxuICogQHJldHVybnMge21hdDJkfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXJBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXSAqIHNjYWxlO1xuICBvdXRbM10gPSBhWzNdICsgYlszXSAqIHNjYWxlO1xuICBvdXRbNF0gPSBhWzRdICsgYls0XSAqIHNjYWxlO1xuICBvdXRbNV0gPSBhWzVdICsgYls1XSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIG1hdHJpY2VzIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDJkfSBhIFRoZSBmaXJzdCBtYXRyaXguXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdICYmIGFbNF0gPT09IGJbNF0gJiYgYVs1XSA9PT0gYls1XTtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBtYXRyaWNlcyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQyZH0gYSBUaGUgZmlyc3QgbWF0cml4LlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGIgVGhlIHNlY29uZCBtYXRyaXguXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXSxcbiAgICAgIGE0ID0gYVs0XSxcbiAgICAgIGE1ID0gYVs1XTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXSxcbiAgICAgIGI0ID0gYls0XSxcbiAgICAgIGI1ID0gYls1XTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpICYmIE1hdGguYWJzKGEzIC0gYjMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEzKSwgTWF0aC5hYnMoYjMpKSAmJiBNYXRoLmFicyhhNCAtIGI0KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNCksIE1hdGguYWJzKGI0KSkgJiYgTWF0aC5hYnMoYTUgLSBiNSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTUpLCBNYXRoLmFicyhiNSkpO1xufVxuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0MmQubXVsdGlwbHl9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG52YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayBtYXQyZC5zdWJ0cmFjdH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLm11bCA9IG11bDtcbnZhciBzdWIgPSBzdWJ0cmFjdDtcbmV4cG9ydHMuc3ViID0gc3ViOyIsIlwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBfdHlwZW9mKG9iaikgeyBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZihvYmopOyB9XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNyZWF0ZSA9IGNyZWF0ZTtcbmV4cG9ydHMuZnJvbU1hdDQgPSBmcm9tTWF0NDtcbmV4cG9ydHMuY2xvbmUgPSBjbG9uZTtcbmV4cG9ydHMuY29weSA9IGNvcHk7XG5leHBvcnRzLmZyb21WYWx1ZXMgPSBmcm9tVmFsdWVzO1xuZXhwb3J0cy5zZXQgPSBzZXQ7XG5leHBvcnRzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5leHBvcnRzLnRyYW5zcG9zZSA9IHRyYW5zcG9zZTtcbmV4cG9ydHMuaW52ZXJ0ID0gaW52ZXJ0O1xuZXhwb3J0cy5hZGpvaW50ID0gYWRqb2ludDtcbmV4cG9ydHMuZGV0ZXJtaW5hbnQgPSBkZXRlcm1pbmFudDtcbmV4cG9ydHMubXVsdGlwbHkgPSBtdWx0aXBseTtcbmV4cG9ydHMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xuZXhwb3J0cy5yb3RhdGUgPSByb3RhdGU7XG5leHBvcnRzLnNjYWxlID0gc2NhbGU7XG5leHBvcnRzLmZyb21UcmFuc2xhdGlvbiA9IGZyb21UcmFuc2xhdGlvbjtcbmV4cG9ydHMuZnJvbVJvdGF0aW9uID0gZnJvbVJvdGF0aW9uO1xuZXhwb3J0cy5mcm9tU2NhbGluZyA9IGZyb21TY2FsaW5nO1xuZXhwb3J0cy5mcm9tTWF0MmQgPSBmcm9tTWF0MmQ7XG5leHBvcnRzLmZyb21RdWF0ID0gZnJvbVF1YXQ7XG5leHBvcnRzLm5vcm1hbEZyb21NYXQ0ID0gbm9ybWFsRnJvbU1hdDQ7XG5leHBvcnRzLnByb2plY3Rpb24gPSBwcm9qZWN0aW9uO1xuZXhwb3J0cy5zdHIgPSBzdHI7XG5leHBvcnRzLmZyb2IgPSBmcm9iO1xuZXhwb3J0cy5hZGQgPSBhZGQ7XG5leHBvcnRzLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG5leHBvcnRzLm11bHRpcGx5U2NhbGFyID0gbXVsdGlwbHlTY2FsYXI7XG5leHBvcnRzLm11bHRpcGx5U2NhbGFyQW5kQWRkID0gbXVsdGlwbHlTY2FsYXJBbmRBZGQ7XG5leHBvcnRzLmV4YWN0RXF1YWxzID0gZXhhY3RFcXVhbHM7XG5leHBvcnRzLmVxdWFscyA9IGVxdWFscztcbmV4cG9ydHMuc3ViID0gZXhwb3J0cy5tdWwgPSB2b2lkIDA7XG5cbnZhciBnbE1hdHJpeCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsOyB2YXIgY2FjaGUgPSBuZXcgV2Vha01hcCgpOyBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUgPSBmdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IHJldHVybiBjYWNoZTsgfTsgcmV0dXJuIGNhY2hlOyB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gaWYgKG9iaiA9PT0gbnVsbCB8fCBfdHlwZW9mKG9iaikgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSB7IHJldHVybiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfSB2YXIgY2FjaGUgPSBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKTsgaWYgKGNhY2hlICYmIGNhY2hlLmhhcyhvYmopKSB7IHJldHVybiBjYWNoZS5nZXQob2JqKTsgfSB2YXIgbmV3T2JqID0ge307IHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgeyB2YXIgZGVzYyA9IGhhc1Byb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDogbnVsbDsgaWYgKGRlc2MgJiYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpOyB9IGVsc2UgeyBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gfSBuZXdPYmpbXCJkZWZhdWx0XCJdID0gb2JqOyBpZiAoY2FjaGUpIHsgY2FjaGUuc2V0KG9iaiwgbmV3T2JqKTsgfSByZXR1cm4gbmV3T2JqOyB9XG5cbi8qKlxyXG4gKiAzeDMgTWF0cml4XHJcbiAqIEBtb2R1bGUgbWF0M1xyXG4gKi9cblxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0M1xyXG4gKlxyXG4gKiBAcmV0dXJucyB7bWF0M30gYSBuZXcgM3gzIG1hdHJpeFxyXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDkpO1xuXG4gIGlmIChnbE1hdHJpeC5BUlJBWV9UWVBFICE9IEZsb2F0MzJBcnJheSkge1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs1XSA9IDA7XG4gICAgb3V0WzZdID0gMDtcbiAgICBvdXRbN10gPSAwO1xuICB9XG5cbiAgb3V0WzBdID0gMTtcbiAgb3V0WzRdID0gMTtcbiAgb3V0WzhdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDb3BpZXMgdGhlIHVwcGVyLWxlZnQgM3gzIHZhbHVlcyBpbnRvIHRoZSBnaXZlbiBtYXQzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIDN4MyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgICB0aGUgc291cmNlIDR4NCBtYXRyaXhcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tTWF0NChvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVs0XTtcbiAgb3V0WzRdID0gYVs1XTtcbiAgb3V0WzVdID0gYVs2XTtcbiAgb3V0WzZdID0gYVs4XTtcbiAgb3V0WzddID0gYVs5XTtcbiAgb3V0WzhdID0gYVsxMF07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyBtYXQzIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgbWF0cml4XHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIG1hdHJpeCB0byBjbG9uZVxyXG4gKiBAcmV0dXJucyB7bWF0M30gYSBuZXcgM3gzIG1hdHJpeFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjbG9uZShhKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg5KTtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgb3V0WzRdID0gYVs0XTtcbiAgb3V0WzVdID0gYVs1XTtcbiAgb3V0WzZdID0gYVs2XTtcbiAgb3V0WzddID0gYVs3XTtcbiAgb3V0WzhdID0gYVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0MyB0byBhbm90aGVyXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gY29weShvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgb3V0WzRdID0gYVs0XTtcbiAgb3V0WzVdID0gYVs1XTtcbiAgb3V0WzZdID0gYVs2XTtcbiAgb3V0WzddID0gYVs3XTtcbiAgb3V0WzhdID0gYVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGUgYSBuZXcgbWF0MyB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMCBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAwKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDIgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMilcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMCBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAzKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDQpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTIgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggNSlcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMCBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAwIHBvc2l0aW9uIChpbmRleCA2KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTIxIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDEgcG9zaXRpb24gKGluZGV4IDcpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjIgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggOClcclxuICogQHJldHVybnMge21hdDN9IEEgbmV3IG1hdDNcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVZhbHVlcyhtMDAsIG0wMSwgbTAyLCBtMTAsIG0xMSwgbTEyLCBtMjAsIG0yMSwgbTIyKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg5KTtcbiAgb3V0WzBdID0gbTAwO1xuICBvdXRbMV0gPSBtMDE7XG4gIG91dFsyXSA9IG0wMjtcbiAgb3V0WzNdID0gbTEwO1xuICBvdXRbNF0gPSBtMTE7XG4gIG91dFs1XSA9IG0xMjtcbiAgb3V0WzZdID0gbTIwO1xuICBvdXRbN10gPSBtMjE7XG4gIG91dFs4XSA9IG0yMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBtYXQzIHRvIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMCBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAwKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDIgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMilcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMCBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAzKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDQpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTIgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggNSlcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMCBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAwIHBvc2l0aW9uIChpbmRleCA2KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTIxIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDEgcG9zaXRpb24gKGluZGV4IDcpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjIgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggOClcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzZXQob3V0LCBtMDAsIG0wMSwgbTAyLCBtMTAsIG0xMSwgbTEyLCBtMjAsIG0yMSwgbTIyKSB7XG4gIG91dFswXSA9IG0wMDtcbiAgb3V0WzFdID0gbTAxO1xuICBvdXRbMl0gPSBtMDI7XG4gIG91dFszXSA9IG0xMDtcbiAgb3V0WzRdID0gbTExO1xuICBvdXRbNV0gPSBtMTI7XG4gIG91dFs2XSA9IG0yMDtcbiAgb3V0WzddID0gbTIxO1xuICBvdXRbOF0gPSBtMjI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IGEgbWF0MyB0byB0aGUgaWRlbnRpdHkgbWF0cml4XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaWRlbnRpdHkob3V0KSB7XG4gIG91dFswXSA9IDE7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IDE7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNwb3NlIHRoZSB2YWx1ZXMgb2YgYSBtYXQzXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNwb3NlKG91dCwgYSkge1xuICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlIHNvbWUgdmFsdWVzXG4gIGlmIChvdXQgPT09IGEpIHtcbiAgICB2YXIgYTAxID0gYVsxXSxcbiAgICAgICAgYTAyID0gYVsyXSxcbiAgICAgICAgYTEyID0gYVs1XTtcbiAgICBvdXRbMV0gPSBhWzNdO1xuICAgIG91dFsyXSA9IGFbNl07XG4gICAgb3V0WzNdID0gYTAxO1xuICAgIG91dFs1XSA9IGFbN107XG4gICAgb3V0WzZdID0gYTAyO1xuICAgIG91dFs3XSA9IGExMjtcbiAgfSBlbHNlIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbM107XG4gICAgb3V0WzJdID0gYVs2XTtcbiAgICBvdXRbM10gPSBhWzFdO1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs3XTtcbiAgICBvdXRbNl0gPSBhWzJdO1xuICAgIG91dFs3XSA9IGFbNV07XG4gICAgb3V0WzhdID0gYVs4XTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogSW52ZXJ0cyBhIG1hdDNcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBpbnZlcnQob3V0LCBhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl07XG4gIHZhciBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV07XG4gIHZhciBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF07XG4gIHZhciBiMDEgPSBhMjIgKiBhMTEgLSBhMTIgKiBhMjE7XG4gIHZhciBiMTEgPSAtYTIyICogYTEwICsgYTEyICogYTIwO1xuICB2YXIgYjIxID0gYTIxICogYTEwIC0gYTExICogYTIwOyAvLyBDYWxjdWxhdGUgdGhlIGRldGVybWluYW50XG5cbiAgdmFyIGRldCA9IGEwMCAqIGIwMSArIGEwMSAqIGIxMSArIGEwMiAqIGIyMTtcblxuICBpZiAoIWRldCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGV0ID0gMS4wIC8gZGV0O1xuICBvdXRbMF0gPSBiMDEgKiBkZXQ7XG4gIG91dFsxXSA9ICgtYTIyICogYTAxICsgYTAyICogYTIxKSAqIGRldDtcbiAgb3V0WzJdID0gKGExMiAqIGEwMSAtIGEwMiAqIGExMSkgKiBkZXQ7XG4gIG91dFszXSA9IGIxMSAqIGRldDtcbiAgb3V0WzRdID0gKGEyMiAqIGEwMCAtIGEwMiAqIGEyMCkgKiBkZXQ7XG4gIG91dFs1XSA9ICgtYTEyICogYTAwICsgYTAyICogYTEwKSAqIGRldDtcbiAgb3V0WzZdID0gYjIxICogZGV0O1xuICBvdXRbN10gPSAoLWEyMSAqIGEwMCArIGEwMSAqIGEyMCkgKiBkZXQ7XG4gIG91dFs4XSA9IChhMTEgKiBhMDAgLSBhMDEgKiBhMTApICogZGV0O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGFkanVnYXRlIG9mIGEgbWF0M1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxyXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGFkam9pbnQob3V0LCBhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl07XG4gIHZhciBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV07XG4gIHZhciBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF07XG4gIG91dFswXSA9IGExMSAqIGEyMiAtIGExMiAqIGEyMTtcbiAgb3V0WzFdID0gYTAyICogYTIxIC0gYTAxICogYTIyO1xuICBvdXRbMl0gPSBhMDEgKiBhMTIgLSBhMDIgKiBhMTE7XG4gIG91dFszXSA9IGExMiAqIGEyMCAtIGExMCAqIGEyMjtcbiAgb3V0WzRdID0gYTAwICogYTIyIC0gYTAyICogYTIwO1xuICBvdXRbNV0gPSBhMDIgKiBhMTAgLSBhMDAgKiBhMTI7XG4gIG91dFs2XSA9IGExMCAqIGEyMSAtIGExMSAqIGEyMDtcbiAgb3V0WzddID0gYTAxICogYTIwIC0gYTAwICogYTIxO1xuICBvdXRbOF0gPSBhMDAgKiBhMTEgLSBhMDEgKiBhMTA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgZGV0ZXJtaW5hbnQgb2YgYSBtYXQzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRldGVybWluYW50IG9mIGFcclxuICovXG5cblxuZnVuY3Rpb24gZGV0ZXJtaW5hbnQoYSkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdO1xuICB2YXIgYTEwID0gYVszXSxcbiAgICAgIGExMSA9IGFbNF0sXG4gICAgICBhMTIgPSBhWzVdO1xuICB2YXIgYTIwID0gYVs2XSxcbiAgICAgIGEyMSA9IGFbN10sXG4gICAgICBhMjIgPSBhWzhdO1xuICByZXR1cm4gYTAwICogKGEyMiAqIGExMSAtIGExMiAqIGEyMSkgKyBhMDEgKiAoLWEyMiAqIGExMCArIGExMiAqIGEyMCkgKyBhMDIgKiAoYTIxICogYTEwIC0gYTExICogYTIwKTtcbn1cbi8qKlxyXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQzJ3NcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl07XG4gIHZhciBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV07XG4gIHZhciBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF07XG4gIHZhciBiMDAgPSBiWzBdLFxuICAgICAgYjAxID0gYlsxXSxcbiAgICAgIGIwMiA9IGJbMl07XG4gIHZhciBiMTAgPSBiWzNdLFxuICAgICAgYjExID0gYls0XSxcbiAgICAgIGIxMiA9IGJbNV07XG4gIHZhciBiMjAgPSBiWzZdLFxuICAgICAgYjIxID0gYls3XSxcbiAgICAgIGIyMiA9IGJbOF07XG4gIG91dFswXSA9IGIwMCAqIGEwMCArIGIwMSAqIGExMCArIGIwMiAqIGEyMDtcbiAgb3V0WzFdID0gYjAwICogYTAxICsgYjAxICogYTExICsgYjAyICogYTIxO1xuICBvdXRbMl0gPSBiMDAgKiBhMDIgKyBiMDEgKiBhMTIgKyBiMDIgKiBhMjI7XG4gIG91dFszXSA9IGIxMCAqIGEwMCArIGIxMSAqIGExMCArIGIxMiAqIGEyMDtcbiAgb3V0WzRdID0gYjEwICogYTAxICsgYjExICogYTExICsgYjEyICogYTIxO1xuICBvdXRbNV0gPSBiMTAgKiBhMDIgKyBiMTEgKiBhMTIgKyBiMTIgKiBhMjI7XG4gIG91dFs2XSA9IGIyMCAqIGEwMCArIGIyMSAqIGExMCArIGIyMiAqIGEyMDtcbiAgb3V0WzddID0gYjIwICogYTAxICsgYjIxICogYTExICsgYjIyICogYTIxO1xuICBvdXRbOF0gPSBiMjAgKiBhMDIgKyBiMjEgKiBhMTIgKyBiMjIgKiBhMjI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNsYXRlIGEgbWF0MyBieSB0aGUgZ2l2ZW4gdmVjdG9yXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBtYXRyaXggdG8gdHJhbnNsYXRlXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IHZlY3RvciB0byB0cmFuc2xhdGUgYnlcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiB0cmFuc2xhdGUob3V0LCBhLCB2KSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV0sXG4gICAgICBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF0sXG4gICAgICB4ID0gdlswXSxcbiAgICAgIHkgPSB2WzFdO1xuICBvdXRbMF0gPSBhMDA7XG4gIG91dFsxXSA9IGEwMTtcbiAgb3V0WzJdID0gYTAyO1xuICBvdXRbM10gPSBhMTA7XG4gIG91dFs0XSA9IGExMTtcbiAgb3V0WzVdID0gYTEyO1xuICBvdXRbNl0gPSB4ICogYTAwICsgeSAqIGExMCArIGEyMDtcbiAgb3V0WzddID0geCAqIGEwMSArIHkgKiBhMTEgKyBhMjE7XG4gIG91dFs4XSA9IHggKiBhMDIgKyB5ICogYTEyICsgYTIyO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBtYXQzIGJ5IHRoZSBnaXZlbiBhbmdsZVxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZShvdXQsIGEsIHJhZCkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdLFxuICAgICAgYTEwID0gYVszXSxcbiAgICAgIGExMSA9IGFbNF0sXG4gICAgICBhMTIgPSBhWzVdLFxuICAgICAgYTIwID0gYVs2XSxcbiAgICAgIGEyMSA9IGFbN10sXG4gICAgICBhMjIgPSBhWzhdLFxuICAgICAgcyA9IE1hdGguc2luKHJhZCksXG4gICAgICBjID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYyAqIGEwMCArIHMgKiBhMTA7XG4gIG91dFsxXSA9IGMgKiBhMDEgKyBzICogYTExO1xuICBvdXRbMl0gPSBjICogYTAyICsgcyAqIGExMjtcbiAgb3V0WzNdID0gYyAqIGExMCAtIHMgKiBhMDA7XG4gIG91dFs0XSA9IGMgKiBhMTEgLSBzICogYTAxO1xuICBvdXRbNV0gPSBjICogYTEyIC0gcyAqIGEwMjtcbiAgb3V0WzZdID0gYTIwO1xuICBvdXRbN10gPSBhMjE7XG4gIG91dFs4XSA9IGEyMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTY2FsZXMgdGhlIG1hdDMgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IHYgdGhlIHZlYzIgdG8gc2NhbGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XHJcbiAqKi9cblxuXG5mdW5jdGlvbiBzY2FsZShvdXQsIGEsIHYpIHtcbiAgdmFyIHggPSB2WzBdLFxuICAgICAgeSA9IHZbMV07XG4gIG91dFswXSA9IHggKiBhWzBdO1xuICBvdXRbMV0gPSB4ICogYVsxXTtcbiAgb3V0WzJdID0geCAqIGFbMl07XG4gIG91dFszXSA9IHkgKiBhWzNdO1xuICBvdXRbNF0gPSB5ICogYVs0XTtcbiAgb3V0WzVdID0geSAqIGFbNV07XG4gIG91dFs2XSA9IGFbNl07XG4gIG91dFs3XSA9IGFbN107XG4gIG91dFs4XSA9IGFbOF07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHRyYW5zbGF0aW9uXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcclxuICogICAgIG1hdDMudHJhbnNsYXRlKGRlc3QsIGRlc3QsIHZlYyk7XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IHYgVHJhbnNsYXRpb24gdmVjdG9yXHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVRyYW5zbGF0aW9uKG91dCwgdikge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAxO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSB2WzBdO1xuICBvdXRbN10gPSB2WzFdO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIGdpdmVuIGFuZ2xlXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcclxuICogICAgIG1hdDMucm90YXRlKGRlc3QsIGRlc3QsIHJhZCk7XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgYyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IHM7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IC1zO1xuICBvdXRbNF0gPSBjO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciBzY2FsaW5nXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcclxuICogICAgIG1hdDMuc2NhbGUoZGVzdCwgZGVzdCwgdmVjKTtcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgbWF0MyByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gdiBTY2FsaW5nIHZlY3RvclxyXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21TY2FsaW5nKG91dCwgdikge1xuICBvdXRbMF0gPSB2WzBdO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB2WzFdO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENvcGllcyB0aGUgdmFsdWVzIGZyb20gYSBtYXQyZCBpbnRvIGEgbWF0M1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIG1hdHJpeCB0byBjb3B5XHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICoqL1xuXG5cbmZ1bmN0aW9uIGZyb21NYXQyZChvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gYVsyXTtcbiAgb3V0WzRdID0gYVszXTtcbiAgb3V0WzVdID0gMDtcbiAgb3V0WzZdID0gYVs0XTtcbiAgb3V0WzddID0gYVs1XTtcbiAgb3V0WzhdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIGEgM3gzIG1hdHJpeCBmcm9tIHRoZSBnaXZlbiBxdWF0ZXJuaW9uXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgUXVhdGVybmlvbiB0byBjcmVhdGUgbWF0cml4IGZyb21cclxuICpcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUXVhdChvdXQsIHEpIHtcbiAgdmFyIHggPSBxWzBdLFxuICAgICAgeSA9IHFbMV0sXG4gICAgICB6ID0gcVsyXSxcbiAgICAgIHcgPSBxWzNdO1xuICB2YXIgeDIgPSB4ICsgeDtcbiAgdmFyIHkyID0geSArIHk7XG4gIHZhciB6MiA9IHogKyB6O1xuICB2YXIgeHggPSB4ICogeDI7XG4gIHZhciB5eCA9IHkgKiB4MjtcbiAgdmFyIHl5ID0geSAqIHkyO1xuICB2YXIgenggPSB6ICogeDI7XG4gIHZhciB6eSA9IHogKiB5MjtcbiAgdmFyIHp6ID0geiAqIHoyO1xuICB2YXIgd3ggPSB3ICogeDI7XG4gIHZhciB3eSA9IHcgKiB5MjtcbiAgdmFyIHd6ID0gdyAqIHoyO1xuICBvdXRbMF0gPSAxIC0geXkgLSB6ejtcbiAgb3V0WzNdID0geXggLSB3ejtcbiAgb3V0WzZdID0genggKyB3eTtcbiAgb3V0WzFdID0geXggKyB3ejtcbiAgb3V0WzRdID0gMSAtIHh4IC0geno7XG4gIG91dFs3XSA9IHp5IC0gd3g7XG4gIG91dFsyXSA9IHp4IC0gd3k7XG4gIG91dFs1XSA9IHp5ICsgd3g7XG4gIG91dFs4XSA9IDEgLSB4eCAtIHl5O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgYSAzeDMgbm9ybWFsIG1hdHJpeCAodHJhbnNwb3NlIGludmVyc2UpIGZyb20gdGhlIDR4NCBtYXRyaXhcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgbWF0MyByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSBNYXQ0IHRvIGRlcml2ZSB0aGUgbm9ybWFsIG1hdHJpeCBmcm9tXHJcbiAqXHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbm9ybWFsRnJvbU1hdDQob3V0LCBhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XSxcbiAgICAgIGExMSA9IGFbNV0sXG4gICAgICBhMTIgPSBhWzZdLFxuICAgICAgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF0sXG4gICAgICBhMjEgPSBhWzldLFxuICAgICAgYTIyID0gYVsxMF0sXG4gICAgICBhMjMgPSBhWzExXTtcbiAgdmFyIGEzMCA9IGFbMTJdLFxuICAgICAgYTMxID0gYVsxM10sXG4gICAgICBhMzIgPSBhWzE0XSxcbiAgICAgIGEzMyA9IGFbMTVdO1xuICB2YXIgYjAwID0gYTAwICogYTExIC0gYTAxICogYTEwO1xuICB2YXIgYjAxID0gYTAwICogYTEyIC0gYTAyICogYTEwO1xuICB2YXIgYjAyID0gYTAwICogYTEzIC0gYTAzICogYTEwO1xuICB2YXIgYjAzID0gYTAxICogYTEyIC0gYTAyICogYTExO1xuICB2YXIgYjA0ID0gYTAxICogYTEzIC0gYTAzICogYTExO1xuICB2YXIgYjA1ID0gYTAyICogYTEzIC0gYTAzICogYTEyO1xuICB2YXIgYjA2ID0gYTIwICogYTMxIC0gYTIxICogYTMwO1xuICB2YXIgYjA3ID0gYTIwICogYTMyIC0gYTIyICogYTMwO1xuICB2YXIgYjA4ID0gYTIwICogYTMzIC0gYTIzICogYTMwO1xuICB2YXIgYjA5ID0gYTIxICogYTMyIC0gYTIyICogYTMxO1xuICB2YXIgYjEwID0gYTIxICogYTMzIC0gYTIzICogYTMxO1xuICB2YXIgYjExID0gYTIyICogYTMzIC0gYTIzICogYTMyOyAvLyBDYWxjdWxhdGUgdGhlIGRldGVybWluYW50XG5cbiAgdmFyIGRldCA9IGIwMCAqIGIxMSAtIGIwMSAqIGIxMCArIGIwMiAqIGIwOSArIGIwMyAqIGIwOCAtIGIwNCAqIGIwNyArIGIwNSAqIGIwNjtcblxuICBpZiAoIWRldCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGV0ID0gMS4wIC8gZGV0O1xuICBvdXRbMF0gPSAoYTExICogYjExIC0gYTEyICogYjEwICsgYTEzICogYjA5KSAqIGRldDtcbiAgb3V0WzFdID0gKGExMiAqIGIwOCAtIGExMCAqIGIxMSAtIGExMyAqIGIwNykgKiBkZXQ7XG4gIG91dFsyXSA9IChhMTAgKiBiMTAgLSBhMTEgKiBiMDggKyBhMTMgKiBiMDYpICogZGV0O1xuICBvdXRbM10gPSAoYTAyICogYjEwIC0gYTAxICogYjExIC0gYTAzICogYjA5KSAqIGRldDtcbiAgb3V0WzRdID0gKGEwMCAqIGIxMSAtIGEwMiAqIGIwOCArIGEwMyAqIGIwNykgKiBkZXQ7XG4gIG91dFs1XSA9IChhMDEgKiBiMDggLSBhMDAgKiBiMTAgLSBhMDMgKiBiMDYpICogZGV0O1xuICBvdXRbNl0gPSAoYTMxICogYjA1IC0gYTMyICogYjA0ICsgYTMzICogYjAzKSAqIGRldDtcbiAgb3V0WzddID0gKGEzMiAqIGIwMiAtIGEzMCAqIGIwNSAtIGEzMyAqIGIwMSkgKiBkZXQ7XG4gIG91dFs4XSA9IChhMzAgKiBiMDQgLSBhMzEgKiBiMDIgKyBhMzMgKiBiMDApICogZGV0O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdlbmVyYXRlcyBhIDJEIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGJvdW5kc1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCBXaWR0aCBvZiB5b3VyIGdsIGNvbnRleHRcclxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCBIZWlnaHQgb2YgZ2wgY29udGV4dFxyXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHByb2plY3Rpb24ob3V0LCB3aWR0aCwgaGVpZ2h0KSB7XG4gIG91dFswXSA9IDIgLyB3aWR0aDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gLTIgLyBoZWlnaHQ7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IC0xO1xuICBvdXRbN10gPSAxO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtYXQzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIG1hdHJpeCB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcclxuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcclxuICovXG5cblxuZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwibWF0MyhcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiLCBcIiArIGFbM10gKyBcIiwgXCIgKyBhWzRdICsgXCIsIFwiICsgYVs1XSArIFwiLCBcIiArIGFbNl0gKyBcIiwgXCIgKyBhWzddICsgXCIsIFwiICsgYVs4XSArIFwiKVwiO1xufVxuLyoqXHJcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBtYXRyaXggdG8gY2FsY3VsYXRlIEZyb2Jlbml1cyBub3JtIG9mXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IEZyb2Jlbml1cyBub3JtXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb2IoYSkge1xuICByZXR1cm4gTWF0aC5oeXBvdChhWzBdLCBhWzFdLCBhWzJdLCBhWzNdLCBhWzRdLCBhWzVdLCBhWzZdLCBhWzddLCBhWzhdKTtcbn1cbi8qKlxyXG4gKiBBZGRzIHR3byBtYXQzJ3NcclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdO1xuICBvdXRbNl0gPSBhWzZdICsgYls2XTtcbiAgb3V0WzddID0gYVs3XSArIGJbN107XG4gIG91dFs4XSA9IGFbOF0gKyBiWzhdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFN1YnRyYWN0cyBtYXRyaXggYiBmcm9tIG1hdHJpeCBhXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHN1YnRyYWN0KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLSBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC0gYlszXTtcbiAgb3V0WzRdID0gYVs0XSAtIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gLSBiWzVdO1xuICBvdXRbNl0gPSBhWzZdIC0gYls2XTtcbiAgb3V0WzddID0gYVs3XSAtIGJbN107XG4gIG91dFs4XSA9IGFbOF0gLSBiWzhdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE11bHRpcGx5IGVhY2ggZWxlbWVudCBvZiB0aGUgbWF0cml4IGJ5IGEgc2NhbGFyLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgbWF0cml4IHRvIHNjYWxlXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgbWF0cml4J3MgZWxlbWVudHMgYnlcclxuICogQHJldHVybnMge21hdDN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtdWx0aXBseVNjYWxhcihvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgb3V0WzNdID0gYVszXSAqIGI7XG4gIG91dFs0XSA9IGFbNF0gKiBiO1xuICBvdXRbNV0gPSBhWzVdICogYjtcbiAgb3V0WzZdID0gYVs2XSAqIGI7XG4gIG91dFs3XSA9IGFbN10gKiBiO1xuICBvdXRbOF0gPSBhWzhdICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBBZGRzIHR3byBtYXQzJ3MgYWZ0ZXIgbXVsdGlwbHlpbmcgZWFjaCBlbGVtZW50IG9mIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZS5cclxuICpcclxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIncyBlbGVtZW50cyBieSBiZWZvcmUgYWRkaW5nXHJcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXJBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXSAqIHNjYWxlO1xuICBvdXRbM10gPSBhWzNdICsgYlszXSAqIHNjYWxlO1xuICBvdXRbNF0gPSBhWzRdICsgYls0XSAqIHNjYWxlO1xuICBvdXRbNV0gPSBhWzVdICsgYls1XSAqIHNjYWxlO1xuICBvdXRbNl0gPSBhWzZdICsgYls2XSAqIHNjYWxlO1xuICBvdXRbN10gPSBhWzddICsgYls3XSAqIHNjYWxlO1xuICBvdXRbOF0gPSBhWzhdICsgYls4XSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIG1hdHJpY2VzIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgVGhlIGZpcnN0IG1hdHJpeC5cclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgVGhlIHNlY29uZCBtYXRyaXguXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl0gJiYgYVszXSA9PT0gYlszXSAmJiBhWzRdID09PSBiWzRdICYmIGFbNV0gPT09IGJbNV0gJiYgYVs2XSA9PT0gYls2XSAmJiBhWzddID09PSBiWzddICYmIGFbOF0gPT09IGJbOF07XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSBUaGUgZmlyc3QgbWF0cml4LlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYiBUaGUgc2Vjb25kIG1hdHJpeC5cclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdLFxuICAgICAgYTYgPSBhWzZdLFxuICAgICAgYTcgPSBhWzddLFxuICAgICAgYTggPSBhWzhdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdLFxuICAgICAgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdLFxuICAgICAgYjYgPSBiWzZdLFxuICAgICAgYjcgPSBiWzddLFxuICAgICAgYjggPSBiWzhdO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSkgJiYgTWF0aC5hYnMoYTMgLSBiMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTMpLCBNYXRoLmFicyhiMykpICYmIE1hdGguYWJzKGE0IC0gYjQpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE0KSwgTWF0aC5hYnMoYjQpKSAmJiBNYXRoLmFicyhhNSAtIGI1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNSksIE1hdGguYWJzKGI1KSkgJiYgTWF0aC5hYnMoYTYgLSBiNikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTYpLCBNYXRoLmFicyhiNikpICYmIE1hdGguYWJzKGE3IC0gYjcpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE3KSwgTWF0aC5hYnMoYjcpKSAmJiBNYXRoLmFicyhhOCAtIGI4KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhOCksIE1hdGguYWJzKGI4KSk7XG59XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayBtYXQzLm11bHRpcGx5fVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxudmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0My5zdWJ0cmFjdH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLm11bCA9IG11bDtcbnZhciBzdWIgPSBzdWJ0cmFjdDtcbmV4cG9ydHMuc3ViID0gc3ViOyIsIlwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBfdHlwZW9mKG9iaikgeyBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZihvYmopOyB9XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNyZWF0ZSA9IGNyZWF0ZTtcbmV4cG9ydHMuY2xvbmUgPSBjbG9uZTtcbmV4cG9ydHMuY29weSA9IGNvcHk7XG5leHBvcnRzLmZyb21WYWx1ZXMgPSBmcm9tVmFsdWVzO1xuZXhwb3J0cy5zZXQgPSBzZXQ7XG5leHBvcnRzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5leHBvcnRzLnRyYW5zcG9zZSA9IHRyYW5zcG9zZTtcbmV4cG9ydHMuaW52ZXJ0ID0gaW52ZXJ0O1xuZXhwb3J0cy5hZGpvaW50ID0gYWRqb2ludDtcbmV4cG9ydHMuZGV0ZXJtaW5hbnQgPSBkZXRlcm1pbmFudDtcbmV4cG9ydHMubXVsdGlwbHkgPSBtdWx0aXBseTtcbmV4cG9ydHMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xuZXhwb3J0cy5zY2FsZSA9IHNjYWxlO1xuZXhwb3J0cy5yb3RhdGUgPSByb3RhdGU7XG5leHBvcnRzLnJvdGF0ZVggPSByb3RhdGVYO1xuZXhwb3J0cy5yb3RhdGVZID0gcm90YXRlWTtcbmV4cG9ydHMucm90YXRlWiA9IHJvdGF0ZVo7XG5leHBvcnRzLmZyb21UcmFuc2xhdGlvbiA9IGZyb21UcmFuc2xhdGlvbjtcbmV4cG9ydHMuZnJvbVNjYWxpbmcgPSBmcm9tU2NhbGluZztcbmV4cG9ydHMuZnJvbVJvdGF0aW9uID0gZnJvbVJvdGF0aW9uO1xuZXhwb3J0cy5mcm9tWFJvdGF0aW9uID0gZnJvbVhSb3RhdGlvbjtcbmV4cG9ydHMuZnJvbVlSb3RhdGlvbiA9IGZyb21ZUm90YXRpb247XG5leHBvcnRzLmZyb21aUm90YXRpb24gPSBmcm9tWlJvdGF0aW9uO1xuZXhwb3J0cy5mcm9tUm90YXRpb25UcmFuc2xhdGlvbiA9IGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uO1xuZXhwb3J0cy5mcm9tUXVhdDIgPSBmcm9tUXVhdDI7XG5leHBvcnRzLmdldFRyYW5zbGF0aW9uID0gZ2V0VHJhbnNsYXRpb247XG5leHBvcnRzLmdldFNjYWxpbmcgPSBnZXRTY2FsaW5nO1xuZXhwb3J0cy5nZXRSb3RhdGlvbiA9IGdldFJvdGF0aW9uO1xuZXhwb3J0cy5mcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlID0gZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZTtcbmV4cG9ydHMuZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZU9yaWdpbiA9IGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uU2NhbGVPcmlnaW47XG5leHBvcnRzLmZyb21RdWF0ID0gZnJvbVF1YXQ7XG5leHBvcnRzLmZydXN0dW0gPSBmcnVzdHVtO1xuZXhwb3J0cy5wZXJzcGVjdGl2ZSA9IHBlcnNwZWN0aXZlO1xuZXhwb3J0cy5wZXJzcGVjdGl2ZUZyb21GaWVsZE9mVmlldyA9IHBlcnNwZWN0aXZlRnJvbUZpZWxkT2ZWaWV3O1xuZXhwb3J0cy5vcnRobyA9IG9ydGhvO1xuZXhwb3J0cy5sb29rQXQgPSBsb29rQXQ7XG5leHBvcnRzLnRhcmdldFRvID0gdGFyZ2V0VG87XG5leHBvcnRzLnN0ciA9IHN0cjtcbmV4cG9ydHMuZnJvYiA9IGZyb2I7XG5leHBvcnRzLmFkZCA9IGFkZDtcbmV4cG9ydHMuc3VidHJhY3QgPSBzdWJ0cmFjdDtcbmV4cG9ydHMubXVsdGlwbHlTY2FsYXIgPSBtdWx0aXBseVNjYWxhcjtcbmV4cG9ydHMubXVsdGlwbHlTY2FsYXJBbmRBZGQgPSBtdWx0aXBseVNjYWxhckFuZEFkZDtcbmV4cG9ydHMuZXhhY3RFcXVhbHMgPSBleGFjdEVxdWFscztcbmV4cG9ydHMuZXF1YWxzID0gZXF1YWxzO1xuZXhwb3J0cy5zdWIgPSBleHBvcnRzLm11bCA9IHZvaWQgMDtcblxudmFyIGdsTWF0cml4ID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vY29tbW9uLmpzXCIpKTtcblxuZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCkgeyBpZiAodHlwZW9mIFdlYWtNYXAgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIG51bGw7IHZhciBjYWNoZSA9IG5ldyBXZWFrTWFwKCk7IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSA9IGZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgcmV0dXJuIGNhY2hlOyB9OyByZXR1cm4gY2FjaGU7IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBpZiAob2JqID09PSBudWxsIHx8IF90eXBlb2Yob2JqKSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHsgcmV0dXJuIHsgXCJkZWZhdWx0XCI6IG9iaiB9OyB9IHZhciBjYWNoZSA9IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpOyBpZiAoY2FjaGUgJiYgY2FjaGUuaGFzKG9iaikpIHsgcmV0dXJuIGNhY2hlLmdldChvYmopOyB9IHZhciBuZXdPYmogPSB7fTsgdmFyIGhhc1Byb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7IHZhciBkZXNjID0gaGFzUHJvcGVydHlEZXNjcmlwdG9yID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSkgOiBudWxsOyBpZiAoZGVzYyAmJiAoZGVzYy5nZXQgfHwgZGVzYy5zZXQpKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdPYmosIGtleSwgZGVzYyk7IH0gZWxzZSB7IG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSB9IG5ld09ialtcImRlZmF1bHRcIl0gPSBvYmo7IGlmIChjYWNoZSkgeyBjYWNoZS5zZXQob2JqLCBuZXdPYmopOyB9IHJldHVybiBuZXdPYmo7IH1cblxuLyoqXHJcbiAqIDR4NCBNYXRyaXg8YnI+Rm9ybWF0OiBjb2x1bW4tbWFqb3IsIHdoZW4gdHlwZWQgb3V0IGl0IGxvb2tzIGxpa2Ugcm93LW1ham9yPGJyPlRoZSBtYXRyaWNlcyBhcmUgYmVpbmcgcG9zdCBtdWx0aXBsaWVkLlxyXG4gKiBAbW9kdWxlIG1hdDRcclxuICovXG5cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IG1hdDRcclxuICpcclxuICogQHJldHVybnMge21hdDR9IGEgbmV3IDR4NCBtYXRyaXhcclxuICovXG5mdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgxNik7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICAgIG91dFszXSA9IDA7XG4gICAgb3V0WzRdID0gMDtcbiAgICBvdXRbNl0gPSAwO1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0gMDtcbiAgICBvdXRbOV0gPSAwO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSAwO1xuICAgIG91dFsxM10gPSAwO1xuICAgIG91dFsxNF0gPSAwO1xuICB9XG5cbiAgb3V0WzBdID0gMTtcbiAgb3V0WzVdID0gMTtcbiAgb3V0WzEwXSA9IDE7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgbWF0NCBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIG1hdHJpeFxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSBtYXRyaXggdG8gY2xvbmVcclxuICogQHJldHVybnMge21hdDR9IGEgbmV3IDR4NCBtYXRyaXhcclxuICovXG5cblxuZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMTYpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICBvdXRbOF0gPSBhWzhdO1xuICBvdXRbOV0gPSBhWzldO1xuICBvdXRbMTBdID0gYVsxMF07XG4gIG91dFsxMV0gPSBhWzExXTtcbiAgb3V0WzEyXSA9IGFbMTJdO1xuICBvdXRbMTNdID0gYVsxM107XG4gIG91dFsxNF0gPSBhWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBtYXQ0IHRvIGFub3RoZXJcclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICBvdXRbOF0gPSBhWzhdO1xuICBvdXRbOV0gPSBhWzldO1xuICBvdXRbMTBdID0gYVsxMF07XG4gIG91dFsxMV0gPSBhWzExXTtcbiAgb3V0WzEyXSA9IGFbMTJdO1xuICBvdXRbMTNdID0gYVsxM107XG4gIG91dFsxNF0gPSBhWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZSBhIG5ldyBtYXQ0IHdpdGggdGhlIGdpdmVuIHZhbHVlc1xyXG4gKlxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDEgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMSlcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMiBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAyIHBvc2l0aW9uIChpbmRleCAyKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAzIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDMgcG9zaXRpb24gKGluZGV4IDMpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTAgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggNClcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMSBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAxIHBvc2l0aW9uIChpbmRleCA1KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTEyIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDIgcG9zaXRpb24gKGluZGV4IDYpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTMgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggNylcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMCBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAwIHBvc2l0aW9uIChpbmRleCA4KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTIxIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDEgcG9zaXRpb24gKGluZGV4IDkpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjIgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMTApXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjMgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggMTEpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzAgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMTIpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzEgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMTMpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzIgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMTQpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzMgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggMTUpXHJcbiAqIEByZXR1cm5zIHttYXQ0fSBBIG5ldyBtYXQ0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21WYWx1ZXMobTAwLCBtMDEsIG0wMiwgbTAzLCBtMTAsIG0xMSwgbTEyLCBtMTMsIG0yMCwgbTIxLCBtMjIsIG0yMywgbTMwLCBtMzEsIG0zMiwgbTMzKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgxNik7XG4gIG91dFswXSA9IG0wMDtcbiAgb3V0WzFdID0gbTAxO1xuICBvdXRbMl0gPSBtMDI7XG4gIG91dFszXSA9IG0wMztcbiAgb3V0WzRdID0gbTEwO1xuICBvdXRbNV0gPSBtMTE7XG4gIG91dFs2XSA9IG0xMjtcbiAgb3V0WzddID0gbTEzO1xuICBvdXRbOF0gPSBtMjA7XG4gIG91dFs5XSA9IG0yMTtcbiAgb3V0WzEwXSA9IG0yMjtcbiAgb3V0WzExXSA9IG0yMztcbiAgb3V0WzEyXSA9IG0zMDtcbiAgb3V0WzEzXSA9IG0zMTtcbiAgb3V0WzE0XSA9IG0zMjtcbiAgb3V0WzE1XSA9IG0zMztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBtYXQ0IHRvIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMCBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAwKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDIgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMilcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMyBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAzIHBvc2l0aW9uIChpbmRleCAzKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTEwIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDAgcG9zaXRpb24gKGluZGV4IDQpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTEgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggNSlcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMiBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAyIHBvc2l0aW9uIChpbmRleCA2KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTEzIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDMgcG9zaXRpb24gKGluZGV4IDcpXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjAgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggOClcclxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMSBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAxIHBvc2l0aW9uIChpbmRleCA5KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTIyIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDIgcG9zaXRpb24gKGluZGV4IDEwKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTIzIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDMgcG9zaXRpb24gKGluZGV4IDExKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTMwIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDAgcG9zaXRpb24gKGluZGV4IDEyKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTMxIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDEgcG9zaXRpb24gKGluZGV4IDEzKVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTMyIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDIgcG9zaXRpb24gKGluZGV4IDE0KVxyXG4gKiBAcGFyYW0ge051bWJlcn0gbTMzIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDMgcG9zaXRpb24gKGluZGV4IDE1KVxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNldChvdXQsIG0wMCwgbTAxLCBtMDIsIG0wMywgbTEwLCBtMTEsIG0xMiwgbTEzLCBtMjAsIG0yMSwgbTIyLCBtMjMsIG0zMCwgbTMxLCBtMzIsIG0zMykge1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTAyO1xuICBvdXRbM10gPSBtMDM7XG4gIG91dFs0XSA9IG0xMDtcbiAgb3V0WzVdID0gbTExO1xuICBvdXRbNl0gPSBtMTI7XG4gIG91dFs3XSA9IG0xMztcbiAgb3V0WzhdID0gbTIwO1xuICBvdXRbOV0gPSBtMjE7XG4gIG91dFsxMF0gPSBtMjI7XG4gIG91dFsxMV0gPSBtMjM7XG4gIG91dFsxMl0gPSBtMzA7XG4gIG91dFsxM10gPSBtMzE7XG4gIG91dFsxNF0gPSBtMzI7XG4gIG91dFsxNV0gPSBtMzM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IGEgbWF0NCB0byB0aGUgaWRlbnRpdHkgbWF0cml4XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaWRlbnRpdHkob3V0KSB7XG4gIG91dFswXSA9IDE7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IDE7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDA7XG4gIG91dFs5XSA9IDA7XG4gIG91dFsxMF0gPSAxO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNwb3NlIHRoZSB2YWx1ZXMgb2YgYSBtYXQ0XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNwb3NlKG91dCwgYSkge1xuICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlIHNvbWUgdmFsdWVzXG4gIGlmIChvdXQgPT09IGEpIHtcbiAgICB2YXIgYTAxID0gYVsxXSxcbiAgICAgICAgYTAyID0gYVsyXSxcbiAgICAgICAgYTAzID0gYVszXTtcbiAgICB2YXIgYTEyID0gYVs2XSxcbiAgICAgICAgYTEzID0gYVs3XTtcbiAgICB2YXIgYTIzID0gYVsxMV07XG4gICAgb3V0WzFdID0gYVs0XTtcbiAgICBvdXRbMl0gPSBhWzhdO1xuICAgIG91dFszXSA9IGFbMTJdO1xuICAgIG91dFs0XSA9IGEwMTtcbiAgICBvdXRbNl0gPSBhWzldO1xuICAgIG91dFs3XSA9IGFbMTNdO1xuICAgIG91dFs4XSA9IGEwMjtcbiAgICBvdXRbOV0gPSBhMTI7XG4gICAgb3V0WzExXSA9IGFbMTRdO1xuICAgIG91dFsxMl0gPSBhMDM7XG4gICAgb3V0WzEzXSA9IGExMztcbiAgICBvdXRbMTRdID0gYTIzO1xuICB9IGVsc2Uge1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVs0XTtcbiAgICBvdXRbMl0gPSBhWzhdO1xuICAgIG91dFszXSA9IGFbMTJdO1xuICAgIG91dFs0XSA9IGFbMV07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICBvdXRbNl0gPSBhWzldO1xuICAgIG91dFs3XSA9IGFbMTNdO1xuICAgIG91dFs4XSA9IGFbMl07XG4gICAgb3V0WzldID0gYVs2XTtcbiAgICBvdXRbMTBdID0gYVsxMF07XG4gICAgb3V0WzExXSA9IGFbMTRdO1xuICAgIG91dFsxMl0gPSBhWzNdO1xuICAgIG91dFsxM10gPSBhWzddO1xuICAgIG91dFsxNF0gPSBhWzExXTtcbiAgICBvdXRbMTVdID0gYVsxNV07XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEludmVydHMgYSBtYXQ0XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaW52ZXJ0KG91dCwgYSkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdLFxuICAgICAgYTAzID0gYVszXTtcbiAgdmFyIGExMCA9IGFbNF0sXG4gICAgICBhMTEgPSBhWzVdLFxuICAgICAgYTEyID0gYVs2XSxcbiAgICAgIGExMyA9IGFbN107XG4gIHZhciBhMjAgPSBhWzhdLFxuICAgICAgYTIxID0gYVs5XSxcbiAgICAgIGEyMiA9IGFbMTBdLFxuICAgICAgYTIzID0gYVsxMV07XG4gIHZhciBhMzAgPSBhWzEyXSxcbiAgICAgIGEzMSA9IGFbMTNdLFxuICAgICAgYTMyID0gYVsxNF0sXG4gICAgICBhMzMgPSBhWzE1XTtcbiAgdmFyIGIwMCA9IGEwMCAqIGExMSAtIGEwMSAqIGExMDtcbiAgdmFyIGIwMSA9IGEwMCAqIGExMiAtIGEwMiAqIGExMDtcbiAgdmFyIGIwMiA9IGEwMCAqIGExMyAtIGEwMyAqIGExMDtcbiAgdmFyIGIwMyA9IGEwMSAqIGExMiAtIGEwMiAqIGExMTtcbiAgdmFyIGIwNCA9IGEwMSAqIGExMyAtIGEwMyAqIGExMTtcbiAgdmFyIGIwNSA9IGEwMiAqIGExMyAtIGEwMyAqIGExMjtcbiAgdmFyIGIwNiA9IGEyMCAqIGEzMSAtIGEyMSAqIGEzMDtcbiAgdmFyIGIwNyA9IGEyMCAqIGEzMiAtIGEyMiAqIGEzMDtcbiAgdmFyIGIwOCA9IGEyMCAqIGEzMyAtIGEyMyAqIGEzMDtcbiAgdmFyIGIwOSA9IGEyMSAqIGEzMiAtIGEyMiAqIGEzMTtcbiAgdmFyIGIxMCA9IGEyMSAqIGEzMyAtIGEyMyAqIGEzMTtcbiAgdmFyIGIxMSA9IGEyMiAqIGEzMyAtIGEyMyAqIGEzMjsgLy8gQ2FsY3VsYXRlIHRoZSBkZXRlcm1pbmFudFxuXG4gIHZhciBkZXQgPSBiMDAgKiBiMTEgLSBiMDEgKiBiMTAgKyBiMDIgKiBiMDkgKyBiMDMgKiBiMDggLSBiMDQgKiBiMDcgKyBiMDUgKiBiMDY7XG5cbiAgaWYgKCFkZXQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGRldCA9IDEuMCAvIGRldDtcbiAgb3V0WzBdID0gKGExMSAqIGIxMSAtIGExMiAqIGIxMCArIGExMyAqIGIwOSkgKiBkZXQ7XG4gIG91dFsxXSA9IChhMDIgKiBiMTAgLSBhMDEgKiBiMTEgLSBhMDMgKiBiMDkpICogZGV0O1xuICBvdXRbMl0gPSAoYTMxICogYjA1IC0gYTMyICogYjA0ICsgYTMzICogYjAzKSAqIGRldDtcbiAgb3V0WzNdID0gKGEyMiAqIGIwNCAtIGEyMSAqIGIwNSAtIGEyMyAqIGIwMykgKiBkZXQ7XG4gIG91dFs0XSA9IChhMTIgKiBiMDggLSBhMTAgKiBiMTEgLSBhMTMgKiBiMDcpICogZGV0O1xuICBvdXRbNV0gPSAoYTAwICogYjExIC0gYTAyICogYjA4ICsgYTAzICogYjA3KSAqIGRldDtcbiAgb3V0WzZdID0gKGEzMiAqIGIwMiAtIGEzMCAqIGIwNSAtIGEzMyAqIGIwMSkgKiBkZXQ7XG4gIG91dFs3XSA9IChhMjAgKiBiMDUgLSBhMjIgKiBiMDIgKyBhMjMgKiBiMDEpICogZGV0O1xuICBvdXRbOF0gPSAoYTEwICogYjEwIC0gYTExICogYjA4ICsgYTEzICogYjA2KSAqIGRldDtcbiAgb3V0WzldID0gKGEwMSAqIGIwOCAtIGEwMCAqIGIxMCAtIGEwMyAqIGIwNikgKiBkZXQ7XG4gIG91dFsxMF0gPSAoYTMwICogYjA0IC0gYTMxICogYjAyICsgYTMzICogYjAwKSAqIGRldDtcbiAgb3V0WzExXSA9IChhMjEgKiBiMDIgLSBhMjAgKiBiMDQgLSBhMjMgKiBiMDApICogZGV0O1xuICBvdXRbMTJdID0gKGExMSAqIGIwNyAtIGExMCAqIGIwOSAtIGExMiAqIGIwNikgKiBkZXQ7XG4gIG91dFsxM10gPSAoYTAwICogYjA5IC0gYTAxICogYjA3ICsgYTAyICogYjA2KSAqIGRldDtcbiAgb3V0WzE0XSA9IChhMzEgKiBiMDEgLSBhMzAgKiBiMDMgLSBhMzIgKiBiMDApICogZGV0O1xuICBvdXRbMTVdID0gKGEyMCAqIGIwMyAtIGEyMSAqIGIwMSArIGEyMiAqIGIwMCkgKiBkZXQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgYWRqdWdhdGUgb2YgYSBtYXQ0XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gYWRqb2ludChvdXQsIGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdLFxuICAgICAgYTExID0gYVs1XSxcbiAgICAgIGExMiA9IGFbNl0sXG4gICAgICBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XSxcbiAgICAgIGEyMSA9IGFbOV0sXG4gICAgICBhMjIgPSBhWzEwXSxcbiAgICAgIGEyMyA9IGFbMTFdO1xuICB2YXIgYTMwID0gYVsxMl0sXG4gICAgICBhMzEgPSBhWzEzXSxcbiAgICAgIGEzMiA9IGFbMTRdLFxuICAgICAgYTMzID0gYVsxNV07XG4gIG91dFswXSA9IGExMSAqIChhMjIgKiBhMzMgLSBhMjMgKiBhMzIpIC0gYTIxICogKGExMiAqIGEzMyAtIGExMyAqIGEzMikgKyBhMzEgKiAoYTEyICogYTIzIC0gYTEzICogYTIyKTtcbiAgb3V0WzFdID0gLShhMDEgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMSAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMxICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMikpO1xuICBvdXRbMl0gPSBhMDEgKiAoYTEyICogYTMzIC0gYTEzICogYTMyKSAtIGExMSAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMxICogKGEwMiAqIGExMyAtIGEwMyAqIGExMik7XG4gIG91dFszXSA9IC0oYTAxICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikgLSBhMTEgKiAoYTAyICogYTIzIC0gYTAzICogYTIyKSArIGEyMSAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpKTtcbiAgb3V0WzRdID0gLShhMTAgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMCAqIChhMTIgKiBhMzMgLSBhMTMgKiBhMzIpICsgYTMwICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikpO1xuICBvdXRbNV0gPSBhMDAgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMCAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMwICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMik7XG4gIG91dFs2XSA9IC0oYTAwICogKGExMiAqIGEzMyAtIGExMyAqIGEzMikgLSBhMTAgKiAoYTAyICogYTMzIC0gYTAzICogYTMyKSArIGEzMCAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpKTtcbiAgb3V0WzddID0gYTAwICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikgLSBhMTAgKiAoYTAyICogYTIzIC0gYTAzICogYTIyKSArIGEyMCAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpO1xuICBvdXRbOF0gPSBhMTAgKiAoYTIxICogYTMzIC0gYTIzICogYTMxKSAtIGEyMCAqIChhMTEgKiBhMzMgLSBhMTMgKiBhMzEpICsgYTMwICogKGExMSAqIGEyMyAtIGExMyAqIGEyMSk7XG4gIG91dFs5XSA9IC0oYTAwICogKGEyMSAqIGEzMyAtIGEyMyAqIGEzMSkgLSBhMjAgKiAoYTAxICogYTMzIC0gYTAzICogYTMxKSArIGEzMCAqIChhMDEgKiBhMjMgLSBhMDMgKiBhMjEpKTtcbiAgb3V0WzEwXSA9IGEwMCAqIChhMTEgKiBhMzMgLSBhMTMgKiBhMzEpIC0gYTEwICogKGEwMSAqIGEzMyAtIGEwMyAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTEzIC0gYTAzICogYTExKTtcbiAgb3V0WzExXSA9IC0oYTAwICogKGExMSAqIGEyMyAtIGExMyAqIGEyMSkgLSBhMTAgKiAoYTAxICogYTIzIC0gYTAzICogYTIxKSArIGEyMCAqIChhMDEgKiBhMTMgLSBhMDMgKiBhMTEpKTtcbiAgb3V0WzEyXSA9IC0oYTEwICogKGEyMSAqIGEzMiAtIGEyMiAqIGEzMSkgLSBhMjAgKiAoYTExICogYTMyIC0gYTEyICogYTMxKSArIGEzMCAqIChhMTEgKiBhMjIgLSBhMTIgKiBhMjEpKTtcbiAgb3V0WzEzXSA9IGEwMCAqIChhMjEgKiBhMzIgLSBhMjIgKiBhMzEpIC0gYTIwICogKGEwMSAqIGEzMiAtIGEwMiAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTIyIC0gYTAyICogYTIxKTtcbiAgb3V0WzE0XSA9IC0oYTAwICogKGExMSAqIGEzMiAtIGExMiAqIGEzMSkgLSBhMTAgKiAoYTAxICogYTMyIC0gYTAyICogYTMxKSArIGEzMCAqIChhMDEgKiBhMTIgLSBhMDIgKiBhMTEpKTtcbiAgb3V0WzE1XSA9IGEwMCAqIChhMTEgKiBhMjIgLSBhMTIgKiBhMjEpIC0gYTEwICogKGEwMSAqIGEyMiAtIGEwMiAqIGEyMSkgKyBhMjAgKiAoYTAxICogYTEyIC0gYTAyICogYTExKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBkZXRlcm1pbmFudCBvZiBhIG1hdDRcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcclxuICogQHJldHVybnMge051bWJlcn0gZGV0ZXJtaW5hbnQgb2YgYVxyXG4gKi9cblxuXG5mdW5jdGlvbiBkZXRlcm1pbmFudChhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XSxcbiAgICAgIGExMSA9IGFbNV0sXG4gICAgICBhMTIgPSBhWzZdLFxuICAgICAgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF0sXG4gICAgICBhMjEgPSBhWzldLFxuICAgICAgYTIyID0gYVsxMF0sXG4gICAgICBhMjMgPSBhWzExXTtcbiAgdmFyIGEzMCA9IGFbMTJdLFxuICAgICAgYTMxID0gYVsxM10sXG4gICAgICBhMzIgPSBhWzE0XSxcbiAgICAgIGEzMyA9IGFbMTVdO1xuICB2YXIgYjAwID0gYTAwICogYTExIC0gYTAxICogYTEwO1xuICB2YXIgYjAxID0gYTAwICogYTEyIC0gYTAyICogYTEwO1xuICB2YXIgYjAyID0gYTAwICogYTEzIC0gYTAzICogYTEwO1xuICB2YXIgYjAzID0gYTAxICogYTEyIC0gYTAyICogYTExO1xuICB2YXIgYjA0ID0gYTAxICogYTEzIC0gYTAzICogYTExO1xuICB2YXIgYjA1ID0gYTAyICogYTEzIC0gYTAzICogYTEyO1xuICB2YXIgYjA2ID0gYTIwICogYTMxIC0gYTIxICogYTMwO1xuICB2YXIgYjA3ID0gYTIwICogYTMyIC0gYTIyICogYTMwO1xuICB2YXIgYjA4ID0gYTIwICogYTMzIC0gYTIzICogYTMwO1xuICB2YXIgYjA5ID0gYTIxICogYTMyIC0gYTIyICogYTMxO1xuICB2YXIgYjEwID0gYTIxICogYTMzIC0gYTIzICogYTMxO1xuICB2YXIgYjExID0gYTIyICogYTMzIC0gYTIzICogYTMyOyAvLyBDYWxjdWxhdGUgdGhlIGRldGVybWluYW50XG5cbiAgcmV0dXJuIGIwMCAqIGIxMSAtIGIwMSAqIGIxMCArIGIwMiAqIGIwOSArIGIwMyAqIGIwOCAtIGIwNCAqIGIwNyArIGIwNSAqIGIwNjtcbn1cbi8qKlxyXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQ0c1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtdWx0aXBseShvdXQsIGEsIGIpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdLFxuICAgICAgYTExID0gYVs1XSxcbiAgICAgIGExMiA9IGFbNl0sXG4gICAgICBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XSxcbiAgICAgIGEyMSA9IGFbOV0sXG4gICAgICBhMjIgPSBhWzEwXSxcbiAgICAgIGEyMyA9IGFbMTFdO1xuICB2YXIgYTMwID0gYVsxMl0sXG4gICAgICBhMzEgPSBhWzEzXSxcbiAgICAgIGEzMiA9IGFbMTRdLFxuICAgICAgYTMzID0gYVsxNV07IC8vIENhY2hlIG9ubHkgdGhlIGN1cnJlbnQgbGluZSBvZiB0aGUgc2Vjb25kIG1hdHJpeFxuXG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl0sXG4gICAgICBiMyA9IGJbM107XG4gIG91dFswXSA9IGIwICogYTAwICsgYjEgKiBhMTAgKyBiMiAqIGEyMCArIGIzICogYTMwO1xuICBvdXRbMV0gPSBiMCAqIGEwMSArIGIxICogYTExICsgYjIgKiBhMjEgKyBiMyAqIGEzMTtcbiAgb3V0WzJdID0gYjAgKiBhMDIgKyBiMSAqIGExMiArIGIyICogYTIyICsgYjMgKiBhMzI7XG4gIG91dFszXSA9IGIwICogYTAzICsgYjEgKiBhMTMgKyBiMiAqIGEyMyArIGIzICogYTMzO1xuICBiMCA9IGJbNF07XG4gIGIxID0gYls1XTtcbiAgYjIgPSBiWzZdO1xuICBiMyA9IGJbN107XG4gIG91dFs0XSA9IGIwICogYTAwICsgYjEgKiBhMTAgKyBiMiAqIGEyMCArIGIzICogYTMwO1xuICBvdXRbNV0gPSBiMCAqIGEwMSArIGIxICogYTExICsgYjIgKiBhMjEgKyBiMyAqIGEzMTtcbiAgb3V0WzZdID0gYjAgKiBhMDIgKyBiMSAqIGExMiArIGIyICogYTIyICsgYjMgKiBhMzI7XG4gIG91dFs3XSA9IGIwICogYTAzICsgYjEgKiBhMTMgKyBiMiAqIGEyMyArIGIzICogYTMzO1xuICBiMCA9IGJbOF07XG4gIGIxID0gYls5XTtcbiAgYjIgPSBiWzEwXTtcbiAgYjMgPSBiWzExXTtcbiAgb3V0WzhdID0gYjAgKiBhMDAgKyBiMSAqIGExMCArIGIyICogYTIwICsgYjMgKiBhMzA7XG4gIG91dFs5XSA9IGIwICogYTAxICsgYjEgKiBhMTEgKyBiMiAqIGEyMSArIGIzICogYTMxO1xuICBvdXRbMTBdID0gYjAgKiBhMDIgKyBiMSAqIGExMiArIGIyICogYTIyICsgYjMgKiBhMzI7XG4gIG91dFsxMV0gPSBiMCAqIGEwMyArIGIxICogYTEzICsgYjIgKiBhMjMgKyBiMyAqIGEzMztcbiAgYjAgPSBiWzEyXTtcbiAgYjEgPSBiWzEzXTtcbiAgYjIgPSBiWzE0XTtcbiAgYjMgPSBiWzE1XTtcbiAgb3V0WzEyXSA9IGIwICogYTAwICsgYjEgKiBhMTAgKyBiMiAqIGEyMCArIGIzICogYTMwO1xuICBvdXRbMTNdID0gYjAgKiBhMDEgKyBiMSAqIGExMSArIGIyICogYTIxICsgYjMgKiBhMzE7XG4gIG91dFsxNF0gPSBiMCAqIGEwMiArIGIxICogYTEyICsgYjIgKiBhMjIgKyBiMyAqIGEzMjtcbiAgb3V0WzE1XSA9IGIwICogYTAzICsgYjEgKiBhMTMgKyBiMiAqIGEyMyArIGIzICogYTMzO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFRyYW5zbGF0ZSBhIG1hdDQgYnkgdGhlIGdpdmVuIHZlY3RvclxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHRyYW5zbGF0ZVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiB2ZWN0b3IgdG8gdHJhbnNsYXRlIGJ5XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNsYXRlKG91dCwgYSwgdikge1xuICB2YXIgeCA9IHZbMF0sXG4gICAgICB5ID0gdlsxXSxcbiAgICAgIHogPSB2WzJdO1xuICB2YXIgYTAwLCBhMDEsIGEwMiwgYTAzO1xuICB2YXIgYTEwLCBhMTEsIGExMiwgYTEzO1xuICB2YXIgYTIwLCBhMjEsIGEyMiwgYTIzO1xuXG4gIGlmIChhID09PSBvdXQpIHtcbiAgICBvdXRbMTJdID0gYVswXSAqIHggKyBhWzRdICogeSArIGFbOF0gKiB6ICsgYVsxMl07XG4gICAgb3V0WzEzXSA9IGFbMV0gKiB4ICsgYVs1XSAqIHkgKyBhWzldICogeiArIGFbMTNdO1xuICAgIG91dFsxNF0gPSBhWzJdICogeCArIGFbNl0gKiB5ICsgYVsxMF0gKiB6ICsgYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbM10gKiB4ICsgYVs3XSAqIHkgKyBhWzExXSAqIHogKyBhWzE1XTtcbiAgfSBlbHNlIHtcbiAgICBhMDAgPSBhWzBdO1xuICAgIGEwMSA9IGFbMV07XG4gICAgYTAyID0gYVsyXTtcbiAgICBhMDMgPSBhWzNdO1xuICAgIGExMCA9IGFbNF07XG4gICAgYTExID0gYVs1XTtcbiAgICBhMTIgPSBhWzZdO1xuICAgIGExMyA9IGFbN107XG4gICAgYTIwID0gYVs4XTtcbiAgICBhMjEgPSBhWzldO1xuICAgIGEyMiA9IGFbMTBdO1xuICAgIGEyMyA9IGFbMTFdO1xuICAgIG91dFswXSA9IGEwMDtcbiAgICBvdXRbMV0gPSBhMDE7XG4gICAgb3V0WzJdID0gYTAyO1xuICAgIG91dFszXSA9IGEwMztcbiAgICBvdXRbNF0gPSBhMTA7XG4gICAgb3V0WzVdID0gYTExO1xuICAgIG91dFs2XSA9IGExMjtcbiAgICBvdXRbN10gPSBhMTM7XG4gICAgb3V0WzhdID0gYTIwO1xuICAgIG91dFs5XSA9IGEyMTtcbiAgICBvdXRbMTBdID0gYTIyO1xuICAgIG91dFsxMV0gPSBhMjM7XG4gICAgb3V0WzEyXSA9IGEwMCAqIHggKyBhMTAgKiB5ICsgYTIwICogeiArIGFbMTJdO1xuICAgIG91dFsxM10gPSBhMDEgKiB4ICsgYTExICogeSArIGEyMSAqIHogKyBhWzEzXTtcbiAgICBvdXRbMTRdID0gYTAyICogeCArIGExMiAqIHkgKyBhMjIgKiB6ICsgYVsxNF07XG4gICAgb3V0WzE1XSA9IGEwMyAqIHggKyBhMTMgKiB5ICsgYTIzICogeiArIGFbMTVdO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTY2FsZXMgdGhlIG1hdDQgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzMgbm90IHVzaW5nIHZlY3Rvcml6YXRpb25cclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byBzY2FsZVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiB0aGUgdmVjMyB0byBzY2FsZSB0aGUgbWF0cml4IGJ5XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICoqL1xuXG5cbmZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgdikge1xuICB2YXIgeCA9IHZbMF0sXG4gICAgICB5ID0gdlsxXSxcbiAgICAgIHogPSB2WzJdO1xuICBvdXRbMF0gPSBhWzBdICogeDtcbiAgb3V0WzFdID0gYVsxXSAqIHg7XG4gIG91dFsyXSA9IGFbMl0gKiB4O1xuICBvdXRbM10gPSBhWzNdICogeDtcbiAgb3V0WzRdID0gYVs0XSAqIHk7XG4gIG91dFs1XSA9IGFbNV0gKiB5O1xuICBvdXRbNl0gPSBhWzZdICogeTtcbiAgb3V0WzddID0gYVs3XSAqIHk7XG4gIG91dFs4XSA9IGFbOF0gKiB6O1xuICBvdXRbOV0gPSBhWzldICogejtcbiAgb3V0WzEwXSA9IGFbMTBdICogejtcbiAgb3V0WzExXSA9IGFbMTFdICogejtcbiAgb3V0WzEyXSA9IGFbMTJdO1xuICBvdXRbMTNdID0gYVsxM107XG4gIG91dFsxNF0gPSBhWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBtYXQ0IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIGdpdmVuIGF4aXNcclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcclxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGF4aXMgdGhlIGF4aXMgdG8gcm90YXRlIGFyb3VuZFxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZShvdXQsIGEsIHJhZCwgYXhpcykge1xuICB2YXIgeCA9IGF4aXNbMF0sXG4gICAgICB5ID0gYXhpc1sxXSxcbiAgICAgIHogPSBheGlzWzJdO1xuICB2YXIgbGVuID0gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbiAgdmFyIHMsIGMsIHQ7XG4gIHZhciBhMDAsIGEwMSwgYTAyLCBhMDM7XG4gIHZhciBhMTAsIGExMSwgYTEyLCBhMTM7XG4gIHZhciBhMjAsIGEyMSwgYTIyLCBhMjM7XG4gIHZhciBiMDAsIGIwMSwgYjAyO1xuICB2YXIgYjEwLCBiMTEsIGIxMjtcbiAgdmFyIGIyMCwgYjIxLCBiMjI7XG5cbiAgaWYgKGxlbiA8IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxlbiA9IDEgLyBsZW47XG4gIHggKj0gbGVuO1xuICB5ICo9IGxlbjtcbiAgeiAqPSBsZW47XG4gIHMgPSBNYXRoLnNpbihyYWQpO1xuICBjID0gTWF0aC5jb3MocmFkKTtcbiAgdCA9IDEgLSBjO1xuICBhMDAgPSBhWzBdO1xuICBhMDEgPSBhWzFdO1xuICBhMDIgPSBhWzJdO1xuICBhMDMgPSBhWzNdO1xuICBhMTAgPSBhWzRdO1xuICBhMTEgPSBhWzVdO1xuICBhMTIgPSBhWzZdO1xuICBhMTMgPSBhWzddO1xuICBhMjAgPSBhWzhdO1xuICBhMjEgPSBhWzldO1xuICBhMjIgPSBhWzEwXTtcbiAgYTIzID0gYVsxMV07IC8vIENvbnN0cnVjdCB0aGUgZWxlbWVudHMgb2YgdGhlIHJvdGF0aW9uIG1hdHJpeFxuXG4gIGIwMCA9IHggKiB4ICogdCArIGM7XG4gIGIwMSA9IHkgKiB4ICogdCArIHogKiBzO1xuICBiMDIgPSB6ICogeCAqIHQgLSB5ICogcztcbiAgYjEwID0geCAqIHkgKiB0IC0geiAqIHM7XG4gIGIxMSA9IHkgKiB5ICogdCArIGM7XG4gIGIxMiA9IHogKiB5ICogdCArIHggKiBzO1xuICBiMjAgPSB4ICogeiAqIHQgKyB5ICogcztcbiAgYjIxID0geSAqIHogKiB0IC0geCAqIHM7XG4gIGIyMiA9IHogKiB6ICogdCArIGM7IC8vIFBlcmZvcm0gcm90YXRpb24tc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cbiAgb3V0WzBdID0gYTAwICogYjAwICsgYTEwICogYjAxICsgYTIwICogYjAyO1xuICBvdXRbMV0gPSBhMDEgKiBiMDAgKyBhMTEgKiBiMDEgKyBhMjEgKiBiMDI7XG4gIG91dFsyXSA9IGEwMiAqIGIwMCArIGExMiAqIGIwMSArIGEyMiAqIGIwMjtcbiAgb3V0WzNdID0gYTAzICogYjAwICsgYTEzICogYjAxICsgYTIzICogYjAyO1xuICBvdXRbNF0gPSBhMDAgKiBiMTAgKyBhMTAgKiBiMTEgKyBhMjAgKiBiMTI7XG4gIG91dFs1XSA9IGEwMSAqIGIxMCArIGExMSAqIGIxMSArIGEyMSAqIGIxMjtcbiAgb3V0WzZdID0gYTAyICogYjEwICsgYTEyICogYjExICsgYTIyICogYjEyO1xuICBvdXRbN10gPSBhMDMgKiBiMTAgKyBhMTMgKiBiMTEgKyBhMjMgKiBiMTI7XG4gIG91dFs4XSA9IGEwMCAqIGIyMCArIGExMCAqIGIyMSArIGEyMCAqIGIyMjtcbiAgb3V0WzldID0gYTAxICogYjIwICsgYTExICogYjIxICsgYTIxICogYjIyO1xuICBvdXRbMTBdID0gYTAyICogYjIwICsgYTEyICogYjIxICsgYTIyICogYjIyO1xuICBvdXRbMTFdID0gYTAzICogYjIwICsgYTEzICogYjIxICsgYTIzICogYjIyO1xuXG4gIGlmIChhICE9PSBvdXQpIHtcbiAgICAvLyBJZiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkaWZmZXIsIGNvcHkgdGhlIHVuY2hhbmdlZCBsYXN0IHJvd1xuICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUm90YXRlcyBhIG1hdHJpeCBieSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBYIGF4aXNcclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcclxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGVYKG91dCwgYSwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpO1xuICB2YXIgYTEwID0gYVs0XTtcbiAgdmFyIGExMSA9IGFbNV07XG4gIHZhciBhMTIgPSBhWzZdO1xuICB2YXIgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF07XG4gIHZhciBhMjEgPSBhWzldO1xuICB2YXIgYTIyID0gYVsxMF07XG4gIHZhciBhMjMgPSBhWzExXTtcblxuICBpZiAoYSAhPT0gb3V0KSB7XG4gICAgLy8gSWYgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gZGlmZmVyLCBjb3B5IHRoZSB1bmNoYW5nZWQgcm93c1xuICAgIG91dFswXSA9IGFbMF07XG4gICAgb3V0WzFdID0gYVsxXTtcbiAgICBvdXRbMl0gPSBhWzJdO1xuICAgIG91dFszXSA9IGFbM107XG4gICAgb3V0WzEyXSA9IGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbMTVdO1xuICB9IC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuXG4gIG91dFs0XSA9IGExMCAqIGMgKyBhMjAgKiBzO1xuICBvdXRbNV0gPSBhMTEgKiBjICsgYTIxICogcztcbiAgb3V0WzZdID0gYTEyICogYyArIGEyMiAqIHM7XG4gIG91dFs3XSA9IGExMyAqIGMgKyBhMjMgKiBzO1xuICBvdXRbOF0gPSBhMjAgKiBjIC0gYTEwICogcztcbiAgb3V0WzldID0gYTIxICogYyAtIGExMSAqIHM7XG4gIG91dFsxMF0gPSBhMjIgKiBjIC0gYTEyICogcztcbiAgb3V0WzExXSA9IGEyMyAqIGMgLSBhMTMgKiBzO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBtYXRyaXggYnkgdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWSBheGlzXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gcm90YXRlWShvdXQsIGEsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTtcbiAgdmFyIGEwMCA9IGFbMF07XG4gIHZhciBhMDEgPSBhWzFdO1xuICB2YXIgYTAyID0gYVsyXTtcbiAgdmFyIGEwMyA9IGFbM107XG4gIHZhciBhMjAgPSBhWzhdO1xuICB2YXIgYTIxID0gYVs5XTtcbiAgdmFyIGEyMiA9IGFbMTBdO1xuICB2YXIgYTIzID0gYVsxMV07XG5cbiAgaWYgKGEgIT09IG91dCkge1xuICAgIC8vIElmIHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGRpZmZlciwgY29weSB0aGUgdW5jaGFuZ2VkIHJvd3NcbiAgICBvdXRbNF0gPSBhWzRdO1xuICAgIG91dFs1XSA9IGFbNV07XG4gICAgb3V0WzZdID0gYVs2XTtcbiAgICBvdXRbN10gPSBhWzddO1xuICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgfSAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cblxuICBvdXRbMF0gPSBhMDAgKiBjIC0gYTIwICogcztcbiAgb3V0WzFdID0gYTAxICogYyAtIGEyMSAqIHM7XG4gIG91dFsyXSA9IGEwMiAqIGMgLSBhMjIgKiBzO1xuICBvdXRbM10gPSBhMDMgKiBjIC0gYTIzICogcztcbiAgb3V0WzhdID0gYTAwICogcyArIGEyMCAqIGM7XG4gIG91dFs5XSA9IGEwMSAqIHMgKyBhMjEgKiBjO1xuICBvdXRbMTBdID0gYTAyICogcyArIGEyMiAqIGM7XG4gIG91dFsxMV0gPSBhMDMgKiBzICsgYTIzICogYztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSb3RhdGVzIGEgbWF0cml4IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFogYXhpc1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZVoob3V0LCBhLCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7XG4gIHZhciBhMDAgPSBhWzBdO1xuICB2YXIgYTAxID0gYVsxXTtcbiAgdmFyIGEwMiA9IGFbMl07XG4gIHZhciBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XTtcbiAgdmFyIGExMSA9IGFbNV07XG4gIHZhciBhMTIgPSBhWzZdO1xuICB2YXIgYTEzID0gYVs3XTtcblxuICBpZiAoYSAhPT0gb3V0KSB7XG4gICAgLy8gSWYgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gZGlmZmVyLCBjb3B5IHRoZSB1bmNoYW5nZWQgbGFzdCByb3dcbiAgICBvdXRbOF0gPSBhWzhdO1xuICAgIG91dFs5XSA9IGFbOV07XG4gICAgb3V0WzEwXSA9IGFbMTBdO1xuICAgIG91dFsxMV0gPSBhWzExXTtcbiAgICBvdXRbMTJdID0gYVsxMl07XG4gICAgb3V0WzEzXSA9IGFbMTNdO1xuICAgIG91dFsxNF0gPSBhWzE0XTtcbiAgICBvdXRbMTVdID0gYVsxNV07XG4gIH0gLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG5cbiAgb3V0WzBdID0gYTAwICogYyArIGExMCAqIHM7XG4gIG91dFsxXSA9IGEwMSAqIGMgKyBhMTEgKiBzO1xuICBvdXRbMl0gPSBhMDIgKiBjICsgYTEyICogcztcbiAgb3V0WzNdID0gYTAzICogYyArIGExMyAqIHM7XG4gIG91dFs0XSA9IGExMCAqIGMgLSBhMDAgKiBzO1xuICBvdXRbNV0gPSBhMTEgKiBjIC0gYTAxICogcztcbiAgb3V0WzZdID0gYTEyICogYyAtIGEwMiAqIHM7XG4gIG91dFs3XSA9IGExMyAqIGMgLSBhMDMgKiBzO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciB0cmFuc2xhdGlvblxyXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcclxuICpcclxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XHJcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCBkZXN0LCB2ZWMpO1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21UcmFuc2xhdGlvbihvdXQsIHYpIHtcbiAgb3V0WzBdID0gMTtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gMTtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzEwXSA9IDE7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gdlswXTtcbiAgb3V0WzEzXSA9IHZbMV07XG4gIG91dFsxNF0gPSB2WzJdO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3Igc2NhbGluZ1xyXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcclxuICpcclxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XHJcbiAqICAgICBtYXQ0LnNjYWxlKGRlc3QsIGRlc3QsIHZlYyk7XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHYgU2NhbGluZyB2ZWN0b3JcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tU2NhbGluZyhvdXQsIHYpIHtcbiAgb3V0WzBdID0gdlswXTtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gdlsxXTtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzEwXSA9IHZbMl07XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNF0gPSAwO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZSBhcm91bmQgYSBnaXZlbiBheGlzXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcclxuICogICAgIG1hdDQucm90YXRlKGRlc3QsIGRlc3QsIHJhZCwgYXhpcyk7XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGF4aXMgdGhlIGF4aXMgdG8gcm90YXRlIGFyb3VuZFxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21Sb3RhdGlvbihvdXQsIHJhZCwgYXhpcykge1xuICB2YXIgeCA9IGF4aXNbMF0sXG4gICAgICB5ID0gYXhpc1sxXSxcbiAgICAgIHogPSBheGlzWzJdO1xuICB2YXIgbGVuID0gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbiAgdmFyIHMsIGMsIHQ7XG5cbiAgaWYgKGxlbiA8IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxlbiA9IDEgLyBsZW47XG4gIHggKj0gbGVuO1xuICB5ICo9IGxlbjtcbiAgeiAqPSBsZW47XG4gIHMgPSBNYXRoLnNpbihyYWQpO1xuICBjID0gTWF0aC5jb3MocmFkKTtcbiAgdCA9IDEgLSBjOyAvLyBQZXJmb3JtIHJvdGF0aW9uLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG4gIG91dFswXSA9IHggKiB4ICogdCArIGM7XG4gIG91dFsxXSA9IHkgKiB4ICogdCArIHogKiBzO1xuICBvdXRbMl0gPSB6ICogeCAqIHQgLSB5ICogcztcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0geCAqIHkgKiB0IC0geiAqIHM7XG4gIG91dFs1XSA9IHkgKiB5ICogdCArIGM7XG4gIG91dFs2XSA9IHogKiB5ICogdCArIHggKiBzO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB4ICogeiAqIHQgKyB5ICogcztcbiAgb3V0WzldID0geSAqIHogKiB0IC0geCAqIHM7XG4gIG91dFsxMF0gPSB6ICogeiAqIHQgKyBjO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFggYXhpc1xyXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcclxuICpcclxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XHJcbiAqICAgICBtYXQ0LnJvdGF0ZVgoZGVzdCwgZGVzdCwgcmFkKTtcclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21YUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7IC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSBjO1xuICBvdXRbNl0gPSBzO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAtcztcbiAgb3V0WzEwXSA9IGM7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNF0gPSAwO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWSBheGlzXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcclxuICogICAgIG1hdDQucm90YXRlWShkZXN0LCBkZXN0LCByYWQpO1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVlSb3RhdGlvbihvdXQsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTsgLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IC1zO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAxO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSBzO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gYztcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBaIGF4aXNcclxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XHJcbiAqXHJcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xyXG4gKiAgICAgbWF0NC5yb3RhdGVaKGRlc3QsIGRlc3QsIHJhZCk7XHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tWlJvdGF0aW9uKG91dCwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpOyAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cbiAgb3V0WzBdID0gYztcbiAgb3V0WzFdID0gcztcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gLXM7XG4gIG91dFs1XSA9IGM7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDA7XG4gIG91dFs5XSA9IDA7XG4gIG91dFsxMF0gPSAxO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgcXVhdGVybmlvbiByb3RhdGlvbiBhbmQgdmVjdG9yIHRyYW5zbGF0aW9uXHJcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxyXG4gKlxyXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcclxuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIHZlYyk7XHJcbiAqICAgICBsZXQgcXVhdE1hdCA9IG1hdDQuY3JlYXRlKCk7XHJcbiAqICAgICBxdWF0NC50b01hdDQocXVhdCwgcXVhdE1hdCk7XHJcbiAqICAgICBtYXQ0Lm11bHRpcGx5KGRlc3QsIHF1YXRNYXQpO1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUm90YXRpb25UcmFuc2xhdGlvbihvdXQsIHEsIHYpIHtcbiAgLy8gUXVhdGVybmlvbiBtYXRoXG4gIHZhciB4ID0gcVswXSxcbiAgICAgIHkgPSBxWzFdLFxuICAgICAgeiA9IHFbMl0sXG4gICAgICB3ID0gcVszXTtcbiAgdmFyIHgyID0geCArIHg7XG4gIHZhciB5MiA9IHkgKyB5O1xuICB2YXIgejIgPSB6ICsgejtcbiAgdmFyIHh4ID0geCAqIHgyO1xuICB2YXIgeHkgPSB4ICogeTI7XG4gIHZhciB4eiA9IHggKiB6MjtcbiAgdmFyIHl5ID0geSAqIHkyO1xuICB2YXIgeXogPSB5ICogejI7XG4gIHZhciB6eiA9IHogKiB6MjtcbiAgdmFyIHd4ID0gdyAqIHgyO1xuICB2YXIgd3kgPSB3ICogeTI7XG4gIHZhciB3eiA9IHcgKiB6MjtcbiAgb3V0WzBdID0gMSAtICh5eSArIHp6KTtcbiAgb3V0WzFdID0geHkgKyB3ejtcbiAgb3V0WzJdID0geHogLSB3eTtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0geHkgLSB3ejtcbiAgb3V0WzVdID0gMSAtICh4eCArIHp6KTtcbiAgb3V0WzZdID0geXogKyB3eDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0geHogKyB3eTtcbiAgb3V0WzldID0geXogLSB3eDtcbiAgb3V0WzEwXSA9IDEgLSAoeHggKyB5eSk7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gdlswXTtcbiAgb3V0WzEzXSA9IHZbMV07XG4gIG91dFsxNF0gPSB2WzJdO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IG1hdDQgZnJvbSBhIGR1YWwgcXVhdC5cclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgTWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBEdWFsIFF1YXRlcm5pb25cclxuICogQHJldHVybnMge21hdDR9IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVF1YXQyKG91dCwgYSkge1xuICB2YXIgdHJhbnNsYXRpb24gPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcbiAgdmFyIGJ4ID0gLWFbMF0sXG4gICAgICBieSA9IC1hWzFdLFxuICAgICAgYnogPSAtYVsyXSxcbiAgICAgIGJ3ID0gYVszXSxcbiAgICAgIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XTtcbiAgdmFyIG1hZ25pdHVkZSA9IGJ4ICogYnggKyBieSAqIGJ5ICsgYnogKiBieiArIGJ3ICogYnc7IC8vT25seSBzY2FsZSBpZiBpdCBtYWtlcyBzZW5zZVxuXG4gIGlmIChtYWduaXR1ZGUgPiAwKSB7XG4gICAgdHJhbnNsYXRpb25bMF0gPSAoYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieSkgKiAyIC8gbWFnbml0dWRlO1xuICAgIHRyYW5zbGF0aW9uWzFdID0gKGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnopICogMiAvIG1hZ25pdHVkZTtcbiAgICB0cmFuc2xhdGlvblsyXSA9IChheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4KSAqIDIgLyBtYWduaXR1ZGU7XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNsYXRpb25bMF0gPSAoYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieSkgKiAyO1xuICAgIHRyYW5zbGF0aW9uWzFdID0gKGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnopICogMjtcbiAgICB0cmFuc2xhdGlvblsyXSA9IChheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4KSAqIDI7XG4gIH1cblxuICBmcm9tUm90YXRpb25UcmFuc2xhdGlvbihvdXQsIGEsIHRyYW5zbGF0aW9uKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiB2ZWN0b3IgY29tcG9uZW50IG9mIGEgdHJhbnNmb3JtYXRpb25cclxuICogIG1hdHJpeC4gSWYgYSBtYXRyaXggaXMgYnVpbHQgd2l0aCBmcm9tUm90YXRpb25UcmFuc2xhdGlvbixcclxuICogIHRoZSByZXR1cm5lZCB2ZWN0b3Igd2lsbCBiZSB0aGUgc2FtZSBhcyB0aGUgdHJhbnNsYXRpb24gdmVjdG9yXHJcbiAqICBvcmlnaW5hbGx5IHN1cHBsaWVkLlxyXG4gKiBAcGFyYW0gIHt2ZWMzfSBvdXQgVmVjdG9yIHRvIHJlY2VpdmUgdHJhbnNsYXRpb24gY29tcG9uZW50XHJcbiAqIEBwYXJhbSAge1JlYWRvbmx5TWF0NH0gbWF0IE1hdHJpeCB0byBiZSBkZWNvbXBvc2VkIChpbnB1dClcclxuICogQHJldHVybiB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGdldFRyYW5zbGF0aW9uKG91dCwgbWF0KSB7XG4gIG91dFswXSA9IG1hdFsxMl07XG4gIG91dFsxXSA9IG1hdFsxM107XG4gIG91dFsyXSA9IG1hdFsxNF07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyB0aGUgc2NhbGluZyBmYWN0b3IgY29tcG9uZW50IG9mIGEgdHJhbnNmb3JtYXRpb25cclxuICogIG1hdHJpeC4gSWYgYSBtYXRyaXggaXMgYnVpbHQgd2l0aCBmcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlXHJcbiAqICB3aXRoIGEgbm9ybWFsaXplZCBRdWF0ZXJuaW9uIHBhcmFtdGVyLCB0aGUgcmV0dXJuZWQgdmVjdG9yIHdpbGwgYmVcclxuICogIHRoZSBzYW1lIGFzIHRoZSBzY2FsaW5nIHZlY3RvclxyXG4gKiAgb3JpZ2luYWxseSBzdXBwbGllZC5cclxuICogQHBhcmFtICB7dmVjM30gb3V0IFZlY3RvciB0byByZWNlaXZlIHNjYWxpbmcgZmFjdG9yIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0gIHtSZWFkb25seU1hdDR9IG1hdCBNYXRyaXggdG8gYmUgZGVjb21wb3NlZCAoaW5wdXQpXHJcbiAqIEByZXR1cm4ge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRTY2FsaW5nKG91dCwgbWF0KSB7XG4gIHZhciBtMTEgPSBtYXRbMF07XG4gIHZhciBtMTIgPSBtYXRbMV07XG4gIHZhciBtMTMgPSBtYXRbMl07XG4gIHZhciBtMjEgPSBtYXRbNF07XG4gIHZhciBtMjIgPSBtYXRbNV07XG4gIHZhciBtMjMgPSBtYXRbNl07XG4gIHZhciBtMzEgPSBtYXRbOF07XG4gIHZhciBtMzIgPSBtYXRbOV07XG4gIHZhciBtMzMgPSBtYXRbMTBdO1xuICBvdXRbMF0gPSBNYXRoLmh5cG90KG0xMSwgbTEyLCBtMTMpO1xuICBvdXRbMV0gPSBNYXRoLmh5cG90KG0yMSwgbTIyLCBtMjMpO1xuICBvdXRbMl0gPSBNYXRoLmh5cG90KG0zMSwgbTMyLCBtMzMpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBxdWF0ZXJuaW9uIHJlcHJlc2VudGluZyB0aGUgcm90YXRpb25hbCBjb21wb25lbnRcclxuICogIG9mIGEgdHJhbnNmb3JtYXRpb24gbWF0cml4LiBJZiBhIG1hdHJpeCBpcyBidWlsdCB3aXRoXHJcbiAqICBmcm9tUm90YXRpb25UcmFuc2xhdGlvbiwgdGhlIHJldHVybmVkIHF1YXRlcm5pb24gd2lsbCBiZSB0aGVcclxuICogIHNhbWUgYXMgdGhlIHF1YXRlcm5pb24gb3JpZ2luYWxseSBzdXBwbGllZC5cclxuICogQHBhcmFtIHtxdWF0fSBvdXQgUXVhdGVybmlvbiB0byByZWNlaXZlIHRoZSByb3RhdGlvbiBjb21wb25lbnRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IG1hdCBNYXRyaXggdG8gYmUgZGVjb21wb3NlZCAoaW5wdXQpXHJcbiAqIEByZXR1cm4ge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRSb3RhdGlvbihvdXQsIG1hdCkge1xuICB2YXIgc2NhbGluZyA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDMpO1xuICBnZXRTY2FsaW5nKHNjYWxpbmcsIG1hdCk7XG4gIHZhciBpczEgPSAxIC8gc2NhbGluZ1swXTtcbiAgdmFyIGlzMiA9IDEgLyBzY2FsaW5nWzFdO1xuICB2YXIgaXMzID0gMSAvIHNjYWxpbmdbMl07XG4gIHZhciBzbTExID0gbWF0WzBdICogaXMxO1xuICB2YXIgc20xMiA9IG1hdFsxXSAqIGlzMjtcbiAgdmFyIHNtMTMgPSBtYXRbMl0gKiBpczM7XG4gIHZhciBzbTIxID0gbWF0WzRdICogaXMxO1xuICB2YXIgc20yMiA9IG1hdFs1XSAqIGlzMjtcbiAgdmFyIHNtMjMgPSBtYXRbNl0gKiBpczM7XG4gIHZhciBzbTMxID0gbWF0WzhdICogaXMxO1xuICB2YXIgc20zMiA9IG1hdFs5XSAqIGlzMjtcbiAgdmFyIHNtMzMgPSBtYXRbMTBdICogaXMzO1xuICB2YXIgdHJhY2UgPSBzbTExICsgc20yMiArIHNtMzM7XG4gIHZhciBTID0gMDtcblxuICBpZiAodHJhY2UgPiAwKSB7XG4gICAgUyA9IE1hdGguc3FydCh0cmFjZSArIDEuMCkgKiAyO1xuICAgIG91dFszXSA9IDAuMjUgKiBTO1xuICAgIG91dFswXSA9IChzbTIzIC0gc20zMikgLyBTO1xuICAgIG91dFsxXSA9IChzbTMxIC0gc20xMykgLyBTO1xuICAgIG91dFsyXSA9IChzbTEyIC0gc20yMSkgLyBTO1xuICB9IGVsc2UgaWYgKHNtMTEgPiBzbTIyICYmIHNtMTEgPiBzbTMzKSB7XG4gICAgUyA9IE1hdGguc3FydCgxLjAgKyBzbTExIC0gc20yMiAtIHNtMzMpICogMjtcbiAgICBvdXRbM10gPSAoc20yMyAtIHNtMzIpIC8gUztcbiAgICBvdXRbMF0gPSAwLjI1ICogUztcbiAgICBvdXRbMV0gPSAoc20xMiArIHNtMjEpIC8gUztcbiAgICBvdXRbMl0gPSAoc20zMSArIHNtMTMpIC8gUztcbiAgfSBlbHNlIGlmIChzbTIyID4gc20zMykge1xuICAgIFMgPSBNYXRoLnNxcnQoMS4wICsgc20yMiAtIHNtMTEgLSBzbTMzKSAqIDI7XG4gICAgb3V0WzNdID0gKHNtMzEgLSBzbTEzKSAvIFM7XG4gICAgb3V0WzBdID0gKHNtMTIgKyBzbTIxKSAvIFM7XG4gICAgb3V0WzFdID0gMC4yNSAqIFM7XG4gICAgb3V0WzJdID0gKHNtMjMgKyBzbTMyKSAvIFM7XG4gIH0gZWxzZSB7XG4gICAgUyA9IE1hdGguc3FydCgxLjAgKyBzbTMzIC0gc20xMSAtIHNtMjIpICogMjtcbiAgICBvdXRbM10gPSAoc20xMiAtIHNtMjEpIC8gUztcbiAgICBvdXRbMF0gPSAoc20zMSArIHNtMTMpIC8gUztcbiAgICBvdXRbMV0gPSAoc20yMyArIHNtMzIpIC8gUztcbiAgICBvdXRbMl0gPSAwLjI1ICogUztcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgcXVhdGVybmlvbiByb3RhdGlvbiwgdmVjdG9yIHRyYW5zbGF0aW9uIGFuZCB2ZWN0b3Igc2NhbGVcclxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XHJcbiAqXHJcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xyXG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgdmVjKTtcclxuICogICAgIGxldCBxdWF0TWF0ID0gbWF0NC5jcmVhdGUoKTtcclxuICogICAgIHF1YXQ0LnRvTWF0NChxdWF0LCBxdWF0TWF0KTtcclxuICogICAgIG1hdDQubXVsdGlwbHkoZGVzdCwgcXVhdE1hdCk7XHJcbiAqICAgICBtYXQ0LnNjYWxlKGRlc3QsIHNjYWxlKVxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHMgU2NhbGluZyB2ZWN0b3JcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlKG91dCwgcSwgdiwgcykge1xuICAvLyBRdWF0ZXJuaW9uIG1hdGhcbiAgdmFyIHggPSBxWzBdLFxuICAgICAgeSA9IHFbMV0sXG4gICAgICB6ID0gcVsyXSxcbiAgICAgIHcgPSBxWzNdO1xuICB2YXIgeDIgPSB4ICsgeDtcbiAgdmFyIHkyID0geSArIHk7XG4gIHZhciB6MiA9IHogKyB6O1xuICB2YXIgeHggPSB4ICogeDI7XG4gIHZhciB4eSA9IHggKiB5MjtcbiAgdmFyIHh6ID0geCAqIHoyO1xuICB2YXIgeXkgPSB5ICogeTI7XG4gIHZhciB5eiA9IHkgKiB6MjtcbiAgdmFyIHp6ID0geiAqIHoyO1xuICB2YXIgd3ggPSB3ICogeDI7XG4gIHZhciB3eSA9IHcgKiB5MjtcbiAgdmFyIHd6ID0gdyAqIHoyO1xuICB2YXIgc3ggPSBzWzBdO1xuICB2YXIgc3kgPSBzWzFdO1xuICB2YXIgc3ogPSBzWzJdO1xuICBvdXRbMF0gPSAoMSAtICh5eSArIHp6KSkgKiBzeDtcbiAgb3V0WzFdID0gKHh5ICsgd3opICogc3g7XG4gIG91dFsyXSA9ICh4eiAtIHd5KSAqIHN4O1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAoeHkgLSB3eikgKiBzeTtcbiAgb3V0WzVdID0gKDEgLSAoeHggKyB6eikpICogc3k7XG4gIG91dFs2XSA9ICh5eiArIHd4KSAqIHN5O1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAoeHogKyB3eSkgKiBzejtcbiAgb3V0WzldID0gKHl6IC0gd3gpICogc3o7XG4gIG91dFsxMF0gPSAoMSAtICh4eCArIHl5KSkgKiBzejtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSB2WzBdO1xuICBvdXRbMTNdID0gdlsxXTtcbiAgb3V0WzE0XSA9IHZbMl07XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHF1YXRlcm5pb24gcm90YXRpb24sIHZlY3RvciB0cmFuc2xhdGlvbiBhbmQgdmVjdG9yIHNjYWxlLCByb3RhdGluZyBhbmQgc2NhbGluZyBhcm91bmQgdGhlIGdpdmVuIG9yaWdpblxyXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcclxuICpcclxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XHJcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCB2ZWMpO1xyXG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgb3JpZ2luKTtcclxuICogICAgIGxldCBxdWF0TWF0ID0gbWF0NC5jcmVhdGUoKTtcclxuICogICAgIHF1YXQ0LnRvTWF0NChxdWF0LCBxdWF0TWF0KTtcclxuICogICAgIG1hdDQubXVsdGlwbHkoZGVzdCwgcXVhdE1hdCk7XHJcbiAqICAgICBtYXQ0LnNjYWxlKGRlc3QsIHNjYWxlKVxyXG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgbmVnYXRpdmVPcmlnaW4pO1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHMgU2NhbGluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IG8gVGhlIG9yaWdpbiB2ZWN0b3IgYXJvdW5kIHdoaWNoIHRvIHNjYWxlIGFuZCByb3RhdGVcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlT3JpZ2luKG91dCwgcSwgdiwgcywgbykge1xuICAvLyBRdWF0ZXJuaW9uIG1hdGhcbiAgdmFyIHggPSBxWzBdLFxuICAgICAgeSA9IHFbMV0sXG4gICAgICB6ID0gcVsyXSxcbiAgICAgIHcgPSBxWzNdO1xuICB2YXIgeDIgPSB4ICsgeDtcbiAgdmFyIHkyID0geSArIHk7XG4gIHZhciB6MiA9IHogKyB6O1xuICB2YXIgeHggPSB4ICogeDI7XG4gIHZhciB4eSA9IHggKiB5MjtcbiAgdmFyIHh6ID0geCAqIHoyO1xuICB2YXIgeXkgPSB5ICogeTI7XG4gIHZhciB5eiA9IHkgKiB6MjtcbiAgdmFyIHp6ID0geiAqIHoyO1xuICB2YXIgd3ggPSB3ICogeDI7XG4gIHZhciB3eSA9IHcgKiB5MjtcbiAgdmFyIHd6ID0gdyAqIHoyO1xuICB2YXIgc3ggPSBzWzBdO1xuICB2YXIgc3kgPSBzWzFdO1xuICB2YXIgc3ogPSBzWzJdO1xuICB2YXIgb3ggPSBvWzBdO1xuICB2YXIgb3kgPSBvWzFdO1xuICB2YXIgb3ogPSBvWzJdO1xuICB2YXIgb3V0MCA9ICgxIC0gKHl5ICsgenopKSAqIHN4O1xuICB2YXIgb3V0MSA9ICh4eSArIHd6KSAqIHN4O1xuICB2YXIgb3V0MiA9ICh4eiAtIHd5KSAqIHN4O1xuICB2YXIgb3V0NCA9ICh4eSAtIHd6KSAqIHN5O1xuICB2YXIgb3V0NSA9ICgxIC0gKHh4ICsgenopKSAqIHN5O1xuICB2YXIgb3V0NiA9ICh5eiArIHd4KSAqIHN5O1xuICB2YXIgb3V0OCA9ICh4eiArIHd5KSAqIHN6O1xuICB2YXIgb3V0OSA9ICh5eiAtIHd4KSAqIHN6O1xuICB2YXIgb3V0MTAgPSAoMSAtICh4eCArIHl5KSkgKiBzejtcbiAgb3V0WzBdID0gb3V0MDtcbiAgb3V0WzFdID0gb3V0MTtcbiAgb3V0WzJdID0gb3V0MjtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gb3V0NDtcbiAgb3V0WzVdID0gb3V0NTtcbiAgb3V0WzZdID0gb3V0NjtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gb3V0ODtcbiAgb3V0WzldID0gb3V0OTtcbiAgb3V0WzEwXSA9IG91dDEwO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IHZbMF0gKyBveCAtIChvdXQwICogb3ggKyBvdXQ0ICogb3kgKyBvdXQ4ICogb3opO1xuICBvdXRbMTNdID0gdlsxXSArIG95IC0gKG91dDEgKiBveCArIG91dDUgKiBveSArIG91dDkgKiBveik7XG4gIG91dFsxNF0gPSB2WzJdICsgb3ogLSAob3V0MiAqIG94ICsgb3V0NiAqIG95ICsgb3V0MTAgKiBveik7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgYSA0eDQgbWF0cml4IGZyb20gdGhlIGdpdmVuIHF1YXRlcm5pb25cclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBRdWF0ZXJuaW9uIHRvIGNyZWF0ZSBtYXRyaXggZnJvbVxyXG4gKlxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21RdWF0KG91dCwgcSkge1xuICB2YXIgeCA9IHFbMF0sXG4gICAgICB5ID0gcVsxXSxcbiAgICAgIHogPSBxWzJdLFxuICAgICAgdyA9IHFbM107XG4gIHZhciB4MiA9IHggKyB4O1xuICB2YXIgeTIgPSB5ICsgeTtcbiAgdmFyIHoyID0geiArIHo7XG4gIHZhciB4eCA9IHggKiB4MjtcbiAgdmFyIHl4ID0geSAqIHgyO1xuICB2YXIgeXkgPSB5ICogeTI7XG4gIHZhciB6eCA9IHogKiB4MjtcbiAgdmFyIHp5ID0geiAqIHkyO1xuICB2YXIgenogPSB6ICogejI7XG4gIHZhciB3eCA9IHcgKiB4MjtcbiAgdmFyIHd5ID0gdyAqIHkyO1xuICB2YXIgd3ogPSB3ICogejI7XG4gIG91dFswXSA9IDEgLSB5eSAtIHp6O1xuICBvdXRbMV0gPSB5eCArIHd6O1xuICBvdXRbMl0gPSB6eCAtIHd5O1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB5eCAtIHd6O1xuICBvdXRbNV0gPSAxIC0geHggLSB6ejtcbiAgb3V0WzZdID0genkgKyB3eDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0genggKyB3eTtcbiAgb3V0WzldID0genkgLSB3eDtcbiAgb3V0WzEwXSA9IDEgLSB4eCAtIHl5O1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogR2VuZXJhdGVzIGEgZnJ1c3R1bSBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cclxuICogQHBhcmFtIHtOdW1iZXJ9IGxlZnQgTGVmdCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmlnaHQgUmlnaHQgYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHBhcmFtIHtOdW1iZXJ9IGJvdHRvbSBCb3R0b20gYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHBhcmFtIHtOdW1iZXJ9IHRvcCBUb3AgYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHBhcmFtIHtOdW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxyXG4gKiBAcGFyYW0ge051bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZydXN0dW0ob3V0LCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIG5lYXIsIGZhcikge1xuICB2YXIgcmwgPSAxIC8gKHJpZ2h0IC0gbGVmdCk7XG4gIHZhciB0YiA9IDEgLyAodG9wIC0gYm90dG9tKTtcbiAgdmFyIG5mID0gMSAvIChuZWFyIC0gZmFyKTtcbiAgb3V0WzBdID0gbmVhciAqIDIgKiBybDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gbmVhciAqIDIgKiB0YjtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gKHJpZ2h0ICsgbGVmdCkgKiBybDtcbiAgb3V0WzldID0gKHRvcCArIGJvdHRvbSkgKiB0YjtcbiAgb3V0WzEwXSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICBvdXRbMTFdID0gLTE7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IGZhciAqIG5lYXIgKiAyICogbmY7XG4gIG91dFsxNV0gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdlbmVyYXRlcyBhIHBlcnNwZWN0aXZlIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGJvdW5kcy5cclxuICogUGFzc2luZyBudWxsL3VuZGVmaW5lZC9ubyB2YWx1ZSBmb3IgZmFyIHdpbGwgZ2VuZXJhdGUgaW5maW5pdGUgcHJvamVjdGlvbiBtYXRyaXguXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cclxuICogQHBhcmFtIHtudW1iZXJ9IGZvdnkgVmVydGljYWwgZmllbGQgb2YgdmlldyBpbiByYWRpYW5zXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBhc3BlY3QgQXNwZWN0IHJhdGlvLiB0eXBpY2FsbHkgdmlld3BvcnQgd2lkdGgvaGVpZ2h0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHBhcmFtIHtudW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW0sIGNhbiBiZSBudWxsIG9yIEluZmluaXR5XHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gcGVyc3BlY3RpdmUob3V0LCBmb3Z5LCBhc3BlY3QsIG5lYXIsIGZhcikge1xuICB2YXIgZiA9IDEuMCAvIE1hdGgudGFuKGZvdnkgLyAyKSxcbiAgICAgIG5mO1xuICBvdXRbMF0gPSBmIC8gYXNwZWN0O1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSBmO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTFdID0gLTE7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE1XSA9IDA7XG5cbiAgaWYgKGZhciAhPSBudWxsICYmIGZhciAhPT0gSW5maW5pdHkpIHtcbiAgICBuZiA9IDEgLyAobmVhciAtIGZhcik7XG4gICAgb3V0WzEwXSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICAgIG91dFsxNF0gPSAyICogZmFyICogbmVhciAqIG5mO1xuICB9IGVsc2Uge1xuICAgIG91dFsxMF0gPSAtMTtcbiAgICBvdXRbMTRdID0gLTIgKiBuZWFyO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSBwZXJzcGVjdGl2ZSBwcm9qZWN0aW9uIG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBmaWVsZCBvZiB2aWV3LlxyXG4gKiBUaGlzIGlzIHByaW1hcmlseSB1c2VmdWwgZm9yIGdlbmVyYXRpbmcgcHJvamVjdGlvbiBtYXRyaWNlcyB0byBiZSB1c2VkXHJcbiAqIHdpdGggdGhlIHN0aWxsIGV4cGVyaWVtZW50YWwgV2ViVlIgQVBJLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBmb3YgT2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZvbGxvd2luZyB2YWx1ZXM6IHVwRGVncmVlcywgZG93bkRlZ3JlZXMsIGxlZnREZWdyZWVzLCByaWdodERlZ3JlZXNcclxuICogQHBhcmFtIHtudW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxyXG4gKiBAcGFyYW0ge251bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHBlcnNwZWN0aXZlRnJvbUZpZWxkT2ZWaWV3KG91dCwgZm92LCBuZWFyLCBmYXIpIHtcbiAgdmFyIHVwVGFuID0gTWF0aC50YW4oZm92LnVwRGVncmVlcyAqIE1hdGguUEkgLyAxODAuMCk7XG4gIHZhciBkb3duVGFuID0gTWF0aC50YW4oZm92LmRvd25EZWdyZWVzICogTWF0aC5QSSAvIDE4MC4wKTtcbiAgdmFyIGxlZnRUYW4gPSBNYXRoLnRhbihmb3YubGVmdERlZ3JlZXMgKiBNYXRoLlBJIC8gMTgwLjApO1xuICB2YXIgcmlnaHRUYW4gPSBNYXRoLnRhbihmb3YucmlnaHREZWdyZWVzICogTWF0aC5QSSAvIDE4MC4wKTtcbiAgdmFyIHhTY2FsZSA9IDIuMCAvIChsZWZ0VGFuICsgcmlnaHRUYW4pO1xuICB2YXIgeVNjYWxlID0gMi4wIC8gKHVwVGFuICsgZG93blRhbik7XG4gIG91dFswXSA9IHhTY2FsZTtcbiAgb3V0WzFdID0gMC4wO1xuICBvdXRbMl0gPSAwLjA7XG4gIG91dFszXSA9IDAuMDtcbiAgb3V0WzRdID0gMC4wO1xuICBvdXRbNV0gPSB5U2NhbGU7XG4gIG91dFs2XSA9IDAuMDtcbiAgb3V0WzddID0gMC4wO1xuICBvdXRbOF0gPSAtKChsZWZ0VGFuIC0gcmlnaHRUYW4pICogeFNjYWxlICogMC41KTtcbiAgb3V0WzldID0gKHVwVGFuIC0gZG93blRhbikgKiB5U2NhbGUgKiAwLjU7XG4gIG91dFsxMF0gPSBmYXIgLyAobmVhciAtIGZhcik7XG4gIG91dFsxMV0gPSAtMS4wO1xuICBvdXRbMTJdID0gMC4wO1xuICBvdXRbMTNdID0gMC4wO1xuICBvdXRbMTRdID0gZmFyICogbmVhciAvIChuZWFyIC0gZmFyKTtcbiAgb3V0WzE1XSA9IDAuMDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSBvcnRob2dvbmFsIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGJvdW5kc1xyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0IExlZnQgYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0IFJpZ2h0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBib3R0b20gQm90dG9tIGJvdW5kIG9mIHRoZSBmcnVzdHVtXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB0b3AgVG9wIGJvdW5kIG9mIHRoZSBmcnVzdHVtXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHBhcmFtIHtudW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBvcnRobyhvdXQsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgbmVhciwgZmFyKSB7XG4gIHZhciBsciA9IDEgLyAobGVmdCAtIHJpZ2h0KTtcbiAgdmFyIGJ0ID0gMSAvIChib3R0b20gLSB0b3ApO1xuICB2YXIgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICBvdXRbMF0gPSAtMiAqIGxyO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAtMiAqIGJ0O1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gMiAqIG5mO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IChsZWZ0ICsgcmlnaHQpICogbHI7XG4gIG91dFsxM10gPSAodG9wICsgYm90dG9tKSAqIGJ0O1xuICBvdXRbMTRdID0gKGZhciArIG5lYXIpICogbmY7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdlbmVyYXRlcyBhIGxvb2stYXQgbWF0cml4IHdpdGggdGhlIGdpdmVuIGV5ZSBwb3NpdGlvbiwgZm9jYWwgcG9pbnQsIGFuZCB1cCBheGlzLlxyXG4gKiBJZiB5b3Ugd2FudCBhIG1hdHJpeCB0aGF0IGFjdHVhbGx5IG1ha2VzIGFuIG9iamVjdCBsb29rIGF0IGFub3RoZXIgb2JqZWN0LCB5b3Ugc2hvdWxkIHVzZSB0YXJnZXRUbyBpbnN0ZWFkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBleWUgUG9zaXRpb24gb2YgdGhlIHZpZXdlclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gY2VudGVyIFBvaW50IHRoZSB2aWV3ZXIgaXMgbG9va2luZyBhdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdXAgdmVjMyBwb2ludGluZyB1cFxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGxvb2tBdChvdXQsIGV5ZSwgY2VudGVyLCB1cCkge1xuICB2YXIgeDAsIHgxLCB4MiwgeTAsIHkxLCB5MiwgejAsIHoxLCB6MiwgbGVuO1xuICB2YXIgZXlleCA9IGV5ZVswXTtcbiAgdmFyIGV5ZXkgPSBleWVbMV07XG4gIHZhciBleWV6ID0gZXllWzJdO1xuICB2YXIgdXB4ID0gdXBbMF07XG4gIHZhciB1cHkgPSB1cFsxXTtcbiAgdmFyIHVweiA9IHVwWzJdO1xuICB2YXIgY2VudGVyeCA9IGNlbnRlclswXTtcbiAgdmFyIGNlbnRlcnkgPSBjZW50ZXJbMV07XG4gIHZhciBjZW50ZXJ6ID0gY2VudGVyWzJdO1xuXG4gIGlmIChNYXRoLmFicyhleWV4IC0gY2VudGVyeCkgPCBnbE1hdHJpeC5FUFNJTE9OICYmIE1hdGguYWJzKGV5ZXkgLSBjZW50ZXJ5KSA8IGdsTWF0cml4LkVQU0lMT04gJiYgTWF0aC5hYnMoZXlleiAtIGNlbnRlcnopIDwgZ2xNYXRyaXguRVBTSUxPTikge1xuICAgIHJldHVybiBpZGVudGl0eShvdXQpO1xuICB9XG5cbiAgejAgPSBleWV4IC0gY2VudGVyeDtcbiAgejEgPSBleWV5IC0gY2VudGVyeTtcbiAgejIgPSBleWV6IC0gY2VudGVyejtcbiAgbGVuID0gMSAvIE1hdGguaHlwb3QoejAsIHoxLCB6Mik7XG4gIHowICo9IGxlbjtcbiAgejEgKj0gbGVuO1xuICB6MiAqPSBsZW47XG4gIHgwID0gdXB5ICogejIgLSB1cHogKiB6MTtcbiAgeDEgPSB1cHogKiB6MCAtIHVweCAqIHoyO1xuICB4MiA9IHVweCAqIHoxIC0gdXB5ICogejA7XG4gIGxlbiA9IE1hdGguaHlwb3QoeDAsIHgxLCB4Mik7XG5cbiAgaWYgKCFsZW4pIHtcbiAgICB4MCA9IDA7XG4gICAgeDEgPSAwO1xuICAgIHgyID0gMDtcbiAgfSBlbHNlIHtcbiAgICBsZW4gPSAxIC8gbGVuO1xuICAgIHgwICo9IGxlbjtcbiAgICB4MSAqPSBsZW47XG4gICAgeDIgKj0gbGVuO1xuICB9XG5cbiAgeTAgPSB6MSAqIHgyIC0gejIgKiB4MTtcbiAgeTEgPSB6MiAqIHgwIC0gejAgKiB4MjtcbiAgeTIgPSB6MCAqIHgxIC0gejEgKiB4MDtcbiAgbGVuID0gTWF0aC5oeXBvdCh5MCwgeTEsIHkyKTtcblxuICBpZiAoIWxlbikge1xuICAgIHkwID0gMDtcbiAgICB5MSA9IDA7XG4gICAgeTIgPSAwO1xuICB9IGVsc2Uge1xuICAgIGxlbiA9IDEgLyBsZW47XG4gICAgeTAgKj0gbGVuO1xuICAgIHkxICo9IGxlbjtcbiAgICB5MiAqPSBsZW47XG4gIH1cblxuICBvdXRbMF0gPSB4MDtcbiAgb3V0WzFdID0geTA7XG4gIG91dFsyXSA9IHowO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB4MTtcbiAgb3V0WzVdID0geTE7XG4gIG91dFs2XSA9IHoxO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB4MjtcbiAgb3V0WzldID0geTI7XG4gIG91dFsxMF0gPSB6MjtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAtKHgwICogZXlleCArIHgxICogZXlleSArIHgyICogZXlleik7XG4gIG91dFsxM10gPSAtKHkwICogZXlleCArIHkxICogZXlleSArIHkyICogZXlleik7XG4gIG91dFsxNF0gPSAtKHowICogZXlleCArIHoxICogZXlleSArIHoyICogZXlleik7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdlbmVyYXRlcyBhIG1hdHJpeCB0aGF0IG1ha2VzIHNvbWV0aGluZyBsb29rIGF0IHNvbWV0aGluZyBlbHNlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBleWUgUG9zaXRpb24gb2YgdGhlIHZpZXdlclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gY2VudGVyIFBvaW50IHRoZSB2aWV3ZXIgaXMgbG9va2luZyBhdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdXAgdmVjMyBwb2ludGluZyB1cFxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHRhcmdldFRvKG91dCwgZXllLCB0YXJnZXQsIHVwKSB7XG4gIHZhciBleWV4ID0gZXllWzBdLFxuICAgICAgZXlleSA9IGV5ZVsxXSxcbiAgICAgIGV5ZXogPSBleWVbMl0sXG4gICAgICB1cHggPSB1cFswXSxcbiAgICAgIHVweSA9IHVwWzFdLFxuICAgICAgdXB6ID0gdXBbMl07XG4gIHZhciB6MCA9IGV5ZXggLSB0YXJnZXRbMF0sXG4gICAgICB6MSA9IGV5ZXkgLSB0YXJnZXRbMV0sXG4gICAgICB6MiA9IGV5ZXogLSB0YXJnZXRbMl07XG4gIHZhciBsZW4gPSB6MCAqIHowICsgejEgKiB6MSArIHoyICogejI7XG5cbiAgaWYgKGxlbiA+IDApIHtcbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gICAgejAgKj0gbGVuO1xuICAgIHoxICo9IGxlbjtcbiAgICB6MiAqPSBsZW47XG4gIH1cblxuICB2YXIgeDAgPSB1cHkgKiB6MiAtIHVweiAqIHoxLFxuICAgICAgeDEgPSB1cHogKiB6MCAtIHVweCAqIHoyLFxuICAgICAgeDIgPSB1cHggKiB6MSAtIHVweSAqIHowO1xuICBsZW4gPSB4MCAqIHgwICsgeDEgKiB4MSArIHgyICogeDI7XG5cbiAgaWYgKGxlbiA+IDApIHtcbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gICAgeDAgKj0gbGVuO1xuICAgIHgxICo9IGxlbjtcbiAgICB4MiAqPSBsZW47XG4gIH1cblxuICBvdXRbMF0gPSB4MDtcbiAgb3V0WzFdID0geDE7XG4gIG91dFsyXSA9IHgyO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSB6MSAqIHgyIC0gejIgKiB4MTtcbiAgb3V0WzVdID0gejIgKiB4MCAtIHowICogeDI7XG4gIG91dFs2XSA9IHowICogeDEgLSB6MSAqIHgwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB6MDtcbiAgb3V0WzldID0gejE7XG4gIG91dFsxMF0gPSB6MjtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSBleWV4O1xuICBvdXRbMTNdID0gZXlleTtcbiAgb3V0WzE0XSA9IGV5ZXo7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtYXQ0XHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIG1hdHJpeCB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcclxuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcclxuICovXG5cblxuZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwibWF0NChcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiLCBcIiArIGFbM10gKyBcIiwgXCIgKyBhWzRdICsgXCIsIFwiICsgYVs1XSArIFwiLCBcIiArIGFbNl0gKyBcIiwgXCIgKyBhWzddICsgXCIsIFwiICsgYVs4XSArIFwiLCBcIiArIGFbOV0gKyBcIiwgXCIgKyBhWzEwXSArIFwiLCBcIiArIGFbMTFdICsgXCIsIFwiICsgYVsxMl0gKyBcIiwgXCIgKyBhWzEzXSArIFwiLCBcIiArIGFbMTRdICsgXCIsIFwiICsgYVsxNV0gKyBcIilcIjtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIEZyb2Jlbml1cyBub3JtIG9mIGEgbWF0NFxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIGNhbGN1bGF0ZSBGcm9iZW5pdXMgbm9ybSBvZlxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBGcm9iZW5pdXMgbm9ybVxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9iKGEpIHtcbiAgcmV0dXJuIE1hdGguaHlwb3QoYVswXSwgYVsxXSwgYVsyXSwgYVszXSwgYVs0XSwgYVs1XSwgYVs2XSwgYVs3XSwgYVs4XSwgYVs5XSwgYVsxMF0sIGFbMTFdLCBhWzEyXSwgYVsxM10sIGFbMTRdLCBhWzE1XSk7XG59XG4vKipcclxuICogQWRkcyB0d28gbWF0NCdzXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGFkZChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXTtcbiAgb3V0WzNdID0gYVszXSArIGJbM107XG4gIG91dFs0XSA9IGFbNF0gKyBiWzRdO1xuICBvdXRbNV0gPSBhWzVdICsgYls1XTtcbiAgb3V0WzZdID0gYVs2XSArIGJbNl07XG4gIG91dFs3XSA9IGFbN10gKyBiWzddO1xuICBvdXRbOF0gPSBhWzhdICsgYls4XTtcbiAgb3V0WzldID0gYVs5XSArIGJbOV07XG4gIG91dFsxMF0gPSBhWzEwXSArIGJbMTBdO1xuICBvdXRbMTFdID0gYVsxMV0gKyBiWzExXTtcbiAgb3V0WzEyXSA9IGFbMTJdICsgYlsxMl07XG4gIG91dFsxM10gPSBhWzEzXSArIGJbMTNdO1xuICBvdXRbMTRdID0gYVsxNF0gKyBiWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdICsgYlsxNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU3VidHJhY3RzIG1hdHJpeCBiIGZyb20gbWF0cml4IGFcclxuICpcclxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gc3VidHJhY3Qob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLSBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC0gYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAtIGJbMl07XG4gIG91dFszXSA9IGFbM10gLSBiWzNdO1xuICBvdXRbNF0gPSBhWzRdIC0gYls0XTtcbiAgb3V0WzVdID0gYVs1XSAtIGJbNV07XG4gIG91dFs2XSA9IGFbNl0gLSBiWzZdO1xuICBvdXRbN10gPSBhWzddIC0gYls3XTtcbiAgb3V0WzhdID0gYVs4XSAtIGJbOF07XG4gIG91dFs5XSA9IGFbOV0gLSBiWzldO1xuICBvdXRbMTBdID0gYVsxMF0gLSBiWzEwXTtcbiAgb3V0WzExXSA9IGFbMTFdIC0gYlsxMV07XG4gIG91dFsxMl0gPSBhWzEyXSAtIGJbMTJdO1xuICBvdXRbMTNdID0gYVsxM10gLSBiWzEzXTtcbiAgb3V0WzE0XSA9IGFbMTRdIC0gYlsxNF07XG4gIG91dFsxNV0gPSBhWzE1XSAtIGJbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE11bHRpcGx5IGVhY2ggZWxlbWVudCBvZiB0aGUgbWF0cml4IGJ5IGEgc2NhbGFyLlxyXG4gKlxyXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHNjYWxlXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgbWF0cml4J3MgZWxlbWVudHMgYnlcclxuICogQHJldHVybnMge21hdDR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtdWx0aXBseVNjYWxhcihvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgb3V0WzNdID0gYVszXSAqIGI7XG4gIG91dFs0XSA9IGFbNF0gKiBiO1xuICBvdXRbNV0gPSBhWzVdICogYjtcbiAgb3V0WzZdID0gYVs2XSAqIGI7XG4gIG91dFs3XSA9IGFbN10gKiBiO1xuICBvdXRbOF0gPSBhWzhdICogYjtcbiAgb3V0WzldID0gYVs5XSAqIGI7XG4gIG91dFsxMF0gPSBhWzEwXSAqIGI7XG4gIG91dFsxMV0gPSBhWzExXSAqIGI7XG4gIG91dFsxMl0gPSBhWzEyXSAqIGI7XG4gIG91dFsxM10gPSBhWzEzXSAqIGI7XG4gIG91dFsxNF0gPSBhWzE0XSAqIGI7XG4gIG91dFsxNV0gPSBhWzE1XSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQWRkcyB0d28gbWF0NCdzIGFmdGVyIG11bHRpcGx5aW5nIGVhY2ggZWxlbWVudCBvZiB0aGUgc2Vjb25kIG9wZXJhbmQgYnkgYSBzY2FsYXIgdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgdGhlIGFtb3VudCB0byBzY2FsZSBiJ3MgZWxlbWVudHMgYnkgYmVmb3JlIGFkZGluZ1xyXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyQW5kQWRkKG91dCwgYSwgYiwgc2NhbGUpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF0gKiBzY2FsZTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV0gKiBzY2FsZTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl0gKiBzY2FsZTtcbiAgb3V0WzNdID0gYVszXSArIGJbM10gKiBzY2FsZTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF0gKiBzY2FsZTtcbiAgb3V0WzVdID0gYVs1XSArIGJbNV0gKiBzY2FsZTtcbiAgb3V0WzZdID0gYVs2XSArIGJbNl0gKiBzY2FsZTtcbiAgb3V0WzddID0gYVs3XSArIGJbN10gKiBzY2FsZTtcbiAgb3V0WzhdID0gYVs4XSArIGJbOF0gKiBzY2FsZTtcbiAgb3V0WzldID0gYVs5XSArIGJbOV0gKiBzY2FsZTtcbiAgb3V0WzEwXSA9IGFbMTBdICsgYlsxMF0gKiBzY2FsZTtcbiAgb3V0WzExXSA9IGFbMTFdICsgYlsxMV0gKiBzY2FsZTtcbiAgb3V0WzEyXSA9IGFbMTJdICsgYlsxMl0gKiBzY2FsZTtcbiAgb3V0WzEzXSA9IGFbMTNdICsgYlsxM10gKiBzY2FsZTtcbiAgb3V0WzE0XSA9IGFbMTRdICsgYlsxNF0gKiBzY2FsZTtcbiAgb3V0WzE1XSA9IGFbMTVdICsgYlsxNV0gKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBtYXRyaWNlcyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIFRoZSBmaXJzdCBtYXRyaXguXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIFRoZSBzZWNvbmQgbWF0cml4LlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWF0cmljZXMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGV4YWN0RXF1YWxzKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gPT09IGJbMF0gJiYgYVsxXSA9PT0gYlsxXSAmJiBhWzJdID09PSBiWzJdICYmIGFbM10gPT09IGJbM10gJiYgYVs0XSA9PT0gYls0XSAmJiBhWzVdID09PSBiWzVdICYmIGFbNl0gPT09IGJbNl0gJiYgYVs3XSA9PT0gYls3XSAmJiBhWzhdID09PSBiWzhdICYmIGFbOV0gPT09IGJbOV0gJiYgYVsxMF0gPT09IGJbMTBdICYmIGFbMTFdID09PSBiWzExXSAmJiBhWzEyXSA9PT0gYlsxMl0gJiYgYVsxM10gPT09IGJbMTNdICYmIGFbMTRdID09PSBiWzE0XSAmJiBhWzE1XSA9PT0gYlsxNV07XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSBUaGUgZmlyc3QgbWF0cml4LlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiBUaGUgc2Vjb25kIG1hdHJpeC5cclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdO1xuICB2YXIgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdLFxuICAgICAgYTYgPSBhWzZdLFxuICAgICAgYTcgPSBhWzddO1xuICB2YXIgYTggPSBhWzhdLFxuICAgICAgYTkgPSBhWzldLFxuICAgICAgYTEwID0gYVsxMF0sXG4gICAgICBhMTEgPSBhWzExXTtcbiAgdmFyIGExMiA9IGFbMTJdLFxuICAgICAgYTEzID0gYVsxM10sXG4gICAgICBhMTQgPSBhWzE0XSxcbiAgICAgIGExNSA9IGFbMTVdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdO1xuICB2YXIgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdLFxuICAgICAgYjYgPSBiWzZdLFxuICAgICAgYjcgPSBiWzddO1xuICB2YXIgYjggPSBiWzhdLFxuICAgICAgYjkgPSBiWzldLFxuICAgICAgYjEwID0gYlsxMF0sXG4gICAgICBiMTEgPSBiWzExXTtcbiAgdmFyIGIxMiA9IGJbMTJdLFxuICAgICAgYjEzID0gYlsxM10sXG4gICAgICBiMTQgPSBiWzE0XSxcbiAgICAgIGIxNSA9IGJbMTVdO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSkgJiYgTWF0aC5hYnMoYTMgLSBiMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTMpLCBNYXRoLmFicyhiMykpICYmIE1hdGguYWJzKGE0IC0gYjQpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE0KSwgTWF0aC5hYnMoYjQpKSAmJiBNYXRoLmFicyhhNSAtIGI1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNSksIE1hdGguYWJzKGI1KSkgJiYgTWF0aC5hYnMoYTYgLSBiNikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTYpLCBNYXRoLmFicyhiNikpICYmIE1hdGguYWJzKGE3IC0gYjcpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE3KSwgTWF0aC5hYnMoYjcpKSAmJiBNYXRoLmFicyhhOCAtIGI4KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhOCksIE1hdGguYWJzKGI4KSkgJiYgTWF0aC5hYnMoYTkgLSBiOSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTkpLCBNYXRoLmFicyhiOSkpICYmIE1hdGguYWJzKGExMCAtIGIxMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEwKSwgTWF0aC5hYnMoYjEwKSkgJiYgTWF0aC5hYnMoYTExIC0gYjExKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMTEpLCBNYXRoLmFicyhiMTEpKSAmJiBNYXRoLmFicyhhMTIgLSBiMTIpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExMiksIE1hdGguYWJzKGIxMikpICYmIE1hdGguYWJzKGExMyAtIGIxMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEzKSwgTWF0aC5hYnMoYjEzKSkgJiYgTWF0aC5hYnMoYTE0IC0gYjE0KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMTQpLCBNYXRoLmFicyhiMTQpKSAmJiBNYXRoLmFicyhhMTUgLSBiMTUpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExNSksIE1hdGguYWJzKGIxNSkpO1xufVxuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgbWF0NC5tdWx0aXBseX1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbnZhciBtdWwgPSBtdWx0aXBseTtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDQuc3VidHJhY3R9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5tdWwgPSBtdWw7XG52YXIgc3ViID0gc3VidHJhY3Q7XG5leHBvcnRzLnN1YiA9IHN1YjsiLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiOyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2Yob2JqKTsgfVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5jcmVhdGUgPSBjcmVhdGU7XG5leHBvcnRzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5leHBvcnRzLnNldEF4aXNBbmdsZSA9IHNldEF4aXNBbmdsZTtcbmV4cG9ydHMuZ2V0QXhpc0FuZ2xlID0gZ2V0QXhpc0FuZ2xlO1xuZXhwb3J0cy5nZXRBbmdsZSA9IGdldEFuZ2xlO1xuZXhwb3J0cy5tdWx0aXBseSA9IG11bHRpcGx5O1xuZXhwb3J0cy5yb3RhdGVYID0gcm90YXRlWDtcbmV4cG9ydHMucm90YXRlWSA9IHJvdGF0ZVk7XG5leHBvcnRzLnJvdGF0ZVogPSByb3RhdGVaO1xuZXhwb3J0cy5jYWxjdWxhdGVXID0gY2FsY3VsYXRlVztcbmV4cG9ydHMuZXhwID0gZXhwO1xuZXhwb3J0cy5sbiA9IGxuO1xuZXhwb3J0cy5wb3cgPSBwb3c7XG5leHBvcnRzLnNsZXJwID0gc2xlcnA7XG5leHBvcnRzLnJhbmRvbSA9IHJhbmRvbTtcbmV4cG9ydHMuaW52ZXJ0ID0gaW52ZXJ0O1xuZXhwb3J0cy5jb25qdWdhdGUgPSBjb25qdWdhdGU7XG5leHBvcnRzLmZyb21NYXQzID0gZnJvbU1hdDM7XG5leHBvcnRzLmZyb21FdWxlciA9IGZyb21FdWxlcjtcbmV4cG9ydHMuc3RyID0gc3RyO1xuZXhwb3J0cy5zZXRBeGVzID0gZXhwb3J0cy5zcWxlcnAgPSBleHBvcnRzLnJvdGF0aW9uVG8gPSBleHBvcnRzLmVxdWFscyA9IGV4cG9ydHMuZXhhY3RFcXVhbHMgPSBleHBvcnRzLm5vcm1hbGl6ZSA9IGV4cG9ydHMuc3FyTGVuID0gZXhwb3J0cy5zcXVhcmVkTGVuZ3RoID0gZXhwb3J0cy5sZW4gPSBleHBvcnRzLmxlbmd0aCA9IGV4cG9ydHMubGVycCA9IGV4cG9ydHMuZG90ID0gZXhwb3J0cy5zY2FsZSA9IGV4cG9ydHMubXVsID0gZXhwb3J0cy5hZGQgPSBleHBvcnRzLnNldCA9IGV4cG9ydHMuY29weSA9IGV4cG9ydHMuZnJvbVZhbHVlcyA9IGV4cG9ydHMuY2xvbmUgPSB2b2lkIDA7XG5cbnZhciBnbE1hdHJpeCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKSk7XG5cbnZhciBtYXQzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vbWF0My5qc1wiKSk7XG5cbnZhciB2ZWMzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vdmVjMy5qc1wiKSk7XG5cbnZhciB2ZWM0ID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcIi4vdmVjNC5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsOyB2YXIgY2FjaGUgPSBuZXcgV2Vha01hcCgpOyBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUgPSBmdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IHJldHVybiBjYWNoZTsgfTsgcmV0dXJuIGNhY2hlOyB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gaWYgKG9iaiA9PT0gbnVsbCB8fCBfdHlwZW9mKG9iaikgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSB7IHJldHVybiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfSB2YXIgY2FjaGUgPSBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKTsgaWYgKGNhY2hlICYmIGNhY2hlLmhhcyhvYmopKSB7IHJldHVybiBjYWNoZS5nZXQob2JqKTsgfSB2YXIgbmV3T2JqID0ge307IHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgeyB2YXIgZGVzYyA9IGhhc1Byb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDogbnVsbDsgaWYgKGRlc2MgJiYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpOyB9IGVsc2UgeyBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gfSBuZXdPYmpbXCJkZWZhdWx0XCJdID0gb2JqOyBpZiAoY2FjaGUpIHsgY2FjaGUuc2V0KG9iaiwgbmV3T2JqKTsgfSByZXR1cm4gbmV3T2JqOyB9XG5cbi8qKlxyXG4gKiBRdWF0ZXJuaW9uXHJcbiAqIEBtb2R1bGUgcXVhdFxyXG4gKi9cblxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgcXVhdFxyXG4gKlxyXG4gKiBAcmV0dXJucyB7cXVhdH0gYSBuZXcgcXVhdGVybmlvblxyXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuXG4gIGlmIChnbE1hdHJpeC5BUlJBWV9UWVBFICE9IEZsb2F0MzJBcnJheSkge1xuICAgIG91dFswXSA9IDA7XG4gICAgb3V0WzFdID0gMDtcbiAgICBvdXRbMl0gPSAwO1xuICB9XG5cbiAgb3V0WzNdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTZXQgYSBxdWF0IHRvIHRoZSBpZGVudGl0eSBxdWF0ZXJuaW9uXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAwO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNldHMgYSBxdWF0IGZyb20gdGhlIGdpdmVuIGFuZ2xlIGFuZCByb3RhdGlvbiBheGlzLFxyXG4gKiB0aGVuIHJldHVybnMgaXQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYXhpcyB0aGUgYXhpcyBhcm91bmQgd2hpY2ggdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIGluIHJhZGlhbnNcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKiovXG5cblxuZnVuY3Rpb24gc2V0QXhpc0FuZ2xlKG91dCwgYXhpcywgcmFkKSB7XG4gIHJhZCA9IHJhZCAqIDAuNTtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICBvdXRbMF0gPSBzICogYXhpc1swXTtcbiAgb3V0WzFdID0gcyAqIGF4aXNbMV07XG4gIG91dFsyXSA9IHMgKiBheGlzWzJdO1xuICBvdXRbM10gPSBNYXRoLmNvcyhyYWQpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdldHMgdGhlIHJvdGF0aW9uIGF4aXMgYW5kIGFuZ2xlIGZvciBhIGdpdmVuXHJcbiAqICBxdWF0ZXJuaW9uLiBJZiBhIHF1YXRlcm5pb24gaXMgY3JlYXRlZCB3aXRoXHJcbiAqICBzZXRBeGlzQW5nbGUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSBzYW1lXHJcbiAqICB2YWx1ZXMgYXMgcHJvdmlkaWVkIGluIHRoZSBvcmlnaW5hbCBwYXJhbWV0ZXIgbGlzdFxyXG4gKiAgT1IgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdmFsdWVzLlxyXG4gKiBFeGFtcGxlOiBUaGUgcXVhdGVybmlvbiBmb3JtZWQgYnkgYXhpcyBbMCwgMCwgMV0gYW5kXHJcbiAqICBhbmdsZSAtOTAgaXMgdGhlIHNhbWUgYXMgdGhlIHF1YXRlcm5pb24gZm9ybWVkIGJ5XHJcbiAqICBbMCwgMCwgMV0gYW5kIDI3MC4gVGhpcyBtZXRob2QgZmF2b3JzIHRoZSBsYXR0ZXIuXHJcbiAqIEBwYXJhbSAge3ZlYzN9IG91dF9heGlzICBWZWN0b3IgcmVjZWl2aW5nIHRoZSBheGlzIG9mIHJvdGF0aW9uXHJcbiAqIEBwYXJhbSAge1JlYWRvbmx5UXVhdH0gcSAgICAgUXVhdGVybmlvbiB0byBiZSBkZWNvbXBvc2VkXHJcbiAqIEByZXR1cm4ge051bWJlcn0gICAgIEFuZ2xlLCBpbiByYWRpYW5zLCBvZiB0aGUgcm90YXRpb25cclxuICovXG5cblxuZnVuY3Rpb24gZ2V0QXhpc0FuZ2xlKG91dF9heGlzLCBxKSB7XG4gIHZhciByYWQgPSBNYXRoLmFjb3MocVszXSkgKiAyLjA7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkIC8gMi4wKTtcblxuICBpZiAocyA+IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICBvdXRfYXhpc1swXSA9IHFbMF0gLyBzO1xuICAgIG91dF9heGlzWzFdID0gcVsxXSAvIHM7XG4gICAgb3V0X2F4aXNbMl0gPSBxWzJdIC8gcztcbiAgfSBlbHNlIHtcbiAgICAvLyBJZiBzIGlzIHplcm8sIHJldHVybiBhbnkgYXhpcyAobm8gcm90YXRpb24gLSBheGlzIGRvZXMgbm90IG1hdHRlcilcbiAgICBvdXRfYXhpc1swXSA9IDE7XG4gICAgb3V0X2F4aXNbMV0gPSAwO1xuICAgIG91dF9heGlzWzJdID0gMDtcbiAgfVxuXG4gIHJldHVybiByYWQ7XG59XG4vKipcclxuICogR2V0cyB0aGUgYW5ndWxhciBkaXN0YW5jZSBiZXR3ZWVuIHR3byB1bml0IHF1YXRlcm5pb25zXHJcbiAqXHJcbiAqIEBwYXJhbSAge1JlYWRvbmx5UXVhdH0gYSAgICAgT3JpZ2luIHVuaXQgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0gIHtSZWFkb25seVF1YXR9IGIgICAgIERlc3RpbmF0aW9uIHVuaXQgcXVhdGVybmlvblxyXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICBBbmdsZSwgaW4gcmFkaWFucywgYmV0d2VlbiB0aGUgdHdvIHF1YXRlcm5pb25zXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEFuZ2xlKGEsIGIpIHtcbiAgdmFyIGRvdHByb2R1Y3QgPSBkb3QoYSwgYik7XG4gIHJldHVybiBNYXRoLmFjb3MoMiAqIGRvdHByb2R1Y3QgKiBkb3Rwcm9kdWN0IC0gMSk7XG59XG4vKipcclxuICogTXVsdGlwbGllcyB0d28gcXVhdCdzXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtdWx0aXBseShvdXQsIGEsIGIpIHtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgdmFyIGJ4ID0gYlswXSxcbiAgICAgIGJ5ID0gYlsxXSxcbiAgICAgIGJ6ID0gYlsyXSxcbiAgICAgIGJ3ID0gYlszXTtcbiAgb3V0WzBdID0gYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieTtcbiAgb3V0WzFdID0gYXkgKiBidyArIGF3ICogYnkgKyBheiAqIGJ4IC0gYXggKiBiejtcbiAgb3V0WzJdID0gYXogKiBidyArIGF3ICogYnogKyBheCAqIGJ5IC0gYXkgKiBieDtcbiAgb3V0WzNdID0gYXcgKiBidyAtIGF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSb3RhdGVzIGEgcXVhdGVybmlvbiBieSB0aGUgZ2l2ZW4gYW5nbGUgYWJvdXQgdGhlIFggYXhpc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXR9IG91dCBxdWF0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWQgYW5nbGUgKGluIHJhZGlhbnMpIHRvIHJvdGF0ZVxyXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZVgob3V0LCBhLCByYWQpIHtcbiAgcmFkICo9IDAuNTtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgdmFyIGJ4ID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGJ3ID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYXggKiBidyArIGF3ICogYng7XG4gIG91dFsxXSA9IGF5ICogYncgKyBheiAqIGJ4O1xuICBvdXRbMl0gPSBheiAqIGJ3IC0gYXkgKiBieDtcbiAgb3V0WzNdID0gYXcgKiBidyAtIGF4ICogYng7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUm90YXRlcyBhIHF1YXRlcm5pb24gYnkgdGhlIGdpdmVuIGFuZ2xlIGFib3V0IHRoZSBZIGF4aXNcclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgcXVhdCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGFuZ2xlIChpbiByYWRpYW5zKSB0byByb3RhdGVcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGVZKG91dCwgYSwgcmFkKSB7XG4gIHJhZCAqPSAwLjU7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl0sXG4gICAgICBhdyA9IGFbM107XG4gIHZhciBieSA9IE1hdGguc2luKHJhZCksXG4gICAgICBidyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGF4ICogYncgLSBheiAqIGJ5O1xuICBvdXRbMV0gPSBheSAqIGJ3ICsgYXcgKiBieTtcbiAgb3V0WzJdID0gYXogKiBidyArIGF4ICogYnk7XG4gIG91dFszXSA9IGF3ICogYncgLSBheSAqIGJ5O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBxdWF0ZXJuaW9uIGJ5IHRoZSBnaXZlbiBhbmdsZSBhYm91dCB0aGUgWiBheGlzXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHF1YXQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byByb3RhdGVcclxuICogQHBhcmFtIHtudW1iZXJ9IHJhZCBhbmdsZSAoaW4gcmFkaWFucykgdG8gcm90YXRlXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gcm90YXRlWihvdXQsIGEsIHJhZCkge1xuICByYWQgKj0gMC41O1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdLFxuICAgICAgYXcgPSBhWzNdO1xuICB2YXIgYnogPSBNYXRoLnNpbihyYWQpLFxuICAgICAgYncgPSBNYXRoLmNvcyhyYWQpO1xuICBvdXRbMF0gPSBheCAqIGJ3ICsgYXkgKiBiejtcbiAgb3V0WzFdID0gYXkgKiBidyAtIGF4ICogYno7XG4gIG91dFsyXSA9IGF6ICogYncgKyBhdyAqIGJ6O1xuICBvdXRbM10gPSBhdyAqIGJ3IC0gYXogKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBXIGNvbXBvbmVudCBvZiBhIHF1YXQgZnJvbSB0aGUgWCwgWSwgYW5kIFogY29tcG9uZW50cy5cclxuICogQXNzdW1lcyB0aGF0IHF1YXRlcm5pb24gaXMgMSB1bml0IGluIGxlbmd0aC5cclxuICogQW55IGV4aXN0aW5nIFcgY29tcG9uZW50IHdpbGwgYmUgaWdub3JlZC5cclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gY2FsY3VsYXRlIFcgY29tcG9uZW50IG9mXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gY2FsY3VsYXRlVyhvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgb3V0WzJdID0gejtcbiAgb3V0WzNdID0gTWF0aC5zcXJ0KE1hdGguYWJzKDEuMCAtIHggKiB4IC0geSAqIHkgLSB6ICogeikpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZSB0aGUgZXhwb25lbnRpYWwgb2YgYSB1bml0IHF1YXRlcm5pb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSB0aGUgZXhwb25lbnRpYWwgb2ZcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBleHAob3V0LCBhKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdLFxuICAgICAgeiA9IGFbMl0sXG4gICAgICB3ID0gYVszXTtcbiAgdmFyIHIgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSArIHogKiB6KTtcbiAgdmFyIGV0ID0gTWF0aC5leHAodyk7XG4gIHZhciBzID0gciA+IDAgPyBldCAqIE1hdGguc2luKHIpIC8gciA6IDA7XG4gIG91dFswXSA9IHggKiBzO1xuICBvdXRbMV0gPSB5ICogcztcbiAgb3V0WzJdID0geiAqIHM7XG4gIG91dFszXSA9IGV0ICogTWF0aC5jb3Mocik7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ2FsY3VsYXRlIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiBhIHVuaXQgcXVhdGVybmlvbi5cclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gY2FsY3VsYXRlIHRoZSBleHBvbmVudGlhbCBvZlxyXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGxuKG91dCwgYSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdLFxuICAgICAgdyA9IGFbM107XG4gIHZhciByID0gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkgKyB6ICogeik7XG4gIHZhciB0ID0gciA+IDAgPyBNYXRoLmF0YW4yKHIsIHcpIC8gciA6IDA7XG4gIG91dFswXSA9IHggKiB0O1xuICBvdXRbMV0gPSB5ICogdDtcbiAgb3V0WzJdID0geiAqIHQ7XG4gIG91dFszXSA9IDAuNSAqIE1hdGgubG9nKHggKiB4ICsgeSAqIHkgKyB6ICogeiArIHcgKiB3KTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGUgdGhlIHNjYWxhciBwb3dlciBvZiBhIHVuaXQgcXVhdGVybmlvbi5cclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gY2FsY3VsYXRlIHRoZSBleHBvbmVudGlhbCBvZlxyXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHF1YXRlcm5pb24gYnlcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBwb3cob3V0LCBhLCBiKSB7XG4gIGxuKG91dCwgYSk7XG4gIHNjYWxlKG91dCwgb3V0LCBiKTtcbiAgZXhwKG91dCwgb3V0KTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBQZXJmb3JtcyBhIHNwaGVyaWNhbCBsaW5lYXIgaW50ZXJwb2xhdGlvbiBiZXR3ZWVuIHR3byBxdWF0XHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xyXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNsZXJwKG91dCwgYSwgYiwgdCkge1xuICAvLyBiZW5jaG1hcmtzOlxuICAvLyAgICBodHRwOi8vanNwZXJmLmNvbS9xdWF0ZXJuaW9uLXNsZXJwLWltcGxlbWVudGF0aW9uc1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdLFxuICAgICAgYXcgPSBhWzNdO1xuICB2YXIgYnggPSBiWzBdLFxuICAgICAgYnkgPSBiWzFdLFxuICAgICAgYnogPSBiWzJdLFxuICAgICAgYncgPSBiWzNdO1xuICB2YXIgb21lZ2EsIGNvc29tLCBzaW5vbSwgc2NhbGUwLCBzY2FsZTE7IC8vIGNhbGMgY29zaW5lXG5cbiAgY29zb20gPSBheCAqIGJ4ICsgYXkgKiBieSArIGF6ICogYnogKyBhdyAqIGJ3OyAvLyBhZGp1c3Qgc2lnbnMgKGlmIG5lY2Vzc2FyeSlcblxuICBpZiAoY29zb20gPCAwLjApIHtcbiAgICBjb3NvbSA9IC1jb3NvbTtcbiAgICBieCA9IC1ieDtcbiAgICBieSA9IC1ieTtcbiAgICBieiA9IC1iejtcbiAgICBidyA9IC1idztcbiAgfSAvLyBjYWxjdWxhdGUgY29lZmZpY2llbnRzXG5cblxuICBpZiAoMS4wIC0gY29zb20gPiBnbE1hdHJpeC5FUFNJTE9OKSB7XG4gICAgLy8gc3RhbmRhcmQgY2FzZSAoc2xlcnApXG4gICAgb21lZ2EgPSBNYXRoLmFjb3MoY29zb20pO1xuICAgIHNpbm9tID0gTWF0aC5zaW4ob21lZ2EpO1xuICAgIHNjYWxlMCA9IE1hdGguc2luKCgxLjAgLSB0KSAqIG9tZWdhKSAvIHNpbm9tO1xuICAgIHNjYWxlMSA9IE1hdGguc2luKHQgKiBvbWVnYSkgLyBzaW5vbTtcbiAgfSBlbHNlIHtcbiAgICAvLyBcImZyb21cIiBhbmQgXCJ0b1wiIHF1YXRlcm5pb25zIGFyZSB2ZXJ5IGNsb3NlXG4gICAgLy8gIC4uLiBzbyB3ZSBjYW4gZG8gYSBsaW5lYXIgaW50ZXJwb2xhdGlvblxuICAgIHNjYWxlMCA9IDEuMCAtIHQ7XG4gICAgc2NhbGUxID0gdDtcbiAgfSAvLyBjYWxjdWxhdGUgZmluYWwgdmFsdWVzXG5cblxuICBvdXRbMF0gPSBzY2FsZTAgKiBheCArIHNjYWxlMSAqIGJ4O1xuICBvdXRbMV0gPSBzY2FsZTAgKiBheSArIHNjYWxlMSAqIGJ5O1xuICBvdXRbMl0gPSBzY2FsZTAgKiBheiArIHNjYWxlMSAqIGJ6O1xuICBvdXRbM10gPSBzY2FsZTAgKiBhdyArIHNjYWxlMSAqIGJ3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSB1bml0IHF1YXRlcm5pb25cclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gcmFuZG9tKG91dCkge1xuICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBodHRwOi8vcGxhbm5pbmcuY3MudWl1Yy5lZHUvbm9kZTE5OC5odG1sXG4gIC8vIFRPRE86IENhbGxpbmcgcmFuZG9tIDMgdGltZXMgaXMgcHJvYmFibHkgbm90IHRoZSBmYXN0ZXN0IHNvbHV0aW9uXG4gIHZhciB1MSA9IGdsTWF0cml4LlJBTkRPTSgpO1xuICB2YXIgdTIgPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgdmFyIHUzID0gZ2xNYXRyaXguUkFORE9NKCk7XG4gIHZhciBzcXJ0MU1pbnVzVTEgPSBNYXRoLnNxcnQoMSAtIHUxKTtcbiAgdmFyIHNxcnRVMSA9IE1hdGguc3FydCh1MSk7XG4gIG91dFswXSA9IHNxcnQxTWludXNVMSAqIE1hdGguc2luKDIuMCAqIE1hdGguUEkgKiB1Mik7XG4gIG91dFsxXSA9IHNxcnQxTWludXNVMSAqIE1hdGguY29zKDIuMCAqIE1hdGguUEkgKiB1Mik7XG4gIG91dFsyXSA9IHNxcnRVMSAqIE1hdGguc2luKDIuMCAqIE1hdGguUEkgKiB1Myk7XG4gIG91dFszXSA9IHNxcnRVMSAqIE1hdGguY29zKDIuMCAqIE1hdGguUEkgKiB1Myk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgaW52ZXJzZSBvZiBhIHF1YXRcclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gY2FsY3VsYXRlIGludmVyc2Ugb2ZcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBpbnZlcnQob3V0LCBhKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM107XG4gIHZhciBkb3QgPSBhMCAqIGEwICsgYTEgKiBhMSArIGEyICogYTIgKyBhMyAqIGEzO1xuICB2YXIgaW52RG90ID0gZG90ID8gMS4wIC8gZG90IDogMDsgLy8gVE9ETzogV291bGQgYmUgZmFzdGVyIHRvIHJldHVybiBbMCwwLDAsMF0gaW1tZWRpYXRlbHkgaWYgZG90ID09IDBcblxuICBvdXRbMF0gPSAtYTAgKiBpbnZEb3Q7XG4gIG91dFsxXSA9IC1hMSAqIGludkRvdDtcbiAgb3V0WzJdID0gLWEyICogaW52RG90O1xuICBvdXRbM10gPSBhMyAqIGludkRvdDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBjb25qdWdhdGUgb2YgYSBxdWF0XHJcbiAqIElmIHRoZSBxdWF0ZXJuaW9uIGlzIG5vcm1hbGl6ZWQsIHRoaXMgZnVuY3Rpb24gaXMgZmFzdGVyIHRoYW4gcXVhdC5pbnZlcnNlIGFuZCBwcm9kdWNlcyB0aGUgc2FtZSByZXN1bHQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBjb25qdWdhdGUgb2ZcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjb25qdWdhdGUob3V0LCBhKSB7XG4gIG91dFswXSA9IC1hWzBdO1xuICBvdXRbMV0gPSAtYVsxXTtcbiAgb3V0WzJdID0gLWFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIHF1YXRlcm5pb24gZnJvbSB0aGUgZ2l2ZW4gM3gzIHJvdGF0aW9uIG1hdHJpeC5cclxuICpcclxuICogTk9URTogVGhlIHJlc3VsdGFudCBxdWF0ZXJuaW9uIGlzIG5vdCBub3JtYWxpemVkLCBzbyB5b3Ugc2hvdWxkIGJlIHN1cmVcclxuICogdG8gcmVub3JtYWxpemUgdGhlIHF1YXRlcm5pb24geW91cnNlbGYgd2hlcmUgbmVjZXNzYXJ5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IG0gcm90YXRpb24gbWF0cml4XHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21NYXQzKG91dCwgbSkge1xuICAvLyBBbGdvcml0aG0gaW4gS2VuIFNob2VtYWtlJ3MgYXJ0aWNsZSBpbiAxOTg3IFNJR0dSQVBIIGNvdXJzZSBub3Rlc1xuICAvLyBhcnRpY2xlIFwiUXVhdGVybmlvbiBDYWxjdWx1cyBhbmQgRmFzdCBBbmltYXRpb25cIi5cbiAgdmFyIGZUcmFjZSA9IG1bMF0gKyBtWzRdICsgbVs4XTtcbiAgdmFyIGZSb290O1xuXG4gIGlmIChmVHJhY2UgPiAwLjApIHtcbiAgICAvLyB8d3wgPiAxLzIsIG1heSBhcyB3ZWxsIGNob29zZSB3ID4gMS8yXG4gICAgZlJvb3QgPSBNYXRoLnNxcnQoZlRyYWNlICsgMS4wKTsgLy8gMndcblxuICAgIG91dFszXSA9IDAuNSAqIGZSb290O1xuICAgIGZSb290ID0gMC41IC8gZlJvb3Q7IC8vIDEvKDR3KVxuXG4gICAgb3V0WzBdID0gKG1bNV0gLSBtWzddKSAqIGZSb290O1xuICAgIG91dFsxXSA9IChtWzZdIC0gbVsyXSkgKiBmUm9vdDtcbiAgICBvdXRbMl0gPSAobVsxXSAtIG1bM10pICogZlJvb3Q7XG4gIH0gZWxzZSB7XG4gICAgLy8gfHd8IDw9IDEvMlxuICAgIHZhciBpID0gMDtcbiAgICBpZiAobVs0XSA+IG1bMF0pIGkgPSAxO1xuICAgIGlmIChtWzhdID4gbVtpICogMyArIGldKSBpID0gMjtcbiAgICB2YXIgaiA9IChpICsgMSkgJSAzO1xuICAgIHZhciBrID0gKGkgKyAyKSAlIDM7XG4gICAgZlJvb3QgPSBNYXRoLnNxcnQobVtpICogMyArIGldIC0gbVtqICogMyArIGpdIC0gbVtrICogMyArIGtdICsgMS4wKTtcbiAgICBvdXRbaV0gPSAwLjUgKiBmUm9vdDtcbiAgICBmUm9vdCA9IDAuNSAvIGZSb290O1xuICAgIG91dFszXSA9IChtW2ogKiAzICsga10gLSBtW2sgKiAzICsgal0pICogZlJvb3Q7XG4gICAgb3V0W2pdID0gKG1baiAqIDMgKyBpXSArIG1baSAqIDMgKyBqXSkgKiBmUm9vdDtcbiAgICBvdXRba10gPSAobVtrICogMyArIGldICsgbVtpICogMyArIGtdKSAqIGZSb290O1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgcXVhdGVybmlvbiBmcm9tIHRoZSBnaXZlbiBldWxlciBhbmdsZSB4LCB5LCB6LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHt4fSBBbmdsZSB0byByb3RhdGUgYXJvdW5kIFggYXhpcyBpbiBkZWdyZWVzLlxyXG4gKiBAcGFyYW0ge3l9IEFuZ2xlIHRvIHJvdGF0ZSBhcm91bmQgWSBheGlzIGluIGRlZ3JlZXMuXHJcbiAqIEBwYXJhbSB7en0gQW5nbGUgdG8gcm90YXRlIGFyb3VuZCBaIGF4aXMgaW4gZGVncmVlcy5cclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxuZnVuY3Rpb24gZnJvbUV1bGVyKG91dCwgeCwgeSwgeikge1xuICB2YXIgaGFsZlRvUmFkID0gMC41ICogTWF0aC5QSSAvIDE4MC4wO1xuICB4ICo9IGhhbGZUb1JhZDtcbiAgeSAqPSBoYWxmVG9SYWQ7XG4gIHogKj0gaGFsZlRvUmFkO1xuICB2YXIgc3ggPSBNYXRoLnNpbih4KTtcbiAgdmFyIGN4ID0gTWF0aC5jb3MoeCk7XG4gIHZhciBzeSA9IE1hdGguc2luKHkpO1xuICB2YXIgY3kgPSBNYXRoLmNvcyh5KTtcbiAgdmFyIHN6ID0gTWF0aC5zaW4oeik7XG4gIHZhciBjeiA9IE1hdGguY29zKHopO1xuICBvdXRbMF0gPSBzeCAqIGN5ICogY3ogLSBjeCAqIHN5ICogc3o7XG4gIG91dFsxXSA9IGN4ICogc3kgKiBjeiArIHN4ICogY3kgKiBzejtcbiAgb3V0WzJdID0gY3ggKiBjeSAqIHN6IC0gc3ggKiBzeSAqIGN6O1xuICBvdXRbM10gPSBjeCAqIGN5ICogY3ogKyBzeCAqIHN5ICogc3o7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHF1YXRlbmlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXHJcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHN0cihhKSB7XG4gIHJldHVybiBcInF1YXQoXCIgKyBhWzBdICsgXCIsIFwiICsgYVsxXSArIFwiLCBcIiArIGFbMl0gKyBcIiwgXCIgKyBhWzNdICsgXCIpXCI7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyBxdWF0IGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgcXVhdGVybmlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0ZXJuaW9uIHRvIGNsb25lXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBhIG5ldyBxdWF0ZXJuaW9uXHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG52YXIgY2xvbmUgPSB2ZWM0LmNsb25lO1xuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgcXVhdCBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHcgVyBjb21wb25lbnRcclxuICogQHJldHVybnMge3F1YXR9IGEgbmV3IHF1YXRlcm5pb25cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmNsb25lID0gY2xvbmU7XG52YXIgZnJvbVZhbHVlcyA9IHZlYzQuZnJvbVZhbHVlcztcbi8qKlxyXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgcXVhdCB0byBhbm90aGVyXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgc291cmNlIHF1YXRlcm5pb25cclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuZnJvbVZhbHVlcyA9IGZyb21WYWx1ZXM7XG52YXIgY29weSA9IHZlYzQuY29weTtcbi8qKlxyXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBxdWF0IHRvIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB3IFcgY29tcG9uZW50XHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmNvcHkgPSBjb3B5O1xudmFyIHNldCA9IHZlYzQuc2V0O1xuLyoqXHJcbiAqIEFkZHMgdHdvIHF1YXQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLnNldCA9IHNldDtcbnZhciBhZGQgPSB2ZWM0LmFkZDtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHF1YXQubXVsdGlwbHl9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5hZGQgPSBhZGQ7XG52YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcclxuICogU2NhbGVzIGEgcXVhdCBieSBhIHNjYWxhciBudW1iZXJcclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdGhlIHZlY3RvciB0byBzY2FsZVxyXG4gKiBAcGFyYW0ge051bWJlcn0gYiBhbW91bnQgdG8gc2NhbGUgdGhlIHZlY3RvciBieVxyXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5tdWwgPSBtdWw7XG52YXIgc2NhbGUgPSB2ZWM0LnNjYWxlO1xuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byBxdWF0J3NcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLnNjYWxlID0gc2NhbGU7XG52YXIgZG90ID0gdmVjNC5kb3Q7XG4vKipcclxuICogUGVyZm9ybXMgYSBsaW5lYXIgaW50ZXJwb2xhdGlvbiBiZXR3ZWVuIHR3byBxdWF0J3NcclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmRvdCA9IGRvdDtcbnZhciBsZXJwID0gdmVjNC5sZXJwO1xuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIHF1YXRcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcclxuICovXG5cbmV4cG9ydHMubGVycCA9IGxlcnA7XG52YXIgbGVuZ3RoID0gdmVjNC5sZW5ndGg7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0Lmxlbmd0aH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmxlbmd0aCA9IGxlbmd0aDtcbnZhciBsZW4gPSBsZW5ndGg7XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBsZW5ndGggb2YgYSBxdWF0XHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHZlY3RvciB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMubGVuID0gbGVuO1xudmFyIHNxdWFyZWRMZW5ndGggPSB2ZWM0LnNxdWFyZWRMZW5ndGg7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0LnNxdWFyZWRMZW5ndGh9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5zcXVhcmVkTGVuZ3RoID0gc3F1YXJlZExlbmd0aDtcbnZhciBzcXJMZW4gPSBzcXVhcmVkTGVuZ3RoO1xuLyoqXHJcbiAqIE5vcm1hbGl6ZSBhIHF1YXRcclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXRlcm5pb24gdG8gbm9ybWFsaXplXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLnNxckxlbiA9IHNxckxlbjtcbnZhciBub3JtYWxpemUgPSB2ZWM0Lm5vcm1hbGl6ZTtcbi8qKlxyXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBxdWF0ZXJuaW9ucyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIFRoZSBmaXJzdCBxdWF0ZXJuaW9uLlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiBUaGUgc2Vjb25kIHF1YXRlcm5pb24uXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuZXhwb3J0cy5ub3JtYWxpemUgPSBub3JtYWxpemU7XG52YXIgZXhhY3RFcXVhbHMgPSB2ZWM0LmV4YWN0RXF1YWxzO1xuLyoqXHJcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHF1YXRlcm5pb25zIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgVGhlIGZpcnN0IHZlY3Rvci5cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgVGhlIHNlY29uZCB2ZWN0b3IuXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuZXhwb3J0cy5leGFjdEVxdWFscyA9IGV4YWN0RXF1YWxzO1xudmFyIGVxdWFscyA9IHZlYzQuZXF1YWxzO1xuLyoqXHJcbiAqIFNldHMgYSBxdWF0ZXJuaW9uIHRvIHJlcHJlc2VudCB0aGUgc2hvcnRlc3Qgcm90YXRpb24gZnJvbSBvbmVcclxuICogdmVjdG9yIHRvIGFub3RoZXIuXHJcbiAqXHJcbiAqIEJvdGggdmVjdG9ycyBhcmUgYXNzdW1lZCB0byBiZSB1bml0IGxlbmd0aC5cclxuICpcclxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uLlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgaW5pdGlhbCB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIGRlc3RpbmF0aW9uIHZlY3RvclxyXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XHJcbiAqL1xuXG5leHBvcnRzLmVxdWFscyA9IGVxdWFscztcblxudmFyIHJvdGF0aW9uVG8gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0bXB2ZWMzID0gdmVjMy5jcmVhdGUoKTtcbiAgdmFyIHhVbml0VmVjMyA9IHZlYzMuZnJvbVZhbHVlcygxLCAwLCAwKTtcbiAgdmFyIHlVbml0VmVjMyA9IHZlYzMuZnJvbVZhbHVlcygwLCAxLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvdXQsIGEsIGIpIHtcbiAgICB2YXIgZG90ID0gdmVjMy5kb3QoYSwgYik7XG5cbiAgICBpZiAoZG90IDwgLTAuOTk5OTk5KSB7XG4gICAgICB2ZWMzLmNyb3NzKHRtcHZlYzMsIHhVbml0VmVjMywgYSk7XG4gICAgICBpZiAodmVjMy5sZW4odG1wdmVjMykgPCAwLjAwMDAwMSkgdmVjMy5jcm9zcyh0bXB2ZWMzLCB5VW5pdFZlYzMsIGEpO1xuICAgICAgdmVjMy5ub3JtYWxpemUodG1wdmVjMywgdG1wdmVjMyk7XG4gICAgICBzZXRBeGlzQW5nbGUob3V0LCB0bXB2ZWMzLCBNYXRoLlBJKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfSBlbHNlIGlmIChkb3QgPiAwLjk5OTk5OSkge1xuICAgICAgb3V0WzBdID0gMDtcbiAgICAgIG91dFsxXSA9IDA7XG4gICAgICBvdXRbMl0gPSAwO1xuICAgICAgb3V0WzNdID0gMTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZlYzMuY3Jvc3ModG1wdmVjMywgYSwgYik7XG4gICAgICBvdXRbMF0gPSB0bXB2ZWMzWzBdO1xuICAgICAgb3V0WzFdID0gdG1wdmVjM1sxXTtcbiAgICAgIG91dFsyXSA9IHRtcHZlYzNbMl07XG4gICAgICBvdXRbM10gPSAxICsgZG90O1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZShvdXQsIG91dCk7XG4gICAgfVxuICB9O1xufSgpO1xuLyoqXHJcbiAqIFBlcmZvcm1zIGEgc3BoZXJpY2FsIGxpbmVhciBpbnRlcnBvbGF0aW9uIHdpdGggdHdvIGNvbnRyb2wgcG9pbnRzXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGMgdGhlIHRoaXJkIG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGQgdGhlIGZvdXJ0aCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcclxuICogQHJldHVybnMge3F1YXR9IG91dFxyXG4gKi9cblxuXG5leHBvcnRzLnJvdGF0aW9uVG8gPSByb3RhdGlvblRvO1xuXG52YXIgc3FsZXJwID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdGVtcDEgPSBjcmVhdGUoKTtcbiAgdmFyIHRlbXAyID0gY3JlYXRlKCk7XG4gIHJldHVybiBmdW5jdGlvbiAob3V0LCBhLCBiLCBjLCBkLCB0KSB7XG4gICAgc2xlcnAodGVtcDEsIGEsIGQsIHQpO1xuICAgIHNsZXJwKHRlbXAyLCBiLCBjLCB0KTtcbiAgICBzbGVycChvdXQsIHRlbXAxLCB0ZW1wMiwgMiAqIHQgKiAoMSAtIHQpKTtcbiAgICByZXR1cm4gb3V0O1xuICB9O1xufSgpO1xuLyoqXHJcbiAqIFNldHMgdGhlIHNwZWNpZmllZCBxdWF0ZXJuaW9uIHdpdGggdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuXHJcbiAqIGF4ZXMuIEVhY2ggYXhpcyBpcyBhIHZlYzMgYW5kIGlzIGV4cGVjdGVkIHRvIGJlIHVuaXQgbGVuZ3RoIGFuZFxyXG4gKiBwZXJwZW5kaWN1bGFyIHRvIGFsbCBvdGhlciBzcGVjaWZpZWQgYXhlcy5cclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHZpZXcgIHRoZSB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSB2aWV3aW5nIGRpcmVjdGlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gcmlnaHQgdGhlIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIGxvY2FsIFwicmlnaHRcIiBkaXJlY3Rpb25cclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHVwICAgIHRoZSB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSBsb2NhbCBcInVwXCIgZGlyZWN0aW9uXHJcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcclxuICovXG5cblxuZXhwb3J0cy5zcWxlcnAgPSBzcWxlcnA7XG5cbnZhciBzZXRBeGVzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbWF0ciA9IG1hdDMuY3JlYXRlKCk7XG4gIHJldHVybiBmdW5jdGlvbiAob3V0LCB2aWV3LCByaWdodCwgdXApIHtcbiAgICBtYXRyWzBdID0gcmlnaHRbMF07XG4gICAgbWF0clszXSA9IHJpZ2h0WzFdO1xuICAgIG1hdHJbNl0gPSByaWdodFsyXTtcbiAgICBtYXRyWzFdID0gdXBbMF07XG4gICAgbWF0cls0XSA9IHVwWzFdO1xuICAgIG1hdHJbN10gPSB1cFsyXTtcbiAgICBtYXRyWzJdID0gLXZpZXdbMF07XG4gICAgbWF0cls1XSA9IC12aWV3WzFdO1xuICAgIG1hdHJbOF0gPSAtdmlld1syXTtcbiAgICByZXR1cm4gbm9ybWFsaXplKG91dCwgZnJvbU1hdDMob3V0LCBtYXRyKSk7XG4gIH07XG59KCk7XG5cbmV4cG9ydHMuc2V0QXhlcyA9IHNldEF4ZXM7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfTsgfSBlbHNlIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mKG9iaik7IH1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuY3JlYXRlID0gY3JlYXRlO1xuZXhwb3J0cy5jbG9uZSA9IGNsb25lO1xuZXhwb3J0cy5mcm9tVmFsdWVzID0gZnJvbVZhbHVlcztcbmV4cG9ydHMuZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25WYWx1ZXMgPSBmcm9tUm90YXRpb25UcmFuc2xhdGlvblZhbHVlcztcbmV4cG9ydHMuZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24gPSBmcm9tUm90YXRpb25UcmFuc2xhdGlvbjtcbmV4cG9ydHMuZnJvbVRyYW5zbGF0aW9uID0gZnJvbVRyYW5zbGF0aW9uO1xuZXhwb3J0cy5mcm9tUm90YXRpb24gPSBmcm9tUm90YXRpb247XG5leHBvcnRzLmZyb21NYXQ0ID0gZnJvbU1hdDQ7XG5leHBvcnRzLmNvcHkgPSBjb3B5O1xuZXhwb3J0cy5pZGVudGl0eSA9IGlkZW50aXR5O1xuZXhwb3J0cy5zZXQgPSBzZXQ7XG5leHBvcnRzLmdldER1YWwgPSBnZXREdWFsO1xuZXhwb3J0cy5zZXREdWFsID0gc2V0RHVhbDtcbmV4cG9ydHMuZ2V0VHJhbnNsYXRpb24gPSBnZXRUcmFuc2xhdGlvbjtcbmV4cG9ydHMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xuZXhwb3J0cy5yb3RhdGVYID0gcm90YXRlWDtcbmV4cG9ydHMucm90YXRlWSA9IHJvdGF0ZVk7XG5leHBvcnRzLnJvdGF0ZVogPSByb3RhdGVaO1xuZXhwb3J0cy5yb3RhdGVCeVF1YXRBcHBlbmQgPSByb3RhdGVCeVF1YXRBcHBlbmQ7XG5leHBvcnRzLnJvdGF0ZUJ5UXVhdFByZXBlbmQgPSByb3RhdGVCeVF1YXRQcmVwZW5kO1xuZXhwb3J0cy5yb3RhdGVBcm91bmRBeGlzID0gcm90YXRlQXJvdW5kQXhpcztcbmV4cG9ydHMuYWRkID0gYWRkO1xuZXhwb3J0cy5tdWx0aXBseSA9IG11bHRpcGx5O1xuZXhwb3J0cy5zY2FsZSA9IHNjYWxlO1xuZXhwb3J0cy5sZXJwID0gbGVycDtcbmV4cG9ydHMuaW52ZXJ0ID0gaW52ZXJ0O1xuZXhwb3J0cy5jb25qdWdhdGUgPSBjb25qdWdhdGU7XG5leHBvcnRzLm5vcm1hbGl6ZSA9IG5vcm1hbGl6ZTtcbmV4cG9ydHMuc3RyID0gc3RyO1xuZXhwb3J0cy5leGFjdEVxdWFscyA9IGV4YWN0RXF1YWxzO1xuZXhwb3J0cy5lcXVhbHMgPSBlcXVhbHM7XG5leHBvcnRzLnNxckxlbiA9IGV4cG9ydHMuc3F1YXJlZExlbmd0aCA9IGV4cG9ydHMubGVuID0gZXhwb3J0cy5sZW5ndGggPSBleHBvcnRzLmRvdCA9IGV4cG9ydHMubXVsID0gZXhwb3J0cy5zZXRSZWFsID0gZXhwb3J0cy5nZXRSZWFsID0gdm9pZCAwO1xuXG52YXIgZ2xNYXRyaXggPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9jb21tb24uanNcIikpO1xuXG52YXIgcXVhdCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL3F1YXQuanNcIikpO1xuXG52YXIgbWF0NCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL21hdDQuanNcIikpO1xuXG5mdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IGlmICh0eXBlb2YgV2Vha01hcCAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gbnVsbDsgdmFyIGNhY2hlID0gbmV3IFdlYWtNYXAoKTsgX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlID0gZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCkgeyByZXR1cm4gY2FjaGU7IH07IHJldHVybiBjYWNoZTsgfVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGlmIChvYmogPT09IG51bGwgfHwgX3R5cGVvZihvYmopICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmogIT09IFwiZnVuY3Rpb25cIikgeyByZXR1cm4geyBcImRlZmF1bHRcIjogb2JqIH07IH0gdmFyIGNhY2hlID0gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCk7IGlmIChjYWNoZSAmJiBjYWNoZS5oYXMob2JqKSkgeyByZXR1cm4gY2FjaGUuZ2V0KG9iaik7IH0gdmFyIG5ld09iaiA9IHt9OyB2YXIgaGFzUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHsgdmFyIGRlc2MgPSBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KSA6IG51bGw7IGlmIChkZXNjICYmIChkZXNjLmdldCB8fCBkZXNjLnNldCkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld09iaiwga2V5LCBkZXNjKTsgfSBlbHNlIHsgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IH0gbmV3T2JqW1wiZGVmYXVsdFwiXSA9IG9iajsgaWYgKGNhY2hlKSB7IGNhY2hlLnNldChvYmosIG5ld09iaik7IH0gcmV0dXJuIG5ld09iajsgfVxuXG4vKipcclxuICogRHVhbCBRdWF0ZXJuaW9uPGJyPlxyXG4gKiBGb3JtYXQ6IFtyZWFsLCBkdWFsXTxicj5cclxuICogUXVhdGVybmlvbiBmb3JtYXQ6IFhZWlc8YnI+XHJcbiAqIE1ha2Ugc3VyZSB0byBoYXZlIG5vcm1hbGl6ZWQgZHVhbCBxdWF0ZXJuaW9ucywgb3RoZXJ3aXNlIHRoZSBmdW5jdGlvbnMgbWF5IG5vdCB3b3JrIGFzIGludGVuZGVkLjxicj5cclxuICogQG1vZHVsZSBxdWF0MlxyXG4gKi9cblxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgZHVhbCBxdWF0XHJcbiAqXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gYSBuZXcgZHVhbCBxdWF0ZXJuaW9uIFtyZWFsIC0+IHJvdGF0aW9uLCBkdWFsIC0+IHRyYW5zbGF0aW9uXVxyXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgdmFyIGRxID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoOCk7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgZHFbMF0gPSAwO1xuICAgIGRxWzFdID0gMDtcbiAgICBkcVsyXSA9IDA7XG4gICAgZHFbNF0gPSAwO1xuICAgIGRxWzVdID0gMDtcbiAgICBkcVs2XSA9IDA7XG4gICAgZHFbN10gPSAwO1xuICB9XG5cbiAgZHFbM10gPSAxO1xuICByZXR1cm4gZHE7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyBxdWF0IGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgcXVhdGVybmlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgZHVhbCBxdWF0ZXJuaW9uIHRvIGNsb25lXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gbmV3IGR1YWwgcXVhdGVybmlvblxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxuZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgZHEgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg4KTtcbiAgZHFbMF0gPSBhWzBdO1xuICBkcVsxXSA9IGFbMV07XG4gIGRxWzJdID0gYVsyXTtcbiAgZHFbM10gPSBhWzNdO1xuICBkcVs0XSA9IGFbNF07XG4gIGRxWzVdID0gYVs1XTtcbiAgZHFbNl0gPSBhWzZdO1xuICBkcVs3XSA9IGFbN107XG4gIHJldHVybiBkcTtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IGR1YWwgcXVhdCBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IHgxIFggY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5MSBZIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0gejEgWiBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHcxIFcgY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4MiBYIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0geTIgWSBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHoyIFogY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB3MiBXIGNvbXBvbmVudFxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG5ldyBkdWFsIHF1YXRlcm5pb25cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21WYWx1ZXMoeDEsIHkxLCB6MSwgdzEsIHgyLCB5MiwgejIsIHcyKSB7XG4gIHZhciBkcSA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDgpO1xuICBkcVswXSA9IHgxO1xuICBkcVsxXSA9IHkxO1xuICBkcVsyXSA9IHoxO1xuICBkcVszXSA9IHcxO1xuICBkcVs0XSA9IHgyO1xuICBkcVs1XSA9IHkyO1xuICBkcVs2XSA9IHoyO1xuICBkcVs3XSA9IHcyO1xuICByZXR1cm4gZHE7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyBkdWFsIHF1YXQgZnJvbSB0aGUgZ2l2ZW4gdmFsdWVzIChxdWF0IGFuZCB0cmFuc2xhdGlvbilcclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IHgxIFggY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5MSBZIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0gejEgWiBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHcxIFcgY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4MiBYIGNvbXBvbmVudCAodHJhbnNsYXRpb24pXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5MiBZIGNvbXBvbmVudCAodHJhbnNsYXRpb24pXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB6MiBaIGNvbXBvbmVudCAodHJhbnNsYXRpb24pXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gbmV3IGR1YWwgcXVhdGVybmlvblxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25WYWx1ZXMoeDEsIHkxLCB6MSwgdzEsIHgyLCB5MiwgejIpIHtcbiAgdmFyIGRxID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoOCk7XG4gIGRxWzBdID0geDE7XG4gIGRxWzFdID0geTE7XG4gIGRxWzJdID0gejE7XG4gIGRxWzNdID0gdzE7XG4gIHZhciBheCA9IHgyICogMC41LFxuICAgICAgYXkgPSB5MiAqIDAuNSxcbiAgICAgIGF6ID0gejIgKiAwLjU7XG4gIGRxWzRdID0gYXggKiB3MSArIGF5ICogejEgLSBheiAqIHkxO1xuICBkcVs1XSA9IGF5ICogdzEgKyBheiAqIHgxIC0gYXggKiB6MTtcbiAgZHFbNl0gPSBheiAqIHcxICsgYXggKiB5MSAtIGF5ICogeDE7XG4gIGRxWzddID0gLWF4ICogeDEgLSBheSAqIHkxIC0gYXogKiB6MTtcbiAgcmV0dXJuIGRxO1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBkdWFsIHF1YXQgZnJvbSBhIHF1YXRlcm5pb24gYW5kIGEgdHJhbnNsYXRpb25cclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBkdWFsIHF1YXRlcm5pb24gcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgYSBub3JtYWxpemVkIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHQgdHJhbmxhdGlvbiB2ZWN0b3JcclxuICogQHJldHVybnMge3F1YXQyfSBkdWFsIHF1YXRlcm5pb24gcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uKG91dCwgcSwgdCkge1xuICB2YXIgYXggPSB0WzBdICogMC41LFxuICAgICAgYXkgPSB0WzFdICogMC41LFxuICAgICAgYXogPSB0WzJdICogMC41LFxuICAgICAgYnggPSBxWzBdLFxuICAgICAgYnkgPSBxWzFdLFxuICAgICAgYnogPSBxWzJdLFxuICAgICAgYncgPSBxWzNdO1xuICBvdXRbMF0gPSBieDtcbiAgb3V0WzFdID0gYnk7XG4gIG91dFsyXSA9IGJ6O1xuICBvdXRbM10gPSBidztcbiAgb3V0WzRdID0gYXggKiBidyArIGF5ICogYnogLSBheiAqIGJ5O1xuICBvdXRbNV0gPSBheSAqIGJ3ICsgYXogKiBieCAtIGF4ICogYno7XG4gIG91dFs2XSA9IGF6ICogYncgKyBheCAqIGJ5IC0gYXkgKiBieDtcbiAgb3V0WzddID0gLWF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgZHVhbCBxdWF0IGZyb20gYSB0cmFuc2xhdGlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGR1YWwgcXVhdGVybmlvbiByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdCB0cmFuc2xhdGlvbiB2ZWN0b3JcclxuICogQHJldHVybnMge3F1YXQyfSBkdWFsIHF1YXRlcm5pb24gcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21UcmFuc2xhdGlvbihvdXQsIHQpIHtcbiAgb3V0WzBdID0gMDtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMTtcbiAgb3V0WzRdID0gdFswXSAqIDAuNTtcbiAgb3V0WzVdID0gdFsxXSAqIDAuNTtcbiAgb3V0WzZdID0gdFsyXSAqIDAuNTtcbiAgb3V0WzddID0gMDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgZHVhbCBxdWF0IGZyb20gYSBxdWF0ZXJuaW9uXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gZHVhbCBxdWF0ZXJuaW9uIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIHRoZSBxdWF0ZXJuaW9uXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gZHVhbCBxdWF0ZXJuaW9uIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tUm90YXRpb24ob3V0LCBxKSB7XG4gIG91dFswXSA9IHFbMF07XG4gIG91dFsxXSA9IHFbMV07XG4gIG91dFsyXSA9IHFbMl07XG4gIG91dFszXSA9IHFbM107XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyBkdWFsIHF1YXQgZnJvbSBhIG1hdHJpeCAoNHg0KVxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIGR1YWwgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4XHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gZHVhbCBxdWF0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tTWF0NChvdXQsIGEpIHtcbiAgLy9UT0RPIE9wdGltaXplIHRoaXNcbiAgdmFyIG91dGVyID0gcXVhdC5jcmVhdGUoKTtcbiAgbWF0NC5nZXRSb3RhdGlvbihvdXRlciwgYSk7XG4gIHZhciB0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIG1hdDQuZ2V0VHJhbnNsYXRpb24odCwgYSk7XG4gIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uKG91dCwgb3V0ZXIsIHQpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBkdWFsIHF1YXQgdG8gYW5vdGhlclxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBzb3VyY2UgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG5mdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNldCBhIGR1YWwgcXVhdCB0byB0aGUgaWRlbnRpdHkgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cclxuICogQHJldHVybnMge3F1YXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaWRlbnRpdHkob3V0KSB7XG4gIG91dFswXSA9IDA7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDE7XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgZHVhbCBxdWF0IHRvIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge051bWJlcn0geDEgWCBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHkxIFkgY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB6MSBaIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0gdzEgVyBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHgyIFggY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5MiBZIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0gejIgWiBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHcyIFcgY29tcG9uZW50XHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG5mdW5jdGlvbiBzZXQob3V0LCB4MSwgeTEsIHoxLCB3MSwgeDIsIHkyLCB6MiwgdzIpIHtcbiAgb3V0WzBdID0geDE7XG4gIG91dFsxXSA9IHkxO1xuICBvdXRbMl0gPSB6MTtcbiAgb3V0WzNdID0gdzE7XG4gIG91dFs0XSA9IHgyO1xuICBvdXRbNV0gPSB5MjtcbiAgb3V0WzZdID0gejI7XG4gIG91dFs3XSA9IHcyO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEdldHMgdGhlIHJlYWwgcGFydCBvZiBhIGR1YWwgcXVhdFxyXG4gKiBAcGFyYW0gIHtxdWF0fSBvdXQgcmVhbCBwYXJ0XHJcbiAqIEBwYXJhbSAge1JlYWRvbmx5UXVhdDJ9IGEgRHVhbCBRdWF0ZXJuaW9uXHJcbiAqIEByZXR1cm4ge3F1YXR9IHJlYWwgcGFydFxyXG4gKi9cblxuXG52YXIgZ2V0UmVhbCA9IHF1YXQuY29weTtcbi8qKlxyXG4gKiBHZXRzIHRoZSBkdWFsIHBhcnQgb2YgYSBkdWFsIHF1YXRcclxuICogQHBhcmFtICB7cXVhdH0gb3V0IGR1YWwgcGFydFxyXG4gKiBAcGFyYW0gIHtSZWFkb25seVF1YXQyfSBhIER1YWwgUXVhdGVybmlvblxyXG4gKiBAcmV0dXJuIHtxdWF0fSBkdWFsIHBhcnRcclxuICovXG5cbmV4cG9ydHMuZ2V0UmVhbCA9IGdldFJlYWw7XG5cbmZ1bmN0aW9uIGdldER1YWwob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbNF07XG4gIG91dFsxXSA9IGFbNV07XG4gIG91dFsyXSA9IGFbNl07XG4gIG91dFszXSA9IGFbN107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IHRoZSByZWFsIGNvbXBvbmVudCBvZiBhIGR1YWwgcXVhdCB0byB0aGUgZ2l2ZW4gcXVhdGVybmlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIGEgcXVhdGVybmlvbiByZXByZXNlbnRpbmcgdGhlIHJlYWwgcGFydFxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxudmFyIHNldFJlYWwgPSBxdWF0LmNvcHk7XG4vKipcclxuICogU2V0IHRoZSBkdWFsIGNvbXBvbmVudCBvZiBhIGR1YWwgcXVhdCB0byB0aGUgZ2l2ZW4gcXVhdGVybmlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIGEgcXVhdGVybmlvbiByZXByZXNlbnRpbmcgdGhlIGR1YWwgcGFydFxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuc2V0UmVhbCA9IHNldFJlYWw7XG5cbmZ1bmN0aW9uIHNldER1YWwob3V0LCBxKSB7XG4gIG91dFs0XSA9IHFbMF07XG4gIG91dFs1XSA9IHFbMV07XG4gIG91dFs2XSA9IHFbMl07XG4gIG91dFs3XSA9IHFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogR2V0cyB0aGUgdHJhbnNsYXRpb24gb2YgYSBub3JtYWxpemVkIGR1YWwgcXVhdFxyXG4gKiBAcGFyYW0gIHt2ZWMzfSBvdXQgdHJhbnNsYXRpb25cclxuICogQHBhcmFtICB7UmVhZG9ubHlRdWF0Mn0gYSBEdWFsIFF1YXRlcm5pb24gdG8gYmUgZGVjb21wb3NlZFxyXG4gKiBAcmV0dXJuIHt2ZWMzfSB0cmFuc2xhdGlvblxyXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRUcmFuc2xhdGlvbihvdXQsIGEpIHtcbiAgdmFyIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XSxcbiAgICAgIGJ4ID0gLWFbMF0sXG4gICAgICBieSA9IC1hWzFdLFxuICAgICAgYnogPSAtYVsyXSxcbiAgICAgIGJ3ID0gYVszXTtcbiAgb3V0WzBdID0gKGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnkpICogMjtcbiAgb3V0WzFdID0gKGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnopICogMjtcbiAgb3V0WzJdID0gKGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYngpICogMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBUcmFuc2xhdGVzIGEgZHVhbCBxdWF0IGJ5IHRoZSBnaXZlbiB2ZWN0b3JcclxuICpcclxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZHVhbCBxdWF0ZXJuaW9uIHRvIHRyYW5zbGF0ZVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiB2ZWN0b3IgdG8gdHJhbnNsYXRlIGJ5XHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgdmFyIGF4MSA9IGFbMF0sXG4gICAgICBheTEgPSBhWzFdLFxuICAgICAgYXoxID0gYVsyXSxcbiAgICAgIGF3MSA9IGFbM10sXG4gICAgICBieDEgPSB2WzBdICogMC41LFxuICAgICAgYnkxID0gdlsxXSAqIDAuNSxcbiAgICAgIGJ6MSA9IHZbMl0gKiAwLjUsXG4gICAgICBheDIgPSBhWzRdLFxuICAgICAgYXkyID0gYVs1XSxcbiAgICAgIGF6MiA9IGFbNl0sXG4gICAgICBhdzIgPSBhWzddO1xuICBvdXRbMF0gPSBheDE7XG4gIG91dFsxXSA9IGF5MTtcbiAgb3V0WzJdID0gYXoxO1xuICBvdXRbM10gPSBhdzE7XG4gIG91dFs0XSA9IGF3MSAqIGJ4MSArIGF5MSAqIGJ6MSAtIGF6MSAqIGJ5MSArIGF4MjtcbiAgb3V0WzVdID0gYXcxICogYnkxICsgYXoxICogYngxIC0gYXgxICogYnoxICsgYXkyO1xuICBvdXRbNl0gPSBhdzEgKiBiejEgKyBheDEgKiBieTEgLSBheTEgKiBieDEgKyBhejI7XG4gIG91dFs3XSA9IC1heDEgKiBieDEgLSBheTEgKiBieTEgLSBhejEgKiBiejEgKyBhdzI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUm90YXRlcyBhIGR1YWwgcXVhdCBhcm91bmQgdGhlIFggYXhpc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBkdWFsIHF1YXRlcm5pb24gdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWQgaG93IGZhciBzaG91bGQgdGhlIHJvdGF0aW9uIGJlXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZVgob3V0LCBhLCByYWQpIHtcbiAgdmFyIGJ4ID0gLWFbMF0sXG4gICAgICBieSA9IC1hWzFdLFxuICAgICAgYnogPSAtYVsyXSxcbiAgICAgIGJ3ID0gYVszXSxcbiAgICAgIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XSxcbiAgICAgIGF4MSA9IGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnksXG4gICAgICBheTEgPSBheSAqIGJ3ICsgYXcgKiBieSArIGF6ICogYnggLSBheCAqIGJ6LFxuICAgICAgYXoxID0gYXogKiBidyArIGF3ICogYnogKyBheCAqIGJ5IC0gYXkgKiBieCxcbiAgICAgIGF3MSA9IGF3ICogYncgLSBheCAqIGJ4IC0gYXkgKiBieSAtIGF6ICogYno7XG4gIHF1YXQucm90YXRlWChvdXQsIGEsIHJhZCk7XG4gIGJ4ID0gb3V0WzBdO1xuICBieSA9IG91dFsxXTtcbiAgYnogPSBvdXRbMl07XG4gIGJ3ID0gb3V0WzNdO1xuICBvdXRbNF0gPSBheDEgKiBidyArIGF3MSAqIGJ4ICsgYXkxICogYnogLSBhejEgKiBieTtcbiAgb3V0WzVdID0gYXkxICogYncgKyBhdzEgKiBieSArIGF6MSAqIGJ4IC0gYXgxICogYno7XG4gIG91dFs2XSA9IGF6MSAqIGJ3ICsgYXcxICogYnogKyBheDEgKiBieSAtIGF5MSAqIGJ4O1xuICBvdXRbN10gPSBhdzEgKiBidyAtIGF4MSAqIGJ4IC0gYXkxICogYnkgLSBhejEgKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSb3RhdGVzIGEgZHVhbCBxdWF0IGFyb3VuZCB0aGUgWSBheGlzXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIGR1YWwgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGR1YWwgcXVhdGVybmlvbiB0byByb3RhdGVcclxuICogQHBhcmFtIHtudW1iZXJ9IHJhZCBob3cgZmFyIHNob3VsZCB0aGUgcm90YXRpb24gYmVcclxuICogQHJldHVybnMge3F1YXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gcm90YXRlWShvdXQsIGEsIHJhZCkge1xuICB2YXIgYnggPSAtYVswXSxcbiAgICAgIGJ5ID0gLWFbMV0sXG4gICAgICBieiA9IC1hWzJdLFxuICAgICAgYncgPSBhWzNdLFxuICAgICAgYXggPSBhWzRdLFxuICAgICAgYXkgPSBhWzVdLFxuICAgICAgYXogPSBhWzZdLFxuICAgICAgYXcgPSBhWzddLFxuICAgICAgYXgxID0gYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieSxcbiAgICAgIGF5MSA9IGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnosXG4gICAgICBhejEgPSBheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4LFxuICAgICAgYXcxID0gYXcgKiBidyAtIGF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgcXVhdC5yb3RhdGVZKG91dCwgYSwgcmFkKTtcbiAgYnggPSBvdXRbMF07XG4gIGJ5ID0gb3V0WzFdO1xuICBieiA9IG91dFsyXTtcbiAgYncgPSBvdXRbM107XG4gIG91dFs0XSA9IGF4MSAqIGJ3ICsgYXcxICogYnggKyBheTEgKiBieiAtIGF6MSAqIGJ5O1xuICBvdXRbNV0gPSBheTEgKiBidyArIGF3MSAqIGJ5ICsgYXoxICogYnggLSBheDEgKiBiejtcbiAgb3V0WzZdID0gYXoxICogYncgKyBhdzEgKiBieiArIGF4MSAqIGJ5IC0gYXkxICogYng7XG4gIG91dFs3XSA9IGF3MSAqIGJ3IC0gYXgxICogYnggLSBheTEgKiBieSAtIGF6MSAqIGJ6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBkdWFsIHF1YXQgYXJvdW5kIHRoZSBaIGF4aXNcclxuICpcclxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZHVhbCBxdWF0ZXJuaW9uIHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGhvdyBmYXIgc2hvdWxkIHRoZSByb3RhdGlvbiBiZVxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGVaKG91dCwgYSwgcmFkKSB7XG4gIHZhciBieCA9IC1hWzBdLFxuICAgICAgYnkgPSAtYVsxXSxcbiAgICAgIGJ6ID0gLWFbMl0sXG4gICAgICBidyA9IGFbM10sXG4gICAgICBheCA9IGFbNF0sXG4gICAgICBheSA9IGFbNV0sXG4gICAgICBheiA9IGFbNl0sXG4gICAgICBhdyA9IGFbN10sXG4gICAgICBheDEgPSBheCAqIGJ3ICsgYXcgKiBieCArIGF5ICogYnogLSBheiAqIGJ5LFxuICAgICAgYXkxID0gYXkgKiBidyArIGF3ICogYnkgKyBheiAqIGJ4IC0gYXggKiBieixcbiAgICAgIGF6MSA9IGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYngsXG4gICAgICBhdzEgPSBhdyAqIGJ3IC0gYXggKiBieCAtIGF5ICogYnkgLSBheiAqIGJ6O1xuICBxdWF0LnJvdGF0ZVoob3V0LCBhLCByYWQpO1xuICBieCA9IG91dFswXTtcbiAgYnkgPSBvdXRbMV07XG4gIGJ6ID0gb3V0WzJdO1xuICBidyA9IG91dFszXTtcbiAgb3V0WzRdID0gYXgxICogYncgKyBhdzEgKiBieCArIGF5MSAqIGJ6IC0gYXoxICogYnk7XG4gIG91dFs1XSA9IGF5MSAqIGJ3ICsgYXcxICogYnkgKyBhejEgKiBieCAtIGF4MSAqIGJ6O1xuICBvdXRbNl0gPSBhejEgKiBidyArIGF3MSAqIGJ6ICsgYXgxICogYnkgLSBheTEgKiBieDtcbiAgb3V0WzddID0gYXcxICogYncgLSBheDEgKiBieCAtIGF5MSAqIGJ5IC0gYXoxICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUm90YXRlcyBhIGR1YWwgcXVhdCBieSBhIGdpdmVuIHF1YXRlcm5pb24gKGEgKiBxKVxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBkdWFsIHF1YXRlcm5pb24gdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIHF1YXRlcm5pb24gdG8gcm90YXRlIGJ5XHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZUJ5UXVhdEFwcGVuZChvdXQsIGEsIHEpIHtcbiAgdmFyIHF4ID0gcVswXSxcbiAgICAgIHF5ID0gcVsxXSxcbiAgICAgIHF6ID0gcVsyXSxcbiAgICAgIHF3ID0gcVszXSxcbiAgICAgIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgb3V0WzBdID0gYXggKiBxdyArIGF3ICogcXggKyBheSAqIHF6IC0gYXogKiBxeTtcbiAgb3V0WzFdID0gYXkgKiBxdyArIGF3ICogcXkgKyBheiAqIHF4IC0gYXggKiBxejtcbiAgb3V0WzJdID0gYXogKiBxdyArIGF3ICogcXogKyBheCAqIHF5IC0gYXkgKiBxeDtcbiAgb3V0WzNdID0gYXcgKiBxdyAtIGF4ICogcXggLSBheSAqIHF5IC0gYXogKiBxejtcbiAgYXggPSBhWzRdO1xuICBheSA9IGFbNV07XG4gIGF6ID0gYVs2XTtcbiAgYXcgPSBhWzddO1xuICBvdXRbNF0gPSBheCAqIHF3ICsgYXcgKiBxeCArIGF5ICogcXogLSBheiAqIHF5O1xuICBvdXRbNV0gPSBheSAqIHF3ICsgYXcgKiBxeSArIGF6ICogcXggLSBheCAqIHF6O1xuICBvdXRbNl0gPSBheiAqIHF3ICsgYXcgKiBxeiArIGF4ICogcXkgLSBheSAqIHF4O1xuICBvdXRbN10gPSBhdyAqIHF3IC0gYXggKiBxeCAtIGF5ICogcXkgLSBheiAqIHF6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZXMgYSBkdWFsIHF1YXQgYnkgYSBnaXZlbiBxdWF0ZXJuaW9uIChxICogYSlcclxuICpcclxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIHF1YXRlcm5pb24gdG8gcm90YXRlIGJ5XHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZHVhbCBxdWF0ZXJuaW9uIHRvIHJvdGF0ZVxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGVCeVF1YXRQcmVwZW5kKG91dCwgcSwgYSkge1xuICB2YXIgcXggPSBxWzBdLFxuICAgICAgcXkgPSBxWzFdLFxuICAgICAgcXogPSBxWzJdLFxuICAgICAgcXcgPSBxWzNdLFxuICAgICAgYnggPSBhWzBdLFxuICAgICAgYnkgPSBhWzFdLFxuICAgICAgYnogPSBhWzJdLFxuICAgICAgYncgPSBhWzNdO1xuICBvdXRbMF0gPSBxeCAqIGJ3ICsgcXcgKiBieCArIHF5ICogYnogLSBxeiAqIGJ5O1xuICBvdXRbMV0gPSBxeSAqIGJ3ICsgcXcgKiBieSArIHF6ICogYnggLSBxeCAqIGJ6O1xuICBvdXRbMl0gPSBxeiAqIGJ3ICsgcXcgKiBieiArIHF4ICogYnkgLSBxeSAqIGJ4O1xuICBvdXRbM10gPSBxdyAqIGJ3IC0gcXggKiBieCAtIHF5ICogYnkgLSBxeiAqIGJ6O1xuICBieCA9IGFbNF07XG4gIGJ5ID0gYVs1XTtcbiAgYnogPSBhWzZdO1xuICBidyA9IGFbN107XG4gIG91dFs0XSA9IHF4ICogYncgKyBxdyAqIGJ4ICsgcXkgKiBieiAtIHF6ICogYnk7XG4gIG91dFs1XSA9IHF5ICogYncgKyBxdyAqIGJ5ICsgcXogKiBieCAtIHF4ICogYno7XG4gIG91dFs2XSA9IHF6ICogYncgKyBxdyAqIGJ6ICsgcXggKiBieSAtIHF5ICogYng7XG4gIG91dFs3XSA9IHF3ICogYncgLSBxeCAqIGJ4IC0gcXkgKiBieSAtIHF6ICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUm90YXRlcyBhIGR1YWwgcXVhdCBhcm91bmQgYSBnaXZlbiBheGlzLiBEb2VzIHRoZSBub3JtYWxpc2F0aW9uIGF1dG9tYXRpY2FsbHlcclxuICpcclxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZHVhbCBxdWF0ZXJuaW9uIHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYXhpcyB0aGUgYXhpcyB0byByb3RhdGUgYXJvdW5kXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgaG93IGZhciB0aGUgcm90YXRpb24gc2hvdWxkIGJlXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZUFyb3VuZEF4aXMob3V0LCBhLCBheGlzLCByYWQpIHtcbiAgLy9TcGVjaWFsIGNhc2UgZm9yIHJhZCA9IDBcbiAgaWYgKE1hdGguYWJzKHJhZCkgPCBnbE1hdHJpeC5FUFNJTE9OKSB7XG4gICAgcmV0dXJuIGNvcHkob3V0LCBhKTtcbiAgfVxuXG4gIHZhciBheGlzTGVuZ3RoID0gTWF0aC5oeXBvdChheGlzWzBdLCBheGlzWzFdLCBheGlzWzJdKTtcbiAgcmFkID0gcmFkICogMC41O1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBieCA9IHMgKiBheGlzWzBdIC8gYXhpc0xlbmd0aDtcbiAgdmFyIGJ5ID0gcyAqIGF4aXNbMV0gLyBheGlzTGVuZ3RoO1xuICB2YXIgYnogPSBzICogYXhpc1syXSAvIGF4aXNMZW5ndGg7XG4gIHZhciBidyA9IE1hdGguY29zKHJhZCk7XG4gIHZhciBheDEgPSBhWzBdLFxuICAgICAgYXkxID0gYVsxXSxcbiAgICAgIGF6MSA9IGFbMl0sXG4gICAgICBhdzEgPSBhWzNdO1xuICBvdXRbMF0gPSBheDEgKiBidyArIGF3MSAqIGJ4ICsgYXkxICogYnogLSBhejEgKiBieTtcbiAgb3V0WzFdID0gYXkxICogYncgKyBhdzEgKiBieSArIGF6MSAqIGJ4IC0gYXgxICogYno7XG4gIG91dFsyXSA9IGF6MSAqIGJ3ICsgYXcxICogYnogKyBheDEgKiBieSAtIGF5MSAqIGJ4O1xuICBvdXRbM10gPSBhdzEgKiBidyAtIGF4MSAqIGJ4IC0gYXkxICogYnkgLSBhejEgKiBiejtcbiAgdmFyIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XTtcbiAgb3V0WzRdID0gYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieTtcbiAgb3V0WzVdID0gYXkgKiBidyArIGF3ICogYnkgKyBheiAqIGJ4IC0gYXggKiBiejtcbiAgb3V0WzZdID0gYXogKiBidyArIGF3ICogYnogKyBheCAqIGJ5IC0gYXkgKiBieDtcbiAgb3V0WzddID0gYXcgKiBidyAtIGF4ICogYnggLSBheSAqIGJ5IC0gYXogKiBiejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBBZGRzIHR3byBkdWFsIHF1YXQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3F1YXQyfSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGFkZChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXTtcbiAgb3V0WzNdID0gYVszXSArIGJbM107XG4gIG91dFs0XSA9IGFbNF0gKyBiWzRdO1xuICBvdXRbNV0gPSBhWzVdICsgYls1XTtcbiAgb3V0WzZdID0gYVs2XSArIGJbNl07XG4gIG91dFs3XSA9IGFbN10gKyBiWzddO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE11bHRpcGxpZXMgdHdvIGR1YWwgcXVhdCdzXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIGR1YWwgcXVhdGVybmlvblxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtdWx0aXBseShvdXQsIGEsIGIpIHtcbiAgdmFyIGF4MCA9IGFbMF0sXG4gICAgICBheTAgPSBhWzFdLFxuICAgICAgYXowID0gYVsyXSxcbiAgICAgIGF3MCA9IGFbM10sXG4gICAgICBieDEgPSBiWzRdLFxuICAgICAgYnkxID0gYls1XSxcbiAgICAgIGJ6MSA9IGJbNl0sXG4gICAgICBidzEgPSBiWzddLFxuICAgICAgYXgxID0gYVs0XSxcbiAgICAgIGF5MSA9IGFbNV0sXG4gICAgICBhejEgPSBhWzZdLFxuICAgICAgYXcxID0gYVs3XSxcbiAgICAgIGJ4MCA9IGJbMF0sXG4gICAgICBieTAgPSBiWzFdLFxuICAgICAgYnowID0gYlsyXSxcbiAgICAgIGJ3MCA9IGJbM107XG4gIG91dFswXSA9IGF4MCAqIGJ3MCArIGF3MCAqIGJ4MCArIGF5MCAqIGJ6MCAtIGF6MCAqIGJ5MDtcbiAgb3V0WzFdID0gYXkwICogYncwICsgYXcwICogYnkwICsgYXowICogYngwIC0gYXgwICogYnowO1xuICBvdXRbMl0gPSBhejAgKiBidzAgKyBhdzAgKiBiejAgKyBheDAgKiBieTAgLSBheTAgKiBieDA7XG4gIG91dFszXSA9IGF3MCAqIGJ3MCAtIGF4MCAqIGJ4MCAtIGF5MCAqIGJ5MCAtIGF6MCAqIGJ6MDtcbiAgb3V0WzRdID0gYXgwICogYncxICsgYXcwICogYngxICsgYXkwICogYnoxIC0gYXowICogYnkxICsgYXgxICogYncwICsgYXcxICogYngwICsgYXkxICogYnowIC0gYXoxICogYnkwO1xuICBvdXRbNV0gPSBheTAgKiBidzEgKyBhdzAgKiBieTEgKyBhejAgKiBieDEgLSBheDAgKiBiejEgKyBheTEgKiBidzAgKyBhdzEgKiBieTAgKyBhejEgKiBieDAgLSBheDEgKiBiejA7XG4gIG91dFs2XSA9IGF6MCAqIGJ3MSArIGF3MCAqIGJ6MSArIGF4MCAqIGJ5MSAtIGF5MCAqIGJ4MSArIGF6MSAqIGJ3MCArIGF3MSAqIGJ6MCArIGF4MSAqIGJ5MCAtIGF5MSAqIGJ4MDtcbiAgb3V0WzddID0gYXcwICogYncxIC0gYXgwICogYngxIC0gYXkwICogYnkxIC0gYXowICogYnoxICsgYXcxICogYncwIC0gYXgxICogYngwIC0gYXkxICogYnkwIC0gYXoxICogYnowO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgcXVhdDIubXVsdGlwbHl9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG52YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcclxuICogU2NhbGVzIGEgZHVhbCBxdWF0IGJ5IGEgc2NhbGFyIG51bWJlclxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBkdWFsIHF1YXQgdG8gc2NhbGVcclxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSBkdWFsIHF1YXQgYnlcclxuICogQHJldHVybnMge3F1YXQyfSBvdXRcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLm11bCA9IG11bDtcblxuZnVuY3Rpb24gc2NhbGUob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICBvdXRbNF0gPSBhWzRdICogYjtcbiAgb3V0WzVdID0gYVs1XSAqIGI7XG4gIG91dFs2XSA9IGFbNl0gKiBiO1xuICBvdXRbN10gPSBhWzddICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gZHVhbCBxdWF0J3MgKFRoZSBkb3QgcHJvZHVjdCBvZiB0aGUgcmVhbCBwYXJ0cylcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge051bWJlcn0gZG90IHByb2R1Y3Qgb2YgYSBhbmQgYlxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cblxudmFyIGRvdCA9IHF1YXQuZG90O1xuLyoqXHJcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gZHVhbCBxdWF0cydzXHJcbiAqIE5PVEU6IFRoZSByZXN1bHRpbmcgZHVhbCBxdWF0ZXJuaW9ucyB3b24ndCBhbHdheXMgYmUgbm9ybWFsaXplZCAoVGhlIGVycm9yIGlzIG1vc3Qgbm90aWNlYWJsZSB3aGVuIHQgPSAwLjUpXHJcbiAqXHJcbiAqIEBwYXJhbSB7cXVhdDJ9IG91dCB0aGUgcmVjZWl2aW5nIGR1YWwgcXVhdFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqL1xuXG5leHBvcnRzLmRvdCA9IGRvdDtcblxuZnVuY3Rpb24gbGVycChvdXQsIGEsIGIsIHQpIHtcbiAgdmFyIG10ID0gMSAtIHQ7XG4gIGlmIChkb3QoYSwgYikgPCAwKSB0ID0gLXQ7XG4gIG91dFswXSA9IGFbMF0gKiBtdCArIGJbMF0gKiB0O1xuICBvdXRbMV0gPSBhWzFdICogbXQgKyBiWzFdICogdDtcbiAgb3V0WzJdID0gYVsyXSAqIG10ICsgYlsyXSAqIHQ7XG4gIG91dFszXSA9IGFbM10gKiBtdCArIGJbM10gKiB0O1xuICBvdXRbNF0gPSBhWzRdICogbXQgKyBiWzRdICogdDtcbiAgb3V0WzVdID0gYVs1XSAqIG10ICsgYls1XSAqIHQ7XG4gIG91dFs2XSA9IGFbNl0gKiBtdCArIGJbNl0gKiB0O1xuICBvdXRbN10gPSBhWzddICogbXQgKyBiWzddICogdDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBpbnZlcnNlIG9mIGEgZHVhbCBxdWF0LiBJZiB0aGV5IGFyZSBub3JtYWxpemVkLCBjb25qdWdhdGUgaXMgY2hlYXBlclxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBkdWFsIHF1YXRlcm5pb25cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIGR1YWwgcXVhdCB0byBjYWxjdWxhdGUgaW52ZXJzZSBvZlxyXG4gKiBAcmV0dXJucyB7cXVhdDJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBpbnZlcnQob3V0LCBhKSB7XG4gIHZhciBzcWxlbiA9IHNxdWFyZWRMZW5ndGgoYSk7XG4gIG91dFswXSA9IC1hWzBdIC8gc3FsZW47XG4gIG91dFsxXSA9IC1hWzFdIC8gc3FsZW47XG4gIG91dFsyXSA9IC1hWzJdIC8gc3FsZW47XG4gIG91dFszXSA9IGFbM10gLyBzcWxlbjtcbiAgb3V0WzRdID0gLWFbNF0gLyBzcWxlbjtcbiAgb3V0WzVdID0gLWFbNV0gLyBzcWxlbjtcbiAgb3V0WzZdID0gLWFbNl0gLyBzcWxlbjtcbiAgb3V0WzddID0gYVs3XSAvIHNxbGVuO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGNvbmp1Z2F0ZSBvZiBhIGR1YWwgcXVhdFxyXG4gKiBJZiB0aGUgZHVhbCBxdWF0ZXJuaW9uIGlzIG5vcm1hbGl6ZWQsIHRoaXMgZnVuY3Rpb24gaXMgZmFzdGVyIHRoYW4gcXVhdDIuaW52ZXJzZSBhbmQgcHJvZHVjZXMgdGhlIHNhbWUgcmVzdWx0LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3F1YXQyfSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBjb25qdWdhdGUgb2ZcclxuICogQHJldHVybnMge3F1YXQyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gY29uanVnYXRlKG91dCwgYSkge1xuICBvdXRbMF0gPSAtYVswXTtcbiAgb3V0WzFdID0gLWFbMV07XG4gIG91dFsyXSA9IC1hWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSAtYVs0XTtcbiAgb3V0WzVdID0gLWFbNV07XG4gIG91dFs2XSA9IC1hWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIGR1YWwgcXVhdFxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgZHVhbCBxdWF0IHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbnZhciBsZW5ndGggPSBxdWF0Lmxlbmd0aDtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHF1YXQyLmxlbmd0aH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmxlbmd0aCA9IGxlbmd0aDtcbnZhciBsZW4gPSBsZW5ndGg7XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBsZW5ndGggb2YgYSBkdWFsIHF1YXRcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIGR1YWwgcXVhdCB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMubGVuID0gbGVuO1xudmFyIHNxdWFyZWRMZW5ndGggPSBxdWF0LnNxdWFyZWRMZW5ndGg7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0Mi5zcXVhcmVkTGVuZ3RofVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuc3F1YXJlZExlbmd0aCA9IHNxdWFyZWRMZW5ndGg7XG52YXIgc3FyTGVuID0gc3F1YXJlZExlbmd0aDtcbi8qKlxyXG4gKiBOb3JtYWxpemUgYSBkdWFsIHF1YXRcclxuICpcclxuICogQHBhcmFtIHtxdWF0Mn0gb3V0IHRoZSByZWNlaXZpbmcgZHVhbCBxdWF0ZXJuaW9uXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSBkdWFsIHF1YXRlcm5pb24gdG8gbm9ybWFsaXplXHJcbiAqIEByZXR1cm5zIHtxdWF0Mn0gb3V0XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5zcXJMZW4gPSBzcXJMZW47XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZShvdXQsIGEpIHtcbiAgdmFyIG1hZ25pdHVkZSA9IHNxdWFyZWRMZW5ndGgoYSk7XG5cbiAgaWYgKG1hZ25pdHVkZSA+IDApIHtcbiAgICBtYWduaXR1ZGUgPSBNYXRoLnNxcnQobWFnbml0dWRlKTtcbiAgICB2YXIgYTAgPSBhWzBdIC8gbWFnbml0dWRlO1xuICAgIHZhciBhMSA9IGFbMV0gLyBtYWduaXR1ZGU7XG4gICAgdmFyIGEyID0gYVsyXSAvIG1hZ25pdHVkZTtcbiAgICB2YXIgYTMgPSBhWzNdIC8gbWFnbml0dWRlO1xuICAgIHZhciBiMCA9IGFbNF07XG4gICAgdmFyIGIxID0gYVs1XTtcbiAgICB2YXIgYjIgPSBhWzZdO1xuICAgIHZhciBiMyA9IGFbN107XG4gICAgdmFyIGFfZG90X2IgPSBhMCAqIGIwICsgYTEgKiBiMSArIGEyICogYjIgKyBhMyAqIGIzO1xuICAgIG91dFswXSA9IGEwO1xuICAgIG91dFsxXSA9IGExO1xuICAgIG91dFsyXSA9IGEyO1xuICAgIG91dFszXSA9IGEzO1xuICAgIG91dFs0XSA9IChiMCAtIGEwICogYV9kb3RfYikgLyBtYWduaXR1ZGU7XG4gICAgb3V0WzVdID0gKGIxIC0gYTEgKiBhX2RvdF9iKSAvIG1hZ25pdHVkZTtcbiAgICBvdXRbNl0gPSAoYjIgLSBhMiAqIGFfZG90X2IpIC8gbWFnbml0dWRlO1xuICAgIG91dFs3XSA9IChiMyAtIGEzICogYV9kb3RfYikgLyBtYWduaXR1ZGU7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBkdWFsIHF1YXRlbmlvblxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGEgZHVhbCBxdWF0ZXJuaW9uIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGR1YWwgcXVhdFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJxdWF0MihcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiLCBcIiArIGFbM10gKyBcIiwgXCIgKyBhWzRdICsgXCIsIFwiICsgYVs1XSArIFwiLCBcIiArIGFbNl0gKyBcIiwgXCIgKyBhWzddICsgXCIpXCI7XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgZHVhbCBxdWF0ZXJuaW9ucyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZmlyc3QgZHVhbCBxdWF0ZXJuaW9uLlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGIgdGhlIHNlY29uZCBkdWFsIHF1YXRlcm5pb24uXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBkdWFsIHF1YXRlcm5pb25zIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdICYmIGFbNF0gPT09IGJbNF0gJiYgYVs1XSA9PT0gYls1XSAmJiBhWzZdID09PSBiWzZdICYmIGFbN10gPT09IGJbN107XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgZHVhbCBxdWF0ZXJuaW9ucyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0Mn0gYSB0aGUgZmlyc3QgZHVhbCBxdWF0LlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdDJ9IGIgdGhlIHNlY29uZCBkdWFsIHF1YXQuXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBkdWFsIHF1YXRzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdLFxuICAgICAgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdLFxuICAgICAgYTYgPSBhWzZdLFxuICAgICAgYTcgPSBhWzddO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdLFxuICAgICAgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdLFxuICAgICAgYjYgPSBiWzZdLFxuICAgICAgYjcgPSBiWzddO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSkgJiYgTWF0aC5hYnMoYTMgLSBiMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTMpLCBNYXRoLmFicyhiMykpICYmIE1hdGguYWJzKGE0IC0gYjQpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE0KSwgTWF0aC5hYnMoYjQpKSAmJiBNYXRoLmFicyhhNSAtIGI1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNSksIE1hdGguYWJzKGI1KSkgJiYgTWF0aC5hYnMoYTYgLSBiNikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTYpLCBNYXRoLmFicyhiNikpICYmIE1hdGguYWJzKGE3IC0gYjcpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE3KSwgTWF0aC5hYnMoYjcpKTtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiOyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2Yob2JqKTsgfVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5jcmVhdGUgPSBjcmVhdGU7XG5leHBvcnRzLmNsb25lID0gY2xvbmU7XG5leHBvcnRzLmZyb21WYWx1ZXMgPSBmcm9tVmFsdWVzO1xuZXhwb3J0cy5jb3B5ID0gY29weTtcbmV4cG9ydHMuc2V0ID0gc2V0O1xuZXhwb3J0cy5hZGQgPSBhZGQ7XG5leHBvcnRzLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG5leHBvcnRzLm11bHRpcGx5ID0gbXVsdGlwbHk7XG5leHBvcnRzLmRpdmlkZSA9IGRpdmlkZTtcbmV4cG9ydHMuY2VpbCA9IGNlaWw7XG5leHBvcnRzLmZsb29yID0gZmxvb3I7XG5leHBvcnRzLm1pbiA9IG1pbjtcbmV4cG9ydHMubWF4ID0gbWF4O1xuZXhwb3J0cy5yb3VuZCA9IHJvdW5kO1xuZXhwb3J0cy5zY2FsZSA9IHNjYWxlO1xuZXhwb3J0cy5zY2FsZUFuZEFkZCA9IHNjYWxlQW5kQWRkO1xuZXhwb3J0cy5kaXN0YW5jZSA9IGRpc3RhbmNlO1xuZXhwb3J0cy5zcXVhcmVkRGlzdGFuY2UgPSBzcXVhcmVkRGlzdGFuY2U7XG5leHBvcnRzLmxlbmd0aCA9IGxlbmd0aDtcbmV4cG9ydHMuc3F1YXJlZExlbmd0aCA9IHNxdWFyZWRMZW5ndGg7XG5leHBvcnRzLm5lZ2F0ZSA9IG5lZ2F0ZTtcbmV4cG9ydHMuaW52ZXJzZSA9IGludmVyc2U7XG5leHBvcnRzLm5vcm1hbGl6ZSA9IG5vcm1hbGl6ZTtcbmV4cG9ydHMuZG90ID0gZG90O1xuZXhwb3J0cy5jcm9zcyA9IGNyb3NzO1xuZXhwb3J0cy5sZXJwID0gbGVycDtcbmV4cG9ydHMucmFuZG9tID0gcmFuZG9tO1xuZXhwb3J0cy50cmFuc2Zvcm1NYXQyID0gdHJhbnNmb3JtTWF0MjtcbmV4cG9ydHMudHJhbnNmb3JtTWF0MmQgPSB0cmFuc2Zvcm1NYXQyZDtcbmV4cG9ydHMudHJhbnNmb3JtTWF0MyA9IHRyYW5zZm9ybU1hdDM7XG5leHBvcnRzLnRyYW5zZm9ybU1hdDQgPSB0cmFuc2Zvcm1NYXQ0O1xuZXhwb3J0cy5yb3RhdGUgPSByb3RhdGU7XG5leHBvcnRzLmFuZ2xlID0gYW5nbGU7XG5leHBvcnRzLnplcm8gPSB6ZXJvO1xuZXhwb3J0cy5zdHIgPSBzdHI7XG5leHBvcnRzLmV4YWN0RXF1YWxzID0gZXhhY3RFcXVhbHM7XG5leHBvcnRzLmVxdWFscyA9IGVxdWFscztcbmV4cG9ydHMuZm9yRWFjaCA9IGV4cG9ydHMuc3FyTGVuID0gZXhwb3J0cy5zcXJEaXN0ID0gZXhwb3J0cy5kaXN0ID0gZXhwb3J0cy5kaXYgPSBleHBvcnRzLm11bCA9IGV4cG9ydHMuc3ViID0gZXhwb3J0cy5sZW4gPSB2b2lkIDA7XG5cbnZhciBnbE1hdHJpeCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsOyB2YXIgY2FjaGUgPSBuZXcgV2Vha01hcCgpOyBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUgPSBmdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IHJldHVybiBjYWNoZTsgfTsgcmV0dXJuIGNhY2hlOyB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gaWYgKG9iaiA9PT0gbnVsbCB8fCBfdHlwZW9mKG9iaikgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSB7IHJldHVybiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfSB2YXIgY2FjaGUgPSBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKTsgaWYgKGNhY2hlICYmIGNhY2hlLmhhcyhvYmopKSB7IHJldHVybiBjYWNoZS5nZXQob2JqKTsgfSB2YXIgbmV3T2JqID0ge307IHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgeyB2YXIgZGVzYyA9IGhhc1Byb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDogbnVsbDsgaWYgKGRlc2MgJiYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpOyB9IGVsc2UgeyBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gfSBuZXdPYmpbXCJkZWZhdWx0XCJdID0gb2JqOyBpZiAoY2FjaGUpIHsgY2FjaGUuc2V0KG9iaiwgbmV3T2JqKTsgfSByZXR1cm4gbmV3T2JqOyB9XG5cbi8qKlxyXG4gKiAyIERpbWVuc2lvbmFsIFZlY3RvclxyXG4gKiBAbW9kdWxlIHZlYzJcclxuICovXG5cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWMyXHJcbiAqXHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBhIG5ldyAyRCB2ZWN0b3JcclxuICovXG5mdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgdmVjMiBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIHZlY3RvclxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gY2xvbmVcclxuICogQHJldHVybnMge3ZlYzJ9IGEgbmV3IDJEIHZlY3RvclxyXG4gKi9cblxuXG5mdW5jdGlvbiBjbG9uZShhKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzIgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXHJcbiAqXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBhIG5ldyAyRCB2ZWN0b3JcclxuICovXG5cblxuZnVuY3Rpb24gZnJvbVZhbHVlcyh4LCB5KSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgyKTtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgdmVjMiB0byBhbm90aGVyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBzb3VyY2UgdmVjdG9yXHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gY29weShvdXQsIGEpIHtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyIHRvIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzZXQob3V0LCB4LCB5KSB7XG4gIG91dFswXSA9IHg7XG4gIG91dFsxXSA9IHk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQWRkcyB0d28gdmVjMidzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGFkZChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFN1YnRyYWN0cyB2ZWN0b3IgYiBmcm9tIHZlY3RvciBhXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHN1YnRyYWN0KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogTXVsdGlwbGllcyB0d28gdmVjMidzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgb3V0WzFdID0gYVsxXSAqIGJbMV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogRGl2aWRlcyB0d28gdmVjMidzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGRpdmlkZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAvIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLyBiWzFdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE1hdGguY2VpbCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzJcclxuICpcclxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdmVjdG9yIHRvIGNlaWxcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjZWlsKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLmNlaWwoYVswXSk7XG4gIG91dFsxXSA9IE1hdGguY2VpbChhWzFdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBNYXRoLmZsb29yIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMlxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gZmxvb3JcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBmbG9vcihvdXQsIGEpIHtcbiAgb3V0WzBdID0gTWF0aC5mbG9vcihhWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5mbG9vcihhWzFdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBtaW5pbXVtIG9mIHR3byB2ZWMyJ3NcclxuICpcclxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbWluKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBNYXRoLm1pbihhWzBdLCBiWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5taW4oYVsxXSwgYlsxXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyB0aGUgbWF4aW11bSBvZiB0d28gdmVjMidzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG1heChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gTWF0aC5tYXgoYVswXSwgYlswXSk7XG4gIG91dFsxXSA9IE1hdGgubWF4KGFbMV0sIGJbMV0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE1hdGgucm91bmQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHZlY3RvciB0byByb3VuZFxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdW5kKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLnJvdW5kKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLnJvdW5kKGFbMV0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNjYWxlcyBhIHZlYzIgYnkgYSBzY2FsYXIgbnVtYmVyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcclxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSB2ZWN0b3IgYnlcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzY2FsZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEFkZHMgdHdvIHZlYzIncyBhZnRlciBzY2FsaW5nIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZVxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYiBieSBiZWZvcmUgYWRkaW5nXHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gc2NhbGVBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWMyJ3NcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxyXG4gKi9cblxuXG5mdW5jdGlvbiBkaXN0YW5jZShhLCBiKSB7XG4gIHZhciB4ID0gYlswXSAtIGFbMF0sXG4gICAgICB5ID0gYlsxXSAtIGFbMV07XG4gIHJldHVybiBNYXRoLmh5cG90KHgsIHkpO1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzInc1xyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcclxuICovXG5cblxuZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlKGEsIGIpIHtcbiAgdmFyIHggPSBiWzBdIC0gYVswXSxcbiAgICAgIHkgPSBiWzFdIC0gYVsxXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHk7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjMlxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIGxlbmd0aCBvZlxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBsZW5ndGggb2YgYVxyXG4gKi9cblxuXG5mdW5jdGlvbiBsZW5ndGgoYSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSk7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBsZW5ndGggb2YgYSB2ZWMyXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHZlY3RvciB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxyXG4gKi9cblxuXG5mdW5jdGlvbiBzcXVhcmVkTGVuZ3RoKGEpIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV07XG4gIHJldHVybiB4ICogeCArIHkgKiB5O1xufVxuLyoqXHJcbiAqIE5lZ2F0ZXMgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHZlY3RvciB0byBuZWdhdGVcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBuZWdhdGUob3V0LCBhKSB7XG4gIG91dFswXSA9IC1hWzBdO1xuICBvdXRbMV0gPSAtYVsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBpbnZlcnNlIG9mIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMlxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB2ZWN0b3IgdG8gaW52ZXJ0XHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaW52ZXJzZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gMS4wIC8gYVswXTtcbiAgb3V0WzFdID0gMS4wIC8gYVsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBOb3JtYWxpemUgYSB2ZWMyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjMn0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHZlY3RvciB0byBub3JtYWxpemVcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBub3JtYWxpemUob3V0LCBhKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdO1xuICB2YXIgbGVuID0geCAqIHggKyB5ICogeTtcblxuICBpZiAobGVuID4gMCkge1xuICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/XG4gICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pO1xuICB9XG5cbiAgb3V0WzBdID0gYVswXSAqIGxlbjtcbiAgb3V0WzFdID0gYVsxXSAqIGxlbjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gdmVjMidzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkb3QgcHJvZHVjdCBvZiBhIGFuZCBiXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGRvdChhLCBiKSB7XG4gIHJldHVybiBhWzBdICogYlswXSArIGFbMV0gKiBiWzFdO1xufVxuLyoqXHJcbiAqIENvbXB1dGVzIHRoZSBjcm9zcyBwcm9kdWN0IG9mIHR3byB2ZWMyJ3NcclxuICogTm90ZSB0aGF0IHRoZSBjcm9zcyBwcm9kdWN0IG11c3QgYnkgZGVmaW5pdGlvbiBwcm9kdWNlIGEgM0QgdmVjdG9yXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNyb3NzKG91dCwgYSwgYikge1xuICB2YXIgeiA9IGFbMF0gKiBiWzFdIC0gYVsxXSAqIGJbMF07XG4gIG91dFswXSA9IG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IHo7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUGVyZm9ybXMgYSBsaW5lYXIgaW50ZXJwb2xhdGlvbiBiZXR3ZWVuIHR3byB2ZWMyJ3NcclxuICpcclxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBsZXJwKG91dCwgYSwgYiwgdCkge1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdO1xuICBvdXRbMF0gPSBheCArIHQgKiAoYlswXSAtIGF4KTtcbiAgb3V0WzFdID0gYXkgKyB0ICogKGJbMV0gLSBheSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHZlY3RvciB3aXRoIHRoZSBnaXZlbiBzY2FsZVxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge051bWJlcn0gW3NjYWxlXSBMZW5ndGggb2YgdGhlIHJlc3VsdGluZyB2ZWN0b3IuIElmIG9tbWl0dGVkLCBhIHVuaXQgdmVjdG9yIHdpbGwgYmUgcmV0dXJuZWRcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByYW5kb20ob3V0LCBzY2FsZSkge1xuICBzY2FsZSA9IHNjYWxlIHx8IDEuMDtcbiAgdmFyIHIgPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIuMCAqIE1hdGguUEk7XG4gIG91dFswXSA9IE1hdGguY29zKHIpICogc2NhbGU7XG4gIG91dFsxXSA9IE1hdGguc2luKHIpICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNmb3JtcyB0aGUgdmVjMiB3aXRoIGEgbWF0MlxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0Mn0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiB0cmFuc2Zvcm1NYXQyKG91dCwgYSwgbSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXTtcbiAgb3V0WzBdID0gbVswXSAqIHggKyBtWzJdICogeTtcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzNdICogeTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMyIHdpdGggYSBtYXQyZFxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IG0gbWF0cml4IHRvIHRyYW5zZm9ybSB3aXRoXHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNmb3JtTWF0MmQob3V0LCBhLCBtKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdO1xuICBvdXRbMF0gPSBtWzBdICogeCArIG1bMl0gKiB5ICsgbVs0XTtcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzNdICogeSArIG1bNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogVHJhbnNmb3JtcyB0aGUgdmVjMiB3aXRoIGEgbWF0M1xyXG4gKiAzcmQgdmVjdG9yIGNvbXBvbmVudCBpcyBpbXBsaWNpdGx5ICcxJ1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiB0cmFuc2Zvcm1NYXQzKG91dCwgYSwgbSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXTtcbiAgb3V0WzBdID0gbVswXSAqIHggKyBtWzNdICogeSArIG1bNl07XG4gIG91dFsxXSA9IG1bMV0gKiB4ICsgbVs0XSAqIHkgKyBtWzddO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzIgd2l0aCBhIG1hdDRcclxuICogM3JkIHZlY3RvciBjb21wb25lbnQgaXMgaW1wbGljaXRseSAnMCdcclxuICogNHRoIHZlY3RvciBjb21wb25lbnQgaXMgaW1wbGljaXRseSAnMSdcclxuICpcclxuICogQHBhcmFtIHt2ZWMyfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IG0gbWF0cml4IHRvIHRyYW5zZm9ybSB3aXRoXHJcbiAqIEByZXR1cm5zIHt2ZWMyfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNmb3JtTWF0NChvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIG91dFswXSA9IG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzEyXTtcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzVdICogeSArIG1bMTNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZSBhIDJEIHZlY3RvclxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCBUaGUgcmVjZWl2aW5nIHZlYzJcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgVGhlIHZlYzIgcG9pbnQgdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIFRoZSBvcmlnaW4gb2YgdGhlIHJvdGF0aW9uXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgVGhlIGFuZ2xlIG9mIHJvdGF0aW9uIGluIHJhZGlhbnNcclxuICogQHJldHVybnMge3ZlYzJ9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGUob3V0LCBhLCBiLCByYWQpIHtcbiAgLy9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuICB2YXIgcDAgPSBhWzBdIC0gYlswXSxcbiAgICAgIHAxID0gYVsxXSAtIGJbMV0sXG4gICAgICBzaW5DID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGNvc0MgPSBNYXRoLmNvcyhyYWQpOyAvL3BlcmZvcm0gcm90YXRpb24gYW5kIHRyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG5cbiAgb3V0WzBdID0gcDAgKiBjb3NDIC0gcDEgKiBzaW5DICsgYlswXTtcbiAgb3V0WzFdID0gcDAgKiBzaW5DICsgcDEgKiBjb3NDICsgYlsxXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBHZXQgdGhlIGFuZ2xlIGJldHdlZW4gdHdvIDJEIHZlY3RvcnNcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgVGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgVGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBhbmdsZSBpbiByYWRpYW5zXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGFuZ2xlKGEsIGIpIHtcbiAgdmFyIHgxID0gYVswXSxcbiAgICAgIHkxID0gYVsxXSxcbiAgICAgIHgyID0gYlswXSxcbiAgICAgIHkyID0gYlsxXSxcbiAgICAgIC8vIG1hZyBpcyB0aGUgcHJvZHVjdCBvZiB0aGUgbWFnbml0dWRlcyBvZiBhIGFuZCBiXG4gIG1hZyA9IE1hdGguc3FydCh4MSAqIHgxICsgeTEgKiB5MSkgKiBNYXRoLnNxcnQoeDIgKiB4MiArIHkyICogeTIpLFxuICAgICAgLy8gbWFnICYmLi4gc2hvcnQgY2lyY3VpdHMgaWYgbWFnID09IDBcbiAgY29zaW5lID0gbWFnICYmICh4MSAqIHgyICsgeTEgKiB5MikgLyBtYWc7IC8vIE1hdGgubWluKE1hdGgubWF4KGNvc2luZSwgLTEpLCAxKSBjbGFtcHMgdGhlIGNvc2luZSBiZXR3ZWVuIC0xIGFuZCAxXG5cbiAgcmV0dXJuIE1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChjb3NpbmUsIC0xKSwgMSkpO1xufVxuLyoqXHJcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzIgdG8gemVyb1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzJ9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcmV0dXJucyB7dmVjMn0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHplcm8ob3V0KSB7XG4gIG91dFswXSA9IDAuMDtcbiAgb3V0WzFdID0gMC4wO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB2ZWN0b3JcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgdmVjdG9yIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJ2ZWMyKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIilcIjtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB2ZWN0b3JzIGV4YWN0bHkgaGF2ZSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbiAod2hlbiBjb21wYXJlZCB3aXRoID09PSlcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGEgVGhlIGZpcnN0IHZlY3Rvci5cclxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IGIgVGhlIHNlY29uZCB2ZWN0b3IuXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cblxuXG5mdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV07XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBhIFRoZSBmaXJzdCB2ZWN0b3IuXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSk7XG59XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMyLmxlbmd0aH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbnZhciBsZW4gPSBsZW5ndGg7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMyLnN1YnRyYWN0fVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMubGVuID0gbGVuO1xudmFyIHN1YiA9IHN1YnRyYWN0O1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5tdWx0aXBseX1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLnN1YiA9IHN1YjtcbnZhciBtdWwgPSBtdWx0aXBseTtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIuZGl2aWRlfVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMubXVsID0gbXVsO1xudmFyIGRpdiA9IGRpdmlkZTtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzIuZGlzdGFuY2V9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5kaXYgPSBkaXY7XG52YXIgZGlzdCA9IGRpc3RhbmNlO1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5zcXVhcmVkRGlzdGFuY2V9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5kaXN0ID0gZGlzdDtcbnZhciBzcXJEaXN0ID0gc3F1YXJlZERpc3RhbmNlO1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMi5zcXVhcmVkTGVuZ3RofVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuc3FyRGlzdCA9IHNxckRpc3Q7XG52YXIgc3FyTGVuID0gc3F1YXJlZExlbmd0aDtcbi8qKlxyXG4gKiBQZXJmb3JtIHNvbWUgb3BlcmF0aW9uIG92ZXIgYW4gYXJyYXkgb2YgdmVjMnMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGFycmF5IG9mIHZlY3RvcnMgdG8gaXRlcmF0ZSBvdmVyXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBzdHJpZGUgTnVtYmVyIG9mIGVsZW1lbnRzIGJldHdlZW4gdGhlIHN0YXJ0IG9mIGVhY2ggdmVjMi4gSWYgMCBhc3N1bWVzIHRpZ2h0bHkgcGFja2VkXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXQgTnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYXJyYXlcclxuICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50IE51bWJlciBvZiB2ZWMycyB0byBpdGVyYXRlIG92ZXIuIElmIDAgaXRlcmF0ZXMgb3ZlciBlbnRpcmUgYXJyYXlcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gRnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCB2ZWN0b3IgaW4gdGhlIGFycmF5XHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbYXJnXSBhZGRpdGlvbmFsIGFyZ3VtZW50IHRvIHBhc3MgdG8gZm5cclxuICogQHJldHVybnMge0FycmF5fSBhXHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5zcXJMZW4gPSBzcXJMZW47XG5cbnZhciBmb3JFYWNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdmVjID0gY3JlYXRlKCk7XG4gIHJldHVybiBmdW5jdGlvbiAoYSwgc3RyaWRlLCBvZmZzZXQsIGNvdW50LCBmbiwgYXJnKSB7XG4gICAgdmFyIGksIGw7XG5cbiAgICBpZiAoIXN0cmlkZSkge1xuICAgICAgc3RyaWRlID0gMjtcbiAgICB9XG5cbiAgICBpZiAoIW9mZnNldCkge1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoY291bnQpIHtcbiAgICAgIGwgPSBNYXRoLm1pbihjb3VudCAqIHN0cmlkZSArIG9mZnNldCwgYS5sZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsID0gYS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZm9yIChpID0gb2Zmc2V0OyBpIDwgbDsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZlY1swXSA9IGFbaV07XG4gICAgICB2ZWNbMV0gPSBhW2kgKyAxXTtcbiAgICAgIGZuKHZlYywgdmVjLCBhcmcpO1xuICAgICAgYVtpXSA9IHZlY1swXTtcbiAgICAgIGFbaSArIDFdID0gdmVjWzFdO1xuICAgIH1cblxuICAgIHJldHVybiBhO1xuICB9O1xufSgpO1xuXG5leHBvcnRzLmZvckVhY2ggPSBmb3JFYWNoOyIsIlwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBfdHlwZW9mKG9iaikgeyBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZihvYmopOyB9XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNyZWF0ZSA9IGNyZWF0ZTtcbmV4cG9ydHMuY2xvbmUgPSBjbG9uZTtcbmV4cG9ydHMubGVuZ3RoID0gbGVuZ3RoO1xuZXhwb3J0cy5mcm9tVmFsdWVzID0gZnJvbVZhbHVlcztcbmV4cG9ydHMuY29weSA9IGNvcHk7XG5leHBvcnRzLnNldCA9IHNldDtcbmV4cG9ydHMuYWRkID0gYWRkO1xuZXhwb3J0cy5zdWJ0cmFjdCA9IHN1YnRyYWN0O1xuZXhwb3J0cy5tdWx0aXBseSA9IG11bHRpcGx5O1xuZXhwb3J0cy5kaXZpZGUgPSBkaXZpZGU7XG5leHBvcnRzLmNlaWwgPSBjZWlsO1xuZXhwb3J0cy5mbG9vciA9IGZsb29yO1xuZXhwb3J0cy5taW4gPSBtaW47XG5leHBvcnRzLm1heCA9IG1heDtcbmV4cG9ydHMucm91bmQgPSByb3VuZDtcbmV4cG9ydHMuc2NhbGUgPSBzY2FsZTtcbmV4cG9ydHMuc2NhbGVBbmRBZGQgPSBzY2FsZUFuZEFkZDtcbmV4cG9ydHMuZGlzdGFuY2UgPSBkaXN0YW5jZTtcbmV4cG9ydHMuc3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZERpc3RhbmNlO1xuZXhwb3J0cy5zcXVhcmVkTGVuZ3RoID0gc3F1YXJlZExlbmd0aDtcbmV4cG9ydHMubmVnYXRlID0gbmVnYXRlO1xuZXhwb3J0cy5pbnZlcnNlID0gaW52ZXJzZTtcbmV4cG9ydHMubm9ybWFsaXplID0gbm9ybWFsaXplO1xuZXhwb3J0cy5kb3QgPSBkb3Q7XG5leHBvcnRzLmNyb3NzID0gY3Jvc3M7XG5leHBvcnRzLmxlcnAgPSBsZXJwO1xuZXhwb3J0cy5oZXJtaXRlID0gaGVybWl0ZTtcbmV4cG9ydHMuYmV6aWVyID0gYmV6aWVyO1xuZXhwb3J0cy5yYW5kb20gPSByYW5kb207XG5leHBvcnRzLnRyYW5zZm9ybU1hdDQgPSB0cmFuc2Zvcm1NYXQ0O1xuZXhwb3J0cy50cmFuc2Zvcm1NYXQzID0gdHJhbnNmb3JtTWF0MztcbmV4cG9ydHMudHJhbnNmb3JtUXVhdCA9IHRyYW5zZm9ybVF1YXQ7XG5leHBvcnRzLnJvdGF0ZVggPSByb3RhdGVYO1xuZXhwb3J0cy5yb3RhdGVZID0gcm90YXRlWTtcbmV4cG9ydHMucm90YXRlWiA9IHJvdGF0ZVo7XG5leHBvcnRzLmFuZ2xlID0gYW5nbGU7XG5leHBvcnRzLnplcm8gPSB6ZXJvO1xuZXhwb3J0cy5zdHIgPSBzdHI7XG5leHBvcnRzLmV4YWN0RXF1YWxzID0gZXhhY3RFcXVhbHM7XG5leHBvcnRzLmVxdWFscyA9IGVxdWFscztcbmV4cG9ydHMuZm9yRWFjaCA9IGV4cG9ydHMuc3FyTGVuID0gZXhwb3J0cy5sZW4gPSBleHBvcnRzLnNxckRpc3QgPSBleHBvcnRzLmRpc3QgPSBleHBvcnRzLmRpdiA9IGV4cG9ydHMubXVsID0gZXhwb3J0cy5zdWIgPSB2b2lkIDA7XG5cbnZhciBnbE1hdHJpeCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL2NvbW1vbi5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSgpIHsgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsOyB2YXIgY2FjaGUgPSBuZXcgV2Vha01hcCgpOyBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUgPSBmdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IHJldHVybiBjYWNoZTsgfTsgcmV0dXJuIGNhY2hlOyB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gaWYgKG9iaiA9PT0gbnVsbCB8fCBfdHlwZW9mKG9iaikgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSB7IHJldHVybiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfSB2YXIgY2FjaGUgPSBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKTsgaWYgKGNhY2hlICYmIGNhY2hlLmhhcyhvYmopKSB7IHJldHVybiBjYWNoZS5nZXQob2JqKTsgfSB2YXIgbmV3T2JqID0ge307IHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgeyB2YXIgZGVzYyA9IGhhc1Byb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDogbnVsbDsgaWYgKGRlc2MgJiYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpOyB9IGVsc2UgeyBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gfSBuZXdPYmpbXCJkZWZhdWx0XCJdID0gb2JqOyBpZiAoY2FjaGUpIHsgY2FjaGUuc2V0KG9iaiwgbmV3T2JqKTsgfSByZXR1cm4gbmV3T2JqOyB9XG5cbi8qKlxyXG4gKiAzIERpbWVuc2lvbmFsIFZlY3RvclxyXG4gKiBAbW9kdWxlIHZlYzNcclxuICovXG5cbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWMzXHJcbiAqXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBhIG5ldyAzRCB2ZWN0b3JcclxuICovXG5mdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyB2ZWMzIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgdmVjdG9yXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBjbG9uZVxyXG4gKiBAcmV0dXJucyB7dmVjM30gYSBuZXcgM0QgdmVjdG9yXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDMpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIHZlYzNcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcclxuICovXG5cblxuZnVuY3Rpb24gbGVuZ3RoKGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSwgeik7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyB2ZWMzIGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xyXG4gKlxyXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxyXG4gKiBAcmV0dXJucyB7dmVjM30gYSBuZXcgM0QgdmVjdG9yXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZyb21WYWx1ZXMoeCwgeSwgeikge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMyk7XG4gIG91dFswXSA9IHg7XG4gIG91dFsxXSA9IHk7XG4gIG91dFsyXSA9IHo7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIHZlYzMgdG8gYW5vdGhlclxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgc291cmNlIHZlY3RvclxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNvcHkob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgdmVjMyB0byB0aGUgZ2l2ZW4gdmFsdWVzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB6IFogY29tcG9uZW50XHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gc2V0KG91dCwgeCwgeSwgeikge1xuICBvdXRbMF0gPSB4O1xuICBvdXRbMV0gPSB5O1xuICBvdXRbMl0gPSB6O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIEFkZHMgdHdvIHZlYzMnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBhZGQob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU3VidHJhY3RzIHZlY3RvciBiIGZyb20gdmVjdG9yIGFcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gc3VidHJhY3Qob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLSBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC0gYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAtIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogTXVsdGlwbGllcyB0d28gdmVjMydzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgb3V0WzFdID0gYVsxXSAqIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKiBiWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIERpdmlkZXMgdHdvIHZlYzMnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBkaXZpZGUob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC8gYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAvIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogTWF0aC5jZWlsIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjM1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gY2VpbFxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNlaWwob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGguY2VpbChhWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5jZWlsKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLmNlaWwoYVsyXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogTWF0aC5mbG9vciB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIGZsb29yXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gZmxvb3Iob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGguZmxvb3IoYVswXSk7XG4gIG91dFsxXSA9IE1hdGguZmxvb3IoYVsxXSk7XG4gIG91dFsyXSA9IE1hdGguZmxvb3IoYVsyXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUmV0dXJucyB0aGUgbWluaW11bSBvZiB0d28gdmVjMydzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG1pbihvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gTWF0aC5taW4oYVswXSwgYlswXSk7XG4gIG91dFsxXSA9IE1hdGgubWluKGFbMV0sIGJbMV0pO1xuICBvdXRbMl0gPSBNYXRoLm1pbihhWzJdLCBiWzJdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG9mIHR3byB2ZWMzJ3NcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbWF4KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBNYXRoLm1heChhWzBdLCBiWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5tYXgoYVsxXSwgYlsxXSk7XG4gIG91dFsyXSA9IE1hdGgubWF4KGFbMl0sIGJbMl0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE1hdGgucm91bmQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byByb3VuZFxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdW5kKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLnJvdW5kKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLnJvdW5kKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLnJvdW5kKGFbMl0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNjYWxlcyBhIHZlYzMgYnkgYSBzY2FsYXIgbnVtYmVyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcclxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSB2ZWN0b3IgYnlcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzY2FsZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBBZGRzIHR3byB2ZWMzJ3MgYWZ0ZXIgc2NhbGluZyB0aGUgc2Vjb25kIG9wZXJhbmQgYnkgYSBzY2FsYXIgdmFsdWVcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIgYnkgYmVmb3JlIGFkZGluZ1xyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNjYWxlQW5kQWRkKG91dCwgYSwgYiwgc2NhbGUpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF0gKiBzY2FsZTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV0gKiBzY2FsZTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl0gKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjMydzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcclxuICovXG5cblxuZnVuY3Rpb24gZGlzdGFuY2UoYSwgYikge1xuICB2YXIgeCA9IGJbMF0gLSBhWzBdO1xuICB2YXIgeSA9IGJbMV0gLSBhWzFdO1xuICB2YXIgeiA9IGJbMl0gLSBhWzJdO1xuICByZXR1cm4gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWMzJ3NcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNxdWFyZWREaXN0YW5jZShhLCBiKSB7XG4gIHZhciB4ID0gYlswXSAtIGFbMF07XG4gIHZhciB5ID0gYlsxXSAtIGFbMV07XG4gIHZhciB6ID0gYlsyXSAtIGFbMl07XG4gIHJldHVybiB4ICogeCArIHkgKiB5ICsgeiAqIHo7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBsZW5ndGggb2YgYSB2ZWMzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcclxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBsZW5ndGggb2YgYVxyXG4gKi9cblxuXG5mdW5jdGlvbiBzcXVhcmVkTGVuZ3RoKGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogejtcbn1cbi8qKlxyXG4gKiBOZWdhdGVzIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjM1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gbmVnYXRlXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gbmVnYXRlKG91dCwgYSkge1xuICBvdXRbMF0gPSAtYVswXTtcbiAgb3V0WzFdID0gLWFbMV07XG4gIG91dFsyXSA9IC1hWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBpbnZlcnRcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBpbnZlcnNlKG91dCwgYSkge1xuICBvdXRbMF0gPSAxLjAgLyBhWzBdO1xuICBvdXRbMV0gPSAxLjAgLyBhWzFdO1xuICBvdXRbMl0gPSAxLjAgLyBhWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE5vcm1hbGl6ZSBhIHZlYzNcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIG5vcm1hbGl6ZVxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZShvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgdmFyIGxlbiA9IHggKiB4ICsgeSAqIHkgKyB6ICogejtcblxuICBpZiAobGVuID4gMCkge1xuICAgIC8vVE9ETzogZXZhbHVhdGUgdXNlIG9mIGdsbV9pbnZzcXJ0IGhlcmU/XG4gICAgbGVuID0gMSAvIE1hdGguc3FydChsZW4pO1xuICB9XG5cbiAgb3V0WzBdID0gYVswXSAqIGxlbjtcbiAgb3V0WzFdID0gYVsxXSAqIGxlbjtcbiAgb3V0WzJdID0gYVsyXSAqIGxlbjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gdmVjMydzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkb3QgcHJvZHVjdCBvZiBhIGFuZCBiXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGRvdChhLCBiKSB7XG4gIHJldHVybiBhWzBdICogYlswXSArIGFbMV0gKiBiWzFdICsgYVsyXSAqIGJbMl07XG59XG4vKipcclxuICogQ29tcHV0ZXMgdGhlIGNyb3NzIHByb2R1Y3Qgb2YgdHdvIHZlYzMnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjcm9zcyhvdXQsIGEsIGIpIHtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXTtcbiAgdmFyIGJ4ID0gYlswXSxcbiAgICAgIGJ5ID0gYlsxXSxcbiAgICAgIGJ6ID0gYlsyXTtcbiAgb3V0WzBdID0gYXkgKiBieiAtIGF6ICogYnk7XG4gIG91dFsxXSA9IGF6ICogYnggLSBheCAqIGJ6O1xuICBvdXRbMl0gPSBheCAqIGJ5IC0gYXkgKiBieDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIHZlYzMnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGxlcnAob3V0LCBhLCBiLCB0KSB7XG4gIHZhciBheCA9IGFbMF07XG4gIHZhciBheSA9IGFbMV07XG4gIHZhciBheiA9IGFbMl07XG4gIG91dFswXSA9IGF4ICsgdCAqIChiWzBdIC0gYXgpO1xuICBvdXRbMV0gPSBheSArIHQgKiAoYlsxXSAtIGF5KTtcbiAgb3V0WzJdID0gYXogKyB0ICogKGJbMl0gLSBheik7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUGVyZm9ybXMgYSBoZXJtaXRlIGludGVycG9sYXRpb24gd2l0aCB0d28gY29udHJvbCBwb2ludHNcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBjIHRoZSB0aGlyZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBkIHRoZSBmb3VydGggb3BlcmFuZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gaGVybWl0ZShvdXQsIGEsIGIsIGMsIGQsIHQpIHtcbiAgdmFyIGZhY3RvclRpbWVzMiA9IHQgKiB0O1xuICB2YXIgZmFjdG9yMSA9IGZhY3RvclRpbWVzMiAqICgyICogdCAtIDMpICsgMTtcbiAgdmFyIGZhY3RvcjIgPSBmYWN0b3JUaW1lczIgKiAodCAtIDIpICsgdDtcbiAgdmFyIGZhY3RvcjMgPSBmYWN0b3JUaW1lczIgKiAodCAtIDEpO1xuICB2YXIgZmFjdG9yNCA9IGZhY3RvclRpbWVzMiAqICgzIC0gMiAqIHQpO1xuICBvdXRbMF0gPSBhWzBdICogZmFjdG9yMSArIGJbMF0gKiBmYWN0b3IyICsgY1swXSAqIGZhY3RvcjMgKyBkWzBdICogZmFjdG9yNDtcbiAgb3V0WzFdID0gYVsxXSAqIGZhY3RvcjEgKyBiWzFdICogZmFjdG9yMiArIGNbMV0gKiBmYWN0b3IzICsgZFsxXSAqIGZhY3RvcjQ7XG4gIG91dFsyXSA9IGFbMl0gKiBmYWN0b3IxICsgYlsyXSAqIGZhY3RvcjIgKyBjWzJdICogZmFjdG9yMyArIGRbMl0gKiBmYWN0b3I0O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFBlcmZvcm1zIGEgYmV6aWVyIGludGVycG9sYXRpb24gd2l0aCB0d28gY29udHJvbCBwb2ludHNcclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBjIHRoZSB0aGlyZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBkIHRoZSBmb3VydGggb3BlcmFuZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gYmV6aWVyKG91dCwgYSwgYiwgYywgZCwgdCkge1xuICB2YXIgaW52ZXJzZUZhY3RvciA9IDEgLSB0O1xuICB2YXIgaW52ZXJzZUZhY3RvclRpbWVzVHdvID0gaW52ZXJzZUZhY3RvciAqIGludmVyc2VGYWN0b3I7XG4gIHZhciBmYWN0b3JUaW1lczIgPSB0ICogdDtcbiAgdmFyIGZhY3RvcjEgPSBpbnZlcnNlRmFjdG9yVGltZXNUd28gKiBpbnZlcnNlRmFjdG9yO1xuICB2YXIgZmFjdG9yMiA9IDMgKiB0ICogaW52ZXJzZUZhY3RvclRpbWVzVHdvO1xuICB2YXIgZmFjdG9yMyA9IDMgKiBmYWN0b3JUaW1lczIgKiBpbnZlcnNlRmFjdG9yO1xuICB2YXIgZmFjdG9yNCA9IGZhY3RvclRpbWVzMiAqIHQ7XG4gIG91dFswXSA9IGFbMF0gKiBmYWN0b3IxICsgYlswXSAqIGZhY3RvcjIgKyBjWzBdICogZmFjdG9yMyArIGRbMF0gKiBmYWN0b3I0O1xuICBvdXRbMV0gPSBhWzFdICogZmFjdG9yMSArIGJbMV0gKiBmYWN0b3IyICsgY1sxXSAqIGZhY3RvcjMgKyBkWzFdICogZmFjdG9yNDtcbiAgb3V0WzJdID0gYVsyXSAqIGZhY3RvcjEgKyBiWzJdICogZmFjdG9yMiArIGNbMl0gKiBmYWN0b3IzICsgZFsyXSAqIGZhY3RvcjQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHZlY3RvciB3aXRoIHRoZSBnaXZlbiBzY2FsZVxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge051bWJlcn0gW3NjYWxlXSBMZW5ndGggb2YgdGhlIHJlc3VsdGluZyB2ZWN0b3IuIElmIG9tbWl0dGVkLCBhIHVuaXQgdmVjdG9yIHdpbGwgYmUgcmV0dXJuZWRcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByYW5kb20ob3V0LCBzY2FsZSkge1xuICBzY2FsZSA9IHNjYWxlIHx8IDEuMDtcbiAgdmFyIHIgPSBnbE1hdHJpeC5SQU5ET00oKSAqIDIuMCAqIE1hdGguUEk7XG4gIHZhciB6ID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyLjAgLSAxLjA7XG4gIHZhciB6U2NhbGUgPSBNYXRoLnNxcnQoMS4wIC0geiAqIHopICogc2NhbGU7XG4gIG91dFswXSA9IE1hdGguY29zKHIpICogelNjYWxlO1xuICBvdXRbMV0gPSBNYXRoLnNpbihyKSAqIHpTY2FsZTtcbiAgb3V0WzJdID0geiAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzMgd2l0aCBhIG1hdDQuXHJcbiAqIDR0aCB2ZWN0b3IgY29tcG9uZW50IGlzIGltcGxpY2l0bHkgJzEnXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHRyYW5zZm9ybU1hdDQob3V0LCBhLCBtKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdLFxuICAgICAgeiA9IGFbMl07XG4gIHZhciB3ID0gbVszXSAqIHggKyBtWzddICogeSArIG1bMTFdICogeiArIG1bMTVdO1xuICB3ID0gdyB8fCAxLjA7XG4gIG91dFswXSA9IChtWzBdICogeCArIG1bNF0gKiB5ICsgbVs4XSAqIHogKyBtWzEyXSkgLyB3O1xuICBvdXRbMV0gPSAobVsxXSAqIHggKyBtWzVdICogeSArIG1bOV0gKiB6ICsgbVsxM10pIC8gdztcbiAgb3V0WzJdID0gKG1bMl0gKiB4ICsgbVs2XSAqIHkgKyBtWzEwXSAqIHogKyBtWzE0XSkgLyB3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzMgd2l0aCBhIG1hdDMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBtIHRoZSAzeDMgbWF0cml4IHRvIHRyYW5zZm9ybSB3aXRoXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gdHJhbnNmb3JtTWF0MyhvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTtcbiAgb3V0WzBdID0geCAqIG1bMF0gKyB5ICogbVszXSArIHogKiBtWzZdO1xuICBvdXRbMV0gPSB4ICogbVsxXSArIHkgKiBtWzRdICsgeiAqIG1bN107XG4gIG91dFsyXSA9IHggKiBtWzJdICsgeSAqIG1bNV0gKyB6ICogbVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMzIHdpdGggYSBxdWF0XHJcbiAqIENhbiBhbHNvIGJlIHVzZWQgZm9yIGR1YWwgcXVhdGVybmlvbnMuIChNdWx0aXBseSBpdCB3aXRoIHRoZSByZWFsIHBhcnQpXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIHF1YXRlcm5pb24gdG8gdHJhbnNmb3JtIHdpdGhcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiB0cmFuc2Zvcm1RdWF0KG91dCwgYSwgcSkge1xuICAvLyBiZW5jaG1hcmtzOiBodHRwczovL2pzcGVyZi5jb20vcXVhdGVybmlvbi10cmFuc2Zvcm0tdmVjMy1pbXBsZW1lbnRhdGlvbnMtZml4ZWRcbiAgdmFyIHF4ID0gcVswXSxcbiAgICAgIHF5ID0gcVsxXSxcbiAgICAgIHF6ID0gcVsyXSxcbiAgICAgIHF3ID0gcVszXTtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTsgLy8gdmFyIHF2ZWMgPSBbcXgsIHF5LCBxel07XG4gIC8vIHZhciB1diA9IHZlYzMuY3Jvc3MoW10sIHF2ZWMsIGEpO1xuXG4gIHZhciB1dnggPSBxeSAqIHogLSBxeiAqIHksXG4gICAgICB1dnkgPSBxeiAqIHggLSBxeCAqIHosXG4gICAgICB1dnogPSBxeCAqIHkgLSBxeSAqIHg7IC8vIHZhciB1dXYgPSB2ZWMzLmNyb3NzKFtdLCBxdmVjLCB1dik7XG5cbiAgdmFyIHV1dnggPSBxeSAqIHV2eiAtIHF6ICogdXZ5LFxuICAgICAgdXV2eSA9IHF6ICogdXZ4IC0gcXggKiB1dnosXG4gICAgICB1dXZ6ID0gcXggKiB1dnkgLSBxeSAqIHV2eDsgLy8gdmVjMy5zY2FsZSh1diwgdXYsIDIgKiB3KTtcblxuICB2YXIgdzIgPSBxdyAqIDI7XG4gIHV2eCAqPSB3MjtcbiAgdXZ5ICo9IHcyO1xuICB1dnogKj0gdzI7IC8vIHZlYzMuc2NhbGUodXV2LCB1dXYsIDIpO1xuXG4gIHV1dnggKj0gMjtcbiAgdXV2eSAqPSAyO1xuICB1dXZ6ICo9IDI7IC8vIHJldHVybiB2ZWMzLmFkZChvdXQsIGEsIHZlYzMuYWRkKG91dCwgdXYsIHV1dikpO1xuXG4gIG91dFswXSA9IHggKyB1dnggKyB1dXZ4O1xuICBvdXRbMV0gPSB5ICsgdXZ5ICsgdXV2eTtcbiAgb3V0WzJdID0geiArIHV2eiArIHV1dno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUm90YXRlIGEgM0QgdmVjdG9yIGFyb3VuZCB0aGUgeC1heGlzXHJcbiAqIEBwYXJhbSB7dmVjM30gb3V0IFRoZSByZWNlaXZpbmcgdmVjM1xyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSBUaGUgdmVjMyBwb2ludCB0byByb3RhdGVcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgVGhlIG9yaWdpbiBvZiB0aGUgcm90YXRpb25cclxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCBUaGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFuc1xyXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdGF0ZVgob3V0LCBhLCBiLCByYWQpIHtcbiAgdmFyIHAgPSBbXSxcbiAgICAgIHIgPSBbXTsgLy9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuXG4gIHBbMF0gPSBhWzBdIC0gYlswXTtcbiAgcFsxXSA9IGFbMV0gLSBiWzFdO1xuICBwWzJdID0gYVsyXSAtIGJbMl07IC8vcGVyZm9ybSByb3RhdGlvblxuXG4gIHJbMF0gPSBwWzBdO1xuICByWzFdID0gcFsxXSAqIE1hdGguY29zKHJhZCkgLSBwWzJdICogTWF0aC5zaW4ocmFkKTtcbiAgclsyXSA9IHBbMV0gKiBNYXRoLnNpbihyYWQpICsgcFsyXSAqIE1hdGguY29zKHJhZCk7IC8vdHJhbnNsYXRlIHRvIGNvcnJlY3QgcG9zaXRpb25cblxuICBvdXRbMF0gPSByWzBdICsgYlswXTtcbiAgb3V0WzFdID0gclsxXSArIGJbMV07XG4gIG91dFsyXSA9IHJbMl0gKyBiWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJvdGF0ZSBhIDNEIHZlY3RvciBhcm91bmQgdGhlIHktYXhpc1xyXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCBUaGUgcmVjZWl2aW5nIHZlYzNcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgVGhlIHZlYzMgcG9pbnQgdG8gcm90YXRlXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBvcmlnaW4gb2YgdGhlIHJvdGF0aW9uXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgVGhlIGFuZ2xlIG9mIHJvdGF0aW9uIGluIHJhZGlhbnNcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiByb3RhdGVZKG91dCwgYSwgYiwgcmFkKSB7XG4gIHZhciBwID0gW10sXG4gICAgICByID0gW107IC8vVHJhbnNsYXRlIHBvaW50IHRvIHRoZSBvcmlnaW5cblxuICBwWzBdID0gYVswXSAtIGJbMF07XG4gIHBbMV0gPSBhWzFdIC0gYlsxXTtcbiAgcFsyXSA9IGFbMl0gLSBiWzJdOyAvL3BlcmZvcm0gcm90YXRpb25cblxuICByWzBdID0gcFsyXSAqIE1hdGguc2luKHJhZCkgKyBwWzBdICogTWF0aC5jb3MocmFkKTtcbiAgclsxXSA9IHBbMV07XG4gIHJbMl0gPSBwWzJdICogTWF0aC5jb3MocmFkKSAtIHBbMF0gKiBNYXRoLnNpbihyYWQpOyAvL3RyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG5cbiAgb3V0WzBdID0gclswXSArIGJbMF07XG4gIG91dFsxXSA9IHJbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSByWzJdICsgYlsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBSb3RhdGUgYSAzRCB2ZWN0b3IgYXJvdW5kIHRoZSB6LWF4aXNcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgVGhlIHJlY2VpdmluZyB2ZWMzXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSB2ZWMzIHBvaW50IHRvIHJvdGF0ZVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiBUaGUgb3JpZ2luIG9mIHRoZSByb3RhdGlvblxyXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIFRoZSBhbmdsZSBvZiByb3RhdGlvbiBpbiByYWRpYW5zXHJcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gcm90YXRlWihvdXQsIGEsIGIsIHJhZCkge1xuICB2YXIgcCA9IFtdLFxuICAgICAgciA9IFtdOyAvL1RyYW5zbGF0ZSBwb2ludCB0byB0aGUgb3JpZ2luXG5cbiAgcFswXSA9IGFbMF0gLSBiWzBdO1xuICBwWzFdID0gYVsxXSAtIGJbMV07XG4gIHBbMl0gPSBhWzJdIC0gYlsyXTsgLy9wZXJmb3JtIHJvdGF0aW9uXG5cbiAgclswXSA9IHBbMF0gKiBNYXRoLmNvcyhyYWQpIC0gcFsxXSAqIE1hdGguc2luKHJhZCk7XG4gIHJbMV0gPSBwWzBdICogTWF0aC5zaW4ocmFkKSArIHBbMV0gKiBNYXRoLmNvcyhyYWQpO1xuICByWzJdID0gcFsyXTsgLy90cmFuc2xhdGUgdG8gY29ycmVjdCBwb3NpdGlvblxuXG4gIG91dFswXSA9IHJbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSByWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gclsyXSArIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogR2V0IHRoZSBhbmdsZSBiZXR3ZWVuIHR3byAzRCB2ZWN0b3JzXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgYW5nbGUgaW4gcmFkaWFuc1xyXG4gKi9cblxuXG5mdW5jdGlvbiBhbmdsZShhLCBiKSB7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl0sXG4gICAgICBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICBieiA9IGJbMl0sXG4gICAgICBtYWcxID0gTWF0aC5zcXJ0KGF4ICogYXggKyBheSAqIGF5ICsgYXogKiBheiksXG4gICAgICBtYWcyID0gTWF0aC5zcXJ0KGJ4ICogYnggKyBieSAqIGJ5ICsgYnogKiBieiksXG4gICAgICBtYWcgPSBtYWcxICogbWFnMixcbiAgICAgIGNvc2luZSA9IG1hZyAmJiBkb3QoYSwgYikgLyBtYWc7XG4gIHJldHVybiBNYXRoLmFjb3MoTWF0aC5taW4oTWF0aC5tYXgoY29zaW5lLCAtMSksIDEpKTtcbn1cbi8qKlxyXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzIHRvIHplcm9cclxuICpcclxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHJldHVybnMge3ZlYzN9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiB6ZXJvKG91dCkge1xuICBvdXRbMF0gPSAwLjA7XG4gIG91dFsxXSA9IDAuMDtcbiAgb3V0WzJdID0gMC4wO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB2ZWN0b3JcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJ2ZWMzKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIpXCI7XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSBmaXJzdCB2ZWN0b3IuXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl07XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSBmaXJzdCB2ZWN0b3IuXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpO1xufVxuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5zdWJ0cmFjdH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5cbnZhciBzdWIgPSBzdWJ0cmFjdDtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMubXVsdGlwbHl9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5zdWIgPSBzdWI7XG52YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLmRpdmlkZX1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLm11bCA9IG11bDtcbnZhciBkaXYgPSBkaXZpZGU7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLmRpc3RhbmNlfVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuZGl2ID0gZGl2O1xudmFyIGRpc3QgPSBkaXN0YW5jZTtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMuc3F1YXJlZERpc3RhbmNlfVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuZGlzdCA9IGRpc3Q7XG52YXIgc3FyRGlzdCA9IHNxdWFyZWREaXN0YW5jZTtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMubGVuZ3RofVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuc3FyRGlzdCA9IHNxckRpc3Q7XG52YXIgbGVuID0gbGVuZ3RoO1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjMy5zcXVhcmVkTGVuZ3RofVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMubGVuID0gbGVuO1xudmFyIHNxckxlbiA9IHNxdWFyZWRMZW5ndGg7XG4vKipcclxuICogUGVyZm9ybSBzb21lIG9wZXJhdGlvbiBvdmVyIGFuIGFycmF5IG9mIHZlYzNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5fSBhIHRoZSBhcnJheSBvZiB2ZWN0b3JzIHRvIGl0ZXJhdGUgb3ZlclxyXG4gKiBAcGFyYW0ge051bWJlcn0gc3RyaWRlIE51bWJlciBvZiBlbGVtZW50cyBiZXR3ZWVuIHRoZSBzdGFydCBvZiBlYWNoIHZlYzMuIElmIDAgYXNzdW1lcyB0aWdodGx5IHBhY2tlZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IE51bWJlciBvZiBlbGVtZW50cyB0byBza2lwIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5XHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBOdW1iZXIgb2YgdmVjM3MgdG8gaXRlcmF0ZSBvdmVyLiBJZiAwIGl0ZXJhdGVzIG92ZXIgZW50aXJlIGFycmF5XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggdmVjdG9yIGluIHRoZSBhcnJheVxyXG4gKiBAcGFyYW0ge09iamVjdH0gW2FyZ10gYWRkaXRpb25hbCBhcmd1bWVudCB0byBwYXNzIHRvIGZuXHJcbiAqIEByZXR1cm5zIHtBcnJheX0gYVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuc3FyTGVuID0gc3FyTGVuO1xuXG52YXIgZm9yRWFjaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHZlYyA9IGNyZWF0ZSgpO1xuICByZXR1cm4gZnVuY3Rpb24gKGEsIHN0cmlkZSwgb2Zmc2V0LCBjb3VudCwgZm4sIGFyZykge1xuICAgIHZhciBpLCBsO1xuXG4gICAgaWYgKCFzdHJpZGUpIHtcbiAgICAgIHN0cmlkZSA9IDM7XG4gICAgfVxuXG4gICAgaWYgKCFvZmZzZXQpIHtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuXG4gICAgaWYgKGNvdW50KSB7XG4gICAgICBsID0gTWF0aC5taW4oY291bnQgKiBzdHJpZGUgKyBvZmZzZXQsIGEubGVuZ3RoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbCA9IGEubGVuZ3RoO1xuICAgIH1cblxuICAgIGZvciAoaSA9IG9mZnNldDsgaSA8IGw7IGkgKz0gc3RyaWRlKSB7XG4gICAgICB2ZWNbMF0gPSBhW2ldO1xuICAgICAgdmVjWzFdID0gYVtpICsgMV07XG4gICAgICB2ZWNbMl0gPSBhW2kgKyAyXTtcbiAgICAgIGZuKHZlYywgdmVjLCBhcmcpO1xuICAgICAgYVtpXSA9IHZlY1swXTtcbiAgICAgIGFbaSArIDFdID0gdmVjWzFdO1xuICAgICAgYVtpICsgMl0gPSB2ZWNbMl07XG4gICAgfVxuXG4gICAgcmV0dXJuIGE7XG4gIH07XG59KCk7XG5cbmV4cG9ydHMuZm9yRWFjaCA9IGZvckVhY2g7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfTsgfSBlbHNlIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mKG9iaik7IH1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuY3JlYXRlID0gY3JlYXRlO1xuZXhwb3J0cy5jbG9uZSA9IGNsb25lO1xuZXhwb3J0cy5mcm9tVmFsdWVzID0gZnJvbVZhbHVlcztcbmV4cG9ydHMuY29weSA9IGNvcHk7XG5leHBvcnRzLnNldCA9IHNldDtcbmV4cG9ydHMuYWRkID0gYWRkO1xuZXhwb3J0cy5zdWJ0cmFjdCA9IHN1YnRyYWN0O1xuZXhwb3J0cy5tdWx0aXBseSA9IG11bHRpcGx5O1xuZXhwb3J0cy5kaXZpZGUgPSBkaXZpZGU7XG5leHBvcnRzLmNlaWwgPSBjZWlsO1xuZXhwb3J0cy5mbG9vciA9IGZsb29yO1xuZXhwb3J0cy5taW4gPSBtaW47XG5leHBvcnRzLm1heCA9IG1heDtcbmV4cG9ydHMucm91bmQgPSByb3VuZDtcbmV4cG9ydHMuc2NhbGUgPSBzY2FsZTtcbmV4cG9ydHMuc2NhbGVBbmRBZGQgPSBzY2FsZUFuZEFkZDtcbmV4cG9ydHMuZGlzdGFuY2UgPSBkaXN0YW5jZTtcbmV4cG9ydHMuc3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZERpc3RhbmNlO1xuZXhwb3J0cy5sZW5ndGggPSBsZW5ndGg7XG5leHBvcnRzLnNxdWFyZWRMZW5ndGggPSBzcXVhcmVkTGVuZ3RoO1xuZXhwb3J0cy5uZWdhdGUgPSBuZWdhdGU7XG5leHBvcnRzLmludmVyc2UgPSBpbnZlcnNlO1xuZXhwb3J0cy5ub3JtYWxpemUgPSBub3JtYWxpemU7XG5leHBvcnRzLmRvdCA9IGRvdDtcbmV4cG9ydHMuY3Jvc3MgPSBjcm9zcztcbmV4cG9ydHMubGVycCA9IGxlcnA7XG5leHBvcnRzLnJhbmRvbSA9IHJhbmRvbTtcbmV4cG9ydHMudHJhbnNmb3JtTWF0NCA9IHRyYW5zZm9ybU1hdDQ7XG5leHBvcnRzLnRyYW5zZm9ybVF1YXQgPSB0cmFuc2Zvcm1RdWF0O1xuZXhwb3J0cy56ZXJvID0gemVybztcbmV4cG9ydHMuc3RyID0gc3RyO1xuZXhwb3J0cy5leGFjdEVxdWFscyA9IGV4YWN0RXF1YWxzO1xuZXhwb3J0cy5lcXVhbHMgPSBlcXVhbHM7XG5leHBvcnRzLmZvckVhY2ggPSBleHBvcnRzLnNxckxlbiA9IGV4cG9ydHMubGVuID0gZXhwb3J0cy5zcXJEaXN0ID0gZXhwb3J0cy5kaXN0ID0gZXhwb3J0cy5kaXYgPSBleHBvcnRzLm11bCA9IGV4cG9ydHMuc3ViID0gdm9pZCAwO1xuXG52YXIgZ2xNYXRyaXggPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9jb21tb24uanNcIikpO1xuXG5mdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoKSB7IGlmICh0eXBlb2YgV2Vha01hcCAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gbnVsbDsgdmFyIGNhY2hlID0gbmV3IFdlYWtNYXAoKTsgX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlID0gZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCkgeyByZXR1cm4gY2FjaGU7IH07IHJldHVybiBjYWNoZTsgfVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGlmIChvYmogPT09IG51bGwgfHwgX3R5cGVvZihvYmopICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmogIT09IFwiZnVuY3Rpb25cIikgeyByZXR1cm4geyBcImRlZmF1bHRcIjogb2JqIH07IH0gdmFyIGNhY2hlID0gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKCk7IGlmIChjYWNoZSAmJiBjYWNoZS5oYXMob2JqKSkgeyByZXR1cm4gY2FjaGUuZ2V0KG9iaik7IH0gdmFyIG5ld09iaiA9IHt9OyB2YXIgaGFzUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHsgdmFyIGRlc2MgPSBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KSA6IG51bGw7IGlmIChkZXNjICYmIChkZXNjLmdldCB8fCBkZXNjLnNldCkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld09iaiwga2V5LCBkZXNjKTsgfSBlbHNlIHsgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IH0gbmV3T2JqW1wiZGVmYXVsdFwiXSA9IG9iajsgaWYgKGNhY2hlKSB7IGNhY2hlLnNldChvYmosIG5ld09iaik7IH0gcmV0dXJuIG5ld09iajsgfVxuXG4vKipcclxuICogNCBEaW1lbnNpb25hbCBWZWN0b3JcclxuICogQG1vZHVsZSB2ZWM0XHJcbiAqL1xuXG4vKipcclxuICogQ3JlYXRlcyBhIG5ldywgZW1wdHkgdmVjNFxyXG4gKlxyXG4gKiBAcmV0dXJucyB7dmVjNH0gYSBuZXcgNEQgdmVjdG9yXHJcbiAqL1xuZnVuY3Rpb24gY3JlYXRlKCkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoNCk7XG5cbiAgaWYgKGdsTWF0cml4LkFSUkFZX1RZUEUgIT0gRmxvYXQzMkFycmF5KSB7XG4gICAgb3V0WzBdID0gMDtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ3JlYXRlcyBhIG5ldyB2ZWM0IGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgdmVjdG9yXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBjbG9uZVxyXG4gKiBAcmV0dXJucyB7dmVjNH0gYSBuZXcgNEQgdmVjdG9yXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgdmVjNCBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcclxuICpcclxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcclxuICogQHBhcmFtIHtOdW1iZXJ9IHcgVyBjb21wb25lbnRcclxuICogQHJldHVybnMge3ZlYzR9IGEgbmV3IDREIHZlY3RvclxyXG4gKi9cblxuXG5mdW5jdGlvbiBmcm9tVmFsdWVzKHgsIHksIHosIHcpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICBvdXRbMF0gPSB4O1xuICBvdXRbMV0gPSB5O1xuICBvdXRbMl0gPSB6O1xuICBvdXRbM10gPSB3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSB2ZWM0IHRvIGFub3RoZXJcclxuICpcclxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIHNvdXJjZSB2ZWN0b3JcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzQgdG8gdGhlIGdpdmVuIHZhbHVlc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge051bWJlcn0geCBYIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0ge051bWJlcn0gdyBXIGNvbXBvbmVudFxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHNldChvdXQsIHgsIHksIHosIHcpIHtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgb3V0WzJdID0gejtcbiAgb3V0WzNdID0gdztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBBZGRzIHR3byB2ZWM0J3NcclxuICpcclxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBTdWJ0cmFjdHMgdmVjdG9yIGIgZnJvbSB2ZWN0b3IgYVxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgb3V0WzNdID0gYVszXSAtIGJbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogTXVsdGlwbGllcyB0d28gdmVjNCdzXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG11bHRpcGx5KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYlswXTtcbiAgb3V0WzFdID0gYVsxXSAqIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKiBiWzJdO1xuICBvdXRbM10gPSBhWzNdICogYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBEaXZpZGVzIHR3byB2ZWM0J3NcclxuICpcclxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gZGl2aWRlKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC8gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAvIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLyBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC8gYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBNYXRoLmNlaWwgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBjZWlsXHJcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gY2VpbChvdXQsIGEpIHtcbiAgb3V0WzBdID0gTWF0aC5jZWlsKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLmNlaWwoYVsxXSk7XG4gIG91dFsyXSA9IE1hdGguY2VpbChhWzJdKTtcbiAgb3V0WzNdID0gTWF0aC5jZWlsKGFbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE1hdGguZmxvb3IgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBmbG9vclxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGZsb29yKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLmZsb29yKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLmZsb29yKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLmZsb29yKGFbMl0pO1xuICBvdXRbM10gPSBNYXRoLmZsb29yKGFbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgdGhlIG1pbmltdW0gb2YgdHdvIHZlYzQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtaW4ob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IE1hdGgubWluKGFbMF0sIGJbMF0pO1xuICBvdXRbMV0gPSBNYXRoLm1pbihhWzFdLCBiWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5taW4oYVsyXSwgYlsyXSk7XG4gIG91dFszXSA9IE1hdGgubWluKGFbM10sIGJbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgdGhlIG1heGltdW0gb2YgdHdvIHZlYzQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBtYXgob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IE1hdGgubWF4KGFbMF0sIGJbMF0pO1xuICBvdXRbMV0gPSBNYXRoLm1heChhWzFdLCBiWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5tYXgoYVsyXSwgYlsyXSk7XG4gIG91dFszXSA9IE1hdGgubWF4KGFbM10sIGJbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE1hdGgucm91bmQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byByb3VuZFxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJvdW5kKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLnJvdW5kKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLnJvdW5kKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLnJvdW5kKGFbMl0pO1xuICBvdXRbM10gPSBNYXRoLnJvdW5kKGFbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFNjYWxlcyBhIHZlYzQgYnkgYSBzY2FsYXIgbnVtYmVyXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcclxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSB2ZWN0b3IgYnlcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzY2FsZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgb3V0WzNdID0gYVszXSAqIGI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQWRkcyB0d28gdmVjNCdzIGFmdGVyIHNjYWxpbmcgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgdGhlIGFtb3VudCB0byBzY2FsZSBiIGJ5IGJlZm9yZSBhZGRpbmdcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBzY2FsZUFuZEFkZChvdXQsIGEsIGIsIHNjYWxlKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdICogc2NhbGU7XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdICogc2NhbGU7XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdICogc2NhbGU7XG4gIG91dFszXSA9IGFbM10gKyBiWzNdICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzQnc1xyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcclxuICogQHJldHVybnMge051bWJlcn0gZGlzdGFuY2UgYmV0d2VlbiBhIGFuZCBiXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGRpc3RhbmNlKGEsIGIpIHtcbiAgdmFyIHggPSBiWzBdIC0gYVswXTtcbiAgdmFyIHkgPSBiWzFdIC0gYVsxXTtcbiAgdmFyIHogPSBiWzJdIC0gYVsyXTtcbiAgdmFyIHcgPSBiWzNdIC0gYVszXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSwgeiwgdyk7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjNCdzXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxyXG4gKi9cblxuXG5mdW5jdGlvbiBzcXVhcmVkRGlzdGFuY2UoYSwgYikge1xuICB2YXIgeCA9IGJbMF0gLSBhWzBdO1xuICB2YXIgeSA9IGJbMV0gLSBhWzFdO1xuICB2YXIgeiA9IGJbMl0gLSBhWzJdO1xuICB2YXIgdyA9IGJbM10gLSBhWzNdO1xuICByZXR1cm4geCAqIHggKyB5ICogeSArIHogKiB6ICsgdyAqIHc7XG59XG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjNFxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIGxlbmd0aCBvZlxyXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBsZW5ndGggb2YgYVxyXG4gKi9cblxuXG5mdW5jdGlvbiBsZW5ndGgoYSkge1xuICB2YXIgeCA9IGFbMF07XG4gIHZhciB5ID0gYVsxXTtcbiAgdmFyIHogPSBhWzJdO1xuICB2YXIgdyA9IGFbM107XG4gIHJldHVybiBNYXRoLmh5cG90KHgsIHksIHosIHcpO1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgbGVuZ3RoIG9mIGEgdmVjNFxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgbGVuZ3RoIG9mIGFcclxuICovXG5cblxuZnVuY3Rpb24gc3F1YXJlZExlbmd0aChhKSB7XG4gIHZhciB4ID0gYVswXTtcbiAgdmFyIHkgPSBhWzFdO1xuICB2YXIgeiA9IGFbMl07XG4gIHZhciB3ID0gYVszXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogeiArIHcgKiB3O1xufVxuLyoqXHJcbiAqIE5lZ2F0ZXMgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBuZWdhdGVcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBuZWdhdGUob3V0LCBhKSB7XG4gIG91dFswXSA9IC1hWzBdO1xuICBvdXRbMV0gPSAtYVsxXTtcbiAgb3V0WzJdID0gLWFbMl07XG4gIG91dFszXSA9IC1hWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBpbnZlcnRcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBpbnZlcnNlKG91dCwgYSkge1xuICBvdXRbMF0gPSAxLjAgLyBhWzBdO1xuICBvdXRbMV0gPSAxLjAgLyBhWzFdO1xuICBvdXRbMl0gPSAxLjAgLyBhWzJdO1xuICBvdXRbM10gPSAxLjAgLyBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIE5vcm1hbGl6ZSBhIHZlYzRcclxuICpcclxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIG5vcm1hbGl6ZVxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZShvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgdmFyIHcgPSBhWzNdO1xuICB2YXIgbGVuID0geCAqIHggKyB5ICogeSArIHogKiB6ICsgdyAqIHc7XG5cbiAgaWYgKGxlbiA+IDApIHtcbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gIH1cblxuICBvdXRbMF0gPSB4ICogbGVuO1xuICBvdXRbMV0gPSB5ICogbGVuO1xuICBvdXRbMl0gPSB6ICogbGVuO1xuICBvdXRbM10gPSB3ICogbGVuO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHR3byB2ZWM0J3NcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcclxuICovXG5cblxuZnVuY3Rpb24gZG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXSArIGFbM10gKiBiWzNdO1xufVxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGNyb3NzLXByb2R1Y3Qgb2YgdGhyZWUgdmVjdG9ycyBpbiBhIDQtZGltZW5zaW9uYWwgc3BhY2VcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IHJlc3VsdCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gVSB0aGUgZmlyc3QgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBWIHRoZSBzZWNvbmQgdmVjdG9yXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBXIHRoZSB0aGlyZCB2ZWN0b3JcclxuICogQHJldHVybnMge3ZlYzR9IHJlc3VsdFxyXG4gKi9cblxuXG5mdW5jdGlvbiBjcm9zcyhvdXQsIHUsIHYsIHcpIHtcbiAgdmFyIEEgPSB2WzBdICogd1sxXSAtIHZbMV0gKiB3WzBdLFxuICAgICAgQiA9IHZbMF0gKiB3WzJdIC0gdlsyXSAqIHdbMF0sXG4gICAgICBDID0gdlswXSAqIHdbM10gLSB2WzNdICogd1swXSxcbiAgICAgIEQgPSB2WzFdICogd1syXSAtIHZbMl0gKiB3WzFdLFxuICAgICAgRSA9IHZbMV0gKiB3WzNdIC0gdlszXSAqIHdbMV0sXG4gICAgICBGID0gdlsyXSAqIHdbM10gLSB2WzNdICogd1syXTtcbiAgdmFyIEcgPSB1WzBdO1xuICB2YXIgSCA9IHVbMV07XG4gIHZhciBJID0gdVsyXTtcbiAgdmFyIEogPSB1WzNdO1xuICBvdXRbMF0gPSBIICogRiAtIEkgKiBFICsgSiAqIEQ7XG4gIG91dFsxXSA9IC0oRyAqIEYpICsgSSAqIEMgLSBKICogQjtcbiAgb3V0WzJdID0gRyAqIEUgLSBIICogQyArIEogKiBBO1xuICBvdXRbM10gPSAtKEcgKiBEKSArIEggKiBCIC0gSSAqIEE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogUGVyZm9ybXMgYSBsaW5lYXIgaW50ZXJwb2xhdGlvbiBiZXR3ZWVuIHR3byB2ZWM0J3NcclxuICpcclxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiBsZXJwKG91dCwgYSwgYiwgdCkge1xuICB2YXIgYXggPSBhWzBdO1xuICB2YXIgYXkgPSBhWzFdO1xuICB2YXIgYXogPSBhWzJdO1xuICB2YXIgYXcgPSBhWzNdO1xuICBvdXRbMF0gPSBheCArIHQgKiAoYlswXSAtIGF4KTtcbiAgb3V0WzFdID0gYXkgKyB0ICogKGJbMV0gLSBheSk7XG4gIG91dFsyXSA9IGF6ICsgdCAqIChiWzJdIC0gYXopO1xuICBvdXRbM10gPSBhdyArIHQgKiAoYlszXSAtIGF3KTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSByYW5kb20gdmVjdG9yIHdpdGggdGhlIGdpdmVuIHNjYWxlXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2NhbGVdIExlbmd0aCBvZiB0aGUgcmVzdWx0aW5nIHZlY3Rvci4gSWYgb21taXR0ZWQsIGEgdW5pdCB2ZWN0b3Igd2lsbCBiZSByZXR1cm5lZFxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHJhbmRvbShvdXQsIHNjYWxlKSB7XG4gIHNjYWxlID0gc2NhbGUgfHwgMS4wOyAvLyBNYXJzYWdsaWEsIEdlb3JnZS4gQ2hvb3NpbmcgYSBQb2ludCBmcm9tIHRoZSBTdXJmYWNlIG9mIGFcbiAgLy8gU3BoZXJlLiBBbm4uIE1hdGguIFN0YXRpc3QuIDQzICgxOTcyKSwgbm8uIDIsIDY0NS0tNjQ2LlxuICAvLyBodHRwOi8vcHJvamVjdGV1Y2xpZC5vcmcvZXVjbGlkLmFvbXMvMTE3NzY5MjY0NDtcblxuICB2YXIgdjEsIHYyLCB2MywgdjQ7XG4gIHZhciBzMSwgczI7XG5cbiAgZG8ge1xuICAgIHYxID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyIC0gMTtcbiAgICB2MiA9IGdsTWF0cml4LlJBTkRPTSgpICogMiAtIDE7XG4gICAgczEgPSB2MSAqIHYxICsgdjIgKiB2MjtcbiAgfSB3aGlsZSAoczEgPj0gMSk7XG5cbiAgZG8ge1xuICAgIHYzID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyIC0gMTtcbiAgICB2NCA9IGdsTWF0cml4LlJBTkRPTSgpICogMiAtIDE7XG4gICAgczIgPSB2MyAqIHYzICsgdjQgKiB2NDtcbiAgfSB3aGlsZSAoczIgPj0gMSk7XG5cbiAgdmFyIGQgPSBNYXRoLnNxcnQoKDEgLSBzMSkgLyBzMik7XG4gIG91dFswXSA9IHNjYWxlICogdjE7XG4gIG91dFsxXSA9IHNjYWxlICogdjI7XG4gIG91dFsyXSA9IHNjYWxlICogdjMgKiBkO1xuICBvdXRbM10gPSBzY2FsZSAqIHY0ICogZDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxyXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWM0IHdpdGggYSBtYXQ0LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcclxuICogQHJldHVybnMge3ZlYzR9IG91dFxyXG4gKi9cblxuXG5mdW5jdGlvbiB0cmFuc2Zvcm1NYXQ0KG91dCwgYSwgbSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdLFxuICAgICAgdyA9IGFbM107XG4gIG91dFswXSA9IG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzhdICogeiArIG1bMTJdICogdztcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzVdICogeSArIG1bOV0gKiB6ICsgbVsxM10gKiB3O1xuICBvdXRbMl0gPSBtWzJdICogeCArIG1bNl0gKiB5ICsgbVsxMF0gKiB6ICsgbVsxNF0gKiB3O1xuICBvdXRbM10gPSBtWzNdICogeCArIG1bN10gKiB5ICsgbVsxMV0gKiB6ICsgbVsxNV0gKiB3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzQgd2l0aCBhIHF1YXRcclxuICpcclxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cclxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgcXVhdGVybmlvbiB0byB0cmFuc2Zvcm0gd2l0aFxyXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHRyYW5zZm9ybVF1YXQob3V0LCBhLCBxKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdLFxuICAgICAgeiA9IGFbMl07XG4gIHZhciBxeCA9IHFbMF0sXG4gICAgICBxeSA9IHFbMV0sXG4gICAgICBxeiA9IHFbMl0sXG4gICAgICBxdyA9IHFbM107IC8vIGNhbGN1bGF0ZSBxdWF0ICogdmVjXG5cbiAgdmFyIGl4ID0gcXcgKiB4ICsgcXkgKiB6IC0gcXogKiB5O1xuICB2YXIgaXkgPSBxdyAqIHkgKyBxeiAqIHggLSBxeCAqIHo7XG4gIHZhciBpeiA9IHF3ICogeiArIHF4ICogeSAtIHF5ICogeDtcbiAgdmFyIGl3ID0gLXF4ICogeCAtIHF5ICogeSAtIHF6ICogejsgLy8gY2FsY3VsYXRlIHJlc3VsdCAqIGludmVyc2UgcXVhdFxuXG4gIG91dFswXSA9IGl4ICogcXcgKyBpdyAqIC1xeCArIGl5ICogLXF6IC0gaXogKiAtcXk7XG4gIG91dFsxXSA9IGl5ICogcXcgKyBpdyAqIC1xeSArIGl6ICogLXF4IC0gaXggKiAtcXo7XG4gIG91dFsyXSA9IGl6ICogcXcgKyBpdyAqIC1xeiArIGl4ICogLXF5IC0gaXkgKiAtcXg7XG4gIG91dFszXSA9IGFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcclxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNCB0byB6ZXJvXHJcbiAqXHJcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXHJcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcclxuICovXG5cblxuZnVuY3Rpb24gemVybyhvdXQpIHtcbiAgb3V0WzBdID0gMC4wO1xuICBvdXRbMV0gPSAwLjA7XG4gIG91dFsyXSA9IDAuMDtcbiAgb3V0WzNdID0gMC4wO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXHJcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB2ZWN0b3JcclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxyXG4gKi9cblxuXG5mdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJ2ZWM0KFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIsIFwiICsgYVszXSArIFwiKVwiO1xufVxuLyoqXHJcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHZlY3RvcnMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSBUaGUgZmlyc3QgdmVjdG9yLlxyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiBUaGUgc2Vjb25kIHZlY3Rvci5cclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIHZlY3RvcnMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIGV4YWN0RXF1YWxzKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gPT09IGJbMF0gJiYgYVsxXSA9PT0gYlsxXSAmJiBhWzJdID09PSBiWzJdICYmIGFbM10gPT09IGJbM107XG59XG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIFRoZSBmaXJzdCB2ZWN0b3IuXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXG5cblxuZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpICYmIE1hdGguYWJzKGEzIC0gYjMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEzKSwgTWF0aC5hYnMoYjMpKTtcbn1cbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQuc3VidHJhY3R9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuXG52YXIgc3ViID0gc3VidHJhY3Q7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0Lm11bHRpcGx5fVxyXG4gKiBAZnVuY3Rpb25cclxuICovXG5cbmV4cG9ydHMuc3ViID0gc3ViO1xudmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5kaXZpZGV9XHJcbiAqIEBmdW5jdGlvblxyXG4gKi9cblxuZXhwb3J0cy5tdWwgPSBtdWw7XG52YXIgZGl2ID0gZGl2aWRlO1xuLyoqXHJcbiAqIEFsaWFzIGZvciB7QGxpbmsgdmVjNC5kaXN0YW5jZX1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmRpdiA9IGRpdjtcbnZhciBkaXN0ID0gZGlzdGFuY2U7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LnNxdWFyZWREaXN0YW5jZX1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmRpc3QgPSBkaXN0O1xudmFyIHNxckRpc3QgPSBzcXVhcmVkRGlzdGFuY2U7XG4vKipcclxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0Lmxlbmd0aH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLnNxckRpc3QgPSBzcXJEaXN0O1xudmFyIGxlbiA9IGxlbmd0aDtcbi8qKlxyXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQuc3F1YXJlZExlbmd0aH1cclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLmxlbiA9IGxlbjtcbnZhciBzcXJMZW4gPSBzcXVhcmVkTGVuZ3RoO1xuLyoqXHJcbiAqIFBlcmZvcm0gc29tZSBvcGVyYXRpb24gb3ZlciBhbiBhcnJheSBvZiB2ZWM0cy5cclxuICpcclxuICogQHBhcmFtIHtBcnJheX0gYSB0aGUgYXJyYXkgb2YgdmVjdG9ycyB0byBpdGVyYXRlIG92ZXJcclxuICogQHBhcmFtIHtOdW1iZXJ9IHN0cmlkZSBOdW1iZXIgb2YgZWxlbWVudHMgYmV0d2VlbiB0aGUgc3RhcnQgb2YgZWFjaCB2ZWM0LiBJZiAwIGFzc3VtZXMgdGlnaHRseSBwYWNrZWRcclxuICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gc2tpcCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBhcnJheVxyXG4gKiBAcGFyYW0ge051bWJlcn0gY291bnQgTnVtYmVyIG9mIHZlYzRzIHRvIGl0ZXJhdGUgb3Zlci4gSWYgMCBpdGVyYXRlcyBvdmVyIGVudGlyZSBhcnJheVxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBGdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIHZlY3RvciBpbiB0aGUgYXJyYXlcclxuICogQHBhcmFtIHtPYmplY3R9IFthcmddIGFkZGl0aW9uYWwgYXJndW1lbnQgdG8gcGFzcyB0byBmblxyXG4gKiBAcmV0dXJucyB7QXJyYXl9IGFcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xuXG5leHBvcnRzLnNxckxlbiA9IHNxckxlbjtcblxudmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB2ZWMgPSBjcmVhdGUoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhLCBzdHJpZGUsIG9mZnNldCwgY291bnQsIGZuLCBhcmcpIHtcbiAgICB2YXIgaSwgbDtcblxuICAgIGlmICghc3RyaWRlKSB7XG4gICAgICBzdHJpZGUgPSA0O1xuICAgIH1cblxuICAgIGlmICghb2Zmc2V0KSB7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgIH1cblxuICAgIGlmIChjb3VudCkge1xuICAgICAgbCA9IE1hdGgubWluKGNvdW50ICogc3RyaWRlICsgb2Zmc2V0LCBhLmxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGwgPSBhLmxlbmd0aDtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBsOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmVjWzBdID0gYVtpXTtcbiAgICAgIHZlY1sxXSA9IGFbaSArIDFdO1xuICAgICAgdmVjWzJdID0gYVtpICsgMl07XG4gICAgICB2ZWNbM10gPSBhW2kgKyAzXTtcbiAgICAgIGZuKHZlYywgdmVjLCBhcmcpO1xuICAgICAgYVtpXSA9IHZlY1swXTtcbiAgICAgIGFbaSArIDFdID0gdmVjWzFdO1xuICAgICAgYVtpICsgMl0gPSB2ZWNbMl07XG4gICAgICBhW2kgKyAzXSA9IHZlY1szXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfTtcbn0oKTtcblxuZXhwb3J0cy5mb3JFYWNoID0gZm9yRWFjaDsiLCIoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICAgIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuICAgIChnbG9iYWwuUmVzaXplT2JzZXJ2ZXIgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbiAgICAvKipcclxuICAgICAqIEEgY29sbGVjdGlvbiBvZiBzaGltcyB0aGF0IHByb3ZpZGUgbWluaW1hbCBmdW5jdGlvbmFsaXR5IG9mIHRoZSBFUzYgY29sbGVjdGlvbnMuXHJcbiAgICAgKlxyXG4gICAgICogVGhlc2UgaW1wbGVtZW50YXRpb25zIGFyZSBub3QgbWVhbnQgdG8gYmUgdXNlZCBvdXRzaWRlIG9mIHRoZSBSZXNpemVPYnNlcnZlclxyXG4gICAgICogbW9kdWxlcyBhcyB0aGV5IGNvdmVyIG9ubHkgYSBsaW1pdGVkIHJhbmdlIG9mIHVzZSBjYXNlcy5cclxuICAgICAqL1xyXG4gICAgLyogZXNsaW50LWRpc2FibGUgcmVxdWlyZS1qc2RvYywgdmFsaWQtanNkb2MgKi9cclxuICAgIHZhciBNYXBTaGltID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodHlwZW9mIE1hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hcDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmV0dXJucyBpbmRleCBpbiBwcm92aWRlZCBhcnJheSB0aGF0IG1hdGNoZXMgdGhlIHNwZWNpZmllZCBrZXkuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcGFyYW0ge0FycmF5PEFycmF5Pn0gYXJyXHJcbiAgICAgICAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIGdldEluZGV4KGFyciwga2V5KSB7XHJcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSAtMTtcclxuICAgICAgICAgICAgYXJyLnNvbWUoZnVuY3Rpb24gKGVudHJ5LCBpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVudHJ5WzBdID09PSBrZXkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBpbmRleDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGNsYXNzXzEoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9fZW50cmllc19fID0gW107XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNsYXNzXzEucHJvdG90eXBlLCBcInNpemVcIiwge1xyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX19lbnRyaWVzX18ubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0geyp9IGtleVxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGNsYXNzXzEucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGdldEluZGV4KHRoaXMuX19lbnRyaWVzX18sIGtleSk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZW50cnkgPSB0aGlzLl9fZW50cmllc19fW2luZGV4XTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeVsxXTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7Kn0ga2V5XHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcclxuICAgICAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gZ2V0SW5kZXgodGhpcy5fX2VudHJpZXNfXywga2V5KTtcclxuICAgICAgICAgICAgICAgIGlmICh+aW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9fZW50cmllc19fW2luZGV4XVsxXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fX2VudHJpZXNfXy5wdXNoKFtrZXksIHZhbHVlXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0geyp9IGtleVxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGNsYXNzXzEucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgICAgIHZhciBlbnRyaWVzID0gdGhpcy5fX2VudHJpZXNfXztcclxuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGdldEluZGV4KGVudHJpZXMsIGtleSk7XHJcbiAgICAgICAgICAgICAgICBpZiAofmluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgICAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gISF+Z2V0SW5kZXgodGhpcy5fX2VudHJpZXNfXywga2V5KTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgY2xhc3NfMS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9fZW50cmllc19fLnNwbGljZSgwKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7Kn0gW2N0eD1udWxsXVxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGNsYXNzXzEucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGN0eCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGN0eCA9PT0gdm9pZCAwKSB7IGN0eCA9IG51bGw7IH1cclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLl9fZW50cmllc19fOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbnRyeSA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGN0eCwgZW50cnlbMV0sIGVudHJ5WzBdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmV0dXJuIGNsYXNzXzE7XHJcbiAgICAgICAgfSgpKTtcclxuICAgIH0pKCk7XG5cbiAgICAvKipcclxuICAgICAqIERldGVjdHMgd2hldGhlciB3aW5kb3cgYW5kIGRvY3VtZW50IG9iamVjdHMgYXJlIGF2YWlsYWJsZSBpbiBjdXJyZW50IGVudmlyb25tZW50LlxyXG4gICAgICovXHJcbiAgICB2YXIgaXNCcm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZG9jdW1lbnQgPT09IGRvY3VtZW50O1xuXG4gICAgLy8gUmV0dXJucyBnbG9iYWwgb2JqZWN0IG9mIGEgY3VycmVudCBlbnZpcm9ubWVudC5cclxuICAgIHZhciBnbG9iYWwkMSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbC5NYXRoID09PSBNYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09PSBNYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzZWxmO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lk1hdGggPT09IE1hdGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXHJcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XHJcbiAgICB9KSgpO1xuXG4gICAgLyoqXHJcbiAgICAgKiBBIHNoaW0gZm9yIHRoZSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgd2hpY2ggZmFsbHMgYmFjayB0byB0aGUgc2V0VGltZW91dCBpZlxyXG4gICAgICogZmlyc3Qgb25lIGlzIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmVxdWVzdHMnIGlkZW50aWZpZXIuXHJcbiAgICAgKi9cclxuICAgIHZhciByZXF1ZXN0QW5pbWF0aW9uRnJhbWUkMSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgLy8gSXQncyByZXF1aXJlZCB0byB1c2UgYSBib3VuZGVkIGZ1bmN0aW9uIGJlY2F1c2UgSUUgc29tZXRpbWVzIHRocm93c1xyXG4gICAgICAgICAgICAvLyBhbiBcIkludmFsaWQgY2FsbGluZyBvYmplY3RcIiBlcnJvciBpZiByQUYgaXMgaW52b2tlZCB3aXRob3V0IHRoZSBnbG9iYWxcclxuICAgICAgICAgICAgLy8gb2JqZWN0IG9uIHRoZSBsZWZ0IGhhbmQgc2lkZS5cclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RBbmltYXRpb25GcmFtZS5iaW5kKGdsb2JhbCQxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChjYWxsYmFjaykgeyByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7IHJldHVybiBjYWxsYmFjayhEYXRlLm5vdygpKTsgfSwgMTAwMCAvIDYwKTsgfTtcclxuICAgIH0pKCk7XG5cbiAgICAvLyBEZWZpbmVzIG1pbmltdW0gdGltZW91dCBiZWZvcmUgYWRkaW5nIGEgdHJhaWxpbmcgY2FsbC5cclxuICAgIHZhciB0cmFpbGluZ1RpbWVvdXQgPSAyO1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgd3JhcHBlciBmdW5jdGlvbiB3aGljaCBlbnN1cmVzIHRoYXQgcHJvdmlkZWQgY2FsbGJhY2sgd2lsbCBiZVxyXG4gICAgICogaW52b2tlZCBvbmx5IG9uY2UgZHVyaW5nIHRoZSBzcGVjaWZpZWQgZGVsYXkgcGVyaW9kLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gYmUgaW52b2tlZCBhZnRlciB0aGUgZGVsYXkgcGVyaW9kLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRlbGF5IC0gRGVsYXkgYWZ0ZXIgd2hpY2ggdG8gaW52b2tlIGNhbGxiYWNrLlxyXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiB0aHJvdHRsZSAoY2FsbGJhY2ssIGRlbGF5KSB7XHJcbiAgICAgICAgdmFyIGxlYWRpbmdDYWxsID0gZmFsc2UsIHRyYWlsaW5nQ2FsbCA9IGZhbHNlLCBsYXN0Q2FsbFRpbWUgPSAwO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEludm9rZXMgdGhlIG9yaWdpbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIGFuZCBzY2hlZHVsZXMgbmV3IGludm9jYXRpb24gaWZcclxuICAgICAgICAgKiB0aGUgXCJwcm94eVwiIHdhcyBjYWxsZWQgZHVyaW5nIGN1cnJlbnQgcmVxdWVzdC5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIHJlc29sdmVQZW5kaW5nKCkge1xyXG4gICAgICAgICAgICBpZiAobGVhZGluZ0NhbGwpIHtcclxuICAgICAgICAgICAgICAgIGxlYWRpbmdDYWxsID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0cmFpbGluZ0NhbGwpIHtcclxuICAgICAgICAgICAgICAgIHByb3h5KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsbGJhY2sgaW52b2tlZCBhZnRlciB0aGUgc3BlY2lmaWVkIGRlbGF5LiBJdCB3aWxsIGZ1cnRoZXIgcG9zdHBvbmVcclxuICAgICAgICAgKiBpbnZvY2F0aW9uIG9mIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBkZWxlZ2F0aW5nIGl0IHRvIHRoZVxyXG4gICAgICAgICAqIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIHRpbWVvdXRDYWxsYmFjaygpIHtcclxuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lJDEocmVzb2x2ZVBlbmRpbmcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgaW52b2NhdGlvbiBvZiB0aGUgb3JpZ2luYWwgZnVuY3Rpb24uXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBwcm94eSgpIHtcclxuICAgICAgICAgICAgdmFyIHRpbWVTdGFtcCA9IERhdGUubm93KCk7XHJcbiAgICAgICAgICAgIGlmIChsZWFkaW5nQ2FsbCkge1xyXG4gICAgICAgICAgICAgICAgLy8gUmVqZWN0IGltbWVkaWF0ZWx5IGZvbGxvd2luZyBjYWxscy5cclxuICAgICAgICAgICAgICAgIGlmICh0aW1lU3RhbXAgLSBsYXN0Q2FsbFRpbWUgPCB0cmFpbGluZ1RpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBTY2hlZHVsZSBuZXcgY2FsbCB0byBiZSBpbiBpbnZva2VkIHdoZW4gdGhlIHBlbmRpbmcgb25lIGlzIHJlc29sdmVkLlxyXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIFwidHJhbnNpdGlvbnNcIiB3aGljaCBuZXZlciBhY3R1YWxseSBzdGFydFxyXG4gICAgICAgICAgICAgICAgLy8gaW1tZWRpYXRlbHkgc28gdGhlcmUgaXMgYSBjaGFuY2UgdGhhdCB3ZSBtaWdodCBtaXNzIG9uZSBpZiBjaGFuZ2VcclxuICAgICAgICAgICAgICAgIC8vIGhhcHBlbnMgYW1pZHMgdGhlIHBlbmRpbmcgaW52b2NhdGlvbi5cclxuICAgICAgICAgICAgICAgIHRyYWlsaW5nQ2FsbCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZWFkaW5nQ2FsbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0cmFpbGluZ0NhbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQodGltZW91dENhbGxiYWNrLCBkZWxheSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGFzdENhbGxUaW1lID0gdGltZVN0YW1wO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHJveHk7XHJcbiAgICB9XG5cbiAgICAvLyBNaW5pbXVtIGRlbGF5IGJlZm9yZSBpbnZva2luZyB0aGUgdXBkYXRlIG9mIG9ic2VydmVycy5cclxuICAgIHZhciBSRUZSRVNIX0RFTEFZID0gMjA7XHJcbiAgICAvLyBBIGxpc3Qgb2Ygc3Vic3RyaW5ncyBvZiBDU1MgcHJvcGVydGllcyB1c2VkIHRvIGZpbmQgdHJhbnNpdGlvbiBldmVudHMgdGhhdFxyXG4gICAgLy8gbWlnaHQgYWZmZWN0IGRpbWVuc2lvbnMgb2Ygb2JzZXJ2ZWQgZWxlbWVudHMuXHJcbiAgICB2YXIgdHJhbnNpdGlvbktleXMgPSBbJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCcsICd3aWR0aCcsICdoZWlnaHQnLCAnc2l6ZScsICd3ZWlnaHQnXTtcclxuICAgIC8vIENoZWNrIGlmIE11dGF0aW9uT2JzZXJ2ZXIgaXMgYXZhaWxhYmxlLlxyXG4gICAgdmFyIG11dGF0aW9uT2JzZXJ2ZXJTdXBwb3J0ZWQgPSB0eXBlb2YgTXV0YXRpb25PYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCc7XHJcbiAgICAvKipcclxuICAgICAqIFNpbmdsZXRvbiBjb250cm9sbGVyIGNsYXNzIHdoaWNoIGhhbmRsZXMgdXBkYXRlcyBvZiBSZXNpemVPYnNlcnZlciBpbnN0YW5jZXMuXHJcbiAgICAgKi9cclxuICAgIHZhciBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlcigpIHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEluZGljYXRlcyB3aGV0aGVyIERPTSBsaXN0ZW5lcnMgaGF2ZSBiZWVuIGFkZGVkLlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZSB7Ym9vbGVhbn1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGVkXyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGVsbHMgdGhhdCBjb250cm9sbGVyIGhhcyBzdWJzY3JpYmVkIGZvciBNdXRhdGlvbiBFdmVudHMuXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqIEBwcml2YXRlIHtib29sZWFufVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdGhpcy5tdXRhdGlvbkV2ZW50c0FkZGVkXyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogS2VlcHMgcmVmZXJlbmNlIHRvIHRoZSBpbnN0YW5jZSBvZiBNdXRhdGlvbk9ic2VydmVyLlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZSB7TXV0YXRpb25PYnNlcnZlcn1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfID0gbnVsbDtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEEgbGlzdCBvZiBjb25uZWN0ZWQgb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZSB7QXJyYXk8UmVzaXplT2JzZXJ2ZXJTUEk+fVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnNfID0gW107XHJcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2l0aW9uRW5kXyA9IHRoaXMub25UcmFuc2l0aW9uRW5kXy5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2ggPSB0aHJvdHRsZSh0aGlzLnJlZnJlc2guYmluZCh0aGlzKSwgUkVGUkVTSF9ERUxBWSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEFkZHMgb2JzZXJ2ZXIgdG8gb2JzZXJ2ZXJzIGxpc3QuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcGFyYW0ge1Jlc2l6ZU9ic2VydmVyU1BJfSBvYnNlcnZlciAtIE9ic2VydmVyIHRvIGJlIGFkZGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUuYWRkT2JzZXJ2ZXIgPSBmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgaWYgKCF+dGhpcy5vYnNlcnZlcnNfLmluZGV4T2Yob2JzZXJ2ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVyc18ucHVzaChvYnNlcnZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQWRkIGxpc3RlbmVycyBpZiB0aGV5IGhhdmVuJ3QgYmVlbiBhZGRlZCB5ZXQuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0ZWRfKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RfKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlbW92ZXMgb2JzZXJ2ZXIgZnJvbSBvYnNlcnZlcnMgbGlzdC5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJTUEl9IG9ic2VydmVyIC0gT2JzZXJ2ZXIgdG8gYmUgcmVtb3ZlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLnJlbW92ZU9ic2VydmVyID0gZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBvYnNlcnZlcnMgPSB0aGlzLm9ic2VydmVyc187XHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IG9ic2VydmVycy5pbmRleE9mKG9ic2VydmVyKTtcclxuICAgICAgICAgICAgLy8gUmVtb3ZlIG9ic2VydmVyIGlmIGl0J3MgcHJlc2VudCBpbiByZWdpc3RyeS5cclxuICAgICAgICAgICAgaWYgKH5pbmRleCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gUmVtb3ZlIGxpc3RlbmVycyBpZiBjb250cm9sbGVyIGhhcyBubyBjb25uZWN0ZWQgb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICBpZiAoIW9ic2VydmVycy5sZW5ndGggJiYgdGhpcy5jb25uZWN0ZWRfKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3RfKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEludm9rZXMgdGhlIHVwZGF0ZSBvZiBvYnNlcnZlcnMuIEl0IHdpbGwgY29udGludWUgcnVubmluZyB1cGRhdGVzIGluc29mYXJcclxuICAgICAgICAgKiBpdCBkZXRlY3RzIGNoYW5nZXMuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBjaGFuZ2VzRGV0ZWN0ZWQgPSB0aGlzLnVwZGF0ZU9ic2VydmVyc18oKTtcclxuICAgICAgICAgICAgLy8gQ29udGludWUgcnVubmluZyB1cGRhdGVzIGlmIGNoYW5nZXMgaGF2ZSBiZWVuIGRldGVjdGVkIGFzIHRoZXJlIG1pZ2h0XHJcbiAgICAgICAgICAgIC8vIGJlIGZ1dHVyZSBvbmVzIGNhdXNlZCBieSBDU1MgdHJhbnNpdGlvbnMuXHJcbiAgICAgICAgICAgIGlmIChjaGFuZ2VzRGV0ZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBVcGRhdGVzIGV2ZXJ5IG9ic2VydmVyIGZyb20gb2JzZXJ2ZXJzIGxpc3QgYW5kIG5vdGlmaWVzIHRoZW0gb2YgcXVldWVkXHJcbiAgICAgICAgICogZW50cmllcy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgXCJ0cnVlXCIgaWYgYW55IG9ic2VydmVyIGhhcyBkZXRlY3RlZCBjaGFuZ2VzIGluXHJcbiAgICAgICAgICogICAgICBkaW1lbnNpb25zIG9mIGl0J3MgZWxlbWVudHMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLnByb3RvdHlwZS51cGRhdGVPYnNlcnZlcnNfID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBDb2xsZWN0IG9ic2VydmVycyB0aGF0IGhhdmUgYWN0aXZlIG9ic2VydmF0aW9ucy5cclxuICAgICAgICAgICAgdmFyIGFjdGl2ZU9ic2VydmVycyA9IHRoaXMub2JzZXJ2ZXJzXy5maWx0ZXIoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JzZXJ2ZXIuZ2F0aGVyQWN0aXZlKCksIG9ic2VydmVyLmhhc0FjdGl2ZSgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgLy8gRGVsaXZlciBub3RpZmljYXRpb25zIGluIGEgc2VwYXJhdGUgY3ljbGUgaW4gb3JkZXIgdG8gYXZvaWQgYW55XHJcbiAgICAgICAgICAgIC8vIGNvbGxpc2lvbnMgYmV0d2VlbiBvYnNlcnZlcnMsIGUuZy4gd2hlbiBtdWx0aXBsZSBpbnN0YW5jZXMgb2ZcclxuICAgICAgICAgICAgLy8gUmVzaXplT2JzZXJ2ZXIgYXJlIHRyYWNraW5nIHRoZSBzYW1lIGVsZW1lbnQgYW5kIHRoZSBjYWxsYmFjayBvZiBvbmVcclxuICAgICAgICAgICAgLy8gb2YgdGhlbSBjaGFuZ2VzIGNvbnRlbnQgZGltZW5zaW9ucyBvZiB0aGUgb2JzZXJ2ZWQgdGFyZ2V0LiBTb21ldGltZXNcclxuICAgICAgICAgICAgLy8gdGhpcyBtYXkgcmVzdWx0IGluIG5vdGlmaWNhdGlvbnMgYmVpbmcgYmxvY2tlZCBmb3IgdGhlIHJlc3Qgb2Ygb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICBhY3RpdmVPYnNlcnZlcnMuZm9yRWFjaChmdW5jdGlvbiAob2JzZXJ2ZXIpIHsgcmV0dXJuIG9ic2VydmVyLmJyb2FkY2FzdEFjdGl2ZSgpOyB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIGFjdGl2ZU9ic2VydmVycy5sZW5ndGggPiAwO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogSW5pdGlhbGl6ZXMgRE9NIGxpc3RlbmVycy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLnByb3RvdHlwZS5jb25uZWN0XyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gRG8gbm90aGluZyBpZiBydW5uaW5nIGluIGEgbm9uLWJyb3dzZXIgZW52aXJvbm1lbnQgb3IgaWYgbGlzdGVuZXJzXHJcbiAgICAgICAgICAgIC8vIGhhdmUgYmVlbiBhbHJlYWR5IGFkZGVkLlxyXG4gICAgICAgICAgICBpZiAoIWlzQnJvd3NlciB8fCB0aGlzLmNvbm5lY3RlZF8pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBTdWJzY3JpcHRpb24gdG8gdGhlIFwiVHJhbnNpdGlvbmVuZFwiIGV2ZW50IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGZvclxyXG4gICAgICAgICAgICAvLyBkZWxheWVkIHRyYW5zaXRpb25zLiBUaGlzIHdheSBpdCdzIHBvc3NpYmxlIHRvIGNhcHR1cmUgYXQgbGVhc3QgdGhlXHJcbiAgICAgICAgICAgIC8vIGZpbmFsIHN0YXRlIG9mIGFuIGVsZW1lbnQuXHJcbiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCB0aGlzLm9uVHJhbnNpdGlvbkVuZF8pO1xyXG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5yZWZyZXNoKTtcclxuICAgICAgICAgICAgaWYgKG11dGF0aW9uT2JzZXJ2ZXJTdXBwb3J0ZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIodGhpcy5yZWZyZXNoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfLm9ic2VydmUoZG9jdW1lbnQsIHtcclxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1YnRyZWU6IHRydWVcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NU3VidHJlZU1vZGlmaWVkJywgdGhpcy5yZWZyZXNoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25FdmVudHNBZGRlZF8gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGVkXyA9IHRydWU7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZW1vdmVzIERPTSBsaXN0ZW5lcnMuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUuZGlzY29ubmVjdF8gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgaWYgcnVubmluZyBpbiBhIG5vbi1icm93c2VyIGVudmlyb25tZW50IG9yIGlmIGxpc3RlbmVyc1xyXG4gICAgICAgICAgICAvLyBoYXZlIGJlZW4gYWxyZWFkeSByZW1vdmVkLlxyXG4gICAgICAgICAgICBpZiAoIWlzQnJvd3NlciB8fCAhdGhpcy5jb25uZWN0ZWRfKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRoaXMub25UcmFuc2l0aW9uRW5kXyk7XHJcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLnJlZnJlc2gpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5tdXRhdGlvbnNPYnNlcnZlcl8pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfLmRpc2Nvbm5lY3QoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGhpcy5tdXRhdGlvbkV2ZW50c0FkZGVkXykge1xyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignRE9NU3VidHJlZU1vZGlmaWVkJywgdGhpcy5yZWZyZXNoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLm11dGF0aW9uc09ic2VydmVyXyA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMubXV0YXRpb25FdmVudHNBZGRlZF8gPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWRfID0gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBcIlRyYW5zaXRpb25lbmRcIiBldmVudCBoYW5kbGVyLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKiBAcGFyYW0ge1RyYW5zaXRpb25FdmVudH0gZXZlbnRcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLm9uVHJhbnNpdGlvbkVuZF8gPSBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICAgICAgdmFyIF9iID0gX2EucHJvcGVydHlOYW1lLCBwcm9wZXJ0eU5hbWUgPSBfYiA9PT0gdm9pZCAwID8gJycgOiBfYjtcclxuICAgICAgICAgICAgLy8gRGV0ZWN0IHdoZXRoZXIgdHJhbnNpdGlvbiBtYXkgYWZmZWN0IGRpbWVuc2lvbnMgb2YgYW4gZWxlbWVudC5cclxuICAgICAgICAgICAgdmFyIGlzUmVmbG93UHJvcGVydHkgPSB0cmFuc2l0aW9uS2V5cy5zb21lKGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAhIX5wcm9wZXJ0eU5hbWUuaW5kZXhPZihrZXkpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYgKGlzUmVmbG93UHJvcGVydHkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZXR1cm5zIGluc3RhbmNlIG9mIHRoZSBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJucyB7UmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5nZXRJbnN0YW5jZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmluc3RhbmNlXykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZV8gPSBuZXcgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2VfO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogSG9sZHMgcmVmZXJlbmNlIHRvIHRoZSBjb250cm9sbGVyJ3MgaW5zdGFuY2UuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcHJpdmF0ZSB7UmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5pbnN0YW5jZV8gPSBudWxsO1xyXG4gICAgICAgIHJldHVybiBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXI7XHJcbiAgICB9KCkpO1xuXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIG5vbi13cml0YWJsZS9lbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgdGhlIHByb3ZpZGVkIHRhcmdldCBvYmplY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCAtIE9iamVjdCBmb3Igd2hpY2ggdG8gZGVmaW5lIHByb3BlcnRpZXMuXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBQcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUYXJnZXQgb2JqZWN0LlxyXG4gICAgICovXHJcbiAgICB2YXIgZGVmaW5lQ29uZmlndXJhYmxlID0gKGZ1bmN0aW9uICh0YXJnZXQsIHByb3BzKSB7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IE9iamVjdC5rZXlzKHByb3BzKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGtleSA9IF9hW19pXTtcclxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogcHJvcHNba2V5XSxcclxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgfSk7XG5cbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGdsb2JhbCBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHByb3ZpZGVkIGVsZW1lbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxyXG4gICAgICogQHJldHVybnMge09iamVjdH1cclxuICAgICAqL1xyXG4gICAgdmFyIGdldFdpbmRvd09mID0gKGZ1bmN0aW9uICh0YXJnZXQpIHtcclxuICAgICAgICAvLyBBc3N1bWUgdGhhdCB0aGUgZWxlbWVudCBpcyBhbiBpbnN0YW5jZSBvZiBOb2RlLCB3aGljaCBtZWFucyB0aGF0IGl0XHJcbiAgICAgICAgLy8gaGFzIHRoZSBcIm93bmVyRG9jdW1lbnRcIiBwcm9wZXJ0eSBmcm9tIHdoaWNoIHdlIGNhbiByZXRyaWV2ZSBhXHJcbiAgICAgICAgLy8gY29ycmVzcG9uZGluZyBnbG9iYWwgb2JqZWN0LlxyXG4gICAgICAgIHZhciBvd25lckdsb2JhbCA9IHRhcmdldCAmJiB0YXJnZXQub3duZXJEb2N1bWVudCAmJiB0YXJnZXQub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldztcclxuICAgICAgICAvLyBSZXR1cm4gdGhlIGxvY2FsIGdsb2JhbCBvYmplY3QgaWYgaXQncyBub3QgcG9zc2libGUgZXh0cmFjdCBvbmUgZnJvbVxyXG4gICAgICAgIC8vIHByb3ZpZGVkIGVsZW1lbnQuXHJcbiAgICAgICAgcmV0dXJuIG93bmVyR2xvYmFsIHx8IGdsb2JhbCQxO1xyXG4gICAgfSk7XG5cbiAgICAvLyBQbGFjZWhvbGRlciBvZiBhbiBlbXB0eSBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgIHZhciBlbXB0eVJlY3QgPSBjcmVhdGVSZWN0SW5pdCgwLCAwLCAwLCAwKTtcclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgcHJvdmlkZWQgc3RyaW5nIHRvIGEgbnVtYmVyLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHRvRmxvYXQodmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSkgfHwgMDtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogRXh0cmFjdHMgYm9yZGVycyBzaXplIGZyb20gcHJvdmlkZWQgc3R5bGVzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7Q1NTU3R5bGVEZWNsYXJhdGlvbn0gc3R5bGVzXHJcbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gcG9zaXRpb25zIC0gQm9yZGVycyBwb3NpdGlvbnMgKHRvcCwgcmlnaHQsIC4uLilcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldEJvcmRlcnNTaXplKHN0eWxlcykge1xyXG4gICAgICAgIHZhciBwb3NpdGlvbnMgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICBwb3NpdGlvbnNbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwb3NpdGlvbnMucmVkdWNlKGZ1bmN0aW9uIChzaXplLCBwb3NpdGlvbikge1xyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBzdHlsZXNbJ2JvcmRlci0nICsgcG9zaXRpb24gKyAnLXdpZHRoJ107XHJcbiAgICAgICAgICAgIHJldHVybiBzaXplICsgdG9GbG9hdCh2YWx1ZSk7XHJcbiAgICAgICAgfSwgMCk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIEV4dHJhY3RzIHBhZGRpbmdzIHNpemVzIGZyb20gcHJvdmlkZWQgc3R5bGVzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7Q1NTU3R5bGVEZWNsYXJhdGlvbn0gc3R5bGVzXHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBQYWRkaW5ncyBib3guXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldFBhZGRpbmdzKHN0eWxlcykge1xyXG4gICAgICAgIHZhciBwb3NpdGlvbnMgPSBbJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCddO1xyXG4gICAgICAgIHZhciBwYWRkaW5ncyA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgcG9zaXRpb25zXzEgPSBwb3NpdGlvbnM7IF9pIDwgcG9zaXRpb25zXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IHBvc2l0aW9uc18xW19pXTtcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVzWydwYWRkaW5nLScgKyBwb3NpdGlvbl07XHJcbiAgICAgICAgICAgIHBhZGRpbmdzW3Bvc2l0aW9uXSA9IHRvRmxvYXQodmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcGFkZGluZ3M7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgY29udGVudCByZWN0YW5nbGUgb2YgcHJvdmlkZWQgU1ZHIGVsZW1lbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTVkdHcmFwaGljc0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgY29udGVudCByZWN0YW5nbGUgb2Ygd2hpY2ggbmVlZHNcclxuICAgICAqICAgICAgdG8gYmUgY2FsY3VsYXRlZC5cclxuICAgICAqIEByZXR1cm5zIHtET01SZWN0SW5pdH1cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0U1ZHQ29udGVudFJlY3QodGFyZ2V0KSB7XHJcbiAgICAgICAgdmFyIGJib3ggPSB0YXJnZXQuZ2V0QkJveCgpO1xyXG4gICAgICAgIHJldHVybiBjcmVhdGVSZWN0SW5pdCgwLCAwLCBiYm94LndpZHRoLCBiYm94LmhlaWdodCk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgY29udGVudCByZWN0YW5nbGUgb2YgcHJvdmlkZWQgSFRNTEVsZW1lbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCBmb3Igd2hpY2ggdG8gY2FsY3VsYXRlIHRoZSBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAqIEByZXR1cm5zIHtET01SZWN0SW5pdH1cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0SFRNTEVsZW1lbnRDb250ZW50UmVjdCh0YXJnZXQpIHtcclxuICAgICAgICAvLyBDbGllbnQgd2lkdGggJiBoZWlnaHQgcHJvcGVydGllcyBjYW4ndCBiZVxyXG4gICAgICAgIC8vIHVzZWQgZXhjbHVzaXZlbHkgYXMgdGhleSBwcm92aWRlIHJvdW5kZWQgdmFsdWVzLlxyXG4gICAgICAgIHZhciBjbGllbnRXaWR0aCA9IHRhcmdldC5jbGllbnRXaWR0aCwgY2xpZW50SGVpZ2h0ID0gdGFyZ2V0LmNsaWVudEhlaWdodDtcclxuICAgICAgICAvLyBCeSB0aGlzIGNvbmRpdGlvbiB3ZSBjYW4gY2F0Y2ggYWxsIG5vbi1yZXBsYWNlZCBpbmxpbmUsIGhpZGRlbiBhbmRcclxuICAgICAgICAvLyBkZXRhY2hlZCBlbGVtZW50cy4gVGhvdWdoIGVsZW1lbnRzIHdpdGggd2lkdGggJiBoZWlnaHQgcHJvcGVydGllcyBsZXNzXHJcbiAgICAgICAgLy8gdGhhbiAwLjUgd2lsbCBiZSBkaXNjYXJkZWQgYXMgd2VsbC5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIFdpdGhvdXQgaXQgd2Ugd291bGQgbmVlZCB0byBpbXBsZW1lbnQgc2VwYXJhdGUgbWV0aG9kcyBmb3IgZWFjaCBvZlxyXG4gICAgICAgIC8vIHRob3NlIGNhc2VzIGFuZCBpdCdzIG5vdCBwb3NzaWJsZSB0byBwZXJmb3JtIGEgcHJlY2lzZSBhbmQgcGVyZm9ybWFuY2VcclxuICAgICAgICAvLyBlZmZlY3RpdmUgdGVzdCBmb3IgaGlkZGVuIGVsZW1lbnRzLiBFLmcuIGV2ZW4galF1ZXJ5J3MgJzp2aXNpYmxlJyBmaWx0ZXJcclxuICAgICAgICAvLyBnaXZlcyB3cm9uZyByZXN1bHRzIGZvciBlbGVtZW50cyB3aXRoIHdpZHRoICYgaGVpZ2h0IGxlc3MgdGhhbiAwLjUuXHJcbiAgICAgICAgaWYgKCFjbGllbnRXaWR0aCAmJiAhY2xpZW50SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbXB0eVJlY3Q7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdHlsZXMgPSBnZXRXaW5kb3dPZih0YXJnZXQpLmdldENvbXB1dGVkU3R5bGUodGFyZ2V0KTtcclxuICAgICAgICB2YXIgcGFkZGluZ3MgPSBnZXRQYWRkaW5ncyhzdHlsZXMpO1xyXG4gICAgICAgIHZhciBob3JpelBhZCA9IHBhZGRpbmdzLmxlZnQgKyBwYWRkaW5ncy5yaWdodDtcclxuICAgICAgICB2YXIgdmVydFBhZCA9IHBhZGRpbmdzLnRvcCArIHBhZGRpbmdzLmJvdHRvbTtcclxuICAgICAgICAvLyBDb21wdXRlZCBzdHlsZXMgb2Ygd2lkdGggJiBoZWlnaHQgYXJlIGJlaW5nIHVzZWQgYmVjYXVzZSB0aGV5IGFyZSB0aGVcclxuICAgICAgICAvLyBvbmx5IGRpbWVuc2lvbnMgYXZhaWxhYmxlIHRvIEpTIHRoYXQgY29udGFpbiBub24tcm91bmRlZCB2YWx1ZXMuIEl0IGNvdWxkXHJcbiAgICAgICAgLy8gYmUgcG9zc2libGUgdG8gdXRpbGl6ZSB0aGUgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGlmIG9ubHkgaXQncyBkYXRhIHdhc24ndFxyXG4gICAgICAgIC8vIGFmZmVjdGVkIGJ5IENTUyB0cmFuc2Zvcm1hdGlvbnMgbGV0IGFsb25lIHBhZGRpbmdzLCBib3JkZXJzIGFuZCBzY3JvbGwgYmFycy5cclxuICAgICAgICB2YXIgd2lkdGggPSB0b0Zsb2F0KHN0eWxlcy53aWR0aCksIGhlaWdodCA9IHRvRmxvYXQoc3R5bGVzLmhlaWdodCk7XHJcbiAgICAgICAgLy8gV2lkdGggJiBoZWlnaHQgaW5jbHVkZSBwYWRkaW5ncyBhbmQgYm9yZGVycyB3aGVuIHRoZSAnYm9yZGVyLWJveCcgYm94XHJcbiAgICAgICAgLy8gbW9kZWwgaXMgYXBwbGllZCAoZXhjZXB0IGZvciBJRSkuXHJcbiAgICAgICAgaWYgKHN0eWxlcy5ib3hTaXppbmcgPT09ICdib3JkZXItYm94Jykge1xyXG4gICAgICAgICAgICAvLyBGb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgcmVxdWlyZWQgdG8gaGFuZGxlIEludGVybmV0IEV4cGxvcmVyIHdoaWNoXHJcbiAgICAgICAgICAgIC8vIGRvZXNuJ3QgaW5jbHVkZSBwYWRkaW5ncyBhbmQgYm9yZGVycyB0byBjb21wdXRlZCBDU1MgZGltZW5zaW9ucy5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gV2UgY2FuIHNheSB0aGF0IGlmIENTUyBkaW1lbnNpb25zICsgcGFkZGluZ3MgYXJlIGVxdWFsIHRvIHRoZSBcImNsaWVudFwiXHJcbiAgICAgICAgICAgIC8vIHByb3BlcnRpZXMgdGhlbiBpdCdzIGVpdGhlciBJRSwgYW5kIHRodXMgd2UgZG9uJ3QgbmVlZCB0byBzdWJ0cmFjdFxyXG4gICAgICAgICAgICAvLyBhbnl0aGluZywgb3IgYW4gZWxlbWVudCBtZXJlbHkgZG9lc24ndCBoYXZlIHBhZGRpbmdzL2JvcmRlcnMgc3R5bGVzLlxyXG4gICAgICAgICAgICBpZiAoTWF0aC5yb3VuZCh3aWR0aCArIGhvcml6UGFkKSAhPT0gY2xpZW50V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIHdpZHRoIC09IGdldEJvcmRlcnNTaXplKHN0eWxlcywgJ2xlZnQnLCAncmlnaHQnKSArIGhvcml6UGFkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChNYXRoLnJvdW5kKGhlaWdodCArIHZlcnRQYWQpICE9PSBjbGllbnRIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgIGhlaWdodCAtPSBnZXRCb3JkZXJzU2l6ZShzdHlsZXMsICd0b3AnLCAnYm90dG9tJykgKyB2ZXJ0UGFkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEZvbGxvd2luZyBzdGVwcyBjYW4ndCBiZSBhcHBsaWVkIHRvIHRoZSBkb2N1bWVudCdzIHJvb3QgZWxlbWVudCBhcyBpdHNcclxuICAgICAgICAvLyBjbGllbnRbV2lkdGgvSGVpZ2h0XSBwcm9wZXJ0aWVzIHJlcHJlc2VudCB2aWV3cG9ydCBhcmVhIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgICAgLy8gQmVzaWRlcywgaXQncyBhcyB3ZWxsIG5vdCBuZWNlc3NhcnkgYXMgdGhlIDxodG1sPiBpdHNlbGYgbmVpdGhlciBoYXNcclxuICAgICAgICAvLyByZW5kZXJlZCBzY3JvbGwgYmFycyBub3IgaXQgY2FuIGJlIGNsaXBwZWQuXHJcbiAgICAgICAgaWYgKCFpc0RvY3VtZW50RWxlbWVudCh0YXJnZXQpKSB7XHJcbiAgICAgICAgICAgIC8vIEluIHNvbWUgYnJvd3NlcnMgKG9ubHkgaW4gRmlyZWZveCwgYWN0dWFsbHkpIENTUyB3aWR0aCAmIGhlaWdodFxyXG4gICAgICAgICAgICAvLyBpbmNsdWRlIHNjcm9sbCBiYXJzIHNpemUgd2hpY2ggY2FuIGJlIHJlbW92ZWQgYXQgdGhpcyBzdGVwIGFzIHNjcm9sbFxyXG4gICAgICAgICAgICAvLyBiYXJzIGFyZSB0aGUgb25seSBkaWZmZXJlbmNlIGJldHdlZW4gcm91bmRlZCBkaW1lbnNpb25zICsgcGFkZGluZ3NcclxuICAgICAgICAgICAgLy8gYW5kIFwiY2xpZW50XCIgcHJvcGVydGllcywgdGhvdWdoIHRoYXQgaXMgbm90IGFsd2F5cyB0cnVlIGluIENocm9tZS5cclxuICAgICAgICAgICAgdmFyIHZlcnRTY3JvbGxiYXIgPSBNYXRoLnJvdW5kKHdpZHRoICsgaG9yaXpQYWQpIC0gY2xpZW50V2lkdGg7XHJcbiAgICAgICAgICAgIHZhciBob3JpelNjcm9sbGJhciA9IE1hdGgucm91bmQoaGVpZ2h0ICsgdmVydFBhZCkgLSBjbGllbnRIZWlnaHQ7XHJcbiAgICAgICAgICAgIC8vIENocm9tZSBoYXMgYSByYXRoZXIgd2VpcmQgcm91bmRpbmcgb2YgXCJjbGllbnRcIiBwcm9wZXJ0aWVzLlxyXG4gICAgICAgICAgICAvLyBFLmcuIGZvciBhbiBlbGVtZW50IHdpdGggY29udGVudCB3aWR0aCBvZiAzMTQuMnB4IGl0IHNvbWV0aW1lcyBnaXZlc1xyXG4gICAgICAgICAgICAvLyB0aGUgY2xpZW50IHdpZHRoIG9mIDMxNXB4IGFuZCBmb3IgdGhlIHdpZHRoIG9mIDMxNC43cHggaXQgbWF5IGdpdmVcclxuICAgICAgICAgICAgLy8gMzE0cHguIEFuZCBpdCBkb2Vzbid0IGhhcHBlbiBhbGwgdGhlIHRpbWUuIFNvIGp1c3QgaWdub3JlIHRoaXMgZGVsdGFcclxuICAgICAgICAgICAgLy8gYXMgYSBub24tcmVsZXZhbnQuXHJcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyh2ZXJ0U2Nyb2xsYmFyKSAhPT0gMSkge1xyXG4gICAgICAgICAgICAgICAgd2lkdGggLT0gdmVydFNjcm9sbGJhcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoaG9yaXpTY3JvbGxiYXIpICE9PSAxKSB7XHJcbiAgICAgICAgICAgICAgICBoZWlnaHQgLT0gaG9yaXpTY3JvbGxiYXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZVJlY3RJbml0KHBhZGRpbmdzLmxlZnQsIHBhZGRpbmdzLnRvcCwgd2lkdGgsIGhlaWdodCk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIENoZWNrcyB3aGV0aGVyIHByb3ZpZGVkIGVsZW1lbnQgaXMgYW4gaW5zdGFuY2Ugb2YgdGhlIFNWR0dyYXBoaWNzRWxlbWVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICB2YXIgaXNTVkdHcmFwaGljc0VsZW1lbnQgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIFNvbWUgYnJvd3NlcnMsIG5hbWVseSBJRSBhbmQgRWRnZSwgZG9uJ3QgaGF2ZSB0aGUgU1ZHR3JhcGhpY3NFbGVtZW50XHJcbiAgICAgICAgLy8gaW50ZXJmYWNlLlxyXG4gICAgICAgIGlmICh0eXBlb2YgU1ZHR3JhcGhpY3NFbGVtZW50ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCkgeyByZXR1cm4gdGFyZ2V0IGluc3RhbmNlb2YgZ2V0V2luZG93T2YodGFyZ2V0KS5TVkdHcmFwaGljc0VsZW1lbnQ7IH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIElmIGl0J3Mgc28sIHRoZW4gY2hlY2sgdGhhdCBlbGVtZW50IGlzIGF0IGxlYXN0IGFuIGluc3RhbmNlIG9mIHRoZVxyXG4gICAgICAgIC8vIFNWR0VsZW1lbnQgYW5kIHRoYXQgaXQgaGFzIHRoZSBcImdldEJCb3hcIiBtZXRob2QuXHJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVuc1xyXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0KSB7IHJldHVybiAodGFyZ2V0IGluc3RhbmNlb2YgZ2V0V2luZG93T2YodGFyZ2V0KS5TVkdFbGVtZW50ICYmXHJcbiAgICAgICAgICAgIHR5cGVvZiB0YXJnZXQuZ2V0QkJveCA9PT0gJ2Z1bmN0aW9uJyk7IH07XHJcbiAgICB9KSgpO1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3Mgd2hldGhlciBwcm92aWRlZCBlbGVtZW50IGlzIGEgZG9jdW1lbnQgZWxlbWVudCAoPGh0bWw+KS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpc0RvY3VtZW50RWxlbWVudCh0YXJnZXQpIHtcclxuICAgICAgICByZXR1cm4gdGFyZ2V0ID09PSBnZXRXaW5kb3dPZih0YXJnZXQpLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyBhbiBhcHByb3ByaWF0ZSBjb250ZW50IHJlY3RhbmdsZSBmb3IgcHJvdmlkZWQgaHRtbCBvciBzdmcgZWxlbWVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgY29udGVudCByZWN0YW5nbGUgb2Ygd2hpY2ggbmVlZHMgdG8gYmUgY2FsY3VsYXRlZC5cclxuICAgICAqIEByZXR1cm5zIHtET01SZWN0SW5pdH1cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0Q29udGVudFJlY3QodGFyZ2V0KSB7XHJcbiAgICAgICAgaWYgKCFpc0Jyb3dzZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGVtcHR5UmVjdDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGlzU1ZHR3JhcGhpY3NFbGVtZW50KHRhcmdldCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGdldFNWR0NvbnRlbnRSZWN0KHRhcmdldCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBnZXRIVE1MRWxlbWVudENvbnRlbnRSZWN0KHRhcmdldCk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgcmVjdGFuZ2xlIHdpdGggYW4gaW50ZXJmYWNlIG9mIHRoZSBET01SZWN0UmVhZE9ubHkuXHJcbiAgICAgKiBTcGVjOiBodHRwczovL2RyYWZ0cy5meHRmLm9yZy9nZW9tZXRyeS8jZG9tcmVjdHJlYWRvbmx5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtET01SZWN0SW5pdH0gcmVjdEluaXQgLSBPYmplY3Qgd2l0aCByZWN0YW5nbGUncyB4L3kgY29vcmRpbmF0ZXMgYW5kIGRpbWVuc2lvbnMuXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NUmVjdFJlYWRPbmx5fVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBjcmVhdGVSZWFkT25seVJlY3QoX2EpIHtcclxuICAgICAgICB2YXIgeCA9IF9hLngsIHkgPSBfYS55LCB3aWR0aCA9IF9hLndpZHRoLCBoZWlnaHQgPSBfYS5oZWlnaHQ7XHJcbiAgICAgICAgLy8gSWYgRE9NUmVjdFJlYWRPbmx5IGlzIGF2YWlsYWJsZSB1c2UgaXQgYXMgYSBwcm90b3R5cGUgZm9yIHRoZSByZWN0YW5nbGUuXHJcbiAgICAgICAgdmFyIENvbnN0ciA9IHR5cGVvZiBET01SZWN0UmVhZE9ubHkgIT09ICd1bmRlZmluZWQnID8gRE9NUmVjdFJlYWRPbmx5IDogT2JqZWN0O1xyXG4gICAgICAgIHZhciByZWN0ID0gT2JqZWN0LmNyZWF0ZShDb25zdHIucHJvdG90eXBlKTtcclxuICAgICAgICAvLyBSZWN0YW5nbGUncyBwcm9wZXJ0aWVzIGFyZSBub3Qgd3JpdGFibGUgYW5kIG5vbi1lbnVtZXJhYmxlLlxyXG4gICAgICAgIGRlZmluZUNvbmZpZ3VyYWJsZShyZWN0LCB7XHJcbiAgICAgICAgICAgIHg6IHgsIHk6IHksIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQsXHJcbiAgICAgICAgICAgIHRvcDogeSxcclxuICAgICAgICAgICAgcmlnaHQ6IHggKyB3aWR0aCxcclxuICAgICAgICAgICAgYm90dG9tOiBoZWlnaHQgKyB5LFxyXG4gICAgICAgICAgICBsZWZ0OiB4XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHJlY3Q7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgRE9NUmVjdEluaXQgb2JqZWN0IGJhc2VkIG9uIHRoZSBwcm92aWRlZCBkaW1lbnNpb25zIGFuZCB0aGUgeC95IGNvb3JkaW5hdGVzLlxyXG4gICAgICogU3BlYzogaHR0cHM6Ly9kcmFmdHMuZnh0Zi5vcmcvZ2VvbWV0cnkvI2RpY3RkZWYtZG9tcmVjdGluaXRcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geCAtIFggY29vcmRpbmF0ZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5IC0gWSBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gUmVjdGFuZ2xlJ3Mgd2lkdGguXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gUmVjdGFuZ2xlJ3MgaGVpZ2h0LlxyXG4gICAgICogQHJldHVybnMge0RPTVJlY3RJbml0fVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBjcmVhdGVSZWN0SW5pdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7XHJcbiAgICAgICAgcmV0dXJuIHsgeDogeCwgeTogeSwgd2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCB9O1xyXG4gICAgfVxuXG4gICAgLyoqXHJcbiAgICAgKiBDbGFzcyB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBjb21wdXRhdGlvbnMgb2YgdGhlIGNvbnRlbnQgcmVjdGFuZ2xlIG9mXHJcbiAgICAgKiBwcm92aWRlZCBET00gZWxlbWVudCBhbmQgZm9yIGtlZXBpbmcgdHJhY2sgb2YgaXQncyBjaGFuZ2VzLlxyXG4gICAgICovXHJcbiAgICB2YXIgUmVzaXplT2JzZXJ2YXRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBSZXNpemVPYnNlcnZhdGlvbi5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCB0byBiZSBvYnNlcnZlZC5cclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBSZXNpemVPYnNlcnZhdGlvbih0YXJnZXQpIHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEJyb2FkY2FzdGVkIHdpZHRoIG9mIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdGhpcy5icm9hZGNhc3RXaWR0aCA9IDA7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBCcm9hZGNhc3RlZCBoZWlnaHQgb2YgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB0aGlzLmJyb2FkY2FzdEhlaWdodCA9IDA7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIGxhc3Qgb2JzZXJ2ZWQgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqIEBwcml2YXRlIHtET01SZWN0SW5pdH1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRoaXMuY29udGVudFJlY3RfID0gY3JlYXRlUmVjdEluaXQoMCwgMCwgMCwgMCk7XHJcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBVcGRhdGVzIGNvbnRlbnQgcmVjdGFuZ2xlIGFuZCB0ZWxscyB3aGV0aGVyIGl0J3Mgd2lkdGggb3IgaGVpZ2h0IHByb3BlcnRpZXNcclxuICAgICAgICAgKiBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgYnJvYWRjYXN0LlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzaXplT2JzZXJ2YXRpb24ucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgcmVjdCA9IGdldENvbnRlbnRSZWN0KHRoaXMudGFyZ2V0KTtcclxuICAgICAgICAgICAgdGhpcy5jb250ZW50UmVjdF8gPSByZWN0O1xyXG4gICAgICAgICAgICByZXR1cm4gKHJlY3Qud2lkdGggIT09IHRoaXMuYnJvYWRjYXN0V2lkdGggfHxcclxuICAgICAgICAgICAgICAgIHJlY3QuaGVpZ2h0ICE9PSB0aGlzLmJyb2FkY2FzdEhlaWdodCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBVcGRhdGVzICdicm9hZGNhc3RXaWR0aCcgYW5kICdicm9hZGNhc3RIZWlnaHQnIHByb3BlcnRpZXMgd2l0aCBhIGRhdGFcclxuICAgICAgICAgKiBmcm9tIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnRpZXMgb2YgdGhlIGxhc3Qgb2JzZXJ2ZWQgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJucyB7RE9NUmVjdEluaXR9IExhc3Qgb2JzZXJ2ZWQgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzaXplT2JzZXJ2YXRpb24ucHJvdG90eXBlLmJyb2FkY2FzdFJlY3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciByZWN0ID0gdGhpcy5jb250ZW50UmVjdF87XHJcbiAgICAgICAgICAgIHRoaXMuYnJvYWRjYXN0V2lkdGggPSByZWN0LndpZHRoO1xyXG4gICAgICAgICAgICB0aGlzLmJyb2FkY2FzdEhlaWdodCA9IHJlY3QuaGVpZ2h0O1xyXG4gICAgICAgICAgICByZXR1cm4gcmVjdDtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBSZXNpemVPYnNlcnZhdGlvbjtcclxuICAgIH0oKSk7XG5cbiAgICB2YXIgUmVzaXplT2JzZXJ2ZXJFbnRyeSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFJlc2l6ZU9ic2VydmVyRW50cnkuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdGhhdCBpcyBiZWluZyBvYnNlcnZlZC5cclxuICAgICAgICAgKiBAcGFyYW0ge0RPTVJlY3RJbml0fSByZWN0SW5pdCAtIERhdGEgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBSZXNpemVPYnNlcnZlckVudHJ5KHRhcmdldCwgcmVjdEluaXQpIHtcclxuICAgICAgICAgICAgdmFyIGNvbnRlbnRSZWN0ID0gY3JlYXRlUmVhZE9ubHlSZWN0KHJlY3RJbml0KTtcclxuICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIGZvbGxvd2luZyBwcm9wZXJ0aWVzIGFyZSBub3Qgd3JpdGFibGVcclxuICAgICAgICAgICAgLy8gYW5kIGFyZSBhbHNvIG5vdCBlbnVtZXJhYmxlIGluIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24uXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIFByb3BlcnR5IGFjY2Vzc29ycyBhcmUgbm90IGJlaW5nIHVzZWQgYXMgdGhleSdkIHJlcXVpcmUgdG8gZGVmaW5lIGFcclxuICAgICAgICAgICAgLy8gcHJpdmF0ZSBXZWFrTWFwIHN0b3JhZ2Ugd2hpY2ggbWF5IGNhdXNlIG1lbW9yeSBsZWFrcyBpbiBicm93c2VycyB0aGF0XHJcbiAgICAgICAgICAgIC8vIGRvbid0IHN1cHBvcnQgdGhpcyB0eXBlIG9mIGNvbGxlY3Rpb25zLlxyXG4gICAgICAgICAgICBkZWZpbmVDb25maWd1cmFibGUodGhpcywgeyB0YXJnZXQ6IHRhcmdldCwgY29udGVudFJlY3Q6IGNvbnRlbnRSZWN0IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gUmVzaXplT2JzZXJ2ZXJFbnRyeTtcclxuICAgIH0oKSk7XG5cbiAgICB2YXIgUmVzaXplT2JzZXJ2ZXJTUEkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBSZXNpemVPYnNlcnZlci5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJDYWxsYmFja30gY2FsbGJhY2sgLSBDYWxsYmFjayBmdW5jdGlvbiB0aGF0IGlzIGludm9rZWRcclxuICAgICAgICAgKiAgICAgIHdoZW4gb25lIG9mIHRoZSBvYnNlcnZlZCBlbGVtZW50cyBjaGFuZ2VzIGl0J3MgY29udGVudCBkaW1lbnNpb25zLlxyXG4gICAgICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyfSBjb250cm9sbGVyIC0gQ29udHJvbGxlciBpbnN0YW5jZSB3aGljaFxyXG4gICAgICAgICAqICAgICAgaXMgcmVzcG9uc2libGUgZm9yIHRoZSB1cGRhdGVzIG9mIG9ic2VydmVyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJ9IGNhbGxiYWNrQ3R4IC0gUmVmZXJlbmNlIHRvIHRoZSBwdWJsaWNcclxuICAgICAgICAgKiAgICAgIFJlc2l6ZU9ic2VydmVyIGluc3RhbmNlIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGNhbGxiYWNrIGZ1bmN0aW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIFJlc2l6ZU9ic2VydmVyU1BJKGNhbGxiYWNrLCBjb250cm9sbGVyLCBjYWxsYmFja0N0eCkge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ29sbGVjdGlvbiBvZiByZXNpemUgb2JzZXJ2YXRpb25zIHRoYXQgaGF2ZSBkZXRlY3RlZCBjaGFuZ2VzIGluIGRpbWVuc2lvbnNcclxuICAgICAgICAgICAgICogb2YgZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqIEBwcml2YXRlIHtBcnJheTxSZXNpemVPYnNlcnZhdGlvbj59XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZU9ic2VydmF0aW9uc18gPSBbXTtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZ2lzdHJ5IG9mIHRoZSBSZXNpemVPYnNlcnZhdGlvbiBpbnN0YW5jZXMuXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqIEBwcml2YXRlIHtNYXA8RWxlbWVudCwgUmVzaXplT2JzZXJ2YXRpb24+fVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZhdGlvbnNfID0gbmV3IE1hcFNoaW0oKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGNhbGxiYWNrIHByb3ZpZGVkIGFzIHBhcmFtZXRlciAxIGlzIG5vdCBhIGZ1bmN0aW9uLicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tfID0gY2FsbGJhY2s7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcl8gPSBjb250cm9sbGVyO1xyXG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrQ3R4XyA9IGNhbGxiYWNrQ3R4O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTdGFydHMgb2JzZXJ2aW5nIHByb3ZpZGVkIGVsZW1lbnQuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdG8gYmUgb2JzZXJ2ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzaXplT2JzZXJ2ZXJTUEkucHJvdG90eXBlLm9ic2VydmUgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgaWYgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IGhhdmUgdGhlIEVsZW1lbnQgaW50ZXJmYWNlLlxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIEVsZW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICEoRWxlbWVudCBpbnN0YW5jZW9mIE9iamVjdCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBnZXRXaW5kb3dPZih0YXJnZXQpLkVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdwYXJhbWV0ZXIgMSBpcyBub3Qgb2YgdHlwZSBcIkVsZW1lbnRcIi4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgb2JzZXJ2YXRpb25zID0gdGhpcy5vYnNlcnZhdGlvbnNfO1xyXG4gICAgICAgICAgICAvLyBEbyBub3RoaW5nIGlmIGVsZW1lbnQgaXMgYWxyZWFkeSBiZWluZyBvYnNlcnZlZC5cclxuICAgICAgICAgICAgaWYgKG9ic2VydmF0aW9ucy5oYXModGFyZ2V0KSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9ic2VydmF0aW9ucy5zZXQodGFyZ2V0LCBuZXcgUmVzaXplT2JzZXJ2YXRpb24odGFyZ2V0KSk7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcl8uYWRkT2JzZXJ2ZXIodGhpcyk7XHJcbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSB1cGRhdGUgb2Ygb2JzZXJ2YXRpb25zLlxyXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJfLnJlZnJlc2goKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFN0b3BzIG9ic2VydmluZyBwcm92aWRlZCBlbGVtZW50LlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IHRvIHN0b3Agb2JzZXJ2aW5nLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS51bm9ic2VydmUgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgaWYgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IGhhdmUgdGhlIEVsZW1lbnQgaW50ZXJmYWNlLlxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIEVsZW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICEoRWxlbWVudCBpbnN0YW5jZW9mIE9iamVjdCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBnZXRXaW5kb3dPZih0YXJnZXQpLkVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdwYXJhbWV0ZXIgMSBpcyBub3Qgb2YgdHlwZSBcIkVsZW1lbnRcIi4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgb2JzZXJ2YXRpb25zID0gdGhpcy5vYnNlcnZhdGlvbnNfO1xyXG4gICAgICAgICAgICAvLyBEbyBub3RoaW5nIGlmIGVsZW1lbnQgaXMgbm90IGJlaW5nIG9ic2VydmVkLlxyXG4gICAgICAgICAgICBpZiAoIW9ic2VydmF0aW9ucy5oYXModGFyZ2V0KSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9ic2VydmF0aW9ucy5kZWxldGUodGFyZ2V0KTtcclxuICAgICAgICAgICAgaWYgKCFvYnNlcnZhdGlvbnMuc2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250cm9sbGVyXy5yZW1vdmVPYnNlcnZlcih0aGlzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU3RvcHMgb2JzZXJ2aW5nIGFsbCBlbGVtZW50cy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB0aGlzLmNsZWFyQWN0aXZlKCk7XHJcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2YXRpb25zXy5jbGVhcigpO1xyXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJfLnJlbW92ZU9ic2VydmVyKHRoaXMpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ29sbGVjdHMgb2JzZXJ2YXRpb24gaW5zdGFuY2VzIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgb2Ygd2hpY2ggaGFzIGNoYW5nZWRcclxuICAgICAgICAgKiBpdCdzIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzaXplT2JzZXJ2ZXJTUEkucHJvdG90eXBlLmdhdGhlckFjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgdGhpcy5jbGVhckFjdGl2ZSgpO1xyXG4gICAgICAgICAgICB0aGlzLm9ic2VydmF0aW9uc18uZm9yRWFjaChmdW5jdGlvbiAob2JzZXJ2YXRpb24pIHtcclxuICAgICAgICAgICAgICAgIGlmIChvYnNlcnZhdGlvbi5pc0FjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuYWN0aXZlT2JzZXJ2YXRpb25zXy5wdXNoKG9ic2VydmF0aW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBJbnZva2VzIGluaXRpYWwgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCBhIGxpc3Qgb2YgUmVzaXplT2JzZXJ2ZXJFbnRyeVxyXG4gICAgICAgICAqIGluc3RhbmNlcyBjb2xsZWN0ZWQgZnJvbSBhY3RpdmUgcmVzaXplIG9ic2VydmF0aW9ucy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5icm9hZGNhc3RBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgaWYgb2JzZXJ2ZXIgZG9lc24ndCBoYXZlIGFjdGl2ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXNBY3RpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBjdHggPSB0aGlzLmNhbGxiYWNrQ3R4XztcclxuICAgICAgICAgICAgLy8gQ3JlYXRlIFJlc2l6ZU9ic2VydmVyRW50cnkgaW5zdGFuY2UgZm9yIGV2ZXJ5IGFjdGl2ZSBvYnNlcnZhdGlvbi5cclxuICAgICAgICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmFjdGl2ZU9ic2VydmF0aW9uc18ubWFwKGZ1bmN0aW9uIChvYnNlcnZhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNpemVPYnNlcnZlckVudHJ5KG9ic2VydmF0aW9uLnRhcmdldCwgb2JzZXJ2YXRpb24uYnJvYWRjYXN0UmVjdCgpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2tfLmNhbGwoY3R4LCBlbnRyaWVzLCBjdHgpO1xyXG4gICAgICAgICAgICB0aGlzLmNsZWFyQWN0aXZlKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDbGVhcnMgdGhlIGNvbGxlY3Rpb24gb2YgYWN0aXZlIG9ic2VydmF0aW9ucy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5jbGVhckFjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5hY3RpdmVPYnNlcnZhdGlvbnNfLnNwbGljZSgwKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRlbGxzIHdoZXRoZXIgb2JzZXJ2ZXIgaGFzIGFjdGl2ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZXNpemVPYnNlcnZlclNQSS5wcm90b3R5cGUuaGFzQWN0aXZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hY3RpdmVPYnNlcnZhdGlvbnNfLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gUmVzaXplT2JzZXJ2ZXJTUEk7XHJcbiAgICB9KCkpO1xuXG4gICAgLy8gUmVnaXN0cnkgb2YgaW50ZXJuYWwgb2JzZXJ2ZXJzLiBJZiBXZWFrTWFwIGlzIG5vdCBhdmFpbGFibGUgdXNlIGN1cnJlbnQgc2hpbVxyXG4gICAgLy8gZm9yIHRoZSBNYXAgY29sbGVjdGlvbiBhcyBpdCBoYXMgYWxsIHJlcXVpcmVkIG1ldGhvZHMgYW5kIGJlY2F1c2UgV2Vha01hcFxyXG4gICAgLy8gY2FuJ3QgYmUgZnVsbHkgcG9seWZpbGxlZCBhbnl3YXkuXHJcbiAgICB2YXIgb2JzZXJ2ZXJzID0gdHlwZW9mIFdlYWtNYXAgIT09ICd1bmRlZmluZWQnID8gbmV3IFdlYWtNYXAoKSA6IG5ldyBNYXBTaGltKCk7XHJcbiAgICAvKipcclxuICAgICAqIFJlc2l6ZU9ic2VydmVyIEFQSS4gRW5jYXBzdWxhdGVzIHRoZSBSZXNpemVPYnNlcnZlciBTUEkgaW1wbGVtZW50YXRpb25cclxuICAgICAqIGV4cG9zaW5nIG9ubHkgdGhvc2UgbWV0aG9kcyBhbmQgcHJvcGVydGllcyB0aGF0IGFyZSBkZWZpbmVkIGluIHRoZSBzcGVjLlxyXG4gICAgICovXHJcbiAgICB2YXIgUmVzaXplT2JzZXJ2ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBSZXNpemVPYnNlcnZlci5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJDYWxsYmFja30gY2FsbGJhY2sgLSBDYWxsYmFjayB0aGF0IGlzIGludm9rZWQgd2hlblxyXG4gICAgICAgICAqICAgICAgZGltZW5zaW9ucyBvZiB0aGUgb2JzZXJ2ZWQgZWxlbWVudHMgY2hhbmdlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIFJlc2l6ZU9ic2VydmVyKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZXNpemVPYnNlcnZlcikpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbi4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJzEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgY29udHJvbGxlciA9IFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5nZXRJbnN0YW5jZSgpO1xyXG4gICAgICAgICAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXJTUEkoY2FsbGJhY2ssIGNvbnRyb2xsZXIsIHRoaXMpO1xyXG4gICAgICAgICAgICBvYnNlcnZlcnMuc2V0KHRoaXMsIG9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgfSgpKTtcclxuICAgIC8vIEV4cG9zZSBwdWJsaWMgbWV0aG9kcyBvZiBSZXNpemVPYnNlcnZlci5cclxuICAgIFtcclxuICAgICAgICAnb2JzZXJ2ZScsXHJcbiAgICAgICAgJ3Vub2JzZXJ2ZScsXHJcbiAgICAgICAgJ2Rpc2Nvbm5lY3QnXHJcbiAgICBdLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xyXG4gICAgICAgIFJlc2l6ZU9ic2VydmVyLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgX2E7XHJcbiAgICAgICAgICAgIHJldHVybiAoX2EgPSBvYnNlcnZlcnMuZ2V0KHRoaXMpKVttZXRob2RdLmFwcGx5KF9hLCBhcmd1bWVudHMpO1xyXG4gICAgICAgIH07XHJcbiAgICB9KTtcblxuICAgIHZhciBpbmRleCA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gRXhwb3J0IGV4aXN0aW5nIGltcGxlbWVudGF0aW9uIGlmIGF2YWlsYWJsZS5cclxuICAgICAgICBpZiAodHlwZW9mIGdsb2JhbCQxLlJlc2l6ZU9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gZ2xvYmFsJDEuUmVzaXplT2JzZXJ2ZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBSZXNpemVPYnNlcnZlcjtcclxuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gaW5kZXg7XG5cbn0pKSk7XG4iLCIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG5cclxuLyogZ2xvYmFsIGdsb2JhbCwgZGVmaW5lLCBTeXN0ZW0sIFJlZmxlY3QsIFByb21pc2UgKi9cclxudmFyIF9fZXh0ZW5kcztcclxudmFyIF9fYXNzaWduO1xyXG52YXIgX19yZXN0O1xyXG52YXIgX19kZWNvcmF0ZTtcclxudmFyIF9fcGFyYW07XHJcbnZhciBfX21ldGFkYXRhO1xyXG52YXIgX19hd2FpdGVyO1xyXG52YXIgX19nZW5lcmF0b3I7XHJcbnZhciBfX2V4cG9ydFN0YXI7XHJcbnZhciBfX3ZhbHVlcztcclxudmFyIF9fcmVhZDtcclxudmFyIF9fc3ByZWFkO1xyXG52YXIgX19zcHJlYWRBcnJheXM7XHJcbnZhciBfX2F3YWl0O1xyXG52YXIgX19hc3luY0dlbmVyYXRvcjtcclxudmFyIF9fYXN5bmNEZWxlZ2F0b3I7XHJcbnZhciBfX2FzeW5jVmFsdWVzO1xyXG52YXIgX19tYWtlVGVtcGxhdGVPYmplY3Q7XHJcbnZhciBfX2ltcG9ydFN0YXI7XHJcbnZhciBfX2ltcG9ydERlZmF1bHQ7XHJcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0O1xyXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldDtcclxudmFyIF9fY3JlYXRlQmluZGluZztcclxuKGZ1bmN0aW9uIChmYWN0b3J5KSB7XHJcbiAgICB2YXIgcm9vdCA9IHR5cGVvZiBnbG9iYWwgPT09IFwib2JqZWN0XCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiA/IHNlbGYgOiB0eXBlb2YgdGhpcyA9PT0gXCJvYmplY3RcIiA/IHRoaXMgOiB7fTtcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xyXG4gICAgICAgIGRlZmluZShcInRzbGliXCIsIFtcImV4cG9ydHNcIl0sIGZ1bmN0aW9uIChleHBvcnRzKSB7IGZhY3RvcnkoY3JlYXRlRXhwb3J0ZXIocm9vdCwgY3JlYXRlRXhwb3J0ZXIoZXhwb3J0cykpKTsgfSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xyXG4gICAgICAgIGZhY3RvcnkoY3JlYXRlRXhwb3J0ZXIocm9vdCwgY3JlYXRlRXhwb3J0ZXIobW9kdWxlLmV4cG9ydHMpKSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBmYWN0b3J5KGNyZWF0ZUV4cG9ydGVyKHJvb3QpKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGNyZWF0ZUV4cG9ydGVyKGV4cG9ydHMsIHByZXZpb3VzKSB7XHJcbiAgICAgICAgaWYgKGV4cG9ydHMgIT09IHJvb3QpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChpZCwgdikgeyByZXR1cm4gZXhwb3J0c1tpZF0gPSBwcmV2aW91cyA/IHByZXZpb3VzKGlkLCB2KSA6IHY7IH07XHJcbiAgICB9XHJcbn0pXHJcbihmdW5jdGlvbiAoZXhwb3J0ZXIpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG5cclxuICAgIF9fZXh0ZW5kcyA9IGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH07XHJcblxyXG4gICAgX19yZXN0ID0gZnVuY3Rpb24gKHMsIGUpIHtcclxuICAgICAgICB2YXIgdCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgICAgICB0W3BdID0gc1twXTtcclxuICAgICAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2RlY29yYXRlID0gZnVuY3Rpb24gKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICAgICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgICAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICAgICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxuICAgIH07XHJcblxyXG4gICAgX19wYXJhbSA9IGZ1bmN0aW9uIChwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxuICAgIH07XHJcblxyXG4gICAgX19tZXRhZGF0YSA9IGZ1bmN0aW9uIChtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXdhaXRlciA9IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgICAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgICAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2dlbmVyYXRvciA9IGZ1bmN0aW9uICh0aGlzQXJnLCBib2R5KSB7XHJcbiAgICAgICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgICAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgICAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fY3JlYXRlQmluZGluZyA9IGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICAgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgICAgICBvW2syXSA9IG1ba107XHJcbiAgICB9O1xyXG5cclxuICAgIF9fZXhwb3J0U3RhciA9IGZ1bmN0aW9uIChtLCBleHBvcnRzKSB7XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIWV4cG9ydHMuaGFzT3duUHJvcGVydHkocCkpIGV4cG9ydHNbcF0gPSBtW3BdO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3ZhbHVlcyA9IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgICAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgICAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIH07XHJcblxyXG4gICAgX19yZWFkID0gZnVuY3Rpb24gKG8sIG4pIHtcclxuICAgICAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICAgICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgICAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICAgICAgZmluYWxseSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFyO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX3NwcmVhZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgICAgIHJldHVybiBhcjtcclxuICAgIH07XHJcblxyXG4gICAgX19zcHJlYWRBcnJheXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICAgICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgICAgIHJldHVybiByO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2F3YWl0ID0gZnVuY3Rpb24gKHYpIHtcclxuICAgICAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxuICAgIH07XHJcblxyXG4gICAgX19hc3luY0dlbmVyYXRvciA9IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICAgICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7ICB9XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgICAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fYXN5bmNEZWxlZ2F0b3IgPSBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBpLCBwO1xyXG4gICAgICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICAgICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG4gICAgfTtcclxuXHJcbiAgICBfX2FzeW5jVmFsdWVzID0gZnVuY3Rpb24gKG8pIHtcclxuICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICAgICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgICAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbiAgICB9O1xyXG5cclxuICAgIF9fbWFrZVRlbXBsYXRlT2JqZWN0ID0gZnVuY3Rpb24gKGNvb2tlZCwgcmF3KSB7XHJcbiAgICAgICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgICAgICByZXR1cm4gY29va2VkO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2ltcG9ydFN0YXIgPSBmdW5jdGlvbiAobW9kKSB7XHJcbiAgICAgICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgICAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICAgICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIHJlc3VsdFtrXSA9IG1vZFtrXTtcclxuICAgICAgICByZXN1bHRbXCJkZWZhdWx0XCJdID0gbW9kO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIF9faW1wb3J0RGVmYXVsdCA9IGZ1bmN0aW9uIChtb2QpIHtcclxuICAgICAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcclxuICAgIH07XHJcblxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCA9IGZ1bmN0aW9uIChyZWNlaXZlciwgcHJpdmF0ZU1hcCkge1xyXG4gICAgICAgIGlmICghcHJpdmF0ZU1hcC5oYXMocmVjZWl2ZXIpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhdHRlbXB0ZWQgdG8gZ2V0IHByaXZhdGUgZmllbGQgb24gbm9uLWluc3RhbmNlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHJpdmF0ZU1hcC5nZXQocmVjZWl2ZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0ID0gZnVuY3Rpb24gKHJlY2VpdmVyLCBwcml2YXRlTWFwLCB2YWx1ZSkge1xyXG4gICAgICAgIGlmICghcHJpdmF0ZU1hcC5oYXMocmVjZWl2ZXIpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhdHRlbXB0ZWQgdG8gc2V0IHByaXZhdGUgZmllbGQgb24gbm9uLWluc3RhbmNlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwcml2YXRlTWFwLnNldChyZWNlaXZlciwgdmFsdWUpO1xyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgZXhwb3J0ZXIoXCJfX2V4dGVuZHNcIiwgX19leHRlbmRzKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3NpZ25cIiwgX19hc3NpZ24pO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3Jlc3RcIiwgX19yZXN0KTtcclxuICAgIGV4cG9ydGVyKFwiX19kZWNvcmF0ZVwiLCBfX2RlY29yYXRlKTtcclxuICAgIGV4cG9ydGVyKFwiX19wYXJhbVwiLCBfX3BhcmFtKTtcclxuICAgIGV4cG9ydGVyKFwiX19tZXRhZGF0YVwiLCBfX21ldGFkYXRhKTtcclxuICAgIGV4cG9ydGVyKFwiX19hd2FpdGVyXCIsIF9fYXdhaXRlcik7XHJcbiAgICBleHBvcnRlcihcIl9fZ2VuZXJhdG9yXCIsIF9fZ2VuZXJhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19leHBvcnRTdGFyXCIsIF9fZXhwb3J0U3Rhcik7XHJcbiAgICBleHBvcnRlcihcIl9fY3JlYXRlQmluZGluZ1wiLCBfX2NyZWF0ZUJpbmRpbmcpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3ZhbHVlc1wiLCBfX3ZhbHVlcyk7XHJcbiAgICBleHBvcnRlcihcIl9fcmVhZFwiLCBfX3JlYWQpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX3NwcmVhZFwiLCBfX3NwcmVhZCk7XHJcbiAgICBleHBvcnRlcihcIl9fc3ByZWFkQXJyYXlzXCIsIF9fc3ByZWFkQXJyYXlzKTtcclxuICAgIGV4cG9ydGVyKFwiX19hd2FpdFwiLCBfX2F3YWl0KTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY0dlbmVyYXRvclwiLCBfX2FzeW5jR2VuZXJhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY0RlbGVnYXRvclwiLCBfX2FzeW5jRGVsZWdhdG9yKTtcclxuICAgIGV4cG9ydGVyKFwiX19hc3luY1ZhbHVlc1wiLCBfX2FzeW5jVmFsdWVzKTtcclxuICAgIGV4cG9ydGVyKFwiX19tYWtlVGVtcGxhdGVPYmplY3RcIiwgX19tYWtlVGVtcGxhdGVPYmplY3QpO1xyXG4gICAgZXhwb3J0ZXIoXCJfX2ltcG9ydFN0YXJcIiwgX19pbXBvcnRTdGFyKTtcclxuICAgIGV4cG9ydGVyKFwiX19pbXBvcnREZWZhdWx0XCIsIF9faW1wb3J0RGVmYXVsdCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRHZXRcIiwgX19jbGFzc1ByaXZhdGVGaWVsZEdldCk7XHJcbiAgICBleHBvcnRlcihcIl9fY2xhc3NQcml2YXRlRmllbGRTZXRcIiwgX19jbGFzc1ByaXZhdGVGaWVsZFNldCk7XHJcbn0pO1xyXG4iLCIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNC1wcmVzZW50LCBGYWNlYm9vaywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTaW1pbGFyIHRvIGludmFyaWFudCBidXQgb25seSBsb2dzIGEgd2FybmluZyBpZiB0aGUgY29uZGl0aW9uIGlzIG5vdCBtZXQuXG4gKiBUaGlzIGNhbiBiZSB1c2VkIHRvIGxvZyBpc3N1ZXMgaW4gZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnRzIGluIGNyaXRpY2FsXG4gKiBwYXRocy4gUmVtb3ZpbmcgdGhlIGxvZ2dpbmcgY29kZSBmb3IgcHJvZHVjdGlvbiBlbnZpcm9ubWVudHMgd2lsbCBrZWVwIHRoZVxuICogc2FtZSBsb2dpYyBhbmQgZm9sbG93IHRoZSBzYW1lIGNvZGUgcGF0aHMuXG4gKi9cblxudmFyIF9fREVWX18gPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nO1xuXG52YXIgd2FybmluZyA9IGZ1bmN0aW9uKCkge307XG5cbmlmIChfX0RFVl9fKSB7XG4gIHZhciBwcmludFdhcm5pbmcgPSBmdW5jdGlvbiBwcmludFdhcm5pbmcoZm9ybWF0LCBhcmdzKSB7XG4gICAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gPiAxID8gbGVuIC0gMSA6IDApO1xuICAgIGZvciAodmFyIGtleSA9IDE7IGtleSA8IGxlbjsga2V5KyspIHtcbiAgICAgIGFyZ3Nba2V5IC0gMV0gPSBhcmd1bWVudHNba2V5XTtcbiAgICB9XG4gICAgdmFyIGFyZ0luZGV4ID0gMDtcbiAgICB2YXIgbWVzc2FnZSA9ICdXYXJuaW5nOiAnICtcbiAgICAgIGZvcm1hdC5yZXBsYWNlKC8lcy9nLCBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGFyZ3NbYXJnSW5kZXgrK107XG4gICAgICB9KTtcbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zb2xlLmVycm9yKG1lc3NhZ2UpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgLy8gLS0tIFdlbGNvbWUgdG8gZGVidWdnaW5nIFJlYWN0IC0tLVxuICAgICAgLy8gVGhpcyBlcnJvciB3YXMgdGhyb3duIGFzIGEgY29udmVuaWVuY2Ugc28gdGhhdCB5b3UgY2FuIHVzZSB0aGlzIHN0YWNrXG4gICAgICAvLyB0byBmaW5kIHRoZSBjYWxsc2l0ZSB0aGF0IGNhdXNlZCB0aGlzIHdhcm5pbmcgdG8gZmlyZS5cbiAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICB9IGNhdGNoICh4KSB7fVxuICB9XG5cbiAgd2FybmluZyA9IGZ1bmN0aW9uKGNvbmRpdGlvbiwgZm9ybWF0LCBhcmdzKSB7XG4gICAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gPiAyID8gbGVuIC0gMiA6IDApO1xuICAgIGZvciAodmFyIGtleSA9IDI7IGtleSA8IGxlbjsga2V5KyspIHtcbiAgICAgIGFyZ3Nba2V5IC0gMl0gPSBhcmd1bWVudHNba2V5XTtcbiAgICB9XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ2B3YXJuaW5nKGNvbmRpdGlvbiwgZm9ybWF0LCAuLi5hcmdzKWAgcmVxdWlyZXMgYSB3YXJuaW5nICcgK1xuICAgICAgICAgICdtZXNzYWdlIGFyZ3VtZW50J1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFjb25kaXRpb24pIHtcbiAgICAgIHByaW50V2FybmluZy5hcHBseShudWxsLCBbZm9ybWF0XS5jb25jYXQoYXJncykpO1xuICAgIH1cbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3YXJuaW5nO1xuIl19